Как добавить столбец с артикулом номенклатуры в форму списка в 1С 8.2 и 8.3 на обычных формах

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

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

В чем суть технической проблемы и почему нельзя просто выбрать реквизит?

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

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

Сравнение методов: ПриВыводеСтроки против ПриПолученииДанных

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

  1. Событие ПриВыводеСтроки. Это событие срабатывает индивидуально для каждой строки таблицы в момент ее отрисовки на экране монитора. Если в коде этого обработчика написать прямое обращение к реквизиту через точку (например, ОформлениеСтроки.ДанныеСтроки.Номенклатура.Артикул), система будет вынуждена делать отдельный запрос к СУБД для каждой выводимой строки. При прокрутке списка пользователем количество запросов начнет лавинообразно расти. Это приводит к так называемой проблеме «N+1 запроса», из-за которой интерфейс начинает заметно «тормозить», зависать и дергаться.
  2. Событие ПриПолученииДанных. Это наиболее оптимальный и профессиональный вариант решения задачи. Данное событие вызывается платформой один раз для целой «пачки» (порции) строк, которые в данный момент подготавливаются к отображению на экране. В этот обработчик передается массив оформлений всех видимых строк. Это позволяет нам собрать все ссылки на номенклатуру из отображаемого списка, выполнить один-единственный быстрый запрос к базе данных и распределить полученные артикулы по ячейкам. Производительность системы при этом практически не снижается, а интерфейс работает плавно даже на слабых компьютерах.

Поэтому в нашей практике мы будем использовать исключительно событие ПриПолученииДанных.

Пошаговая инструкция по реализации задачи

Проанализируем пошагово процесс добавления колонки с артикулом на форму списка документов в конфигурации на примере «ДАЛИОН: Автобизнес» (или любой другой конфигурации на обычных формах 1С 8.2 / 8.3).

Шаг 1. Подготовка интерфейса в конфигураторе

Сначала нам необходимо подготовить саму форму визуально:

  1. Откройте конфигуратор вашей информационной базы и найдите нужную форму списка (или форму выбора), где располагается табличное поле с номенклатурой.
  2. Дважды кликните по табличному полю, чтобы открыть его свойства, или нажмите клавишу F4.
  3. В окне свойств найдите пункт Колонки и откройте редактор строк.
  4. Добавьте новую колонку в список.
  5. В свойствах новой колонки укажите уникальное Имя (например, КолонкаАртикул) и задайте понятный пользователю Текст шапки (например, Артикул).
  6. Критически важно: поле свойства Данные для этой колонки оставьте полностью пустым. Нам не нужно связывать ее напрямую с реквизитами источника.

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

Теперь свяжем визуальный элемент с программным кодом:

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

Шаг 3. Написание оптимизированного программного кода

Замените созданный платформой шаблон процедуры на следующий оптимизированный программный код. Этот алгоритм учитывает все особенности работы с динамическими списками: он корректно обрабатывает пустые строки, строки без выбранного товара, а также дублирующиеся позиции номенклатуры.


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

КонецПроцедуры

Детальный анализ программного кода

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

На первом этапе мы инициализируем коллекцию Соответствие. Она работает по принципу «Ключ - Значение», где в качестве ключа выступает ссылка на элемент справочника Номенклатура, а в качестве значения — массив строк оформления ОформлениеСтроки. Это необходимо из-за того, что на экране пользователя может отображаться несколько одинаковых товаров (например, в разных строках спецификации одного документа). Такой подход защищает нас от избыточных циклов.

На втором этапе мы собираем все уникальные ссылки на товары в МассивНоменклатуры. Платформа передает в обработчик только те строки, которые пользователь видит на экране прямо сейчас (обычно от 10 до 30 строк). Соответственно, наш массив будет содержать не более 30 элементов.

На третьем этапе выполняется запрос к базе данных. Использование конструкции ГДЕ Ссылка В(&МассивНоменклатуры) позволяет СУБД отработать запрос за доли миллисекунды, так как поиск происходит по первичному индексу таблицы. Мы получаем плоскую выборку соответствий ссылок и артикулов.

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

Особенности работы в конфигурации ДАЛИОН и отраслевых решениях

Конфигурация «ДАЛИОН: Автобизнес» разработана на базе стандартных паттернов программирования 1С. Однако при переносе кода в вашу систему обратите внимание на следующие нюансы:

Заключение

Использование события ПриПолученииДанных — это классический «золотой стандарт» разработки в среде обычного приложения 1С 8.2 и 8.3. Этот подход позволяет гибко кастомизировать интерфейсы под требования пользователей, выводя любую связанную информацию (артикулы, штрихкоды, остатки на складах, цены) без ущерба для скорости работы программы. Следуя нашей инструкции, вы сможете легко решить задачу вывода артикулов и повысить удобство работы пользователей в вашей системе. При необходимости расширить перечень способов вывода полей можно использовать методы доработки динамических списков.

← На главную