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