Как свернуть сильно кастомизированную базу 1С:УПП 1.3, если стандартная обработка выдает ошибки?

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

Свертка крупных и сильно измененных («переписанных») баз на платформе 1С:Предприятие — это всегда вызов для разработчика. Особенно остро эта проблема стоит в конфигурации 1С:Управление производственным предприятием (УПП) редакции 1.3. Из-за обилия сложных, тесно связанных между собой регистров накопления и сведений, стандартная обработка свертки (СверткаИнформационнойБазы.epf с диска ИТС) часто оказывается абсолютно бессильной. Она либо аварийно завершает работу из-за ошибок уникальности записей, либо зависает на этапе записи документов корректировки, либо формирует некорректные остатки.

В этой статье мы подробно разберем, почему стандартные механизмы пасуют перед кастомизированными конфигурациями, какие данные категорически нельзя подвергать автоматической свертке и как реализовать надежные альтернативные сценарии свертки базы данных своими силами.

Почему стандартная свертка «ломается» на нетиповых базах УПП 1.3?

Давайте проанализируем основные технические причины, по которым стандартная обработка превращает свертку базы в бесконечный процесс устранения ошибок:

  1. Конфликты уникальности в регистрах сведений. При попытке «схлопнуть» периодические регистры сведений на определенную дату (например, ЖурналУчетаСчетовФактур, ЦеныНоменклатуры, разнообразные регистры соответствия объектов) стандартный механизм пытается записать данные с одинаковым набором измерений. Если в базе за прошлые годы скопился «мусор» или ручные корректировки с некорректными датами, транзакция записи падает по ошибке уникальности.
  2. Сложная структура учета НДС. Подсистема учета НДС в УПП 1.3 завязана на документы-регистраторы (счета-фактуры, документы поступления и реализации). Если мы просто запишем остатки по регистрам НДС предъявленный или НДС Расчеты с поставщиками с помощью документа КорректировкаЗаписейРегистров (КЗР) и удалим исходные документы прошлых периодов, мы получим «битые ссылки» в аналитике партий НДС. Это сделает невозможным построение книги покупок и продаж за переходный период.
  3. Проблемы с РАУЗ (Расширенная аналитика учета затрат). При использовании РАУЗ вся себестоимость и затраты хранятся в ключевых регистрах УчетЗатрат и УчетЗатратРегл. Стандартная свертка не учитывает скрытые перекосы в аналитике (например, когда по какому-то ключу аналитики зависла сумма без количества или наоборот). После стандартной свертки первый же расчет себестоимости в новом периоде выдаст критические ошибки или некорректные распределения.

Что категорически нельзя сворачивать (исключаем из обработки)

Прежде чем приступать к процедуре свертки (любым из способов), мы должны настроить правила так, чтобы не обрабатывать разделы учета, жестко завязанные на исторические данные:

---

Вариант А. Перенос остатков в чистую базу (Рекомендуемый подход)

Если конфигурация сильно переписана, лучшим решением по соотношению трудозатрат и итогового качества будет создание пустой копии текущей базы (сохранив только структуру метаданных со всеми вашими доработками) и перенос остатков.

Рассмотрим пошагово этот сценарий:

  1. Создаем резервную копию рабочей базы, выгружаем конфигурацию в файл .cf.
  2. Создаем новую пустую базу данных и загружаем в нее сохраненную структуру метаданных.
  3. С помощью конфигурации «1С:Конвертация данных 2.0» создаем правила обмена между старой и новой базами. При этом настраиваем перенос только справочной информации (НСИ). Это отличный шанс очистить базу от дублей и помеченных на удаление неиспользуемых элементов справочников.
  4. Формируем правила переноса остатков по бухгалтерским счетам на дату свертки (например, на 31.12.2017) в документы ВводОстатков.
  5. Переносим остатки по регистрам накопления (взаиморасчеты, товары на складах) напрямую в документы КорректировкаЗаписейРегистров в новой базе.

Преимущества: В новой базе гарантированно не будет скрытого мусора, транзакционного лога на терабайты и битых ссылок. База максимально сжимается в объеме и демонстрирует высокую производительность с первых дней работы.

---

Вариант Б. Написание собственной «быстрой» свертки через КЗР и транзакции

Если перенос данных в новую базу затруднен из-за слишком сложных нетиповых связей, мы можем написать собственную обработку для «мягкой» очистки базы на месте. Наша главная задача — обойти тяжелые стандартные механизмы контроля ссылочной целостности при удалении старых документов, которые и вызывают зависание системы.

Проанализируем по шагам логику работы нашей будущей обработки:

Шаг 1. Получение остатков и создание документов КЗР

Мы должны программно собрать остатки по ключевым регистрам накопления на дату свертки и записать их в документы КорректировкаЗаписейРегистров. Рассмотрим пример кода для формирования остатков по регистру накопления ТоварыНаСкладах:


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

Шаг 2. Очистка движений старых документов (Снятие с проведения)

Перед тем как удалять сами документы, нам нужно быстро очистить их движения в базе данных. Стандартная процедура отмены проведения может занимать колоссальное количество времени, так как она запускает алгоритмы контроля остатков. Чтобы этого избежать, мы будем использовать свойство ОбменДанными.Загрузка = Истина. Это позволит очистить наборы записей регистров напрямую.

Рассмотрим пример быстрого отключения движений у документов реализации:


Процедура ОчиститьДвиженияРеализаций(ДатаСвертки)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   РеализацияТоваровУслуг.Ссылка КАК Ссылка
        |ИЗ
        |   Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
        |ГДЕ
        |   РеализацияТоваровУслуг.Дата <= &ДатаСвертки";
    
    Запрос.УстановитьПараметр("ДатаСвертки", КонецДня(ДатаСвертки));
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
        
        // Очищаем движения по всем регистрам, на которые влияет документ
        Для Каждого НаборДвижений Из ДокОбъект.Движения Цикл
            Если НаборДвижений.Количество() > 0 Тогда
                НаборДвижений.Очистить();
                НаборДвижений.Записать();
            КонецЕсли;
        КонецЦикла;
        
        // Помечаем документ на удаление без лишней бизнес-логики
        ДокОбъект.ОбменДанными.Загрузка = Истина;
        ДокОбъект.ПометкаУдаления = Истина;
        ДокОбъект.Записать();
    КонецЦикла;
    
    Сообщить("Движения документов реализации до даты свертки успешно очищены.");
    
КонецПроцедуры

Шаг 3. Физическое удаление объектов

После того как все документы до даты свертки лишились движений в регистрах и были помечены на удаление, мы запускаем стандартную процедуру «Удаление помеченных объектов».

Если объем удаляемых данных исчисляется миллионами строк, рекомендуется выполнять удаление порциями, чтобы избежать переполнения лога транзакций СУБД. В завершение обязательно запускаем операцию «Тестирование и исправление информационной базы» (ТиИ) со включенными опциями «Очищать ссылки» для обработки оставшихся зависших ссылок в реквизитах других объектов.

---

Вариант В. Свертка на уровне СУБД (Для терабайтных баз)

Если размер вашей базы данных УПП 1.3 превышает несколько сотен гигабайт, удаление старых документов стандартными средствами платформы 1С может занять недели. В таких критических случаях системные администраторы и ведущие разработчики прибегают к гибридному методу с задействованием СУБД (MS SQL Server или PostgreSQL):

  1. Создаем документы остатков КЗР на дату свертки средствами 1С (как описано в Варианте Б).
  2. Переводим базу данных в режим Simple (для MS SQL), чтобы не перегружать транзакционный лог.
  3. На уровне СУБД с помощью SQL-скриптов выполняем быструю очистку таблиц документов и таблиц движений регистров по условию даты. Ниже представлен концептуальный пример SQL-запроса для очистки движений (физические имена таблиц 1С можно узнать с помощью функции ПолучитьСтруктуруХраненияБазыДанных()):
    
    -- Пример очистки движений регистра накопления в MS SQL Server
    DELETE FROM _AccumReg12345 
    WHERE Period <= '2017-12-31 23:59:59'
    
  4. После выполнения удаления на уровне SQL база данных будет содержать некорректные индексные таблицы и миллионы «битых» объектных ссылок (UUID, которые ссылаются на несуществующие строки в таблицах документов).
  5. Для восстановления целостности базы данных в обязательном порядке запускаем утилиту chdbfl.exe (для файловых баз) или запускаем Тестирование и исправление в конфигураторе 1С с выбранными режимами:
    • При наличии недействительных ссылок на объекты: Очищать ссылки.
    • При наличии объектов с несуществующими ссылками: Удалять объекты.

Важное предупреждение: Метод SQL-свертки требует глубокого понимания структуры хранения данных 1С и должен выполняться исключительно на копии базы данных опытным администратором СУБД.

---

Подведем итоги

Свертка кастомизированной базы 1С:УПП 1.3 — это сложная процедура, требующая индивидуального архитектурного планирования. Мы выяснили, что стандартная обработка часто оказывается неэффективной из-за специфики учета НДС, РАУЗ и кадровых данных.

Для большинства переписанных баз оптимальным путем является Вариант А (создание новой базы и перенос остатков). Он гарантирует чистоту учета и отсутствие скрытых ошибок. Если же вы ограничены во времени или бюджете, используйте Вариант Б с программным формированием документов корректировки и отключением транзакционной логики через ОбменДанными.Загрузка = Истина. Это сбережет ваши нервы и позволит успешно войти в новый рабочий год с легкой и быстрой базой данных!

← На главную