Выбор характеристик товаров в таблице значений Розница 2.2: как вернуть выбранное значение в таблицу?

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

При разработке внешних обработок для 1С:Предприятие 8.3, таких как загрузка накладных из файлов Excel, часто возникает задача интерактивного редактирования загруженных данных перед их окончательной записью в информационную базу. Одной из типичных проблем, с которой сталкиваются разработчики на управляемых формах, является выбор характеристик номенклатуры в таблице значений на форме. Сценарий простой: форма выбора характеристик открывается с правильным отбором по владельцу (номенклатуре), но после того как пользователь дважды кликает по нужной строке, форма выбора закрывается, а ячейка в исходной таблице значений остается пустой.

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

Выясняем причину: почему выбранное значение не возвращается в таблицу значений?

Рассмотрим подробнее исходный код, который часто пишут начинающие разработчики в обработчике события НачалоВыбора для поля ввода характеристики:


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

Проанализируем ситуацию: почему форма выбора успешно открывается с нужным фильтром по владельцу-номенклатуре, но значение не возвращается обратно? Обратим внимание на строку вызова функции ОткрытьФорму. Здесь передаются всего два параметра: имя открываемой формы выбора и структура параметров формы ПараметрыФормы. При таком вызове платформа открывает форму выбора изолированно. Она «не знает», какому именно объекту или элементу формы нужно вернуть результат сделанного выбора. Из-за отсутствия указания владельца формы выбора (третьего параметра метода ОткрытьФорму) платформа игнорирует закрытие формы с выбором и не передает значение в вызвавшую ячейку.

Способ 1. Самое простое решение — передача параметра «Владелец»

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

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


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

В данном случае переменная Элемент, поступающая на вход обработчика события, указывает на конкретное поле ввода текущей строки таблицы. Этого достаточно, чтобы платформа выполнила всю рутинную работу по возврату значения самостоятельно без написания дополнительных обработчиков.

Способ 2. Декларативная настройка через «Связи параметров выбора» (Без кода)

Зачем писать код программной фильтрации, если платформа 1С может сделать все сама? В платформе 1С:Предприятие 8.3 реализован мощный декларативный механизм связей параметров выбора, который позволяет полностью отказаться от написания программного кода для фильтрации характеристик по номенклатуре. Настроить это можно непосредственно в свойствах элементов формы.

Разберем этот процесс по шагам:

  1. Откройте форму вашей обработки в конфигураторе.
  2. В дереве элементов формы найдите вашу таблицу значений и выберите колонку (поле ввода) Характеристика.
  3. В палитре свойств найдите категорию Параметры выбора и свойство Связи параметров выбора (Choice parameter links).
  4. Нажмите на кнопку с многоточием для открытия окна настройки связей.
  5. Добавьте новую строку связи:
    • Имя параметра: укажите Отбор.Владелец (поскольку характеристики подчинены справочнику Номенклатура).
    • Путь к данным: укажите путь к колонке номенклатуры в этой же строке таблицы (например, Элементы.ТабличнаяЧастьНакладной.ТекущиеДанные.НоменклатураСправочника).
  6. Установите режим изменения связанного значения в состояние Очищать. Это гарантирует, что при изменении номенклатуры в строке ранее выбранная характеристика будет автоматически сброшена, исключая логические ошибки ввода данных.

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

Способ 3. Использование описания оповещения о закрытии (Callback)

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

Разберем, как реализовать этот алгоритм:

  1. Создадим описание оповещения в процедуре начала выбора, указав имя экспортной процедуры, которая должна быть вызвана после закрытия формы выбора.
  2. Передадим созданное описание оповещения в качестве седьмого параметра метода ОткрытьФорму.

Посмотрим на пример программного кода для реализации этого сценария:


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

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

Способ 4. Перехват события «ОбработкаВыбора» таблицы

Еще один профессиональный способ управления процессом подбора — перехват события выбора непосредственно на уровне таблицы формы. Для этого при открытии формы выбора в качестве ее владельца передается сама таблица, а в модуле формы описывается обработчик события таблицы ОбработкаВыбора.

Реализуется это следующим образом:


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

&НаКлиенте
Процедура ТабличнаяЧастьНакладнойОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку платформы
    
    ТекущиеДанные = Элементы.ТабличнаяЧастьНакладной.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        ТекущиеДанные.ХарактеристикаСправочника = ВыбранноеЗначение;
    КонецЕсли;
    
КонецПроцедуры

Рекомендации: как избежать снятия конфигурации с поддержки?

Один из важных вопросов, поднятых автором обсуждения на форуме, — нежелательность снятия типовой конфигурации «1С:Розница 2.2» с поддержки ради реализации подобной доработки. В современной экосистеме 1С существует два отличных инструмента, которые позволяют решить эту задачу без внесения изменений в типовой код конфигурации:

1. Использование механизма Расширений конфигурации

Расширения позволяют добавлять собственные реквизиты, формы, а также перехватывать и дополнять модули типовой конфигурации. Вы можете заимствовать форму нужного документа или обработки в расширение, добавить туда ваш код (используя аннотации &Перед, &После или &Вместо) и сохранить основную конфигурацию на полной поддержке. Это значительно упростит последующие автоматические обновления системы.

2. Разработка внешних обработок заполнения табличных частей

Если загрузка данных из Excel выполняется в рамках типового документа (например, Поступление товаров), наилучшим решением будет создание Внешней обработки заполнения табличных частей. Такие обработки подключаются через справочник «Дополнительные отчеты и обработки» и работают абсолютно изолированно от кода конфигурации. Весь интерфейс загрузки и сопутствующий код будут находиться в одном внешнем файле .epf, что полностью исключает любые проблемы при обновлении конфигурации.

Используйте описанные рекомендации и выбирайте наиболее подходящий для вашего проекта способ реализации выбора характеристик товаров!

← На главную