Как исправить ошибку «Поле не найдено» при обращении к общему реквизиту через точку в запросе 1С?

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

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

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

Анализ исходной ситуации и текста ошибки

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


Запрос.Текст = "ВЫБРАТЬ
               |    Бюджеты.Ссылка КАК Ссылка,
               |    ЕСТЬNULL(Бюджеты.омУИД, """") КАК ID,
               |    Бюджеты.ПометкаУдаления КАК IsDeleted,
               |    ЕСТЬNULL(Бюджеты.Код, """") КАК Code,
               |    ЕСТЬNULL(Бюджеты.Наименование, """") КАК Name,
               |    ЕСТЬNULL(Бюджеты.Элемент.омУИД, """") КАК ElementBID,
               |    ЕСТЬNULL(Бюджеты.Элемент.Код, """") КАК ElementBCode,
               |    ЕСТЬNULL(Бюджеты.НаименованиеПубличноПравовогоОбразования, """") КАК EducationName,
               |    ЕСТЬNULL(Бюджеты.НаименованиеФинансовогоОргана, """") КАК FiscalName,
               |    ЕСТЬNULL(Бюджеты.КодОрФК, """") КАК CodeOrFk,
               |    ЕСТЬNULL(Бюджеты.КодОКПОФинансовогоОргана, """") КАК CodeOKPO,
               |    ЕСТЬNULL(Бюджеты.НаименованиеПолное, """") КАК FullName,
               |    ЕСТЬNULL(Бюджеты.Родитель.омУИД, """") КАК ParentID,
               |    ЕСТЬNULL(Бюджеты.Родитель.Код, """") КАК ParentCode
               |ИЗ
               |    Справочник.Бюджеты КАК Бюджеты
               |ГДЕ
               |    Бюджеты.Ссылка = &ОбъектСсылка";

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

При выполнении метода Выполнить() система возвращает исключение:

«Ошибка при вызове метода контекста (Выполнить) по причине: Поле не найдено "Бюджеты.Элемент.омУИД"»

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

Выясняем причину: как работают общие реквизиты

Для того чтобы понять природу ошибки, важно обратиться к архитектуре платформы «1С:Предприятие». Поле омУИД (уникальный идентификатор, часто используемый в интеграционных модулях компании «Омега» для БГУ) является не обычным реквизитом конкретного справочника, а общим реквизитом.

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

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

В рассматриваемой нами ситуации общий реквизит омУИД включен для справочника Бюджеты, но он отключен (не используется) для того справочника, который назначен типом данных для реквизита Элемент. Платформа 1С при трансляции запроса на язык SQL пытается выполнить левое соединение (LEFT JOIN) с таблицей подчиненного справочника и выбрать поле общего реквизита, которого там физически нет.

Пошаговая инструкция по решению проблемы в Конфигураторе

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

  1. Определяем тип данных реквизита:

    Откроем конфигурацию в режиме «Конфигуратор». Найдем в дереве метаданных справочник Бюджеты, раскроем его ветку «Реквизиты» и откроем свойства реквизита Элемент. В палитре свойств обратим внимание на строку «Тип». Выясним, на какой именно справочник ссылается это поле (например, это может быть справочник КлассификаторЭлементовБюджета).

  2. Переходим к настройке общего реквизита:

    В дереве метаданных найдем ветку Общие, далее раскроем Общие реквизиты. Найдем в списке общий реквизит с именем омУИД и откроем его палитру свойств (клавиша Alt+Enter или через контекстное меню).

  3. Редактируем состав общего реквизита:

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

    Посмотрим на текущее значение в колонке «Использование». Скорее всего, там установлено значение «Не использовать». Нам необходимо изменить его на «Использовать».

  4. Сохраняем изменения:

    Нажимаем кнопку «ОК» в окне состава, закрываем свойства и выполняем обновление конфигурации базы данных (клавиша F7 или кнопка на панели инструментов).

После выполнения этих шагов СУБД пересоздаст физическую таблицу для подчиненного справочника, добавив в нее колонку для хранения общего реквизита омУИД. Ошибка в запросе исчезнет.

Сложный случай: работа с составным типом данных

Ситуация может усложниться, если реквизит Элемент имеет составной тип данных (то есть может ссылаться на несколько разных справочников, например, СтатьиДоходов, СтатьиРасходов и ЦелевыеСтатьи).

При выполнении запроса вида Бюджеты.Элемент.омУИД для поля составного типа платформа 1С осуществляет неявное левое соединение со всеми таблицами справочников, входящих в этот составной тип. Если хотя бы у одного из этих справочников в составе общего реквизита омУИД указано «Не использовать», запрос упадет с аналогичной ошибкой «Поле не найдено».

В данном случае у нас есть два пути решения:

Решение А: Настройка метаданных (глобальное). Нам потребуется найти все справочники, входящие в составной тип реквизита Элемент, и для каждого из них включить использование общего реквизита омУИД в его составе (как описано в пошаговой инструкции выше). Это наиболее правильный путь с точки зрения целостности архитектуры.

Решение Б: Ограничение типа в запросе (локальное). Если мы не хотим или не имеем возможности менять метаданные состава (например, конфигурация находится на поддержке без возможности изменения, а отчет/обработка внешние), мы можем принудительно ограничить тип проверяемого поля непосредственно в тексте запроса с помощью функции ВЫРАЗИТЬ.

Рассмотрим пример использования функции ВЫРАЗИТЬ для решения этой проблемы:


// Вместо небезопасного обращения:
// ЕСТЬNULL(Бюджеты.Элемент.омУИД, "") КАК ElementBID

// Используем явное приведение к конкретному типу:
ЕСТЬNULL(ВЫРАЗИТЬ(Бюджеты.Элемент КАК Справочник.КлассификаторЭлементовБюджета).омУИД, "") КАК ElementBID

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

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

Мы выяснили, что ошибка «Поле не найдено» при работе с общими реквизитами часто возникает из-за несогласованности состава реквизитов у связанных справочников. В конфигурациях линейки БГУ подобные ситуации нередко происходят после установки очередных обновлений, когда разработчики типового решения добавляют новые справочники в составные типы данных, но забывают включить их в состав кастомных (проектных) общих реквизитов.

При проектировании собственных метаданных и написании запросов всегда проверяйте:

← На главную