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