К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как поменять местами элементы массива в 1С

Как поменять местами элементы массива в 1С: через временную переменную, методы Вставить и Удалить, сортировка. Примеры кода, ошибки и проверка результата.

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

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

Базовый способ: обмен через временную переменную

Классический приём перестановки выглядит так: значение первого элемента сохраняется во временную переменную, на его место записывается значение второго элемента, а затем сохранённое значение помещается на место второго. Без временной переменной одно из значений будет безвозвратно потеряно уже на первом присваивании.

// Меняем местами элементы с индексами Индекс1 и Индекс2

ВременноеЗначение = Массив[Индекс1];

Массив[Индекс1] = Массив[Индекс2];

Массив[Индекс2] = ВременноеЗначение;

Этот код работает с элементами любого типа: числами, строками, ссылками, структурами. Временная переменная хранит значение (или ссылку на объект), поэтому дополнительных преобразований не требуется. Для ссылочных типов копируется ссылка, а не сам объект — это нормально для задачи перестановки.

Если перестановка выполняется в нескольких местах модуля, имеет смысл оформить её в виде отдельной процедуры с параметрами. Это убирает дублирование и снижает риск ошибки при правках.

Процедура ПоменятьМестамиЭлементы(Массив, Индекс1, Индекс2) Экспорт

Если Индекс1 = Индекс2 Тогда

Возврат;

КонецЕсли;

ВременноеЗначение = Массив[Индекс1];

Массив[Индекс1] = Массив[Индекс2];

Массив[Индекс2] = ВременноеЗначение;

КонецПроцедуры

1c
ВременноеЗначение = Массив[Индекс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 и наоборот

Тревожный признак

Оба элемента содержат одинаковое значение — временная переменная не использовалась

Остальные элементы
Норма

Порядок прочих элементов не изменился

Тревожный признак

Соседние элементы сдвинуты — вероятно, применялись Удалить/Вставить без корректировки

Количество элементов
Норма

Массив.Количество() не изменилось

Тревожный признак

Количество уменьшилось — элемент был удалён без последующей вставки

Типичные ошибки
01
Обмен без временной переменной: второе присваивание затирает значение первого, оба элемента становятся одинаковыми.
02
Индексация с единицы: попытка обратиться к Массив[1] как к первому элементу смещает всю логику и приводит к выходу за границы на последнем элементе.
03
Использование результата Найти() без проверки на Неопределено — ошибка исполнения при отсутствии элемента.
04
Вставка после Удалить() по нескорректированному индексу — элемент встаёт не на ту позицию.
05
Перестановка в цикле по всему массиву при развороте — двойной обмен возвращает исходный порядок.

Альтернативы: список значений и таблица значений

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

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

Маршрут решения

Как выбрать действие

Нужно обменять два элемента с известными индексамиИспользуйте обмен через временную переменную с проверкой границ индексов
Нужно переместить один элемент на другую позицию со сдвигом остальныхИспользуйте Удалить() и Вставить(), скорректировав индекс вставки
Данные в списке значений или таблице значенийИспользуйте метод Сдвинуть() коллекции
Нужно упорядочить весь набор по значениюПримените встроенные методы сортировки вместо ручных перестановок
Итог

Что важно запомнить

Обмен элементов массива в 1С выполняется через временную переменную в три строки. Индексы начинаются с нуля, поэтому перед обменом проверяйте границы и результат Найти(). Для перемещения со сдвигом подходят Удалить() и Вставить(), для списков и таблиц значений — метод Сдвинуть(), для полного упорядочивания — встроенная сортировка.

Частые вопросы

С какого индекса начинается массив в 1С?

Индексация массивов во встроенном языке 1С начинается с нуля. Первый элемент — Массив[0], последний — Массив[Массив.Количество() - 1]. Это отличается от нумерации строк табличных частей в пользовательском интерфейсе, где нумерация отображается с единицы.

Можно ли поменять элементы местами без временной переменной?

Надёжного способа без временного хранения во встроенном языке нет. Арифметические трюки для чисел (через сумму и разность) работают только с числовыми типами и чреваты переполнением, поэтому в прикладном коде их не применяют. Временная переменная — стандартное и безопасное решение.

Что произойдёт, если указать индекс больше размера массива?

Платформа выдаст ошибку «Индекс находится за границами массива» и прервёт выполнение текущего кода. Если ошибка происходит в регламентном задании или обработке обмена, операция завершится не полностью, поэтому индексы всегда проверяют перед обращением.

Как поменять местами строки табличной части документа?

Табличная часть — это коллекция, а не массив, но приём тот же: значения полей одной строки сохраняют во временные переменные или структуру, копируют значения из второй строки, затем записывают сохранённые. Для перемещения строки в таблице значений удобнее метод Сдвинуть() у коллекции строк.

Меняется ли исходный массив при передаче в процедуру?

Массив передаётся в процедуру по ссылке, если параметр не объявлен с ключевым словом Знач. Поэтому перестановка внутри процедуры изменяет исходный массив вызывающего кода — это обычно и требуется. Если нужно сохранить исходный порядок, предварительно создайте копию через конструктор Новый Массив с копированием элементов.

Как быстро развернуть массив в обратном порядке?

Пройдите циклом от начала до середины массива, меняя местами симметричные элементы: позицию i с позицией Количество - 1 - i. Останавливайтесь на середине, иначе каждая пара обменяется дважды и порядок не изменится.