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