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