При работе с типовыми конфигурациями на базе 1С:ERP и 1С:Комплексная автоматизация 2.4 программисты часто сталкиваются с задачей автоматизации заполнения реквизитов, которые обычно заполняются пользователем вручную через вспомогательные формы. Одной из таких задач является заполнение таблицы Платежно-расчетные документы в документе СчетФактураВыданный, а также сопутствующее заполнение реквизитов контрагента. Рассмотрим подробно, как реализовать этот механизм правильно, избежав типичных ошибок начинающих разработчиков.
Типичная ошибка при попытке автоматизировать заполнение — это попытка программно «нажать» на кнопку формы или вызвать процедуру, расположенную в модуле формы документа. Разберем, почему это приводит к ошибке Интерактивные операции недоступны. Когда документ записывается или проводится, выполнение кода происходит на сервере в контексте транзакции базы данных. В этот момент интерфейсные объекты, такие как «Форма», недоступны. Попытка вызвать ПолучитьФорму() или обратиться к реквизитам открытой формы из серверного модуля объекта неизбежно приведет к исключению.
Проанализируем ситуацию: логика заполнения платежных документов в типовых решениях часто «размазана» между модулем формы и модулем менеджера. В таких случаях часто помогает подключение внешней обработки заполнения из расширения. Наша задача — вычленить полезный алгоритм и перенести его в Модуль объекта или в Расширение модуля объекта, используя только данные самого документа.
Для реализации автоматического заполнения лучше всего использовать механизм расширений. Мы будем перехватывать событие ПередЗаписью. Выбор этого события обоснован тем, что при проведении (событие ОбработкаПроведения) модифицировать реквизиты самого объекта уже поздно или не рекомендуется, так как объект уже находится в процессе записи движений. Заполняя данные ПередЗаписью, мы гарантируем, что в базу попадут уже актуальные сведения.
Рассмотрим пошагово, какие данные нам понадобятся для успешного вызова типового метода заполнения:
Объект.Организация.ДокументыОснования.ПлатежноРасчетныеДокументы, которую нам нужно подготовить и заполнить, используя в том числе и дополнительные реквизиты табличных частей.Выясним причину, по которой метод ЗаполнитьПлатежноРасчетныеДокументы требует массив оснований. Система должна проанализировать связанные платежи (например, через регистр «Расчеты с клиентами»), чтобы понять, какие именно платежки закрыли долг по данной реализации. Поэтому первым делом мы должны собрать все документы-основания в один массив.
Посмотрим на пример кода, который можно разместить в расширении модуля объекта СчетФактураВыданный. Мы используем аннотацию &После для процедуры ПередЗаписью, чтобы дополнить стандартное поведение системы.
&После("ПередЗаписью")
Процедура ПРД_ПередЗаписьюПосле(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что документ не помечается на удаление
Если ЭтотОбъект.ПометкаУдаления Тогда
Возврат;
КонецЕсли;
// Не заполняем ПРД, если они уже заполнены вручную (опционально)
Если ЭтотОбъект.ПлатежноРасчетныеДокументы.Количество() > 0 Тогда
// Здесь можно добавить логику проверки: нужно ли перезаполнять
КонецЕсли;
// 1. Формируем массив документов-оснований
МассивОснований = Новый Массив;
Для Каждого СтрокаОснование Из ЭтотОбъект.ДокументыОснования Цикл
Если ЗначениеЗаполнено(СтрокаОснование.ДокументОснование) Тогда
МассивОснований.Добавить(СтрокаОснование.ДокументОснование);
КонецЕсли;
КонецЦикла;
Если МассивОснований.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// 2. Подготавливаем таблицу для заполнения (выгружаем структуру)
ТаблицаПРД = ЭтотОбъект.ПлатежноРасчетныеДокументы.Выгрузить();
// 3. Вызываем стандартный метод менеджера документа для заполнения таблицы
// В КА 2.4 этот метод часто находится в модуле менеджера
Документы.СчетФактураВыданный.ЗаполнитьПлатежноРасчетныеДокументы(
ТаблицаПРД,
МассивОснований,
ЭтотОбъект.Организация
);
// 4. Загружаем результат обратно в табличную часть объекта
ЭтотОбъект.ПлатежноРасчетныеДокументы.Загрузить(ТаблицаПРД);
КонецПроцедуры
Рассмотрим подробнее работу метода ЗаполнитьПлатежноРасчетныеДокументы. Этот метод является экспортным в модуле менеджера СчетФактураВыданный. Он инкапсулирует в себе сложную логику поиска платежей. Если счет-фактура выписан на аванс, он возьмет данные непосредственно из документа оплаты. Если на реализацию — он попытается найти зачет аванса. Используя именно этот метод, мы сохраняем единство алгоритмов с типовой конфигурацией, что важно для корректного формирования печатных форм и отчетности по НДС.
Проанализируем ситуацию, когда документ создается программно, например, при автоматической генерации счетов-фактур обработкой «Формирование счетов-фактур». В этом случае наш код в ПередЗаписью отработает идеально. Однако стоит помнить о некоторых нюансах:
ДополнительныеСвойства или проверять наличие флага «Изменено вручную», если таковой предусмотрен в логике вашей компании.Для более гибкого управления заполнением можно использовать коллекцию ДополнительныеСвойства. Например, если мы хотим, чтобы автоматическое заполнение срабатывало только при создании документа, а при последующих изменениях (например, когда пользователь меняет ответственного) таблица ПРД не перезаполнялась. Для этого в процедуре ОбработкаЗаполнения можно установить флаг, а в ПередЗаписью его проверять.
Разберем пример установки флага:
// В модуле объекта или расширении
Процедура ПРД_ОбработкаЗаполненияПосле(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
ЭтотОбъект.ДополнительныеСвойства.Вставить("НужноЗаполнитьПРД", Истина);
КонецПроцедуры
И модифицируем наш основной код:
&После("ПередЗаписью")
Процедура ПРД_ПередЗаписьюПосле(Отказ, РежимЗаписи, РежимПроведения)
Если ЭтотОбъект.ДополнительныеСвойства.Свойство("НужноЗаполнитьПРД")
И ЭтотОбъект.ДополнительныеСвойства.НужноЗаполнитьПРД Тогда
// Выполняем заполнение, как описано выше...
// После успешного заполнения флаг можно снять
ЭтотОбъект.ДополнительныеСвойства.Удалить("НужноЗаполнитьПРД");
КонецЕсли;
КонецПроцедуры
Подводя итог, можно сказать, что ключ к решению задачи автоматического заполнения в 1С:КА 2.4 лежит в отказе от работы с экранными формами в пользу работы с данными объекта и методами модулей менеджеров. Это делает код устойчивым к ошибкам «Интерактивные операции недоступны» и позволяет системе работать корректно как при ручном вводе, так и при автоматической генерации документов.