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