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