Как в ячейке табличной части 1С отобразить реквизит объекта вместо его ссылки с сохранением выбора

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

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

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

Способ 1. Разделение полей ввода: скрытая ссылка и видимая строка (Управляемые формы)

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

Суть метода заключается в разделении логики хранения и отображения данных. В табличную часть добавляются два реквизита:

  1. НоменклатураСсылка (тип: СправочникСсылка.Номенклатура) — скрытое поле, в котором хранится реальная ссылка для базы данных.
  2. КодОтображения (тип: Строка) — видимое текстовое поле на форме, в котором пользователь видит и выбирает нестандартный код.

Разберем по шагам процесс реализации этой схемы:

Шаг 1. Настройка свойств элемента формы.
Для элемента формы КодОтображения установите свойство КнопкаВыбора в значение Истина. Это активирует отображение стандартной кнопки с тремя точками в конце ячейки.

Шаг 2. Перехват начала выбора.
Создадим обработчик события НачалоВыбора для поля КодОтображения. В нем мы программно инициируем открытие формы выбора справочника:


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

Шаг 3. Обработка выбора элемента.
При выборе элемента в форме сработает событие ОбработкаВыбора. Нам нужно перехватить выбранную ссылку, записать ее в скрытую колонку, а текстовое представление кода — в видимую ячейку:


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

&НаСервереБезКонтекста
Функция ПолучитьКодОбъектаНаСервере(СсылкаНаОбъект)
    // Возвращаем нестандартный реквизит из справочника
    Возврат СсылкаНаОбъект.НестандартныйКод; 
КонецФункции

Шаг 4. Настройка быстрого ввода (Автоподбор).
Чтобы пользователь мог вводить нестандартный код прямо с клавиатуры, настроим событие АвтоПодбор на строковом поле:


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

Способ 2. Оптимизированный вывод в Обычных формах через событие ПриПолученииДанных

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

Важное предупреждение: Никогда не используйте событие ПриВыводеСтроки для получения реквизитов через точку (например, ДанныеСтроки.Номенклатура.НестандартныйКод). Это приводит к лавинообразному увеличению количества запросов к СУБД (проблема N+1 запроса), из-за чего интерфейс 1С начнет зависать даже при простой прокрутке списка.

Рассмотрим правильный, оптимизированный алгоритм с использованием предопределенного события ПриПолученииДанных. Он получает данные пакетным запросом сразу для всей видимой области экрана:


Процедура ТабличнаяЧастьПриПолученииДанных(Элемент, ОформленияСтрок)
    
    // 1. Создаем массив для накопления уникальных ссылок видимых строк
    МассивСсылок = Новый Массив;
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
        Если ДанныеСтроки <> Неопределено Тогда
            СсылкаНаОбъект = ДанныеСтроки.НоменклатураСсылка;
            Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
                МассивСсылок.Добавить(СсылкаНаОбъект);
            КонецЕсли;
        КонецЕсли;
    КонецДляОбохода;
    
    Если МассивСсылок.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // 2. Делаем один единственный запрос к СУБД по массиву ссылок
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.Ссылка КАК Ссылка,
        |	Номенклатура.НестандартныйКод КАК НестандартныйКод
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.Ссылка В (&МассивСсылок)";
    
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    ТаблицаРезультатов = Запрос.Выполнить().Выгрузить();
    
    // 3. Переносим результаты в Соответствие для сверхбыстрого поиска в памяти
    СоответствиеКодов = Новый Соответствие;
    Для Каждого СтрокаРез Из ТаблицаРезультатов Цикл
        СоответствиеКодов.Вставить(СтрокаРез.Ссылка, СтрокаРез.НестандартныйКод);
    КонецЦикла;
    
    // 4. Заполняем текстовое представление ячейки без обращения к базе данных
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
        Если ДанныеСтроки <> Неопределено Тогда
            СсылкаНаОбъект = ДанныеСтроки.НоменклатураСсылка;
            Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
                ТекстовоеЗначение = СоответствиеКодов.Получить(СсылкаНаОбъект);
                Если ТекстовоеЗначение <> Неопределено Тогда
                    // Устанавливаем текст отображения в ячейке, не меняя тип значения
                    ОформлениеСтроки.Ячейки.КодЯчейка.УстановитьТекст(ТекстовоеЗначение);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Способ 3. Визуальный прием «В ячейке» (без программирования в Управляемых формах)

Платформа 1С v8.3 предоставляет встроенный визуальный механизм группировки элементов формы, позволяющий соединить кнопку выбора ссылки и отображение любого её реквизита в границах одного поля.

Рассмотрим, как настроить такую группировку в конфигураторе или через режим «Изменить форму»:

  1. Разверните свойства реквизита табличной части (например, Номенклатура) и перетащите на форму его дочерний реквизит (через путь данных Номенклатура.НестандартныйКод).
  2. Добавьте в дерево элементов табличной части новую группу колонок. В свойстве Группировка этой группы выберите режим «В ячейке».
  3. Переместите внутрь этой группы два поля: саму колонку со ссылкой Номенклатура и текстовую колонку Номенклатура.НестандартныйКод.
  4. В свойствах поля ссылки Номенклатура отключите отображение текста, установив видимость только кнопки выбора. А для поля кода снимите доступность редактирования, оставив только показ данных.

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

Способ 4. Переопределение представления объекта на уровне Модуля Менеджера

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

В модуле менеджера справочника (например, Номенклатура) переопределим стандартные обработчики формирования представления:


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

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

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

Резюме

Выбор конкретного метода зависит от архитектуры вашей конфигурации. Для простых и быстрых интерфейсных изменений без кодинга отлично подходит Способ 3 (группировка «В ячейке»). Если вам требуется строгий контроль ввода данных и сложные алгоритмы проверки — выбирайте Способ 1 (разделение полей). При оптимизации старых конфигураций на обычных формах незаменимым остается Способ 2 (пакетный запрос ПриПолученииДанных).

← На главную