Как перенести элементы массива в другой массив по списку индексов в 1С

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

В процессе разработки на платформе 1С:Предприятие часто возникает задача трансформации данных. Одной из таких задач является создание выборки из существующего массива на основе набора индексов, хранящихся в другой коллекции (например, в СписокЗначений). В отличие от высокоуровневых языков программирования, таких как Python, где это решается одной строкой (срезами), в 1С требуется понимание работы с коллекциями и циклами.

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

Метод 1: Базовый перебор с использованием цикла

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

Разберем пример кода, реализующий эту задачу:


// Инициализируем исходные данные
Массив0 = Новый Массив; // Допустим, здесь уже есть данные
СписокИндексов = Новый СписокЗначений; // Здесь лежат числа-индексы

// Создаем приемник
Массив1 = Новый Массив;

// Начинаем обход списка индексов
Для Каждого ЭлементСписка Из СписокИндексов Цикл
    // Получаем индекс из элемента списка
    ТекущийИндекс = ЭлементСписка.Значение;
    
    // Извлекаем значение из первого массива и добавляем во второй
    ЗначениеИзМассива = Массив0[ТекущийИндекс];
    Массив1.Добавить(ЗначениеИзМассива);
КонецЦикла;

Этот способ является наиболее очевидным и рабочим. Однако в реальной разработке "голый" код без проверок может привести к аварийному завершению работы программы.

Метод 2: Защищенный перенос данных (с проверкой границ)

Выясним причину, по которой код выше может вызвать ошибку. В 1С обращение по индексу к массиву требует, чтобы индекс был не меньше 0 и строго меньше количества элементов в массиве. Если в ваш СписокЗначений попадет число, превышающее Массив.Количество() - 1, система выдаст ошибку "Индекс находится за границами массива".

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


Массив1 = Новый Массив;
КоличествоЭлементов = Массив0.Количество();

Для Каждого ЭлементСписка Из СписокИндексов Цикл
    // Принудительно приводим к числу для исключения ошибок типа
    Попытка
        ТекущийИндекс = Число(ЭлементСписка.Значение);
    Исключение
        Продолжить; // Если в списке не число, пропускаем итерацию
    КонецПопытки;

    // Проверяем вхождение индекса в допустимый диапазон
    Если ТекущийИндекс >= 0 И ТекущийИндекс < КоличествоЭлементов Тогда
        Массив1.Добавить(Массив0[ТекущийИндекс]);
    Иначе
        // Здесь можно добавить логирование ошибки или оповещение
    КонецЕсли;
КонецЦикла;

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

Метод 3: Использование временных таблиц и запросов (для больших данных)

Проанализируем ситуацию, когда объемы данных исчисляются десятками тысяч элементов. Перебор в цикле на стороне сервера приложений может быть менее эффективным, чем обработка данных на стороне СУБД. В 1С мы можем использовать механизм временных таблиц для "автоматизации" процесса сопоставления.

Рассмотрим по шагам, как это работает:

  1. Создаем таблицу значений с колонкой Индекс и Значение (заполняем ее данными из Массив0).
  2. Создаем вторую таблицу значений только со списком искомых индексов.
  3. Передаем обе таблицы в запрос.
  4. Выполняем ВНУТРЕННЕЕ СОЕДИНЕНИЕ по полю индекса.
  5. Выгружаем результат обратно в массив.

Хотя этот метод кажется избыточным для простых задач, он позволяет использовать всю мощь языка SQL для фильтрации и сортировки итогового массива в один проход.

Метод 4: Функции общего назначения и БСП

Если вы работаете в современной конфигурации (например, ERP, УТ 11 или БП 3.0), в ней наверняка подключена Библиотека стандартных подсистем (БСП). Разберем, как сделать код чище, используя готовые модули. В модуле ОбщегоНазначенияКлиентСервер часто встречаются функции для работы с коллекциями.

Несмотря на отсутствие метода ВыбратьПоИндексам, хорошей практикой считается вынос логики переноса в отдельную функцию, которую можно вызывать многократно. Это и есть правильная "автоматизация" в понимании архитектуры 1С:


// Функция в общем модуле
Функция ПолучитьПодмножествоМассива(ИсходныйМассив, СписокИндексов) Экспорт
    Результат = Новый Массив;
    Для Каждого Индекс Из СписокИндексов Цикл
        // Добавьте сюда проверку границ из Метода 2
        Результат.Добавить(ИсходныйМассив[Индекс]);
    КонецЦикла;
    Возврат Результат;
КонецФункции

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

Важные нюансы типизации

Важно помнить, что СписокЗначений может хранить данные любого типа. Если в него по ошибке попадет строка "5" вместо числа 5, обращение Массив[ТекущийИндекс] может отработать корректно в некоторых случаях (благодаря неявному приведению типов в 1С), но лучше всегда использовать явное преобразование Число().

Также стоит учитывать, что при удалении элементов из исходного массива индексы оставшихся элементов смещаются. Если ваша задача предполагает не только копирование, но и очистку исходного массива, всегда выполняйте обход с конца (от большего индекса к меньшему), используя цикл Для Счетчик = -Количество + 1 По 0 или аналогичные конструкции.

Подводя итог, мы выяснили, что "волшебной кнопки" для автоматического среза массива в 1С нет, но использование циклов с проверкой границ и вынос логики в общие модули позволяют решать эту задачу эффективно и профессионально.

← На главную