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