Как добавить и программно заполнить новую колонку в списке документов на обычных формах 1С?

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

При работе с конфигурациями на обычных формах (например, УПП 1.3 или КА 1.1) часто возникает задача расширения функционала стандартных журналов или списков документов. Одной из популярных задач является добавление колонки, которая не просто выводит реквизит документа, а отображает вычисляемую информацию — например, признак наличия данных в определенной табличной части. Рассмотрим, как реализовать это правильно, эффективно и с соблюдением стандартов производительности 1С.

Постановка задачи и выбор метода решения

Предположим, нам нужно в списке документов РеализацияТоваровИУслуг добавить колонку, в которой будет отображаться отметка, если в документе заполнена определенная вкладка (табличная часть). Если мы просто добавим колонку на форму, она будет пустой. Нам необходимо найти событие, которое «пробегает» по списку при его отображении и позволяет заполнить ячейки данными.

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

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

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

Реализация через событие ПриПолученииДанных

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

Рассмотрим пример кода, который решает задачу автора темы оптимальным способом:


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

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

    // 3. Заполняем нашу колонку (например, с именем "НаличиеУслуг")
    Пока Выборка.Следующий() Цикл
        Оформление = СоответствиеОформлений.Получить(Выборка.Ссылка);
        Если Оформление <> Неопределено Тогда
            // Можно установить текст
            Оформление.Ячейки.НаличиеУслуг.УстановитьТекст("Да");
            // Или отобразить флажок
            Оформление.Ячейки.НаличиеУслуг.ОтображатьФлажок = Истина;
            Оформление.Ячейки.НаличиеУслуг.ЗначениеФлажка = Истина;
        КонецЕсли;
    КонецЦикла;

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

Почему обращение через точку — это ошибка?

В сообщениях форума автор пытался использовать конструкцию оформлениеСтроки.ДанныеСтроки.Ссылка.МояВкладка.Количество(). Проанализируем ситуацию: когда 1С обращается к Ссылка.ТабличнаяЧасть, система не просто проверяет количество строк. Она неявно считывает весь объект документа из базы данных в память сервера приложений. Если пользователь пролистывает список из 100 документов, система совершит 100 тяжелых операций чтения объектов. При использовании запроса (как в примере выше) мы обращаемся только к конкретной таблице базы данных и получаем только необходимые нам идентификаторы, что в десятки раз быстрее.

Работа с визуальным оформлением ячейки

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

  1. Текстовое значение: Метод УстановитьТекст("Текст") просто выводит строку. Подходит для простых статусов.
  2. Флажок (Checkbox): Самый наглядный вариант для булевых значений. Нужно установить свойство ОтображатьФлажок = Истина и передать состояние в ЗначениеФлажка.
  3. Картинки: Мы можем выводить иконки (например, зеленую галочку или красный восклицательный знак). Для этого нужно создать общую картинку (коллекцию иконок), назначить ее свойству КартинкиСтрок табличного поля и в коде устанавливать ИндексКартинки для ячейки.
  4. Цвет и шрифт: Свойство ОформлениеСтроки.Ячейки.ИмяКолонки.ЦветТекста или ЦветФона позволяет выделить важную информацию визуально.

Важные ограничения динамических колонок

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

Отсутствие сортировки и поиска: Так как данные в колонке вычисляются только в момент отрисовки на экране, они не хранятся в базе данных в составе списка. Это означает, что пользователь не сможет нажать на заголовок колонки и отсортировать список по этому полю. Также по этой колонке не будет работать стандартный поиск 1С (Ctrl+F) и отборы.

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

Заключение

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

← На главную