Перенос сложного запроса из консоли в Систему компоновки данных (СКД) нередко сопровождается ошибками вида «Поле не найдено». Давайте разберем, почему это происходит и как правильно адаптировать код для работы в отчетах.
Основная причина заключается в разнице между выполнением запроса в консоли и в СКД. Консоль выполняет запрос «как есть», тогда как СКД проводит глубокий анализ: она пытается оптимизировать запрос, исключая поля, которые явно не используются в настройках отчета или группировках. Если поле ДатаПриход было объявлено во временной таблице, но не выбрано в итоговом наборе данных, система может посчитать его лишним, что приводит к ошибке при обращении.
Также важно помнить, что АВТОНОМЕРЗАПИСИ() — это инструмент для временных таблиц. При попытках использовать его в сложных запросах с соединениями или объединениями в СКД результат может быть непредсказуемым из-за того, что платформа перестраивает план выполнения запроса.
Рассмотрим ваш запрос. Вы используете временную таблицу ВТДанныеПриходРасход для финального вывода данных. В контексте СКД это часто избыточно. СКД сама умеет работать с наборами данных и соединениями. Попробуйте вывести результат финального блока напрямую, не помещая его во временную таблицу.
Вместо сохранения в ПОМЕСТИТЬ, вы можете просто выполнить выборку в конечном запросе. Это снимет проблему с видимостью полей, так как СКД будет «видеть» все поля финальной выборки как доступные для полей набора данных.
Использование конструкций вида Регистратор.Номер и Регистратор.Ответственный является «антипаттерном». Когда вы обращаетесь к полю через точку, платформа вынуждена «приклеивать» к запросу все возможные типы документов, которые могут быть регистраторами данного регистра. Это катастрофически сказывается на производительности.
Чтобы ускорить выполнение и избежать ошибок, рекомендуем использовать оператор ВЫРАЗИТЬ. Это позволит ограничить типы документов и даст оптимизатору запросов четкое понимание структуры данных.
Посмотрим на пример правильного обращения:
ВЫБРАТЬ
ВЫРАЗИТЬ(БухгалтерияКазахстанаОборотыДтКт.Регистратор КАК Документ.ПриходныйКассовыйОрдер).Ответственный КАК Ответственный
ИЗ
РегистрБухгалтерии.БухгалтерияКазахстана.ОборотыДтКт(&НачалоПериода, &КонецПериода, , , , , , ) КАК БухгалтерияКазахстанаОборотыДтКт
В вашем коде используется ЕСТЬNULL(..., "") для полей даты и чисел. Это плохая практика, так как она вызывает неявное приведение типов (например, даты к строке). Для чисел лучше использовать ЕСТЬNULL(..., 0), а для дат — корректные значения по умолчанию.
Посмотрим, как привести запрос к правильному виду:
// Вместо строк используем числовые константы или значения по умолчанию
ЕСТЬNULL(Приход.ПриходПриход, 0) КАК ПриходПриход,
ЕСТЬNULL(Приход.ДатаПриход, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаПриход
ПОМЕСТИТЬ. Выводите результат выборки напрямую.ВЫРАЗИТЬ для полей Регистратор, чтобы платформа не тратила ресурсы на соединение со всеми возможными документами конфигурации."" в функции ЕСТЬNULL на соответствующие типы данных (числа или даты), чтобы избежать проблем с приведением типов при расчете итогов.Следуя этим шагам, вы не только решите проблему с доступностью полей, но и значительно ускорите работу вашего отчета, сделав код более профессиональным и легким в поддержке.