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