Как передать данные из формы подбора обратно в документ в 1С 7.7?

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает классическая задача: при подборе номенклатуры необходимо передать в документ не только выбранную позицию, но и дополнительные данные. Например, при сканировании карты лояльности в форме подбора нужно, чтобы найденный контрагент автоматически «пробросился» в шапку чека ККМ. В этой статье мы подробно рассмотрим, как реализовать механизм обмена данными между формами, разберем работу с контекстом и использование списков значений для возврата параметров.

Постановка задачи и анализ механизмов 1С 7.7

Рассмотрим стандартную ситуацию. Из документа ЧекККМ вызывается форма подбора справочника Номенклатура. В этой форме реализована обработка внешнего события (сканирование штрихкода). Нам нужно передать результат поиска (объект Контрагент) обратно в документ. Основная сложность в 7.7 заключается в том, что стандартный метод ВыполнитьВыбор() принимает только один параметр, а прямая передача контекста через глобальные функции подбора может быть неочевидной.

Способ 1: Использование СпискаЗначений в методе ВыполнитьВыбор

Самый простой и надежный способ вернуть несколько значений из формы подбора — это упаковать их в объект СписокЗначений. Платформа 7.7 позволяет передать этот список в качестве параметра метода ВыполнитьВыбор(). Проанализируем, как это реализовать по шагам.

Во-первых, в форме подбора (например, в процедуре обработки сканирования) мы формируем список значений:


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

Во-вторых, в самом документе (вызывающей форме) необходимо модифицировать процедуру ОбработкаПодбора, чтобы она умела различать, пришел ли к нам простой элемент справочника (товар) или наш специальный список:


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

Способ 2: Передача и использование контекста формы

Если нам нужно менять реквизиты документа «на лету», не закрывая форму подбора (немодальный режим), мы можем пробросить контекст вызывающей формы. Рассмотрим, как это сделать через параметр метода ОткрытьПодбор.

При вызове подбора из документа мы передаем Контекст в качестве параметра:


// В документе ЧекККМ
Процедура ПоКнопкеПодбор()
    Параметры = СоздатьОбъект("СписокЗначений");
    // Передаем контекст текущей формы документа
    Параметры.Установить("КонтекстДокумента", Контекст);
    
    ОткрытьПодбор("Справочник.Номенклатура", "ФормаСписка", Параметры, 0);
КонецПроцедуры

В форме подбора при открытии (в процедуре ПриОткрытии) мы извлекаем этот контекст и сохраняем его в переменную модуля формы. Теперь мы можем напрямую обращаться к реквизитам и методам документа.


// В модуле формы подбора
Переменная КонтДок;

Процедура ПриОткрытии()
    Парам = Форма.Параметр;
    Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
        КонтДок = Парам.Получить("КонтекстДокумента");
    КонецЕсли;
КонецПроцедуры

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

Нюансы работы с контекстом и ОбработкаОжидания

Важно помнить, что прямая модификация реквизитов через Контекст не всегда приводит к немедленному визуальному обновлению формы документа. Проанализируем ситуацию: пользователь отсканировал карту, контрагент в памяти изменился, но на экране в чеке остался старый. Выясним причину: форме документа нужно «сообщить», что данные обновились.

Одним из изящных решений в 7.7 является использование функции Форма.ОбработкаОжидания(). Мы можем инициировать выполнение процедуры в документе из формы подбора:

  1. В форме подбора через КонтДок вызываем КонтДок.Форма.ОбработкаОжидания("ОбновитьДанныеЧека", 1).
  2. В модуле формы документа создаем процедуру ОбновитьДанныеЧека(), в которой первым делом выключаем ожидание: Форма.ОбработкаОжидания("", 0).
  3. В этой же процедуре выполняем обновление интерфейса и пересчеты.

Рекомендации по реализации

При выборе метода проброса параметров рекомендуем придерживаться следующих правил:

Таким образом, для решения задачи автора наиболее подходящим будет Способ 1 (СписокЗначений в ВыполнитьВыбор), если нужно закрыть подбор после сканирования, или Способ 2 (Передача контекста), если подбор должен остаться открытым для дальнейшего добавления товаров.

← На главную