Редактирование движений документов информационной базы 1С:Предприятие, версии 7.7, так как это возможно в версии 8.Х. В том числе и обработка движений выборки документов программно.
В 1С 8 — вечном источнике моего вдохновения ))), есть возможность через свойство «Движения» обратиться к набору движений документа напрямую из любого модуля. Что дает довольно много возможностей, в том числе, редактирование движений документа «вручную». Это там — вообще, стандартная «вещь». К сожалению, в 1С 7.7, это не так. И в данной статье, мы постараемся с этим что-то сделать.
О классе «ВыполняемыйМодуль» компоненты 1С++ я уже говорил [ссылка], когда описывал добавление дополнительных модулей в конфигурацию 1С 7.7.
Создадим новую конфигурацию информационной базы. Зададим справочник «Клиенты», документ «Продажа» с реквизитами в шапке «Клиент» — тип «Справочник.Клиенты» и «СуммаДокумента» — тип «Число». Документ будет проводится по оборотному регистру накопления «Продажи», в котором следует определить измерение «Клиент» — тип «Справочник.Клиенты» и ресурс «Сумма».
Также, добавим общий журнал «ОбщийЖурнал», на форме списка которого зададим кнопку «Провести» с определением обработчика в модуле формы:
//*******************************************
// запись движений
Процедура Провести()
Документы = СоздатьОбъект("Документ");
Документы.НайтиДокумент(ТекущийДокумент);
// передача управления в модуль документа
Документы.Провести(, РучноеФормированиеДвижений());
КонецПроцедуры
Процедура «РучноеФормированиеДвижений» служит для эмуляции создания, нового, уже отредактированного вручную набора движений текущего документа журнала. Представим, что в некоторой диалоговой форме, мы отредактировали вручную движения документа и теперь хотим записать изменения.
//*******************************************
// формирование движений отредактированных вручную
Функция РучноеФормированиеДвижений()
// движения документа в xml-формате
хмлПарсер = СоздатьОбъект("Msxml2.DOMDocument.6.0");
хмлДвиженияДокумента = хмлПарсер
.appendChild(хмлПарсер.createElement("ДвиженияДокумента"));
// определение набора движений [по регистру]
хмлНаборДвижений = хмлДвиженияДокумента
.appendChild(хмлПарсер.createElement("Продажи"));
// запись набора
хмлЗапись = хмлНаборДвижений.appendChild(хмлПарсер.createElement("п"));
// реквизиты записи
хмлРеквизит = хмлЗапись.appendChild(хмлПарсер.createElement("Направление"));
хмлРеквизит.text = 0;
хмлРеквизит = хмлЗапись.appendChild(хмлПарсер.createElement("Клиент"));
хмлРеквизит.text = ЗначениеВСтрокуВнутр(ТекущийДокумент.Клиент);
хмлРеквизит = хмлЗапись.appendChild(хмлПарсер.createElement("Сумма"));
хмлРеквизит.text = 2000;
Возврат хмлПарсер;
КонецФункции
Сам набор движений, как видите, представлен в xml-формате. Что очень удобно для разного рода манипуляций с этими данными. В модуле документа «Продажа», в обработке проведения, передадим управление глобальной процедуре проведения с передачей, в качестве параметра, контекста этого самого документа.
//*******************************************
// вызов процедуры проведения документа
Процедура ОбработкаПроведения(Параметр)
// передача управления в глобальный модуль
глОбработкаПроведения(Контекст, Параметр);
КонецПроцедуры
«глОбработкаПроведения» — это и есть та самая универсальная процедура записи движений документа. Она позволяет нам корректировать движения документа в журнале. Определить документ корректировки записей регистров, наподобие того, как это сделано в некоторых конфигурациях на платформе 1С 8. И, как я покажу дальше, не только это. Текст процедуры представлен ниже:
//*******************************************
// глобальная процедура проведения документа
Процедура глОбработкаПроведения(Конт, ДвиженияДокумента) Экспорт
хмлДвиженияДокумента = ДвиженияДокумента
.getElementsByTagName("ДвиженияДокумента").item(0);
// обход наборов движений
хмлВыбНаборЗаписей = хмлДвиженияДокумента.childNodes;
Для й = 0 По хмлВыбНаборЗаписей.length - 1 Цикл
хмлНаборЗаписей = хмлВыбНаборЗаписей.item(й);
ВыпМодуль = СоздатьОбъект("ВыполняемыйМодуль");
// назначение контекста модуля документа
ВыпМодуль.НазначитьКонтекст(Конт);
// объявление регистра накопления
ВыпМодуль.УстановитьМодуль("Рег = Регистр."
+ хмлНаборЗаписей.tagName);
ВыпМодуль.КомпилироватьМодуль();
ВыпМодуль.ВыполнитьМодуль();
// передача регистра в контекст глобального модуля
Рег = ВыпМодуль.Рег;
// обход записей набора
хмлВыбЗаписей = хмлНаборЗаписей.childNodes;
Для ж = 0 По хмлВыбЗаписей.length - 1 Цикл
хмлЗапись = хмлВыбЗаписей.item(ж);
Направление = 0;
// обход реквизитов записи
хмлВыбРеквизитов = хмлЗапись.childNodes;
Для к = 0 По хмлВыбРеквизитов.length - 1 Цикл
хмлРеквизит = хмлВыбРеквизитов.item(к);
Ид = хмлРеквизит.tagName;
// формирование движений
Если Ид = "Направление" Тогда
Направление = хмлРеквизит.text;
Иначе
Значение = хмлРеквизит.text;
// преобразование значения ссылочного типа
Значение = ?(Лев(Значение, 1) <> "{", Значение,
ЗначениеИзСтрокиВнутр(Значение));
Рег.УстановитьАтрибут(Ид, Значение);
КонецЕсли;
КонецЦикла;
Если Направление = 0 Тогда
Рег.ДвижениеВыполнить();
ИначеЕсли Направление = 1 Тогда
Рег.ДвижениеПриходВыполнить();
Иначе
Рег.ДвижениеРасходВыполнить();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Естественно, для использования компоненты 1С++, ее нужно подключить:
//*******************************************
// подключение внешней компоненты 1С++
ИмяФайлаКомпоненты = "1cpp.dll";
Если ЗагрузитьВнешнююКомпоненту(ИмяФайлаКомпоненты) = 0 Тогда
// исключительное сообщение:
Сообщить("Ошибка при загрузке внешней компоненты: "
+ ИмяФайлаКомпоненты, "!");
КонецЕсли;
Примечание
Помимо возможности отредактировать движения документов без их перепроведения, универсальная обработка записи движений дает возможность каким то образом структурировать саму подсистему учета. Позволяет заменить правку несвязных и «разбросанных» по разным модулям процедур формирования движений документов редактированием данных некоторой общей структуры, представленной в наглядном и удобном для этого виде.