Как вывести наименование артикула номенклатуры в списке документов в 1С

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

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

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

Выясняем причину: почему колонка на форме остается пустой?

Для начала проанализируем ситуацию. Когда мы выводим на форму списка поле через цепочку реквизитов (например, Список.Ссылка.Номенклатура.Артикул), платформа должна динамически считать это значение из базы данных. Однако на практике колонка может не заполняться по трем основным причинам:

  1. Сбой сопоставления путей к данным (известный баг платформы). При изменении произвольного запроса динамического списка платформа автоматически пытается перестроить колонки таблицы. Если сопоставление полей сбивается, путь к данным в свойствах элемента формы заменяется на битый (помечается символом тильды ~ в XML-структуре формы) и колонка визуально исчезает или перестает обновляться.
  2. Оптимизация клиент-серверного вызова. Платформа 1С запрашивает с сервера только те данные, которые непосредственно отображаются на экране. Если поле используется в коде, но колонка скрыта пользователем, данные по ней не передаются на клиент, что вызывает пустые значения или ошибки выполнения кода.
  3. Попытка прямого соединения с табличной частью. Если разработчик пытается связать основную таблицу документов с его табличной частью (Товары, СписокЗЧ) прямо в запросе динамического списка через левое соединение, строки документов начинают дублироваться, ломая логику работы интерфейса.

Разберем по шагам, как исправить каждую из этих проблем.

Решение 1. Восстановление сбившихся путей к данным (устранение бага платформы)

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

  1. Откроем форму списка документов в конфигураторе.
  2. В дереве элементов формы найдем «проблемное» поле (колонку таблицы).
  3. Откроем палитру свойств этого элемента (сочетание клавиш Alt + Enter).
  4. Обратим внимание на свойство «ПутьКДанным». Если перед путем стоит знак тильды (например, ~Список.АртикулНаименование), значит, связь потеряна.
  5. Нажмем на кнопку выбора в строке «ПутьКДанным» и вручную выберем нужное поле из раскрывающегося списка реквизитов динамического списка. Символ тильды исчезнет, связь восстановится, и данные снова начнут отображаться в режиме «1С:Предприятие».

Решение 2. Использование свойства «Использовать всегда»

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

Для настройки выполним следующие шаги:

  1. В окне свойств динамического списка (на вкладке реквизитов формы) найдем наш основной реквизит (обычно он называется Список).
  2. Раскроем его структуру и найдем нужное поле (например, Артикул).
  3. В свойствах этого поля установим флажок «Использовать всегда».

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


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

Решение 3. Настройка произвольного запроса динамического списка

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

Выполним настройку запроса по шагам:

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

Посмотрим на пример правильного запроса для динамического списка:


ВЫБРАТЬ
    ДокументПриход.Ссылка КАК Ссылка,
    ДокументПриход.ПометкаУдаления КАК ПометкаУдаления,
    ДокументПриход.Номер КАК Номер,
    ДокументПриход.Дата КАК Дата,
    ДокументПриход.Проведен КАК Проведен,
    ДокументПриход.Организация КАК Организация,
    ДокументПриход.Контрагент КАК Контрагент,
    // Получаем наименование артикула через левое соединение со справочником запчастей/номенклатуры
    ЕСТЬNULL(СправочникНоменклатура.Артикул.Наименование, "") КАК НаименованиеАртикула
ИЗ
    Документ.ПриходнаяНакладная КАК ДокументПриход
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СправочникНоменклатура
        ПО ДокументПриход.Номенклатура = СправочникНоменклатура.Ссылка

Использование функции ЕСТЬNULL позволяет избежать пустых значений в интерфейсе, если номенклатура в документе по какой-то причине не заполнена.

Решение 4. Вывод данных из табличной части документа (Архитектурный подход)

Часто разработчики пытаются вывести реквизиты табличной части (например, список всех артикулов из спецификации документа) прямо в общую колонку списка документов. Если сделать это простым соединением таблиц в запросе динамического списка, СУБД вернет дублирующиеся строки для одного и того же документа (по одной строке на каждую строку табличной части).

Чтобы избежать этого, применим стандартный архитектурный шаблон «Мастер-Деталь» (Master-Detail). Мы разделим форму списка на две части:

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


&НаСервере
Процедура ОбновитьТабличнуюЧастьНаСервере(СсылкаНаДокумент)
    
    // Очищаем вспомогательную таблицу на форме (тип: ТаблицаЗначений)
    ТаблицаДеталей.Очистить();
    
    Если Не ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
        Возврат;
    КонецЕсли;
    
    // Запрашиваем данные табличной части выбранного документа вместе с артикулами
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ПриходнаяНакладнаяТовары.Номенклатура КАК Номенклатура,
        |	ПриходнаяНакладнаяТовары.Количество КАК Количество,
        |	ПриходнаяНакладнаяТовары.Цена КАК Цена,
        |	ПриходнаяНакладнаяТовары.Сумма КАК Сумма,
        |	ПриходнаяНакладнаяТовары.Номенклатура.Артикул КАК Артикул
        |ИЗ
        |	Документ.ПриходнаяНакладная.Товары КАК ПриходнаяНакладнаяТовары
        |ГДЕ
        |	ПриходнаяНакладнаяТовары.Ссылка = &СсылкаНаДокумент";
        
    Запрос.УстановитьПараметр("СсылкаНаДокумент", СсылкаНаДокумент);
    
    РезультатЗапроса = Запрос.Выполнить();
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Пока Выборка.Следующий() Цикл
            НоваяСтрока = ТаблицаДеталей.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

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

← На главную