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

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

При разработке отчетов и обработок в среде «1С:Предприятие» программисты регулярно сталкиваются с задачей, когда в запросе необходимо завязаться на конкретный элемент справочника. Например, если условие в выборке требует подставить определенное значение по умолчанию, конкретного контрагента, или техническое физическое лицо (например, "Физ. лицо" для розничных продаж).

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

Способ 1. Использование параметров запроса (Классический метод)

Если ваш запрос выполняется в обычном коде на встроенном языке 1С, наиболее простым и логичным способом является использование параметров. Писать жесткие текстовые строки в условии, такие как "Физ. лицо", крайне не рекомендуется, поскольку в базе данных тип этого поля должен быть ссылочным, а не строковым. Для сопоставления строкового представления или UUID непосредственно в самом запросе можно использовать приемы сравнения строк с представлением ссылки в запросах 1С.

Рассмотрим, как правильно переписать исходный запрос с использованием параметра:


ВЫБОР
    КОГДА ШихтаМастеровОбороты.Регистратор ССЫЛКА Документ.АктВыгрузки
        ТОГДА ШихтаМастеровОбороты.Регистратор.Контрагент
    ИНАЧЕ &ФизЛицо
КОНЕЦ КАК Контрагент

После написания текста запроса нам необходимо передать в него реальную ссылку на элемент справочника из базы данных. Для этого используется метод УстановитьПараметр объекта Запрос. Разберем пример кода на встроенном языке:


// Создаем объект запроса
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВЫБОР
    |		КОГДА ШихтаМастеровОбороты.Регистратор ССЫЛКА Документ.АктВыгрузки
    |			ТОГДА ШихтаМастеровОбороты.Регистратор.Контрагент
    |		ИНАЧЕ &ФизЛицо
    |	КОНЕЦ КАК Контрагент
    |ИЗ
    |	РегистрНакопления.ШихтаМастеров.Обороты КАК ШихтаМастеровОбороты";

// Находим нужный элемент справочника (например, по коду)
СсылкаНаФизЛицо = Справочники.ФизическиеЛица.НайтиПоКоду("00000001");

// Устанавливаем параметр запроса
Запрос.УстановитьПараметр("ФизЛицо", СсылкаНаФизЛицо);

// Выполняем запрос
РезультатЗапроса = Запрос.Выполнить();

Способ 2. Использование предопределенных элементов и конструкции ЗНАЧЕНИЕ()

Что делать, если мы не хотим писать лишний код на встроенном языке для установки параметров, а желаем, чтобы запрос работал "из коробки" прямо на уровне СУБД? Для этого идеально подходит использование предопределенных элементов справочника.

Предопределенный элемент создается разработчиком на этапе конфигурирования системы. Обратиться к нему напрямую по имени в тексте запроса нельзя. Для этого в платформе 1С предусмотрена специальная системная функция ЗНАЧЕНИЕ().

Рассмотрим синтаксис использования этой функции в нашем запросе:


ВЫБОР
    КОГДА ШихтаМастеровОбороты.Регистратор ССЫЛКА Документ.АктВыгрузки
        ТОГДА ШихтаМастеровОбороты.Регистратор.Контрагент
    ИНАЧЕ ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ФизическоеЛицоПоУмолчанию)
КОНЕЦ КАК Контрагент

Давайте проанализируем особенности этого подхода:

  1. Максимальное быстродействие: Такой запрос транслируется платформой напрямую в SQL-запрос с подстановкой внутреннего идентификатора предопределенного элемента. Базе данных не требуется делать дополнительные соединения или ожидать передачи внешних параметров.
  2. Чистота кода: Нам вообще не нужно писать код установки параметров в программных модулях. Запрос полностью самодостаточен.
  3. Ограничение: Метод работает только для элементов, которые были жестко заданы в конфигураторе как предопределенные. Для обычных элементов, созданных пользователями вручную в режиме предприятия, этот способ не применим.

Способ 3. Использование поля «Выражение» в параметрах СКД

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

Выясним, как обойти это ограничение стандартными средствами СКД без написания программного кода. Для этого мы можем использовать колонку «Выражение» на вкладке «Параметры» в схеме компоновки данных.

В зависимости от того, как именно мы хотим найти элемент, в поле «Выражение» для параметра &ФизЛицо можно прописать следующие формулы:

  1. Если элемент является предопределенным: Используем системную функцию получения предопределенного значения: ПредопределенноеЗначение("Справочник.ФизическиеЛица.ФизическоеЛицоПоУмолчанию")
  2. Если нужно найти обычный элемент по его коду: Пропишем вызов метода менеджера справочника: Справочники.ФизическиеЛица.НайтиПоКоду("00000001")
  3. Если поиск осуществляется по наименованию: Используем метод поиска по наименованию: Справочники.ФизическиеЛица.НайтиПоНаименованию("Физ. лицо")

При формировании отчета СКД сама вычислит это выражение на сервере 1С и автоматически подставит полученную ссылку в соответствующий параметр запроса.

Способ 4. Программная установка параметров в СКД (ПриКомпоновкеРезультата)

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

Давайте разберем правильный шаблон кода, который гарантированно перезапишет параметр как в основных, так и в пользовательских настройках компоновщика отчета:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Задаем имя нашего параметра и получаем нужную ссылку
    ИмяПараметра = "ФизЛицо";
    НужноеЗначение = Справочники.ФизическиеЛица.НайтиПоКоду("00000001");
    
    // 1. Устанавливаем значение в основных настройках схемы
    Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.Найти(ИмяПараметра);
    Если Параметр <> Неопределено Тогда
        Параметр.Значение = НужноеЗначение;
        Параметр.Использование = Истина;
        
        // 2. Синхронизируем значение с Пользовательскими настройками (если они выведены на форму)
        ИдентификаторНастройки = Параметр.ИдентификаторПользовательскойНастройки;
        Если ЗначениеЗаполнено(ИдентификаторНастройки) Тогда
            Для Каждого ЭлементНастройки Из КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
                Если ЭлементНастройки.ИдентификаторПользовательскойНастройки = ИдентификаторНастройки Тогда
                    ЭлементНастройки.Значение = НужноеЗначение;
                    ЭлементНастройки.Использование = Истина;
                    Прервать;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Способ 5. Архитектурное решение через механизм Констант

Зашивать конкретные строковые коды (вроде "00000001") или наименования прямо в код конфигурации или в параметры СКД считается плохим тоном разработки (hardcode). Пользователи или администраторы в режиме «1С:Предприятие» могут случайно изменить код элемента или отредактировать его наименование, из-за чего отчет или запрос мгновенно сломается.

Чтобы сделать систему гибкой и расширяемой, спроектируем правильную архитектуру с использованием объекта метаданных Константы. Выполним следующие шаги:

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

ВЫБРАТЬ
    ВЫБОР
        КОГДА ШихтаМастеровОбороты.Регистратор ССЫЛКА Документ.АктВыгрузки
            ТОГДА ШихтаМастеровОбороты.Регистратор.Контрагент
        ИНАЧЕ КонстантыТаблица.ФизическоеЛицоПоУмолчанию
    КОНЕЦ КАК Контрагент
ИЗ
    РегистрНакопления.ШихтаМастеров.Обороты КАК ШихтаМастеровОбороты
    ЛЕВОЕ СОЕДИНЕНИЕ Константы КАК КонстантыТаблица ПО ИСТИНА

Этот способ является наиболее гибким, масштабируемым и безопасным с точки зрения сопровождения баз данных 1С. После создания константы ссылочного типа её значение можно выбирать и изменять в обработке просмотра констант без правки запроса. Она работает с уже существующими константами и не создаёт новый объект метаданных.

Способ 6. Поиск элемента по Уникальному Идентификатору (UUID)

Если в вашей конфигурации нельзя создавать новые предопределенные элементы или константы, а поиск по наименованию или коду ненадежен, остается самый стабильный низкоуровневый способ программного поиска — использование уникального идентификатора (GUID / UUID) ссылки.

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


// Уникальный идентификатор элемента, скопированный из базы данных
ГУИД = Новый УникальныйИдентификатор("d3b07384-d113-11e7-80d5-00155d033a03"); 

// Получаем прямую ссылку на элемент справочника
ФизЛицоСсылка = Справочники.ФизическиеЛица.ПолучитьСсылку(ГУИД);

// Передаем полученную ссылку в параметры нашего запроса
Запрос.УстановитьПараметр("ФизЛицо", ФизЛицоСсылка);

Использование UUID обеспечивает высокую надежность кода, однако помните, что при переносе данных между сильно отличающимися базами (например, через файлы обмена без сохранения идентификаторов) UUID элементов могут измениться, поэтому данный способ требует аккуратности. Чтобы избежать дублирования объектов при несовпадении ссылок, можно использовать специальный инструмент для переноса данных между похожими конфигурациями 1С, который позволяет настроить сопоставление по любым реквизитам.

Резюме и рекомендации

Мы проанализировали различные варианты решения проблемы. Для простых разовых отчетов в СКД отлично подойдет настройка выражения параметра через ПредопределенноеЗначение или НайтиПоКоду. Для тиражируемых промышленных решений лучшим выбором будет использование механизма Констант или создание предопределенных элементов в структуре метаданных. Это убережет вашу программу от непредвиденных сбоев при изменении данных пользователями.

← На главную