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