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