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