Как правильно определить строку табличной части в обработчике ОбработкаВыбора?

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

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

Проблема использования свойства ТекущиеДанные

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

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

Решение 1: Использование Описания Оповещения и идентификатора строки

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

Для начала нам нужно перехватить начало выбора. Рассмотрим пример кода для события НачалоВыбора конкретного поля в табличной части:


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

Теперь проанализируем процедуру обработки оповещения, которая сработает после того, как пользователь выберет значение:


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

Решение 2: Передача параметров через событие ОбработкаВыбора

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

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

  1. В событии НачалоВыбора вы открываете форму и передаете в неё ИдентификаторСтроки.
  2. В форме выбора, при срабатывании события выбора, вы формируете не просто ссылку, а Структуру.
  3. В структуре передаете: Значение (выбранная ссылка) и ID_Строки (тот самый идентификатор).
  4. В основной форме в ОбработкаВыбора вы разворачиваете структуру и находите нужную строку методом НайтиПоИдентификатору().

Решение 3: Использование Ключа Связи (для сложных ТЧ)

В типовых конфигурациях (например, ERP или УТ 11) часто используется реквизит КлючСвязи. Это особенно актуально, если у вас есть связанные табличные части (например, список товаров и список серийных номеров для каждого товара). Посмотрим, как это работает:

При выборе значения система ищет строку не по внутреннему идентификатору платформы, а по бизнес-ключу, который вы сами назначили строке. Это позволяет гарантировать уникальность связи данных даже после записи объекта в базу или его переоткрытия. Если ваша задача подразумевает сложную логику распределения данных (например, подбор партий, где одна строка подбора может разбиться на три строки в документе), КлючСвязи становится незаменимым инструментом.

Практические советы и рекомендации

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

Выясним причину, почему разработчики часто выбирают передачу "номера строки". Это кажется простым, но это плохая практика. Если в процессе выбора данных сработает какой-то фоновый процесс (например, автоматическая сортировка или удаление пустых строк), номер строки изменится, и данные попадут не туда. Использование ИдентификаторСтроки полностью решает эту проблему.

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

← На главную