Как в 1С удалить все строки в таблице значений, кроме последней?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие часто возникают задачи по манипуляции данными во временных структурах, таких как ТаблицаЗначений. Одной из типичных, но иногда вызывающих затруднение задач является очистка таблицы с сохранением лишь одной — последней — строки. На первый взгляд задача кажется тривиальной, однако при её реализации важно учитывать особенности работы платформы с памятью, жизненный цикл объектов типа СтрокаТаблицыЗначений и производительность системы при больших объемах данных.

В этой статье мы подробно разберем несколько подходов к решению этой задачи, проанализируем их эффективность и выясним, почему некоторые очевидные решения могут привести к ошибкам в коде.

Метод 1. Удаление первой строки в цикле

Самый простой и интуитивно понятный способ — это последовательное удаление самой первой строки таблицы до тех пор, пока в ней не останется всего один элемент. Рассмотрим этот алгоритм подробнее.

Принцип работы: мы проверяем количество строк в таблице. Если оно больше единицы, мы удаляем строку с индексом 0. Платформа при этом автоматически сдвигает все последующие строки вверх, и бывшая вторая строка становится первой.


Пока ТЗ.Количество() > 1 Цикл
    ТЗ.Удалить(0);
КонецЦикла;

Анализ ситуации: данный метод идеально подходит для таблиц с небольшим количеством строк (как в случае автора темы, где строк не более трех). Однако стоит помнить о производительности. При удалении первой строки (индекс 0) в большой таблице (например, 100 000 строк), платформа вынуждена 99 999 раз перемещать данные в памяти, чтобы заполнить образовавшуюся пустоту. Если ваша таблица велика, этот способ будет крайне медленным.

Метод 2. Удаление строк с конца (Оптимизированный цикл)

Чтобы избежать постоянного сдвига строк в памяти, эффективнее использовать удаление с конца таблицы. Мы оставим последнюю строку, а все остальные удалим, начиная с предпоследней и двигаясь к началу.

Разберем по шагам логику этого процесса:

  1. Определяем индекс последней строки: ТЗ.Количество() - 1.
  2. Начинаем цикл с индекса ТЗ.Количество() - 2 (предпоследняя строка).
  3. Двигаемся с шагом -1 до 0.

ВсегоСтрок = ТЗ.Количество();
Для Индекс = ВсегоСтрок - 2 По 0 Шаг -1 Цикл
    ТЗ.Удалить(Индекс);
КонецЦикла;

Почему это быстрее? При удалении строки, за которой нет других данных (в данном случае мы удаляем строки «с хвоста»), системе не нужно пересчитывать индексы и сдвигать оставшиеся элементы. Хотя мы оставляем самую последнюю строку, технически удаление элементов перед ней с конца все равно эффективнее, чем постоянное удаление нулевого индекса.

Метод 3. Использование метода Скопировать() и массива строк

Платформа 1С предоставляет мощный инструмент для работы с подмножествами строк — метод Скопировать(). Это, пожалуй, самый «красивый» и быстрый способ с точки зрения использования встроенных функций платформы.

Проанализируем пример кода:


МассивСтрТЗ = Новый Массив;
Если ТЗ.Количество() > 0 Тогда
    МассивСтрТЗ.Добавить(ТЗ[ТЗ.Количество() - 1]);
    ТЗ = ТЗ.Скопировать(МассивСтрТЗ);
КонецЕсли;

Важные нюансы:

Метод 4. Сохранение данных через структуру (Безопасный метод)

Выясним причину, по которой нельзя просто написать Стр = ТЗ[Последняя]; ТЗ.Очистить(); ТЗ.Добавить(Стр);. Объект типа СтрокаТаблицыЗначений жестко связан со своим владельцем. Как только вызывается метод Очистить(), строка уничтожается в памяти, и ссылка на неё становится недействительной.

Поэтому правильным подходом будет сохранение значений колонок в промежуточный контейнер, который не зависит от таблицы (например, в структуру), очистка таблицы и создание новой строки.

Рассмотрим подробный пример реализации:


Если ТЗ.Количество() > 0 Тогда
    // 1. Получаем последнюю строку
    ПоследняяСтрока = ТЗ[ТЗ.Количество() - 1];
    
    // 2. Копируем данные в структуру
    ДанныеСтроки = Новый Структура;
    Для Каждого Колонка Из ТЗ.Колонки Цикл
        ДанныеСтроки.Вставить(Колонка.Имя, ПоследняяСтрока[Колонка.Имя]);
    КонецЦикла;
    
    // 3. Очищаем таблицу - это происходит мгновенно
    ТЗ.Очистить();
    
    // 4. Добавляем новую строку и заполняем её данными
    НоваяСтрока = ТЗ.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки);
КонецЕсли;

Этот метод сочетает в себе высокую скорость (метод Очистить() работает значительно быстрее удаления строк по одной) и надежность, так как мы не создаем новую таблицу значений, а работаем в рамках существующего объекта.

Подведем итоги

Выбор конкретного метода зависит от контекста вашей задачи:

Мы рассмотрели основные способы манипуляции строками ТаблицыЗначений. Надеемся, что этот разбор поможет вам избежать «зависаний» при решении подобных задач и писать оптимальный, отказоустойчивый код.

← На главную