Как получить значение из другой колонки при выборе из формы в 1С 8.3

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

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

Проблема: Почему стандартный выбор возвращает только ссылку?

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

Решение 1: Переопределение события «Выбор значения» в форме выбора

Самый надежный и правильный способ — это вмешательство в логику самой формы выбора. Нам нужно перехватить момент выбора и вместо ссылки передать структуру. Разберем этот процесс по шагам.

Шаг 1. Настройка динамического списка

Прежде всего, убедимся, что нужная нам колонка (например, Размер) присутствует в динамическом списке формы выбора. Если вы используете произвольный запрос, проверьте, что поле выбрано. Для того чтобы данные гарантированно были доступны на клиенте, найдите это поле в настройках списка и установите флаг Использовать всегда.

Шаг 2. Создание обработчика события

В форме выбора для таблицы (обычно она называется Список) создадим обработчик события ВыборЗначения. Пропишем в нем следующий код:


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

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

Решение 2: Обработка результата в форме документа (владельце)

Теперь рассмотрим, как принять эти данные в основной форме, где происходит заполнение табличной части. Существует два основных способа: через стандартное событие ОбработкаВыбора или через описание оповещения (Callback).

Вариант А: Использование события «ОбработкаВыбора»

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


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

Вариант Б: Программное открытие через «ОткрытьФорму»

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


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

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

Почему передача через «ПараметрыОповещения» не работала у автора?

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

Особенности работы с динамическими списками

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

Резюме для практического применения

  1. Выясним, какие именно поля из формы выбора нам нужны (проверяем запрос динамического списка).
  2. В форме выбора переопределяем событие ВыборЗначения для таблицы, отключаем СтандартнаяОбработка и вызываем ОповеститьОВыборе(Структура).
  3. В вызывающей форме ловим эту структуру в ОбработкаВыбора или в процедуре оповещения.
  4. Используем проверку ТипЗнч(Результат) = Тип("Структура"), чтобы избежать ошибок, если пользователь закроет форму без выбора или выберет значение стандартным способом.

Такой подход делает интерфейс более дружелюбным: пользователю не нужно совершать лишние клики для выбора размера, если он уже нашел нужную строку с остатком в форме выбора.

← На главную