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