При работе в распределенных информационных базах (РИБ) с большим количеством узлов (например, более 50 магазинов) разработчики часто сталкиваются с проблемой обновления конфигурации. Если база данных работает давно, в ней накапливаются миллионы архивных чеков ККМ. Попытка добавить даже один новый реквизит в шапку или табличную часть документа ЧекККМ стандартным способом приводит к запуску процесса реструктуризации СУБД.
Для крупных таблиц этот процесс может занимать долгие часы, блокируя работу торговых точек и создавая колоссальную нагрузку на дисковую подсистему серверов. В этой статье мы подробно разберем, как реализовать задачу добавления новой аналитики («Количество») к чеку ККМ и последующего переноса этих данных в ОтчетОРозничныхПродажах без изменения структуры самого документа.
Когда мы добавляем новый реквизит непосредственно в метаданные документа Документ.ЧекККМ, платформа 1С при обновлении конфигурации базы данных выполняет реструктуризацию таблицы этого документа. На СУБД (например, MS SQL Server или PostgreSQL) создается временная таблица, куда копируются все миллионы существующих записей, после чего старая таблица удаляется, а новая переименовывается. В распределенной сети из 50+ баз такое обновление гарантированно приведет к простоям на кассовых узлах. Нам необходимо найти архитектурное решение, которое позволит обойти этот процесс.
Проанализируем четыре наиболее эффективных и безопасных способа решения этой задачи.
---
Это наиболее надежный, гибкий и профессиональный подход. Вместо изменения самого документа ЧекККМ мы создаем новый независимый регистр сведений, который будет хранить связь между чеком и нужным нам показателем.
Шаг 1. Создание нового регистра сведений
Создадим в конфигураторе новый регистр сведений, например, ДополнительныеДанныеЧеков со следующими свойствами:
ЧекККМ (тип ДокументСсылка.ЧекККМ).Количество (тип Число, длина 10, точность 3).Шаг 2. Добавление поля ввода на форму РМК
В расширении конфигурации добавим на форму РМК (рабочее место кассира) новое поле ввода, связанное с реквизитом формы (не реквизитом объекта!). Кассир будет заполнять это поле при оформлении продажи.
Шаг 3. Запись данных при пробитии чека
В модуле формы РМК или при проведении чека (через подписку на событие ПередЗаписью или ПриЗаписи) выполним программную запись значения в наш регистр сведений. Разберем пример кода:
Процедура ЗаписатьДополнительныеДанныеЧека(СсылкаНаЧек, ВведенноеКоличество) Экспорт
НаборЗаписей = РегистрыСведений.ДополнительныеДанныеЧеков.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ЧекККМ.Установить(СсылкаНаЧек);
НоваяСтрока = НаборЗаписей.Добавить();
НоваяСтрока.ЧекККМ = СсылкаНаЧек;
НоваяСтрока.Количество = ВведенноеКоличество;
Попытка
НаборЗаписей.Записать();
Исключение
ЗаписьЖурналаРегистрации("Ошибка записи дополнительных данных чека",
УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Шаг 4. Сбор данных при закрытии смены
При формировании документа ОтчетОРозничныхПродажах во время закрытия смены мы можем легко прочитать эти данные с помощью запроса, связав чеки смены с нашим регистром сведений, просуммировать количество и записать его в движения документа по новому регистру накопления.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеДанные.Количество КАК Количество,
| ДополнительныеДанные.ЧекККМ КАК ЧекККМ
|ИЗ
| РегистрСведений.ДополнительныеДанныеЧеков КАК ДополнительныеДанные
|ГДЕ
| ДополнительныеДанные.ЧекККМ.Ссылка В (&МассивЧековСмены)";
Запрос.УстановитьПараметр("МассивЧековСмены", МассивЧеков);
РезультатЗапроса = Запрос.Выполнить();
При таком подходе структура таблиц документов вообще не меняется. Новый регистр сведений создается "с нуля", он пуст, поэтому обновление в РИБ на всех 50 точках пройдет мгновенно.
---
Если мы не хотим создавать собственные регистры сведений, мы можем задействовать типовой механизм Библиотеки Стандартных Подсистем (БСП) — Дополнительные сведения.
Важно не путать их с «Дополнительными реквизитами»:
РегистрСведений.ДополнительныеСведения. Ссылка на документ выступает в качестве измерения Объект.Разберем по шагам, как это настроить:
ЧекККМ добавим новое дополнительное сведение «Количество» (тип Число).
// Запись значения дополнительного сведения для чека ККМ
СвойствоКоличество = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Количество (Чек ККМ)");
Если ЗначениеЗаполнено(СвойствоКоличество) Тогда
УправлениеСвойствами.ЗаписатьЗначениеСвойства(СсылкаНаЧек, СвойствоКоличество, ВведенноеКоличество); КонецЕсли;
Этот способ хорош тем, что использует полностью стандартную архитектуру 1С и БСП, не требуя создания новых объектов метаданных в конфигурации. Синхронизация регистра ДополнительныеСведения в РИБ уже настроена по умолчанию.
---
Рассмотрим альтернативный вариант, который часто применяется в условиях жесткого дефицита времени или при невозможности вносить изменения в структуру метаданных распределенной информационной базы.
Практически у каждого документа в 1С есть стандартное строковое поле Комментарий. Мы можем использовать его для хранения сериализованных или структурированных текстовых данных.
При оформлении чека в РМК мы можем записывать введенное кассиром количество в комментарий чека по определенному шаблону. Например:
[ДопКоличество: 15]
При закрытии смены и проведении документа ОтчетОРозничныхПродажах система будет обходить чеки смены, считывать строку комментария и извлекать оттуда число с помощью несложного алгоритма парсинга:
Функция ПолучитьКоличествоИзКомментария(СтрокаКомментария)
ПоискМаркера = Найти(СтрокаКомментария, "[ДопКоличество:");
Если ПоискМаркера = 0 Тогда
Возврат 0;
КонецЕсли;
ПолезныйТекст = Сред(СтрокаКомментария, ПоискМаркера + 14); // Длина маркера
КонечныйМаркер = Найти(ПолезныйТекст, "]");
Если КонечныйМаркер = 0 Тогда
Возврат 0;
КонецЕсли;
ЧислоСтрокой = СокрЛП(Лев(ПолезныйТекст, КонечныйМаркер - 1));
Попытка
Возврат Число(ЧислоСтрокой);
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Преимущества метода:
Комментарий гарантированно участвует во всех правилах обмена РИБ по умолчанию.Минусы: Метод является «костылем». При ручном изменении комментария пользователем данные могут быть повреждены. Использовать его рекомендуется только в крайних случаях.
---
Если в будущем вам все же придется вносить изменения в структуру тяжелых документов типа ЧекККМ, воспользуйтесь следующими рекомендациями, чтобы минимизировать время простоя баз в магазинах:
ОтчетОРозничныхПродажах. Это позволяет уменьшить физический размер таблицы чеков в десятки раз, и любая последующая реструктуризация будет проходить за минуты.conf.cfg пропишите параметр UpdateDBCfg=v2. В этом режиме СУБД выполняет команду быстрого добавления колонки ALTER TABLE ADD COLUMN, минуя фазу долгого копирования данных во временные таблицы.Мы проанализировали ситуацию и выяснили, что оптимальным решением для распределенной структуры с 50+ базами является Решение 1 (создание собственного независимого регистра сведений) или Решение 2 (использование дополнительных сведений БСП). Оба варианта позволяют полностью исключить реструктуризацию огромных таблиц чеков ККМ, обеспечивают быструю и корректную передачу данных через РИБ и гарантируют стабильную работу кассовых зон без задержек на обновление программного обеспечения.