При свертке информационных баз, таких как Альфа-Авто, часто возникает потребность в сохранении данных о продажах за прошлые периоды для целей планирования закупок. Однако хранение сотен тысяч записей в основной базе после свертки может казаться избыточным, если эти данные потребуются лишь временно (на год или полтора). Рассмотрим ситуацию, когда необходимо сохранить около 720 000 записей об оборотах товаров с возможностью быстрого произвольного доступа по конкретным позициям, не прибегая к полному сканированию файла.
Проанализируем стандартные механизмы работы 1С с форматами XML и JSON. Объекты ЧтениеXML и ЧтениеJSON работают по принципу потокового чтения. Это означает, что для поиска данных по одному товару, находящемуся в конце файла объемом в 700 000 строк, системе придется последовательно прочитать и обработать все предыдущие записи.
Разберем основные ограничения этих форматов:
XPath существует для XML, его использование часто требует полной загрузки DOM (объект ДокументHTML или аналоги), что при объеме в 720 000 записей приведет к колоссальному потреблению оперативной памяти и зависанию системы.JSONPath, что делает произвольный поиск в больших JSON-файлах еще более трудоемким.Если данные необходимо хранить именно в файле, проверенным временем и эффективным решением является формат DBF. В отличие от текстовых форматов, объект 1С XBase поддерживает работу с индексами, что обеспечивает мгновенный поиск.
Рассмотрим алгоритм реализации этого метода:
.dbf с полями: ID_TOVAR (строка для UUID), PERIOD (дата или число), QUANTITY (число)..cdx по полю ID_TOVAR.Посмотрим на пример кода для поиска данных в таком файле:
// Открываем файл и подключаем индекс
ФайлАрхива = Новый XBase;
ФайлАрхива.ОткрытьФайл("C:\Archive\Sales.dbf", "C:\Archive\Sales.cdx");
Если ФайлАрхива.Открыта() Тогда
ФайлАрхива.ТекущийИндекс = ФайлАрхива.Индексы.ID_IDX;
// Ищем конкретный товар по его уникальному идентификатору
UUIDТовара = Строка(ТоварСсылка.УникальныйИдентификатор());
Если ФайлАрхива.Найти(UUIDТовара, "=") Тогда
// Данные найдены, можем перебирать записи, если их несколько
Пока ФайлАрхива.ID_TOVAR = UUIDТовара Цикл
// Обработка данных (например, суммирование по месяцам)
Количество = ФайлАрхива.QUANTITY;
Если Не ФайлАрхива.Следующая() Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ФайлАрхива.ЗакрытьФайл();
КонецЕсли;
Преимущества: Скорость поиска практически не зависит от размера файла, а работа ведется напрямую из 1С без внешних компонент.
Если требуется более сложная аналитика (например, запросы со сложными фильтрами), проанализируем использование SQLite. Это компактная база данных в одном файле, к которой можно обращаться через COM-объект ADODB.Connection.
Выясним преимущества этого подхода:
SELECT SUM(Quantity) FROM Sales WHERE ItemID = ...).Для работы потребуется установленный в системе ODBC драйвер SQLite. Обращение из 1С будет выглядеть как работа с внешним источником данных, но на уровне программного кода через ADO.
Несмотря на желание вынести данные из базы, разберем ситуацию с точки зрения производительности SQL-сервера, на котором работает 1С. 720 000 записей — это крайне малый объем для современной СУБД (Microsoft SQL Server или PostgreSQL). В среднем такая таблица будет занимать от 50 до 150 Мб дискового пространства.
Почему стоит выбрать Регистр Сведений (РС):
Запросы, Система Компоновки Данных (СКД), автоматические итоги (если использовать Регистр Накопления).Если конфигурация "Альфа-Авто" не поддерживает расширения (например, из-за режима совместимости или специфики защиты), вы можете добавить новый объект в саму конфигурацию. Поскольку данные нужны на ограниченный срок, по истечении года этот регистр можно просто очистить или удалить объект из метаданных.
При любом способе хранения (кроме внутреннего регистра) важно помнить, что после свертки базы ссылки на объекты могут физически исчезнуть. Поэтому при выгрузке данных в файл всегда сохраняйте текстовое представление Уникального Идентификатора (UUID).
Рассмотрим пример получения строкового ID для записи в файл:
ИдентификаторСтрокой = Строка(СсылкаНаТовар.УникальныйИдентификатор());
// Именно эту строку мы записываем в поле ID_TOVAR нашего DBF или SQLite файла
При поиске в архиве вы будете получать идентификатор текущего товара из базы и сопоставлять его со строкой в файле. Это гарантирует точность поиска даже при частичном изменении наименований товаров в основной базе.
Проанализировав все варианты, можно сделать следующие выводы: