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

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

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

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

Решение 1: Использование программного отбора «В списке»

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

Шаг 1. Подготовка переменной для хранения списка документов.

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

Шаг 2. Создание документов и наполнение массива.

Разберем пример кода, где на сервере создается документ, а на клиенте обновляется список:


&НаСервере
Функция СоздатьСчетНаСервере(ДанныеФайла)
    НовыйСчет = Документы.СчетНаОплатуПокупателю.СоздатьДокумент();
    // Заполнение реквизитов документа из ДанныеФайла...
    НовыйСчет.Дата = ТекущаяДата();
    НовыйСчет.Записать();
    
    Возврат НовыйСчет.Ссылка;
КонецФункции

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

Шаг 3. Программная установка отбора в динамическом списке.

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


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

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

Решение 2: Использование Таблицы Значений (ТЗ) на форме

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

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

  1. Создайте реквизит формы с типом ТаблицаЗначений (назовем его ТЗ_Результаты).
  2. Добавьте в эту таблицу колонку Документ с типом ДокументСсылка.СчетНаОплатуПокупателю.
  3. Перетащите таблицу на форму в виде элемента Таблица.

Заполнение такой таблицы выглядит следующим образом:


&НаСервере
Процедура ЗаполнитьТЗНаСервере(МассивСсылок)
    // Очищаем предыдущие результаты
    ТЗ_Результаты.Очистить();
    
    Для Каждого Ссылка Из МассивСсылок Цикл
        НоваяСтрока = ТЗ_Результаты.Добавить();
        НоваяСтрока.Документ = Ссылка;
    КонецЦикла;
КонецПроцедуры

Чтобы пользователь мог открыть документ двойным кликом по строке такой таблицы, убедитесь, что в свойствах колонки установлено свойство КнопкаОткрытия = Истина или настроено событие Выбор.

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

Рассмотрим ситуацию, с которой часто сталкиваются разработчики при переходе с версии 7.7 на 8.3: попытка работы с объектами компоновки данных напрямую на сервере без учета контекста формы.

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

Как правильно: Всегда работайте с реквизитом формы напрямую. Если код выполняется в процедуре &НаСервере, используйте синтаксис ЭтаФорма.Список.Отбор... или просто Список.Отбор..., так как реквизиты формы доступны в серверном контексте модуля формы.

Продвинутый метод: Использование параметров запроса

Если ваш динамический список построен на Произвольном запросе, рассмотрим более элегантный способ фильтрации — через параметры запроса. Это работает быстрее, чем стандартные отборы СКД на больших объемах данных.

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


ВЫБРАТЬ
    Счета.Ссылка,
    Счета.Номер,
    Счета.Дата,
    Счета.СуммаДокумента
ИЗ
    Документ.СчетНаОплатуПокупателю КАК Счета
ГДЕ
    (&ИспользоватьОтбор = ЛОЖЬ ИЛИ Счета.Ссылка В (&МассивСсылок))

В этом случае управление списком сводится к установке параметров:


&НаКлиенте
Процедура ОбновитьСписокЧерезПараметры(МассивСсылок)
    Список.Параметры.УстановитьЗначениеПараметра("МассивСсылок", МассивСсылок);
    Список.Параметры.УстановитьЗначениеПараметра("ИспользоватьОтбор", МассивСсылок.Количество() > 0);
КонецПроцедуры

Этот подход позволяет избежать загромождения пользовательского окна настроек «Найти» и «Сортировать», оставляя программный фильтр «под капотом» системы.

Рекомендации по отображению статусов оплаты

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

Для корректного отображения таких данных:

Используя предложенные методы, мы создадим надежный и удобный интерфейс для пользователя, обеспечив при этом высокую производительность системы.

← На главную