Как вывести значение типа булево (флажок или текст) в форму списка обычного приложения 1С

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

При работе с обычными формами в «1С:Предприятие 8» (например, в конфигурации «Управление производственным предприятием» — УПП) разработчики часто сталкиваются с задачей динамического отображения дополнительных данных в списках документов. Классический пример: нужно прямо в форме списка заказов показать, выписана ли по конкретному заказу подчиненная «Налоговая накладная».

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

Анализ типичных ошибок автора темы

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

  1. Использование неправильного события формы. Автор пытается использовать событие ПриОткрытии и передает туда параметр ОформленияСтрок. Событие формы ПриОткрытии срабатывает один раз при создании окна, оно не имеет такого параметра и не предназначено для динамической отрисовки строк при прокрутке списка.
  2. Ошибка обращения к свойству ячейки. Код ОформлениеСтроки.Ячейки.Флаг = Истина; вызывает ошибку «Значение не является значением объектного типа (Ячейки)». Проблема в том, что в цикле переменная оформления строки называется Стр, а автор пытается обратиться к несуществующей в данном контексте переменной ОформлениеСтроки. Кроме того, напрямую присвоить ячейке булево значение нельзя — нужно настраивать свойства самой ячейки (такие как Флажок, Значение или Текст).
  3. Использование критерия отбора с массивом в запросе. Попытка использовать виртуальную таблицу критерия отбора КритерийОтбора.СвязанныеДокументы(&ЗначениеКритерияОтбора), передавая туда массив ссылок, приведет к ошибке платформы. Данная таблица принимает на вход только единичную ссылку.
  4. Потенциальный «запрос в цикле». Обращение к базе данных внутри цикла отрисовки строк (например, при получении поочередно данных для каждого заказа) — это худшее решение для производительности. Если в списке будет отображаться 50 строк, система выполнит 50 отдельных запросов к СУБД, что вызовет сильные зависания интерфейса при прокрутке.

Правильное решение: использование события «ПриПолученииДанных»

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

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

Рассмотрим по шагам правильную реализацию этого механизма.

Шаг 1. Создание колонки на форме списка

Прежде чем писать программный код, подготовим визуальный элемент в конфигураторе:

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

Шаг 2. Написание программного кода в модуле формы

Теперь создадим обработчик события ПриПолученииДанных для табличного поля списка. Ниже приведен полностью готовый, оптимизированный шаблон кода с подробными комментариями:


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

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

Как работает этот алгоритм?

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

Альтернативный вариант: Отображение картинок (Иконок)

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

Для реализации этой возможности выполните следующие действия:

  1. Добавьте в свойства табличного поля картинку из библиотеки картинок конфигурации (через свойство КартинкиСтрок).
  2. В коде обхода оформления строк вместо установки флага используйте метод УстановитьКартинку() ячейки.

Пример кода для вывода картинки из коллекции:


// Устанавливаем картинку по её индексу в коллекции картинок табличного поля
Если ЕстьНакладная Тогда
    Ячейка.ИндексКартинки = 1; // Индекс зеленой галочки в вашей коллекции
Иначе
    Ячейка.ИндексКартинки = 0; // Индекс пустой картинки или серой точки
КонецЕсли;

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

← На главную