Разработка и Конфигурация · 9 мин
Как создать матрицу в 1С
Способы создать матрицу в 1С: вложенные массивы, таблицы значений, заполнение и обход ячеек, типичные ошибки и примеры кода на встроенном языке.
В языке 1С нет отдельного типа данных «матрица», как в математических библиотеках других языков. Двумерную структуру данных разработчик собирает из доступных коллекций: чаще всего это массив массивов либо таблица значений. Выбор зависит от того, что требуется — простая числовая сетка с доступом по индексам или именованные колонки с типизацией.
Массив массивов подходит для расчётов, где важны позиции строки и столбца: игровые поля, коэффициенты, шахматные сетки, расписания. Таблица значений удобнее, когда у колонок есть смысл — «Номенклатура», «Склад», «Количество» — и когда данные нужно выводить пользователю или передавать в запросы и отчёты.
Ниже разобраны оба подхода с готовыми примерами кода, способы заполнения и обхода матрицы, проверка результата и ошибки, которые чаще всего встречаются у начинающих разработчиков.
Что в 1С заменяет матрицу
Матрица — это прямоугольная структура данных с фиксированным числом строк и столбцов, где каждый элемент адресуется парой индексов. Во встроенном языке 1С такую структуру моделируют двумя способами.
Первый способ — массив, каждый элемент которого сам является массивом. Доступ к ячейке выглядит как Матрица[Строка][Колонка]. Индексация в 1С начинается с нуля, это важно учитывать при циклах.
Второй способ — объект ТаблицаЗначений. Здесь строки и колонки — полноценные объекты, колонки имеют имена и типы, а таблицу можно сортировать, сворачивать, искать в ней и выводить на форму. За удобство приходится платить большим расходом памяти и меньшей скоростью доступа по сравнению с массивом.
Сравнение вариантов
Подходит для числовых сеток и алгоритмов с доступом по индексам. Быстрый, компактный, но колонки безымянные.
Подходит для данных с именованными колонками, вывода на форму, поиска и итогов. Тяжелее и медленнее массива.
Подходит для разреженных матриц, где заполнена малая часть ячеек. Нет прямого доступа по индексу.
Создание матрицы через вложенные массивы
Базовый приём — сначала создать внешний массив для строк, затем в цикле добавить в него внутренние массивы нужной длины. Заполнить ячейки можно нулями, случайными числами или результатами расчёта.
Функция СоздатьМатрицу(ЧислоСтрок, ЧислоКолонок)
Матрица = Новый Массив;
Для ИндексСтроки = 0 По ЧислоСтрок - 1 Цикл
Строка = Новый Массив;
Для ИндексКолонки = 0 По ЧислоКолонок - 1 Цикл
Строка.Добавить(0);
КонецЦикла;
Матрица.Добавить(Строка);
КонецЦикла;
Возврат Матрица;
КонецФункции
Обращение к элементу выполняется двойной индексацией: Матрица[2][3] = 15; записывает значение в третью строку, четвёртую колонку. Помните о нумерации с нуля — попытка обратиться к Матрица[ЧислоСтрок] вызовет ошибку выхода за границы массива.
Если размеры матрицы заранее неизвестны, тот же код работает без изменений: массивы в 1С динамические, метод Добавить() расширяет их автоматически. Заранее резервировать размер не требуется.
- 1Создайте внешний массив через Новый Массив
- 2В цикле по строкам создайте внутренний массив
- 3Заполните внутренний массив начальными значениями
- 4Добавьте внутренний массив во внешний
- 5Проверьте размеры: Матрица.Количество() и Матрица[0].Количество()
Матрица на базе таблицы значений
Когда у столбцов есть смысл, таблица значений удобнее. Колонки объявляются с именами и типами, строки добавляются методом Добавить(), а ячейки заполняются по имени колонки или по индексу.
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Месяц", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("План", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Факт", Новый ОписаниеТипов("Число"));
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Месяц = "Январь";
НоваяСтрока.План = 100;
НоваяСтрока.Факт = 92;
Доступ по индексам тоже возможен: Таблица[0][1] вернёт значение первой строки второй колонки. Однако читабельность кода выше при обращении по имени колонки, особенно когда таблица расширяется.
Дополнительное преимущество — встроенные операции: Итог() считает сумму по колонке, Найти() ищет строку по значению, Сортировать() упорядочивает данные. Для массива массивов всё это пришлось бы писать вручную.
Заполнение и обход матрицы
Типовой обход — два вложенных цикла: внешний по строкам, внутренний по колонкам. Для массива массивов границы берутся методом Количество(), для таблицы значений удобнее цикл Для Каждого.
// Обход массива массивов
Для И = 0 По Матрица.Количество() - 1 Цикл
Для Ж = 0 По Матрица[И].Количество() - 1 Цикл
Матрица[И][Ж] = И * 10 + Ж;
КонецЦикла;
КонецЦикла;
// Обход таблицы значений
Для Каждого Строка Из Таблица Цикл
Строка.Отклонение = Строка.Факт - Строка.План;
КонецЦикла;
Для диагональных операций — например, заполнения главной диагонали единицами при построении единичной матрицы — достаточно одного цикла: Матрица[И][И] = 1;. Условие внутри двойного цикла Если И = Ж Тогда тоже работает, но выполняет лишние итерации.
Если матрица большая и в цикле выполняются обращения к базе данных, вынесите запросы за пределы цикла: получите выборку один раз и обходите её в памяти. Запрос внутри вложенного цикла — самая частая причина «зависающих» обработок.
Проверка результата и отладка
Убедиться, что матрица создана корректно, можно без вывода на форму. Для массива проверьте количество строк и длину первой строки — этого достаточно, чтобы отловить «рваные» вложенные массивы. Для таблицы значений полезно вывести содержимое через ВыбратьСтроку() в толстом клиенте или временно загрузить таблицу в реквизит формы.
Сообщить("Строк: " + Матрица.Количество());
Сообщить("Колонок: " + Матрица[0].Количество());
Сообщить("Ячейка [1][1]: " + Матрица[1][1]);
В отладчике конфигуратора массивы и таблицы значений раскрываются в табло: добавьте переменную в окно наблюдения и проверяйте значения ячеек пошагово. Это быстрее, чем расставлять Сообщить() по всему коду.
Как проверить результат
Матрица.Количество() равно заданному числу строк, все внутренние массивы одинаковой длины
Длины строк различаются — при обходе будет ошибка индекса
Ячейки содержат ожидаемые начальные значения (0, пусто, расчёт)
Ячейки содержат Неопределено — массив создан, но не заполнен
Колонки имеют имена и типы, строки добавлены
Колонки есть, но строк нет — цикл Для Каждого молча ничего не делает
Типичные ошибки при работе с матрицами
Самая распространённая ошибка — путаница с нумерацией с нуля. Разработчик создаёт массив из десяти элементов и обращается к индексу 10, получая исключение. Проверяйте границы циклов: условие должно быть По Количество - 1.
Вторая частая проблема — «рваная» матрица, когда внутренние массивы имеют разную длину. Такое случается, если строки добавляются в разных ветках условий. Перед обходом стоит перебирать строки через Для Каждого и брать длину каждой строки отдельно, а не опираться на первую.
Третья ошибка — использование таблицы значений там, где достаточно массива: например, для промежуточной матрицы коэффициентов в расчёте. Таблица тяжелее, и на больших объёмах разница в скорости заметна. Обратная ошибка — попытка вывести массив массивов пользователю, хотя для этого предназначена таблица значений или динамический список.
Частые вопросы
Можно ли создать трёхмерную матрицу в 1С?
Да, добавив ещё один уровень вложенности: массив, содержащий массивы массивов. Обращение будет вида Куб[И][Ж][К]. На практике структуры глубже трёх измерений быстро становятся нечитаемыми — для таких данных лучше подходит таблица значений с дополнительными колонками-измерениями.
Как вывести матрицу на форму пользователю?
Создайте реквизит формы типа ТаблицаЗначений с нужными колонками, перетащите его на форму и в коде загрузите данные методом ЗначениеВРеквизитФормы или напрямую заполните реквизит. Массив массивов на форму напрямую не выводится — его сначала преобразуют в таблицу значений.
Что быстрее: массив массивов или таблица значений?
Для доступа по индексу и простых вычислений массив массивов заметно легче и быстрее. Таблица значений выигрывает, когда нужны поиск по значению, сортировка, итоги по колонкам и вывод в интерфейс — эти операции в ней встроенные.
Как передать матрицу с клиента на сервер?
Таблица значений напрямую между клиентом и сервером не сериализуется в управляемом приложении. Передавайте массив структур или массив массивов — они переносятся между контекстами, а на сервере при необходимости преобразуются в таблицу значений.
Как заполнить матрицу случайными числами?
Используйте объект ГенераторСлучайныхЧисел: создайте его один раз до цикла с начальным числом и вызывайте метод СлучайноеЧисло(Мин, Макс) при заполнении каждой ячейки. Создавать генератор внутри цикла не нужно — последовательность будет хуже, а код медленнее.
Есть ли в 1С готовые матричные операции — сложение, умножение матриц?
Нет, встроенных математических операций над матрицами в языке нет. Сложение, умножение и транспонирование реализуются вложенными циклами вручную. Для тяжёлой математики иногда используют внешние компоненты, но в типовых учётных задачах это почти не требуется.
Что важно запомнить
Матрица в 1С — это массив массивов для индексных вычислений или таблица значений для именованных данных. Помните про нумерацию с нуля, не выполняйте запросы внутри вложенных циклов и проверяйте размерность до обхода.