В каких случаях это пригодится:
- Массовое исправление существующих движений после обнаружения ошибки.
- Исправление движений в закрытом периоде.
- Заполнение движениями нового пустого регистра.
- Проведение документа, проведение которого из интерфейса невозможно.
- Перепроведение документов после изменения одного из параметров учета.
В 1С есть возможность записывать движения сразу в регистр. И основной трудностью здесь является получение таблицы с движениями документа, которые будут записаны. Один из самых популярных и универсальных методов заключается в следующем:
- Начинаем транзакцию
- Проводим документ
- Сохраняем нужные движения во временную таблицу
- Отменяем транзакцию
- Помещаем движения из временной таблицы в регистр.
Однако, у этого метода есть недостатки.
Во-первых, поскольку требуется проведение документа, срабатывают все процедуры с этим связанные. Проверка заполнения, подписки на события и т.п. Следовательно, это очень замедляет проведение. Особенно если это старая база и документов несколько сотен тысяч.
Во-вторых, если при проведении документ не прошел какую-либо проверку - проведения не будет. Причем движения то нам может быть нужно обновить по совсем незначительному регистру, но при этом их мы не получим вообще.
Способ, который я предлагаю, основан на типовом алгоритме проведения, принятом в большинстве "больших" документов типовых конфигураций. По крайней мере документов УТ и ERP, почти наверняка КА и УХ и, вероятно, БП. Если вы внимательно изучите их модули объектов и обратите внимание на проведение, то заметите сходство. Это сходство я и предлагаю использовать. В общем виде алгоритм выглядит так:
- Инициализация таблиц для движений
- Заполнение их с использованием менеджера документа
- Помещение движений в регистры
И его реализация в виде кода:
ТипДокумента = "ЗаказКлиента";
Документ = Документы[ТипДокумента].НайтиПоНомеру("0000-000001", ТекущаяДатаСеанса());
МенеджерРегистров = РегистрыНакопления;
ИмяРегистра = "РасчетыСКлиентами";
ОбменДаннымиЗагрузка = Истина;
ДокОбъект = Документ.ПолучитьОбъект();
// Инициализация дополнительных свойств
ПроведениеСерверУТ.ИнициализироватьДополнительныеСвойстваДляПроведения(Документ, ДокОбъект.ДополнительныеСвойства, РежимПроведенияДокумента.Неоперативный);
// Выполнение запросов и получение данных о движениях
Документы[ТипДокумента].ИнициализироватьДанныеДокумента(Документ, ДокОбъект.ДополнительныеСвойства);
Если Не ДокОбъект.ДополнительныеСвойства.ТаблицыДляДвижений.Свойство("Таблица" + ИмяРегистра) Тогда
Сообщить("Регистр " + ИмяРегистра + " пропущен. Движения по нему не формируются при проведении документа.");
Возврат;
КонецЕсли;
Таблица = ДокОбъект.ДополнительныеСвойства.ТаблицыДляДвижений["Таблица" + ИмяРегистра];
НаборЗаписей = МенеджерРегистров[ИмяРегистра].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокОбъект.Ссылка);
НаборЗаписей.Загрузить(Таблица);
НаборЗаписей.ОбменДанными.Загрузка = ОбменДаннымиЗагрузка;
НаборЗаписей.Записать();
Интерфейсная реализация будет зависеть от конкретных целей которые стоят перед разработчиком. Файл обработки, прикрепленный к статье, не несет в себе важных особенностей, без которых невозможно воспользоваться методом. Есть небольшой задел универсальности, но повторить ее не составит трудности любому программисту умеющему работать с метаданными.
Тестировалось на платформе 8.3.15.1565 и конфигурации 1С:ERP 2.4.10.89.