Разработка и Конфигурация · 10 мин
Как передать данные в обработку в 1С
Разбираем, как передать данные во внешнюю обработку 1С: параметры формы, ОткрытьФорму, ОткрытьЗначение, передача таблиц значений и документов на примерах кода.
Передача данных в обработку — одна из самых частых задач при доработке конфигураций 1С. Обработка без входных данных мало полезна: ей нужно знать, какой документ заполнить, какую таблицу деталей разобрать или по какому периоду построить выборку. В зависимости от того, откуда вызывается обработка и в каком режиме работает конфигурация (обычное или управляемое приложение), применяются разные механизмы.
В управляемых формах основной инструмент — структура параметров, передаваемая через метод ОткрытьФорму(). В обычных формах — реквизиты обработки и метод ПолучитьФорму(). Отдельные сценарии возникают при вызове из схемы компоновки, через команду интерфейса или при передаче больших объёмов данных через временное хранилище.
Ниже разобраны рабочие способы с примерами кода, ограничения каждого подхода и типичные ошибки, из-за которых обработка открывается пустой или падает с ошибкой.
Открытие обработки с параметрами через ОткрытьФорму
Стандартный способ в управляемом приложении — сформировать структуру с нужными значениями и передать её вторым аргументом в ОткрытьФорму(). Этот метод работает для внешних обработок и для обработок, встроенных в конфигурацию.
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("ДокументСсылка", ТекущийДокумент);
СтруктураПараметров.Вставить("Период", НачалоМесяца(ТекущаяДатаСеанса()));
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма", СтруктураПараметров, ЭтотОбъект);
Для обработки, встроенной в конфигурацию, путь выглядит иначе: Обработка.ЗаполнениеЦен.Форма. Первый аргумент — строка пути к форме, второй — структура параметров, третий — владелец формы (удобно для блокировки окна владельца и организации иерархии окон).
Ограничение: в структуру параметров нельзя помещать несериализуемые объекты — например, таблицу значений напрямую. Ссылки, примитивные типы, массивы и структуры из допустимых значений передаются без проблем.
Получение параметров внутри обработки
На стороне обработки переданные значения доступны в обработчике ПриСозданииНаСервере через коллекцию Параметры. Прежде чем использовать значение, проверяйте, что параметр действительно передан.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ДокументСсылка")
И ЗначениеЗаполнено(Параметры.ДокументСсылка) Тогда
ДокументОбъект = Параметры.ДокументСсылка;
ЗаполнитьТабличнуюЧасть(ДокументОбъект);
КонецЕсли;
КонецПроцедуры
Если обработка открывается и без параметров (например, из меню «Файл — Открыть»), задайте поведение по умолчанию: инициализируйте реквизиты пустыми значениями, чтобы форма не упала при обращении к незаполненным данным.
Передача таблиц значений через временное хранилище
Таблицу значений, результат запроса или дерево значений нельзя положить в структуру параметров напрямую. Решение — временное хранилище: данные помещаются на сервере, а в обработку передаётся только адрес (строка-идентификатор).
&НаСервере
Функция ПодготовитьАдресДанных()
ТаблицаДанных = СформироватьТаблицу();
Возврат ПоместитьВоВременноеХранилище(ТаблицаДанных, Новый УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура ОткрытьОбработку(Команда)
Адрес = ПодготовитьАдресДанных();
Парам = Новый Структура("АдресДанных", Адрес);
ОткрытьФорму("ВнешняяОбработка.Разбор.Форма", Парам, ЭтотОбъект);
КонецПроцедуры
В обработке данные извлекаются методом ПолучитьИзВременногоХранилища(Адрес). После чтения хранилище желательно очистить вызовом УдалитьИзВременногоХранилища(), если данные больше не нужны — иначе они будут занимать память сеанса до закрытия формы-владельца.
Данные = ПолучитьИзВременногоХранилища(Параметры.АдресДанных);
Если ТипЗнч(Данные) = Тип("ТаблицаЗначений") Тогда
ТаблицаФормы.Загрузить(Данные);
КонецЕсли;Передача данных в обычном приложении
В обычных формах механизм другой: параметры формы в привычном виде отсутствуют, поэтому данные передают через реквизиты обработки или экспортные переменные модуля формы. Сначала получают объект обработки и её форму, затем присваивают значения и только потом открывают форму.
Обработка = ВнешниеОбработки.Создать("C:\Обработки\Заполнение.epf");
Обработка.ДокументОснование = ТекущийДокумент;
ФормаОбработки = Обработка.ПолучитьФорму("Форма");
ФормаОбработки.Открыть();
Здесь ДокументОснование — реквизит обработки, созданный в конфигураторе. Присваивание выполняется до открытия формы, иначе обработчик ПриОткрытии() увидит пустое значение. Этот подход проще, но требует, чтобы все передаваемые данные были заранее объявлены как реквизиты.
Сравнение способов
Управляемое приложение. Подходит для ссылок, дат, чисел, строк. Не принимает таблицы значений напрямую.
Управляемое приложение, крупные данные: таблицы, результаты запросов. Требует очистки хранилища.
Обычное приложение. Просто, но все поля нужно объявить в конфигураторе заранее.
Передача данных из документа или справочника через команду
Типовой сценарий — кнопка «Заполнить» в форме документа, которая открывает обработку и передаёт ей ссылку на текущий объект. В модуле формы документа создаётся клиентская процедура, в которой ссылка берётся из реквизита Объект.Ссылка.
&НаКлиенте
Процедура ЗаполнитьЦены(Команда)
Если Объект.Ссылка.Пустая() Тогда
ПоказатьПредупреждение(, "Сначала запишите документ");
Возврат;
КонецЕсли;
Парам = Новый Структура("ДокументСсылка", Объект.Ссылка);
ОткрытьФорму("Обработка.ЗаполнениеЦен.Форма", Парам, ЭтотОбъект);
КонецПроцедуры
Важный нюанс: если документ изменён, но не записан, обработка получит ссылку на старую версию данных из базы. Либо требуйте записи перед открытием, либо передавайте сами данные (табличные части) через временное хранилище, а не только ссылку.
Возврат результата из обработки обратно
Обратная задача — обработка должна вернуть результат в вызвавшую форму. В управляемом приложении для этого используется ОписаниеОповещения: при открытии указывается процедура-обработчик, которая сработает при закрытии формы обработки.
&НаКлиенте
Процедура ОткрытьПодбор(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияПодбора", ЭтотОбъект);
ОткрытьФорму("Обработка.Подбор.Форма", , ЭтотОбъект, , , , Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗакрытияПодбора(Результат, ДопПараметры) Экспорт
Если Результат <> Неопределено Тогда
ОбработатьРезультат(Результат);
КонецЕсли;
КонецПроцедуры
Чтобы обработка вернула значение, в её коде форму закрывают методом Закрыть(Результат), передавая структуру, массив или адрес временного хранилища. Форма при этом должна открываться в режиме, допускающем возврат значения.
- 1Определите, какие данные нужны обработке: ссылки и примитивы или таблицы
- 2Для простых типов сформируйте структуру и передайте в ОткрытьФорму
- 3Для таблиц значений поместите данные во временное хранилище и передайте адрес
- 4В обработке прочитайте значения из Параметры в ПриСозданииНаСервере и сохраните в реквизиты
- 5Проверьте открытие с параметрами и без, убедитесь, что форма не падает при пустых значениях
Типичные ошибки и их диагностика
Чаще всего проблемы возникают не из-за механизма передачи, а из-за мелких несоответствий между вызывающим кодом и обработкой. Ниже — признаки, по которым можно быстро локализовать причину.
Если обработка открывается, но данные «не доходят», поставьте точку останова в ПриСозданииНаСервере и посмотрите содержимое коллекции Параметры в отладчике. Это самый быстрый способ понять, что реально передалось: имя ключа, тип и значение.
Как проверить результат
Ключи совпадают с именами в ОткрытьФорму, значения заполнены
Ключ отсутствует или значение Неопределено
Форма открывается с пустыми реквизитами без ошибок
Ошибка обращения к незаполненному значению
ПолучитьИзВременногоХранилища возвращает таблицу нужной структуры
Возвращается Неопределено — адрес недействителен или хранилище очищено
FAQ
Можно ли передать данные в уже открытую обработку?
Напрямую через параметры — нет, параметры доступны только при создании формы. Используйте метод Оповестить() с именем события, а в обработке — обработчик ОбработкаОповещения(), либо найдите форму и вызовите её экспортную процедуру.
Почему структура с таблицей значений вызывает ошибку?
Таблица значений не сериализуется при передаче между клиентом и сервером в параметрах формы. Поместите таблицу во временное хранилище на сервере и передайте в обработку адрес хранилища, а там извлеките данные методом ПолучитьИзВременногоХранилища.
Как передать данные в обработку, открываемую программно без формы?
Если форма не нужна, создайте объект обработки через Обработки.ИмяОбработки.Создать() или ВнешниеОбработки.Создать(), присвойте значения реквизитам и вызовите экспортную процедуру модуля объекта. Параметры формы в этом сценарии не используются.
Чем отличается передача данных во внешнюю и встроенную обработку?
Механизм одинаковый, отличается только путь к форме: для внешней — «ВнешняяОбработка.Имя.Форма», для встроенной — «Обработка.Имя.Форма». Внешняя обработка должна быть предварительно зарегистрирована в справочнике дополнительных отчетов и обработок или открыта через файл.
Как передать массив ссылок в обработку?
Массив из сериализуемых значений (ссылок, строк, чисел) можно поместить прямо в структуру параметров. В обработке прочитайте его через Параметры.Свойство() и обойдите в цикле. Для очень больших массивов надёжнее использовать временное хранилище.
Безопасно ли передавать в обработку ссылку на редактируемый документ?
Ссылка указывает на данные в базе, а не на открытую форму. Если документ изменён, но не записан, обработка увидит старую версию. Требуйте записи документа перед открытием обработки или передавайте актуальные данные через временное хранилище.
Что важно запомнить
В управляемом приложении данные передаются структурой через ОткрытьФорму и читаются из Параметры в ПриСозданииНаСервере. Таблицы значений передают через временное хранилище. В обычном приложении используют реквизиты обработки и ПолучитьФорму. Всегда проверяйте наличие параметра и поведение формы без входных данных.