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