Как добавить и обработать выбранное значение со ссылкой на строку таблицы в 1С

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

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

Понимание механизма передачи «Выбранного значения»

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

Проанализируем ситуацию: если мы хотим, чтобы в основную форму вернулся номер строки, мы должны позаботиться об этом еще в момент вызова выбора. Если форма выбора стандартная, она обычно возвращает ссылку. Чтобы вернуть структуру, нам придется переопределить событие выбора в форме-источнике.

Различие между номером строки и идентификатором

В среде 1С существует критически важное различие между НомерСтроки и ИдентификаторСтроки. Рассмотрим подробнее каждый из них, чтобы не допускать ошибок при поиске данных:

  1. Номер строки: Это визуальный порядковый номер (1, 2, 3...), который пользователь видит в таблице. Он крайне нестабилен. Если пользователь отсортирует таблицу по названию или цене, номер строки у конкретного товара изменится.
  2. Идентификатор строки: Это внутренний уникальный индекс строки в памяти текущего сеанса формы. Он возвращается свойством Элементы.ИмяТаблицы.ТекущаяСтрока. Этот идентификатор остается неизменным, пока строка существует в таблице, даже если таблицу сортируют или фильтруют.

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

Реализация передачи данных через структуру

Рассмотрим по шагам, как передать номер строки или идентификатор из формы выбора обратно в документ. Для этого мы будем использовать структуру.

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


ПараметрыВыбора = Новый Структура;
ПараметрыВыбора.Вставить("ИдентификаторТекущейСтроки", Элементы.Товары.ТекущаяСтрока);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыВыбора, Элементы.Товары);

Шаг 2. Возврат данных из формы выбора. В форме выбора (например, справочника) в событии Выбор мы должны сформировать структуру ответа:


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

Обработка результата в основной форме

Теперь выясним, как правильно принять эти данные. В событии ОбработкаВыбора мы должны проверить тип пришедшего значения и произвести поиск строки.


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

Решение проблемы «Текущая строка не найдена»

Разберем причину ошибки из сообщения №12. Она часто возникает, когда программист пытается обратиться к ТекущаяСтрока напрямую в контексте, где элемент управления еще не доступен или контекст выполнения (сервер/клиент) не позволяет корректно считать состояние формы.

Чтобы гарантированно получить объект строки и её номер, используйте метод НайтиПоИдентификатору(). Помните, что Элементы.Товары.ТекущаяСтрока возвращает число (ID), а не саму строку. Чтобы получить номер, нужно пройти через получение объекта строки:


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

Продвинутый подход: Использование стабильных ключей

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

Рекомендованный алгоритм:

  1. Добавьте в табличную часть скрытый реквизит КлючСвязи (тип Строка или УникальныйИдентификатор).
  2. При добавлении новой строки генерируйте уникальное значение: Строка.КлючСвязи = Новый УникальныйИдентификатор();.
  3. В структуру ВыбранноеЗначение передавайте именно этот КлючСвязи.
  4. При обработке выбора ищите строку методом НайтиСтроки():

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

Если НайденныеСтроки.Количество() > 0 Тогда
    СтрокаДляИзменения = НайденныеСтроки[0];
    // Работаем с найденной строкой
КонецЕсли;

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

Резюме

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

← На главную