Что делать, если запрос в 1С не возвращает данные и результат не отображается

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

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

Причина 1: Пустой цикл обхода результатов запроса

Когда мы пользуемся стандартным инструментом Конструктор запроса с обработкой результата, платформа автоматически генерирует шаблон кода для обхода выборки. Выглядит он следующим образом:


ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // Вставить обработку выборки ВыборкаДетальныеЗаписи
КонецЦикла;

Обратите внимание на комментарий внутри цикла. Конструктор лишь подготавливает структуру обхода данных, но сам ничего не выводит на экран и никуда не записывает полученные значения. Если оставить этот цикл «холостым», программа отработает корректно, без ошибок, но пользователь не увидит никаких изменений на экране. Чтобы проверить, попадают ли данные в цикл, мы можем добавить простую команду вывода сообщений:


Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Сообщить("Найдена ссылка: " + ВыборкаДетальныеЗаписи.Ссылка);
КонецЦикла;

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

Причина 2: Неверный тип параметра запроса (Передача пустой строки)

Проанализируем фрагмент кода установки параметров из примера на форуме:


Ссылка = ДанныеОбъекта.Ссылка;
Вид = "";
Запрос.УстановитьПараметр("Вид", Вид);
Запрос.УстановитьПараметр("Ссылка", Ссылка);

Здесь переменной Вид присваивается значение пустой строки "". В то же время в условиях запроса стоит жесткий фильтр:


ГДЕ
    СтруктурныеЕдиницыКонтактнаяИнформация.Ссылка = &Ссылка
    И СтруктурныеЕдиницыКонтактнаяИнформация.Вид = &Вид

Реквизит Вид в табличной части контактной информации имеет тип ссылки на справочник СправочникСсылка.ВидыКонтактнойИнформации. Когда мы передаем в параметр пустую строку "", СУБД пытается найти записи, у которых вид контактной информации буквально равен строке. Естественно, таких записей в базе нет, и запрос возвращает пустой результат.

Для исправления этой ситуации нам нужно передать в параметр реальную ссылку на элемент справочника ВидыКонтактнойИнформации. Сделать это можно несколькими способами:

Способ 1. Получение предопределенного значения (самый надежный способ, если нужный вид задан в конфигураторе):


Вид = ПредопределенноеЗначение("Справочник.ВидыКонтактнойИнформации.ТелефонСклада");
Запрос.УстановитьПараметр("Вид", Вид);

Способ 2. Поиск по наименованию (подходит для простых внешних обработок, но не рекомендуется для тиражируемых решений):


Вид = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Телефон");
Если ЗначениеЗаполнено(Вид) Тогда
    Запрос.УстановитьПараметр("Вид", Вид);
Иначе
    Сообщить("Не найден вид контактной информации 'Телефон'!");
КонецЕсли;

Способ 3. Поиск по имени предопределенных данных (актуально для конфигураций на БСП):


Вид = Справочники.ВидыКонтактнойИнформации.НайтиПоРеквизиту("ИмяПредопределенныхДанных", "СвязанныйТелефон");
Запрос.УстановитьПараметр("Вид", Вид);

Причина 3: Синтаксические ошибки при обращении к метаданным

В процессе обсуждения на форуме возникла типичная ошибка компиляции, когда разработчик попытался написать следующий код:


СправочникСсылка.ВидыКонтактнойИнформации = Вид;

А затем по совету коллег изменил его на:


Справочник.ВидыКонтактнойИнформации = Вид;

Оба эти варианта ошибочны по своей сути. Разберемся, почему компилятор выдает ошибки:

  1. СправочникСсылка — это тип данных, описывающий ссылку на любой справочник в системе. Ему нельзя присвоить значение напрямую, это не переменная и не объект метаданных.
  2. Справочник — это несуществующий тип или объект в глобальном контексте.
  3. Для обращения к менеджерам справочников в 1С используется глобальная коллекция Справочники (обязательно с буквой «и» на конце). Например: Справочники.ВидыКонтактнойИнформации. Однако даже этому менеджеру нельзя напрямую присвоить значение переменной Вид. Мы можем лишь вызывать у него методы поиска (например, НайтиПоНаименованию() или НайтиПоКоду()).

Причина 4: Особенности хранения контактной информации в современных конфигурациях (БСП)

Если вы работаете в современной конфигурации, разработанной на основе **Библиотеки стандартных подсистем (БСП)** (например, УТ 11, ERP, Комплексная автоматизация, УНФ), то прямое обращение к табличной части справочника Справочник.СтруктурныеЕдиницы.КонтактнаяИнформация может вообще не вернуть данных.

В таких системах контактная информация часто выносится в отдельный регистр сведений — РегистрСведений.КонтактнаяИнформация. В самом справочнике табличная часть может быть пустой или использоваться только как временное хранилище.

Чтобы ваш код работал стабильно и не зависел от обновлений конфигурации, следует использовать программный интерфейс БСП — общий модуль УправлениеКонтактнойИнформацией. Посмотрим на пример кода, который решает задачу получения контактной информации без написания сложных ручных запросов:


// 1. Находим нужный вид контактной информации
ВидКИ = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Телефон");

Если ЗначениеЗаполнено(ВидКИ) Тогда
    // 2. Получаем контактную информацию с помощью стандартной функции БСП
    // Функция автоматически определит, где лежат данные: в ТЧ или в регистре сведений
    ТаблицаКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(ДанныеОбъекта.Ссылка, ВидКИ, ТекущаяДатаСеанса(), Ложь);
    
    // 3. Обходим полученную таблицу результатов
    Для Каждого СтрокаКИ Из ТаблицаКИ Цикл
        Сообщить("Вид: " + СтрокаКИ.Вид + " | Представление: " + СтрокаКИ.Представление);
    КонецЦикла;
Иначе
    Сообщить("Вид контактной информации не найден!");
КонецЕсли;

Как правильно отлаживать запросы в 1С

Если вы написали запрос, но данные не выводятся, не пытайтесь угадать причину по тексту кода. Воспользуйтесь проверенной методикой отладки:

  1. Используйте «Консоль запросов». Это специальная внешняя обработка, которая позволяет в интерактивном режиме вставить ваш текст запроса, заполнить параметры реальными значениями из базы и увидеть итоговую таблицу данных. Если консоль возвращает пустую таблицу, значит, проблема в условиях соединения (ПО) или условиях фильтрации (ГДЕ).
  2. Используйте точку останова в конфигураторе. Установите точку останова на строке сразу после выполнения запроса:
    
    РезультатЗапроса = Запрос.Выполнить();
    
  3. Запустите сеанс в режиме отладки, дойдите до этой точки, нажмите сочетание клавиш Shift + F9 (окно «Вычислить выражение») и проверьте результат с помощью функций:
    • РезультатЗапроса.Пустой() — вернет Истина, если в выборке нет ни одной строки.
    • РезультатЗапроса.Выгрузить() — выгрузит результат в таблицу значений, которую можно визуально просмотреть в режиме отладки и проанализировать состав колонок и строк.

Применяя эти простые правила, проверяя типы передаваемых параметров и используя готовые механизмы БСП, вы сможете быстро локализовать проблему и избежать досадных ошибок при работе с запросами в 1С.

← На главную