При разработке и доработке конфигураций 1С часто возникает тривиальная, но важная задача — очистить табличную часть документа или справочника от пустых строк. Такие строки могут появляться при загрузке данных из внешних файлов (Excel, CSV), при неаккуратном парсинге строк или в результате действий пользователей. Разберем по шагам, какие способы решения этой задачи существуют, и выясним причину возникновения типичных ошибок у начинающих программистов.
Самая распространенная ошибка начинающего разработчика — попытка удалить строки в обычном цикле Для Каждого или цикле со счетчиком от нуля до количества строк. Проанализируем ситуацию: когда вы удаляете строку, например, с индексом 2, следующая за ней строка (которая была под индексом 3) смещается вверх и получает индекс 2. Цикл же переходит к индексу 3, тем самым пропуская проверку сместившейся строки. В результате удаляются не все пустые строки, и алгоритм отрабатывает некорректно.
Чтобы избежать этого, рассмотрим несколько правильных подходов к программному удалению строк.
Классический метод, который безотказно работает еще со времен версии платформы 7.7. Суть заключается в том, чтобы перебирать строки табличной части, начиная с последней и двигаясь к первой. В этом случае удаление строки никак не влияет на индексы тех строк, которые мы еще не проверили.
Посмотрим на пример реализации данного алгоритма:
&НаКлиенте
Процедура УдалитьПустые(Команда)
Сч = Объект.Контрагенты.Количество();
Пока Сч > 0 Цикл
Сч = Сч - 1;
СтрокаТЧ = Объект.Контрагенты[Сч];
Если НЕ ЗначениеЗаполнено(СтрокаТЧ.Контрагент) Тогда
Объект.Контрагенты.Удалить(Сч);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗначениеЗаполнено универсальна и позволяет корректно обрабатывать различные "пустые" значения, будь то пустая ссылка, пустая строка, NULL или Неопределено.
Этот способ считается более современным и элегантным. Платформа 1С позволяет найти нужные строки по заданным параметрам с помощью метода НайтиСтроки, который возвращает массив строк табличной части. Затем мы перебираем этот массив и удаляем соответствующие строки из исходной таблицы.
Обратите внимание на тип данных колонки, по которой идет поиск. Если колонка имеет строковый тип, ищем пустую строку. Если ссылочный — пустую ссылку.
// Пример для колонки со строковым типом данных
МассивПустыхСтрок = ТЧ.НайтиСтроки(Новый Структура("Контрагент", ""));
Для Каждого СтрокаМассива Из МассивПустыхСтрок Цикл
ТЧ.Удалить(СтрокаМассива);
КонецЦикла;
Альтернативный вариант обхода массива, также исключающий проблемы со сдвигом индексов:
Строки = ТЧ.НайтиСтроки(Новый Структура("Контрагент,Количество,Сумма", "", 0, 0));
Пока Строки.Количество() > 0 Цикл
ТЧ.Удалить(Строки[0]);
Строки.Удалить(0); // Удаляем элемент из массива, чтобы цикл не стал бесконечным
КонецЦикла;
Если табличная часть содержит тысячи строк (например, при массовой загрузке данных), построчное удаление через объектную модель может работать медленно. В таких случаях рассмотрим профессиональный подход — использование языка запросов.
ГДЕ накладываем условие отбора (например, исключаем строки, где контрагент пустой).Этот метод полностью исключает необходимость циклов и работает максимально быстро.
Еще один вариант обхода проблемы со сдвигом индексов — работа через временные таблицы и массивы. Разберем логику:
Скопировать для создания таблицы только с нужными данными.Очистить.Часто проблема пустых строк возникает на этапе парсинга и загрузки данных. Как метко подмечают опытные разработчики: "Лучше не добавлять что-нибудь ненужное, чем потом удалять". Проанализируем ваш код заполнения табличной части.
Вместо того чтобы сначала использовать метод Добавить, а затем проверять результат, делайте проверку до добавления:
ЗначениеКонтрагента = Сред(ДанныеСтроки[0], Найти(ДанныеСтроки[0], "\")+1);
// Дополнительная обработка строки...
Если ЗначениеЗаполнено(ЗначениеКонтрагента) Тогда
НоваяСтрока = Объект.ДанныеТО.Добавить();
НоваяСтрока.Контрагент = ЗначениеКонтрагента;
// Заполнение остальных реквизитов
КонецЕсли;
Если задача заключается в автоматической очистке пустых строк перед сохранением документа, правильным решением будет использование обработчика события ПередЗаписью (в модуле объекта) или создание отдельной подписки на событие ПередЗаписью для ряда документов.
Важно: Никогда не выполняйте модификацию данных табличной части (в том числе удаление строк) внутри процедуры ОбработкаПроведения. Это категорически противоречит архитектурным стандартам 1С. Для автоматического выявления подобных ошибок и проверки кода можно использовать обработку для поиска нарушений стандартов БСП и платформы.
В некоторых случаях задача очистки возникает у рядовых пользователей. В современных типовых конфигурациях (1С:ERP, УТ, КА, Бухгалтерия) в командной панели табличной части или в меню "Еще" часто присутствует штатная кнопка "Удалить пустые строки". Рекомендуем сначала проверить ее наличие.
Если кнопки нет, воспользуйтесь стандартными горячими клавишами (совет от ленивого, но умного программиста):
Подводя итоги, мы разобрали множество способов управления строками табличных частей. Используйте обратные циклы для небольших таблиц, метод поиска строк для лаконичного кода и запросы — для максимальной производительности при больших объемах данных.