В процессе разработки и поддержки систем на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с нетипичным поведением расширений конфигурации. Одной из наиболее загадочных и сложнодиагностируемых проблем является ситуация, когда абсолютно одинаковый запрос к регистру или таблице возвращает корректные данные при выполнении из основного кода конфигурации, но возвращает пустой результат или совершенно другие данные, если его запустить из контекста расширения.
Представим стандартный сценарий: регистр сведений СостоянияЗаказовКлиентов заимствован в расширение без изменения его структуры (не добавлялись новые измерения, ресурсы или реквизиты). Программист выполняет запрос под учетной записью с полными правами (Администратор) из основной конфигурации и видит заполненную таблицу данных. Однако при выполнении того же самого запроса под той же учетной записью, но из модуля расширения, результат оказывается пустым или неполным. Давайте подробно разберем, почему возникает этот феномен, проанализируем внутренние механизмы платформы и рассмотрим пошаговые методы устранения данной проблемы.
Первое, на что падает подозрение при разнице в результатах запросов под одним пользователем — это права доступа. Даже если пользователь авторизован под ролью с полными правами, платформа 1С может применять различные механизмы ограничений в зависимости от контекста исполнения кода.
Если в базе данных активно ограничение доступа на уровне записей (RLS), шаблоны ограничений могут использовать обращения к связанным таблицам: группам доступа, организациям, физическим лицам или подразделениям. При выполнении запроса из основной конфигурации платформа успешно строит сложный SQL-запрос с учетом всех ограничений. Однако если эти связанные объекты метаданных, фигурирующие в шаблонах RLS, не были заимствованы в расширение, транслятор запросов 1С в контексте расширения не может корректно разрешить связи. Вместо вывода ошибки платформа зачастую «молча» отсекает строки, которые считает недоступными, возвращая пустую выборку.
Также важно проверить роли внутри самого расширения. Если в расширении созданы собственные роли, они могут неявно переопределять или накладывать дополнительные ограничения на заимствованные объекты.
Рассмотрим ситуацию с точки зрения ссылочной целостности метаданных. Допустим, наш регистр СостоянияЗаказовКлиентов содержит измерение Заказ с типом ДокументСсылка.ЗаказКлиента. Если сам документ ЗаказКлиента или типы данных, входящие в состав его реквизитов, не перенесены в расширение, платформа внутри контекста расширения сталкивается с неопределенностью типов.
При выполнении SQL-запроса СУБД выполняет соединения таблиц (JOIN). Если тип измерения не определен в расширении, платформа может транслировать это поле как Неопределено или представить его в виде некорректного типа данных. В результате любые операции сравнения или соединения по этому полю в запросе будут возвращать ложь (Ложь), что приведет к пустому результату выборки.
Одной из наиболее частых причин «мистического» поведения 1С является кэширование метаданных. Платформа активно использует кэш для оптимизации работы с СУБД, сопоставляя логические таблицы SDBL с физическими таблицами SQL-сервера. При заимствовании объектов в расширение схема сопоставления может нарушиться.
В локальном кэше конфигуратора или на сервере приложений 1С (каталог ConfigCacheStorage) сохраняются старые структуры данных. СУБД получает запросы со смещениями полей, которые уже не соответствуют реальному физическому расположению данных в базе. Это приводит к тому, что запрос из расширения обращается «не туда» и возвращает пустые строки.
Если режим совместимости расширения отличается от режима совместимости основной конфигурации, это напрямую влияет на работу построителя запросов. Разные версии платформы по-разному транслируют запросы к заимствованным таблицам. Особенно часто такие проблемы встречаются на версиях платформы 8.3.14 – 8.3.18. Несовпадение режимов совместимости может приводить к генерации некорректного SQL-кода при обращении к виртуальным таблицам регистров.
Проанализируем практические шаги, которые помогут локализовать и устранить данную проблему в вашей информационной базе:
СостоянияЗаказовКлиентов в расширении. Убедитесь, что все типы данных, используемые в измерениях, ресурсах и реквизитах регистра (например, справочники, документы, перечисления), также заимствованы в это расширение. Если тип составной, все типы, входящие в его состав, должны быть перенесены.РежимСовместимости установлено в значение "Версия платформы" или строго соответствует режиму совместимости основной конфигурации.srvinfo\reg_1541\, за исключением файлов баз данных).%LocalAppData%\1C\1Cv8\ и %AppData%\1C\1Cv8\.СостоянияЗаказовКлиентов из расширения, сохраните конфигурацию базы данных, а затем заимствуйте его заново. Это принудительно обновит внутренние идентификаторы и связи метаданных SDBL.Для диагностики и проверки корректности получения данных мы можем использовать простой отладочный код. Попробуем выгрузить результат запроса в таблицу значений и проанализировать типы колонок:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СостоянияЗаказов.Заказ КАК Заказ,
| СостоянияЗаказов.Состояние КАК Состояние
|ИЗ
| РегистрСведений.СостоянияЗаказовКлиентов КАК СостоянияЗаказов";
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Для Каждого Колонка Из ТаблицаРезультата.Колонки Цикл
Сообщить("Колонка: " + Колонка.Имя + ", Тип: " + Строка(Колонка.ТипЗначения));
КонецЦикла;
Сообщить("Количество строк в результате: " + Строка(ТаблицаРезультата.Количество()));
Если при выполнении этого кода из расширения тип колонки Заказ возвращается как Неопределено или тип не совпадает с ожидаемым ДокументСсылка.ЗаказКлиента, это явный признак того, что тип данных не заимствован или заимствован некорректно. Следуя приведенным инструкциям, вы сможете быстро устранить расхождения в результатах запросов и восстановить стабильную работу вашей системы.