Как установить отбор в журнале документов по результатам запроса в обычном приложении 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В типовых и доработанных конфигурациях на обычных формах (например, «Управление торговлей 10.3», «Управление производственным предприятием 1.3») часто возникает задача отфильтровать список документов по сложным условиям, которых нет в прямых реквизитах шапки документа. Типичный пример — отображение только тех заказов покупателей, по которым поступила оплата в заданном периоде, либо отбор документов по дополнительным статусам из связанных регистров сведений.

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

Решение через программную установку отбора по списку ссылок

Основной способ реализации выборочного отображения документов по внешним данным — выполнение запроса к базе данных, получение массива или списка подходящих ссылок и передача их в стандартный элемент отбора динамического списка (ЖурналДокументовСписок или ДокументСписок) с видом сравнения ВидСравнения.ВСписке.

Посмотрим на практическую реализацию обработчика нажатия кнопки на командной панели формы списка:


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

Ограничения и подводные камни отбора через ВидСравнения.ВСписке

Несмотря на простоту реализации, этот метод имеет технические ограничения, о которых необходимо помнить разработчику:

  1. Ограничения СУБД на размер списка параметров: При передаче списка ссылок платформа 1С подставляет их в итоговый SQL-запрос как конструкцию IN (...). Если выборка возвращает десятки тысяч документов, размер текста SQL-запроса превысит допустимые лимиты СУБД, что вызовет аварийное завершение работы или сильные зависания.
  2. Потеря динамического обновления: Полученный список ссылок фиксируется в памяти на момент нажатия кнопки. Если в базу будут введены новые подходящие документы, они не отобразятся в журнале до повторного ручного нажатия кнопки фильтрации.
  3. Обработка пустых результатов: В обычном приложении при передаче пустого СпискаЗначений в свойство отбора Значение отбор может проигнорироваться платформой. Обязательно проверяйте количество записей и при нулевом результате передавайте пустую ссылку нужного типа.

Типичные ошибки при оформлении строк списка (ПриПолученииДанных)

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


// НЕПРАВИЛЬНЫЙ ПОДХОД: Запрос в цикле приводит к зависаниям при прокрутке списка
Для Каждого Строка Из ОформленияСтрок Цикл
    Запрос.УстановитьПараметр("Документ", Строка.ДанныеСтроки.Ссылка);
    // Выполнение запроса на каждой строке вызывает многократные блокировки базы данных
    Выборка = Запрос.Выполнить().Выбрать();
    // ...
КонецЦикла;

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

Альтернативные архитектурные решения

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

  1. Хранение расчетных данных в реквизитах или регистрах сведений: Если требуется быстрый отбор (например, по факту оплаты или признаку согласования), создайте дополнительный реквизит документа или непериодический регистр сведений. Заполняйте эти данные при проведении платежных документов. В таком случае отбор можно будет наложить через стандартный интерфейс формы списка без тяжелых запросов.
  2. Создание АРМ на базе ТаблицыЗначений и ПостроителяОтчета: Вместо стандартного динамического списка создается форма рабочего места, где источником данных служит ТаблицаЗначений. Пользователю предоставляются параметры периода и фильтров, после чего данные единым запросом рассчитываются и выгружаются в таблицу.
  3. Использование критериев отбора: Если связь между документами прямая (по реквизиту ссылки или основанию), в дереве метаданных настраивается объект КритерийОтбора, который автоматически индексируется платформой и работает без снижения производительности.
← На главную