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