Как при открытии справочника найти и вывести элементы с незаполненными реквизитами в 1С?

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

Каждый начинающий разработчик в среде «1С:Предприятие» рано или поздно сталкивается с задачей обхода элементов справочника и проверки заполнения их реквизитов. В этой статье мы подробно разберем, как правильно реализовать эту задачу, исправим типичные ошибки новичков, поговорим о клиент-серверной архитектуре и рассмотрим современные UX/UI-альтернативы привычному выводу сообщений.

Анализ исходных ошибок разработчика

Для начала проанализируем попытки автора темы решить задачу самостоятельно. В коде автора присутствуют две критические ошибки:

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

Давайте разберем по шагам, как построить правильное, быстрое и архитектурно верное решение.

Шаг 1. Понимание клиент-серверной архитектуры в 1С

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

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

Разберем шаблон такой структуры кода в модуле формы списка:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Вызываем серверную процедуру для анализа данных
    ПроверитьЗаполнениеРеквизитовНаСервере();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПроверитьЗаполнениеРеквизитовНаСервере()
    // Здесь будет выполняться запрос к базе данных
КонецПроцедуры

Шаг 2. Особенности работы с пустой датой в запросах 1С

В платформе 1С тип данных Дата всегда содержит и дату, и время. Понятия «пустого» значения даты в привычном понимании (как NULL в SQL или undefined в JavaScript) для заполненных реквизитов типа дата по умолчанию не существует. Вместо этого пустая дата представляется как начало григорианского календаря: 01 января 1 года (01.01.0001 00:00:00).

При составлении запроса важно учитывать следующие особенности:

Шаг 3. Создание оптимизированного запроса

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

Поскольку наша цель — просто вывести имена людей, у которых не заполнена дата рождения, мы должны выбирать только поле Наименование. Рассмотрим оптимизированный текст запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Люди.Наименование КАК ФИО
    |ИЗ
    |   Справочник.Люди КАК Люди
    |ГДЕ
    |   Люди.ДатаРождения = ДАТАВРЕМЯ(1, 1, 1)";

Обратите внимание на условие в секции ГДЕ. Мы выбираем только те записи, у которых реквизит ДатаРождения равен пустой дате ДАТАВРЕМЯ(1, 1, 1).

Шаг 4. Полный программный код решения

Теперь объединим полученные знания в готовое решение. Этот код необходимо разместить в Модуле формы списка справочника «Люди»:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Инициируем проверку незаполненных дат на сервере
    ПроверитьЗаполнениеДатНаСервере();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПроверитьЗаполнениеДатНаСервере()
    
    // Создаем запрос для поиска элементов с пустой датой
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Люди.Наименование КАК ФИО
        |ИЗ
        |   Справочник.Люди КАК Люди
        |ГДЕ
        |   Люди.ДатаРождения = ДАТАВРЕМЯ(1, 1, 1)";
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // Если результат пустой, прерываем выполнение, чтобы сэкономить ресурсы
    Если РезультатЗапроса.Пустой() Тогда
        Возврат;
    КонецЕсли;
    
    // Обходим результаты запроса в цикле
    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        // Метод Сообщить() доступен на сервере, 
        // сообщения будут переданы на клиент и показаны пользователю
        Сообщить("У сотрудника " + Выборка.ФИО + " не указана дата рождения!");
    КонецЦикла;
    
КонецПроцедуры

Альтернативные и более современные решения (Best Practices)

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

Рассмотрим, как решить эту задачу более элегантно и в соответствии с современными стандартами разработки 1С.

Вариант А. Условное оформление динамического списка (Без программирования)

Вместо написания запросов и программного обхода элементов мы можем визуально выделить строки с незаполненной датой прямо в списке. Это делается стандартными средствами платформы в дизайнере формы списка:

  1. Откроем форму списка справочника «Люди» в конфигураторе.
  2. В окне «Свойства» для элемента Список (динамический список) найдем строку Условное оформление и нажмем «Открыть».
  3. Добавим новое правило оформления:
    • Оформление: Например, установим красный цвет текста или светло-желтый фон для привлечения внимания.
    • Условие: Добавим условие ДатаРождения Равно '0001-01-01' (пустая дата).
    • Оформляемые поля: Выберем поле Наименование или ДатаРождения.

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

Вариант Б. Быстрый отбор на форме

Мы можем вывести на форму кнопку или флажок «Показать незаполненные». При изменении этого флажка динамический список будет мгновенно отфильтрован. Нам не нужно писать тяжелые запросы вручную — платформа сделает это автоматически на уровне СУБД:


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

Вариант В. Использование всплывающих оповещений

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


// Пример использования вместо Сообщить()
ПоказатьОповещениеПользователя(
    "Внимание!", 
    , 
    "Обнаружены сотрудники без указанной даты рождения!", 
    БиблиотекаКартинок.Важно
);

Используя эти методы, мы делаем наши прикладные решения на платформе «1С:Предприятие 8» быстрыми, надежными и удобными для конечного пользователя.

← На главную