Как в 1С 8.3 удалить элемент из массива по значению (сотрудника, строку или объект)?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

В этой статье мы подробно разберем, как правильно удалять элементы из массива, если нам известно только их значение, проанализируем типичные ошибки и выясним, какие инструменты платформы лучше использовать для фильтрации списков сотрудников.

Метод 1. Поиск индекса и удаление (классический способ)

Если нам нужно удалить конкретного сотрудника (ссылку на справочник) или определенную строку из массива, мы должны действовать в два этапа: сначала найти, под каким номером «лежит» этот объект, а затем вызвать команду удаления по этому номеру. Рассмотрим программный код, который решает эту задачу:


// Предположим, у нас есть МассивСотрудников и ЗначениеДляУдаления
Индекс = МассивСотрудников.Найти(ЗначениеДляУдаления);

Если Индекс <> Неопределено Тогда
    МассивСотрудников.Удалить(Индекс);
КонецЕсли;

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

Метод 2. Удаление всех дублирующихся значений в цикле

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


Пока Истина Цикл
    Индекс = Массив.Найти(НужноеЗначение);
    Если Индекс = Неопределено Тогда
        Прервать; // Выходим из цикла, когда значений больше нет
    КонецЕсли;
    Массив.Удалить(Индекс);
КонецЦикла;

Этот подход гарантирует, что из массива будут удалены все элементы, соответствующие условию. Рассмотрим альтернативный вариант — обход массива с конца. Это «золотое правило» программирования в 1С при удалении элементов в цикле Для. Если вы пойдете с начала (от 0 до Количества), то при удалении элементы сдвинутся, и цикл пропустит следующий за удаленным объект.

Проанализируем правильный обход с конца:


ВсегоЭлементов = Массив.Количество();
Для Счетчик = 1 По ВсегоЭлементов Цикл
    ОбратныйИндекс = ВсегоЭлементов - Счетчик;
    Если Массив[ОбратныйИндекс] = ЗначениеДляУдаления Тогда
        Массив.Удалить(ОбратныйИндекс);
    КонецЕсли;
КонецЦикла;

Метод 3. Фильтрация данных на этапе запроса (архитектурно верный подход)

Часто задача удаления из массива возникает из-за неправильной стратегии получения данных. Как было отмечено в обсуждении, если вы хотите скрыть определенных сотрудников в документе, лучше вообще не включать их в выборку, вместо того чтобы сначала создавать огромный массив, а потом «выкусывать» из него лишних людей.

Использование Запроса — это самый быстрый и профессиональный способ. Рассмотрим, как исключить сотрудника (или группу сотрудников) сразу при получении списка:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Сотрудники.Ссылка КАК Сотрудник
    |ИЗ
    |	Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |	Сотрудники.Должность = &Должность
    |	И НЕ Сотрудники.Ссылка В (&МассивИсключений)";

Запрос.УстановитьПараметр("Должность", ВыбраннаяДолжность);
Запрос.УстановитьПараметр("МассивИсключений", СписокСкрытыхСотрудников);

РезультатЗапроса = Запрос.Выполнить();
// Теперь мы можем выгрузить только нужных людей в массив
МассивОчищенный = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Сотрудник");

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

Использование СписокЗначений как альтернатива

Если ваша задача связана с интерфейсом (выбор из списка на форме), рассмотрите объект СписокЗначений. В отличие от массива, у него есть более удобные методы для работы с объектами. Рассмотрим пример:

  1. Метод НайтиПоЗначению() возвращает ЭлементСпискаЗначений.
  2. Метод Удалить() в списке значений может принимать не только индекс, но и сам найденный элемент.

Элемент = СписокСотрудников.НайтиПоЗначению(СотрудникСсылка);
Если Элемент <> Неопределено Тогда
    СписокСотрудников.Удалить(Элемент);
КонецЕсли;

Практические советы по работе с массивами

Проанализируем ситуацию, описанную автором темы: нужно скрыть сотрудника в списке выбора реквизита. Вместо ручного удаления из массива, 1С предоставляет мощные визуальные средства:

Подведем итог: для удаления из массива используйте связку Найти() и Удалить(Индекс). Но помните, что в профессиональной разработке на платформе 1С 8.3 массивы чаще используются для передачи параметров в запросы, а фильтрация данных должна происходить на уровне базы данных (SQL) через условия ГДЕ.

← На главную