При интеграции 1С со сторонними сервисами часто возникает задача периодической загрузки больших массивов нормативно-справочной информации (например, 50 000–100 000 строк). При этом конфигурация (например, «1С:Розница 2.x») должна оставаться на полной поддержке поставщика. Разберем основные варианты реализации этой задачи, их преимущества, ограничения и примеры программного кода.
Выясним причину ключевых сложностей: хранение 90 000 строк требует не только места, но и быстрого доступа при создании номенклатуры, возможности регулярной полной перезаписи и корректной работы как в файловом, так и в клиент-серверном вариантах базы.
Рассмотрим наиболее надежный и современный подход. Начиная с платформы 8.3.11, расширения позволяют создавать собственные структуры хранения данных (новые справочники и регистры сведений), которые физически размещаются в основной базе данных СУБД, сохраняя конфигурацию на полной поддержке.
Преимущества решения:
Посмотрим на пример кода полной перезаписи регистра сведений через объект РегистрСведенийНаборЗаписей:
Набор = РегистрыСведений.лм_СопоставлениеНоменклатуры.СоздатьНаборЗаписей();
Набор.Загрузить(ТаблицаДанных);
// Параметр Истина включает режим замещения существующих записей
Набор.Записать(Истина);
Если создание расширения по каким-то причинам не подходит, проанализируем вариант с выгрузкой таблицы значений в файл или реквизит служебного справочника («Присоединенные файлы»).
Для сохранения таблицы значений на диск используются методы ЗначениеВФайл и ЗначениеИзФайла, однако при работе в клиент-серверном режиме важно помнить, что путь к файлу должен быть доступен службе сервера 1С.
// Сохранение таблицы значений в файл
ИмяФайла = "C:\Exchange\HandbookData.dat";
ЗначениеВФайл(ИмяФайла, ТаблицаДанных);
// Чтение таблицы значений из файла
ТаблицаДанных = ЗначениеИзФайла(ИмяФайла);
Если требуется хранить данные непосредственно внутри базы (например, в хранилище значений), обязательно используем объект СжатиеДанных, так как несжатая таблица на 90 000 строк может занимать значительный объем памяти.
// Упаковка таблицы с максимальным сжатием
Хранилище = Новый ХранилищеЗначения(ТаблицаДанных, Новый СжатиеДанных(9));
// Извлечение таблицы из хранилища
ТаблицаДанных = Хранилище.Получить();
Разберем вариант хранения структуры данных в системных таблицах настроек. Прямой вызов метода УстановитьПривилегированныйРежим() во внешних обработках блокируется платформой по соображениям безопасности. Однако в типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как «Розница 2.x», присутствуют экспортные методы общих модулей, работающие в привилегированном контексте.
Посмотрим на программную реализацию сохранения и чтения данных через модуль ОбщегоНазначения:
// Сохранение структуры данных в ХранилищеОбщихНастроек
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(
"ИнтеграцияСправочников",
"ТаблицаСопоставления",
ХранилищеТаблицы
);
// Загрузка структуры данных
ХранилищеТаблицы = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
"ИнтеграцияСправочников",
"ТаблицаСопоставления"
);
Если ХранилищеТаблицы <> Неопределено Тогда
ТаблицаДанных = ХранилищеТаблицы.Получить();
КонецЕсли;
Важное ограничение: Не рекомендуется хранить многомегабайтные структуры в пользовательских настройках форм, так как это увеличивает размер сеансовых данных и замедляет запуск клиентского приложения.
Если необходимо изолировать массив данных от рабочей базы 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();
Когда таблица прочитана в объект ТаблицаЗначений, стандартный метод НайтиСтроки() может работать медленно при последовательном сканировании большого объема строк. Чтобы ускорить выборку данных при интерактивном создании номенклатуры, обязательно используем встроенные индексы таблицы значений:
// Добавление индекса ускоряет поиск до логарифмической сложности
ТаблицаДанных.Индексы.Добавить("Артикул");
ТаблицаДанных.Индексы.Добавить("Код, Производитель");
// Быстрый отбор с использованием индекса
ПараметрыОтбора = Новый Структура("Артикул", ИскомыйАртикул);
НайденныеСтроки = ТаблицаДанных.НайтиСтроки(ПараметрыОтбора);
Также таблицу значений можно передавать в качестве параметра в объект Запрос на сервере, помещать ее во временную таблицу с помощью конструкции ПОМЕСТИТЬ ВТ_Данные ИНДЕКСИРОВАТЬ ПО и соединять со справочником номенклатуры стандартными средствами СУБД.
Итог: Для регулярной перезаписи и быстрого поиска оптимальным решением является создание независимого регистра сведений в расширении конфигурации. Если расширения использовать нельзя, наиболее безопасным путем будет упаковка таблицы через ХранилищеЗначения с максимальным сжатием и сохранение через методы БСП или справочник присоединенных файлов.