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

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

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

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

Удаление строк из табличной части документа — рутинная задача при доработке конфигураций 1С: очистка «Товаров» перед перезаполнением, удаление строк с нулевым количеством, отбор позиций по условию. Встроенный язык предлагает несколько способов, и выбор конкретного влияет на корректность пересчёта итогов, нумерации строк и работы обработчиков событий.

Главная ловушка новичков — удаление строк в прямом цикле по индексу: после каждого удаления коллекция «сдвигается», и часть строк просто пропускается. Вторая частая проблема — работа с объектом документа вместо данных формы (и наоборот), из-за чего изменения не сохраняются или не отображаются на форме.

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

Основные методы работы с табличной частью

Табличная часть документа в коде представлена коллекцией строк. Для удаления используются три базовых подхода: метод Очистить() удаляет все строки сразу, метод Удалить() удаляет конкретную строку (по объекту строки или по индексу), а отбор строк через НайтиСтроки() позволяет сначала собрать кандидатов на удаление, а потом удалить их пакетно.

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

Полная очистка табличной части

Самый простой и безопасный сценарий — удалить все строки разом. Для этого достаточно одного вызова:

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

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

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

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

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

СтрокиКУдалению = Новый Массив;

Для Каждого СтрокаТовары Из Объект.Товары Цикл

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

СтрокиКУдалению.Добавить(СтрокаТовары);

КонецЕсли;

КонецЦикла;

Для Каждого СтрокаКУдалению Из СтрокиКУдалению Цикл

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

КонецЦикла;

Альтернатива — обход коллекции в обратном порядке по индексу. При удалении «с конца» индексы ещё не обработанных строк не сдвигаются:

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

Для Индекс = 1 По КоличествоСтрок Цикл

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

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

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

КонецЕсли;

КонецЦикла;

Если условие простое и совпадает с отбором, удобен метод НайтиСтроки() — он возвращает массив строк по структуре отбора:

Отбор = Новый Структура("Количество", 0);

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

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

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

КонецЦикла;

Удаление текущей строки на форме документа

Когда пользователь работает с формой, удалять обычно нужно выделенную строку. В управляемой форме текущая строка табличного поля доступна через Элементы.Товары.ТекущиеДанные:

&НаКлиенте

Процедура УдалитьТекущуюСтроку(Команда)

ТекущиеДанные = Элементы.Товары.ТекущиеДанные;

Если ТекущиеДанные = Неопределено Тогда

Возврат;

КонецЕсли;

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

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

Для удаления нескольких выделенных строк используйте Элементы.Товары.ВыделенныеСтроки — это массив идентификаторов строк данных формы. Каждую строку получают через Объект.Товары.НайтиПоИдентификатору(Идентификатор), после чего удаляют. Соберите строки в массив заранее, чтобы не работать с изменяющейся коллекцией.

После программного удаления на клиенте имеет смысл установить признак модифицированности (Модифицированность = Истина), чтобы платформа предложила сохранить документ при закрытии формы. Обычно установка происходит автоматически при изменении данных, но при нестандартных сценариях лучше проконтролировать это явно.

Удаление строк на сервере и запись документа

Массовые операции — например, очистка табличных частей у группы документов — выполняются на сервере через объект документа. Типовой шаблон:

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

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

ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

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

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

Порядок безопасной массовой очистки
  1. 1
    Сделайте резервную копию базы или выгрузку затрагиваемых документов
  2. 2
    Отберите документы запросом с явными условиями отбора
  3. 3
    Для каждого документа получите объект и очистите или отфильтруйте табличную часть
  4. 4
    Запишите документ в нужном режиме, обернув запись в Попытка/Исключение
  5. 5
    Проверьте на выборке документов состав строк и движения по регистрам

Типичные ошибки и как их избежать

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

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

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

Типичные ошибки
01
Удаление в прямом цикле по индексу — часть строк пропускается и остаётся в табличной части
02
Передача строки из другой коллекции в Удалить() — ошибка выполнения или удаление не той строки
03
Отсутствие пересчёта итогов после удаления — сумма документа не соответствует строкам
04
Запись проведённого документа без перепроведения — движения по регистрам не соответствуют табличной части

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

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

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

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

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

Количество строк после удаления
Норма

Совпадает с ожидаемым числом оставшихся строк

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

Строк больше или меньше — ошибка в условии или пропуски при цикле

Итоговая сумма документа
Норма

Равна сумме по оставшимся строкам

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

Итог не пересчитан — вызовите штатную процедуру пересчёта

Движения по регистрам
Норма

Соответствуют новому составу строк после перепроведения

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

Движения старые — документ записан без проведения

Часто задаваемые вопросы

Можно ли удалить строку по номеру строки?

Да, но с осторожностью. Метод Удалить() принимает индекс строки, который на единицу меньше номера: Объект.Товары.Удалить(НомерСтроки - 1). Учтите, что номера строк у оставшихся элементов после удаления пересчитаются автоматически.

Почему после удаления строк на форме изменения не сохраняются?

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

Как удалить все строки, кроме одной или нескольких нужных?

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

Нужно ли перепроводить документ после удаления строк?

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

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

Напишите серверную процедуру или внешнюю обработку: запросом отберите ссылки документов, в цикле получайте объект, очищайте или фильтруйте табличную часть и записывайте. Обязательно обрабатывайте исключения и тестируйте на копии базы.

Чем Очистить() отличается от удаления строк в цикле?

Метод Очистить() удаляет все строки за один вызов и работает быстрее цикла с Удалить(). Цикл нужен только когда удаляется часть строк по условию. Для полной очистки всегда предпочтительнее Очистить().

Итог

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

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