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