Как скрыть строки в таблице списка документов по сроку действия в 1С?

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

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

Анализ типичной ошибки: почему не стоит собирать массив документов в цикле

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


Функция ПроверкаАктивности() Экспорт
    Массив = Новый Массив;
    Выборка = Документы.ДоверенностиОтПокупателей.Выбрать();
    Пока Выборка.Следующий() Цикл
        СД = Выборка.СрокДействия;
        Если СД < ТекущаяДата() Тогда 
            Массив.Добавить(Выборка.СрокДействия); // Ошибка: добавляется дата, а не ссылка
        КонецЕсли;
    КонецЦикла;
    Возврат Массив;
КонецФункции

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

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

Кроме того, распространенным заблуждением является попытка скрыть строки через условное оформление. Механизм условного оформления платформы 1С не имеет свойства видимости для всей строки: он позволяет менять цвет фона, текста, шрифт или очищать текст в ячейках, но сама строка всегда остается в таблице. Единственный корректный способ полностью убрать строки — применить фильтрацию данных.

Решение для обычных форм (толстый клиент)

Если разработка ведется в обычном приложении, список документов представляет собой объект типа ТабличноеПоле с источником данных ДокументСписок. Нам не требуется обходить базу циклом: достаточно напрямую установить отбор по реквизиту СрокДействия.

Посмотрим на пример установки отбора в процедуре ПриОткрытии:


Процедура ПриОткрытии()
    Список.Отбор.СрокДействия.ВидСравнения = ВидСравнения.Больше;
    Список.Отбор.СрокДействия.Значение = ТекущаяДата();
    Список.Отбор.СрокДействия.Использовать = Истина;
КонецПроцедуры

В данном случае платформа транслирует условие непосредственно в запрос к базе данных, и СУБД возвращает только те строки, которые удовлетворяют заданному критерию.

Решение для управляемых форм (Динамический список)

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

Устанавливать отбор рекомендуется на стороне сервера в обработчике ПриСозданииНаСервере. Создадим новый элемент отбора компоновки данных:


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

Защита отбора от изменения пользователем

Если добавить отбор в коллекцию Список.Отбор, пользователь сможет открыть стандартное окно «Настроить список» и снять флажок с установленного условия. Если требуется жестко зафиксировать видимость только действующих документов без возможности отключения, используем фиксированные настройки динамического списка:


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

Важные нюансы работы со временем и датами

При настройке фильтрации по датам необходимо учитывать следующие моменты:

  1. Учет времени: если реквизит СрокДействия хранит только дату (со временем 00:00:00), прямое сравнение с ТекущаяДата() сделает документ невидимым сразу после полуночи наступившего дня. Чтобы документ оставался видимым в течение всего последнего дня его действия, используйте функцию НачалоДня() с видом сравнения БольшеИлиРавно либо КонецДня() в зависимости от учетной политики.
  2. Часовые пояса: в клиент-серверном варианте и веб-клиенте функция ТекущаяДата() может выдавать время локального компьютера пользователя. Для исключения рассинхронизации всегда применяйте ТекущаяДатаСеанса().
  3. Динамическое обновление: если пользователь оставляет список открытым на ночь, переход на следующие сутки не приведет к автоматическому исчезновению строк до тех пор, пока форма не будет перечитана или обновлена вызовом метода Элементы.Список.Обновить().
← На главную