При работе с электронным документооборотом (ЭДО) через модуль Контур.Диадок часто возникает необходимость кастомизировать данные, которые передаются контрагенту. Одной из типичных задач является автоматическое заполнение или изменение должностных лиц, например, поля «Отпуск разрешил» в Универсальном передаточном документе (УПД). Разберем подробно, почему стандартные события могут «не подхватываться» и как правильно реализовать эту логику в подключаемом модуле.
Прежде чем приступать к написанию кода, нам необходимо выяснить, с какой именно архитектурой модуля мы имеем дело. В экосистеме Контур.Диадок существуют две основные ветки модулей: «Стандарт» и «Универсальный». Это критически важно, так как набор доступных событий и методов в них различается.
Проанализируем способы определения версии:
СведенияОВнешнейОбработке(). Если в возвращаемой структуре в поле наименования или версии явно указано «Стандарт» — это старая ветка. В современных «Универсальных» модулях (ветка 5.x.x и выше) разработчики Контура часто опускают это уточнение в метаданных, но добавляют расширенные настройки.ЗаполнитьРеквизитыДокумента реализовано как стандартный механизм кастомизации.Рассмотрим ситуацию, с которой часто сталкиваются разработчики: обработка создана, событие прописано, но точка останова в процедуре ЗаполнитьРеквизитыДокумента не срабатывает при открытии списка документов в модуле. Выясним причину этого поведения.
Многие ошибочно полагают, что это событие отвечает за заполнение данных в таблице (журнале) документов модуля Диадок. На самом деле, жизненный цикл формирования документа выглядит иначе:
ДобавитьКолонкиВСписокДокументов и ЗаполнитьЗначенияКолонокСписка).ЗаполнитьРеквизитыДокумента. Она позволяет «перехватить» уже собранный пакет данных и изменить его перед отправкой.Вывод: Если вы хотите проверить работу кода, не смотрите на список документов. Попробуйте нажать кнопку формирования или отправки тестового документа — только тогда управление перейдет в вашу процедуру.
Допустим, нам нужно, чтобы в УПД поле «Отпуск разрешил» заполнялось не текущим пользователем системы, а ответственным лицом, указанным в специальном реквизите документа или константе. Разберем, как это сделать программно в подключаемом модуле.
В подключаемом модуле (внешней обработке) нам необходимо объявить процедуру с экспортным статусом. Посмотрим на пример кода:
Процедура ЗаполнитьРеквизитыДокумента(ДанныеДокумента, Источник, ТипДокументаДиадок) Экспорт
// Проверяем, что работаем именно с УПД (UniversalTransferDocument)
Если ТипДокументаДиадок = "UniversalTransferDocument" Тогда
// Анализируем структуру ДанныеДокумента.
// В УПД за ответственных отвечают структуры в коллекции 'Лица' или 'Подписанты'
// В зависимости от версии формата (5.01 или 5.02) структура может отличаться.
Если ДанныеДокумента.Свойство("Содержание") Тогда
// Для примера установим ФИО и Должность лица, разрешившего отпуск
ДанныеДокумента.Содержание.ДолжностьОтпускРазрешил = "Главный бухгалтер";
ДанныеДокумента.Содержание.ФИООтпускРазрешил = "Иванова Мария Ивановна";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важно помнить, что структура ДанныеДокумента является отражением формата XML, утвержденного ФНС. Поэтому имена свойств должны строго соответствовать тем, которые ожидает основной модуль Диадока для заполнения соответствующих тегов.
Чтобы основной модуль «понял», что нужно обращаться к вашей внешней обработке, необходимо правильно зарегистрировать событие. Проанализируем функцию СписокСобытий, которая должна присутствовать в вашей обработке:
Функция СписокСобытий() Экспорт
Список = Новый СписокЗначений;
// Обязательно добавляем строковое имя события
Список.Добавить("ЗаполнитьРеквизитыДокумента");
// Если нужно менять данные в списке, добавляем также эти события:
// Список.Добавить("ЗаполнитьЗначенияКолонокСписка");
Возврат Список;
КонецФункции
Если вы добавили код в процедуру ЗаполнитьРеквизитыДокумента, но забыли добавить ее название в СписокСобытий, основной модуль просто проигнорирует вашу обработку в момент генерации документа.
Поскольку подключаемый модуль запускается основным модулем через ВнешниеОбработки.Создать(), отладка может быть затруднена. Рассмотрим самый надежный способ проверить, «заходит» ли программа в ваш код:
ВызватьИсключение "Модуль подключен успешно!";.Остановить по ошибке в конфигураторе или прописывайте путь к обработке в настройках так, чтобы она не кэшировалась (переподключайте файл после изменений).Если же ваша задача заключалась не в изменении XML-файла, а в том, чтобы пользователь видел в колонке модуля Диадок фамилию того, кто разрешил отпуск, вам потребуются другие инструменты. Выясним, как работать со списком:
Во-первых, используйте ДобавитьКолонкиВСписокДокументов, чтобы создать новое поле в таблице. Во-вторых, реализуйте логику в ЗаполнитьЗначенияКолонокСписка. Рассмотрим пример:
Процедура ЗаполнитьЗначенияКолонокСписка(ДанныеСтроки, Данные1С) Экспорт
// Данные1С - это объект документа или выборка из БД
// ДанныеСтроки - структура, значения которой попадут в колонки списка
Если ТипЗнч(Данные1С) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
ДанныеСтроки.Вставить("ИмяВашейКолонки", Данные1С.Ответственный);
КонецЕсли;
КонецПроцедуры
Этот код выполняется именно в момент отрисовки списка, что и требовалось автору вопроса в исходном сообщении, если бы речь шла о визуальном представлении. Однако для корректной передачи данных контрагенту через ЭДО обязательным остается использование именно ЗаполнитьРеквизитыДокумента.
Таким образом, мы проанализировали основные этапы кастомизации модуля Контур.Диадок. Помните, что ключевым моментом является понимание того, в какой именно момент вызывается конкретное событие, и соответствие имен процедур технической документации API Диадока.