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

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

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

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

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

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

Ниже разобраны оба способа с готовыми фрагментами кода, правила выбора между ними, приёмы заполнения из запроса и типичные ошибки, которые приводят к обращению за границы массива или к потере данных.

Какими способами можно имитировать двумерный массив в 1С

Первый способ — вложенные массивы. Внешний массив хранит строки, каждая строка — это отдельный массив с элементами-колонками. Доступ к ячейке выглядит как Матрица[ИндексСтроки][ИндексКолонки].

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

Третий, менее очевидный вариант — соответствие, где ключом служит структура или строка вида «Строка_Колонка». Такой подход оправдан для разреженных матриц, где заполнена лишь малая часть ячеек. Но для типовых задач он избыточен и усложняет чтение кода.

Сравнение вариантов

Массив массивов

Подходит для вычислений по индексам и математических операций; нет именованных колонок, поиск и сортировку придётся писать вручную.

Таблица значений

Подходит для прикладных данных: именованные колонки, поиск, сортировка, итоги; тяжелее по памяти и неудобна для чисто индексной арифметики.

Соответствие с составным ключом

Подходит для разреженных матриц с редкими заполненными ячейками; сложнее отладка и обход всех ячеек.

Создание и заполнение массива массивов

Чтобы создать матрицу фиксированного размера, сначала формируют внешний массив, затем в цикле добавляют в него внутренние массивы нужной длины. Метод Установить(Индекс, Значение) или прямое присваивание по индексу заполняет ячейки. Ниже пример создания матрицы 5 на 3 и заполнения её произведением индексов.

КоличествоСтрок = 5;

КоличествоКолонок = 3;

Матрица = Новый Массив;

Для ИндексСтроки = 0 По КоличествоСтрок - 1 Цикл

СтрокаМассива = Новый Массив;

Для ИндексКолонки = 0 По КоличествоКолонок - 1 Цикл

СтрокаМассива.Добавить(ИндексСтроки * ИндексКолонки);

КонецЦикла;

Матрица.Добавить(СтрокаМассива);

КонецЦикла;

Обращение к конкретной ячейке выполняется двойной индексацией: Значение = Матрица[2][1];. Перед обращением полезно убедиться, что строка с таким индексом существует, иначе платформа выдаст ошибку «Индекс находится за границами массива».

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

Порядок создания массива массивов
  1. 1
    Объявите внешний массив: Матрица = Новый Массив
  2. 2
    В цикле по строкам создайте внутренний массив и заполните его значениями через Добавить()
  3. 3
    Добавьте внутренний массив во внешний: Матрица.Добавить(СтрокаМассива)
  4. 4
    Обращайтесь к ячейкам по двум индексам: Матрица[Строка][Колонка]
  5. 5
    Проверьте размеры через Матрица.Количество() и Матрица[0].Количество()

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

Таблица значений создаётся декларативно: сначала описываются колонки, затем добавляются строки. Тип колонки задаётся через объект «ОписаниеТипов» — это защищает от смешения данных и упрощает последующую сортировку и итоги.

Таблица = Новый ТаблицаЗначений;

Таблица.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("Строка"));

Таблица.Колонки.Добавить("Склад", Новый ОписаниеТипов("Строка"));

Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));

НоваяСтрока = Таблица.Добавить();

НоваяСтрока.Номенклатура = "Кабель ВВГ 3х2.5";

НоваяСтрока.Склад = "Основной";

НоваяСтрока.Количество = 120;

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

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

Заполнение двумерной структуры из запроса

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Остатки.Номенклатура КАК Номенклатура,

| Остатки.Склад КАК Склад,

| Остатки.КоличествоОстаток КАК Количество

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки";

ТаблицаОстатков = Запрос.Выполнить().Выгрузить();

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

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

Обход, изменение и проверка заполненной матрицы

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

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

СтрокаМассива = Матрица[ИндексСтроки];

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

Матрица[ИндексСтроки][ИндексКолонки] = 0; // обнуление ячейки

КонецЦикла;

КонецЦикла;

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

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

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

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

Размер внешнего массива
Норма

Матрица.Количество() равно числу строк данных

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

Строк меньше, чем в источнике — часть данных потеряна при заполнении

Длина каждой строки
Норма

Все внутренние массивы имеют одинаковое Количество()

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

Строки разной длины — при обращении по индексу будет ошибка за границами

Типы значений в ячейках
Норма

Числовые ячейки содержат числа, а не строки с цифрами

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

Сортировка и итоги работают неправильно из-за строкового типа

Заполненность таблицы значений
Норма

Таблица.Количество() совпадает с числом строк выборки запроса

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

Ноль строк — проверьте текст запроса и отборы

Типичные ошибки и ограничения

Самая частая ошибка — обращение к ячейке, которой не существует. В массиве массивов каждая строка создаётся отдельно, и если логика заполнения допускает «рваные» строки разной длины, любое обращение по фиксированному индексу колонки превращается в ловушку. Решение — либо гарантировать одинаковую длину при создании, либо проверять Количество() перед доступом.

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

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

Типичные ошибки
01
Индексация с единицы вместо нуля — первый элемент массива имеет индекс 0, обращение Матрица[1] пропускает первую строку
02
Изменение ячейки через переменную цикла «Для Каждого» — присваивание меняет локальную копию, исходная матрица остаётся прежней
03
Присваивание массива другой переменной вместо копирования — обе переменные указывают на один объект, правки дублируются
04
Добавление колонки таблицы значений без типа — смешение строк и чисел ломает сортировку и итоги
05
Материализация огромной выборки в массив — переполнение памяти сеанса вместо потокового чтения выборки

Что выбрать в конкретной ситуации

Критерий выбора прост: если дальнейшая работа с данными строится вокруг индексов и вычислений — берите массив массивов; если вокруг поиска, отбора, сортировки и вывода пользователю — таблицу значений. Сомнительные случаи почти всегда разрешаются в пользу таблицы значений, потому что прикладной код в 1С чаще оперирует смысловыми полями, а не координатами.

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

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

Как выбрать структуру

Нужны вычисления по координатам ячеек, математика, игровые поля, сеткиИспользуйте массив массивов с доступом по двум индексам
Данные приходят из запроса и нужны поиск, сортировка, итогиИспользуйте таблицу значений — выгрузка запроса уже даёт её готовой
Матрицу нужно передать на клиент или сохранить в хранилище значенийИспользуйте массив массивов или массив структур — они проще сериализуются
Заполнена лишь малая часть ячеек большой сеткиИспользуйте соответствие с ключом «Строка_Колонка», не храните пустые ячейки

Наконец, учитывайте альтернативу вне кода: для отчётных перекрёстных таблиц система компоновки данных строит матрицу настройками группировок без единой строки программирования. Если конечная цель — отчёт для пользователя, сначала проверьте, не решает ли задачу СКД.

Итог

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

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

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

Можно ли объявить двумерный массив одной строкой, как в других языках?

Нет, синтаксиса вида «Новый Массив(5, 3)» платформа не поддерживает. Конструктор массива принимает только размерность одного измерения. Двумерная структура всегда собирается вложением: внешний массив заполняется внутренними массивами в цикле.

Как узнать количество строк и колонок в массиве массивов?

Число строк возвращает Матрица.Количество(). Число колонок первой строки — Матрица[0].Количество(), но только если массив не пуст. Перед обращением к нулевому элементу проверьте, что Матрица.Количество() > 0, иначе получите ошибку выхода за границы.

Чем массив структур лучше массива массивов?

Массив структур хранит строки с именованными полями: Строка.Номенклатура вместо Строка[2]. Код становится самодокументируемым и устойчивым к перестановке полей. По смыслу это облегчённая таблица значений, которую можно свободно передавать между клиентом и сервером.

Как отсортировать массив массивов по значению колонки?

Штатного метода сортировки для вложенных массивов нет. Либо реализуйте алгоритм сортировки вручную с сравнением элементов по нужному индексу, либо перенесите данные в таблицу значений и используйте её метод Сортировать("ИмяКолонки") — второй вариант почти всегда проще и надёжнее.

Можно ли сохранить двумерный массив в базе данных между сеансами?

Напрямую массив в реквизите объекта не хранится. Типовой приём — поместить массив или таблицу значений в хранилище значений через Новый ХранилищеЗначения(Матрица) и записать в реквизит соответствующего типа. Альтернатива — сериализация в JSON через объект «ЗаписьJSON».

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

Переменная цикла получает копию значения элемента, если элемент — примитивный тип. Присваивание меняет только эту копию. Чтобы изменить исходную ячейку, используйте индексный цикл и присваивайте значение через Матрица[ИндексСтроки][ИндексКолонки] = НовоеЗначение.