16 июля 2026
1C-RarusTechDay 2026
9-я открытая техническая конференция для специалистов 1С
Зарегистрироваться
{{countBasket}}
От экспертов «1С-Рарус»: Миграция из 1С:Документооборот 2.1 в 3.0. Часть 3 — восстановление доступа к файлам в ERP
От экспертов «1С-Рарус»: Миграция из 1С:Документооборот 2.1 в 3.0. Часть 3 — восстановление доступа к файлам в ERP

От экспертов «1С‑Рарус»: Миграция из 1С:Документооборот 2.1 в 3.0. Часть 3 — восстановление доступа к файлам в ERP

29.04.2026
157 мин
2068

Оглавление

  1. Предисловие
  2. Отображение файлов, открытие данных документооборота в ДО3 после миграции
  3. Неизвестный тип DMInternalDocument
  4. «Пропавшие» файлы
  5. Реализация обработчиков пакетной обработки: план автоматизации
  6. Техническая реализация: от плана к коду
  7. Результаты

Предисловие

Уважаемые читатели, мы продолжаем историю про миграцию данных из «1С:Документооборот» редакции 2.1 в 3.0.

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

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

Отображение файлов, открытие данных документооборота в ДО3 после миграции

Итак, «в прошлой серии» мы выполнили оптимизацию загрузки данных и обеспечили продолжение активных бизнес-процессов, перенесённых из ДО2 в ДО3. После этого мы снова запустили пробную миграцию на тестовом контуре. Это позволило убедиться, что основные механизмы работают, а время переноса данных сократилось до приемлемых значений (2 недели).

Вспомним схему нашего контура. На ней можно заметить, что к базе Документооборота подключена база ERP:

Схема взаимодействия систем на начало миграции

Схема взаимодействия систем на начало миграции

Данный обмен реализован через бесшовную интеграцию с помощью «Библиотеки интеграции с 1С:Документооборотом» — или «БИД» (its.1c.ru/db/bid302doc).

На момент миграции использовалась ERP версии 2.5.12.265, и Библиотека интеграции с 1С:Документооборотом версии 3.0.2.3.

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

Хранение файлов в томах DOC на примере документа «Реализация»

Теперь, после того как пробная миграция завершилась успешно — предстояло перенастроить эту интеграцию в ERP и проверить, как система поведёт себя в новой реальности.

Для этого в базе ERP мы перешли в раздел «НСИ и администрирование» → «Настройки интеграции» → «Интеграция с 1С:Документооборот», прописали в поле «URL» путь к новому опубликованному веб сервису ДО3 и установили флажок «Интеграция с 1С:Документооборотом редакции 3»:

Настройка интеграции с ДО3 в ERP: указание URL веб-сервиса и установка флага версии 3

Далее провели простую проверку: зашли как обычно в документ реализации, нажали на знакомую гиперссылку «Документооборот», чтобы проверить наличие файлов. И получили чистое поле и ошибку:

Проверка доступа к файлам через «Документооборот» — результат: пустое поле и ошибка

Может мы где-то промахнулись в настройках? Решили вернуться в форму интеграции, удостовериться в её корректности. И заметили, что настройка «Хранение присоединенных файлов» установлена в вариант «1С:Документооборот не используется»:

Настройки после переключения интеграции на ДО

Настройки после переключения интеграции на ДО

И тут важно уточнить, что до миграции при работе интеграции с ДО2 был выбран вариант «Файлы в отдельных папках», а теперь он и вовсе исчез, вот так поворот:

Настройка «Файлы в отдельных папках» присутствовала в ДО2, но исчезла в ДО3

Выбираем доступный вариант

Получается единственным доступным режимом, предполагающим хранение файлов в ДО, остался «Файлы прикреплены к документам»? За неимением альтернативы мы выбрали его:

Единственный вариант хранения файлов в ДО3

Единственный вариант хранения файлов в ДО3

Для проверки снова открываем несколько документов «Реализация товаров и услуг», к которым до миграции были прикреплены файлы.

И увы ситуация всё та же.

Симптом 1. Ошибка при открытии данных ДО

При попытке перейти по гиперссылке «Документооборот» по-прежнему возникала ошибка:

Ошибка связи документа ERP с Документооборотом

Ошибка связи документа ERP с Документооборотом

Симптом 2. Пропали файлы

В режиме «Файлы прикреплены к документам» в интерфейсе документа появилась гиперссылка «Файлы ДО»:

В режиме «Файлы прикреплены к документам» в интерфейсе появилась гиперссылка «Файлы ДО»

Но как на зло, в ней также не оказалось файлов, которые ранее были прикреплены к документу

Список файлов документа после миграции и перевода настроек интеграции на ДО3

Список файлов документа после миграции и перевода настроек интеграции на ДО3

Пробуем обновить Библиотеку интеграции документооборота (БИД)

На тот момент у нас была установлена БИД для 1C:ERP версии 3.0.2.3, хотя актуальной уже была 3.0.2.7. И возникла мысль, что дело может быть в устаревшей версии.

Мы обновили БИД в надежде, что это решит проблему, но, к сожалению, ситуацию это не исправило, и режим хранения «Файлы в отдельных папках» не вернуло.

Значит, причина глубже.

Проверяем наличие файлов в ДО3

А файлы сами то на месте? Может мы потеряли их при миграции?! Заходим в базу ДО3, проверяем:

Путь к «Файлам» в интерфейсе ДО3

Путь к «Файлам» в интерфейсе ДО3

Переходим в меню «Документы» → «Файлы» и, к счастью, обнаруживаем, что:

  • Все файлы на месте.
  • Они лежат в тех же папках, что и раньше.
  • Структура, созданная режимом «Файлы в отдельных папках», сохранилась.

Файлы в ДО3

Файлы в ДО3

Давайте разбираться.

Неизвестный тип DMInternalDocument

Начнем с относительно простого — со всплывающей ошибки в карточке документа ERP.
Имеем следующий текст ошибки:

Ошибка при получении объекта:
Попытка получить тип 1С:Документооборота для неизвестного типа XDTO: DMInternalDocument
{ОбщийМодуль.ОбработкаЗапросовXDTO.Модуль(2585)}:ВызватьИсключение СтрШаблон(
{ОбщийМодуль.ОбработкаЗапросовXDTO.Модуль(2469)}:ПолучитьТипДОПоТипуXDTO(objectId.type, ИмяТипа);
{ОбщийМодуль.ОбработкаЗапросовXDTO.Модуль(4969)}:Ссылка = ПолучитьСсылкуПоObjectID(ОбъектИд);
{ОбщийМодуль.ОбработкаЗапросовXDTO.Модуль(39)}:Результат = ПолучитьОбъекты(Сообщение);
{ОбщийМодуль.ОбработкаЗапросовXDTO.Модуль(4700)}:Ответ = ОбработатьУниверсальноеСообщение(СообщениеПакета);
{ОбщийМодуль.ОбработкаЗапросовXDTO.Модуль(30)}:Результат = ОбработатьПакет(Сообщение);
{WebСервис.DMService.Модуль(5)}:Возврат ОбработкаЗапросовXDTO.ОбработатьУниверсальноеСообщение(Запрос);

Данная фраза указывает на проблему с XDTO-типами: «Попытка получить тип 1С:Документооборота для неизвестного типа XDTO: DMInternalDocument».

Тип XDTO в 1С:Документообороте используется в обмене через веб-сервис интеграции, и в ряде случае является отражением типа метаданных базы ДО. Подробнее об этом можно почитать тут its.1c.ru/db/metod8dev#content:5889:hdoc.

Кроме этого, он участвует в блоке связи объектов ДО и интегрированных систем, расскажем про это подробнее.

Как связаны объекты ERP и ДО (архитектура интеграции)

Одна из возможностей, которую предоставляет БИД — это организация двусторонней связи объектов 1С:Документооборота и интегрированной системы. Что позволяет работать с данными ДО из интерфейса этой системы, появляется возможность обрабатывать некоторые события для участия в бизнес-процессах.

Для хранения данных об этой связи используются следующие регистры сведений, которые работают в паре:

  • «Объекты, интегрированные с 1С:Документооборотом» на стороне ERP;
  • «Связи объектов интегрированных систем» на стороне ДО.

Регистр «Объекты, интегрированные с 1С:Документооборотом» в 1С:ERP

Это главная «шпаргалка» ERP. Здесь хранится информация о том, какой документ ERP с каким документом в ДО связан. В регистре три поля:

  1. Объект — ссылка на конкретный объект в самой ERP. Например, на документ реализации товаров.
  2. Тип XDTO объекта — строковое представления XDTO типа того объекта в ДО, с которым установлена связь. Например, тот самый «DMInternalDocument», на который у нас ругалась система.
  3. Идентификатор объекта ДО — GUID связанного объекта в базе документооборота.

Пример связи объекта ERP с ДО

Пример связи объекта ERP с ДО

Когда пользователь в ERP в форме документа нажимает гиперссылку «Документооборот», система идет именно в этот регистр, находит нужную запись и по ней открывает карточку документа в ДО.

Помимо этого, при модификации объектов в ERP, система регистрирует правки, после чего регламентное задание «Обмен с Документооборотом» формирует и отправляет сообщение с изменениями.

Регистр «Связи объектов интегрированных систем» в ДО

Его задача хранить обратную информацию: какой объект ДО с каким объектом ERP связан. Здесь уже четыре основных поля:

  1. Узел интегрированной системы — ссылка на узел плана обмена, определяющий систему, с которой настроена интеграция. В нашем случае это ERP. Документооборот может одновременно обслуживать несколько учетных систем, поэтому и узлов может быть разное количество.
  2. Ссылка на объект ДО — ссылка на конкретный объект в ДО. Например для ДО2 на элемент справочника «Внутренние документы».
  3. Тип внешнего объекта — строковое представление типа объекта интегрированной системы, уже не в нотации XDTO, а в обычном представлении метаданных 1С. Например, «Документ.РеализацияТоваровУслуг».
  4. Идентификатор внешнего объекта — GUID объекта интегрированной системы.

Пример связи объектов ДО с ERP

Пример связи объектов ДО ERP

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

Помимо этого изменения, инициированные на стороне документооборота, могут служить триггерами для событий внутри ERP. К примеру, после успешного согласования документа «Заказ клиента» в ДО, его статус меняется с «На согласовании» на «К выполнению». Это изменение попадает в очередь обмена, затем регламентное задание «Обмен с Документооборотом» передает информацию в ERP. На стороне ERP на основе полученных данных по обмену может быть автоматически создан документ «Заказ на производство».

Как регистры работают в паре

Разберём процесс на примере создания нового документа в ERP и отправки его в ДО.

  1. Пользователь создает в ERP документ «Реализация товаров и услуг». Система отправляет данные в ДО3.
  2. Документооборот получает запрос web-сервиса, создает новый элемент в справочнике «Документы предприятия» и сразу делает запись в своем регистре связей.

    Связь на стороне ДО

    Связь на стороне ДО
  3. ERP получает подтверждение от ДО вместе с GUID созданного объекта и записывает связь уже в свой регистр: «Объект ERP связан с документом ДО, у которого GUID = такой-то, тип = DMDocument».

    Связь на стороне ERP

    Связь на стороне ERP
  4. Теперь системы синхронизированы. При следующем открытии документа в ERP найдет в своем регистре GUID и откроет нужный документ в ДО.

    Общая схема связей выглядит так:

    Связь объектов ERP — ДО

    Связь объектов ERP — ДО

Примечание: помимо прочего, чтобы объект участвовал в такой связи, необходимо настроить специальные правила интеграции, в которых будет указана связь реквизитов объектов и другие настройки. Иначе система не сможет определить, каким образом создавать документ в ДО. В ДО2 и ДО3 эти правила настраиваются по-разному. Здесь подробно не будем на этом останавливаться. Пример, как они выглядят в ERP с интеграцией ДО2:

Правила интеграции ERP с ДО2 (для ДО3 настройка отличается)

Правила интеграции ERP с ДО2 (для ДО3 настройка отличается)

Что случилось с типами?

Итак, с новыми знаниями заходим в ERP в регистр сведений «Объекты, интегрированные с 1С:Документооборотом» и видим, что здесь указан тип «DMInternalDocument».

Регистр сведений хранения связанных данных объектов ДО

Регистр сведений хранения связанных данных объектов ДО

Как мы уже писали, данный тип является отражением типа метаданных базы ДО, такой тип должен присутствовать в XDTO-пакете DM, и именно в нём находятся основные типы участвующие в обмене.

Проверим сторону ДО — для этого запустим конфигуратор базы ДО3 и пройдем в XDTO-пакет «DM»:

Путь к пакету XDTO «DM»

Путь к пакету XDTO «DM»

Ищем тип DMInternalDocument и как видим такого в ДО3 уже не существует:

Поиск типа DMInternalDocument в пакете DM версии ДО3

Поиск типа DMInternalDocument в пакете DM версии ДО3

Допустим, тип DMInternalDocument устарел, попробуем узнать актуальный тип. Для этого создаем тестовую реализацию в ERP и создаем связанный объект в ДО3. И далее смотрим какой тип записался в регистр. Оказалось, это «DMDocument».

Регистр сведений «Объекты, интегрированные с 1С:Документооборотом»

Регистр сведений «Объекты, интегрированные с 1С:Документооборотом»

Изменение типизации XDTO

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

В ДО2 объекты интегрированных систем были связаны с элементами трёх разных справочников и для каждого из них зарезервирован свой тип XDTO:

  • Справочник.ВнутренниеДокументы — тип DMInternalDocument;
  • Справочник.ВходящиеДокументы — тип DMIncomingDocument;
  • Справочник.ИсходящиеДокументы — тип DMOutgoingDocument.

В ДО3 всё устроено проще: теперь используется единый справочник «Документы предприятия» и соответственно один тип XDTO:

  • Справочник.ДокументыПредприятия — тип DMDocument.

Что важно: во время миграции все элементы справочников ВнутренниеДокументы, ВходящиеДокументы, ИсходящиеДокументы автоматически «перетекли» в новый справочник ДокументыПредприятия:

Автоматическая миграция данных: Внутренние/Входящие/Исходящие документы → ДокументыПредприятия

Подробнее об этих изменениях можно почитать по ссылкам:

  • 1С:Документооборот КОРП. Редакция 2.1 — Глава 4.1. Типы документов:
    its.1c.ru/db/doccorp21#content:769:hdoc
  • 1С:Документооборот. Редакция 3.0 — Глава 6.1. Единый справочник документов:
    its.1c.ru/db/doc30#content:53:hdoc
  • 1С:Документооборот Новое в версии 3.0.10, раздел Миграция данных с предыдущих версий, Глава 5.5. Миграция документов:
    its.1c.ru/db/updinfo#content:1427:hdoc:issogl2_18

Решение

Раз все прежние элементы теперь находятся в справочнике ДокументыПредприятия, логика подсказала, что для исправления ошибки может быть достаточно переименовать прежние типы "DMInternalDocument"/"DMIncomingDocument"/"DMOutgoingDocument" в регистре на новый тип «DMDocument». Проверим эту гипотезу.

Возьмем проблемный документ «Реализация товаров и услуг ТД00-002349 от 17.02.2026». Найдем по нему в регистре «Объекты, интегрированные с 1С:Документооборотом» соответствующую запись и изменим поле «Тип объекта ДО» с «DMInternalDocument» на «DMDocument»:

Интегрированный объект после переименования

Интегрированный объект после переименования

Повторно открываем данные документооборота из карточки документа в ERP — и, вуаля, ошибка исчезла, данные открываются корректно!

Данные документооборота из карточки документа ERP

Данные документооборота из карточки документа ERP

Эксперимент подтвердил: достаточно скорректировать всего одно поле в регистре «Объекты, интегрированные с 1С:Документооборотом», чтобы доступ к данным восстановился.

Только вот прикрепленные файлы при этом всё равно не появляются.

И, несмотря на кажущуюся простоту исправления, мы не станем торопиться с разработкой обработчика для пакетной замены типов. Логичнее сначала разобраться со второй проблемой — «пропажей» режима хранения «Файлы в отдельных папках» и отображением файлов в ERP. Возможно, эти две трудности связаны и исправлять их лучше в рамках единого комплексного подхода.

«Пропавшие» файлы

Теперь разберем вторую проблему: в базе ERP при подключении к ДО3 стал недоступен вариант хранения «Файлы в отдельных папках». И переключение в режим «Файлы прикреплены к документам» не помогает — ранее прикрепленные файлы не отображаются.

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

В базе ERP интегрированной с ДО2 были следующие варианты:

  • «1C:Документооборот не используется».
  • «Файлы прикреплены к документам».
  • «Файлы в отдельных папках».

Настройки интеграции с 1С:Документооборот

Настройки интеграции с 1С:Документооборот

Если кратко, можно описать их так:

  • Настройка «Файлы прикреплены к документам» означает, что карточка файла в базе данных ДО привязана к «клону» объекта ERP на стороне ДО, например, к элементу справочника «Внутренний документ».
  • Настройка «Файлы в отдельных папках» — что владельцем карточки является элемент справочника «Папки файлов», и в этом случае в связи объектов нет необходимости.

Предлагаем изучить их по отдельности и понять в чем отличия на уровне объектов.

Режим «1С:Документооборот не используется» само собой мы не рассматриваем :)

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

Том хранения файлов в 1С:Документооборот — это настройка (элемент справочника), которая указывает системе физическую папку на диске или в сети для хранения файлов. Она позволяет хранить файлы не внутри базы данных, а отдельно — на диске.

Подробнее о настройках томов можно ознакомиться по ссылке на ИТС:

  • ДО2 — its.1c.ru/db/doccorp21#content:789:hdoc:issogl2_хранить_файлы_в_томах_на_диске
  • ДО3 — its.1c.ru/db/doc30ruseng/content/81/hdoc

Пример настройки хранения файлов в Томе

Пример настройки хранения файлов в Томе

Различия настроек хранения присоединённых файлов

Настройка «Файлы прикреплены к документам»

Этот способ подразумевает, что файл будет прикрепляться только к объектам ERP, которые участвуют в интеграции. То есть тем, о которых мы рассказали выше в разделе статьи «Как связаны объекты ERP и ДО (архитектура интеграции)», для которых настроены правила интеграции.

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

Рассмотрим процесс на примере документа «Реализация товаров и услуг» — для него правила интеграции в нашей тестовой демо базе уже заданы. Проследим цепочку действий шаг за шагом, чтобы в дальнейшем увидеть разницу с проблемным случаем:

  • Создадим новый документ «Реализации товаров и услуг» на стороне ERP, в карточке документа переходим по гиперссылке «Файлы ДО», расположенной в командной панели:

    Карточка документа ER

    Карточка документа ERP
  • Загружаем тестовый файл с диска:

    Список файлов документа на стороне ERP

    Список файлов документа на стороне ERP
  • В верхней панели карточки документа выбираем гиперссылку «Документооборот» и обнаруживаем, что в карточке уже есть ссылка на связанный объект, хотя мы его не создавали. Это подтверждает то, что механизм интеграции создал его в момент добавления файла:

    Карточка документа на стороне ERP

    Карточка документа на стороне ERP
  • Переключаемся в ДО2 и находим созданный по нашему документу ERP связанный элемент справочника «Внутренний документ» с прикрепленным к нему файлом:

    Карточка документа на стороне ДО2

    Карточка документа на стороне ДО2
  • Откроем карточку этого файла в ДО2. Для этого выберем файл из списка в правой части окна и дважды щелкнем левой кнопкой мыши. В открывшейся карточке файла видно, что владельцем указан целевой внутренний документ:

    Карточка файла

    Карточка файла
  • В том, что внутренний документ стал владельцем файла, можно убедиться открыв элемент файла через редактор реквизитов:

    Ссылка на файл открытый в редакторе реквизитов

    Ссылка на файл открытый в редакторе реквизитов

Что важно запомнить: в этом режиме файл всегда принадлежит конкретному объекту ДО созданному из ERP. Это обеспечивает прямую связь «объект ERP -> объект ДО -> файл». Однако такая логика требует обязательной настройки правил интеграции для каждого типа объектов ERP, где планируется хранение файлов.

Настройка «Файлы в отдельных папках»

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

Меню настройки объектов, интегрируемых с 1С:Документооборотом

Меню настройки объектов, интегрируемых с 1С:Документооборотом

Объекты интегрируемые с 1С:Документооборотом

Объекты интегрируемые с 1С:Документооборотом

Разберем его ключевые особенности:

  1. В настройках интеграции требуется указать корневую папку в ДО, где будут храниться файлы:

    Настройка корневой папки хранения файлов

    Настройка корневой папки хранения файлов
  2. В интерфейсе документа ERP исчезает гиперссылка «Файлы ДО»:

    Отличия в командной панели карточки документа

    Отличия в командной панели карточки документа
  3. В разделе «Документооборот» карточки документа ERP появляется вкладка «Файлы»:

    Сравнение карточек данных Документооборота на стороне ERP в разных вариантах хранения файлов

    Сравнение карточек данных Документооборота на стороне ERPв разных вариантах хранения файлов
  4. Перейдем к файлам на стороне ДО2, в меню выбираем «Документы и файлы» → «Файлы»:

    Путь к «Файлам» в интерфейсе ДО2

    Путь к «Файлам» в интерфейсе ДО2

    В указанной в настройках корневой папке автоматически формируется иерархия вложенных папок по следующему принципу:

    • Корневая папка.
    • «Каталог типа» — папка, в наименовании которой указывается полное имя объекта метаданных ERP, например, «Документ.РеализацияТоваровУслуг».
    • «Каталог объекта» — папка, с наименованием в виде представления объекта, и в скобках GUID объекта.

    Хранение файлов на стороне ДО2 при варианте настройки: «Файлы в отдельных папках»

    Хранение файлов на стороне ДО2 при варианте настройки: «Файлы в отдельных папках»

    Через редактор реквизитов можем убедиться, что владельцем устанавливается папка объекта:

    Владелец файла объект — Папка файлов

    Владелец файла объект — Папка файлов
  5. Дополнительно можем убедиться в том, что данный механизм позволяет прикреплять файлы к объектам ERP, для которых в системе не настроены правила бесшовной интеграции. Можем увидеть, например, что в системе есть папки для таких типов объектов, как «Приобретение товаров и услуг», «Приобретение услуг и прочих активов» и «Счет-фактура полученный»:

    Типы объектов ERP на которые не настроены правила бесшовной интеграции

    Типы объектов ERP на которые не настроены правила бесшовной интеграции

    Для данных объектов в нашей базе отсутствовали правила интеграции, тем не менее, благодаря режиму «Файлы в отдельных папках», файлы к ним успешно прикреплялись:

    Настроенные правила бесшовной интеграции объектов ERP

    Настроенные правила бесшовной интеграции объектов ERP
Что важно запомнить: в этом режиме файлы хранятся в папках, а не привязываются к документам ДО. Это дает гибкость: можно прикреплять файлы к объектам ERP даже без настроенных правил интеграции.

Решение

Изыскания в документации и погружение в тему убедили, что глаза нас не обманули и, действительно, режим «Файлы в отдельных папках» при переходе на интеграцию с ДО3, перестал поддерживаться.

Почитать можно в разделе «Библиотека интеграции с 1С:Документооборотом 3.0.2» на ИТС (its.1c.ru/db/bid302doc#content:16:hdoc).

Хранение присоединенных файлов

При этом, какого-то штатного метода переноса файлов между режимами «Файлы в отдельных папках» и «Файлы прикреплены к документам» мы, увы, не нашли. Однако, необходимость «вернуть» пользователям их файлы никто не отменял. Да и отсутствие чего-то в программе нас редко когда останавливало. Так что в итоге мы пришли к идее разработки собственного механизма по переносу из прежнего режима в новый.

Шаг 1. Анализируем текущую ситуацию

Перед тем как что-то исправлять, нужно было чётко понять, в каком состоянии находятся данные после миграции. Мы проверили в ДО3 несколько документов, по которым в ДО2 использовался режим «Файлы в отдельных папках», и зафиксировали следующую картину:

Что проверяем Что обнаружили
Где хранятся файлы после миграции Все файлы на месте, лежат в ДО3 в тех же папках, что и раньше
Кто указан владельцем файла Владельцем по-прежнему числится папка — ровно так, как работал режим «Файлы в отдельных папках» в ДО2
Есть ли в ДО3 объект, связанный с объектом ERP В некоторых случаях объект существовал, в некоторых — нет. Напомним, что в режиме «Файлы в отдельных папках» документ в ДО мог вообще не создаваться
Настроены ли правила интеграции для данного типа объектов Для части объектов правила были, для части — отсутствовали. Как мы видели ранее, режим «Файлы в отдельных папках» позволял прикреплять файлы даже без настроенных правил

Шаг 2. Алгоритм действий

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

Алгоритм состоит из четырёх шагов, выполняемых последовательно:

  1. Создание правил интеграции.
    1. Для создания связанных объектов, для всех типов объектов ERP, по которым есть файлы, должны существовать правила загрузки данных в ДО3. Там, где правил нет, их нужно создать.
    2. Также в рамках этого пункта потребуется создать в ДО3 элемент в справочнике «Виды документов» соответствующий типу документа в ERP, если его нет.
  2. Создание связанных объектов.
    1. Если для объекта ERP в ДО3 не существует связанного объекта, его необходимо создать.
  3. Смена владельца файлов.
    1. В ДО3 владельцем файла должен быть элемент справочника «Документы предприятия», а не папка. Для каждого файла, привязанного к папке, нужно найти соответствующий элемент и переназначить владельца.
  4. Формирование связей между системами.
    1. После того как файлы будут перепривязаны к новым владельцам, ERP должна «узнать» об этих новых связях. Для этого требуется создать соответствующие записи в регистрах интеграции — как на стороне ДО3, так и в ERP.
    2. В этот же пункт включим исправление ситуации с ошибкой с XDTO-типами, разобранную ранее.

Примечание:

При создании правил интеграции необходимо учесть, что при переходе с 1С:Документооборот 2.1 на версию 3.0 изменился подход к настройке бесшовной интеграции с учетными системами.

В версии 2.1 все правила обмена (загрузка, отправка, соответствие документов) настраивались исключительно на стороне ERP. В версии 3.0 настройки разделились по принципу применения: правила загрузки данных в ДО создаются в 1С:Документообороте, а правила получения изменений от ДО настраиваются на стороне ERP.

Ниже представлено сравнение места настройки правил в каждой из версий.

Вид правил 1С:Документооборот 2.1 1С:Документооборот 3.0
Правила загрузки данных в ДО Настраиваются в ERP Настраиваются в ДО (раздел «Настройка» → «Настройки интеграции» → «Правила загрузки данных»)
Правила получения в ERP Настраиваются в ERP Настраиваются в ERP (раздел «НСИ и Администрирование» → «Интеграция с 1С:Документооборотом» → «Правила интеграции»

Шаг 3. Проверяем алгоритм на практике

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

Разберем три случая:

  1. Объект в ДО3 создан, правила интеграции есть.
  2. Объект в ДО3 не создан, правила интеграции есть.
  3. Объект в ДО3 не создан, правил интеграции нет.

Случай № 1. Объект на стороне ДО3 создан, правила интеграции существуют

Начнем с наиболее простого сценария. Для документа ERP «Реализация товаров и услуг ТД00-002345 от 13.02.2026», к которому был прикреплен файл, в ДО3 уже существует связанный документ.

Исходная ситуация:

Пример случая документа ERP с существующим связанным документом ДО3

Пример случая документа ERP с существующим связанным документом ДО3
  • На стороне ERP файл не отображается:

    Отсутствие ранее прикрепленного файла у документа ТД00-002345

    Отсутствие ранее прикрепленного файла у документа ТД00-002345
  • На стороне ДО3 файл присутствует, но его владельцем является папка, а не документ:

    Папка с «потерянным» файлом на стороне ДО3

    Папка с «потерянным» файлом на стороне ДО3

Процесс исправления:

  1. Смена владельца файла в ДО3. Открываем карточку файла через редактор реквизитов и в поле «ВладелецФайла» заменяем ссылку на папку ссылкой на целевой документ ДО3:

    Смена владельца файла в ДО3

    После этой операции файл появляется в карточке документа ДО3:

    Файл в карточке целевого документа

    Файл в карточке целевого документа
  2. Корректировка типа объекта в регистре связей ERP. В регистре сведений «Объекты, интегрированные с 1С:Документооборотом» находим запись, соответствующую нашему документу, и исправляем значение поля «Тип объекта ДО» с «DMInternalDocument» на «DMDocument»:

    Скорректированная запись связи документов ERP — ДО

    Скорректированная запись связи документов ERP — ДО
  3. Проверка результата. Открываем документ в ERP. Данные документооборота открываются без ошибок, а список файлов снова содержит наш файл:

    Данные ДО в карточке документа ERP

    Данные ДО в карточке документа ERP

    Восстановленное отображение файла для Реализации

    Восстановленное отображение файла для Реализации

Случай № 2. Объект на стороне ДО3 не создан, правила интеграции существуют

Рассмотрим на примере документа «Реализация товаров и услуг ТД00-000047 от 12.02.2026». В базе ДО файл добавлен:

Папка с файлом документа ERP

Папка с файлом документа ERP

Но связанного объекта не существует:

Связанный объект  ERP-ДО не создан

Связанный объект ERP-ДО не создан

В базе ERP также видно, что связанный объект ДО отсутствует:

Отсутствие связанного объекта ДО

Отсутствие связанного объекта ДО

Процесс исправления:

  1. Создание связанного объекта. С помощью механизма интеграции со стороны ERP создаем объект в ДО3.

    Для этого в карточке документа переходим по гиперссылке «Документооборот»:

    Переход к данным Документооборота

    Переход к данным Документооборота

    В открывшемся окне выбираем команду «Создать»:

    Команда «Создать» документ на стороне ДО

    Команда «Создать» документ на стороне ДО

    Объект ДО успешно создан:

    Созданный объект ДО

    Созданный объект ДО

    В регистре «Объекты, интегрированные с 1С:Документооборотом» автоматически появилась запись связи документа ERP c объектом ДО:

    Связь документа ERP c ДО

    Связь документа ERP c ДО
  2. Смена владельца файла в ДО3. С помощью редактора реквизитов аналогично Случаю № 1 заменяем владельца на созданный объект.
  3. Проверка результата. Список файлов снова содержит наш файл:

    Список файлов документа ERP

    Список файлов документа ERP

Случай № 3. Объект на стороне ДО3 не создан, правила интеграции не существуют

Этот сценарий является наиболее сложным из всех рассматриваемых, поскольку требует восстановления интеграционных связей «с нуля». Возьмём для примера документ «Счет-фактура полученный № 79 от 01.12.2022», в котором ранее был прикреплен файл, но в ДО3 отсутствует как связанный объект, так и настроенные правила интеграции для данного типа объектов:

Пример файла документа ERP Счет фактура полученный

Пример файла документа ERP Счет фактура полученный

Исходная ситуация:

  • Файл физически перенесен в ДО3 и находится в папке.
  • Связанный объект в ДО3 отсутствует.
  • Правила бесшовной интеграции для документов «Счет-фактура полученный» не настроены:

Правило интеграции для СЧФ не настроено

Правило интеграции для СЧФ не настроено

Процесс исправления:

  1. Создание нового вида документа. В ДО3 проверяем наличие вида документа «Счет-фактура полученный». Переходим в подсистему «НСИ» → пункт «Виды документов»:

    Переход к списку Видов документов

    Переход к списку Видов документов

    Так как искомого вида нет, создаем его:

    Список Видов документов

    Список Видов документов

    Заполняем, записываем новый вид документа «Счет-фактура полученный»:

    Карточка нового вида документа «Счет-фактура полученный»

    Карточка нового вида документа «Счет-фактура полученный»
  2. Создание правила интеграции. В меню ДО3 выбираем «Настройки» → «Настройки интеграции»:

    Переход к настройкам интеграции в ДО3

    Переход к настройкам интеграции в ДО3

    В открывшемся окне нажимаем на гиперссылку «Правила загрузки данных в 1С:Документооборот»:

    Пункт настройки правил загрузки в ДО

    Пункт настройки правил загрузки в ДО

    В форме списка правил нажимаем кнопку «Создать» и заполняем «Вид документа» и необходимые параметры правила для объекта «Счет-фактура полученный», указывая соответствия реквизитов и настройки загрузки:

    Создание правил интеграции

    Создание правил интеграции

    Созданное правило интеграции для СЧФ полученный

    Созданное правило интеграции для СЧФ полученный

    Мы не будем подробно описывать настройку правил интеграции, об этом можно почитать по ссылке на ИТС (its.1c.ru/db/bid303doc#content:17:hdoc).

  3. Создание связанного документа. После создания правила интеграции в ERP становится доступной команда формирования связанного документа. Действуем аналогично Случаю № 2. В карточке документа ERP переходим по гиперссылке «Документооборот» и выбираем команду «Создать». Система автоматически:
    • Формирует связанный объект в ДО3 на основе созданного правила.
    • Создает запись в регистре «Объекты, интегрированные с 1С:Документооборотом» с корректным типом «DMDocument» (в отличие от Случая № 1, где тип приходилось исправлять вручную):

      Созданный связанный объект ДО

      Созданный связанный объект ДО
  4. Смена владельца файла в ДО3. Выполняется аналогично предыдущим случаям — через редактор реквизитов открываем карточку файла и в поле «ВладелецФайла» заменяем ссылку на папку ссылкой на созданный документ ДО3.
  5. Проверка результата. Возвращаемся в карточку документа ERP. Список файлов снова содержит ранее прикрепленный файл, данные документооборота открываются без ошибок:

    Восстановленное отображение файла СЧФ

    Восстановленное отображение файла СЧФ

Реализация обработчиков пакетной обработки: план автоматизации

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

Однако за кадром остаются реальные масштабы продуктивного контура клиента:

  • 700 тысяч внутренних документов ДО требуют замены типа объекта обмена в регистре связей на стороне ERP и переназначения владельцев файлов на стороне ДО3.
  • 800 тысяч документов ERP нуждаются в создании документов-владельцев и привязке файлов.

Итого: порядка 1,5 миллионов объектов разной степени сложности. С таким количеством о ручном исправлении не могло быть и речи. Поэтому понимая логику восстановления и имея подтвержденный алгоритм, мы решили переложить его на код и обработать миллионы записей автоматически.

Как мы уже писали, на стороне ERP хранится информация об интегрированных объектах, но не о добавленных файлах. Поэтому большая часть исправлений предполагается на стороне ДО3, и уже затем следует синхронизация связей объектов с ERP.

План действий разбили на четыре этапа:

Схема восстановления отображения файлов

Схема восстановления отображения файлов

Этап 1. Подготовительный: анализ и создание правил интеграции.

  • Создание правил интеграции. На этом этапе выявляем типы объектов ERP, по которым в ДО3 есть файлы, и создаем правила интеграции для тех, у кого их нет. Это обязательная предпосылка для последующего создания документов-владельцев.

Этап 2. Основной: обработка данных в ДО3.

  • Выборка файлов к обработке. Выбираем файлы, у которых владельцем является объект папка.
  • Автоматическое создание связанных объектов. Для найденных папок на основе созданных правил формируем объекты в ДО3, сразу создавая записи в регистре «Связи объектов интегрированных систем» и помечая их для выгрузки в ERP.
  • Замена владельцев файлов. Обработка проходит по всем мигрировавшим файлам: если владелец — папка, ищем соответствующий объект в ДО3 (по ГУИД в представлении) и переназначаем владельца.

Этап 3. Выгрузка данных для ERP.

  • Обработка формирует файл обмена со связями созданных объектов ДО и объектов ERP.

Этап 4. Загрузка в ERP.

  • Обработка читает файл, создает записи в регистре «Объекты, интегрированные с 1С:Документооборотом».
  • А также заменяет устаревший тип «DMInternalDocument» на «DMDocument» во всех записях.

От разовой обработки к работающей системе

Здесь следует понимать, что хоть в плане мы и оперируем понятиями «выборка», «выгрузка», «замена» — на самом деле мы подразумеваем, что для решения задачи такого масштаба (1,5 млн объектов) простой разовой обработки было бы недостаточно.

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

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

Идентификация объекта ERP со стороны ДО

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

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

Идентификация по структуре папок

Идентификация по структуре папок

Эту закономерность мы и будем использовать для определения типа и ссылки объекта ERP, то есть получим их из иерархии папок файлов. Такой подход позволяет явно привязать файл к внешнему объекту и идентифицировать саму систему через общую корневую папку.

Структура папок файлов внешних интегрированных объектов

Структура папок файлов внешних интегрированных объектов

Техническая реализация: от плана к коду

Приступим к реализации. Четыре описанных этапа должны превратиться в работающий программный код, который без участия человека обработает 1,5 млн объектов. Давайте разберем техническую начинку каждого блока.

I. Подготовительный этап: создание правил интеграции

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

Алгоритм работы обработки

  1. Выбираем узел ERP, с которым настраивается интеграция.
  2. Указываем общую корневую папку хранения файлов (заданную в настройках ERP).
  3. Запускаем анализ и генерацию правил.

Папки файлов типов объектов ERP

Папки файлов типов объектов ERP

Обработка выполняет запрос, который находит все папки, которые входят в настроенный корневой каталог (соответствующие типам объектов ERP) и сопоставляет их с существующими правилами интеграции. Для папок, по которым правила отсутствуют, автоматически создаются новые правила с предзаполненными реквизитами.

Внешний вид обработки автоматического создания правил интеграции

Внешний вид обработки автоматического создания правил интеграции

Результат работы обработки

В табличной части отображаются созданные правила интеграции. Например, на картинке отсутствует «Счет-фактура полученный» — мы создавали его вручную при разборе Случая № 3, и обработка его не дублирует. В реальном проекте таким образом было автоматически сгенерировано 62 правила интеграции, что заняло бы длительное время при ручном создании, в итоге правила сформировались в течении 5 минут.

Ключевые моменты программного создания правил

  • Для каждого типа объекта автоматически определяется или создается соответствующий вид документа в ДО3.
  • Создается папка документов данного вида (если отсутствует).
  • Формируется правило заполнения реквизитов с настройками по умолчанию.
  • Создается связанное правило интеграции в информационной системе (ERP) через механизм обмена.

Обработка работает в транзакционном режиме: при возникновении ошибки на любом этапе транзакция откатывается, информация об ошибке логируется в журнал регистрации, а проблемный объект пропускается для последующего ручного разбора.

Ключевой метод автоматического создания правил:

// Переопределяет размер порций в запрос
// Определяет объекты у которых отсутствует правило интеграции, автоматически создает их
//
&НаСервере
Процедура СгенерироватьПравилаНаСервере()

Если Не ЗначениеЗаполнено(Узел) Тогда
Сообщить("Заполните узел");
Возврат;
КонецЕсли;

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

Запрос.УстановитьПараметр("Родитель", ПапкаОбщая);

РезультатЗапроса = Запрос.Выполнить();

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

ПравилаЗаполненияРеквизитовДО.ПолучитьЭлементы().Очистить();
Объект.ПравилаЗаполненияРеквизитовДО.Очистить();

НачатьТранзакцию();

Попытка

ТипДокумента = "Справочник.ДокументыПредприятия";
ВидДокументаСтрокой = СформироватьСиноним(СтрЗаменить(Выборка.Наименование, "Документ.", ""));
ВидДокумента = Справочники.ВидыДокументов.НайтиПоНаименованию(ВидДокументаСтрокой);
Папка = Справочники.ПапкиДокументов.НайтиПоНаименованию(ВидДокументаСтрокой);

Если ВидДокумента = Справочники.ВидыДокументов.ПустаяСсылка() Тогда
СтруктураЗаполнения = Новый Структура("Наименование, ФормаДокумента"
, ВидДокументаСтрокой, Перечисления.ВариантыФормДокументов.БумажнаяИлиЭлектронная);
ВидДокумента = Справочники.ВидыДокументов.СоздатьВидДокумента(СтруктураЗаполнения);
КонецЕсли;

Если Папка = Справочники.ПапкиДокументов.ПустаяСсылка() Тогда
СтруктураЗаполнения = Новый Структура("Наименование", ВидДокументаСтрокой);
Папка = Справочники.ПапкиДокументов.СоздатьПапку(СтруктураЗаполнения);
КонецЕсли;

Объект.ТипОбъектаДО = ТипДокумента;
Объект.ТипОбъектаИС = Выборка.Наименование;
Объект.ВидДокумента = ВидДокумента;

ЗаполнитьСтруктуруРеквизитовОбъектаДОПоПравилу();
ЗаполнитьПоУмолчаниюНаСервере(Ложь, Истина, Истина);

Для Каждого текДанные Из ПравилаЗаполненияРеквизитовДО.ПолучитьЭлементы() Цикл

Если текДанные.ИмяРеквизитаОбъектаДО = "ВидДокумента" Тогда
текДанные.ЗначениеРеквизитаДО = ВидДокумента;
текДанные.Вариант = Перечисления.ВариантыПравилЗаполненияРеквизитов.УказанноеЗначение;
КонецЕсли;

Если текДанные.ИмяРеквизитаОбъектаДО = "Папка" Тогда
текДанные.ЗначениеРеквизитаДО = Папка;
текДанные.Вариант = Перечисления.ВариантыПравилЗаполненияРеквизитов.УказанноеЗначение;
КонецЕсли;

Если текДанные.ИмяРеквизитаОбъектаДО = "ФормаДокумента" Тогда
текДанные.ЗначениеРеквизитаДО = Перечисления.ВариантыФормДокументов.БумажнаяИлиЭлектронная;
текДанные.Вариант = Перечисления.ВариантыПравилЗаполненияРеквизитов.УказанноеЗначение;
КонецЕсли;

КонецЦикла;

ПеренестиПравилаВОбъект(Объект, ПравилаЗаполненияРеквизитовДО);

НовоеПравило = Справочники.ПравилаЗагрузкиДанныхВДО.СоздатьЭлемент();
НовоеПравило.ВидДокумента = Объект.ВидДокумента;
НовоеПравило.ИзМакета = Ложь;
НовоеПравило.Комментарий = "Сгенерировано автоматически";
НовоеПравило.ПредставлениеОбъектаДО = "Документ, " + ВидДокументаСтрокой;
НовоеПравило.ПредставлениеОбъектаИС = ВидДокументаСтрокой;
НовоеПравило.ТипОбъектаДО = Объект.ТипОбъектаДО;
НовоеПравило.ТипОбъектаИС = Объект.ТипОбъектаИС;
НовоеПравило.ТипФайловСохраненияПечатныхФорм = Перечисления.ТипыФайловСохраненияПечатныхФормОбъектов.PDF_A_1;
НовоеПравило.УзелИнтегрированнойСистемы = Узел;
                                                   НовоеПравило.ПравилаЗаполненияРеквизитовДО.Загрузить(Объект.ПравилаЗаполненияРеквизитовДО.Выгрузить());

НовоеПравило.Записать();

Стр = СозданныеПравила.Добавить();
Стр.Правило = НовоеПравило.Ссылка;

СоздатьСвязанноеПравилоИнтеграцииВИС(
Узел,
НовоеПравило.Ссылка,
НовоеПравило.ВидДокумента,
НовоеПравило.ТипОбъектаДО,
НовоеПравило.ТипОбъектаИС,
НовоеПравило.ПредставлениеОбъектаДО,
НовоеПравило.Комментарий);

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();
ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());

Сообщить("Ошибка при создании правила для " + Выборка.Наименование + ". " + ТекстОшибки);
ЗаписьЖурналаРегистрации("ГенерацияПравилОбмена", УровеньЖурналаРегистрации.Ошибка, Выборка.Папка, Выборка.Папка, ТекстОшибки);

КонецПопытки;

КонецЦикла;

КонецПроцедуры

II. Основной этап: создание документов, замена владельцев

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

Логика алгоритма

  1. С некоторой периодичностью запускается регламентное задание, которое отбирает из справочника файлов порцию ссылок с папками, находящимися в иерархии корневой папки. И формирует несколько потоков обработки в виде фоновых заданий
  2. Фоновое задание для каждого файла из порции:
    1. Определяет тип и GUID внешнего объекта по наименованиям папок.
    2. Ищет связанный объект ДО по GUIDу объекта в регистре «Связи объектов интегрированных систем».
    3. В случае если связанного объекта нет — создает его и добавляет запись в регистр связей.
    4. Заменяет владельца файла с папки на связанный объект ДО.

Описание вспомогательных метаданных

Константы для идентификации контура интеграции:

  • Узел интегрированной системы: указывает на конкретный узел обмена, в нашем проекте это единственный узел ERP. Это необходимо для фильтрации данных и корректной адресации при обмене.
  • Общая папка хранения файлов: задает корневую папку в ДО3, которая в настройках интеграции ERP указана как точка монтирования для режима «Файлы в отдельных папках».

Константы

Константы
Важно! Реализованный механизм рассчитан на сценарий с одним узлом ERP и одной общей папкой (В нашем случае был только один узел интеграции). Если в системе используется несколько узлов, но при этом в настройках интеграции прописана одна и та же корневая папка, предложенный подход потребует доработки. Однако, если разным узлам соответствуют разные корневые папки, обработку можно выполнить последовательно, просто переключая константы.

Регистры сведений для хранения промежуточных данных:

  1. ОбработанныеПапки: регистр, фиксирующий факт обработки файла и замены его владельца.

    Измерения:

    • Папка: папка файла до замены.
    • Файл: целевой обрабатываемый файл.

    Ресурсы:

    • Замена: ссылка на документ предприятия — новый владелец.
    • Ошибка: признак ошибки.
    • ТекстОшибки: текст ошибки.
    • Дата: дата обработки.
    • Выгружено: признак выгрузки, для дальнейшей порционной выгрузки.

    Регистр хранения обработанных папок

    Регистр хранения обработанных папок
  2. СоответствиеВидовДокументовПапок: регистр для явного указания соответствий между объектами ERP и структурой ДО3. В нашем случае часть папок и видов документов в ДО3 уже существовала на момент миграции — они могли быть созданы ранее при тестовых интеграциях или в ходе другой деятельности пользователей.

    Регистр «СоответствиеВидовДокументовПапок» для явной привязки объектов ERP к структуре ДО3

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

    Этот регистр решает проблему однозначно — он позволяет в ручном или полуавтоматическом режиме указать, какой именно вид документа ДО3 и какую целевую папку следует использовать при создании нового документа-владельца для конкретного типа объектов ERP.

    Измерения:

    • Папка: папка файла до замены.

    Ресурсы:

    • ПапкаДокументов: папка документа.
    • ВидДокумента: вид документа.

    Регистр хранения соответствий видов документов и папок

    Регистр хранения соответствий видов документов и папок

Общий модуль и регламентное задание

  • Общий модуль ОбработкаЗамены: вся серверная логика по поиску «потерянных» файлов, созданию документов и переназначению владельцев вынесена в этот модуль.
  • Регламентное задание ЗаменаВладельцевФайлов: инициирует выполнение основной обработки в фоновом режиме.

Общие объекты

Общие объекты

Метод регламентного задания «ЗаменаВладельцевФайловНачать()»

Запускает многопоточную обработку по замене владельцев файлов. Разбивает общую коллекцию объектов на порции и для каждой порции создает отдельное фоновое задание:

// Запускает замену владельцев файла на документы
//
Процедура ЗаменаВладельцевФайловНачать() Экспорт

ПредставлениеЗадания = "Замена владельцев папок (Files)";
ПараметрыОтбора = Новый Структура("Наименование, Состояние", ПредставлениеЗадания, СостояниеФоновогоЗадания.Активно);

Если ФоновыеЗадания.ПолучитьФоновыеЗадания(ПараметрыОтбора).Количество() Тогда
Возврат;
КонецЕсли;

Коллекция = КоллекцияКОбработкеПолучить();
КоличествоПотоков = 30;

ДанныеКоличество = Коллекция.Количество();
Размер = ДанныеКоличество / КоличествоПотоков;
ПорцияРазмер = ?(Размер = Цел(Размер), Размер, Цел(Размер) + 1);

ПорцияЗадания = Новый Массив;
МетодаИмя = "files_ОбработкаЗамены.ФайлыВладельцыЗаменить";
Задания = Новый Массив;
Для Каждого СоставПараметров Из Коллекция Цикл
ПорцияЗадания.Добавить(СоставПараметров);

Если ПорцияЗадания.Количество() = ПорцияРазмер Тогда
ПараметрыМетода = Новый Массив;
ПараметрыМетода.Добавить(Новый Структура("Порция", ПорцияЗадания));

Задания.Добавить(ФоновоеЗапустить(МетодаИмя, ПараметрыМетода, , ПредставлениеЗадания));
ПорцияЗадания = Новый Массив;
КонецЕсли;
КонецЦикла; 

Если ПорцияЗадания.Количество() Тогда
ПараметрыМетода = Новый Массив;
ПараметрыМетода.Добавить(Новый Структура("Порция", ПорцияЗадания));
Задания.Добавить(ФоновоеЗапустить(МетодаИмя, ПараметрыМетода, , ПредставлениеЗадания));
КонецЕсли;

КонецПроцедуры // ЗаменаВладельцевФайловНачать

Метод регламентного задания «КоллекцияКОбработкеПолучить()»

Коллекцию объектов для обработки мы получаем непосредственно из папок хранения файлов так как именно эти объекты являются первоисточником к обработке:

// Возвращает коллекцию к обработке
//
// Возвращаемое значение:
// Массив
//
Функция КоллекцияКОбработкеПолучить() Экспорт

ПапкаХраненияФайлов = Константы.files_ПапкаХраненияФайлов.Получить();
Если Не ЗначениеЗаполнено(ПапкаХраненияФайлов) Тогда
ВызватьИсключение "Не заполнена константа ""Папка хранения файлов (Files)""...";
КонецЕсли;

Запрос = Новый Запрос(ТекстЗапросаВыборка()); 
Запрос.УстановитьПараметр("Родитель", ПапкаХраненияФайлов);

Выборка = Запрос.Выполнить().Выбрать();

Результат = Новый Массив;
Пока Выборка.Следующий() Цикл
Данные = Новый Структура("Файл, ГУИД, ВладелецФайла");
ЗаполнитьЗначенияСвойств(Данные, Выборка);
Результат.Добавить(Данные);
КонецЦикла;

Возврат Результат;

КонецФункции // КоллекцияКОбработкеПолучить

// Возвращает текст запроса данных к обработке
//
// Возвращаемое значение:
// Строка
//
Функция ТекстЗапросаВыборка()

Возврат "ВЫБРАТЬ ПЕРВЫЕ 5000
| Т.Ссылка КАК Файл,
| Т.ВладелецФайла КАК ВладелецФайла,
| ПРАВ(ВЫРАЗИТЬ(Т.ВладелецФайла КАК Справочник.ПапкиФайлов).Наименование, 38) КАК ГУИД
|ИЗ
| Справочник.Файлы КАК Т
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.files_ОбработанныеПапки КАК Обработанные
| ПО Т.Ссылка = Обработанные.Файл
| И (Обработанные.Ошибка)
|ГДЕ
| ТИПЗНАЧЕНИЯ(Т.ВладелецФайла) = ТИП(Справочник.ПапкиФайлов)
| И Обработанные.Файл ЕСТЬ NULL
| И Т.ВладелецФайла.Родитель.Родитель = &Родитель";

КонецФункции // ТекстЗапросаВыборка

Основной метод замены владельцев «ФайлыВладельцыЗаменить()»

Выполняет замену владельца для группы файлов с папки на документ ДО3. Для каждого файла из переданной порции данных выполняет:

  • Поиск связанного объекта ДО3 по GUID объекта ERP.
  • Создание нового объекта, если он не найден.
  • Установку найденного/созданного документа владельцем файла.
  • Запись результата обработки в регистр files_ОбработанныеПапки.

// Заменяет владельцы файлов на документы по полученному ГУИД
//
// Параметры:
// Источник - Массив - Источник
//
Процедура ФайлыВладельцыЗаменить(Источник) Экспорт

Узел = Константы.files_УзелИнтегрированнойСистемы.Получить();
Для  каждого Элемент Из Источник Цикл

ГуидПредварительно = Элемент.ГУИД;
ГУИД = СтрЗаменить(ГуидПредварительно, "(", "");
ГУИД = СтрЗаменить(ГУИД, ")", "");

ТекстОшибки = "";
ВладелецПапка = Элемент.ВладелецФайла;
ВладелецНовый = Неопределено;
НачатьТранзакцию();
Попытка
ФайлОбъект = Элемент.Файл.ПолучитьОбъект();

ВладелецНовый = СвязанныйДокументПолучить(ГУИД, Узел);
Если ВладелецНовый = Неопределено Тогда
ДокументСоздать(ВладелецПапка, ВладелецНовый, ФайлОбъект.Автор, ФайлОбъект.ДатаСоздания);
СвязиСоздать(ВладелецПапка, ВладелецНовый, ГУИД);
КонецЕсли;

ФайлОбъект.ВладелецФайла = ВладелецНовый;
ФайлОбъект.Записать();
ЗафиксироватьТранзакцию();
Исключение
ТекстОшибки = СтрШаблон("По файлу %1 и строке гуид %2 не удалось заменить владельца по причине: %3"
, Элемент.Файл
, ГУИД
, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ОтменитьТранзакцию();
КонецПопытки;

ПараметрыФиксации = Новый Структура("Папка, Файл, Замена, ТекстОшибки"
, ВладелецПапка
, Элемент.Файл
, ВладелецНовый
, ТекстОшибки);

РезультатЗафиксировать(ПараметрыФиксации);
КонецЦикла;

КонецПроцедуры // ФайлыВладельцыЗаменить

Метод идентификации связанного объекта ERP «СвязанныйДокументПолучить()»

Выполняет поиск связанного документа ДО3 по идентификатору внешнего объекта ERP и узлу указанному в константе:

// Выполняет поиск связанного документа ДО3 по идентификатору внешнего объекта ERP
// и узлу интегрированной системы. Используется для определения, существует ли уже
// в ДО3 документ, соответствующий конкретному объекту ERP в рамках заданного узла обмена.
//
// Параметры:
// Идентификатор - Строка - GUID объекта ERP, по которому выполняется поиск.
// Узел - ПланОбменаСсылка - Узел интегрированной системы
//
// Возвращаемое значение:
// СправочникСсылка.ДокументыПредприятия - ссылка на найденный документ ДО3,
// если связь существует.
// Неопределено - если связанный документ не найден.
//
Функция СвязанныйДокументПолучить(Идентификатор, Узел)

Результат = Неопределено;

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

РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();

Результат = Выборка.СсылкаНаОбъектДО;
КонецЕсли;

Возврат Результат;

КонецФункции // СвязанныйДокументПолучить()

Метод создания документа ДО «ДокументСоздать»

Если не обнаружили связанный документ с внешним объектом интегрированной системы создаем документ по данным папки-владельца файла:

  • Определяем вид и папку документа по родителю папки, используя настройки соответствия.
  • Заполняем реквизиты: наименование (из папки), автора, дату, форму (Электронная).
  • В регистре «Текущие состояния документов» устанавливаем статус «Проект». По данному регистру определяются настройки доступности документов а так же файлов для редактирования и просмотра. Настройка доступности по состоянию производится в справочнике «Настройки доступности по состоянию». Подробно о настройках доступности по состоянию можно ознакомиться на ИТС (its.1c.ru/db/doc30/content/262/hdoc).

// Создает карточку документа для привязки к файлу
//
// Параметры:
// ВладелецПапка - Справочник.ПапкиФайлов - Папка файла
// СсылкаНового - Справочник.ДокументПредприятия - Ссылка нового
// Автор - Справочник.Сотрудники/Пользователи - Ссылка нового
//
// Возвращаемое значение
// Справочник.ДокументыПредприятия
//
Процедура ДокументСоздать(ВладелецПапка, СсылкаНового, Автор, ДатаСоздания)

ДанныеВладельца = Новый Структура("Родитель, Наименование");
ЗаполнитьЗначенияСвойств(ДанныеВладельца, ВладелецПапка);

РодительВладельца = ДанныеВладельца.Родитель;
Настройки = НастройкиСозданияДокумента(РодительВладельца);
ТекстОшибки = "";
Если Настройки.ВидДокумента = Неопределено Тогда
ТекстОшибки = СтрШаблон("По родителю %1 папки %2 не удалось определить вид документа
|из регистра Соответствие видов документов папок (Files)..."
, РодительВладельца
, ДанныеВладельца.Наименование);         
КонецЕсли;

Если Настройки.ПапкаДокумента = Неопределено Тогда
Текст = СтрШаблон("По родителю %1 папки %2 не удалось определить папку документа
|из регистра Соответствие видов документов папок (Files)..."
, РодительВладельца
, ДанныеВладельца.Наименование);

ТекстОшибки = ТекстОшибки + Символы.ПС + Текст;
КонецЕсли;

Если ТекстОшибки <> "" Тогда
ВызватьИсключение ТекстОшибки;
КонецЕсли;

ДокументНовый = Справочники.ДокументыПредприятия.СоздатьЭлемент();
ДокументНовый.Наименование = ДанныеВладельца.Наименование;
ДокументНовый.ДатаСоздания = ДатаСоздания;
ДокументНовый.ВидДокумента = Настройки.ВидДокумента; 
ДокументНовый.Папка = Настройки.ПапкаДокумента;
ДокументНовый.Заголовок = ДанныеВладельца.Наименование;
ДокументНовый.Создал = Автор;
ДокументНовый.Комментарий = СозданоАвтоматическиТекст();
ДокументНовый.ФормаДокумента = Перечисления.ВариантыФормДокументов.Электронная;
//ДокументНовый.ОбменДанными.Загрузка = Истина;
ДокументНовый.Записать();

СсылкаНового = ДокументНовый.Ссылка;

СостояниеДокументаУстановить(ДокументНовый.Ссылка, Перечисления.СостоянияДокументов.Проект);

КонецПроцедуры // ДокументСоздать

// Устанавливает текущее состояние для указанного документа в регистре сведений
// ТекущиеСостоянияДокументов.
//
// Параметры:
// Элемент - ЛюбаяСсылка - Ссылка на документ или другой объект метаданных,
// для которого устанавливается состояние.
// Состояние - ПеречислениеСсылка.СостоянияДокументов - Устанавливаемое состояние
//
Процедура СостояниеДокументаУстановить(Элемент, Состояние) Экспорт

// Создаем набор записей регистра с отбором по документу и состоянию
НаборЗаписей = РегистрыСведений.ТекущиеСостоянияДокументов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Документ.Установить(Элемент);
НаборЗаписей.Отбор.Состояние.Установить(Состояние);

// Добавляем новую запись
Запись = НаборЗаписей.Добавить();
Запись.Документ = Элемент;
Запись.Состояние = Состояние;
Запись.ДатаУстановки = ТекущаяДатаСеанса();

// Выполняем запись с обработкой возможных ошибок
Попытка
НаборЗаписей.Записать();
Исключение
// В случае ошибки записываем информацию в журнал регистрации
ЗаписьЖурналаРегистрации(
"ТекущиеСтатусыДокументов.Ошибка",
УровеньЖурналаРегистрации.Ошибка,
, // Необязательные параметры пропускаем
Элемент,
СтрШаблон("Не удалось установить статус проект по причине %1",
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
КонецПопытки;

КонецПроцедуры

Метод «СвязиСоздать»

Создает связь документа ДО с интегрированным объектом ERP в регистре «Связи объектов интегрированных систем»:

// Создает связи интеграции по узлу
//
// Параметры:
// ВладелецПапка - Справочник.ПапкиФайлов - ВладелецПапка
// ВладелецНовый - Справочник.ДокументыПредприятия - ВладелецНовый
// ГУИД - Строка - ГУИД
//
Процедура СвязиСоздать(ВладелецПапка, ВладелецНовый, ГУИД)

ДанныеВладельца = Новый Структура("Родитель, Наименование");
ЗаполнитьЗначенияСвойств(ДанныеВладельца, ВладелецПапка);

УзелИнтегрированнойСистемы = Константы.files_УзелИнтегрированнойСистемы.Получить();
СсылкаНаОбъектДО = ВладелецНовый;
ИДВнешнегоОбъекта = ГУИД;
ТипВнешнегоОбъекта = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ДанныеВладельца.Родитель, "Наименование");

НаборЗаписей = РегистрыСведений.СвязиОбъектовИнтегрированныхСистем.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.УзелИнтегрированнойСистемы.Установить(УзелИнтегрированнойСистемы);
НаборЗаписей.Отбор.СсылкаНаОбъектДО.Установить(СсылкаНаОбъектДО);
НаборЗаписей.Отбор.ТипВнешнегоОбъекта.Установить(ТипВнешнегоОбъекта);
НаборЗаписей.Отбор.ИДВнешнегоОбъекта.Установить(ИДВнешнегоОбъекта);

Запись = НаборЗаписей.Добавить();
Запись.УзелИнтегрированнойСистемы = УзелИнтегрированнойСистемы;
Запись.СсылкаНаОбъектДО = СсылкаНаОбъектДО;
Запись.ТипВнешнегоОбъекта = ТипВнешнегоОбъекта;
Запись.ИДВнешнегоОбъекта = ИДВнешнегоОбъекта;

НаборЗаписей.Записать();

КонецПроцедуры // СвязиСоздать

Итоги основного этапа

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

  • Провел инвентаризацию «потерянных» файлов, идентифицировав их по структуре папок.
  • Нашел существующие документы-владельцы для части файлов.
  • Создал недостающие документы в ДО3 для тех объектов ERP, у которых их не было.
  • Переназначил владельцев для всех файлов, переподчинив их от папок к документам ДО3.
  • Зафиксировал результаты каждой операции в специализированных регистрах, обеспечив прозрачность и возможность проконтролировать процесс.

Все операции выполнялись в многопоточном режиме, что позволило обработать полуторамиллионный массив данных за приемлемое время. Благодаря 30 параллельным потокам и порционной обработке, замена владельцев и создание документов для 1,5 млн объектов заняли около часа, что считаем отличным результатом для такого объема данных.

Многопоточная обработка замены владельцев файлов

Многопоточная обработка замены владельцев файлов

III. Выгрузка данных для ERP

Когда основная обработка данных в ДО3 завершена — объекты-владельцы созданы, файлы переназначены, а связи зарегистрированы — перед нами встала задача передать эту информацию в ERP. Без этого шага все выполненные операции останутся «известными» только документообороту, а в карточках документов ERP файлы по-прежнему отображаться не будут.

Для решения этой задачи мы реализовали механизм, который выгружает данные о новых связях в формате, понятном для ERP.

Основная сложность заключалась в объемах. Выгружать сразу миллион записей — значит получить гигантский файл, с которым ERP не сможет работать. Поэтому мы применили порционный подход. Порционная выгрузка выполняет не только функцию оптимизации, но и служит индикатором успешности переноса. Механизм работы построен по принципу «транзакционного файла»: порция удаляется только после полной и успешной загрузки в ERP. Следовательно, наличие файла в каталоге однозначно говорит о том, что данные этой порции еще не загружены. Это простое и надежное решение, перешедшее к нам из опыта миграции с ДО2, позволяет гарантировать сохранность данных на всех этапах.

Логика выгрузки

В обработке был реализован метод «ВыгрузитьНаСервере()». Его задача — выбирать из регистра «files_ОбработанныеПапки» записи, по которым уже выполнена замена владельца, но которые еще не были выгружены, и сохранять их в файл для передачи в ERP.

Интерфейс внешней обработки выгрузки данных

Интерфейс внешней обработки выгрузки данных

Алгоритм выгрузки данных обработанных папок

Алгоритм выгрузки данных обработанных папок

Алгоритм работы

  1. Запрос порции данных. Метод выполняет запрос к регистру «files_ОбработанныеПапки», отбирая записи, не попавшие во временную таблицу. Размер порции настраивается (По умолчанию это 50 000 записей).
  2. Формирование табличного документа. С полями:

    1. ИДВнешнегоОбъекта — GUID объекта ERP, извлеченный ранее из наименования папки.
    2. ТипОбъектаИС — тип объекта ERP, например «Документ.РеализацияТоваровУслуг».
    3. ИДДО — GUID объекта ДО.

    Пример файла выгрузки для ERP

    Пример файла выгрузки для ERP
  3. Сохранение файла.

    1. Каждая сформированная порция сохраняется в отдельный файл формата ODS. Особых причин по выбору именно этого формата нет, просто у нас под рукой были наработки готового алгоритма для него, поэтому их и использовали.
    2. Имя файла генерируется с порядковым номером, чтобы при передаче не возникало путаницы — ДанныеСинхронизацииДО_1.ods, ДанныеСинхронизацииДО_2.ods и так далее.

    Пример файла выгрузки для ERP

    Пример выгрузки файлов для ERP
  4. Фиксация выгрузки. После успешного сохранения файла метод вызывает процедуру «ВыгруженоУстановить()», которая проставляет признак выгрузки для обработанных записей в регистре «files_ОбработанныеПапки». Это гарантирует, что в следующих порциях эти записи не попадут в выборку повторно.
  5. Повторение цикла. Метод продолжает работу, пока в регистре остаются невыгруженные записи. Как только очередной запрос возвращает пустой результат, выгрузка завершается.

Код порционной выгрузки данных в файл

// // Выгружает данные из базы источника в соответствии с макетом и текстом запроса.
// Реализован механизм пакетной обработки: данные выгружаются порциями,
// количество записей в порции задается в реквизите "Порция" (через замену в тексте запроса).
// Каждая порция сохраняется в отдельный файл ODS.
// В процессе работы ведется учет выгруженных объектов для исключения дублирования
// в последующих порциях.
//
&НаСервере
Процедура ВыгрузитьНаСервере()

Выгружать = Истина;
ТаблицаОбработанных = Новый ТаблицаЗначений;

Тип36 = Новый КвалификаторыСтроки(36);
Тип1024 = Новый КвалификаторыСтроки(1024);
ТаблицаОбработанных.Колонки.Добавить("ИДВнешнегоОбъекта", Новый ОписаниеТипов("Строка", Тип36));
ТаблицаОбработанных.Колонки.Добавить("ТипОбъектаИС", Новый ОписаниеТипов("Строка", Тип1024));
СчетчикФайл = 0;

ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОбработкаОбъект.ПолучитьМакет("Макет");

ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка"); 
ТекстЗапроса = ТекстЗапроса();
Если Объект.Порция <> "" Тогда
ТекстПоиска = "50000 //Замена";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ТекстПоиска, Объект.Порция);
КонецЕсли;
Пока Выгружать Цикл
СчетчикФайл = СчетчикФайл + 1;
Запрос = Новый Запрос(ТекстЗапроса);

Запрос.УстановитьПараметр("Обработанные", ТаблицаОбработанных);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Выгружать = Ложь;
Прервать;
КонецЕсли;
ТабЛицаРезультат = РезультатЗапроса.Выбрать();
ТабДок = Новый ТабличныйДокумент;

ТабДок.Вывести(ОбластьЗаголовок);

ОтметитьВыгрузку = Новый Массив;
Пока ТабЛицаРезультат.Следующий() Цикл

ОбластьСтрока.Параметры.ИДВнешнегоОбъекта = ТабЛицаРезультат.ИДВнешнегоОбъекта;
ОбластьСтрока.Параметры.ИДДО = Строка(ТабЛицаРезультат.Замена.УникальныйИдентификатор());
ОбластьСтрока.Параметры.ТипОбъектаИС = ТабЛицаРезультат.ТипОбъектаИС;


ТабДок.Вывести(ОбластьСтрока);
НоваяСтрока = ТаблицаОбработанных.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ТабЛицаРезультат);

ОтметкаВыгрузки = Новый Структура("Папка, Файл");
ЗаполнитьЗначенияСвойств(ОтметкаВыгрузки, ТабЛицаРезультат);
ОтметитьВыгрузку.Добавить(ОтметкаВыгрузки);
КонецЦикла;

ПутьЗаписи = СтрШаблон("%1\ДанныеСинхронизацииДО_%2.ods", ПутьВыгрузки, СчетчикФайл);
ТабДок.Записать(ПутьЗаписи, ТипФайлаТабличногоДокумента.ODS);

ВыгруженоУстановить(ОтметитьВыгрузку);
КонецЦикла;

КонецПроцедуры

// Обновляет значение ресурса "Выгружено" в существующих записях регистра
// сведений files_ОбработанныеПапки для указанных ключей "Папка, Файл".
//
// !!! Важно: Новые записи не создаются. Обновляются только существующие.
// Другие измерения и ресурсы регистра не изменяются.
//
// Параметры:
// МассивДанных - Массив - Коллекция структур, каждая из которых содержит ключи:
// * Папка - СправочникСсылка.ПапкиФайлов - Ссылка на папку (обязательно).
// * Файл - СправочникСсылка.Файлы - Ссылка на файл (обязательно).
// Выгружено - Булево - Новое значение ресурса "Выгружено".
// По умолчанию: Истина.
//
// Возвращаемое значение:
// Число - Количество записей, которые были обновлены.
//
&НаСервереБезКонтекста
Функция ВыгруженоУстановить(МассивДанных, Выгружено = Истина) Экспорт

Если МассивДанных = Неопределено ИЛИ МассивДанных.Количество() = 0 Тогда
Возврат 0;
КонецЕсли;

КоличествоОбновлено = 0;

// Начинаем транзакцию для  обеспечения целостности
НачатьТранзакцию();

Попытка

Для Каждого ЭлементДанных Из МассивДанных Цикл

// Проверка наличия необходимых ключей
Если ЭлементДанных = Неопределено
ИЛИ ЭлементДанных.Свойство("Папка") = Ложь
ИЛИ ЭлементДанных.Свойство("Файл") = Ложь Тогда
Продолжить;
КонецЕсли;

Папка = ЭлементДанных.Папка;
Файл = ЭлементДанных.Файл;

// Пропускаем пустые ссылки
Если Папка = Неопределено ИЛИ Папка.Пустая()
ИЛИ Файл = Неопределено ИЛИ Файл.Пустая() Тогда
Продолжить;
КонецЕсли;

// Создаем менеджер записи для конкретного ключа
МенеджерЗаписи = РегистрыСведений.files_ОбработанныеПапки.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Папка = Папка;
МенеджерЗаписи.Файл = Файл;

// Пытаемся прочитать существующую запись
МенеджерЗаписи.Прочитать();

// Если запись существует - обновляем только ресурс Выгружено
Если МенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Выгружено = Выгружено;
МенеджерЗаписи.Записать();
КоличествоОбновлено = КоличествоОбновлено + 1;
КонецЕсли;

КонецЦикла;

// Фиксируем транзакцию
ЗафиксироватьТранзакцию();

Исключение
// Отменяем транзакцию при ошибке
ОтменитьТранзакцию();

// Логируем ошибку
ТекстОшибки = СтрШаблон(
"Ошибка при обновлении признака выгружено (обновлено %1 из %2): %3",
КоличествоОбновлено,
МассивДанных.Количество(),
ОписаниеОшибки());

ЗаписьЖурналаРегистрации(
"files_ОбработанныеПапки.Ошибка",
УровеньЖурналаРегистрации.Ошибка,
, , , ТекстОшибки);

// Пробрасываем исключение дальше
ВызватьИсключение ТекстОшибки;
КонецПопытки;

Возврат КоличествоОбновлено;

КонецФункции

// Возвращает текст запроса получения данных синхронизации
//
// Возвращаемое значение:
// Строка
&НаСервереБезКонтекста
Функция ТекстЗапроса()

Возврат "ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОП.Замена КАК Замена,
| ОП.Папка КАК Папка,
| ОП.Файл КАК Файл,
| ОП.Замена.ВидДокумента КАК ЗаменаВидДокумента,
| СВ.ИДВнешнегоОбъекта КАК ИДВнешнегоОбъекта,
| ПравилаЗагрузкиДанныхВДО.ТипОбъектаИС КАК ТипОбъектаИС
|ПОМЕСТИТЬ ДанныеПредварительно
|ИЗ
| РегистрСведений.files_ОбработанныеПапки КАК ОП
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиОбъектовИнтегрированныхСистем КАК СВ
| ПО ОП.Замена = СВ.СсылкаНаОбъектДО
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПравилаЗагрузкиДанныхВДО КАК ПравилаЗагрузкиДанныхВДО
| ПО ОП.Замена.ВидДокумента = ПравилаЗагрузкиДанныхВДО.ВидДокумента
|ГДЕ
| СВ.ИДВнешнегоОбъекта ЕСТЬ НЕ NULL
| И ПравилаЗагрузкиДанныхВДО.ТипОбъектаИС ЕСТЬ НЕ NULL
| И НЕ ОП.Ошибка
| И НЕ ОП.Выгружено
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ ПЕРВЫЕ 50000 //Замена
| ДанныеПредварительно.ИДВнешнегоОбъекта КАК ИДВнешнегоОбъекта,
| ДанныеПредварительно.Папка КАК Папка,
| ДанныеПредварительно.Замена КАК Замена,
| ДанныеПредварительно.Файл КАК Файл,
| ДанныеПредварительно.ТипОбъектаИС КАК ТипОбъектаИС
|ИЗ
| ДанныеПредварительно КАК ДанныеПредварительно";

КонецФункции // ТекстЗапроса

Далее файлы передаются на сторону ERP для выполнения завершающего шага — загрузки в регистр «Объекты, интегрированные с 1С:Документооборотом».

Итоги этапа выгрузки данных для ERP

С помощью данного механизма нам удалось превратить миллионный массив данных в компактные, готовые к передаче файлы. На нашем проекте было сформировано порядка 150 файлов (при объеме 1,5 млн записей и порции в 10 000 записей), а общее время выгрузки составило не более 15 минут.

IV. Загрузка данных для ERP (Синхронизация связей интеграции)

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

Архитектура загрузки данных

В отличие от описанных ранее задач здесь мы работаем исключительно в контуре ERP.

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

Схема загрузки данных синхронизации

Схема загрузки данных синхронизации

В основе лежит регламентное задание, которое выполняет ряд действий по шагам.

Шаг 1. Замена типов

Поиск всех записей с типами DMInternalDocument, DMIncomingDocument и DMOutgoingDocument и замена их на актуальный DMDocument.

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

// Выполняет многопоточную синхронизацию в 10 потоков интеграции путем пакетной
// обработки файлов из указанного каталога. Процесс ограничен таймаутом 120 минут.
//
// Параметры:
// Путь - Строка - полный путь к каталогу, содержащему файлы для синхронизации.
//
Процедура СинхронизацияИнтеграцииЗапустить(Путь = Неопределено) Экспорт

Если Не ЗначениеЗаполнено(Путь) Тогда 
Путь = Константы.sync_КаталогСинхронизации.Получить();
КонецЕсли;

ТипыОбъектовДООбновить();

Повторять = Истина;

ТаймаутМинут = 120;
ТаймаутМиллисекунд = ТаймаутМинут * 60 * 1000;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
ВремяТаймаут = ВремяНачала + ТаймаутМиллисекунд;

МетодИмя = "sync_ВходящиеСообщения.ПотокСинхронизацииСоздать";
ПредставлениеЗадания = "Синхронизация связей интеграции с ДО (Sync)"; 

Пока Повторять Цикл
Если ТекущаяУниверсальнаяДатаВМиллисекундах() > ВремяТаймаут Тогда
ЗаписьЖурналаРегистрации("Синхронизация.МногопоточнаяЗагрузка"
, УровеньЖурналаРегистрации.Предупреждение
,
,
, СтрШаблон("Загрузка прервана. Превышен таймаут синхронизации: %1 минут", ТаймаутМинут));
Прервать;
КонецЕсли;

Файлы = ПачкаФайловПолучить(Путь, 10);
Если НЕ Файлы.Количество() Тогда
Повторять = Ложь;
КонецЕсли;

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

КонецПроцедуры

// Создает поток синхронизации для обработки файлов по указанному пути.
// Использует обработку sync_ЗагрузкаДанныхСинхронизации для выполнения
// синхронизации данных из внешних файлов.
//
// Параметры:
// Путь - Строка - полный путь к файлу, который содержит
// данные для  синхронизации
//

Процедура ПотокСинхронизацииСоздать(Путь) Экспорт

ОбработкаТ = Обработки.sync_ЗагрузкаДанныхСинхронизации.Создать();
ОбработкаТ.ИнтеграцияСинхронизировать(Путь);

КонецПроцедуры

// Выполняет замену устаревших значений измерения ТипОбъектаДО
// в регистре сведений "ОбъектыИнтегрированныеС1СДокументооборотом".
// Заменяемые значения: DMOutgoingDocument, DMIncomingDocument, DMInternalDocument
// Новое значение: DMDocument
//
Процедура ТипыОбъектовДООбновить()

КоллекцияТипов = Новый Массив;
КоллекцияТипов.Добавить("DMOutgoingDocument");
КоллекцияТипов.Добавить("DMIncomingDocument");
КоллекцияТипов.Добавить("DMInternalDocument");

Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1000
| Т.Объект КАК Объект,
| Т.ТипОбъектаДО КАК ТипОбъектаДО,
| Т.ИдентификаторОбъектаДО КАК ИдентификаторОбъектаДО
|ИЗ
| РегистрСведений.ОбъектыИнтегрированныеС1СДокументооборотом КАК Т
|ГДЕ
| Т.ТипОбъектаДО В(&Типы)");
Запрос.УстановитьПараметр("Типы", КоллекцияТипов);

Замена = "DMDocument";
Обрабатывать = Истина;
Пока Обрабатывать Цикл
Выборка = Запрос.Выполнить().Выбрать();
Обрабатывать = Выборка.Количество() > 0;   
НачатьТранзакцию();
Попытка
Пока Выборка.Следующий() Цикл 
// Чистим 
НаборЗаписей = РегистрыСведений.ОбъектыИнтегрированныеС1СДокументооборотом.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(Выборка.Объект);
НаборЗаписей.Отбор.ТипОбъектаДО.Установить(Выборка.ТипОбъектаДО);
НаборЗаписей.Отбор.ИдентификаторОбъектаДО.Установить(Выборка.ИдентификаторОбъектаДО);
НаборЗаписей.Записать();
// Добавляем
НаборНовый = РегистрыСведений.ОбъектыИнтегрированныеС1СДокументооборотом.СоздатьНаборЗаписей();
НаборНовый.Отбор.Объект.Установить(Выборка.Объект);
НаборНовый.Отбор.ТипОбъектаДО.Установить(Замена);
НаборНовый.Отбор.ИдентификаторОбъектаДО.Установить(Выборка.ИдентификаторОбъектаДО);
ЗаписьНовая = НаборНовый.Добавить();

ЗаписьНовая.Объект = Выборка.Объект;
ЗаписьНовая.ТипОбъектаДО = Замена;
ЗаписьНовая.ИдентификаторОбъектаДО = Выборка.ИдентификаторОбъектаДО;

НаборНовый.Записать();
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки
КонецЦикла;

КонецПроцедуры

Шаг 2. Подготовка к многопоточной обработке 

Проверяется каталог, указанный в константе sync_КаталогСинхронизации. Если файлов нет, задание завершается. Если есть — начинается загрузка.

// Получает список файлов по указанному пути
// и возвращает первые 5 файлов
//
// Параметры:
// ПутьКаталога - Строка - полный путь к каталогу на диске.
// КоличествоФайлов - Число - количество файлов для отбора
// (по умолчанию 5).
//
// Возвращаемое значение:
// Массив - массив строк с полными именами файлов.
Функция ПачкаФайловПолучить(Знач ПутьКаталога, Знач КоличествоФайлов = 5)

Результат = Новый Массив;

Если НЕ ФайлСуществует(ПутьКаталога) Тогда
Возврат Результат;
КонецЕсли;

ВсеФайлы = НайтиФайлы(ПутьКаталога, "*.*", Ложь);

Для Индекс = 0 По Мин(КоличествоФайлов - 1, ВсеФайлы.Количество() - 1) Цикл
Результат.Добавить(ВсеФайлы[Индекс].ПолноеИмя);
КонецЦикла;

Возврат Результат;

КонецФункции // ПачкаФайловПолучить()

Шаг 3. Многопоточная обработка

Если в каталоге присутствуют файлы (те самые порционные ODS-файлы из ДО3), система запускает многопоточную обработку. Принцип простой: каждый файл получает отдельный поток — для этого создается собственный экземпляр обработки sync_ЗагрузкаДанныхСинхронизации. Благодаря параллельной работе мы можем обрабатывать десятки файлов одновременно, максимально используя ресурсы сервера. И что важно, потоки при этом не конфликтуют — у каждого свои уникальные данные. После запуска всех файлов в потоки производится ожидание выполнения заданий.

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

Шаг 3. Экземпляр обработки

Каждый экземпляр sync_ЗагрузкаДанныхСинхронизации работает самостоятельно и выполняет следующие действия:

  1. Открывает файл и читает данные из ODS-таблицы.
  2. Ищет в базе ERP объекты по их GUID и типу.
  3. Раскладывает результаты по двум направлениям:
    1. Если объект нашелся — записывает связь в регистр «Объекты, интегрированные с 1С:Документооборотом». Именно после этой записи файлы снова появляются в карточках документов ERP. Можно сказать, что здесь происходит «магия» восстановления.
    2. Если объект не нашелся (например, GUID изменился или документ случайно удалили), запись уходит в специальный регистр «Неидентифицированные объекты».

Зачем нужен регистр «Неидентифицированные объекты»

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

Пример ссылок, которые не удалось идентифицировать

Пример ссылок, которые не удалось идентифицировать

// Создает поток синхронизации для обработки файлов по указанному пути.
// Использует обработку sync_ЗагрузкаДанныхСинхронизации для выполнения
// синхронизации данных из внешних файлов.
//
// Параметры:
// Путь - Строка - полный путь к файлу, который содержит
// данные для  синхронизации
//
Процедура ПотокСинхронизацииСоздать(Путь) Экспорт

ОбработкаТ = Обработки.sync_ЗагрузкаДанныхСинхронизации.Создать();
ОбработкаТ.ИнтеграцияСинхронизировать(Путь);

КонецПроцедуры

// Код модуля объекта обработки:

#Область ПрограммныйИнтерфейс

// Выполняет синхронизацию данных интеграции с Документооборотом.
// Читает данные из файла, записывает идентифицированные объекты в регистр
// сведений и удаляет исходный файл при успешной обработке.
//
// Параметры:
// Путь - Строка - полный путь к файлу с данными для синхронизации.
//
Процедура ИнтеграцияСинхронизировать(Путь) Экспорт

ДанныеТаблицаПрочитать(Путь);
ТипДокумент = "DMDocument";
Для Каждого Строка Из ИдентифицированныеДанные Цикл
НаборЗаписей = РегистрыСведений.ОбъектыИнтегрированныеС1СДокументооборотом.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(Строка.Ссылка);
НаборЗаписей.Отбор.ТипОбъектаДО.Установить(ТипДокумент);
НаборЗаписей.Отбор.ИдентификаторОбъектаДО.Установить(Строка.ИДДО);

Запись = НаборЗаписей.Добавить();
Запись.Объект = Строка.Ссылка;
Запись.ТипОбъектаДО = ТипДокумент;
Запись.ИдентификаторОбъектаДО = Строка.ИДДО;
НаборЗаписей.Записать();
КонецЦикла;

Если Не НеУдалять Тогда
Попытка
// Удаляем
Файл = Новый Файл(Путь);
УдалитьФайлы(Путь);
Исключение
ВызватьИсключение;
КонецПопытки;
КонецЕсли;

КонецПроцедуры // ИнтеграцияСинхронизировать()

#КонецОбласти

#Область ОбработчикиСобытий

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Выполняет чтение данных из файла ODS и заполняет таблицы: ДанныеКОбработке, ИдентифицированныеДанные.
//
// Параметры:
// Путь - Строка - полный путь к файлу ODS на сервере.
Процедура ДанныеТаблицаПрочитать(Путь)

ПрочитатьODSСоВторойСтроки(Путь); 
СсылкиИдентифицировать();

КонецПроцедуры // ДанныеТаблицаКЛЗаполнитьНаСервере

// Читает файл ODS со 2-й строки, заполняет таблицу ДанныеКОбработке
//
// Параметры:
//  ПутьКФайлу - Строка - полный путь к файлу ODS на сервере
//
Процедура ПрочитатьODSСоВторойСтроки(Знач ПутьКФайлу) Экспорт

Попытка
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);

КоличествоСтрок = ТабличныйДокумент.ВысотаТаблицы;
Для НомерСтроки = 2 По КоличествоСтрок Цикл

// Получаем значения ячеек
ЗначениеКолонки1 = СокрЛП(ТабличныйДокумент.Область(НомерСтроки, 1).Текст);
ЗначениеКолонки2 = СокрЛП(ТабличныйДокумент.Область(НомерСтроки, 2).Текст);
ЗначениеКолонки3 = СокрЛП(ТабличныйДокумент.Область(НомерСтроки, 3).Текст);

Если ЗначениеКолонки1 = "" И ЗначениеКолонки2 = "" И ЗначениеКолонки3 = ""Тогда
Продолжить;
КонецЕсли;

// Добавляем строку в результат
НоваяСтрока = ДанныеКОбработке.Добавить();
НоваяСтрока.ИДВнешнегоОбъекта = ЗначениеКолонки1;
НоваяСтрока.ТипОбъектаИС = ЗначениеКолонки2;
НоваяСтрока.ИДДО = ЗначениеКолонки3;

КонецЦикла;

Исключение
ВызватьИсключение;
КонецПопытки;

КонецПроцедуры // ПрочитатьODSСоВторойСтроки()

Процедура СсылкиИдентифицировать()

// Обрабатываем каждую строку
Для Каждого Строка Из ДанныеКОбработке Цикл

НоваяСтрока = ИдентифицированныеДанные.Добавить();
НоваяСтрока.ИДВнешнегоОбъекта = Строка.ИДВнешнегоОбъекта;
НоваяСтрока.ТипОбъектаИС = Строка.ТипОбъектаИС;
НоваяСтрока.ИДДО = Строка.ИДДО;

Попытка
// Ищем ссылку по GUID
Ссылка = СсылкуПоГУИДНайти(Строка.ИДВнешнегоОбъекта, Строка.ТипОбъектаИС);

Если Ссылка = Неопределено Тогда
НеидентифицированнаяСсылкаЗаписать(Строка.ИДВнешнегоОбъекта, Строка.ТипОбъектаИС);
НеУдалять = Истина;
Иначе
НоваяСтрока.Ссылка = Ссылка;
КонецЕсли;

Исключение
НеидентифицированнаяСсылкаЗаписать(Строка.ИДВнешнегоОбъекта
, Строка.ТипОбъектаИС
, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
НеУдалять = Истина;
КонецПопытки;
КонецЦикла;

КонецПроцедуры // СсылкиИдентифицировать()

// Выполняет запись информации о неидентифицированной ссылке
// в регистр сведений "НеидентифицированныеОбъекты".
// Используется при обнаружении GUID из внешнего источника,
// для которого не найден соответствующий объект в базе данных.
//
// Параметры:
// ГУИД - Строка - уникальный идентификатор объекта
Процедура НеидентифицированнаяСсылкаЗаписать(Знач ГУИД, Знач ТипОбъектаИС, ТекстОшибки = "")

Запись = РегистрыСведений.sync_НеидентифицированныеОбъекты.СоздатьМенеджерЗаписи();
Запись.ИДВнешнегоОбъекта = ГУИД;
Запись.ТипОбъектаИС = ТипОбъектаИС;
Запись.Комментарий = ТекстОшибки;
Запись.ДатаДобавления = ТекущаяДатаСеанса();
Запись.Записать();

КонецПроцедуры



// Возвращает ссылку по GUID. Поиск во всех справочниках и документах 
//
// Параметры:
// GUID - Строка - уникальный идентификатор объекта в формате GUID
// ПолноеИмяМетаданных - Строка - Полное имя метаданных
//
// Возвращаемое значение:
// ЛюбаяСсылка - ссылка на найденный объект или Неопределено, если объект не найден
//
Функция СсылкуПоГУИДНайти(Знач GUID, Знач ПолноеИмяМетаданных) Экспорт

Если ПустаяСтрока(GUID) ИЛИ ПустаяСтрока(ПолноеИмяМетаданных) Тогда
Возврат Неопределено;
КонецЕсли;

Попытка
УИД = Новый УникальныйИдентификатор(GUID);
Исключение
Возврат Неопределено;
КонецПопытки;

Менеджер = ПолучитьМенеджерПоИмени(ПолноеИмяМетаданных); //Возвращает менеджер объекта метаданных по его полному имени

Если Менеджер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;

Попытка
Ссылка = Менеджер.ПолучитьСсылку(УИД);
Возврат ?(ОбщегоНазначения.СсылкаСуществует(Ссылка), Ссылка, Неопределено);
Исключение
Возврат Неопределено;
КонецПопытки;

КонецФункции // СсылкуПоГУИДНайти()  

#КонецОбласти

Шаг 4. Уборка и завершение цикла 

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

// .................................
Если Не НеУдалять Тогда
Попытка
// Удаляем
Файл = Новый Файл(Путь);
УдалитьФайлы(Путь);
Исключение
ВызватьИсключение;
КонецПопытки;
КонецЕсли;
// .................................

Итоги этапа загрузки данных в ERP

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

Ключевые результаты работы механизма:

  • Автоматическая замена устаревших типов. На старте процесса было выполнено обновление регистра «Объекты, интегрированные с 1С:Документооборотом» — все записи с типами DMInternalDocument, DMIncomingDocument и DMOutgoingDocument заменены на актуальный DMDocument. Это устранило саму причину ошибки открытия данных документооборота.
  • Многопоточная обработка порционных файлов. Механизм анализировал каталог синхронизации, отбирал файлы порциями по 10 штук и запускал для каждого файла отдельный поток обработки. Это позволило максимально эффективно использовать ресурсы сервера и обработать все файлы.
  • Идентификация объектов и восстановление связей. Для каждой записи из файла выполнялся поиск соответствующего объекта в базе ERP по GUID и типу. Найденные объекты получали новую запись в регистре интеграции, что моментально восстанавливало отображение файлов в карточках документов.
  • Контроль полноты обработки. Для неидентфицированных объектов предусмотрен регистр «Неидентифицированные объекты», выполняющий роль страховочной сетки.
  • Автоматическая очистка. После успешной обработки файлы удалялись из каталога, что исключало повторную загрузку и служило индикатором выполнения.

На нашем проекте общее время загрузки данных в ERP составило около 20 минут.

Результаты

По итогу восстановлено отображение файлов и возможность работы с данными документооборота в ERP после миграции:

  • Устранена ошибка открытия данных документооборота, связанная с устаревшими типами обмена пакета XDTO «DM».
  • Полностью восстановлено отображение файлов в карточках документов ERP.
  • Создана отказоустойчивая, прозрачная и масштабируемая система, которая при необходимости может быть запущена повторно.
  • Общее время обработки — менее 1,5 часов при объеме данных в 1,5 млн объектов.

Проблема, с которой мы столкнулись после миграции, выглядела пугающе: файлы исчезли из карточек ERP, а при попытке открыть данные документооборота возникали ошибки. Причина крылась в архитектурных изменениях ДО3 — устаревший режим хранения «Файлы в отдельных папках» перестал поддерживаться, старая структура связей оказалась несовместима с новой логикой интеграции.

Вместо «быстрых» заплаток, мы построили целостную систему восстановления, которая поэтапно решила проблему комплексно:

  • Диагностика.

    Проанализированы механизмы связи ERP и ДО, выявлена причина ошибок (устаревшие XDTO-типы) и отсутствия файлов (неподдерживаемый режим хранения).

  • Разработка универсального алгоритма.

    Создан алгоритм, покрывающий все возможные сценарии: от простой корректировки связей до полного восстановления «с нуля».

  • Подготовка инфраструктуры.

    Автоматически сгенерированы недостающие правила интеграции для типов объектов, по которым были файлы, но не было настроек.

    В нашем проекте таким образом было создано 62 правила, что заняло бы длительное время при ручном создании, в итоге правила сформировались в течении 5 минут.

  • Обработка данных в ДО3.

    Разработанная система в многопоточном режиме (30 потоков) выполнила инвентаризацию файлов, создала недостающие связанные объекты и переназначила владельцев файлов.

    На продуктивной системе для 1,5 млн объектов это заняло около 1 часа.

  • Порционная выгрузка.

    Результаты обработаны и упакованы в файлы.

    В нашем случае получилось ~150 файлов (порциями по 10 000 записей), общее время выгрузки ~15 минут.

  • Загрузка и синхронизация в ERP.

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

    Время выполнения ~20 минут.

Для конечных пользователей всё выглядит просто и привычно: они открывают карточку документа, переходят к файлам ДО и видят все прикрепленные файлы. Новая реальность (ДО3) осталась за кулисами, никак не усложняя пользовательский опыт. А для нас это означает, что восстановление прошло успешно, и 1,5 млн объектов больше не разделяют, а связывают две системы.

Друзья, на этом цикл статей ещё не завершен, ожидайте новостей о выходе четвертой части, где мы расскажем про сложности с миграцией прав доступа, а также с практическими данными и результатами продуктивной миграции.

До скорых встреч.

Вы читаете статью из рубрики:
От экспертов «1С-Рарус»

Читайте первыми статьи от экспертов «1С‑Рарус»

Вы можете получать оповещения по электронной почте

Поле является обязательным

Или получайте уведомления в телеграм-боте

Есть вопросы по статье? Задайте их нам!

Рассылка «Новости компании»

Узнавайте первыми о новых статьях, мероприятиях и спецпредложениях.

Посмотреть все рассылки «1С‑Рарус»

Заинтересованы в сотрудничестве?
Нужна консультация?
Свяжитесь с нами!