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

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

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


{ВнешнийОтчет.ВнешнийОтчет2.МодульОбъекта(117)}: Ошибка при вызове метода контекста (Выполнить)
    РезультатЗапроса = Запрос.Выполнить();
по причине:
{(2, 2)}: Поле не найдено "ОтчетПроизводстваЗаСмену.Дата"
<<?>>ОтчетПроизводстваЗаСмену.Дата КАК Дата,

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

Причины возникновения ошибки

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

Табличная часть документа представляет собой отдельную физическую таблицу СУБД. В ней содержатся только ее собственные реквизиты (номенклатура, количество, спецификация и т. д.), а также системные поля: Ссылка (указывающая на документ-владелец) и НомерСтроки. Поля Дата непосредственно в составе табличной части нет, поэтому платформа справедливо сообщает: «Поле не найдено».

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

Способ 1. Разыменование через стандартный реквизит «Ссылка»

Рассмотрим самое быстрое решение, к которому пришел автор темы. Если в отчете требуется выводить строки табличной части и одновременно получать дату документа, к ней следует обращаться через системный реквизит Ссылка:


ВЫБРАТЬ
    ОтчетПроизводстваЗаСменуПродукция.Ссылка.Дата КАК Дата,
    ОтчетПроизводстваЗаСменуПродукция.Номенклатура КАК Номенклатура,
    ОтчетПроизводстваЗаСменуПродукция.Количество КАК Количество
ИЗ
    Документ.ОтчетПроизводстваЗаСмену.Продукция КАК ОтчетПроизводстваЗаСменуПродукция

Обращение через точку к реквизиту ссылочного типа заставляет платформу автоматически подтянуть значение из шапки соответствующего документа.

Способ 2. Выбор таблицы документа вместо табличной части

Разберем другую распространенную ситуацию. Если в вашем отчете или обработке вообще не нужны строки продукции, материалов или услуг, а требуются только реквизиты шапки (дата, номер, подразделение, организация), то выбирать табличную часть в секции ИЗ ошибочно.

В этом случае заменим источник данных на сам документ:


ВЫБРАТЬ
    ОтчетПроизводстваЗаСмену.Ссылка КАК Ссылка,
    ОтчетПроизводстваЗаСмену.Номер КАК Номер,
    ОтчетПроизводстваЗаСмену.Дата КАК Дата,
    ОтчетПроизводстваЗаСмену.Организация КАК Организация
ИЗ
    Документ.ОтчетПроизводстваЗаСмену КАК ОтчетПроизводстваЗаСмену
ГДЕ
    ОтчетПроизводстваЗаСмену.Проведен = ИСТИНА

При таком подходе поле Дата принадлежит непосредственно опрашиваемой таблице, и ошибка исчезает.

Способ 3. Использование явного соединения таблиц (JOIN)

Разыменование полей через точку (ОтчетПроизводстваЗаСменуПродукция.Ссылка.Дата) на уровне СУБД трансформируется в неявное соединение LEFT OUTER JOIN. Если таких полей много (дата, склад, подразделение, организация), неявные соединения могут усложнить план выполнения запроса.

Посмотрим на более надежный и контролируемый вариант — явное соединение таблицы документа и его табличной части:


ВЫБРАТЬ
    Шапка.Дата КАК Дата,
    Шапка.Номер КАК Номер,
    ТЧ.Номенклатура КАК Номенклатура,
    ТЧ.Количество КАК Количество
ИЗ
    Документ.ОтчетПроизводстваЗаСмену.Продукция КАК ТЧ
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОтчетПроизводстваЗаСмену КАК Шапка
        ПО ТЧ.Ссылка = Шапка.Ссылка
ГДЕ
    Шапка.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
    И Шапка.Проведен = ИСТИНА

В этом запросе мы явно разделили источники: из таблицы Шапка берем дату и номер, а из таблицы ТЧ — номенклатуру и количество.

Способ 4. Оптимизация через временную таблицу

В тяжелых базах данных, таких как «Управление производственным предприятием 1.3» (УПП), таблицы документов насчитывают миллионы строк. Наложение условий по дате на табличную часть через неявное разыменование (ГДЕ ТЧ.Ссылка.Дата МЕЖДУ ...) заставляет СУБД сканировать всю таблицу строк документа, так как кластерный индекс табличной части построен по полям Ссылка и НомерСтроки, но не по дате.

Для ускорения работы разобьем задачу на два этапа с использованием временной таблицы:


ВЫБРАТЬ
    Док.Ссылка КАК Ссылка,
    Док.Дата КАК Дата
ПОМЕСТИТЬ ВТ_Документы
ИЗ
    Документ.ОтчетПроизводстваЗаСмену КАК Док
ГДЕ
    Док.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
    И Док.Проведен = ИСТИНА
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Документы.Дата КАК Дата,
    ТЧПродукция.Номенклатура КАК Номенклатура,
    ТЧПродукция.Количество КАК Количество
ИЗ
    ВТ_Документы КАК ВТ_Документы
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОтчетПроизводстваЗаСмену.Продукция КАК ТЧПродукция
        ПО ВТ_Документы.Ссылка = ТЧПродукция.Ссылка

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

Рекомендации разработчику

  1. Пользуйтесь конструктором запросов: если перетаскивать поля из дерева метаданных в конструкторе запросов 1С, платформа самостоятельно подставляет корректные пути (например, автоматически добавит поле Ссылка при выборе реквизитов родительского документа).
  2. Проверяйте псевдонимы: следите за соответствием имен таблиц в секциях ВЫБРАТЬ и ИЗ.
  3. Избегайте избыточных соединений: не обращайтесь к табличной части, если данные строк в отчете не участвуют.
← На главную