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