Как корректно выгрузить одну организацию из крупной базы 1С:УПП 1.3?

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

При ведении многофирменного учета в конфигурации 1С:Управление производственным предприятием (УПП) редакции 1.3 рано или поздно возникает задача разделения бизнеса или передачи учета по конкретному юридическому лицу сторонним владельцам. На практике это означает необходимость выгрузить все данные по одной организации в отдельную базу, оставив историю, справочники и настройки в неизменном виде.

Когда размер базы составляет несколько гигабайт, задача решается стандартной выгрузкой в XML. Но если база имеет внушительный объем (например, от 20–30 ГБ в формате .dt, что в СУБД эквивалентно 100 ГБ и более), классические механизмы 1С начинают выдавать ошибки нехватки памяти (Out of memory) или растягивают процесс на недели. Разберем детально три эффективных метода разделения крупной информационной базы УПП 1.3, проанализируем их плюсы, минусы и особенности реализации.

Метод 1. Создание полной копии базы и удаление лишних данных

Для баз данных большого объема это самый надежный и предсказуемый способ. Вместо попыток выгрузить огромный объем нужной информации в пустую базу, мы берем копию текущей базы и удаляем из нее все сведения по ненужным организациям. Однако стандартное удаление помеченных объектов в УПП на больших объемах документов работает крайне медленно из-за непрерывного контроля ссылочной целостности платформой 1С.

Рассмотрим по шагам, как автоматизировать этот процесс программно, отключив контроль целостности на время удаления.

Шаг 1. Программная пометка на удаление документов по фильтру организации

Для начала напишем обработку, которая быстро пометит на удаление все документы, относящиеся к исключаемым организациям. Мы будем обходить метаданные документов, искать реквизит Организация и устанавливать пометку.


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

Шаг 2. Непосредственное удаление документов без контроля ссылок

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


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

Шаг 3. Восстановление целостности базы через Тестирование и исправление (ТиИ)

После удаления документов в базе останутся связанные записи в регистрах сведений, регистр накопления и битые ссылки. Чтобы корректно завершить очистку:

  1. Откроем базу в режиме Конфигуратор.
  2. Перейдем в меню Администрирование -> Тестирование и исправление...
  3. Установим флаги напротив проверок: «Проверка ссылочной целостности информационной базы».
  4. В правилах обработки ошибок выберем опции:
    • При наличии неразрешенных ссылок -> «Очищать ссылки»;
    • При наличии объектов без зарегистрированных данных -> «Удалять объекты».
  5. Запустим процесс. Платформа самостоятельно удалит осиротевшие движения регистров и очистит реквизиты, ссылавшиеся на удаленные документы.

Совет для СУБД MS SQL/PostgreSQL: Если вы обладаете навыками администрирования баз данных, удаление записей по организации в таблицах _Document... и связанных с ними таблицах движений _AccumReg... можно выполнить напрямую через SQL-запросы. Это займет не более 10–15 минут, после чего запущенное в конфигураторе Тестирование и исправление (ТиИ) приведет базу 1С в полностью корректное и целостное состояние.

---

Метод 2. Модификация плана обмена «Обмен с УПП 1.3» (РИБ с фильтрацией)

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

Шаг 1. Включение признака РИБ в конфигураторе

  1. Откроем конфигурацию УПП в Конфигураторе (база должна быть снята с поддержки или находиться на поддержке с возможностью изменения).
  2. Найдем ветку Планы обмена -> ОбменУПП.
  3. Откроем палитру свойств этого плана обмена и установим свойство «Распределенная информационная база» в значение Истина.
  4. Обновим конфигурацию базы данных (F7).

Шаг 2. Создание узла обмена и начального образа

  1. Запустим программу 1С:УПП в режиме Предприятие.
  2. Откроем форму настроек плана обмена «Обмен с УПП 1.3».
  3. Создадим новый подчиненный узел. В табличной части настройки отборов укажем только ту Организацию, данные по которой нам нужно перенести.
  4. Теперь, благодаря включенному свойству РИБ, нам станет доступна кнопка «Создать начальный образ». Нажмем ее и выберем файловый вариант или укажем серверные параметры для создания новой чистой базы. Платформа автоматически выгрузит туда конфигурацию и только те данные, которые соответствуют нашему отбору.

Шаг 3. Отвязка созданной базы от главного узла

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

ПланыОбмена.УстановитьГлавныйУзел(Неопределено);

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

---

Метод 3. Использование Конвертации Данных 2.0 (КД 2) с фильтрацией на уровне обработчиков событий

Если требуется перенести не просто «всё по организации», а выборочно исключить определенные виды документов или перенастроить структуру данных в процессе переноса, незаменимым инструментом становится конфигурация «Конвертация данных 2.0».

Главная проблема выгрузки через КД для баз объемом более 20 ГБ — переполнение оперативной памяти. Разберем, как правильно настроить правила конвертации, организовать фильтрацию по организации и обойти проблему нехватки памяти.

Шаг 1. Настройка глобального фильтра в правилах конвертации

Создадим правила обмена «УПП -> УПП» в Конвертации Данных. Чтобы не прописывать условия в каждом правиле выгрузки данных (ПВД) вручную, используем единый обработчик в корне правил.

  1. В КД перейдем на вкладку «Параметры» и добавим параметр Организация (тип — Ссылка на справочник «Организации»).
  2. В обработчике событий правил конвертации «Перед выгрузкой объекта» пропишем следующий универсальный код фильтрации:

// Проверяем, является ли выгружаемый объект справочником или документом
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект)) Или Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект)) Тогда
    // Проверяем наличие реквизита "Организация" у метаданных объекта
    Если Объект.Метаданные().Реквизиты.Найти("Организация") <> Неопределено Тогда
        // Сравниваем значение реквизита с переданным параметром выгрузки
        Если Объект.Организация <> Параметры.Организация Тогда
            Отказ = Истина; // Отменяем выгрузку этого объекта
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Этот код автоматически проверит любой справочник или документ перед отправкой в файл XML. Если у объекта есть реквизит Организация, и он не совпадает с выбранной нами в параметрах организацией, выгрузка объекта будет отменена.

Шаг 2. Решение проблемы нехватки памяти при выгрузке (пакетирование)

Стандартная обработка УниверсальныйОбменДаннымиXML пытается собрать весь файл выгрузки в оперативной памяти сервера перед записью на диск. При выгрузке базы объемом в десятки гигабайт это гарантированно приведет к аварийному завершению процесса. Решить эту проблему можно следующими способами:

  1. Выгрузка по периодам: Выгружайте документы частями (например, помесячно или поквартально). Сначала перенесите всю нормативно-справочную информацию (НСИ) без документов, а затем последовательно запускайте выгрузку документов за отдельные периоды.
  2. Использование пакетного режима обработки: Применяйте специализированные версии обработки обмена (например, с поддержкой разделения файлов). Такие обработки выгружают данные порциями по 5000–10000 объектов, закрывают текущий XML-файл (или отправляют его через web-сервис в базу-приемник) и очищают память перед обработкой следующего пакета.

---

Подведем итоги и выберем оптимальный вариант

Выбор конкретного метода зависит от технических характеристик вашего сервера и размера базы данных:

← На главную