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