Как правильно передать и сохранить параметры во внешней обработке в 1С?

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

При разработке внешних обработок в среде управляемого приложения 1С, особенно в таких сложных конфигурациях, как Комплексная автоматизация (КА) или ERP, программисты часто сталкиваются с проблемой: параметры в форму передаются, но при попытке сохранить их в реквизиты формы они «исчезают». Это происходит из-за непонимания жизненного цикла параметров и специфики серверных вызовов. В данной статье мы подробно разберем, почему данные могут пропадать и как реализовать стабильную передачу данных между документом и внешней обработкой.

Разберем причину: почему данные «пропадают»?

Прежде всего, проанализируем ситуацию. В управляемых формах 1С параметры, которые мы передаем в функцию ОткрытьФорму(), попадают в специальную структуру Параметры. Эта структура доступна только в момент создания формы на сервере. Рассмотрим основные причины потери данных:

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

Решение 1: Правильное использование параметров и реквизитов формы

Рассмотрим стандартный и самый надежный способ передачи данных. Сначала создадим в форме обработки реквизит (например, ДокументСсылка с соответствующим типом ссылки на документ). Далее в модуле формы документа пропишем открытие обработки:


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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем наличие параметра и записываем его в реквизит формы
    Если Параметры.Свойство("СсылкаНаДокумент") Тогда
        ДокументСсылка = Параметры.СсылкаНаДокумент;
    КонецЕсли;
    
КонецПроцедуры

После выполнения этого кода переменная ДокументСсылка будет доступна в любых других процедурах формы (и на клиенте, и на сервере), пока форма открыта.

Решение 2: Использование Владельца формы для прямого доступа

Если обработка открывается непосредственно из формы документа, мы можем обратиться к данным документа через свойство ВладелецФормы. Это позволяет не передавать параметры явно, а считывать их «на лету». Рассмотрим, как это реализовать на сервере в модуле формы обработки:


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

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

Решение 3: Возврат результата через ОписаниеОповещения

Часто задача стоит не просто передать ссылку в обработку, но и вернуть результат (например, заполненную таблицу) обратно в документ. Для этого идеально подходит механизм ОписаниеОповещения. Выясним, как это работает по шагам.

Шаг 1. В документе вызываем форму обработки и указываем процедуру, которая примет результат:


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

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

Шаг 2. В форме обработки, после того как пользователь закончил работу, вызываем закрытие с передачей данных:


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

Особенности работы в типовых конфигурациях (БСП)

В конфигурациях вроде 1С:Комплексная автоматизация внешние обработки часто подключаются через механизм «Дополнительные отчеты и обработки» (БСП). В этом случае система сама передает параметры в форму обработки. Проанализируем структуру этих параметров:

Чтобы данные не терялись при использовании БСП, в методе ПриСозданииНаСервере обязательно нужно извлечь ссылку из массива ОбъектыНазначения:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("ОбъектыНазначения") И Параметры.ОбъектыНазначения.Количество() > 0 Тогда
        // Сохраняем первую ссылку в реквизит формы
        ОбъектОснование = Параметры.ОбъектыНазначения[0];
    КонецЕсли;
    
КонецПроцедуры

Подведем итоги

Для того чтобы параметры внешней обработки не «пропадали», придерживайтесь следующих правил:

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

Используя эти подходы, вы обеспечите стабильную работу своих внешних обработок и исключите ошибки потери данных при взаимодействии с основными объектами системы.

← На главную