Почему Конструктор запросов не видит реквизит «Владелец» в 1С 8.3 и как это исправить?

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

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда при попытке построить запрос к подчиненному справочнику (например, к справочнику ХарактеристикиНоменклатуры) в списке доступных полей Конструктора запросов отсутствует стандартный реквизит Владелец. Это вызывает недоумение, ведь на уровне логики базы данных у подчиненного справочника этот реквизит обязан присутствовать всегда.

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

Причина проблемы: особенности работы расширений конфигурации

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

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

Аналогичным образом платформа ведет себя и с иерархическими справочниками. Если вы заимствуете иерархический справочник в расширение, но не укажете свойства иерархии, Конструктор запросов скроет от вас стандартные реквизиты Родитель и ЭтоГруппа.

Ниже мы разберем по шагам, как решить эту проблему различными путями.

Способ 1: Правильное заимствование свойств в расширение (Рекомендуемый метод)

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

Выполним следующие шаги:

  1. Откройте дерево метаданных вашего расширения конфигурации в конфигураторе.
  2. Найдите заимствованный справочник (в нашем примере это ХарактеристикиНоменклатуры) и откройте его свойства (клавиша Alt + Enter).
  3. В палитре свойств найдите строку «Владельцы».
  4. Перенесите это свойство в расширение (заимствуйте его) и установите для него режим контроля — отметьте его как контролируемое свойство.

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

Полезный совет: Точно так же поступайте и с иерархическими справочниками. Чтобы вернуть в Конструктор запросов поля Родитель и ЭтоГруппа, добавьте в расширение свойство справочника «Иерархический» и сделайте его контролируемым.

Способ 2: Ручное написание текста запроса (Быстрый обход проблемы)

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

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

Посмотрим на пример кода:


// Пример ручного написания условия по владельцу в коде 1С
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Характеристики.Ссылка КАК Ссылка,
    |	Характеристики.Наименование КАК Наименование,
    |	Характеристики.Владелец КАК Владелец
    |ИЗ
    |	Справочник.ХарактеристикиНоменклатуры КАК Характеристики
    |ГДЕ
    |	Характеристики.Владелец = &Владелец";

Запрос.УстановитьПараметр("Владелец", ВыбраннаяНоменклатура);
РезультатЗапроса = Запрос.Выполнить();

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

Способ 3: Использование консоли запросов в режиме «1С:Предприятие»

Еще один удобный практический прием — это написание и отладка сложных запросов в режиме пользователя с помощью внешней обработки «Консоль запросов».

Выясним, почему этот метод работает:

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

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

Способ 4: Обход через автозамену текста (Лайфхак для сложных отчетов)

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

Разберем этот метод по шагам:

  1. В Конструкторе запросов вместо отсутствующего поля Владелец выберите любое другое доступное поле ссылочного типа, например, поле Ссылка.
  2. Задайте этому полю уникальный псевдоним, например, СсылкаВместоВладельца.
  3. В коде перед вызовом метода Выполнить() сделайте замену текста запроса с помощью стандартной функции СтрЗаменить().

Посмотрим на пример реализации данного лайфхака:


// Создаем запрос с использованием временной заглушки для конструктора
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Характеристики.Ссылка КАК Ссылка,
    |	Характеристики.Ссылка КАК СсылкаВместоВладельца
    |ИЗ
    |	Справочник.ХарактеристикиНоменклатуры КАК Характеристики
    |ГДЕ
    |	Характеристики.Ссылка = &Владелец";

// Производим автозамену заглушки на реальный реквизит Владелец
Запрос.Текст = СтрЗаменить(Запрос.Текст, "Характеристики.Ссылка КАК СсылкаВместоВладельца", "Характеристики.Владелец КАК Владелец");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "Характеристики.Ссылка = &Владелец", "Характеристики.Владелец = &Владелец");

// Устанавливаем параметры и выполняем запрос
Запрос.УстановитьПараметр("Владелец", ПараметрВладелец);
Результат = Запрос.Выполнить();

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

Резюме

Мы детально проанализировали проблему отсутствия реквизита Владелец в Конструкторе запросов 1С 8.3 при разработке внутри расширений. Рекомендуемым и наиболее профессиональным решением является добавление свойства «Владельцы» в заимствованный объект расширения с включением контроля свойств (Способ 1). В тех же случаях, когда требуется быстрое решение «здесь и сейчас» без изменения структуры метаданных расширения, отлично подойдут методы ручного редактирования или автозамены текста запроса.

← На главную