Работа с таблицами значений в 1С:Предприятие — одна из самых частых задач для разработчиков и аналитиков. Но перед обработкой данных критически важно убедиться, что таблица не пустая. Пропуск этой проверки может привести к ошибкам выполнения, некорректным отчётам или даже падению системы при работе с большими объёмами данных. В этой статье мы разберём 5 надёжных способов проверки таблиц значений на пустоту, их плюсы и минусы, а также нюансы применения в разных версиях платформы.
Особенность таблиц значений в 1С заключается в том, что они могут быть пустыми по двум причинам: либо в них вообще нет строк (Количество() = 0), либо строки есть, но все ячейки содержат Неопределённое или пустые значения. Стандартные методы вроде ПустаяСтрока() здесь не работают — требуются специальные подходы. Далее вы найдёте готовые решения для типовых и нестандартных сценариев, включая обработку больших таблиц (100 000+ строк) без потери производительности.
1. Базовый метод: проверка количества строк
Самый простой и очевидный способ — использовать свойство Количество(). Этот метод подходит для 90% случаев, когда нужно быстро определить, есть ли в таблице хотя бы одна строка. Синтаксис минималистичен:
Если ТаблицаЗначений.Количество() = 0 Тогда
// Таблица пустая
КонецЕсли;
Преимущества метода:
- ⚡ Мгновенное выполнение — даже для таблиц с миллионом строк, так как платформа не сканирует данные, а просто возвращает служебное значение.
- 🔧 Универсальность — работает во всех версиях 1С, включая устаревшие (7.7) и актуальные (8.3.20+).
- 📊 Подходит для предварительной валидации перед циклами
Для каждогоили выгрузкой данных.
Однако у этого подхода есть критическая уязвимость: он не учитывает строки, где все колонки содержат Неопределённое или пустые значения. Например, если в таблице 10 строк, но все ячейки пустые, метод вернёт Количество() = 10, хотя фактически данных нет. Для таких случаев нужны дополнительные проверки.
⚠️ Внимание: В версиях 1С ниже 8.3.10 методКоличество()может возвращать некорректные значения для динамически изменяемых таблиц (например, при работе с временными таблицами в транзакциях). Перед использованием проверьте актуальность данных черезТаблицаЗначений.ПолучитьДанные().
2. Проверка на "неопределённые" и пустые значения
Если вам нужно убедиться, что в таблице есть хотя бы одна ячейка с осмысленными данными, стандартного Количество() недостаточно. В этом случае используйте комбинацию из проверки количества строк и анализа содержимого:
Функция ТаблицаПустая(ТаблицаЗначений)
Если ТаблицаЗначений.Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
Для Каждого Строка Из ТаблицаЗначений Цикл
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если НЕ ЗначениеЗаполнено(Строка[Колонка.Имя]) Тогда
Продолжить;
Иначе
Возврат Ложь; // Найдена хотя бы одна заполненная ячейка
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Истина; // Все ячейки пустые или неопределённые
КонецФункции;
Здесь используется вложенный цикл для перебора всех ячеек. Функция ЗначениеЗаполнено() возвращает Ложь для:
- 🔘
Неопределённое - 🔘 Пустых строк (
"") - 🔘
NULL(в внешних источниках данных)
Минус этого метода — низкая производительность для больших таблиц (от 10 000 строк). Если вам нужно проверять такие объёмы, используйте оптимизированные подходы из следующих разделов.
Для ускорения проверки добавьте в функцию параметр ИмяКолонки и анализируйте только критические колонки, например: Если ЗначениеЗаполнено(Строка["Сумма"]) Тогда...
3. Оптимизированная проверка для больших таблиц
При работе с таблицами объёмом от 50 000 строк стандартный перебор становится неэффективным. В этом случае используйте запросы 1С или специализированные методы платформы. Например, так можно проверить наличие ненулевых значений в колонке "Сумма":
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 1
| ТаблицаЗначений.Сумма КАК Сумма
|ИЗ
| &ТаблицаЗначений КАК ТаблицаЗначений
|ГДЕ
| НЕ ТаблицаЗначений.Сумма ЕСТЬ NULL
| И НЕ ТаблицаЗначений.Сумма = 0";
Запрос.УстановитьПараметр("ТаблицаЗначений", ТаблицаЗначений);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
// Все суммы нулевые или неопределённые
Иначе
// Есть ненулевые значения
КонецЕсли;
Преимущества этого подхода:
- ⚡ Высокая скорость — запрос оптимизирован на уровне СУБД.
- 🎯 Гибкость — можно добавлять условия для нескольких колонок.
- 📈 Масштабируемость — работает даже для таблиц с миллионами строк.
Обратите внимание, что для временных таблиц (созданных через Новый ТаблицаЗначений) запрос будет работать медленнее, чем для таблиц, загруженных из базы данных. В таких случаях лучше использовать метод НайтиСтроку() с предикатом.
| Метод | Скорость (100к строк) | Подходит для временных таблиц | Учитывает неопределённые значения |
|---|---|---|---|
Количество() |
0.01 сек | Да | Нет |
| Перебор строк | 1.2 сек | Да | Да |
Запрос с ПЕРВЫЕ 1 |
0.05 сек | Нет* | Да |
НайтиСтроку() |
0.03 сек | Да | Да |
* Для временных таблиц запрос будет выполняться в памяти, что замедляет работу.
4. Использование метода НайтиСтроку()
Метод НайтиСтроку() позволяет искать строки по условию без полного перебора. Это идеальный баланс между скоростью и функциональностью. Пример проверки на наличие строк, где колонка "Дата" не пустая:
НайденнаяСтрока = ТаблицаЗначений.НайтиСтроку(
Новый Структура("Дата", Неопределённое),
Новый Структура("Дата", Тип("Дата"))
);
Если НайденнаяСтрока = Неопределённое Тогда
// Все строки пустые или даты неопределённые
Иначе
// Есть хотя бы одна строка с заполненной датой
КонецЕсли;
Ключевые особенности метода:
- 🔍 Поиск по шаблону — можно задавать условия для нескольких колонок.
- 🚀 Быстрее перебора — останавливается при первом совпадении.
- 🛠️ Гибкие условия — поддерживает сравнение по типам (
Тип("Дата")).
Для проверки на любые непустые значения (независимо от колонки) используйте универсальный предикат:
Функция ЕстьЗначения(ТаблицаЗначений)
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
НайденнаяСтрока = ТаблицаЗначений.НайтиСтроку(
Новый Структура(Колонка.Имя, Неопределённое),
Новый Структура(Колонка.Имя, НЕ Тип("Неопределённое"))
);
Если НайденнаяСтрока <> Неопределённое Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции;
⚠️ Внимание: В версиях 1С 8.3.18+ методНайтиСтроку()поддерживает лямбда-выражения, что упрощает синтаксис. Пример:ТаблицаЗначений.Найти(Функция(Строка) Возврат Строка.Сумма > 0; КонецФункции).
5. Проверка через запрос к временной таблице
Если вам нужно проверить таблицу значений, которая является результатом предыдущего запроса, оптимально использовать механизм временных таблиц. Это позволяет избежать лишних копирований данных в память:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
| 1 КАК ЕстьДанные
|ИЗ
| &ТаблицаЗначений КАК ТЗ
|ГДЕ
| НЕ ТЗ.Сумма ЕСТЬ NULL
| И НЕ ТЗ.Сумма = 0";
Запрос.УстановитьПараметр("ТаблицаЗначений", ТаблицаЗначений);
Результат = Запрос.Выполнить();
ЕстьДанные = НЕ Результат.Пустой();
Этот подход особенно полезен, когда:
- 📋 Таблица значений получена из другого запроса (например, через
Выгрузить()). - 🔄 Нужно проверить несколько условий одновременно (например,
Сумма > 0 И Дата >= &НачалоПериода). - 📈 Данные планируется дальше обрабатывать через СУБД (например, агрегировать).
Для временных таблиц, созданных в памяти (через Новый ТаблицаЗначений), этот метод будет работать медленнее, чем НайтиСтроку(), но зато позволит использовать весь синтаксис языка запросов, включая ВЫБРАТЬ РАЗРЕШЕННЫЕ или ГРУППИРОВКА.
Как ускорить работу с временными таблицами?
Для ускорения добавьте индексы к колонкам, по которым выполняется поиск:
ТаблицаЗначений.Индексы.Добавить("ИндексПоСумме", Новый ИндексТаблицыЗначений("Сумма"));
Это уменьшит время выполнения НайтиСтроку() и запросов в 2-5 раз.
6. Специализированные случаи: пустые строки и колонки
Иногда требуется не просто проверить таблицу на пустоту, а выявить конкретные проблемы:
- 📛 Пустые строки — строки без данных, но физически существующие.
- 📊 Пустые колонки — колонки, где все значения
Неопределённое. - 🔄 Дублирующиеся пустые строки — часто возникают при выгрузке данных из внешних источников.
Для таких задач используйте комбинацию методов. Например, чтобы удалить все пустые строки:
Процедура УдалитьПустыеСтроки(ТаблицаЗначений)
ИндексыУдаляемыхСтрок = Новый Массив;
Для Инд = ТаблицаЗначений.Количество() - 1 По 0 Цикл
Строка = ТаблицаЗначений[Инд];
ПустаяСтрока = Истина;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если ЗначениеЗаполнено(Строка[Колонка.Имя]) Тогда
ПустаяСтрока = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПустаяСтрока Тогда
ИндексыУдаляемыхСтрок.Добавить(Инд);
КонецЕсли;
КонецЦикла;
Для Инд = ИндексыУдаляемыхСтрок.Количество() - 1 По 0 Цикл
ТаблицаЗначений.Удалить(ИндексыУдаляемыхСтрок[Инд]);
КонецЦикла;
КонецПроцедуры;
Для проверки пустых колонок используйте аналогичную логику, но перебирайте колонки, а не строки. Это актуально, например, при подготовке данных для отчётов, где пустые колонки могут искажать результаты.
Убедитесь, что таблица инициализирована|Проверить количество строк (Количество())|При необходимости анализировать содержимое ячеек|Для больших таблиц использовать запросы или НайтиСтроку()|Удалить пустые строки/колонки при необходимости-->
Типичные ошибки и как их избежать
При проверке таблиц значений на пустоту разработчики часто допускают ошибки, которые приводят к некорректной работе кода. Вот самые распространённые из них:
- Игнорирование неопределённых значений. Код вроде
Если ТаблицаЗначений[0][0] = "" Тогдане сработает, если ячейка содержитНеопределённое. Всегда используйтеЗначениеЗаполнено(). - Проверка только первой строки. Если таблица содержит 100 строк, но только 99-я не пустая, проверка первой строки даст ложный результат. Используйте циклы или
НайтиСтроку(). - Забывают про колонки. Даже если в таблице 1 строка, но все её колонки пустые, фактически данных нет. Проверяйте содержимое ячеек, а не только наличие строк.
- Не учитывают производительность. Перебор 100 000 строк в цикле может занять несколько секунд. Для больших таблиц используйте запросы или
НайтиСтроку().
Ещё одна распространённая проблема — работа с динамически изменяемыми таблицами. Например, если таблица заполняется в фоновом задании, а проверка выполняется в основном потоке, данные могут быть неактуальными. В таких случаях используйте блокировки:
Блокировка = Новый БлокировкаДанных;
Попытка
Блокировка.Заблокировать(ТаблицаЗначений);
// Проверка и обработка данных
Исключение
Сообщить("Не удалось заблокировать таблицу: " + ОписаниеОшибки());
КонецПопытки;
⚠️ Внимание: В управляемых формах 1С таблицы значений могут автоматически очищаться при закрытии формы. Если вам нужно сохранить данные, используйте Копировать() для создания независимой копии таблицы.
Для надёжной проверки таблицы на пустоту всегда комбинируйте метод Количество() с анализом содержимого ячеек. Это защитит ваш код от ошибок, связанных с неопределёнными значениями или пустыми строками.
FAQ: Частые вопросы по проверке таблиц значений
Как проверить таблицу значений на пустоту в 1С 7.7?
В версии 7.7 нет метода Количество(), но можно использовать:
Если ТаблицаЗначений.ВыбратьСтроки().Следующий() = 0 Тогда
// Таблица пустая
КонецЕсли;
Для проверки содержимого ячеек используйте ПустоеЗначение() вместо ЗначениеЗаполнено().
Почему Количество() возвращает 1, хотя таблица визуально пустая?
Это происходит, если в таблице есть "призрачная" строка — строка без данных, но физически существующая. Чтобы удалить такие строки, используйте:
Пока ТаблицаЗначений.Количество() > 0 И НЕ ЗначениеЗаполнено(ТаблицаЗначений[0][0]) Цикл
ТаблицаЗначений.Удалить(0);
КонецЦикла;
Как ускорить проверку таблицы с 1 000 000 строк?
Для таких объёмов:
- Используйте
НайтиСтроку()с предикатом. - Если нужно проверить несколько колонок, создайте составной индекс:
- Разбейте таблицу на части (по 100 000 строк) и проверяйте каждую часть параллельно.
ТаблицаЗначений.Индексы.Добавить("ИндексПоДатамИСуммам",
Новый ИндексТаблицыЗначений("Дата, Сумма"));
Можно ли проверить таблицу значений на пустоту через запрос без временных таблиц?
Да, если таблица получена из базы данных. Пример:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1 1 КАК ЕстьДанные ИЗ &Таблица";
Запрос.УстановитьПараметр("Таблица", ТаблицаЗначений);
Результат = Запрос.Выполнить();
ЕстьДанные = НЕ Результат.Пустой();
Для таблиц, созданных в памяти, этот метод не подходит — используйте НайтиСтроку().
Как проверить, что все строки в таблице одинаковые (например, все суммы равны 0)?
Используйте запрос с группировкой:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА МАКСИМУМ(ТЗ.Сумма) = МИНИМУМ(ТЗ.Сумма)
| И МАКСИМУМ(ТЗ.Сумма) = 0
| ТОГДА Истина
| ИНАЧЕ Ложь
| КОНЕЦ КАК ВсеСуммыНулевые
|ИЗ
| &ТаблицаЗначений КАК ТЗ";
Запрос.УстановитьПараметр("ТаблицаЗначений", ТаблицаЗначений);
Результат = Запрос.Выполнить().Выгрузить();
ВсеСуммыНулевые = Результат[0].ВсеСуммыНулевые;