Как проверить СписокЗначений в 1С на пустое значение, если в нем есть элементы

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

В процессе разработки на платформе 1С:Предприятие начинающие программисты часто сталкиваются с неочевидным поведением коллекций значений. Одной из таких ситуаций является проверка объекта типа СписокЗначений на наличие данных. Проблема заключается в том, что список может формально содержать элементы, но при этом «смысловой» нагрузки они не несут (например, это пустые ссылки или неопределенные значения). В этой статье мы подробно разберем, почему стандартные методы могут вводить в заблуждение и как корректно выполнить проверку.

Анализ проблемы: почему ЗначениеЗаполнено и Количество не работают напрямую

Рассмотрим ситуацию, когда у нас есть переменная СписокФильтров. При попытке проверить ее стандартными методами мы получаем неожиданные результаты. Выясним причину такого поведения:

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

Проанализируем пример кода, который часто приводит к ошибкам:


// Ошибочный подход
Если ЗначениеЗаполнено(СписокФильтров) Тогда
    // Код выполнится, даже если в списке один пустой элемент
КонецЕсли;

Способ 1. Проверка конкретного элемента списка

Если мы заранее знаем, что в списке может быть только один элемент, или нам критически важно проверить именно первый элемент, мы должны обратиться напрямую к его свойству Значение. Разберем, как это сделать правильно, чтобы избежать ошибки обращения к несуществующему индексу:


Если СписокФильтров.Количество() > 0 Тогда
    Если ЗначениеЗаполнено(СписокФильтров[0].Значение) Тогда
        // Первый элемент действительно содержит данные
    КонецЕсли;
КонецЕсли;

Здесь мы сначала проверяем, что в списке в принципе есть строки, а затем анализируем содержимое первой строки. Это решает проблему, озвученную в обсуждении, когда список «как бы пустой», но содержит одну пустую запись.

Способ 2. Обход списка в цикле (наиболее надежный метод)

В реальных задачах СписокЗначений может содержать несколько строк, часть из которых заполнена, а часть — нет. Проверки только первого элемента СписокФильтров[0] будет недостаточно. Проанализируем ситуацию: если первый элемент пуст, а второй содержит ссылку на справочник, проверка по индексу [0] даст ложный результат. Рассмотрим алгоритм полного обхода:


ЕстьДанные = Ложь;
Для Каждого Элемент Из СписокФильтров Цикл
    Если ЗначениеЗаполнено(Элемент.Значение) Тогда
        ЕстьДанные = Истина;
        Прервать; // Нашли хотя бы одно заполненное значение, дальше можно не искать
    КонецЕсли;
КонецЦикла;

Если ЕстьДанные Тогда
    // Обрабатываем заполненный список
КонецЕсли;

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

Способ 3. Предварительная очистка списка от пустых значений

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


Индекс = СписокФильтров.Количество() - 1;
Пока Индекс >= 0 Цикл
    Если Не ЗначениеЗаполнено(СписокФильтров[Индекс].Значение) Тогда
        СписокФильтров.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

// Теперь обычная проверка будет работать корректно
Если СписокФильтров.Количество() > 0 Тогда
    // Список гарантированно содержит только полезные данные
КонецЕсли;

Способ 4. Использование метода ВыгрузитьЗначения()

Иногда удобнее работать не с самим объектом СписокЗначений, а с массивом его значений. Метод ВыгрузитьЗначения() позволяет получить массив, содержащий только данные из колонки Значение. Это полезно для передачи данных в другие функции или для быстрой отладки.

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


МассивЗначений = СписокФильтров.ВыгрузитьЗначения();
// Теперь мы можем работать с массивом
Для Каждого ТекЗначение Из МассивЗначений Цикл
    Если ЗначениеЗаполнено(ТекЗначение) Тогда
        // Значение найдено
    КонецЕсли;
КонецЦикла;

Нюансы работы с запросами

Выясним причину, по которой правильная проверка списка критически важна при работе с запросами. Если вы передаете СписокЗначений в качестве параметра запроса в условие ГДЕ Ссылка В (&СписокФильтров), платформа ведет себя следующим образом:

Поэтому всегда очищайте список или проверяйте его на «смысловую» пустоту перед передачей в запрос.

Обработка значения Неопределено

Проанализируем еще один важный момент: инициализацию переменной. Если ваш код подразумевает, что СписокФильтров может быть не создан вовсе, то попытка вызвать метод Количество() приведет к аварийному завершению программы. Разберем безопасный алгоритм проверки:


// 1. Проверяем, создан ли объект вообще
Если СписокФильтров = Неопределено Тогда
    Сообщить("Список не инициализирован");
Иначе
    // 2. Проверяем наличие записей
    Если СписокФильтров.Количество() = 0 Тогда
        Сообщить("В списке нет ни одного элемента");
    Иначе
        // 3. Проверяем содержательную часть первого элемента
        Если Не ЗначениеЗаполнено(СписокФильтров[0].Значение) Тогда
             Сообщить("Первый элемент списка пуст");
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Подведем итог: для корректной работы со СпискомЗначений всегда разделяйте понятия «наличие записи в списке» и «наличие данных внутри этой записи». Используйте проверку ЗначениеЗаполнено(ЭлементСписка.Значение) для получения достоверного результата.

← На главную