Разработка и Конфигурация · 9 мин
1С: как удалить строку из табличной части программно
Как программно удалить строку из табличной части документа в 1С: методы Удалить, Очистить, циклы по условию, типичные ошибки и примеры кода на встроенном языке.
Удаление строк из табличной части — одна из самых частых операций при доработке документов и обработок в 1С. Встроенный язык предоставляет для этого методы Удалить() и Очистить(), однако неправильное их применение в цикле приводит к пропуску строк или ошибкам обращения по индексу.
Табличная часть в 1С — это коллекция строк, у каждой из которых есть индекс (начинается с нуля) и номер строки (начинается с единицы). Удалить строку можно по объекту строки, по индексу или очистить всю коллекцию целиком. Выбор способа зависит от задачи: точечное удаление, удаление по условию или полная очистка.
Ниже разобраны все рабочие варианты с примерами кода, различия между управляемыми и обычными формами, а также типичные ошибки, из-за которых удаление «не срабатывает» или удаляет не те строки.
Метод Удалить(): базовый синтаксис
Метод Удалить() принимает либо объект строки табличной части, либо её индекс. Оба варианта равнозначны, но передача объекта строки надёжнее, когда строка уже получена в цикле или через поиск.
// Удаление по объекту строки
СтрокаТЧ = Объект.Товары[0];
Объект.Товары.Удалить(СтрокаТЧ);
// Удаление по индексу (индексация с нуля)
Объект.Товары.Удалить(0);
// Удаление последней строки
Объект.Товары.Удалить(Объект.Товары.Количество() - 1);
После удаления номера строк пересчитываются автоматически, поэтому свойство НомерСтроки у оставшихся строк изменится. Если на номера завязана другая логика (например, ссылки на строки из другой табличной части), её нужно обновлять вручную.
Удаление строк по условию в цикле
Самая частая ошибка новичков — удаление строк прямо в цикле «Для Каждого» или при прямом переборе по индексу от первой строки к последней. При удалении текущей строки все последующие сдвигаются на позицию вверх, и следующая итерация пропускает строку.
Правильные подходы — обход коллекции с конца или предварительный сбор строк в массив:
// Способ 1: обход с конца
Для Индекс = 1 - Объект.Товары.Количество() По 0 Цикл
ТекИндекс = -Индекс;
Если Объект.Товары[ТекИндекс].Количество = 0 Тогда
Объект.Товары.Удалить(ТекИндекс);
КонецЕсли;
КонецЦикла;
// Способ 2: сбор в массив, затем удаление
СтрокиКУдалению = Новый Массив;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если СтрокаТЧ.Количество = 0 Тогда
СтрокиКУдалению.Добавить(СтрокаТЧ);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаТЧ Из СтрокиКУдалению Цикл
Объект.Товары.Удалить(СтрокаТЧ);
КонецЦикла;
Способ с массивом читается проще и безопаснее: цикл «Для Каждого» идёт по исходной коллекции, а удаление выполняется отдельно. Способ с обратным обходом экономит память на больших табличных частях.
Полная очистка табличной части
Если нужно удалить все строки, используйте метод Очистить(). Он быстрее и нагляднее, чем цикл с удалением каждой строки:
Объект.Товары.Очистить();
Метод вызывает события формы, связанные с изменением табличной части, поэтому в управляемой форме после очистки корректно отработают подписанные обработчики. В типовых конфигурациях часто вместо прямой очистки вызывают процедуры пересчёта документа, чтобы сбросить итоговые суммы и связанные реквизиты.
Удаление на управляемой форме и на сервере
В управляемом приложении код разделён на клиентский и серверный. Работа с табличной частью объекта (реквизит формы типа «ДанныеФормыКоллекция») доступна и на клиенте, поэтому удаление строки по нажатию кнопки можно выполнить без вызова сервера:
&НаКлиенте
Процедура УдалитьНулевыеСтроки(Команда)
СтрокиКУдалению = Новый Массив;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если СтрокаТЧ.Количество = 0 Тогда
СтрокиКУдалению.Добавить(СтрокаТЧ);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаТЧ Из СтрокиКУдалению Цикл
Объект.Товары.Удалить(СтрокаТЧ);
КонецЦикла;
Модифицированность = Истина;
КонецПроцедуры
Если удаление — часть серверной логики (например, при записи документа), код размещают в модуле объекта в обработчике ПередЗаписью или ОбработкаЗаполнения, обращаясь к табличной части через ЭтотОбъект.Товары.
Удаление строки по найденному значению
Когда нужно удалить строки с конкретным товаром или другим значением реквизита, удобно использовать НайтиСтроки() — он возвращает массив подходящих строк, которые затем удаляются:
Отбор = Новый Структура("Номенклатура", УдаляемаяНоменклатура);
НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);
Для Каждого СтрокаТЧ Из НайденныеСтроки Цикл
Объект.Товары.Удалить(СтрокаТЧ);
КонецЦикла;
Этот вариант устойчив к смещению индексов, потому что массив строк формируется до начала удаления. Для отбора по нескольким реквизитам просто добавьте их в структуру отбора.
- 1Определите условие, по которому строки должны быть удалены
- 2Соберите подходящие строки в массив через НайтиСтроки() или цикл
- 3Удалите каждую строку методом Удалить() уже после формирования списка
- 4При работе на форме установите признак Модифицированность
- 5Проверьте результат: количество строк и итоговые суммы документа
Ограничения и риски
Удаление строк из табличной части проведённого документа меняет движения по регистрам при перепроведении. Если документ участвует в последовательности или по нему построены отчёты, массовое удаление строк в закрытых периодах может нарушить учётные данные. Перед пакетной обработкой делайте резервную копию информационной базы.
Также учитывайте, что в типовых конфигурациях на удаление строк могут быть завязаны подписки на события и обработчики, пересчитывающие скидки, налоги и связанные табличные части. Прямое удаление в обход штатных механизмов формы может оставить документ в несогласованном состоянии — например, с итоговой суммой, не соответствующей строкам.
Проверка результата после удаления
После удаления полезно убедиться, что коллекция находится в ожидаемом состоянии. Минимальные проверки: количество строк соответствует ожиданию, условие отбора больше не возвращает строк, итоговые суммы пересчитаны.
Как проверить результат
Объект.Товары.Количество() уменьшилось на число удалённых строк
Количество не изменилось — удаление выполнялось над копией данных или без Записать()
НайтиСтроки() с тем же отбором возвращает пустой массив
Строки по-прежнему находятся — цикл пропускал строки из-за смещения индексов
Суммы по документу пересчитаны с учётом удалённых строк
Итоги устарели — не вызван штатный пересчёт типовой конфигурации
Что важно запомнить
Удаляйте строки методом Удалить() по объекту строки или индексу, всю табличную часть — методом Очистить(). При удалении по условию собирайте строки в массив или обходите коллекцию с конца. Изменения объекта сохраняются только после Записать(), а в проведённых документах требуют перепроведения и контроля движений.
Частые вопросы
Как удалить текущую строку табличной части на форме?
Используйте свойство Элементы.Товары.ТекущиеДанные на клиенте и передайте эту строку в Объект.Товары.Удалить(ТекущиеДанные). Перед удалением проверьте, что текущая строка существует (значение не Неопределено), иначе получите ошибку.
Почему после удаления в цикле остаются строки, которые должны были удалиться?
Причина — смещение индексов: после удаления строки следующая занимает её место, а цикл переходит к следующему индексу и пропускает её. Решение — обход коллекции с конца или предварительный сбор строк в массив с последующим удалением.
Чем отличается Удалить() от Очистить()?
Удалить() убирает одну конкретную строку по объекту или индексу, Очистить() удаляет все строки табличной части за один вызов. Для полной очистки всегда используйте Очистить() — это короче и эффективнее цикла.
Можно ли удалить строку табличной части запросом?
Нет, запросы в 1С предназначены только для чтения данных. Изменение табличных частей выполняется через объектную модель: получить объект документа методом ПолучитьОбъект(), удалить строки и вызвать Записать().
Удалил строки в обработке, но в базе ничего не изменилось. В чём дело?
Скорее всего, объект не был записан после изменений. Удаление строк происходит в памяти; для сохранения нужен вызов ОбъектДокумента.Записать() с нужным режимом (например, РежимЗаписиДокумента.Проведение для проведённого документа).
Как удалить строки табличной части у всех документов за период?
Выберите ссылки документов запросом, в цикле получайте объект каждого документа, удаляйте строки по условию и записывайте. Такую обработку обязательно тестируйте на копии базы и выполняйте в транзакции или с протоколированием, чтобы контролировать результат.