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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие часто возникает задача хранения данных в виде таблицы, размеры которой (количество строк и столбцов) заранее не определены. Например, это может быть импорт данных из внешнего файла Excel, где количество заполненных ячеек варьируется от случая к случаю. В классических языках программирования для этого используются многомерные динамические массивы, однако в 1С есть свои архитектурные особенности и специализированные объекты. Рассмотрим подробнее все доступные варианты реализации этой задачи.

Вариант 1. Использование массива массивов (зубчатый массив)

Хотя стандартный конструктор Новый Массив(10, 10) требует четкого указания размерности на этапе инициализации, мы можем обойти это ограничение, создав массив, элементами которого являются другие массивы. Разберем этот подход по шагам.

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

Рассмотрим пример кода для заполнения такого массива:


// Инициализируем основной (внешний) массив
ДвумерныйМассив = Новый Массив;

// Предположим, мы читаем данные в цикле (например, из файла)
Для НомерСтроки = 0 По 10 Цикл
    // Для каждой "строки" создаем новый вложенный массив
    НоваяСтрока = Новый Массив;
    
    Для НомерКолонки = 0 По 5 Цикл
        // Наполняем строку данными
        НоваяСтрока.Добавить("Значение_" + Строка(НомерСтроки) + "_" + Строка(НомерКолонки));
    КонецЦикла;
    
    // Добавляем готовую строку во внешний массив
    ДвумерныйМассив.Добавить(НоваяСтрока);
КонецЦикла;

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

Вариант 2. Таблица значений — стандарт 1С для табличных данных

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

Преимущества Таблицы Значений:

  1. Возможность типизации колонок (число, строка, дата).
  2. Встроенные методы сортировки, поиска и сворачивания (группировки) данных.
  3. Возможность использования в запросах (после помещения во временную таблицу).
  4. Удобная работа с индексами для ускорения поиска.

Разберем пример создания динамической таблицы:


// Создаем объект ТаблицаЗначений
ТЗ = Новый ТаблицаЗначений;

// Колонки можно добавлять динамически
Для НомерКол = 1 По КоличествоКолонокВФайле Цикл
    ТЗ.Колонки.Добавить("Колонка" + Строка(НомерКол));
КонецЦикла;

// Добавляем строки с данными
Для Каждого СтрокаИзФайла Из ДанныеФайла Цикл
    НоваяСтрокаТЗ = ТЗ.Добавить();
    Для НомерКол = 0 По ТЗ.Колонки.Количество() - 1 Цикл
        НоваяСтрокаТЗ[НомерКол] = СтрокаИзФайла.ПолучитьЗначение(НомерКол);
    КонецЦикла;
КонецЦикла;

Важное ограничение: объект ТаблицаЗначений доступен только на стороне сервера (за исключением толстого клиента). Если вы считываете данные из Excel на клиенте, вам придется либо передавать данные на сервер частями, либо использовать массив для транспортировки.

Вариант 3. Использование соответствия с составным ключом

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

Идея заключается в формировании ключа в виде строки, объединяющей координаты X и Y. Рассмотрим реализацию:


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

// Запись значения
ИндексСтроки = 15;
ИндексКолонки = 42;
Ключ = Строка(ИндексСтроки) + "|" + Строка(ИндексКолонки);
Матрица.Вставить(Ключ, "Данные ячейки");

// Чтение значения
Значение = Матрица.Получить(Ключ);
Если Значение = Неопределено Тогда
    // Ячейка не заполнена
КонецЕсли;

Этот метод избавляет от необходимости создавать вложенные объекты для пустых строк или столбцов, экономя память при работе с очень большими, но полупустыми таблицами.

Вариант 4. Массив структур — когда колонки имеют смысл

Если во втором измерении (колонках) у вас хранятся разнородные, но логически связанные данные (например: Артикул, Цена, Количество), лучше всего использовать массив Структур. Это повышает читаемость кода, так как вместо индексов [0], [1] вы будете обращаться к свойствам по именам.

Проанализируем пример:


ДанныеДляИмпорта = Новый Массив;

// В цикле по данным
НоваяЗапись = Новый Структура;
НоваяЗапись.Вставить("Номенклатура", СсылкаНаТовар);
НоваяЗапись.Вставить("Количество", 10);
НоваяЗапись.Вставить("Цена", 1500);

ДанныеДляИмпорта.Добавить(НоваяЗапись);

// Обращение к данным становится понятным
Для Каждого СтрокаДанных Из ДанныеДляИмпорта Цикл
    ИтоговаяСумма = СтрокаДанных.Цена * СтрокаДанных.Количество;
КонецЦикла;

Сравнение производительности и передачи данных

Выбор структуры данных часто зависит от того, где эти данные будут использоваться. Рассмотрим технические нюансы:

  1. Передача Клиент-Сервер: Объект Массив (включая массив массивов или массив структур) является универсальным типом. Его можно легко передать с клиента на сервер и обратно. ТаблицаЗначений требует преобразования (например, в массив структур или через временное хранилище) для передачи в тонком клиенте.
  2. Память: Массив массивов потребляет чуть меньше памяти, чем ТаблицаЗначений, так как у него нет служебной информации о типах колонок и индексах. Однако при объемах данных до 100 000 строк эта разница несущественна.
  3. Математические задачи: Если вам нужно реализовать математическую матрицу, лучше использовать одномерный массив с вычисляемым индексом по формуле Индекс = НомерСтроки * ОбщееКоличествоКолонок + НомерКолонки. Это самый быстрый способ доступа к данным в 1С.

Практический совет по импорту из Excel

Для задачи, описанной в контексте обсуждения (импорт из Excel и последующее соединение с данными базы через запрос), наиболее эффективным будет следующий алгоритм:

  1. На клиенте прочитать файл Excel в Массив (или ТабличныйДокумент).
  2. Передать этот массив на сервер.
  3. На сервере выгрузить массив в ТаблицуЗначений.
  4. Поместить ТаблицуЗначений в МенеджерВременныхТаблиц.
  5. Выполнить запрос к временной таблице, соединяя её с необходимыми справочниками или регистрами.

Такой подход объединяет гибкость динамических структур на этапе чтения и мощь механизмов 1С при обработке данных в запросах.

← На главную