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