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