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

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

Как удалить элемент из массива в 1С

Как удалить элемент из массива в 1С: методы Удалить(), Очистить(), удаление по значению и индексу, обход в обратном порядке, типовые ошибки и примеры кода.

Массив в 1С — это упорядоченная коллекция значений, и удаление элементов из него выполняется через встроенные методы объекта. Чаще всего применяется метод Удалить(), который принимает индекс удаляемого элемента, а для полной очистки используется Очистить(). Удаления «по значению» напрямую нет — сначала нужно найти индекс методом Найти().

Главная тонкость при работе с массивами в 1С — сдвиг индексов после удаления. Когда элемент удалён, все последующие элементы смещаются на одну позицию влево. Если удалять элементы в цикле «вперёд», часть значений будет пропущена, а обращение по старому индексу вызовет ошибку выхода за границы массива.

Материал охватывает встроенный язык 1С (платформа 8.3). Примеры пригодны для управляемых и обычных форм, а также для серверного кода. Отдельно разобраны удаление по условию, работа со структурой и соответствием как альтернатива, типовые ошибки и способы проверки результата.

Как устроен массив в 1С и почему это важно при удалении

Массив создаётся конструктором Новый Массив или литералом, индексация начинается с нуля. Количество элементов возвращает метод Количество(), последний допустимый индекс всегда равен Количество() - 1. Обращение по индексу вне диапазона вызывает исключение «Индекс находится за границами массива».

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

Ключевое следствие: массив — структура с последовательным доступом по индексу. Любая операция удаления меняет нумерацию, поэтому код, который запомнил индексы «на потом», после первого удаления работает уже с другими позициями. Это нужно учитывать при проектировании алгоритма.

Удаление элемента по индексу: метод Удалить()

Базовый способ — метод Удалить(Индекс). Он удаляет один элемент по указанной позиции, а все элементы правее сдвигаются на одну позицию. Метод ничего не возвращает.

Массив = Новый Массив;

Массив.Добавить("Первый");

Массив.Добавить("Второй");

Массив.Добавить("Третий");

Массив.Удалить(0); // удалили "Первый"

// Теперь Массив[0] = "Второй", Массив[1] = "Третий"

Перед удалением проверяйте границы: индекс должен быть не меньше нуля и меньше Количество(). Если индекс вычисляется динамически (например, берётся из параметра или результата поиска), явная проверка убережёт от падения кода в неожиданном месте.

Индекс = 2;

Если Индекс >= 0 И Индекс < Массив.Количество() Тогда

Массив.Удалить(Индекс);

КонецЕсли;

Удаление элемента по значению

Метода «удалить по значению» в массиве нет. Сначала значение ищется методом Найти(), который возвращает индекс первого вхождения или Неопределено, если значение не найдено. Затем найденный индекс передаётся в Удалить().

Индекс = Массив.Найти("Второй");

Если Индекс <> Неопределено Тогда

Массив.Удалить(Индекс);

КонецЕсли;

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

Если одинаковых значений несколько, Найти() вернёт только первое. Чтобы удалить все вхождения, нужен цикл, который повторяет поиск до тех пор, пока метод не вернёт Неопределено:

Пока Истина Цикл

Индекс = Массив.Найти(ИскомоеЗначение);

Если Индекс = Неопределено Тогда

Прервать;

КонецЕсли;

Массив.Удалить(Индекс);

КонецЦикла;

Удаление нескольких элементов по условию

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

Обход в обратном порядке

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

Для Индекс = -Массив.Количество() + 1 По 0 Цикл

ТекИндекс = -Индекс;

Если Не ЗначениеЗаполнено(Массив[ТекИндекс]) Тогда

Массив.Удалить(ТекИндекс);

КонецЕсли;

КонецЦикла;

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

Формирование нового массива

Альтернатива — не удалять, а собрать новый массив только из подходящих элементов. Код проще читается и не зависит от сдвига индексов:

Результат = Новый Массив;

Для Каждого Элемент Из Массив Цикл

Если ЗначениеЗаполнено(Элемент) Тогда

Результат.Добавить(Элемент);

КонецЕсли;

КонецЦикла;

Сравнение подходов

Обратный обход с Удалить()

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

Новый массив с отбором

Проще и безопаснее, не зависит от сдвига индексов. Не подходит, если внешний код держит ссылку именно на исходный массив.

Цикл Найти() + Удалить()

Удобен для удаления всех вхождений конкретного значения. Не годится для сложных условий — Найти() проверяет только равенство.

Полная очистка массива

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

Массив.Очистить();

// Массив.Количество() = 0

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

Порядок действий при удалении по условию
  1. 1
    Определите условие отбора удаляемых элементов
  2. 2
    Решите, нужно ли менять исходный массив или можно собрать новый
  3. 3
    При изменении на месте организуйте обход от конца к началу
  4. 4
    Внутри цикла проверяйте условие и вызывайте Удалить(Индекс)
  5. 5
    После цикла проверьте Массив.Количество() и содержимое через отладчик

Типичные ошибки и альтернативы массиву

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

Типичные ошибки
01
Удаление внутри цикла Для Каждого — коллекция изменяется во время итерации, элементы пропускаются или возникает ошибка
02
Обход вперёд с Удалить(Индекс) — после удаления нумерация сдвигается, следующий элемент пропускается
03
Передача Неопределено в Удалить() без проверки результата Найти() — исключение в момент выполнения
04
Сравнение строк без учёта регистра при Найти() — значение не находится, хотя визуально оно есть в массиве
05
Ожидание, что удаление ссылки из массива удалит объект из базы — массив хранит только ссылки, данные не затрагиваются

Если удаление по значению выполняется часто, массив может быть не лучшим выбором. Соответствие позволяет удалять пару по ключу одним вызовом Удалить(Ключ) без поиска индекса, а СписокЗначений имеет метод Удалить() как по индексу, так и по элементу. Для проверки уникальности и быстрого поиска удобнее соответствие, где значение хранится как ключ.

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

В отладчике удобно проверять результат удаления через вычисление выражения Массив.Количество() до и после операции, а содержимое — через раскрытие переменной в табло. Это быстрее, чем выводить элементы сообщениями в цикле.
ПЗ
Практическое замечание

Проверка результата удаления

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

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

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

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

Уменьшилось ровно на число удалённых элементов

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

Не изменилось или уменьшилось сильнее — удалён не тот элемент

Повторный Найти(Значение)
Норма

Возвращает Неопределено

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

Возвращает индекс — остались дубликаты значения

Обход массива после удаления
Норма

Цикл Для Каждого проходит без ошибок, элементы в ожидаемом порядке

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

Ошибка выхода за границы или неожиданные значения

В прикладном коде полезно добавить защитные проверки: перед удалением убеждаться, что массив инициализирован (переменная не Неопределено), а индексы находятся в допустимых пределах. Это особенно важно в функциях, которые получают массив как параметр из внешнего кода.

Итог

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

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

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

Как удалить последний элемент массива?

Вызовите Массив.Удалить(Массив.Количество() - 1). Предварительно убедитесь, что массив не пуст, иначе получите ошибку выхода за границы. Для пустого массива Количество() вернёт 0, и индекс станет равен -1.

Можно ли удалить элемент внутри цикла Для Каждого?

Нет, изменять коллекцию во время обхода циклом Для Каждого нельзя — это приводит к ошибке или непредсказуемому поведению. Используйте индексный цикл от конца к началу или собирайте новый массив с нужными элементами.

Чем Удалить() отличается от Очистить()?

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

Удалит ли Удалить() объект из базы, если в массиве ссылка?

Нет. Массив хранит только ссылки на объекты. Удаление элемента из массива убирает ссылку из коллекции, но сам объект в информационной базе остаётся нетронутым. Для удаления объекта из базы нужны отдельные операции с установкой пометки удаления или непосредственным удалением.

Почему Найти() не находит значение, которое точно есть в массиве?

Чаще всего дело в регистре строк или различии типов: строка «001» и число 1 — разные значения, «Товар» и «товар» тоже различаются. Проверьте типы элементов и при необходимости приводите значения к одному виду перед сравнением.

Как удалить из массива элементы другого массива?

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