При загрузке данных из внешних источников, таких как Excel, мы часто сталкиваемся с избыточностью данных. Представим ситуацию: у нас есть табличная часть на 100 колонок, но нам необходимо программно обработать и выгрузить в объект ТаблицаЗначений только те столбцы, которые содержат числовые данные и сумма которых по всем строкам больше нуля. В рамках этой статьи мы разберем, как эффективно решить эту задачу, соблюдая требования платформы 1С к именованию объектов и оптимизации производительности.
Первый и самый очевидный способ — выгрузить всю табличную часть в ТаблицаЗначений, а затем «почистить» ее от ненужных данных. Проанализируем этот подход. Основная хитрость здесь заключается в правильном обходе коллекции колонок. Если мы будем удалять колонки в обычном цикле (от первой к последней), то индексы сместятся, и мы пропустим часть данных или получим ошибку.
Рассмотрим правильный алгоритм удаления с конца:
// 1. Выгружаем все данные из табличной части объекта в ТЗ
ТЗ = Объект.ИмяТабличнойЧасти.Выгрузить();
// 2. Обходим колонки с конца к началу, чтобы не сбить индексы при удалении
КоличествоКолонок = ТЗ.Колонки.Количество();
Для Индекс = 1 По КоличествоКолонок Цикл
НомерКолонки = КоличествоКолонок - Индекс;
ТекущаяКолонка = ТЗ.Колонки[НомерКолонки];
// Проверяем итог по колонке. Метод Итог() работает быстро
Попытка
Если ТЗ.Итог(ТекущаяКолонка.Имя) <= 0 Тогда
ТЗ.Колонки.Удалить(ТекущаяКолонка);
КонецЕсли;
Исключение
// Если колонка не числовая, метод Итог() вызовет исключение
// В этом случае решаем: оставить колонку или удалить
ТЗ.Колонки.Удалить(ТекущаяКолонка);
КонецПопытки;
КонецЦикла;
Важный нюанс: метод Итог() встроен в объект ТаблицаЗначений и работает на уровне платформы крайне быстро. Однако он требует, чтобы тип данных в колонке был числовым. Если данные из Excel загрузились как строки, предварительно потребуется их типизация.
Если мы заранее знаем структуру и хотим избежать лишних операций по копированию всех данных, мы можем пойти другим путем: проанализировать исходную табличную часть и добавить в новую ТаблицаЗначений только нужные колонки.
Разберем, как это сделать по шагам:
ТаблицаЗначений.Для заполнения данных можно использовать метод ВыгрузитьКолонку() и ЗагрузитьКолонку(). Проанализируем пример кода:
НоваяТЗ = Новый ТаблицаЗначений;
ИсходнаяТЗ = Объект.ИмяТабличнойЧасти.Выгрузить();
Для Каждого КолонкаТЧ Из Объект.ИмяТабличнойЧасти.ВыгрузитьКолонки().Колонки Цикл
// Считаем итог программно (если не уверены в типах)
СуммаПоКолонке = ИсходнаяТЗ.Итог(КолонкаТЧ.Имя);
Если СуммаПоКолонке > 0 Тогда
// Добавляем колонку в новую ТЗ, перенося имя и тип
НоваяТЗ.Колонки.Добавить(КолонкаТЧ.Имя, КолонкаТЧ.ТипЗначения, КолонкаТЧ.Заголовок);
// Копируем данные массива значений
МассивДанных = ИсходнаяТЗ.ВыгрузитьКолонку(КолонкаТЧ.Имя);
НоваяТЗ.ЗагрузитьКолонку(МассивДанных, КолонкаТЧ.Имя);
КонецЕсли;
КонецЦикла;
Часто в Excel заголовки содержат пробелы, спецсимволы или начинаются с цифр (например, "2023 год" или "Сумма (руб.)"). Платформа 1С предъявляет строгие требования к свойству Имя колонки таблицы значений — оно должно быть идентификатором. Это значит: никаких пробелов, знаков препинания (кроме подчеркивания) и начинаться должно с буквы или подчеркивания.
Выясним, как преобразовать произвольный заголовок в корректное имя. Для этого удобно использовать вспомогательную функцию. Рассмотрим логику очистки строки:
Функция ПолучитьКорректноеИмяКолонки(Знач ЗаголовокИзЭксель)
// Убираем лишние пробелы по краям
Результат = СокрЛП(ЗаголовокИзЭксель);
// Заменяем пробелы и дефисы на подчеркивания
Результат = СтрЗаменить(Результат, " ", "_");
Результат = СтрЗаменить(Результат, "-", "_");
// Удаляем все недопустимые символы (упрощенно)
ДопустимыеСимволы = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZабвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ0123456789_";
ОчищеннаяСтрока = "";
Для Поз = 1 По СтрДлина(Результат) Цикл
Символ = Сред(Результат, Поз, 1);
Если Найти(ДопустимыеСимволы, Символ) > 0 Тогда
ОчищеннаяСтрока = ОчищеннаяСтрока + Символ;
КонецЕсли;
КонецЦикла;
// Проверка на первый символ (не может быть цифрой)
ПервыйСимвол = Лев(ОчищеннаяСтрока, 1);
Если Найти("0123456789", ПервыйСимвол) > 0 Тогда
ОчищеннаяСтрока = "п_" + ОчищеннаяСтрока;
КонецЕсли;
Возврат ОчищеннаяСтрока;
КонецФункции
Используя такую функцию, мы можем создавать колонку, где Имя будет системным идентификатором, а Заголовок — исходным текстом из Excel. Это позволит пользователю видеть привычные названия, а программисту — обращаться к данным через ТЗ.Колонки.ИмяКолонки.
Проанализируем еще одну проблему: Excel часто передает числа как строки или значения с плавающей запятой, которые 1С может интерпретировать неоднозначно. Чтобы метод Итог() не выдавал ошибку, при создании колонок в ТаблицаЗначений настоятельно рекомендуется явно указывать описание типов.
Посмотрим на пример правильного создания колонки:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
КвалификаторыЧисла = Новый КвалификаторыЧисла(15, 2);
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , КвалификаторыЧисла);
ТЗ.Колонки.Добавить(ИмяИдентификатор, ОписаниеТипаЧисло, ОригинальныйЗаголовок);
При таком подходе, когда мы будем заполнять ТаблицаЗначений данными из Excel, платформа попытается автоматически привести значения к числу, что сделает расчет итогов корректным.
Если количество строк в вашей таблице исчисляется десятками тысяч, цикл по колонкам с методом Итог() может замедлиться. В этом случае мы можем применить механизм запросов. Мы можем поместить ТаблицаЗначений во временную таблицу и одним запросом получить суммы по всем 100 колонкам.
Разберем схему такого решения:
СтрШаблон или конкатенацию), где перечисляются все колонки: СУММА(Колонка1) КАК К1, СУММА(Колонка2) КАК К2....Этот метод значительно эффективнее, так как платформа оптимизирует агрегатные функции при работе с временными таблицами в памяти.
Таким образом, мы рассмотрели несколько стратегий фильтрации колонок. Выбор конкретного метода зависит от объема данных и необходимости сохранения исходной структуры. Главное — помнить про обратный порядок удаления и обязательную проверку имен на соответствие правилам идентификаторов 1С.