Как отловить программное добавление строки в табличную часть управляемой формы в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке и доработке документов на управляемых формах часто возникает задача перехватить или проанализировать момент, когда в табличную часть добавляются новые строки. Типичный сценарий — заполнение документа через специализированную форму подбора номенклатуры. Разработчик пытается установить точку останова в стандартных событиях таблицы или формы (таких как ОбработкаВыбора, ПередНачаломДобавления, ОбработкаОповещения), однако отладчик в них не останавливается. Рассмотрим подробнее архитектурные причины такого поведения платформы 1С:Предприятие 8 и разберем практические способы решения этой задачи.

Почему стандартные события формы и таблицы не срабатывают

Проанализируем механику работы управляемой формы. Коллекция строк таблицы на форме представляет собой объект ДанныеФормыКоллекция, а в модуле объекта — обычную табличную часть. Платформа строго разграничивает интерактивные действия пользователя и программные манипуляции с данными:

  1. События элементов формы ориентированы на интерактив: события таблицы (ПередНачаломДобавления, ПриОкончанииРедактирования, ОбработкаВыбора) вызываются платформой исключительно тогда, когда пользователь физически нажимает кнопку добавления строки на командной панели или выбирает значение непосредственно в поле ввода ячейки. Программные вызовы методов Добавить(), Вставить(), Загрузить() эти события не инициируют.
  2. Отсутствие встроенных событий у коллекций: у объекта ДанныеФормыКоллекция и у табличных частей прикладных объектов в платформе 1С отсутствуют события уровня «ПриДобавленииСтроки» или «ПриИзмененииСостава».
  3. Асинхронность и механизм обратных вызовов: в современных управляемых формах форма подбора чаще всего открывается через метод ОткрытьФорму() с параметром ОписаниеОповещения. При завершении выбора форма подбора не генерирует оповещения общего назначения, а сразу передает результат в клиентскую процедуру обратного вызова (callback).

Способ 1. Точка останова в процедуре завершения подбора (Callback)

Разберем по шагам, как найти точное место в коде формы, где происходит перенос строк из формы подбора в документ:

  1. Открываем модуль управляемой формы документа и находим процедуру команды, открывающей подбор (например, ПодборТоваров или ОбработкаКомандыПодбор).
  2. Находим вызов метода ОткрытьФорму() и смотрим, какой обработчик оповещения передан в параметрах.
  3. Находим процедуру обратного вызова (например, ПодборТоваровЗавершение) и вызываемую из нее серверную процедуру заполнения табличной части.

Посмотрим на пример стандартной реализации обработки подбора:


&НаКлиенте
Процедура ПодборТоваров(Команда)
    
    Оповещение = Новый ОписаниеОповещения("ПодборТоваровЗавершение", ЭтотОбъект);
    ПараметрыФормы = Новый Структура("РежимВыбора", Истина);
    
    ОткрытьФорму("Обработка.ПодборНоменклатуры.Форма.Форма", ПараметрыФормы, ЭтотОбъект,,,, Оповещение);
    
КонецПроцедуры

&НаКлиенте
Процедура ПодборТоваровЗавершение(РезультатВыбора, ДополнительныеПараметры) Экспорт
    
    Если РезультатВыбора = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Именно здесь или в серверной процедуре ставится точка останова
    ПеренестиДанныеПодбораНаСервере(РезультатВыбора);
    
КонецПроцедуры

&НаСервере
Процедура ПеренестиДанныеПодбораНаСервере(РезультатВыбора)
    
    Для Каждого СтрокаВыбора Из РезультатВыбора Цикл
        НоваяСтрока = Объект.Товары.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаВыбора);
    КонецЦикла;
    
КонецПроцедуры

Важно: для отладки программного добавления строк точку останова необходимо ставить непосредственно внутри процедуры ПодборТоваровЗавершение на клиенте или внутри цикла метода ПеренестиДанныеПодбораНаСервере на сервере.

Способ 2. Перехват процедуры через расширение конфигурации

Если необходимо добавить собственную логику обработки вновь добавленных строк без изменения типовой конфигурации, воспользуемся механизмом расширений:

  1. Добавляем форму документа в расширение конфигурации.
  2. Находим процедуру, которая обрабатывает результат выбора из формы подбора или заполняет табличную часть на сервере.
  3. Подключаем к ней метод расширения с директивой &После или &Вместо.

Посмотрим на пример перехвата заполнения через расширение:


&Вместо("ПеренестиДанныеПодбораНаСервере")
Процедура Расш_ПеренестиДанныеПодбораНаСервере(РезультатВыбора)
    
    // Выполняем базовую логику заполнения
    ПродолжитьВызов(РезультатВыбора);
    
    // Логика постобработки добавленных строк
    Для Каждого СтрокаВыбора Из РезультатВыбора Цикл
        // Обработка и валидация добавленных позиций
    КонецЦикла;
    
КонецПроцедуры

Способ 3. Фиксация добавленных строк по идентификаторам

В ситуации, когда процесс заполнения полностью инкапсулирован внутри сложного типового механизма и прямого доступа к конкретным строкам нет, выясним факт появления новых строк с помощью уникальных идентификаторов элементов коллекции ДанныеФормыКоллекция. Метод ПолучитьИдентификатор() возвращает уникальный номер строки в текущем сеансе формы.

Разберем алгоритм выявления новых строк:


&НаКлиенте
Процедура ВыполнитьКонтрольДобавления()
    
    // Запоминаем идентификаторы существующих строк перед операцией
    МассивИдентификаторов = Новый Массив;
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        МассивИдентификаторов.Добавить(СтрокаТЧ.ПолучитьИдентификатор());
    КонецЦикла;
    
    // ... Вызов операции подбора или заполнения ...
    
    // После возврата управления определяем, какие строки являются новыми
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        Если МассивИдентификаторов.Найти(СтрокаТЧ.ПолучитьИдентификатор()) = Неопределено Тогда
            // Найдена программно добавленная строка
            ИдентификаторНовойСтроки = СтрокаТЧ.ПолучитьИдентификатор();
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Способ 4. Валидация на уровне модуля объекта

Если цель перехвата заключается в проверке корректности заполнения реквизитов (например, контроль цен, остатков или заполненности аналитики), лучшей практикой является перенос контроля на уровень модуля объекта в обработчики ПередЗаписью или ОбработкаПроверкиЗаполнения. Это гарантирует, что данные будут проверены независимо от того, каким образом они попали в документ — интерактивным вводом, через форму подбора или внешней обработкой.

← На главную