Данные 1С через XML: перенос между базами обработкой и встроенным языком

· 9 мин

Содержание

Скопировать данные из одной базы 1С в другую через XML проще всего обработкой «Выгрузка и загрузка данных XML»: в базе-источнике отмечаете нужные справочники и документы, получаете файл .xml, а в базе-приёмнике загружаете его той же обработкой. Условие одно — конфигурации обеих баз должны совпадать по структуре объектов. Если они разные, нужен обмен по правилам конвертации или свой код на ЗаписьXML и ЧтениеXML.

Всё, что описано ниже, относится к платформе 1С:Предприятие 8.3 в целом и не зависит от конкретной конфигурации: БП 3.0, ЗУП 3.1, УТ 11 используют одни и те же механизмы XML. Различаются только встроенные средства обмена, о них — в первом разделе.

Какой способ выгрузки и загрузки XML выбрать

Под «скопировать XML в 1С» скрываются четыре разные задачи. Сначала определите свою.

ЗадачаЧем делатьОграничения
Перенести справочники и документы между базами с одинаковой конфигурациейОбработка «Выгрузка и загрузка данных XML»Структура метаданных должна совпадать
Перенести данные между разными конфигурациями (например, из УТ в БП)Встроенная синхронизация данных или «Универсальный обмен данными в формате XML» с правиламиНужны правила конвертации или типовой формат обмена
Сохранить конфигурацию в виде набора XML-файловКонфигуратор: Конфигурация → Выгрузить конфигурацию в файлыВыгружаются метаданные и модули, а не данные
Сформировать или прочитать файл своей структуры (для банка, сайта, контрагента)Код на встроенном языкеПишет программист

Если нужна полная копия базы со всеми данными, XML не нужен. Выгрузите базу в .dt через Конфигуратор (Администрирование → Выгрузить информационную базу) или скопируйте каталог файловой базы целиком.

Обработка «Выгрузка и загрузка данных XML»

Это внешняя обработка (файл .epf) от фирмы 1С, её распространяют для пользователей с договором сопровождения. Под платформу 8.3 используйте версию обработки для 8.3: файл для 8.2 тоже открывается, но с новыми типами данных работает хуже.

Порядок работы в базе-источнике:

  1. Откройте обработку через главное меню: Файл → Открыть. Платформа спросит разрешение на запуск внешней обработки, если база защищена от опасных действий, — подтвердите, если уверены в источнике файла.
  2. На вкладке выгрузки отметьте флажками нужные объекты: справочники, документы, регистры сведений.
  3. Укажите период, если выгружаете документы за конкретные месяцы.
  4. Включите опцию выгрузки объектов по ссылкам, если нужны связанные элементы. Без неё документ придёт в приёмник с «битыми» ссылками на контрагентов и номенклатуру.
  5. Укажите имя файла и нажмите кнопку выгрузки.

В базе-приёмнике:

  1. Сделайте резервную копию: загрузка пишет объекты напрямую и откатить её одной кнопкой нельзя.
  2. Откройте ту же обработку, перейдите на вкладку загрузки.
  3. Выберите файл и запустите загрузку.

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

Обмен между разными конфигурациями

Между разными прикладными решениями переносить данные «один в один» нельзя: у справочника «Номенклатура» в УТ 11 и БП 3.0 разный набор реквизитов. Здесь работают два пути:

  • 🔄 Встроенная синхронизация. В типовых конфигурациях она находится в разделе Администрирование → Синхронизация данных. Обмен идёт в формате EnterpriseData, это тоже XML. Можно настроить обмен через общий каталог или выгрузку в файл.
  • 🧩 Универсальный обмен данными в формате XML. Обработка, которая выгружает и загружает данные по правилам из конфигурации «Конвертация данных ». Подходит, когда типового обмена между вашими конфигурациями нет.

Как создать и скопировать XML средствами встроенного языка

Когда файл нужен своей структуры, программист пишет его объектом ЗаписьXML. Это потоковая запись: данные уходят в файл по мере формирования, память не забивается.

Пример выгружает коды и наименования справочника в файл. Код рассчитан на выполнение на сервере или в толстом клиенте.

Процедура ВыгрузитьКонтрагентов(ИмяФайла)

    Запись = Новый ЗаписьXML;
    Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
    Запись.ЗаписатьОбъявлениеXML();
    Запись.ЗаписатьНачалоЭлемента("Контрагенты");

    Выборка = Справочники.Контрагенты.Выбрать();
    Пока Выборка.Следующий() Цикл
        Запись.ЗаписатьНачалоЭлемента("Контрагент");
        Запись.ЗаписатьАтрибут("Код", СокрЛП(Выборка.Код));
        Запись.ЗаписатьТекст(Выборка.Наименование);
        Запись.ЗаписатьКонецЭлемента();
    КонецЦикла;

    Запись.ЗаписатьКонецЭлемента();
    Запись.Закрыть();

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

На выходе получится файл вида <Контрагенты><Контрагент Код="000000001">ООО Ромашка</Контрагент>...</Контрагенты>.

Чтение XML и перенос значений в 1С

Обратная операция — объект ЧтениеXML. Он идёт по файлу узел за узлом: начало элемента, текст, конец элемента.

Процедура ПрочитатьКонтрагентов(ИмяФайла)

    Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ИмяФайла);

    Пока Чтение.Прочитать() Цикл
        Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента
            И Чтение.Имя = "Контрагент" Тогда

            Код = Чтение.ПолучитьАтрибут("Код");
            Наименование = "";

            Чтение.Прочитать();
            Если Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
                Наименование = Чтение.Значение;
            КонецЕсли;

            Сообщить(Код + " — " + Наименование);
        КонецЕсли;
    КонецЦикла;

    Чтение.Закрыть();

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

Проверка ТипУзлаXML.Текст нужна для пустых наименований: у пустого элемента текстового узла нет, и без проверки в наименование попал бы следующий узел.

Копирование объектов целиком через СериализаторXDTO

Если нужно перенести объекты со всеми реквизитами и табличными частями между базами с одинаковой конфигурацией, удобнее сериализатор. Именно на нём построена обработка из первого раздела.

Выгрузка в базе-источнике:

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Данные");

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    СериализаторXDTO.ЗаписатьXML(Запись, Выборка.ПолучитьОбъект());
КонецЦикла;

Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();

Загрузка в базе-приёмнике:

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Чтение.ПерейтиКСодержимому(); // корневой элемент <Данные>
Чтение.Прочитать();           // первый объект внутри

Пока СериализаторXDTO.ВозможностьЧтенияXML(Чтение) Цикл
    Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
    Объект.ОбменДанными.Загрузка = Истина;
    Объект.Записать();
КонецЦикла;

Чтение.Закрыть();

Флаг ОбменДанными.Загрузка = Истина отключает проверки и обработчики при записи. Так загрузка не споткнётся о незаполненные обязательные реквизиты, но и контроль ляжет на вас.

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

Пути к файлам: где лежит XML и кто его видит

Половина проблем с XML в 1С — не в коде, а в путях. Код на сервере и код на клиенте видят разные файловые системы.

  • 🖥️ Файловая база, тонкий или толстый клиент. Код выполняется на компьютере пользователя, путь C:\Обмен\data.xml работает как есть.
  • 🏢 Клиент-серверная база . Код в серверной процедуре открывает файл на сервере 1С. Путь C:\Обмен\ — это диск сервера, а не ваш.
  • 🌐 Веб-клиент. Прямого доступа к диску пользователя нет вообще, файл передают через временное хранилище.

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

// На сервере: двоичные данные из временного хранилища в файл
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
ДанныеФайла = ПолучитьИзВременногоХранилища(АдресВХранилище);
ДанныеФайла.Записать(ИмяВременногоФайла);

// ... читаем ИмяВременногоФайла через ЧтениеXML ...

УдалитьФайлы(ИмяВременногоФайла);

Адрес во временном хранилище клиент получает асинхронными методами помещения файла (НачатьПомещениеФайла, в новых версиях платформы — НачатьПомещениеФайлаНаСервер).

Скопировать сам файл XML

Если задача — просто положить готовый XML в другой каталог, используйте КопироватьФайл(Источник, Приемник) на сервере или НачатьКопированиеФайла на клиенте. Перед копированием проверьте наличие файла:

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

Права на каталог обмена

Служба сервера 1С работает от отдельной учётной записи Windows, обычно USR1CV8. Если обмен идёт через сетевую папку, права на запись нужны именно этой учётной записи, а не пользователю, который запустил обмен.

Путь к сетевой папке указывайте в формате UNC: \\СерверФайлов\Обмен\. Подключённый у пользователя диск Z: служба не видит.

Ошибки при загрузке XML и проверка структуры файла

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

Попытка
    Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ИмяФайла);
    // ... разбор ...
    Чтение.Закрыть();
Исключение
    ЗаписьЖурналаРегистрации("Обмен XML",
        УровеньЖурналаРегистрации.Ошибка, , ,
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

Текст ошибки потом ищут в журнале регистрации: Администрирование → Обслуживание → Журнал регистрации, отбор по событию «Обмен XML».

Проверка по XSD-схеме

Если партнёр прислал схему файла (.xsd), проверяйте входящий XML по ней до загрузки. Платформа строит фабрику XDTO прямо из схемы:

Фабрика = СоздатьФабрикуXDTO(ПутьКСхеме);
ТипДанных = Фабрика.Тип("http://example.com/exchange", "Документ");

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
ОбъектДанных = Фабрика.ПрочитатьXML(Чтение, ТипДанных);
ОбъектДанных.Проверить();
Чтение.Закрыть();

Если файл не соответствует схеме, ПрочитатьXML или Проверить() вызовут исключение с описанием проблемного элемента. Вместо адреса из примера подставьте пространство имён из атрибута targetNamespace вашей схемы.

Диагностика: выберите симптом

Большие объёмы: как выгрузить и загрузить XML быстрее

На тысяче элементов разница между подходами не видна. На миллионе строк неверно выбранный способ превращает загрузку из минут в часы или роняет процесс по памяти.

ПриёмЧто даёт
Потоковые ЧтениеXML и ЗаписьXML вместо ДокументDOMDOM грузит весь файл в память; файл на 500 МБ в DOM занимает в разы больше
Запросом выбирать только нужные поляВыборка.ПолучитьОбъект() читает объект целиком с табличными частями — это дорого
Запись пакетами в транзакцииОдна транзакция на 500–1000 объектов быстрее, чем по одной на каждый
ОбменДанными.Загрузка = ИстинаНе выполняются обработчики ПередЗаписью и проверки заполнения
Выполнение на сервереНет передачи каждого объекта между клиентом и сервером
Деление файла на частиСбой на 900-тысячном элементе не заставляет начинать всё заново

Пример записи пакетами:

Счетчик = 0;
НачатьТранзакцию();
Пока СериализаторXDTO.ВозможностьЧтенияXML(Чтение) Цикл
    Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
    Объект.ОбменДанными.Загрузка = Истина;
    Объект.Записать();
    Счетчик = Счетчик + 1;
    Если Счетчик % 1000 = 0 Тогда
        ЗафиксироватьТранзакцию();
        НачатьТранзакцию();
    КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();

В рабочем коде добавьте Попытка ... Исключение с ОтменитьТранзакцию(), чтобы ошибка в пакете не оставляла открытую транзакцию.

Для передачи по сети сожмите большой XML в архив объектом ЗаписьZipФайла. Текстовый XML с повторяющимися тегами обычно сжимается в несколько раз.

Ещё один практичный приём: выгружайте справочники и документы в разные файлы. Справочники загружаются первыми, и к моменту загрузки документов все ссылки уже есть в базе.

Когда XML — не лучший вариант

XML выбирают по привычке, хотя иногда есть способы проще:

  • 📦 Полная копия базы — выгрузка .dt в Конфигураторе. Быстрее и без риска потерять объекты.
  • 📊 Перенос одного списка (цены, остатки, контрагенты) — загрузка из табличного документа или Excel. В типовых конфигурациях она встроена в формы многих списков.
  • 🔁 Регулярный обмен двух типовых баз — встроенная синхронизация данных. Она сама отслеживает изменения и не гоняет всю базу каждый раз.
  • 🔌 Обмен с сайтом или сервисом в реальном времени — HTTP-сервисы или REST-интерфейс OData. JSON в таких сценариях компактнее XML.

Вопросы, которые остаются после первой выгрузки

Можно ли загрузить XML из 1С 7.7 в 1С 8.3?
Напрямую обработкой «Выгрузка и загрузка данных XML» — нет, структура данных разная. Перенос из 7.7 делают через правила конвертации: в типовых конфигурациях 8.3 для этого есть встроенный механизм переноса из 7.7.
Загрузка XML создаст дубли справочников?
При переносе обработкой и сериализатором — нет: объекты переносятся со своими идентификаторами и перезаписываются. Дубли появляются, если элемент с тем же наименованием уже был создан в приёмнике вручную.
Как выгрузить в XML только изменённые объекты?
Для этого нужен план обмена: он регистрирует изменения, и выгружаются только они. Встроенная синхронизация данных работает именно так.
Почему XML из 1С не открывается в Excel как таблица?
Excel ждёт плоскую структуру, а выгрузка 1С вложенная, с табличными частями и ссылками. Для Excel формируйте файл табличного вида или сохраняйте отчёт в формате xlsx.
Можно ли запускать выгрузку XML по расписанию?
Да. Код выгрузки размещают в регламентном задании, оно выполняется на сервере 1С. Пути к файлам при этом должны быть доступны учётной записи службы сервера.