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

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

Как создать матрицу в 1С

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

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

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

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

Что в 1С заменяет матрицу

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

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

Второй способ — объект ТаблицаЗначений. Здесь строки и колонки — полноценные объекты, колонки имеют имена и типы, а таблицу можно сортировать, сворачивать, искать в ней и выводить на форму. За удобство приходится платить большим расходом памяти и меньшей скоростью доступа по сравнению с массивом.

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

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

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

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

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

Соответствие с ключом-структурой

Подходит для разреженных матриц, где заполнена малая часть ячеек. Нет прямого доступа по индексу.

Создание матрицы через вложенные массивы

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

Функция СоздатьМатрицу(ЧислоСтрок, ЧислоКолонок)

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

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

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

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

Строка.Добавить(0);

КонецЦикла;

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

КонецЦикла;

Возврат Матрица;

КонецФункции

Обращение к элементу выполняется двойной индексацией: Матрица[2][3] = 15; записывает значение в третью строку, четвёртую колонку. Помните о нумерации с нуля — попытка обратиться к Матрица[ЧислоСтрок] вызовет ошибку выхода за границы массива.

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

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

Матрица на базе таблицы значений

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

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

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

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

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

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

НоваяСтрока.Месяц = "Январь";

НоваяСтрока.План = 100;

НоваяСтрока.Факт = 92;

Доступ по индексам тоже возможен: Таблица[0][1] вернёт значение первой строки второй колонки. Однако читабельность кода выше при обращении по имени колонки, особенно когда таблица расширяется.

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

Заполнение и обход матрицы

Типовой обход — два вложенных цикла: внешний по строкам, внутренний по колонкам. Для массива массивов границы берутся методом Количество(), для таблицы значений удобнее цикл Для Каждого.

// Обход массива массивов

Для И = 0 По Матрица.Количество() - 1 Цикл

Для Ж = 0 По Матрица[И].Количество() - 1 Цикл

Матрица[И][Ж] = И * 10 + Ж;

КонецЦикла;

КонецЦикла;

// Обход таблицы значений

Для Каждого Строка Из Таблица Цикл

Строка.Отклонение = Строка.Факт - Строка.План;

КонецЦикла;

Для диагональных операций — например, заполнения главной диагонали единицами при построении единичной матрицы — достаточно одного цикла: Матрица[И][И] = 1;. Условие внутри двойного цикла Если И = Ж Тогда тоже работает, но выполняет лишние итерации.

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

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

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

Сообщить("Строк: " + Матрица.Количество());

Сообщить("Колонок: " + Матрица[0].Количество());

Сообщить("Ячейка [1][1]: " + Матрица[1][1]);

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

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

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

Размерность
Норма

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

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

Длины строк различаются — при обходе будет ошибка индекса

Значения ячеек
Норма

Ячейки содержат ожидаемые начальные значения (0, пусто, расчёт)

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

Ячейки содержат Неопределено — массив создан, но не заполнен

Таблица значений
Норма

Колонки имеют имена и типы, строки добавлены

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

Колонки есть, но строк нет — цикл Для Каждого молча ничего не делает

Типичные ошибки при работе с матрицами

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

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

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

Типичные ошибки
01
Обращение к индексу, равному размеру массива — в 1С нумерация с нуля, возникает ошибка выхода за границы
02
Внутренние массивы разной длины — обход по длине первой строки падает на короткой строке
03
Запрос к базе внутри двойного цикла — резкое падение производительности
04
Ожидание, что таблица значений сама появится на форме — без реквизита формы и Загрузить() она невидима пользователю

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

Можно ли создать трёхмерную матрицу в 1С?

Да, добавив ещё один уровень вложенности: массив, содержащий массивы массивов. Обращение будет вида Куб[И][Ж][К]. На практике структуры глубже трёх измерений быстро становятся нечитаемыми — для таких данных лучше подходит таблица значений с дополнительными колонками-измерениями.

Как вывести матрицу на форму пользователю?

Создайте реквизит формы типа ТаблицаЗначений с нужными колонками, перетащите его на форму и в коде загрузите данные методом ЗначениеВРеквизитФормы или напрямую заполните реквизит. Массив массивов на форму напрямую не выводится — его сначала преобразуют в таблицу значений.

Что быстрее: массив массивов или таблица значений?

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

Как передать матрицу с клиента на сервер?

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

Как заполнить матрицу случайными числами?

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

Есть ли в 1С готовые матричные операции — сложение, умножение матриц?

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

Итог

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

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