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