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

· 9 мин

Содержание

Чтобы удалить выделенные строки в 1С, отметьте их мышью с зажатым Shift (подряд) или Ctrl (вразнобой) и нажмите Delete. В табличной части документа строки исчезнут сразу, а в списке справочника или журнале документов Delete только поставит пометку на удаление. В коде выделенные строки берут из свойства ВыделенныеСтроки элемента формы и удаляют через НайтиПоИдентификатору() и Удалить().

Главные проблемы начинаются в деталях: удалилась половина строк, а не все; строки табличного документа «съехали»; отчёт на СКД упрямо показывает лишнее. Ниже разобраны все эти случаи для платформы 8.3 с интерфейсом «Такси» — сначала руками, потом кодом.

Как выделить и удалить строки вручную в интерфейсе «Такси»

Этот способ одинаков во всех типовых конфигурациях: Бухгалтерии 3.0, ЗУП 3.1, УТ 11. Поведение задаёт платформа, а не конфигурация.

Выделение нескольких строк

Что нужноКак сделать
Строки подрядЩёлкните первую строку, затем с зажатым Shift — последнюю
Строки вразнобойЩёлкайте нужные строки с зажатым Ctrl
Расширить выделение с клавиатурыShift + стрелки вверх/вниз
Все строки таблицыCtrl+A, когда курсор стоит в таблице
Снять выделение со строкиПовторный щелчок по ней с зажатым Ctrl

Если щелчок с Shift выделяет только одну строку, у таблицы включён режим одиночного выделения. Это решение разработчика формы, пользователь его не меняет. Тогда удаляйте по одной или попросите программиста переключить режим.

Удаление в табличной части документа

  1. Откройте документ, например «Реализация (акт, накладная)» или «Поступление (акт, накладная)».
  2. Выделите строки на вкладке с товарами или услугами.
  3. Нажмите Delete. Тот же результат даст команда «Удалить» в контекстном меню (правая кнопка мыши) или в меню Ещё над таблицей.
  4. Нажмите «Записать» или «Провести и закрыть».

Пока документ не записан, удаление обратимо. Закройте форму и на вопрос о сохранении ответьте «Нет» — строки вернутся.

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

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

Здесь Delete работает иначе. Выделенные элементы получают пометку на удаление — красный крестик в первой колонке. Физически они остаются в базе.

  • 🗑️ Пометить или снять пометку — Delete или команда «Пометить на удаление / Снять пометку».
  • ⚡ Удалить сразу — Shift+Delete, но только если у пользователя есть право непосредственного удаления. В типовых ролях его обычно нет.
  • 🧹 Окончательно стереть помеченное — обработка «Удаление помеченных объектов» в разделе Администрирование → Обслуживание.

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

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

Удаляем строки табличного документа: руками и программно

Табличный документ — это то, что вы видите в печатной форме или отчёте: сетка ячеек как в Excel. Строки в нём удаляют иначе, чем в таблице документа.

В пользовательском режиме

Результат отчёта обычно открыт только для чтения. Чтобы убрать строки:

  1. Сохраните результат в файл .mxl или .xlsx кнопкой сохранения в форме отчёта.
  2. Откройте файл через Файл → Открыть (меню в левом верхнем углу окна) или в Excel.
  3. Выделите строки щелчком по их номерам слева, с Shift для диапазона.
  4. В контекстном меню выберите «Удалить». Нижние строки поднимутся.

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

Через встроенный язык

Удаляет строки метод УдалитьОбласть() со сдвигом по вертикали. Ключевое правило: удаляйте снизу вверх. Каждое удаление сдвигает всё, что ниже, и номера следующих областей перестают совпадать, если идти сверху.

&НаКлиенте
Процедура УдалитьВыделенныеСтрокиОтчета(Команда)

	// Собираем границы выделенных областей
	Границы = Новый ТаблицаЗначений;
	Границы.Колонки.Добавить("Верх");
	Границы.Колонки.Добавить("Низ");

	Для Каждого Выделение Из Элементы.Результат.ВыделенныеОбласти Цикл
		Если ТипЗнч(Выделение) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
			Стр = Границы.Добавить();
			Стр.Верх = Выделение.Верх;
			Стр.Низ = Выделение.Низ;
		КонецЕсли;
	КонецЦикла;

	// Самая нижняя область — первой
	Границы.Сортировать("Верх Убыв");

	Для Каждого Стр Из Границы Цикл
		ИмяОбласти = СтрШаблон("R%1:R%2",
			Формат(Стр.Верх, "ЧГ=0"), Формат(Стр.Низ, "ЧГ=0"));
		Область = Результат.Область(ИмяОбласти);
		Результат.УдалитьОбласть(Область, ТипСмещенияТабличногоДокумента.ПоВертикали);
	КонецЦикла;

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

Здесь Результат — реквизит формы типа «ТабличныйДокумент», Элементы.Результат — поле на форме, которое его показывает. Формат(..., "ЧГ=0") нужен, чтобы номер строки 1250 не превратился в «1 250» и имя области не сломалось.

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

Удаление выделенных строк табличной части кодом

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

&НаКлиенте
Процедура УдалитьВыделенные(Команда)

	// Копируем идентификаторы: исходный массив меняется при удалении строк
	Идентификаторы = Новый Массив;
	Для Каждого Ид Из Элементы.Товары.ВыделенныеСтроки Цикл
		Идентификаторы.Добавить(Ид);
	КонецЦикла;

	Для Каждого Ид Из Идентификаторы Цикл
		СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Ид);
		Если СтрокаТЧ <> Неопределено Тогда
			Объект.Товары.Удалить(СтрокаТЧ);
		КонецЕсли;
	КонецЦикла;

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

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

Три детали, которые часто упускают:

  • 📌 Копия массива. Если перебирать прямо Элементы.Товары.ВыделенныеСтроки и удалять, массив сокращается на ходу, и часть строк пропускается.
  • 📌 Модифицированность = Истина. Без неё форма может не спросить о сохранении при закрытии.
  • 📌 Пересчёт итогов. Если в документе есть сумма по табличной части, вызовите ту же процедуру пересчёта, что срабатывает при изменении строки.

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

Списки значений, таблицы значений и временные таблицы

Коллекции в памяти чистят по одному принципу: нельзя удалять элементы в прямом цикле по индексам, пока по коллекции идёт обход.

Обратный цикл

// ТЗ — ТаблицаЗначений с колонкой "Количество"
Для Сч = 1 По ТЗ.Количество() Цикл
	Строка = ТЗ[ТЗ.Количество() - Сч];
	Если Строка.Количество = 0 Тогда
		ТЗ.Удалить(Строка);
	КонецЕсли;
КонецЦикла;

Граница цикла вычисляется один раз в начале. Индекс ТЗ.Количество() - Сч берётся от текущего размера: при удалении строки уменьшаются оба, и цикл не перескакивает соседей. Пример с таблицей из 5 строк: на шаге 1 берётся строка с индексом 4, на шаге 2 — с индексом 3, и так до индекса 0, даже если по пути что-то удалили.

Поиск, затем удаление

Отбор = Новый Структура("Количество", 0);
Найденные = ТЗ.НайтиСтроки(Отбор);
Для Каждого Строка Из Найденные Цикл
	ТЗ.Удалить(Строка);
КонецЦикла;

НайтиСтроки() возвращает отдельный массив, поэтому по нему безопасно идти вперёд.

Список значений

У СписокЗначений метод Удалить() принимает элемент или его индекс. Чтобы убрать отмеченные пользователем галочкой пункты, используйте обратный цикл и проверку свойства Пометка.

Временные таблицы в запросе

Строку из временной таблицы удалить нельзя — запрос не умеет менять данные. Ненужные записи отсекают условием в следующем запросе пакета:

ВЫБРАТЬ
	Т.Номенклатура,
	Т.Количество
ИЗ
	ВТ_Товары КАК Т
ГДЕ
	НЕ Т.Номенклатура В (&Исключить)

В параметр Исключить передайте массив ссылок, которые пользователь выделил на форме. Когда временная таблица больше не нужна, освободите память командой УНИЧТОЖИТЬ ВТ_Товары в конце пакета.

Как убрать лишние строки из отчёта на СКД

Отчёт на системе компоновки данных пересобирается при каждом формировании. Поэтому удалять строки из готового результата бессмысленно: следующая кнопка «Сформировать» вернёт всё обратно. Лишнее убирают в настройках.

ЗадачаГде решается
Скрыть строки по значению поляОтбор в настройках отчёта: в типовых отчётах — кнопка «Настройки», затем вкладка с отборами
Убрать группировки с нулевым итогомОтбор по ресурсу на уровне группировки (работает как условие на итог)
Не выводить детальные записиУдалить «Детальные записи» из структуры отчёта
Убрать конкретные элементыОтбор «Не в списке» по нужному полю

Если без кода не обойтись, получите результат компоновки не в табличный документ, а в таблицу значений через ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. В ней удалите строки любым способом из раздела выше и только потом выводите пользователю.

Удалять строки из табличного документа после вывода СКД — плохая идея. Ломается расшифровка: щелчок по ячейке открывает не тот документ, потому что данные расшифровки привязаны к исходным координатам.

Массовое удаление без зависаний

Когда строк десятки тысяч, построчное удаление становится заметно медленным. Особенно на клиенте, где каждая операция с данными формы ещё и перерисовывает таблицу.

Что ускоряет работу

  • 🚀 Переносите обработку на сервер. Одна серверная процедура с циклом быстрее, чем перерисовка таблицы после каждой удалённой строки на клиенте.
  • 🚀 Собирайте нужное, а не удаляйте ненужное. Если убрать надо больше половины строк, ТЗ.Скопировать(МассивНужныхСтрок) создаст новую таблицу без лишнего, и это дешевле множества вызовов Удалить().
  • 🚀 Отбирайте запросом. Если строки пришли из базы, условие ГДЕ в запросе не даст им попасть в коллекцию вообще.
  • 🚀 Очищайте целиком. Объект.Товары.Очистить() с последующей загрузкой подготовленной таблицы через Загрузить() работает быстрее, чем тысяча удалений по одной.

Пример: оставить в табличной части только строки с количеством

&НаСервере
Процедура ОставитьНенулевыеНаСервере()

	ТЗ = Объект.Товары.Выгрузить();
	Нужные = Новый Массив;
	Для Каждого Строка Из ТЗ Цикл
		Если Строка.Количество <> 0 Тогда
			Нужные.Добавить(Строка);
		КонецЕсли;
	КонецЦикла;

	Объект.Товары.Загрузить(ТЗ.Скопировать(Нужные));

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

Здесь удаления нет вовсе: собрали нужные строки, скопировали, загрузили. Номера строк табличной части пересчитаются автоматически.

Ошибки, из-за которых удаляются не те строки

Диагностика: выберите симптом

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

Можно ли вернуть строки, удалённые из табличной части?
Да, если документ ещё не записан: закройте его без сохранения. После записи вернуть можно только из резервной копии или через историю данных, если она включена для этого документа.
Почему не работает Ctrl+A в таблице?
Курсор стоит в поле ввода ячейки, а не в самой таблице. Нажмите Esc, чтобы выйти из редактирования, и повторите. Если таблица разрешает выделять только одну строку, Ctrl+A тоже не сработает.
Как удалить пустые строки из табличной части документа?
Отсортируйте таблицу щелчком по заголовку колонки «Количество» или «Сумма» — нулевые строки соберутся вместе. Выделите их с Shift и нажмите Delete.
Влияет ли удаление строк на нумерацию в табличной части?
Да. Колонка «N» пересчитывается сама, пропусков в номерах не остаётся. Если на номер строки ссылалась внешняя обработка, эти ссылки станут неверными.
Удаляются ли строки у других пользователей сразу?
Нет. Изменения в документе видят другие только после записи. До этого у каждого открыта своя копия формы.