Где и как хранить большую таблицу данных без изменения типовой конфигурации 1С?

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

При интеграции 1С со сторонними сервисами часто возникает задача периодической загрузки больших массивов нормативно-справочной информации (например, 50 000–100 000 строк). При этом конфигурация (например, «1С:Розница 2.x») должна оставаться на полной поддержке поставщика. Разберем основные варианты реализации этой задачи, их преимущества, ограничения и примеры программного кода.

Выясним причину ключевых сложностей: хранение 90 000 строк требует не только места, но и быстрого доступа при создании номенклатуры, возможности регулярной полной перезаписи и корректной работы как в файловом, так и в клиент-серверном вариантах базы.

Вариант 1. Собственный независимый регистр сведений в расширении конфигурации

Рассмотрим наиболее надежный и современный подход. Начиная с платформы 8.3.11, расширения позволяют создавать собственные структуры хранения данных (новые справочники и регистры сведений), которые физически размещаются в основной базе данных СУБД, сохраняя конфигурацию на полной поддержке.

Преимущества решения:

  1. Возможность строить прямые запросы к данным на языке 1С.
  2. Автоматическое индексирование полей и быстрый поиск.
  3. Простая и быстрая перезапись всей таблицы за одну транзакцию с замещением данных.

Посмотрим на пример кода полной перезаписи регистра сведений через объект РегистрСведенийНаборЗаписей:


Набор = РегистрыСведений.лм_СопоставлениеНоменклатуры.СоздатьНаборЗаписей();
Набор.Загрузить(ТаблицаДанных);
// Параметр Истина включает режим замещения существующих записей
Набор.Записать(Истина);

Вариант 2. Хранение сериализованной таблицы значений в файле или реквизите со сжатием

Если создание расширения по каким-то причинам не подходит, проанализируем вариант с выгрузкой таблицы значений в файл или реквизит служебного справочника («Присоединенные файлы»).

Для сохранения таблицы значений на диск используются методы ЗначениеВФайл и ЗначениеИзФайла, однако при работе в клиент-серверном режиме важно помнить, что путь к файлу должен быть доступен службе сервера 1С.


// Сохранение таблицы значений в файл
ИмяФайла = "C:\Exchange\HandbookData.dat";
ЗначениеВФайл(ИмяФайла, ТаблицаДанных);

// Чтение таблицы значений из файла
ТаблицаДанных = ЗначениеИзФайла(ИмяФайла);

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


// Упаковка таблицы с максимальным сжатием
Хранилище = Новый ХранилищеЗначения(ТаблицаДанных, Новый СжатиеДанных(9));

// Извлечение таблицы из хранилища
ТаблицаДанных = Хранилище.Получить();

Вариант 3. Использование Хранилища системных настроек через механизмы БСП

Разберем вариант хранения структуры данных в системных таблицах настроек. Прямой вызов метода УстановитьПривилегированныйРежим() во внешних обработках блокируется платформой по соображениям безопасности. Однако в типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как «Розница 2.x», присутствуют экспортные методы общих модулей, работающие в привилегированном контексте.

Посмотрим на программную реализацию сохранения и чтения данных через модуль ОбщегоНазначения:


// Сохранение структуры данных в ХранилищеОбщихНастроек
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(
    "ИнтеграцияСправочников",
    "ТаблицаСопоставления",
    ХранилищеТаблицы
);

// Загрузка структуры данных
ХранилищеТаблицы = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
    "ИнтеграцияСправочников",
    "ТаблицаСопоставления"
);
Если ХранилищеТаблицы <> Неопределено Тогда
    ТаблицаДанных = ХранилищеТаблицы.Получить();
КонецЕсли;

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

Вариант 4. Использование компактной базы SQLite

Если необходимо изолировать массив данных от рабочей базы 1С, но сохранить возможность выполнения быстрых SQL-запросов, разберем создание локальной базы SQLite в общем сетевом каталоге. Подключение выполняется через стандартный COM-объект ADODB.Connection.


Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "DRIVER=SQLite3 ODBC Driver;Database=\\server\share\data.db;";
Соединение.Open(СтрокаПодключения);

Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Соединение;
Команда.CommandText = "SELECT * FROM Handbook WHERE Code = '12345'";
Выборка = Команда.Execute();

Оптимизация работы с таблицей на 90 000 строк в памяти

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


// Добавление индекса ускоряет поиск до логарифмической сложности
ТаблицаДанных.Индексы.Добавить("Артикул");
ТаблицаДанных.Индексы.Добавить("Код, Производитель");

// Быстрый отбор с использованием индекса
ПараметрыОтбора = Новый Структура("Артикул", ИскомыйАртикул);
НайденныеСтроки = ТаблицаДанных.НайтиСтроки(ПараметрыОтбора);

Также таблицу значений можно передавать в качестве параметра в объект Запрос на сервере, помещать ее во временную таблицу с помощью конструкции ПОМЕСТИТЬ ВТ_Данные ИНДЕКСИРОВАТЬ ПО и соединять со справочником номенклатуры стандартными средствами СУБД.

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

← На главную