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

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

Как изменить значение в массиве 1С

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

Массив в 1С — это упорядоченная коллекция значений, доступ к которым выполняется по числовому индексу, начинающегося с нуля. Изменить значение элемента можно двумя базовыми способами: прямым присваиванием по индексу (Массив[2] = НовоеЗначение;) или универсальным методом Установить(). Оба варианта работают одинаково, но второй удобнее, когда индекс вычисляется динамически или код пишется в стиле, совместимом с другими коллекциями.

Главная сложность при изменении массива — не само присваивание, а правильное определение позиции, которую нужно изменить. Если индекс известен заранее, задача решается одной строкой. Если элемент нужно найти по значению или условию, потребуется метод Найти() или перебор циклом с проверкой. Ошибка в индексе приводит к исключению «Индекс находится за границами массива», поэтому перед обращением всегда стоит проверять границы через ВГраница() или Количество().

Ниже разобраны все практические сценарии: изменение по известному индексу, поиск и замена по значению, изменение в цикле, работа с вложенными структурами и типичные ошибки, которые допускают разработчики при работе с массивами.

Изменение элемента по известному индексу

Самый простой случай — когда позиция элемента известна. Индексация в массивах 1С начинается с нуля: первый элемент имеет индекс 0, второй — 1 и так далее. Чтобы заменить значение, достаточно присвоить новое значение элементу по его индексу.

Массив = Новый Массив;

Массив.Добавить("Январь");

Массив.Добавить("Февраль");

Массив.Добавить("Март");

// Заменяем второй элемент (индекс 1)

Массив[1] = "Апрель";

Альтернатива — метод Установить(), который принимает два параметра: индекс и новое значение. Результат полностью аналогичен прямому присваиванию:

Массив.Установить(1, "Апрель");

Метод Установить() удобен, когда индекс хранится в переменной и код должен читаться единообразно с другими операциями над коллекцией. Функциональной разницы нет, выбор — вопрос стиля команды разработки.

Проверка границ массива перед изменением

Обращение к несуществующему индексу вызывает исключение, которое прерывает выполнение кода. Это одна из самых частых причин падения обработок, особенно когда размер массива формируется динамически — по данным запроса, файла или пользовательского ввода.

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

Индекс = 5;

Если Индекс >= 0 И Индекс <= Массив.ВГраница() Тогда

Массив[Индекс] = НовоеЗначение;

Иначе

// Индекс за пределами массива — обработка ситуации

КонецЕсли;

Отдельно проверяйте случай пустого массива: у него ВГраница() возвращает -1, и любое обращение по индексу будет ошибкой. Если логика предполагает, что массив может быть пустым, добавьте явную проверку Массив.Количество() > 0.

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

Поиск элемента и замена по значению

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

Индекс = Массив.Найти("Февраль");

Если Индекс <> Неопределено Тогда

Массив[Индекс] = "Апрель";

КонецЕсли;

Важная особенность: Найти() сравнивает значения по равенству. Для строк сравнение выполняется с учётом регистра, поэтому «февраль» и «Февраль» — разные значения. Если регистр не гарантирован, приводите обе стороны к одному виду функциями ВРег() или НРег() при переборе.

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

Изменение элементов в цикле

Для массовой обработки элементов удобен цикл Для с обходом по индексам. Именно по индексам, а не Для Каждого: переменная цикла «Для Каждого» содержит копию ссылки на значение, и присваивание ей нового значения не меняет элемент массива.

// Приводим все строки массива к верхнему регистру

Для Индекс = 0 По Массив.ВГраница() Цикл

Массив[Индекс] = ВРег(Массив[Индекс]);

КонецЦикла;

Для замены всех вхождений конкретного значения добавьте условие внутри цикла:

Для Индекс = 0 По Массив.ВГраница() Цикл

Если Массив[Индекс] = СтароеЗначение Тогда

Массив[Индекс] = НовоеЗначение;

КонецЕсли;

КонецЦикла;

Если внутри цикла нужно не менять, а удалять элементы, идите по массиву в обратном порядке — от последнего индекса к первому. Иначе после удаления элемента индексы сдвинутся, и часть элементов будет пропущена.

Порядок действий при замене значения
  1. 1
    Определите индекс элемента: напрямую, через Найти() или перебором с условием
  2. 2
    Проверьте, что индекс найден (не Неопределено) и лежит в диапазоне от 0 до ВГраница()
  3. 3
    Присвойте новое значение: Массив[Индекс] = Значение или Массив.Установить(Индекс, Значение)
  4. 4
    Проверьте результат: выведите Массив[Индекс] или пройдите массив циклом и убедитесь в замене

Изменение значений внутри структур и соответствий в массиве

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

// Массив структур с данными товаров

Для Каждого СтрокаДанных Из МассивТоваров Цикл

СтрокаДанных.Цена = СтрокаДанных.Цена * 1.1;

КонецЦикла;

Здесь цикл Для Каждого уместен, потому что изменяется свойство объекта, на который ссылается элемент, а не сам элемент массива. Структуры передаются по ссылке, поэтому изменение сохраняется в исходной коллекции.

Если нужно заменить всю структуру целиком, а не отдельное свойство, снова потребуется обход по индексам: МассивТоваров[Индекс] = НоваяСтруктура;.

Сравнение способов изменения

Присваивание по индексу Массив[И] = З

Самый короткий и наглядный способ; требует точного знания индекса и его проверки

Метод Установить(Индекс, Значение)

Равнозначен присваиванию; удобен при едином стиле работы с коллекциями, чуть длиннее записывается

Вставить(Индекс, Значение)

Не заменяет, а добавляет элемент со сдвигом остальных; подходит только если нужно именно добавление

Перебор циклом с условием

Единственный вариант, когда позиция определяется сложным условием или нужно заменить несколько элементов

Массивы в типовых объектах: табличные части и параметры

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

Если процедура не должна менять исходный массив, либо объявляйте параметр с Знач, либо создавайте копию внутри: РабочаяКопия = Новый Массив; с последующим копированием элементов в цикле. Универсального метода «Скопировать» у массива нет, поэтому копирование делается перебором.

При выгрузке данных из табличной части в массив (например, ТабличнаяЧасть.ВыгрузитьКолонку("Номенклатура")) полученный массив не связан с документом: изменения в нём не затрагивают данные объекта. Чтобы изменить данные документа, работайте со строками табличной части напрямую.

Проверка результата и отладка

После замены убедитесь, что изменение действительно произошло. Самый быстрый способ — вывести содержимое массива в сообщение или посмотреть значение в отладчике через табло (вычисление выражения Массив покажет все элементы).

Для Индекс = 0 По Массив.ВГраница() Цикл

Сообщить("Элемент " + Индекс + ": " + Массив[Индекс]);

КонецЦикла;

В отладчике конфигуратора удобно поставить точку останова сразу после строки присваивания и проверить элемент через «Вычислить выражение». Если массив большой, проверяйте не весь список, а конкретный индекс: Массив[5].

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

Контрольные точки

Как проверить результат

Значение по индексу после присваивания
Норма

Массив[Индекс] возвращает новое значение

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

Возвращается старое значение — присваивание не выполнилось или менялась копия

Результат Найти() перед заменой
Норма

Возвращён числовой индекс от 0 до ВГраница()

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

Возвращено Неопределено — элемент не найден, сравнение по значению не сработало

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

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

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

Количество выросло — использовался Вставить() вместо замены

Часто задаваемые вопросы

Чем отличается Установить() от Вставить() в массиве 1С?

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

Почему присваивание в цикле «Для Каждого» не меняет элементы массива?

Переменная цикла «Для Каждого» получает значение элемента, а не ссылку на позицию в массиве. Присваивание этой переменной нового значения меняет только её саму. Чтобы изменить элементы, используйте цикл «Для Индекс = 0 По Массив.ВГраница()» и обращайтесь к элементам через Массив[Индекс].

Как заменить несколько одинаковых значений в массиве?

Метод Найти() возвращает только первое вхождение, поэтому для замены всех совпадений пройдите массив циклом по индексам от 0 до ВГраница() и внутри условия «Если Массив[Индекс] = СтароеЗначение» выполняйте присваивание нового значения.

Можно ли изменить элемент массива, если он хранится в структуре?

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

Что делать, если возникает ошибка «Индекс находится за границами массива»?

Проверьте, что индекс лежит в диапазоне от 0 до Массив.ВГраница(). Типичные причины: использование Количество() вместо Количество() - 1, обращение к пустому массиву, использование результата Найти() без проверки на Неопределено. Добавьте явную проверку границ перед обращением к элементу.

Как создать копию массива, чтобы изменения не затрагивали оригинал?

У массива нет встроенного метода копирования. Создайте новый массив и перенесите элементы циклом: Для Каждого Элемент Из ИсходныйМассив Цикл Копия.Добавить(Элемент); КонецЦикла. Учтите, что это поверхностная копия: вложенные объекты (структуры, другие массивы) останутся общими по ссылке.

Итог

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

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