Как сравнить булевы реквизиты справочника и регистра сведений в 1С

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

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

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

Вариант 1. Сравнение «на лету» в форме элемента (Объектный метод)

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

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

Проанализируем пример кода, который можно разместить в модуле формы элемента справочника:


&НаСервере
Процедура ПриОткрытииНаСервере()
    
    // Шаг 1. Формируем структуру отбора по ключевым измерениям регистра
    Отбор = Новый Структура;
    Отбор.Вставить("Сотрудник", Объект.Сотрудник);
    Отбор.Вставить("ОбучающийМатериал", Объект.Ссылка);
    
    // Шаг 2. Обращаемся к менеджеру регистра сведений для получения записи
    РесурсыРегистра = РегистрыСведений.ПройденноеОбучение.Получить(Отбор);
    
    // Шаг 3. Извлекаем булево значение из структуры ресурсов
    ЗначениеИзРегистра = Ложь;
    Если РесурсыРегистра.Свойство("БулевскийРеквизит") Тогда
        ЗначениеИзРегистра = РесурсыРегистра.БулевскийРеквизит;
    КонецЕсли;
    
    // Шаг 4. Сравниваем значение в справочнике со значением в регистре
    Если Объект.БулевскийРеквизит = ЗначениеИзРегистра Тогда
        // Сообщаем пользователю о совпадении или выполняем логику
        ПоказатьОповещениеПользователя("Данные актуальны",, "Статусы в справочнике и регистре совпадают.");
    Иначе
        // Обрабатываем ситуацию расхождения данных
        ПоказатьОповещениеПользователя("Внимание",, "Обнаружено расхождение статусов выполнения!");
    КонецЕсли;
    
КонецПроцедуры

Важное замечание: Если ваш регистр сведений является периодическим, метод Получить() использовать нельзя. Вместо него следует применять методы ПолучитьПоследнее() или ПолучитьПервое(), передав в качестве первого параметра дату (период), на которую актуальны данные.

Вариант 2. Сравнение данных с помощью запроса (Для отчетов и обработок)

Если перед нами стоит задача сравнить данные не по одному элементу, а сразу по всей базе (например, для построения отчета о расхождениях или для массовой корректировки), то объектный обход будет крайне неэффективен. В этом случае единственно верным решением является использование запроса.

Для сопоставления таблиц в базах данных используется механизм Левого соединения (LEFT JOIN). Мы берем за основу таблицу справочника и "присоединяем" к ней таблицу регистра сведений по ключевым полям — сотруднику и материалу.

Рассмотрим важнейший нюанс: если для какого-то элемента справочника в регистре сведений вообще нет записи, соединение вернет значение NULL. Прямое сравнение булева значения (Истина/Ложь) со значением NULL в языке запросов 1С вернет отрицательный результат, что приведет к ошибкам в логике. Чтобы обойти это ограничение, мы обязательно используем функцию ЕСТЬNULL(), заменяя отсутствующую запись на дефолтное значение ЛОЖЬ.

Давайте посмотрим на текст запроса, реализующий это сравнение:


ВЫБРАТЬ
	Материалы.Ссылка КАК ОбучающийМатериал,
	Материалы.Сотрудник КАК Сотрудник,
	Материалы.БулевскийРеквизит КАК ЗначениеВСправочнике,
	ЕСТЬNULL(ПройденноеОбучение.БулевскийРеквизит, ЛОЖЬ) КАК ЗначениеВРегистре,
	
	// Вычисляем поле сравнения на лету в запросе
	ВЫБОР
		КОГДА Материалы.БулевскийРеквизит = ЕСТЬNULL(ПройденноеОбучение.БулевскийРеквизит, ЛОЖЬ)
			ТОГДА ИСТИНА
		ИНАЧЕ ЛОЖЬ
	КОНЕЦ КАК ЗначенияСовпадают
ИЗ
	Справочник.ОбучающиеМатериалы КАК Материалы
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПройденноеОбучение КАК ПройденноеОбучение
		ПО ПройденноеОбучение.Сотрудник = Материалы.Сотрудник
		И ПройденноеОбучение.ОбучающийМатериал = Материалы.Ссылка

Этот запрос возвращает полную картину по всей базе данных. Колонка ЗначенияСовпадают сразу покажет нам, где именно возникли расхождения.

Вариант 3. Интеграция сравнения в Динамический список

Для удобства работы пользователей мы можем вывести результат этого сравнения прямо в форму списка справочника ОбучающиеМатериалы. Это позволит диспетчерам или администраторам обучения моментально видеть проблемные строки визуально.

Разберем по шагам, как это настроить:

  1. Откройте форму списка справочника в конфигураторе.
  2. Перейдите в свойства основного реквизита формы (обычно это Список типа ДинамическийСписок).
  3. Установите флаг Произвольный запрос и нажмите на ссылку "Открыть" для редактирования текста запроса.
  4. Вставьте туда текст запроса, который мы разработали во втором варианте.
  5. В списке колонок формы добавьте новое поле ЗначенияСовпадают. Вы можете отобразить его как обычный флажок (Булево).

Чтобы сделать интерфейс еще более эргономичным, мы можем применить Условное оформление динамического списка. Перейдите во вкладку "Условное оформление" настроек динамического списка и задайте правило: если поле ЗначенияСовпадают равно Ложь, то выделять строку бледно-красным цветом фона. Это позволит пользователю мгновенно фокусировать внимание на ошибках расхождения данных.

← На главную