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