Каждый начинающий разработчик в среде 1С сталкивается с ситуацией, когда написанный запрос не выдает никаких ошибок, но на выходе получается абсолютно пустой результат. При этом в консоли запросов или при ручном поиске данные в базе вроде бы присутствуют. Разберем детально, почему так происходит, какие классические ошибки допускают новички и как правильно решить эту задачу с использованием современных стандартов разработки на платформе 1С:Предприятие 8.3.
Когда мы пользуемся стандартным инструментом Конструктор запроса с обработкой результата, платформа автоматически генерирует шаблон кода для обхода выборки. Выглядит он следующим образом:
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Вставить обработку выборки ВыборкаДетальныеЗаписи
КонецЦикла;
Обратите внимание на комментарий внутри цикла. Конструктор лишь подготавливает структуру обхода данных, но сам ничего не выводит на экран и никуда не записывает полученные значения. Если оставить этот цикл «холостым», программа отработает корректно, без ошибок, но пользователь не увидит никаких изменений на экране. Чтобы проверить, попадают ли данные в цикл, мы можем добавить простую команду вывода сообщений:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Сообщить("Найдена ссылка: " + ВыборкаДетальныеЗаписи.Ссылка);
КонецЦикла;
Если после этого в окно сообщений ничего не вывелось, значит, проблема глубже — сам запрос возвращает пустую таблицу. Выясним, почему это происходит.
Проанализируем фрагмент кода установки параметров из примера на форуме:
Ссылка = ДанныеОбъекта.Ссылка;
Вид = "";
Запрос.УстановитьПараметр("Вид", Вид);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Здесь переменной Вид присваивается значение пустой строки "". В то же время в условиях запроса стоит жесткий фильтр:
ГДЕ
СтруктурныеЕдиницыКонтактнаяИнформация.Ссылка = &Ссылка
И СтруктурныеЕдиницыКонтактнаяИнформация.Вид = &Вид
Реквизит Вид в табличной части контактной информации имеет тип ссылки на справочник СправочникСсылка.ВидыКонтактнойИнформации. Когда мы передаем в параметр пустую строку "", СУБД пытается найти записи, у которых вид контактной информации буквально равен строке. Естественно, таких записей в базе нет, и запрос возвращает пустой результат.
Для исправления этой ситуации нам нужно передать в параметр реальную ссылку на элемент справочника ВидыКонтактнойИнформации. Сделать это можно несколькими способами:
Способ 1. Получение предопределенного значения (самый надежный способ, если нужный вид задан в конфигураторе):
Вид = ПредопределенноеЗначение("Справочник.ВидыКонтактнойИнформации.ТелефонСклада");
Запрос.УстановитьПараметр("Вид", Вид);
Способ 2. Поиск по наименованию (подходит для простых внешних обработок, но не рекомендуется для тиражируемых решений):
Вид = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Телефон");
Если ЗначениеЗаполнено(Вид) Тогда
Запрос.УстановитьПараметр("Вид", Вид);
Иначе
Сообщить("Не найден вид контактной информации 'Телефон'!");
КонецЕсли;
Способ 3. Поиск по имени предопределенных данных (актуально для конфигураций на БСП):
Вид = Справочники.ВидыКонтактнойИнформации.НайтиПоРеквизиту("ИмяПредопределенныхДанных", "СвязанныйТелефон");
Запрос.УстановитьПараметр("Вид", Вид);
В процессе обсуждения на форуме возникла типичная ошибка компиляции, когда разработчик попытался написать следующий код:
СправочникСсылка.ВидыКонтактнойИнформации = Вид;
А затем по совету коллег изменил его на:
Справочник.ВидыКонтактнойИнформации = Вид;
Оба эти варианта ошибочны по своей сути. Разберемся, почему компилятор выдает ошибки:
СправочникСсылка — это тип данных, описывающий ссылку на любой справочник в системе. Ему нельзя присвоить значение напрямую, это не переменная и не объект метаданных.Справочник — это несуществующий тип или объект в глобальном контексте.Справочники (обязательно с буквой «и» на конце). Например: Справочники.ВидыКонтактнойИнформации. Однако даже этому менеджеру нельзя напрямую присвоить значение переменной Вид. Мы можем лишь вызывать у него методы поиска (например, НайтиПоНаименованию() или НайтиПоКоду()).Если вы работаете в современной конфигурации, разработанной на основе **Библиотеки стандартных подсистем (БСП)** (например, УТ 11, ERP, Комплексная автоматизация, УНФ), то прямое обращение к табличной части справочника Справочник.СтруктурныеЕдиницы.КонтактнаяИнформация может вообще не вернуть данных.
В таких системах контактная информация часто выносится в отдельный регистр сведений — РегистрСведений.КонтактнаяИнформация. В самом справочнике табличная часть может быть пустой или использоваться только как временное хранилище.
Чтобы ваш код работал стабильно и не зависел от обновлений конфигурации, следует использовать программный интерфейс БСП — общий модуль УправлениеКонтактнойИнформацией. Посмотрим на пример кода, который решает задачу получения контактной информации без написания сложных ручных запросов:
// 1. Находим нужный вид контактной информации
ВидКИ = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Телефон");
Если ЗначениеЗаполнено(ВидКИ) Тогда
// 2. Получаем контактную информацию с помощью стандартной функции БСП
// Функция автоматически определит, где лежат данные: в ТЧ или в регистре сведений
ТаблицаКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(ДанныеОбъекта.Ссылка, ВидКИ, ТекущаяДатаСеанса(), Ложь);
// 3. Обходим полученную таблицу результатов
Для Каждого СтрокаКИ Из ТаблицаКИ Цикл
Сообщить("Вид: " + СтрокаКИ.Вид + " | Представление: " + СтрокаКИ.Представление);
КонецЦикла;
Иначе
Сообщить("Вид контактной информации не найден!");
КонецЕсли;
Если вы написали запрос, но данные не выводятся, не пытайтесь угадать причину по тексту кода. Воспользуйтесь проверенной методикой отладки:
ПО) или условиях фильтрации (ГДЕ).
РезультатЗапроса = Запрос.Выполнить();
РезультатЗапроса.Пустой() — вернет Истина, если в выборке нет ни одной строки.РезультатЗапроса.Выгрузить() — выгрузит результат в таблицу значений, которую можно визуально просмотреть в режиме отладки и проанализировать состав колонок и строк.Применяя эти простые правила, проверяя типы передаваемых параметров и используя готовые механизмы БСП, вы сможете быстро локализовать проблему и избежать досадных ошибок при работе с запросами в 1С.