К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как программно очистить табличную часть в 1С

Как программно очистить табличную часть документа или справочника в 1С: метод Очистить(), удаление строк в цикле, отборы, типичные ошибки и примеры кода на встроенном языке.

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

Основной инструмент — метод Очистить(), который есть у любой табличной части и у таблицы значений. Он удаляет все строки за один вызов, работает быстро и не требует цикла. Однако на практике встречаются нюансы: очистка в модуле объекта и на форме ведёт себя по-разному, удаление строк в цикле «в лоб» приводит к пропуску элементов, а при работе с управляемыми формами нужно учитывать контекст клиента и сервера.

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

Базовый способ: метод Очистить()

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

// Очистка табличной части документа

ДокументОбъект.Товары.Очистить();

// Очистка таблицы значений

ТаблицаРезультат.Очистить();

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

После вызова Очистить() количество строк становится равным нулю, что легко проверить методом Количество(). Если табличная часть отображается на форме, её визуальное содержимое обновится автоматически при обращении к данным объекта.

bsl
Объект.Товары.Очистить();
Если Объект.Товары.Количество() = 0 Тогда
    Сообщить("Табличная часть очищена");
КонецЕсли;

Очистка в модуле объекта и на форме: в чём разница

В модуле объекта (например, в обработчике ОбработкаЗаполнения или ПередЗаписью) обращение идёт напрямую через ЭтотОбъект или через параметр обработчика. Здесь очистка выполняется на сервере, и результат попадёт в базу при записи объекта.

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

// Перед заполнением по новым данным очищаем старые строки

Товары.Очистить();

// ... далее добавление новых строк

КонецПроцедуры

На форме ситуация тоньше. В управляемой форме реквизит Объект — это данные формы, и обращение Объект.Товары.Очистить() допустимо, но методы объекта как такового недоступны: нельзя, например, вызвать Записать() напрямую. Если очистка выполняется в клиентской процедуре, обращение к Объект.Товары разрешено, поскольку коллекция доступна на клиенте.

Типичная команда формы выглядит так:

&НаКлиенте

Процедура ОчиститьТовары(Команда)

Объект.Товары.Очистить();

Модифицированность = Истина;

КонецПроцедуры

Удаление строк по условию

Когда нужно удалить не все строки, а только часть — например, строки с нулевым количеством или по конкретной номенклатуре — есть два корректных подхода: обход коллекции с конца и использование отбора с поиском строк.

Обход с конца

Классическая ошибка новичка — удалять строки в прямом цикле Для Каждого или в цикле по индексу от нуля. При удалении текущего элемента индексы остальных сдвигаются, и следующая строка пропускается. Надёжное решение — идти от последней строки к первой:

КолвоСтрок = Объект.Товары.Количество();

Для Сч = 1 По КолвоСтрок Цикл

СтрокаТаб = Объект.Товары[КолвоСтрок - Сч];

Если СтрокаТаб.Количество = 0 Тогда

Объект.Товары.Удалить(СтрокаТаб);

КонецЕсли;

КонецЦикла;

Удаление через НайтиСтроки

Если условие — равенство одного или нескольких полей, удобнее метод НайтиСтроки() с отбором. Он возвращает массив найденных строк, который затем удаляется в простом цикле — здесь сдвиг индексов не страшен, потому что в массиве хранятся ссылки на сами строки, а не их позиции.

Отбор = Новый Структура("Номенклатура", ВыбраннаяНоменклатура);

НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);

Для Каждого СтрокаТаб Из НайденныеСтроки Цикл

Объект.Товары.Удалить(СтрокаТаб);

КонецЦикла;

Типичные ошибки
01
Удаление строк в прямом цикле Для Каждого — часть строк пропускается из-за сдвига индексов
02
Использование цикла с Удалить(0) для полной очистки вместо одного вызова Очистить() — код работает в разы медленнее
03
Очистка табличной части на клиенте без установки Модифицированность — изменения теряются при закрытии
04
Обращение к табличной части по имени строкой через квадратные скобки без проверки её существования — ошибка выполнения в чужих конфигурациях

Очистка табличной части у записанного объекта через ссылку

Если документ уже записан в базе, а очистить его табличную часть нужно из внешней обработки или другого кода, работа идёт через объект, полученный из ссылки. После очистки объект обязательно записывается, иначе изменения не сохранятся.

ДокОбъект = ДокументСсылка.ПолучитьОбъект();

ДокОбъект.Товары.Очистить();

ДокОбъект.Записать();

Здесь важно учитывать два момента. Во-первых, запись документа запускает все его обработчики — проверки заполнения, проведение, подписки на события. Если документ проведён, потребуется режим записи с отменой проведения или перепроведение. Во-вторых, массовая обработка множества документов в цикле с ПолучитьОбъект() и Записать() — тяжёлая операция; для больших объёмов её стоит выполнять в транзакции с контролем ошибок или в фоновом задании.

Очистка таблицы значений и динамического списка на форме

Реквизит формы типа «ТаблицаЗначений» очищается тем же методом Очистить(). Если таблица заполняется из запроса заново, предварительная очистка обязательна — иначе Загрузить() добавит строки к существующим и данные задвоятся.

ТаблицаНаФорме.Очистить();

ТаблицаНаФорме.Загрузить(РезультатЗапроса.Выгрузить());

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

Сравнение вариантов

Очистить()

Полное удаление всех строк. Самый быстрый способ, подходит везде, где нужна пустая таблица

Удалить() в цикле с конца

Выборочное удаление по сложному условию, которое не выразить равенством полей

НайтиСтроки() + Удалить()

Удаление строк по точному совпадению значений одного или нескольких полей

Перезаполнение через Загрузить()

Для таблиц значений: очистка плюс заполнение новыми данными одной операцией

Проверка результата и контрольные точки

После очистки полезно убедиться, что коллекция действительно пуста, прежде чем продолжать логику. Для этого служит метод Количество(): нулевое значение означает успешную очистку. В отладчике содержимое табличной части видно через вычисление выражения Объект.Товары.Количество() или через табло.

Если после очистки и записи строки «возвращаются», почти всегда причина в одном из трёх: объект не был записан, запись прошла в обработчике, который заново заполняет табличную часть (например, ПриЗаписи или подписка), либо очищалась копия данных формы, а не сам объект. Проверяйте цепочку: очистка → запись → повторное чтение из базы.

Контрольные точки

Как проверить результат

Количество строк после Очистить()
Норма

Количество() возвращает 0

Тревожный признак

Строки остались — очистка применена не к той коллекции

Данные после записи объекта
Норма

При повторном открытии табличная часть пуста

Тревожный признак

Строки вернулись — объект не записан или обработчик перезаполняет таблицу

Флаг модифицированности формы
Норма

После очистки форма предлагает записать при закрытии

Тревожный признак

Форма закрывается молча — изменения потеряны

Частые вопросы

Можно ли очистить табличную часть без записи документа?

Да, если работа идёт в открытой форме: очистка меняет данные в памяти, а запись выполнит пользователь кнопкой «Записать» или «Провести». Если же объект не открыт, изменения из базы читаются и пишутся только через ПолучитьОбъект() и Записать() — без записи очистка не сохранится.

Почему цикл Для Каждого с Удалить() пропускает строки?

При удалении текущего элемента коллекции индексы оставшихся строк сдвигаются на единицу, а итератор переходит к следующей позиции — так одна строка оказывается пропущенной. Решение: обход коллекции с конца по индексу или удаление по массиву, полученному через НайтиСтроки().

Как очистить несколько табличных частей документа сразу?

Переберите их через метаданные: Для Каждого ТабЧасть Из ДокОбъект.Метаданные().ТабличныеЧасти Цикл ДокОбъект[ТабЧасть.Имя].Очистить(); КонецЦикла. Такой код универсален и не зависит от конкретного вида документа.

Очистится ли табличная часть при УстановитьНовыйНомер или копировании документа?

Нет. При копировании документа табличные части переносятся со всеми строками. Если копия должна быть пустой, очистку нужно выполнить явно — например, в обработчике ПриКопировании модуля объекта вызовом Очистить() для нужных табличных частей.

Чем отличается Очистить() у табличной части от присваивания пустой таблицы?

Табличной части объекта нельзя присвоить другую таблицу — она существует как часть объекта. Метод Очистить() удаляет строки внутри неё. Присваивание возможно только для таблиц значений и реквизитов формы соответствующего типа.

Безопасно ли очищать табличную часть в проведённом документе?

Технически возможно, но при перепроведении движения документа будут пересчитаны по пустой табличной части, что исказит учётные данные. Перед такими изменениями делайте резервную копию и проверяйте логику на копии базы.

Итог

Что важно запомнить

Для полной очистки табличной части используйте метод Очистить() — он быстрый и безопасный. Частичное удаление делайте обходом с конца или через НайтиСтроки(). На форме не забывайте про Модифицированность, а при работе со ссылкой — про Записать(). Массовую очистку проведённых документов выполняйте только после резервного копирования.