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