К статье
Практический материал

Разработка и Конфигурация · 13 мин

Обработка заполнения в 1С: как передать параметр

Как передать параметры в обработку заполнения табличной части 1С: ПараметрыВыполненияКоманды, ДополнительныеПараметры, примеры кода и типичные ошибки.

Обработки заполнения табличных частей — один из самых востребованных механизмов доработки типовых конфигураций 1С. Почти в каждом проекте возникает задача: заполнить табличную часть документа не стандартным способом, а по своему алгоритму — из остатков, из другого документа, по произвольному отбору. И почти сразу встает вопрос: как передать в обработку параметры, чтобы один и тот же код работал по-разному в зависимости от выбора пользователя или контекста вызова.

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

Материал ориентирован на разработчиков, работающих с БСП (библиотека стандартных подсистем) в управляемых формах. Примеры применимы к конфигурациям на базе БСП: ERP, УТ, КА, БП и другим. Для обычных форм и самописных конфигураций без БСП принципы те же, но точки подключения отличаются — об этом тоже сказано отдельно.

Как устроен механизм команд заполнения в БСП

В конфигурациях на базе БСП обработки заполнения подключаются через подсистему «Дополнительные отчеты и обработки». Разработчик создает внешнюю обработку, в модуле объекта которой описывает функцию СведенияОВнешнейОбработке. В ней регистрируется одна или несколько команд вида «ЗаполнениеОбъекта» с указанием объектов, для которых команда доступна.

Когда пользователь нажимает кнопку команды в форме документа, БСП формирует структуру ПараметрыВыполненияКоманды и вызывает экспортную процедуру ВыполнитьКоманду из модуля обработки. В простейшем случае процедура получает массив ссылок на объекты и идентификатор команды — этого достаточно, если обработка всегда делает одно и то же.

Ограничение механизма: стандартная структура параметров не содержит произвольных пользовательских полей. БСП передает ссылку на объект, идентификатор команды, тип команды, имя формы-источника и служебные данные. Все, что выходит за эти рамки, нужно передавать обходными путями, которые и разобраны ниже.

Способ 1: несколько команд с разными идентификаторами

Самый надежный способ «передать параметр» — не передавать его вовсе, а зарегистрировать отдельную команду под каждый вариант заполнения. Если обработка умеет заполнять документ тремя способами (по остаткам, по продажам за период, по типовой спецификации), регистрируются три команды: ЗаполнитьПоОстаткам, ЗаполнитьПоПродажам, ЗаполнитьПоСпецификации. В модуле обработки идентификатор команды анализируется через Если/ИначеЕсли, и для каждой ветки вызывается своя процедура со своими жестко заданными параметрами.

Преимущества подхода: команды видны пользователю как отдельные пункты меню с понятными названиями, не требуется никаких форм и диалогов, код прост и легко тестируется. Недостаток очевиден: число вариантов фиксировано на этапе разработки, а параметры «зашиты» в код. Если пользователю нужно выбирать склад или период произвольно — этот способ не подходит.

// В СведенияОВнешнейОбработке

НоваяКоманда = ТаблицаКоманд.Добавить();

НоваяКоманда.Представление = НСтр("ru = 'Заполнить по остаткам'");

НоваяКоманда.Идентификатор = "ЗаполнитьПоОстаткам";

НоваяКоманда.Использование = "ЗаполнениеФормы";

НоваяКоманда.ПоказыватьОповещение = Истина;

Маршрут решения

Как выбрать способ передачи параметров

Вариантов заполнения мало и они известны заранееЗарегистрируйте отдельную команду под каждый вариант
Пользователь должен вводить значения перед заполнением (период, склад, отбор)Используйте команду с использованием ОткрытиеФормы и собственную форму обработки
Параметры нужны программно при вызове из другого кодаПередавайте структуру через ДополнительныеПараметры при программном вызове ВыполнитьКоманду

Способ 2: команда с открытием формы для ввода параметров

Когда параметры должен задавать пользователь, в СведенияОВнешнейОбработке команде назначается использование «ОткрытиеФормы». При нажатии кнопки БСП открывает основную форму обработки и передает в нее параметры, среди которых — массив объектов (обычно в параметре с именем, заданным в свойстве команды, либо через стандартные параметры формы). На форме разработчик размещает поля ввода: период, склад, организацию, флажки режимов.

Пользователь заполняет поля и нажимает кнопку «Заполнить». В обработчике кнопки значения полей собираются в структуру и вместе со ссылкой на объект передаются в серверную процедуру заполнения. Это самый гибкий вариант: набор параметров не ограничен, можно добавить проверки заполнения обязательных полей и подсказки.

Важная деталь: при использовании «ОткрытиеФормы» объект документа, из которого вызвана обработка, может быть еще не записан. Перед заполнением следует проверить, что документ проведен или хотя бы записан, либо работать с данными формы-источника, а не с базой. Иначе обработка заполнит данные, которые пользователь потом потеряет при закрытии формы без записи.

Способ 3: ДополнительныеПараметры при программном вызове

Если обработку заполнения нужно вызвать не кнопкой из формы, а программно — из другой обработки, регламентного задания или расширения — параметры передаются напрямую через структуру. Вызывающий код формирует структуру ПараметрыВыполненияКоманды, добавляет в нее свои ключи (или вложенную структуру ДополнительныеПараметры) и вызывает ВыполнитьКоманду модуля обработки.

В модуле обработки процедура ВыполнитьКоманду должна уметь извлекать эти значения с проверкой наличия ключа: ПараметрыВыполненияКоманды.Свойство("Склад", Склад). Такой код устойчив и к штатному вызову из БСП (ключа нет — используется значение по умолчанию), и к программному вызову с параметрами.

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт

Период = Неопределено;

Склад = Неопределено;

ПараметрыВыполненияКоманды.Свойство("Период", Период);

ПараметрыВыполненияКоманды.Свойство("Склад", Склад);

Если Период = Неопределено Тогда

Период = ТекущаяДатаСеанса();

КонецЕсли;

// ... далее логика заполнения

КонецПроцедуры

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

Передача параметров в типовой обработчик ОбработкаЗаполнения документа

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

При вводе на основании в ДанныеЗаполнения обычно приходит ссылка на документ-основание. При открытии формы с параметрами структура из параметра «ЗначенияЗаполнения» также оказывается в ДанныеЗаполнения. В модуле объекта проверяют тип: если это структура — извлекают нужные ключи, если ссылка — заполняют по основанию.

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)

Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда

Если ДанныеЗаполнения.Свойство("Склад") Тогда

Склад = ДанныеЗаполнения.Склад;

КонецЕсли;

КонецЕсли;

КонецПроцедуры

Ограничение: через ДанныеЗаполнения передаются только сериализуемые значения, которые «переживут» передачу между клиентом и сервером. Сложные объекты (таблицы значений с данными СКД, COM-объекты) так передать нельзя — их нужно формировать на сервере уже внутри обработчика.

Проверка результата и типичные ошибки

После внедрения передачи параметров проверку стоит строить на трех уровнях. Первый — сам вызов: обработчик получил именно те значения, которые ввел пользователь или передал вызывающий код. Второй — заполнение: табличная часть содержит ожидаемые строки, отборы по параметрам сработали. Третий — запись: объект сохранился без конфликтов версий, проведение не сломалось.

Контрольные точки

Как проверить результат

Значения параметров в начале ВыполнитьКоманду
Норма

Через отладку видно переданные значения, отсутствующие ключи заменены значениями по умолчанию

Тревожный признак

Параметры Неопределено там, где должны быть заполнены, — значит, ключи в вызове и в чтении не совпадают

Состав табличной части после заполнения
Норма

Строки соответствуют отбору по переданным параметрам (склад, период)

Тревожный признак

Заполняется без учета параметров — признак того, что параметры читаются, но не используются в запросе

Запись объекта
Норма

Документ записывается, форма обновляется без ошибок

Тревожный признак

Ошибка конфликта версий или «объект изменен» — обработка писала объект параллельно с открытой формой

Из практики чаще всего встречаются четыре ошибки. Первая — несовпадение имен ключей: при передаче структура содержит ключ «Склад», а читается «СкладОтгрузки». Ошибки выполнения нет, параметр молча теряется. Вторая — обращение к ключу без Свойство(): при штатном вызове из БСП такого ключа нет, и обработка падает с ошибкой именно у пользователя, а не у разработчика.

Третья ошибка — передача несериализуемых типов через параметры формы: таблиц значений, хранилищ значений, ссылок на временные данные. Четвертая — игнорирование контекста: обработка рассчитана на записанный документ, но вызывается из формы нового объекта, и запрос по «ссылке» возвращает пустой результат.

Типичные ошибки
01
Разные имена ключей при передаче и чтении — параметр молча теряется без ошибки выполнения
02
Чтение ключа структуры без проверки Свойство() — падение обработки при штатном вызове из меню
03
Попытка передать таблицу значений или COM-объект через параметры формы — ошибка сериализации
04
Заполнение объекта через Записать() при открытой форме документа — конфликт версий и потеря ручных правок пользователя
05
Отсутствие значения по умолчанию — при программном вызове без параметров обработка работает некорректно

Границы самостоятельной доработки

Описанные приемы безопасны, пока обработка только читает данные и заполняет табличную часть в рамках одного объекта. Риск возрастает, когда обработка начинает записывать несколько документов пакетно, изменять проведенные объекты задним числом или работать в транзакциях с блокировками. В таких сценариях ошибка в параметрах способна испортить не один документ, а пласт учетных данных.

Правило простое: любую обработку заполнения сначала тестируют на копии базы с реальными данными, проверяют поведение при пустых и некорректных параметрах, и только потом публикуют пользователям. Если обработка массово изменяет документы, добавьте в нее режим «только показать, что будет заполнено» без записи — это дешевый способ избежать дорогих ошибок.

Итог

Что важно запомнить

Параметры в обработку заполнения передаются тремя путями: отдельными командами под каждый вариант, собственной формой с полями ввода (использование ОткрытиеФормы) и структурой ПараметрыВыполненияКоманды при программном вызове. Читайте ключи через Свойство() со значениями по умолчанию, не передавайте несериализуемые типы и проверяйте состояние объекта перед записью.

Частые вопросы

Можно ли передать параметр в команду заполнения без открытия формы?

Да, если вызов программный: сформируйте структуру ПараметрыВыполненияКоманды с нужными ключами и вызовите ВыполнитьКоманду напрямую. При интерактивном вызове кнопкой из меню БСП произвольные параметры передать нельзя — используйте несколько команд с разными идентификаторами или форму ввода.

Как понять, откуда вызвана обработка — из формы или программно?

Проверяйте состав ПараметрыВыполненияКоманды. При вызове из БСП в структуре есть служебные ключи подсистемы дополнительных отчетов и обработок (например, сведения об источнике и типе команды). При программном вызове состав ключей полностью определяет ваш код. Надежный признак — наличие ваших пользовательских ключей: они появляются только при программной передаче.

Почему параметр передается, но обработка его «не видит»?

Чаще всего не совпадают имена ключей в структуре при передаче и при чтении, либо значение читается из другой вложенной структуры. Поставьте точку останова в начале ВыполнитьКоманду и посмотрите фактический состав структуры в отладчике — это быстрее, чем искать несоответствие по коду.

Можно ли передать список значений или таблицу в качестве параметра?

Список значений и массив простых типов (ссылки, строки, числа) сериализуются и передаются без проблем. Таблицу значений через параметры формы передать нельзя — передавайте массив структур или формируйте таблицу на сервере по переданным отборам.

Что делать, если обработка должна работать и в фоне, без пользователя?

Вынесите всю логику заполнения в серверную процедуру, принимающую структуру параметров. Интерактивная команда и регламентное задание будут вызывать одну и ту же процедуру, передавая свои наборы значений. Убедитесь, что в фоновом режиме код не обращается к интерактивным элементам — предупреждениям и вопросам пользователю.

Опасно ли менять типовую команду заполнения вместо добавления своей?

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