В процессе разработки на платформе 1С:Предприятие часто возникает задача хранения данных в виде таблицы, размеры которой (количество строк и столбцов) заранее не определены. Например, это может быть импорт данных из внешнего файла Excel, где количество заполненных ячеек варьируется от случая к случаю. В классических языках программирования для этого используются многомерные динамические массивы, однако в 1С есть свои архитектурные особенности и специализированные объекты. Рассмотрим подробнее все доступные варианты реализации этой задачи.
Хотя стандартный конструктор Новый Массив(10, 10) требует четкого указания размерности на этапе инициализации, мы можем обойти это ограничение, создав массив, элементами которого являются другие массивы. Разберем этот подход по шагам.
Проанализируем ситуацию: внешний массив будет выступать в роли "строк", а вложенные массивы — в роли "ячеек" внутри этих строк. Это позволяет нам динамически добавлять как новые строки, так и новые колонки в любую из строк в любой момент времени.
Рассмотрим пример кода для заполнения такого массива:
// Инициализируем основной (внешний) массив
ДвумерныйМассив = Новый Массив;
// Предположим, мы читаем данные в цикле (например, из файла)
Для НомерСтроки = 0 По 10 Цикл
// Для каждой "строки" создаем новый вложенный массив
НоваяСтрока = Новый Массив;
Для НомерКолонки = 0 По 5 Цикл
// Наполняем строку данными
НоваяСтрока.Добавить("Значение_" + Строка(НомерСтроки) + "_" + Строка(НомерКолонки));
КонецЦикла;
// Добавляем готовую строку во внешний массив
ДвумерныйМассив.Добавить(НоваяСтрока);
КонецЦикла;
Для доступа к элементам такого массива используется двойная индексация: ДвумерныйМассив[ИндексСтроки][ИндексКолонки]. Важно помнить, что при таком подходе система не контролирует "одинаковость" длины строк. Одна строка может содержать 3 элемента, а другая — 10, что делает структуру очень гибкой.
Выясним причину, по которой опытные разработчики 1С чаще рекомендуют использовать объект ТаблицаЗначений вместо сложных вложенных массивов. ТаблицаЗначений — это специализированный объект, оптимизированный для работы со структурами, имеющими строки и именованные колонки.
Преимущества Таблицы Значений:
Разберем пример создания динамической таблицы:
// Создаем объект ТаблицаЗначений
ТЗ = Новый ТаблицаЗначений;
// Колонки можно добавлять динамически
Для НомерКол = 1 По КоличествоКолонокВФайле Цикл
ТЗ.Колонки.Добавить("Колонка" + Строка(НомерКол));
КонецЦикла;
// Добавляем строки с данными
Для Каждого СтрокаИзФайла Из ДанныеФайла Цикл
НоваяСтрокаТЗ = ТЗ.Добавить();
Для НомерКол = 0 По ТЗ.Колонки.Количество() - 1 Цикл
НоваяСтрокаТЗ[НомерКол] = СтрокаИзФайла.ПолучитьЗначение(НомерКол);
КонецЦикла;
КонецЦикла;
Важное ограничение: объект ТаблицаЗначений доступен только на стороне сервера (за исключением толстого клиента). Если вы считываете данные из Excel на клиенте, вам придется либо передавать данные на сервер частями, либо использовать массив для транспортировки.
Посмотрим на альтернативный и довольно креативный способ имитации двумерного пространства с помощью объекта Соответствие. Это может быть полезно, если ваша матрица разреженная (заполнено мало ячеек, а координат много).
Идея заключается в формировании ключа в виде строки, объединяющей координаты X и Y. Рассмотрим реализацию:
Матрица = Новый Соответствие;
// Запись значения
ИндексСтроки = 15;
ИндексКолонки = 42;
Ключ = Строка(ИндексСтроки) + "|" + Строка(ИндексКолонки);
Матрица.Вставить(Ключ, "Данные ячейки");
// Чтение значения
Значение = Матрица.Получить(Ключ);
Если Значение = Неопределено Тогда
// Ячейка не заполнена
КонецЕсли;
Этот метод избавляет от необходимости создавать вложенные объекты для пустых строк или столбцов, экономя память при работе с очень большими, но полупустыми таблицами.
Если во втором измерении (колонках) у вас хранятся разнородные, но логически связанные данные (например: Артикул, Цена, Количество), лучше всего использовать массив Структур. Это повышает читаемость кода, так как вместо индексов [0], [1] вы будете обращаться к свойствам по именам.
Проанализируем пример:
ДанныеДляИмпорта = Новый Массив;
// В цикле по данным
НоваяЗапись = Новый Структура;
НоваяЗапись.Вставить("Номенклатура", СсылкаНаТовар);
НоваяЗапись.Вставить("Количество", 10);
НоваяЗапись.Вставить("Цена", 1500);
ДанныеДляИмпорта.Добавить(НоваяЗапись);
// Обращение к данным становится понятным
Для Каждого СтрокаДанных Из ДанныеДляИмпорта Цикл
ИтоговаяСумма = СтрокаДанных.Цена * СтрокаДанных.Количество;
КонецЦикла;
Выбор структуры данных часто зависит от того, где эти данные будут использоваться. Рассмотрим технические нюансы:
Массив (включая массив массивов или массив структур) является универсальным типом. Его можно легко передать с клиента на сервер и обратно. ТаблицаЗначений требует преобразования (например, в массив структур или через временное хранилище) для передачи в тонком клиенте.ТаблицаЗначений, так как у него нет служебной информации о типах колонок и индексах. Однако при объемах данных до 100 000 строк эта разница несущественна.Индекс = НомерСтроки * ОбщееКоличествоКолонок + НомерКолонки. Это самый быстрый способ доступа к данным в 1С.Для задачи, описанной в контексте обсуждения (импорт из Excel и последующее соединение с данными базы через запрос), наиболее эффективным будет следующий алгоритм:
Массив (или ТабличныйДокумент).ТаблицуЗначений.ТаблицуЗначений в МенеджерВременныхТаблиц.Такой подход объединяет гибкость динамических структур на этапе чтения и мощь механизмов 1С при обработке данных в запросах.