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

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает задача обрезать «хвост» таблицы значений (ТЗ). Например, после выполнения запроса или сортировки нам требуется оставить только первые N строк. Самым очевидным и быстрым способом кажется прямое переопределение количества строк. Однако в среде разработчиков «семерки» долгое время ходили слухи о небезопасности такого метода. Разберем детально, как работает этот механизм, в чем заключаются реальные риски и как их избежать.

Механизм работы метода КоличествоСтрок(N)

Рассмотрим стандартную ситуацию. У нас есть объект ТаблицаЗначений, в котором содержится 100 строк. Нам необходимо оставить только первые 95. Мы можем использовать следующий код:


// Пример обрезания ТЗ
ТЗ.КоличествоСтрок(95);

Проанализируем, что происходит «под капотом» платформы. Метод КоличествоСтрок при передаче в него параметра, меньшего текущего значения, просто изменяет внутренний указатель (счетчик) количества доступных строк в объекте. С точки зрения стандартной платформы 1С 7.7, это законная и документированная операция. Все строки, индекс которых превышает новое значение, становятся недоступными для методов перебора, поиска и обращения по индексу.

Сравнение со способом УдалитьСтроку()

Посмотрим на альтернативный вариант — удаление строк в цикле с конца таблицы. Это могло бы выглядеть так:


// Удаление строк в цикле
Для Ном = 1 По 5 Цикл
    ТЗ.УдалитьСтроку(ТЗ.КоличествоСтрок());
КонецЦикла;

Выясним причину, почему первый вариант предпочтительнее. Использование КоличествоСтрок(N) работает за константное время O(1). Платформа просто меняет одно числовое значение в заголовке структуры ТЗ. Метод УдалитьСтроку, даже если он удаляет последнюю строку, требует большего количества ресурсов на обслуживание связей внутри объекта. Если же удаление происходит из середины, системе приходится физически сдвигать вышестоящие элементы в памяти, что на больших таблицах (десятки тысяч строк) приводит к катастрофическому падению производительности.

Разбор мифов о «глючности» метода

Многие разработчики опасаются использовать КоличествоСтрок(N) для уменьшения таблицы, ссылаясь на возможные ошибки при последующей сортировке или поиске. Проанализируем, откуда взялись эти опасения. Как показывают обсуждения на профильных форумах, основные проблемы возникали не в штатной конфигурации, а при использовании внешней компоненты 1CPP.dll.

В расширении 1CPP существует объект ИндексированнаяТаблица. Вот в нем прямое изменение количества строк через КоличествоСтрок() действительно могло привести к критическим ошибкам (Access Violation). Это происходило из-за того, что индексы, построенные компонентой для быстрого поиска, не обновлялись автоматически при «силовом» изменении счетчика строк 1С. В результате компонента пыталась обратиться к данным по старым индексам, которые указывали на уже «отсеченную» область памяти.

Важно: Если вы используете стандартную ТаблицаЗначений без внешних надстроек, метод КоличествоСтрок(N) абсолютно безопасен.

Нюансы работы с памятью и очистка объектов

Рассмотрим ситуацию с точки зрения потребления оперативной памяти. Когда мы обрезаем таблицу, физическая память, выделенная под удаленные строки, не всегда освобождается немедленно. 1С 7.7 склонна удерживать зарезервированный объем памяти до тех пор, пока объект ТЗ не будет полностью уничтожен или переинициализирован методом Очистить().

Также проанализируем поведение агрегатных объектов. Если в колонках таблицы хранились ссылки на другие объекты (например, другие ТЗ или СпискиЗначений), то при выполнении ТЗ.КоличествоСтрок(95) ссылки на объекты в строках с 96 по 100 будут разорваны. Однако деструкторы этих объектов сработают в соответствии с внутренними алгоритмами 1С, что в редких случаях может вызвать временное удержание памяти.

Рекомендации по использованию в циклах

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


// ОШИБОЧНЫЙ КОД
Для Ном = 1 По ТЗ.КоличествоСтрок() Цикл
    Если ТЗ.ПолучитьЗначение(Ном, "Статус") = "Удалить" Тогда
        // Попытка обрезать таблицу прямо во время итерации
        ТЗ.КоличествоСтрок(ТЗ.КоличествоСтрок() - 1); 
    КонецЕсли;
КонецЦикла;

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

Выводы и лучшие практики

Подведем итог нашему анализу:

  1. Безопасность: Для стандартной ТаблицаЗначений в 1С 7.7 метод КоличествоСтрок(N) является штатным, быстрым и безопасным способом удаления строк с конца.
  2. Скорость: Это самый производительный метод, работающий мгновенно независимо от размера таблицы.
  3. Ограничения: Будьте осторожны, если в вашем проекте используется 1CPP и объект ИндексированнаяТаблица. В этом случае используйте специализированные методы компоненты для удаления строк.
  4. Сортировка: Метод Сортировать() в штатной ТЗ корректно учитывает новое количество строк после обрезания «хвоста».

Таким образом, мы можем уверенно использовать КоличествоСтрок(N) для оптимизации работы с данными, не опасаясь за стабильность системы в рамках стандартного функционала платформы.

← На главную