Предисловие
Думаю, многие задумывались о том, что механизм быстрого формирования движений по регистрам, предлагаемый платформой 1С:Предприятие 8, находится где-то между уровнем «первый раз открыл конфигуратор» и «уверенный junior». Идеал, к которому стоит стремиться при разработке своих учётных конфигураций, — это подход, реализованный в типовых решениях. Но что делать, когда мы пишем всё с нуля, а не наследуем готовую базу?
Я столкнулся с этим вопросом, когда начал активно разрабатывать мини конфигурации на заказ. При этом опыт работы с типовыми конфигурациями у меня уже был. Посидев в отладчике пару дней, я проанализировал и немного унифицировал типовой алгоритм проведения, «выдранный» из БГУ 2. Результатом этой работы стала простая, но гибкая система, которой я теперь пользуюсь сам и хочу поделиться с вами.
Не сочтите нижесказанное за холивар, это всего лишь мнение автора, которое может не совпадать с вашим. В любом случае продуктивная критика и обсуждения приветствуются!
Как выглядит базовое проведение (конструктор)
Стандартный подход, который предлагает платформа, выглядит примерно так:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
//{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
// регистр ЗапасыНаСкладах Расход
Движения.ЗапасыНаСкладах.Записывать = Истина;
Для Каждого ТекСтрокаЗапасы Из Запасы Цикл
Движение = Движения.ЗапасыНаСкладах.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Организация = Организация;
Движение.Склад = Склад;
Движение.Номенклатура = ТекСтрокаЗапасы.Номенклатура;
Движение.ЕдиницаИзмерения = ТекСтрокаЗапасы.ЕдиницаИзмерения;
Движение.Количество = ТекСтрокаЗапасы.Количество;
КонецЦикла;
//}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
КонецПроцедуры
Думаю, те, кто открывал нетленные рукописи товарища Радченко или хотя бы конфигуратор, знакомы с этим механизмом.
- Это работает.
- Но выглядит не очень солидно, а главное — при масштабировании проекта такой код становится источником проблем: дублирование, сложность изменений, риск ошибок.
Как выглядит улучшенное проведение
Теперь посмотрим на тот же документ, но реализованный через мой подход.
Модуль объекта
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
ПроведениеДокументов.ИнициализироватьДополнительныеСвойстваДляПроведения(Ссылка, ДополнительныеСвойства);
Документы.РасходнаяНакладная.ИнициализироватьТаблицыПроводок(Ссылка, ДополнительныеСвойства);
ТаблицыПроводок = ДополнительныеСвойства.ТаблицыДляДвижений;
ПроведениеДокументов.ПровестиДокумент(ЭтотОбъект, "ЗапасыНаСкладах", ТаблицыПроводок);
ПроведениеДокументов.ЗаписатьНаборыЗаписей(ЭтотОбъект);
ПроведениеДокументов.КонтрольОстатков();
КонецПроцедуры
Процедура ОбработкаУдаленияПроведения(Отказ)
ПроведениеДокументов.ОчиститьДвиженияДокумента(ЭтотОбъект);
КонецПроцедуры
Модуль менеджера
Процедура ИнициализироватьТаблицыПроводок(ДокументСсылка, ДополнительныеСвойства) Экспорт
ВидДвижения_ЗапасыНаСкладах = ПроведениеДокументов.ВидДвиженияТаблицыДокумента(ДокументСсылка, "ЗапасыНаСкладах");
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = ДополнительныеСвойства.ДляПроведения.СтруктураВременныеТаблицы.МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
| РасходнаяНакладнаяЗапасы.Ссылка.Дата КАК Период,
| РасходнаяНакладнаяЗапасы.Ссылка.Организация КАК Организация,
| РасходнаяНакладнаяЗапасы.Ссылка.Склад КАК Склад,
| РасходнаяНакладнаяЗапасы.Номенклатура КАК Номенклатура,
| РасходнаяНакладнаяЗапасы.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| СУММА(РасходнаяНакладнаяЗапасы.Количество) КАК Количество,
| &ВидДвижения_ЗапасыНаСкладах КАК ВидДвижения
|ПОМЕСТИТЬ ЗапасыНаСкладах
|ИЗ
| Документ.РасходнаяНакладная.Запасы КАК РасходнаяНакладнаяЗапасы
|ГДЕ
| РасходнаяНакладнаяЗапасы.Номенклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Запас)
| И РасходнаяНакладнаяЗапасы.Ссылка = &ДокументСсылка
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяЗапасы.ЕдиницаИзмерения,
| РасходнаяНакладнаяЗапасы.Ссылка.Дата,
| РасходнаяНакладнаяЗапасы.Номенклатура,
| РасходнаяНакладнаяЗапасы.Ссылка.Организация,
| РасходнаяНакладнаяЗапасы.Ссылка.Склад";
Запрос.УстановитьПараметр("ДокументСсылка", ДокументСсылка);
Запрос.УстановитьПараметр("ВидДвижения_ЗапасыНаСкладах", ВидДвижения_ЗапасыНаСкладах);
РезультатЗапроса = Запрос.Выполнить();
ПроведениеДокументов.СоздатьТаблицыДвижений(ДокументСсылка, ДополнительныеСвойства);
КонецПроцедуры
Общий модуль ПроведениеДокументов содержит универсальные функции формирования, записи и контроля движений. Его реализацию я оставляю за рамками статьи, чтобы не перегружать её, но при необходимости готов поделиться в комментариях.
Как это работает?
Документ функционирует по принципу: «я знаю, какой набор данных нужно подготовить, но не знаю, как именно он будет записан в регистры». Всё, что относится к конкретному регистру, вынесено в общий модуль.
В обработке проведения документа происходит следующее:
-
Инициализация дополнительных свойств — общий модуль создаёт служебные структуры, менеджер временных таблиц и т.д.
-
Вызов процедуры модуля менеджера — в ней формируются временные таблицы с данными для движений. Каждый документ сам решает, какие данные и в каком виде он предоставит.
-
Получение таблиц проводок — после вызова все подготовленные таблицы оказываются в свойстве
ДополнительныеСвойства.ТаблицыДляДвижений. -
Проведение по регистрам — универсальная процедура читает таблицы и генерирует нужные наборы записей.
-
Запись движений — выполняется стандартная запись наборов.
-
Контроль остатков — при необходимости запускается общий механизм проверки.
Какой в этом плюс?
- Избавление от дублирования кода — логика записи движений, работы с временными таблицами и контроля остатков сосредоточена в одном месте.
- Простота внесения изменений — если нужно изменить поведение для всех регистров (например, добавить протоколирование или изменить порядок записи), правка делается в общем модуле.
- Унификация подходов — все документы в конфигурации начинают выглядеть одинаково, что упрощает онбординг новых разработчиков.
- Удобство тестирования — можно легко подменить таблицы движений и проверить логику документа изолированно.
- Гибкость — документ отвечает только за подготовку данных, а не за то, как они будут интерпретированы регистрами.
Заключение
Предложенный подход — не идеал последней инстанции и не попытка переписать типовые механизмы «с чистого листа». Это всего лишь один из возможных способов организовать проведение документов, который сложился у меня в ходе работы над небольшими заказными конфигурациями. Он показался мне достаточно удобным, чтобы поделиться им с сообществом.
Проверено на следующих конфигурациях и релизах:
- 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.10.403
Вступайте в нашу телеграмм-группу Инфостарт