При разработке на 1С часто возникает задача накопления данных в ТаблицаЗначений внутри циклов, особенно при выгрузке или чтении данных из внешних файлов, таких как Excel. Давайте разберем, почему возникают ошибки «пустой таблицы» или «перезатирания данных» и как правильно организовать архитектуру кода.
Главная ошибка, с которой сталкиваются начинающие разработчики, — это создание объекта ТаблицаЗначений внутри вызываемой функции, которая находится внутри цикла. В 1С любая переменная, созданная внутри процедуры или функции, является локальной. Как только выполнение кода выходит за пределы функции, эта переменная уничтожается, а память освобождается.
Если вы объявляете Перем ТЗ; в начале модуля, это лишь резервирует имя переменной. Если же внутри цикла вы каждый раз вызываете ТЗ = СоздатьОбъект("ТаблицаЗначений"), вы каждый раз создаете новую «чистую» таблицу, уничтожая результаты предыдущих итераций. Рассмотрим, как этого избежать.
Чтобы данные накапливались, нам нужно создать объект один раз, а затем передавать ссылку на него во все функции, которые должны с ним работать. Давайте разберем этот процесс по шагам.
Перем ТЗ; в самом начале модуля.ТаблицаЗначений до входа в основной цикл.Посмотрим на пример правильной организации кода:
// Правильная структура функции, которая принимает ТЗ как параметр
Функция ОбработатьСтроку(ТЗ, Товар, ТекСтрока, Excel)
// Добавляем новую строку в переданную таблицу
ТЗ.НоваяСтрока();
ТЗ.Авто = СокрЛП(Строка(Excel.Cells(ТекСтрока, СтлбАВТО).Value));
ТЗ.Водитель = СокрЛП(Строка(Excel.Cells(ТекСтрока, СтлбСотр).Value));
ТЗ.Документ = Сред(Строка(Excel.Cells(ТекСтрока, СтлбРН).Value), 21, 10);
ТЗ.ВЧ = СокрЛП(Строка(Excel.Cells(ТекСтрока, СтлбВЧ).Value));
Возврат 1;
КонецФункции
// Основная процедура
Процедура Выполнить()
// Создаем объект один раз перед циклом
ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Авто", "Строка");
ТЗ.НоваяКолонка("Водитель", "Строка");
ТЗ.НоваяКолонка("Документ", "Строка");
ТЗ.НоваяКолонка("ВЧ", "Строка");
Тов = СоздатьОбъект("Справочник.Номенклатура");
Excel = СоздатьОбъект("Excel.Application");
Excel.Workbooks.Open(СокрЛП(ИмяФайла));
Строк = 200; // Примерное количество строк
Для ТекСтрока = 2 По Строк Цикл
// Передаем ТЗ в функцию
Если ОбработатьСтроку(ТЗ, Тов, ТекСтрока, Excel) = 0 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Excel.Visible = 1;
КонецПроцедуры
Разберем подробнее, что изменилось:
Выполнить. Это экономит ресурсы процессора и памяти, так как мы не пересоздаем структуру таблицы на каждой итерации.ОбработатьСтроку, метод ТЗ.НоваяСтрока() работает именно с той таблицей, которую мы создали в начале. Это позволяет успешно накапливать строки данных.Помимо архитектуры работы с ТаблицаЗначений, стоит учесть еще несколько моментов для стабильной работы:
Excel.Application обязательно закрывайте книгу и приложение после завершения работы. Если не вызывать Excel.Quit(), процессы Excel будут «зависать» в диспетчере задач, что со временем приведет к нехватке оперативной памяти.Используя этот подход, вы избавитесь от ошибок, связанных с потерей данных, и сделаете ваш код более профессиональным, надежным и легким в поддержке.