При проектировании алгоритмов автоматического заказа товаров и планирования закупок разработчики часто сталкиваются с задачей регулярной выборки и временного хранения статистических данных. Рассмотрим типовой сценарий: каждое воскресенье регламентное задание собирает продажи за прошедшую неделю в разрезе дней и магазинов. В течение следующей недели другое фоновое задание ежедневно анализирует эти показатели и формирует заказы поставщикам. Возникает вопрос: в каком объекте конфигурации эффективнее и правильнее хранить подобные данные — в документе, регистре сведений или регистре накопления?
Разберем архитектурные особенности каждого объекта платформы 1С:Предприятие, проанализируем их плюсы, минусы и подберем оптимальный вариант для реализации задачи.
Регистр накопления с видом Обороты на первый взгляд кажется логичным выбором для хранения фактов продаж, так как такие данные не требуют списания остатков и всегда отражают чистый приход оборотов за период. Однако здесь кроется серьезное платформенное ограничение.
Архитектурные ограничения регистра накопления:
Если задача заключается исключительно в хранении временного недельного среза для последующего чтения регламентными заданиями, оптимальным инструментом выступает независимый регистр сведений.
Преимущества независимого регистра сведений:
РегистрСведенийНаборЗаписей.Магазин, Номенклатура и ДатаПродажи, СУБД автоматически создаст кластерный индекс. Это обеспечит максимальную производительность при выборке срезов для алгоритма автозаказа.Посмотрим на пример того, как регламентное задание может записать рассчитанные агрегаты продаж в независимый регистр сведений:
НаборЗаписей = РегистрыСведений.ПродажиЗаПрошлуюНеделю.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Магазин.Установить(ТекущийМагазин);
// Очищаем предыдущие данные по магазину перед обновлением
НаборЗаписей.Записать();
// Заполняем актуальными расчетами
Для Каждого СтрокаТаблицы Из ТаблицаПродаж Цикл
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Магазин = СтрокаТаблицы.Магазин;
НоваяЗапись.Номенклатура = СтрокаТаблицы.Номенклатура;
НоваяЗапись.ДатаПродажи = СтрокаТаблицы.ДатаПродажи;
НоваяЗапись.Количество = СтрокаТаблицы.Количество;
КонецЦикла;
НаборЗаписей.Записать();
Объект конфигурации Документ предназначен для отражения хозяйственных операций, фиксации фактов во времени и взаимодействия с пользователем.
Использовать документ для хранения недельных данных целесообразно только в следующих случаях:
Прежде чем создавать отдельный регистр или документ, проанализируем источник первичных данных. Если продажи уже фиксируются в этой же информационной базе типовыми документами (например, чеками ККМ, отчетами о розничных продажах или реализациями товаров), создание промежуточного регистра часто оказывается избыточным дублированием информации.
В типовых конфигурациях продажи уже формируют записи в штатных регистрах накопления. В этом случае регламентному заданию достаточно напрямую обратиться с запросом к виртуальной таблице Обороты соответствующего регистра за нужный интервал дат:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПродажиОбороты.ПериодДЕНЬ КАК ДатаПродажи,
| ПродажиОбороты.Склад КАК Магазин,
| ПродажиОбороты.Номенклатура КАК Номенклатура,
| ПродажиОбороты.КоличествоОборот КАК Количество
|ИЗ
| РегистрНакопления.Продажи.Обороты(&НачалоПрошлойНедели, &КонецПрошлойНедели, Авто, ) КАК ПродажиОбороты";
Запрос.УстановитьПараметр("НачалоПрошлойНедели", НачалоНедели(ТекущаяДата() - 7 * 86400));
Запрос.УстановитьПараметр("КонецПрошлойНедели", КонецНедели(ТекущаяДата() - 7 * 86400));
РезультатЗапроса = Запрос.Выполнить();
Создание отдельного хранилища (независимого регистра сведений) полностью оправдано лишь тогда, когда данные загружаются из внешних баз, кассовых серверов, либо расчет недельного агрегата настолько ресурсоемок, что его предварительное кэширование в воскресенье критически снижает нагрузку на систему в течение недели.