Как исправить ошибку Поле не найдено при использовании временных таблиц в запросах 1С

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

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

Анализ причины возникновения ошибки

Рассмотрим ситуацию, представленную в коде. Проблема заключается в том, что во временную таблицу ДоговорыЗаПериод помещаются данные из справочника ДоговорыКонтрагентов, но имена полей в этой таблице не соответствуют тем, которые ожидаются в последующих частях запроса. Проанализируем первый пакет запроса:


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

В данном фрагменте кода создается временная таблица с полями: Ссылка, Полуфабрикат, КоличествоПолуфабриката и СрокДействия. Однако в следующем пакете запроса автор пытается обратиться к полю ДоговорыЗаПериод.Договор:


// ... фрагмент второго пакета ...
ПО ДоговорыЗаПериод.Полуфабрикат = ХозрасчетныйОбороты.Субконто1
 И ДоговорыЗаПериод.Договор = ХозрасчетныйОбороты.Субконто2.ДоговорКонтрагента

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

Решение проблемы: правильное именование полей

Чтобы запрос заработал корректно, нам нужно изменить описание полей в первом пакете. Используем ключевое слово КАК для назначения псевдонима. Рассмотрим исправленный вариант кода:


ВЫБРАТЬ
    ДоговорыКонтрагентов.Ссылка КАК Договор,
    ДоговорыКонтрагентов.Полуфабрикат,
    ДоговорыКонтрагентов.КоличествоПолуфабриката,
    ДоговорыКонтрагентов.СрокДействия
ПОМЕСТИТЬ ДоговорыЗаПериод
ИЗ
    Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов

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

Оптимизация работы с субконто и неявными соединениями

В исходном запросе используется обращение ХозрасчетныйОбороты.Субконто2.ДоговорКонтрагента. В системе 1С поле Субконто является составным типом. Когда мы обращаемся к его реквизитам через точку, платформа создает неявные левые соединения со всеми таблицами объектов, которые могут быть назначены этому виду субконто на данном счете. Это существенно замедляет работу БД.

Разберем, как правильно работать с такими полями:

  1. Приведение типов: Рекомендуется использовать функцию ВЫРАЗИТЬ. Это подскажет системе, к какой конкретно таблице нужно обратиться.
  2. Прямое сравнение ссылок: Если поле Субконто2 на счете всегда хранит тип СправочникСсылка.ДоговорыКонтрагентов, лучше сравнивать его напрямую с договором, не обращаясь к вложенным реквизитам.

Проанализируем пример с использованием типизации:


ПО ДоговорыЗаПериод.Полуфабрикат = ХозрасчетныйОбороты.Субконто1
 И ДоговорыЗаПериод.Договор = ВЫРАЗИТЬ(ХозрасчетныйОбороты.Субконто2 КАК Справочник.ДоговорыКонтрагентов)

Использование индексов во временных таблицах

Если в справочнике ДоговорыКонтрагентов содержится большое количество записей, соединение с виртуальной таблицей оборотов может стать "узким местом". Чтобы ускорить процесс, необходимо индексировать временную таблицу по полям связи. Посмотрим, как добавить инструкцию индексирования:


ВЫБРАТЬ
    ДоговорыКонтрагентов.Ссылка КАК Договор,
    ДоговорыКонтрагентов.Полуфабрикат,
    // ... другие поля
ПОМЕСТИТЬ ДоговорыЗаПериод
ИЗ
    Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
ГДЕ
    ДоговорыКонтрагентов.СрокДействия МЕЖДУ &НачалоПериода И &КонецПериода
ИНДЕКСИРОВАТЬ ПО
    Договор,
    Полуфабрикат
;

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

Тонкости работы с виртуальными таблицами

При получении данных из регистра бухгалтерии крайне важно передавать максимальное количество фильтров в параметры виртуальной таблицы, а не в секцию ГДЕ. Посмотрим на фрагмент кода автора:

РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Полуфабрикаты), , , , )

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

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

Для исключения ошибок типа "Поле не найдено" и опечаток, придерживайтесь следующих правил:

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

← На главную