Как выполнить отбор по ресурсу регистра сведений в 1С и исправить ошибку «Значение не является значением объектного типа (Количество)»?

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

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

Выясним причину ошибки

Рассмотрим исходный фрагмент кода, который приводит к сбою:


Рез = Набор.ВыгрузитьКолонку("НазваниеРесурса").Найти(ЗначениеОтбора);
Если Рез.Количество() = 0 Тогда 
    // Запись не найдена
КонецЕсли;

При выполнении этого кода платформа выдает ошибку: «Значение не является значением объектного типа (Количество)».

Проанализируем, почему это происходит:

  1. Метод ВыгрузитьКолонку() возвращает объект типа Массив.
  2. Метод Найти() у массива ищет элемент и возвращает его индекс (число) или значение Неопределено, если совпадение не найдено.
  3. Ни у числа, ни у значения Неопределено нет метода или свойства Количество(). Попытка вызвать этот метод приводит к фатальной ошибке выполнения.

Кроме того, важно помнить об ограничениях платформы: свойство Отбор объекта РегистрСведенийНаборЗаписей предназначен исключительно для установки фильтров по измерениям, регистратору и периоду. Устанавливать отбор непосредственно по ресурсам через объект Отбор платформа не позволяет.

Способ 1. Использование запроса (оптимальный вариант)

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

Рассмотрим пример кода для выборки с помощью запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	РС.Измерение1 КАК Измерение1,
    |	РС.НазваниеРесурса КАК НазваниеРесурса
    |ИЗ
    |	РегистрСведений.ИмяРегистраСведений КАК РС
    |ГДЕ
    |	РС.НазваниеРесурса = &ЗначениеОтбора";

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

Если РезультатЗапроса.Пустой() Тогда
    // Записи с указанным ресурсом не найдены
КонецЕсли;

Способ 2. Проверка результата поиска на Неопределено

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

Посмотрим на пример реализации:


ТЗ = Набор.Выгрузить();
НайденнаяСтрока = ТЗ.Найти(ЗначениеОтбора, "НазваниеРесурса");

Если НайденнаяСтрока = Неопределено Тогда
    // Запись не найдена
Иначе
    // Запись найдена, работаем со строкой
КонецЕсли;

Способ 3. Поиск с помощью метода НайтиСтроки()

Если вам требуется найти все строки таблицы значений, соответствующие значению ресурса, и узнать их точное количество, используем метод НайтиСтроки(). Этот метод принимает структуру с параметрами отбора и возвращает Массив строк, у которого есть метод Количество().

Разберем пример кода:


ТЗ = Набор.Выгрузить();
Отбор = Новый Структура("НазваниеРесурса", ЗначениеОтбора);
НайденныеСтроки = ТЗ.НайтиСтроки(Отбор);

Если НайденныеСтроки.Количество() = 0 Тогда
    // Записи не найдены
КонецЕсли;

Способ 4. Прямой обход набора записей в цикле

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

Проанализируем данный вариант:


ЗаписьНайдена = Ложь;
Для Каждого Запись Из Набор Цикл
    Если Запись.НазваниеРесурса = ЗначениеОтбора Тогда
        ЗаписьНайдена = Истина;
        Прервать;
    КонецЕсли;
КонецЦикла;

Если Не ЗаписьНайдена Тогда
    // Запись не найдена
КонецЕсли;
← На главную