Почему запрос к справочнику Контрагенты по ИНН работает в консоли, но возвращает пустой результат в коде

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Многие разработчики 1С сталкиваются с ситуацией, когда идеально работающий запрос в «Консоли запросов» при переносе в программный модуль конфигурации внезапно перестает возвращать данные. На первый взгляд код кажется правильным, параметры переданы верно, но результат выборки остается пустым. Проанализируем эту ситуацию на примере поиска контрагента по ИНН и разберем основные причины, по которым это происходит, а также способы правильной реализации этого механизма.

Обязательное позиционирование на результате: метод Следующий()

Самая распространенная причина, по которой разработчик не видит данных после выполнения запроса в коде — это отсутствие вызова метода Следующий(). В 1С объект ВыборкаИзРезультатаЗапроса после метода Выбрать() представляет собой курсор, который стоит перед первой записью. Чтобы получить доступ к значениям полей (например, к ссылке контрагента), необходимо переместить этот курсор на первую строку.

Разберем типичную ошибку в коде:


Результат = Запрос.Выполнить().Выбрать();
// Ошибка: здесь Результат.Контрагент будет содержать Неопределено или вызовет ошибку,
// так как выборка еще не спозиционирована ни на одной строке.
Возврат Результат.Контрагент;

Рассмотрим, как правильно организовать получение данных. Если мы ожидаем, что запрос должен вернуть хотя бы одну запись, нам необходимо использовать условие Если или цикл Пока:


Результат = Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
    // Теперь мы находимся на первой строке выборки
    Возврат Результат.Контрагент;
КонецЕсли;

Методы отладки: проверка «пустоты» результата

Если даже при использовании метода Следующий() данные не возвращаются, нам необходимо убедиться, что запрос вообще что-то нашел в базе данных. В отладчике при просмотре переменной типа ВыборкаИзРезультатаЗапроса содержимое полей увидеть невозможно, что часто вводит разработчиков в заблуждение.

Проанализируем ситуацию с помощью отладчика. Вместо просмотра выборки, попробуем вычислить выражение с выгрузкой в таблицу значений. В окне «Вычислить выражение» (Shift+F9) выполните следующую команду:

Запрос.Выполнить().Выгрузить()

Если полученная таблица содержит строки, значит, проблема была именно в позиционировании курсора. Если таблица пуста — проблема в параметрах или в самой базе данных. Также полезно проверять количество записей методом Количество() объекта выборки или результата запроса.

Проблема уникальности ИНН и учет КПП

При поиске контрагентов важно понимать бизнес-логику хранения данных. Вопреки распространенному мнению, ИНН в базе данных 1С не всегда является уникальным. Существует несколько причин, по которым по одному ИНН может быть найдено несколько записей:

  1. Обособленные подразделения: Головная организация и её филиалы имеют общий ИНН, но разные КПП. В учетных системах они часто заводятся как разные элементы справочника Контрагенты для корректного формирования счетов-фактур.
  2. Дублирование данных: В результате ошибок ввода или миграции данных в базе могут появиться дубли.
  3. Разные типы контрагентов: Юридические лица (10 знаков) и Индивидуальные предприниматели (12 знаков).

Если мы будем искать контрагента только по ИНН, используя метод НайтиПоРеквизиту или простой запрос, система вернет первую попавшуюся ссылку, которая может оказаться неверной (например, филиалом вместо основной организации). Разберем пример более надежного поиска с учетом КПП:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Контрагенты.Ссылка КАК Ссылка,
    |   Контрагенты.КПП КАК КПП
    |ИЗ
    |   Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |   Контрагенты.ИНН = &ИНН";

Запрос.УстановитьПараметр("ИНН", ИНН);
Результат = Запрос.Выполнить();

Если НЕ Результат.Пустой() Тогда
    ТаблицаРезультатов = Результат.Выгрузить();
    
    // Если передан КПП, пытаемся найти точное совпадение
    Если ЗначениеЗаполнено(ПараметрКПП) Тогда
        ПараметрыОтбора = Новый Структура("КПП", ПараметрКПП);
        Строки = ТаблицаРезультатов.НайтиСтроки(ПараметрыОтбора);
        Если Строки.Количество() > 0 Тогда
            Возврат Строки[0].Ссылка;
        КонецЕсли;
    КонецЕсли;
    
    // Если точного совпадения по КПП нет или КПП не задан, возвращаем первую запись
    Возврат ТаблицаРезультатов[0].Ссылка;
КонецЕсли;

Нюансы строковых типов и лишние пробелы

Выясним причину, по которой запрос может не срабатывать из-за специфики хранения строк. В справочнике Контрагенты реквизит ИНН имеет тип Строка. Здесь могут скрываться две ловушки:

  1. Фиксированная длина строки: Если в метаданных установлена фиксированная длина (например, 12 символов), то ИНН юридического лица (10 символов) будет дополнен двумя пробелами в конце. При сравнении через = в запросе строка "1234567890" не будет равна строке "1234567890 ".
  2. Невидимые символы: При копировании ИНН из внешних источников (Excel, PDF) в строку могут попасть неразрывные пробелы или символы переноса.

Для решения этих проблем при передаче параметра в запрос рекомендуется всегда использовать функцию СокрЛП(), а в самом запросе, если есть подозрение на проблемы с длиной, использовать оператор ПОДОБНО или предварительно нормализовать данные в базе.


// В коде перед установкой параметра
ИНН_ДляПоиска = СокрЛП(ИНН);
Запрос.УстановитьПараметр("ИНН", ИНН_ДляПоиска);

Влияние прав доступа и RLS

Проанализируем ситуацию, когда под полными правами (в консоли) запрос работает, а в коде под обычным пользователем — нет. В 1С реализован механизм RLS (Row Level Security) — ограничение доступа на уровне записей. Если для пользователя настроены ограничения на чтение справочника Контрагенты (например, по группам доступа или организациям), то запрос просто «не увидит» часть записей. При этом система не выдаст ошибку доступа, а просто вернет пустой результат, как будто записей, соответствующих условию ГДЕ, не существует.

Чтобы проверить эту версию, попробуйте выполнить тот же код в Привилегированном модуле или под пользователем с полными правами. Если данные появятся — необходимо корректировать настройки прав доступа или использовать поиск в привилегированном режиме.

Итоги

Для надежного поиска данных через запрос в коде 1С необходимо придерживаться следующих правил:

← На главную