Проведение всех документов в конфигурациях УТ 11, КА 2.4, ЕРП 2.4 построено по одному и томе же принципу, который хорошо описан тут: https:// /ut11-articles/2017-09-07-documents-posting-scheme/
Я не буду повторяться, так как цель данной статьи не описание механизмов проведения, а возможные способы доработки этих механизмов. Приведу лишь краткую выжимку, чтобы далее было понятно, о чем идет речь.
Оглавление
- Типовой механизм проведения документов
- Добавление новых движений по регистрам
- Добавление движений по новым регистрам, используя механизм локализации и расширений
- Внесение изменений в существующие движения
- Механизм локализации в типовых документах
Типовой механизм проведения документов
ПроведениеСерверУТ.ИнициализироватьДополнительныеСвойстваДляПроведения - настройка и инициализация дополнительных параметров, которые необходимы для создания движений по регистрам.
Документы.<Имя документа>.ИнициализироватьДанныеДокумента - обращение к модулю менеджера документа, для формирования структуры с таблицами движений. Поля таблиц четко соответствуют полям таблиц регистров.
- ЗаполнитьПараметрыИнициализации – формирование запроса к основной таблице документа, обход выборки и установка значений параметров по всем необходимым реквизитам документа.
- ТекстЗапросаТаблица<Имя регистра> - формирование текстов запросов для заполнения всех таблиц движений, которые будут перенесены в регистры.
- <Имя документа>Локализация.ДополнитьТекстыЗапросовПроведения – процедура, в которой можно дополнить тексты запросов и задать дополнительные параметры.
- ПроведениеСерверУТ.ИнициализироватьТаблицыДляДвижений – компонуется текст запроса, формируется результат, создаются таблицы движений.
ПроведениеСерверУТ.ПодготовитьНаборыЗаписейКРегистрацииДвижений – процедура, необходимость которой у меня вызывает много вопросов. В первую очередь происходит очистка наборов записей движений документа, что актуально только для «толстого» клиента. Далее происходит выборочная установка свойства «Записывать = Истина» для всех регистров, по которым будут сформированы движения. Это действие избыточное, так как в последующих процедурах данное свойство будет установлено отдельно для всех необходимых регистров.
<Имя общего модуля>.Отразить<Имя регистра> - перенос данных из сформированных таблиц в наборы записей регистров. Также устанавливается свойство наборов записей «Записывать = Истина».
СформироватьСписокРегистровДляКонтроля - формируется и записывается в дополнительные свойства документа массив с регистрами, по которым требуется выполнять контроль результатов проведения.
<Имя документа>Локализация.ОбработкаПроведения - процедура, в которой можно до заполнить какие-либо наборы записей регистров или заполнить новые наборы.
ПроведениеСерверУТ.ЗаписатьНаборыЗаписей – запись всех наборов записей регистров в базу данных, в которых установлено свойство «Записывать = Истина». Для всех регистров из списка регистров для контроля устанавливается дополнительное свойство набора записей «РассчитыватьИзменения». Далее в модулях наборов записей регистров происходит формирование временных таблиц с изменениями записей до и после записи набора. Дополнительно, в структуру «СтруктураВременныеТаблицы» заносятся данные о наличие записей во временных таблицах с изменениями.
ЗапасыСервер.СформироватьРезервыПоТоварамОрганизаций – (для документов, которые участвуют в товародвижении) расчет необходимых резервов и формирование записей в регистре «Резервы товаров организаций», для работы механизма Интеркампани. Более подробно о работе данного механизма смотрите здесь и здесь.
ПроведениеСерверУТ.ВыполнитьКонтрольРезультатовПроведения – Проверяется наличие не пустых временных таблиц с изменениями записей регистров в структуре «СтруктураВременныеТаблицы». Для всех регистров, по которым есть изменения, формируются запросы для проверки остатков. Далее происходит обход результатов выполнения результирующего запроса, и формируются сообщения об ошибках проведения:
СообщитьОбОшибкахПроведенияПоРегистру<Имя регистра>(Объект, Отказ, Результат);
ПроведениеСерверУТ.ОчиститьДополнительныеСвойстваДляПроведения – очищается менеджер временных таблиц:
ДополнительныеСвойства.ДляПроведения.СтруктураВременныеТаблицы.МенеджерВременныхТаблиц.Закрыть();
Добавление новых движений по регистрам
Добавление новых движений в проведение типовых документов можно выполнить несколькими, различными способами:
- Создать подписку на событие «ОбработкаПроведения» и выполнить все необходимые действия в ней (для этого все-таки придется «снять с замка» основную конфигурацию, однако обновление можно будет выполнить в автоматическом режиме).
- Добавить в расширении конфигурации обработку события «ОбработкаПроведения». Этот способ очень похож на предыдущий. Плюсом является то, что основная конфигурация остается без изменений.
- Использовать процедуры локализации типовых документов для точечного внесения изменений. Процедуры можно изменять как в основной конфигурации, так и добавлять их в расширение.
Общим минусом первого и второго вариантов является то, что необходимо повторить в подписке на событие или расширении всю типовую последовательность процедур.
Во-первых, это достаточно трудоемко. Во-вторых, может получиться дублирование выполнения некоторых операций. Например, заполнение параметров инициализации для запроса или формирование движений по регистру «Активы и пассивы».
Третий вариант, на мой взгляд, является наиболее оптимальным с точки зрения минимизации дополнительного кода и максимального использования типовых механизмов. Особенно, если использовать механизм расширений. Рассмотрим его более подробно.
Добавление движений по новым регистрам, используя механизмы локализации и расширений
Используя данные механизмы можно точечно внести необходимые изменения. Объем нового кода будет минимальным, как и в случае внесения изменений непосредственно в основную конфигурацию. При этом, используя расширения, конфигурацию можно оставить полностью без изменений.
Первая процедура, которая нам необходима:
<Имя документа>Локализация.ДополнитьТекстыЗапросовПроведения (Запрос, ТекстыЗапроса, Регистры);
Здесь можно сформировать необходимое количество запросов для формирования движений по новым регистрам, и добавить их к общему массиву запросов, переданному в качестве параметра.
Внимание. Если требуется задать дополнительные параметры для результирующего запроса, необходимо дополнительно добавить в расширение процедуру модуля менеджера документа «ЗаполнитьПараметрыИнициализации». Если не использовать расширения, придется вносить изменения в модуль менеджера документа.
Вторая процедура локализации, которую требуется доработать:
Имя документа>Локализация.ОбработкаПроведения (ЭтотОбъект, Отказ, РежимПроведения);
Процедура вызывается перед записью сформированных таблиц движений в наборы записей регистров. В ней можно перенести новые сформированные таблицы движений в новые регистры:
Таблица = ДополнительныеСвойства.ТаблицыДляДвижений.Таблица<Имя регистра>;
Если Отказ ИЛИ Таблица.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Движения.<Имя регистра>.Записывать = Истина;
Движения.<Имя регистра>.Загрузить(Таблица);
Внимание. Следует не забывать включать новые регистры в список движений документа. Начиная с версии платформы 8.3.12 – это можно выполнить в расширении конфигурации.
Если для проведения по новым регистрам требуется выполнять контроль результатов проведения, необходимо дополнительно выполнить следующие действия:
Дополнить массив регистров для контроля в той же процедуре локализации:
ДополнительныеСвойства.ДляПроведения.РегистрыДляКонтроля. Добавить(Движения.<Имя регистра>);
Обработать событие «ПриЗаписи» в модуле записей регистра, для формирования таблицы изменений:
СтруктураВременныеТаблицы = ДополнительныеСвойства.ДляПроведения.СтруктураВременныеТаблицы;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Регистратор", Отбор.Регистратор.Значение);
Запрос.МенеджерВременныхТаблиц = СтруктураВременныеТаблицы.МенеджерВременныхТаблиц;
Запрос.Текст = «
…
|ПОМЕСТИТЬ Движения<Имя регистра>Изменение
…»;
Выборка = Запрос.ВыполнитьПакет()[0].Выбрать();
Выборка.Следующий();
СтруктураВременныеТаблицы.Вставить("Движения<Имя регистра>Изменение", Выборка.Количество > 0);
Дополнить процедуру:
ПроведениеСерверУТ.ВыполнитьКонтрольРезультатовПроведения (ЭтотОбъект, Отказ);
по следующему шаблону:
ПакетЗапросов = Новый Запрос;
МассивКонтролей = Новый Массив;
ТекстЗапроса = "";
Если ЕстьИзмененияВТаблице(ДанныеТаблиц," Движения<Имя регистра>Изменение") Тогда
МассивКонтролей.Добавить(Врег("<Имя регистра>"));
ТекстЗапроса = ТекстЗапроса + "<Текст контроля>";
КонецЕсли;
Если МассивКонтролей.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ПакетЗапросов.Текст = ТекстЗапроса;
ПакетЗапросов.МенеджерВременныхТаблиц = ДанныеТаблиц.МенеджерВременныхТаблиц;
МассивРезультатов = ПакетЗапросов.ВыполнитьПакет();
Итератор = -1;
Для Каждого Результат Из МассивРезультатов Цикл
Итератор = Итератор + 1;
Если Результат.Пустой() Тогда
Продолжить;
КонецЕсли;
ИмяКонтроля = МассивКонтролей[Итератор];
Если ИмяКонтроля = Врег("<Имя регистра>") Тогда
СообщитьОбОшибкахПроведенияПоРегистру<Имя регистра> (Объект, Отказ, Результат);
КонецЕсли;
КонецЦикла;
Если Отказ Тогда
Если Объект.ДополнительныеСвойства.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
ТекстСообщения = НСтр("ru = 'Проведение не выполнено %ПредставлениеОбъекта%'");
Иначе
ТекстСообщения = НСтр("ru = 'Отмена проведения не выполнена %ПредставлениеОбъекта%'");
КонецЕсли;
ТекстСообщения = СтрЗаменить(ТекстСообщения, "%ПредставлениеОбъекта%", Строка(Объект));
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения, Объект);
КонецЕсли;
Примечание. Все выше перечисленные действия, также можно выполнить в расширении конфигурации.
Внесение изменений в существующие движения
Все корректировки и дополнения будем выполнять в расширении, так как наша задача оставить основную конфигурацию без изменений.
Исходя из общего описания типового алгоритма проведения документов, можно сделать вывод, что вносить изменения в механизм формирования движений можно либо на этапе формирования текстов запросов. Это процедуры модуля менеджера документа «ТекстЗапросаТаблица<Имя регистра>». Либо в таблицах сформированных движений до их переноса в наборы записей регистров «ДополнительныеСвойства.ТаблицыДляДвижений.Таблица<Имя регистра>».
Рассмотрим более подробно различные варианты корректировки:
Полная замена функции, формирующей текст запроса
Для этого нужно добавить в расширение функцию «ТекстЗапросаТаблица<Имя регистра>» модуля менеджера документа с аннотацией «Вместо».
Имеет смысл пользоваться данным способом, если необходимо выполнить кардинальные изменения относительно базового варианта. После обновления информационной базы необходимо будет проанализировать изменения в типовом коде, и учесть их в переопределенной функции.
Дополнение или изменение сформированного текста запроса
Для этого нужно добавить в расширение процедуру «<Имя документа>Локализация.ДополнитьТекстыЗапросовПроведения» с любой аннотацией.
В переопределенной процедуре можно заменить определенный фрагмент текста запроса, либо добавить новый (например, объединение с новым запросом). Внося изменения таким способом, после обновления конфигурации основной базы необходимо проверять, чтобы текст заменяемого фрагмента кода не был изменен, а поля добавленного объединением запроса, соответствовали полям основного.
Например, для документа «Реализация товаров и услуг» в формировании движений по регистру «Свободные остатки», необходимо исключить многооборотную тару.
Необходимо написать следующий код:
ТекстыЗапроса[«СвободныеОстатки»] = СтрЗаменить(ТекстыЗапроса[«СвободныеОстатки»],
«ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.МногооборотнаяТара)»,
«NULL»);
Изменение данных в уже сформированной таблице движений до ее переноса в набор записей регистра
Для этого нужно добавить в расширение процедуру «ПроведениеСерверУТ.ИнициализироватьТаблицыДляДвижений» с аннотацией «После».
Данный способ корректировки удобен тем, что не требуется разбираться и потом отслеживать изменения в текстах запросов. Его можно использовать для простановки либо изменения каких-либо значений в сформированных наборах записей.
Например, в движениях документа «Реализация товаров и услуг» по регистру «Расчеты с клиентами» требуется перезаполнить реквизит «ДатаПлатежа» значением даты документа для всех строк.
Необходимо реализовать следующий код:
Для Каждого СтрокаРасчетов Из Таблицы.ТаблицаРасчетыСКлиентами Цикл
СтрокаРасчетов.ДатаПлатежа = Запрос.Параметры.Период;
КонецЦикла
В описанном примере подставляемое значение было взято из сформированных ранее параметров запроса. Следует иметь в виду, если для получения требуемых значений нужно обращаться к базе данных, лучше вносить изменения в тексты запросов.
Механизм локализации в типовых документах
В конце статьи, хочу обратить Ваше внимание на то, что используя механизм локализации, можно вносить изменения не только в алгоритмы проведения документов. Можно дополнять все основные обработчики модуля объекта документа: «ОбработкаЗаполнения», «ПередЗаписью», «ПриЗаписи»,… а также некоторые процедуры модуля менеджера документа.
На заметку. Если Вы используете расширения, имеет смысл использовать только выше описанные и приведенные ниже процедуры, так как остальные можно заменить непосредственным добавлением в расширение требуемого события или метода:
- ОбработкаУдаленияПроведения
- СформироватьКомплектПечатныхФорм
На этом все, спасибо Вам за внимание. Надеюсь, статья оказалась полезной. Буду рад увидеть в комментариях Ваши дополнения или пожелания на счет тем для новых статей.
Другие мои статьи по описанию различных механизмов УТ 11, КА 2, ЕРП 2»