Свертка крупных и сильно измененных («переписанных») баз на платформе 1С:Предприятие — это всегда вызов для разработчика. Особенно остро эта проблема стоит в конфигурации 1С:Управление производственным предприятием (УПП) редакции 1.3. Из-за обилия сложных, тесно связанных между собой регистров накопления и сведений, стандартная обработка свертки (СверткаИнформационнойБазы.epf с диска ИТС) часто оказывается абсолютно бессильной. Она либо аварийно завершает работу из-за ошибок уникальности записей, либо зависает на этапе записи документов корректировки, либо формирует некорректные остатки.
В этой статье мы подробно разберем, почему стандартные механизмы пасуют перед кастомизированными конфигурациями, какие данные категорически нельзя подвергать автоматической свертке и как реализовать надежные альтернативные сценарии свертки базы данных своими силами.
Давайте проанализируем основные технические причины, по которым стандартная обработка превращает свертку базы в бесконечный процесс устранения ошибок:
ЖурналУчетаСчетовФактур, ЦеныНоменклатуры, разнообразные регистры соответствия объектов) стандартный механизм пытается записать данные с одинаковым набором измерений. Если в базе за прошлые годы скопился «мусор» или ручные корректировки с некорректными датами, транзакция записи падает по ошибке уникальности.НДС предъявленный или НДС Расчеты с поставщиками с помощью документа КорректировкаЗаписейРегистров (КЗР) и удалим исходные документы прошлых периодов, мы получим «битые ссылки» в аналитике партий НДС. Это сделает невозможным построение книги покупок и продаж за переходный период.УчетЗатрат и УчетЗатратРегл. Стандартная свертка не учитывает скрытые перекосы в аналитике (например, когда по какому-то ключу аналитики зависла сумма без количества или наоборот). После стандартной свертки первый же расчет себестоимости в новом периоде выдаст критические ошибки или некорректные распределения.Прежде чем приступать к процедуре свертки (любым из способов), мы должны настроить правила так, чтобы не обрабатывать разделы учета, жестко завязанные на исторические данные:
---
Если конфигурация сильно переписана, лучшим решением по соотношению трудозатрат и итогового качества будет создание пустой копии текущей базы (сохранив только структуру метаданных со всеми вашими доработками) и перенос остатков.
Рассмотрим пошагово этот сценарий:
.cf.ВводОстатков.КорректировкаЗаписейРегистров в новой базе.Преимущества: В новой базе гарантированно не будет скрытого мусора, транзакционного лога на терабайты и битых ссылок. База максимально сжимается в объеме и демонстрирует высокую производительность с первых дней работы.
---
Если перенос данных в новую базу затруднен из-за слишком сложных нетиповых связей, мы можем написать собственную обработку для «мягкой» очистки базы на месте. Наша главная задача — обойти тяжелые стандартные механизмы контроля ссылочной целостности при удалении старых документов, которые и вызывают зависание системы.
Проанализируем по шагам логику работы нашей будущей обработки:
Мы должны программно собрать остатки по ключевым регистрам накопления на дату свертки и записать их в документы КорректировкаЗаписейРегистров. Рассмотрим пример кода для формирования остатков по регистру накопления ТоварыНаСкладах:
Процедура СформироватьОстаткиТоваров(ДатаСвертки)
// Получаем остатки на конец дня даты свертки
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.Склад КАК Склад,
| ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТоварыНаСкладахОстатки.СерияНоменклатуры КАК СерияНоменклатуры,
| ТоварыНаСкладахОстатки.Качество КАК Качество,
| ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период) КАК ТоварыНаСкладахОстатки";
// Граница на конец дня даты свертки
Запрос.УстановитьПараметр("Период", Новый Граница(КонецДня(ДатаСвертки), ВидГраницы.Включая));
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат;
КонецЕсли;
ТаблицаОстатков = РезультатЗапроса.Выгрузить();
// Создаем документ КорректировкаЗаписейРегистров
ДокКЗР = Документы.КорректировкаЗаписейРегистров.СоздатьДокумент();
ДокКЗР.Дата = КонецДня(ДатаСвертки);
ДокКЗР.Комментарий = "Свертка остатков товаров (технический документ)";
// Добавляем запись о регистре ТоварыНаСкладах в таблицу регистров документа
НоваяСтрокаРегистра = ДокКЗР.ТаблицаРегистровНакопления.Добавить();
НоваяСтрокаРегистра.Имя = "ТоварыНаСкладах";
// Заполняем движения документа
ДвиженияРегистра = ДокКЗР.Движения.ТоварыНаСкладах;
Для Каждого СтрокаОстатка Из ТаблицаОстатков Цикл
НовоеДвижение = ДвиженияРегистра.Добавить();
НовоеДвижение.ВидДвижения = ВидДвиженияНакопления.Приход;
НовоеДвижение.Период = КонецДня(ДатаСвертки);
ЗаполнитьЗначенияСвойств(НовоеДвижение, СтрокаОстатка);
КонецЦикла;
// Записываем документ без выполнения проверок в модулях проведения
ДокКЗР.ОбменДанными.Загрузка = Истина;
ДокКЗР.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Успешно создан документ корректировки остатков по товарам.");
КонецПроцедуры
Перед тем как удалять сами документы, нам нужно быстро очистить их движения в базе данных. Стандартная процедура отмены проведения может занимать колоссальное количество времени, так как она запускает алгоритмы контроля остатков. Чтобы этого избежать, мы будем использовать свойство ОбменДанными.Загрузка = Истина. Это позволит очистить наборы записей регистров напрямую.
Рассмотрим пример быстрого отключения движений у документов реализации:
Процедура ОчиститьДвиженияРеализаций(ДатаСвертки)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата <= &ДатаСвертки";
Запрос.УстановитьПараметр("ДатаСвертки", КонецДня(ДатаСвертки));
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Очищаем движения по всем регистрам, на которые влияет документ
Для Каждого НаборДвижений Из ДокОбъект.Движения Цикл
Если НаборДвижений.Количество() > 0 Тогда
НаборДвижений.Очистить();
НаборДвижений.Записать();
КонецЕсли;
КонецЦикла;
// Помечаем документ на удаление без лишней бизнес-логики
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.ПометкаУдаления = Истина;
ДокОбъект.Записать();
КонецЦикла;
Сообщить("Движения документов реализации до даты свертки успешно очищены.");
КонецПроцедуры
После того как все документы до даты свертки лишились движений в регистрах и были помечены на удаление, мы запускаем стандартную процедуру «Удаление помеченных объектов».
Если объем удаляемых данных исчисляется миллионами строк, рекомендуется выполнять удаление порциями, чтобы избежать переполнения лога транзакций СУБД. В завершение обязательно запускаем операцию «Тестирование и исправление информационной базы» (ТиИ) со включенными опциями «Очищать ссылки» для обработки оставшихся зависших ссылок в реквизитах других объектов.
---
Если размер вашей базы данных УПП 1.3 превышает несколько сотен гигабайт, удаление старых документов стандартными средствами платформы 1С может занять недели. В таких критических случаях системные администраторы и ведущие разработчики прибегают к гибридному методу с задействованием СУБД (MS SQL Server или PostgreSQL):
Simple (для MS SQL), чтобы не перегружать транзакционный лог.ПолучитьСтруктуруХраненияБазыДанных()):
-- Пример очистки движений регистра накопления в MS SQL Server
DELETE FROM _AccumReg12345
WHERE Period <= '2017-12-31 23:59:59'
chdbfl.exe (для файловых баз) или запускаем Тестирование и исправление в конфигураторе 1С с выбранными режимами:
Важное предупреждение: Метод SQL-свертки требует глубокого понимания структуры хранения данных 1С и должен выполняться исключительно на копии базы данных опытным администратором СУБД.
---
Свертка кастомизированной базы 1С:УПП 1.3 — это сложная процедура, требующая индивидуального архитектурного планирования. Мы выяснили, что стандартная обработка часто оказывается неэффективной из-за специфики учета НДС, РАУЗ и кадровых данных.
Для большинства переписанных баз оптимальным путем является Вариант А (создание новой базы и перенос остатков). Он гарантирует чистоту учета и отсутствие скрытых ошибок. Если же вы ограничены во времени или бюджете, используйте Вариант Б с программным формированием документов корректировки и отключением транзакционной логики через ОбменДанными.Загрузка = Истина. Это сбережет ваши нервы и позволит успешно войти в новый рабочий год с легкой и быстрой базой данных!