При написании запросов в системе 1С:Предприятие начинающие разработчики часто сталкиваются с ситуацией, когда платформа выдает ошибку «Поле не найдено», хотя визуально это поле присутствует в тексте запроса. Давайте подробно разберем, почему так происходит, изучим логику работы механизма запросов и выясним, как правильно составлять условия фильтрации данных.
Рассмотрим ситуацию, представленную в вопросе. Разработчик пытается выполнить следующий запрос:
ВЫБРАТЬ
докум.дата КАК датадок
ИЗ
Документ.ЗаказТовара КАК докум
ГДЕ
датадок >= &Дата
На первый взгляд запрос кажется логичным: мы присвоили полю Дата понятный псевдоним датадок и хотим использовать его в условии ГДЕ. Однако система выдает ошибку. Выясним причину: в языке запросов 1С (как и в стандартном SQL) псевдонимы полей, заданные в секции ВЫБРАТЬ, недоступны для использования в секции ГДЕ. Это связано со строгой последовательностью обработки частей запроса СУБД.
Чтобы понять, почему возникает ошибка, проанализируем логический порядок выполнения операций при исполнении запроса. Несмотря на то, что мы пишем код, начиная со слова ВЫБРАТЬ, компьютер обрабатывает его иначе:
ВЫБРАТЬ еще не сформированы.КАК...).Как мы видим, на этапе 2 (секция ГДЕ) система еще «не знает» о существовании имени датадок, так как оно будет определено только на этапе 5. Поэтому для исправления ошибки нам необходимо использовать в условии либо прямое имя поля, либо путь к полю через псевдоним таблицы.
Рассмотрим подробнее правильный вариант исправления. Вместо использования псевдонима датадок, мы должны обратиться к реальному имени поля из базы данных.
Вариант 1 (с использованием псевдонима таблицы):
ВЫБРАТЬ
докум.Дата КАК датадок
ИЗ
Документ.ЗаказТовара КАК докум
ГДЕ
докум.Дата >= &Дата
Вариант 2 (если таблица одна и нет неоднозначности):
ВЫБРАТЬ
Дата КАК датадок
ИЗ
Документ.ЗаказТовара
ГДЕ
Дата >= &Дата
Проанализируем ситуацию: использование докум.Дата предпочтительнее, так как это делает код более читаемым и защищает от ошибок, если в будущем в запрос будут добавлены другие таблицы (например, через соединение), в которых тоже может быть поле Дата.
Важно отметить интересную особенность: в отличие от секции ГДЕ, в секции УПОРЯДОЧИТЬ ПО использование псевдонимов разрешено. Посмотрим на пример:
ВЫБРАТЬ
Продажи.СуммаОборот КАК Выручка
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
УПОРЯДОЧИТЬ ПО
Выручка УБЫВ
Этот запрос отработает без ошибок, потому что сортировка выполняется в самом конце, когда псевдоним Выручка уже успешно присвоен полю.
Иногда нам нужно наложить условие на результат сложного вычисления. Например, мы хотим найти документы, где сумма с учетом налога превышает определенный порог. Поскольку псевдоним использовать нельзя, у нас есть два пути решения.
Путь 1: Дублирование выражения
ВЫБРАТЬ
Заказ.СуммаДокумента * 1.2 КАК СуммаСНДС
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
Заказ.СуммаДокумента * 1.2 > 1000
Путь 2: Использование вложенного запроса
Это более элегантный способ, если выражение слишком длинное. Мы выносим расчет во внутренний запрос, присваиваем ему псевдоним, а во внешнем запросе этот псевдоним уже воспринимается как полноценное поле таблицы.
ВЫБРАТЬ
Вложенный.СуммаСНДС
ИЗ
(ВЫБРАТЬ
Заказ.СуммаДокумента * 1.2 КАК СуммаСНДС
ИЗ
Документ.ЗаказПокупателя КАК Заказ) КАК Вложенный
ГДЕ
Вложенный.СуммаСНДС > 1000
В тексте форума упоминалось использование докум.Дата. Давайте выясним, зачем вообще нужно задавать псевдоним таблицы через ключевое слово КАК. Псевдоним таблицы (например, докум) критически важен в следующих сценариях:
ЛЕВОЕ СОЕДИНЕНИЕ или ПОЛНОЕ СОЕДИНЕНИЕ часто встречаются одинаковые имена полей (например, Ссылка, Номер, Дата). Указание псевдонима таблицы (Заказы.Дата vs Реализации.Дата) однозначно говорит системе, из какого источника взять данные.Чтобы избежать других ошибок компиляции запроса, при создании псевдонимов следует придерживаться строгих правил:
1_Поле — недопустимо)._.ВЫБРАТЬ, ИНДЕКСИРОВАТЬ, ГДЕ).Т1, Т2) допустимо, но считается плохим тоном. Старайтесь давать осмысленные сокращения, такие как Товары, Остатки или Продажи.Подведем итог: всегда помните, что секция ГДЕ работает с исходными данными таблиц, а не с результатом, который вы формируете в ВЫБРАТЬ. Использование правильных имен полей и понимание логики СУБД поможет вам писать безошибочный и производительный код в 1С.