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