Выгрузка данных в XML-файл средствами встроенного языка 1С 8.3
Содержание
Чтобы сохранить XML в файл в 1С, создайте объект ЗаписьXML, откройте файл методом ОткрытьФайл(ИмяФайла, "UTF-8"), запишите объявление, элементы и атрибуты и обязательно вызовите Закрыть(). Если нужно выгрузить объект базы целиком (документ, элемент справочника, таблицу значений), вместо ручной разметки передайте его в СериализаторXDTO.ЗаписатьXML() — платформа сама построит XML.
Типичная ситуация: контрагент просит прайс в XML, или нужно отдать остатки во внешнюю систему, которая не умеет читать Excel. Обработку пишут за час, а потом файл оказывается пустым, не открывается у получателя или лежит не на том компьютере. Всё описанное относится к платформе 8.3 и не зависит от конфигурации: код одинаково работает в БП 3.0, ЗУП 3.1, УТ 11 и в собственных разработках.
Что подготовить до написания кода
Сначала договоритесь о структуре файла. Получатель обычно присылает пример или XSD-схему: какие элементы, где атрибуты, какой формат дат и чисел. Без этого придётся переделывать выгрузку после первой же попытки загрузки.
Решите три вопроса:
- 📁 Где окажется файл. Код в модуле с директивой
&НаСерверепишет на диск сервера 1С. Пользователь клиент-серверной базы этот файл не увидит. - 🔤 Какая кодировка. По умолчанию
UTF-8. Старые учётные системы иногда ждутwindows-1251. - 🧩 Вручную или сериализацией. Чужой формат — только вручную через
ЗаписьXML. Обмен между базами 1С с одинаковыми объектами — проще через XDTO.
| Способ | Когда подходит | Ограничения |
|---|---|---|
ЗаписьXML вручную | Формат задан получателем, нужен полный контроль над тегами | Больше кода, баланс начала и конца элементов на вас |
СериализаторXDTO | Обмен 1С ↔ 1С, бэкап отдельных объектов, отладка | Структура и имена тегов задаются платформой |
| Обработка «Выгрузка и загрузка данных XML» | Разовая выгрузка без программирования | Только для обмена между базами с одинаковой конфигурацией |
Ручная запись XML в файл через ЗаписьXML
ЗаписьXML — потоковый писатель. Он не держит документ в памяти, а сразу выводит в файл всё, что вы ему передаёте. Поэтому им можно выгружать хоть сто тысяч строк без роста потребления памяти.
Порядок вызовов
Новый ЗаписьXML— создать писатель.ОткрытьФайл(...)— указать путь и кодировку (или объектПараметрыЗаписиXML).ЗаписатьОбъявлениеXML()— строка<?xml version="1.0" encoding="UTF-8"?>. Вызывается первой.ЗаписатьНачалоЭлемента("Имя")— открыть тег.ЗаписатьАтрибут("Имя", Значение)— атрибуты пишутся сразу после начала элемента, до текста и вложенных тегов.ЗаписатьТекст(Строка)— содержимое.ЗаписатьКонецЭлемента()— закрыть тег. Каждому началу — свой конец.Закрыть()— сбросить буфер на диск и освободить файл.
Пример: выгрузка номенклатуры
&НаСервере
Процедура ВыгрузитьНоменклатуруВXML(ИмяФайла)
Параметры = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина); // Истина — с отступами
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, Параметры);
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Каталог");
Запись.ЗаписатьАтрибут("Дата", XMLСтрока(ТекущаяДатаСеанса()));
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа
| И НЕ Номенклатура.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Запись.ЗаписатьНачалоЭлемента("Товар");
Запись.ЗаписатьАтрибут("Ид", XMLСтрока(Выборка.Ссылка));
ЗаписатьПоле(Запись, "Код", СокрЛП(Выборка.Код));
ЗаписатьПоле(Запись, "Наименование", Выборка.Наименование);
Запись.ЗаписатьКонецЭлемента(); // Товар
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // Каталог
Запись.Закрыть();
КонецПроцедуры
&НаСервере
Процедура ЗаписатьПоле(Запись, ИмяЭлемента, Значение)
Запись.ЗаписатьНачалоЭлемента(ИмяЭлемента);
Запись.ЗаписатьТекст(Значение);
Запись.ЗаписатьКонецЭлемента();
КонецПроцедуры
На выходе получится файл такого вида:
<?xml version="1.0" encoding="UTF-8"?>
<Каталог Дата="2026-10-07T14:05:12">
<Товар Ид="5f1c2a90-3b7e-11ef-9c3a-00155d0a1f02">
<Код>00-00000017</Код>
<Наименование>Бумага офисная А4</Наименование>
</Товар>
</Каталог>
Даты, числа, булевы значения и ссылки переводите в текст функцией XMLСтрока(), а не Строка(). Строка(1250.5) даст 1 250,5 с пробелом и запятой — внешняя программа такое число не разберёт. XMLСтрока(1250.5) вернёт 1250.5, дата превратится в 2026-10-07T14:05:12, ссылка — в уникальный идентификатор.
Пространства имён и префиксы
Если получатель требует теги с префиксом, объявите пространство имён сразу после открытия корневого элемента:
Запись.ЗаписатьНачалоЭлемента("Документ", "urn:example:invoice");
Запись.ЗаписатьСоответствиеПространстваИмен("inv", "urn:example:invoice");
Дальше все элементы, открытые с тем же URI вторым параметром, получат префикс inv:.
Сохранение в строку вместо файла
Иногда XML нужен не на диске, а в переменной: для отправки в HTTP-запросе или записи в реквизит. Тогда вместо ОткрытьФайл вызовите Запись.УстановитьСтроку("UTF-8"). Метод Закрыть() в этом случае вернёт готовый текст. Сохранить его в файл потом можно через ЗаписьТекста или Новый ТекстовыйДокумент с методом Записать.
Сериализация объектов 1С через СериализаторXDTO
Когда нужно выгрузить в XML документ или справочник целиком, со всеми реквизитами и табличными частями, писать каждый тег руками бессмысленно. Глобальный объект СериализаторXDTO делает это одной строкой.
&НаСервере
Процедура ВыгрузитьКонтрагентов(ИмяФайла)
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Данные");
Запись.ЗаписатьСоответствиеПространстваИмен("xs", "http://www.w3.org/2001/XMLSchema");
Запись.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
Объект = Выборка.ПолучитьОбъект();
СериализаторXDTO.ЗаписатьXML(Запись, Объект, НазначениеТипаXML.Явное);
КонецЦикла;
Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();
КонецПроцедуры
Объявление префиксов xs и xsi на корневом элементе не обязательно, но без него платформа повторит их в каждом вложенном объекте, и файл распухнет.
Что ещё умеет сериализатор:
- 📋 Таблицы значений.
СериализаторXDTO.ЗаписатьXML(Запись, ТаблицаЗначений)— удобно, чтобы сохранить результат запроса и загрузить его в другой базе без пересборки. - 🗂 Наборы записей регистров — как и объекты, пишутся целиком вместе с отбором.
- 🔁 Обратное чтение.
СериализаторXDTO.ПрочитатьXML(Чтение)восстанавливает значение исходного типа.
Ссылки в сериализованном XML записываются как уникальные идентификаторы. Если в базе-приёмнике нет объекта с тем же идентификатором, после загрузки на его месте окажется «битая» ссылка <Объект не найден>. Выгружайте связанные справочники вместе с документами.
Чтение обратно для проверки
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Чтение.Прочитать(); // встали на корневой элемент «Данные»
Чтение.Прочитать(); // перешли к первому объекту
Пока СериализаторXDTO.ВозможностьЧтенияXML(Чтение) Цикл
Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
// здесь можно сравнить реквизиты или записать объект
КонецЦикла;
Чтение.Закрыть();
Для разовой выгрузки без кода есть универсальная обработка «Выгрузка и загрузка данных XML». Она работает на том же механизме: отметили объекты, указали файл, нажали «Выгрузить». Применяют её для переноса справочников между базами одной конфигурации.
Как передать файл с сервера на компьютер пользователя
Самая частая жалоба: «код отработал, а файла нет». В клиент-серверной базе путь C:\Выгрузка\price.xml в серверной процедуре означает диск сервера 1С. В файловой базе в тонком клиенте серверный код тоже может работать на другой машине, если база опубликована на веб-сервере.
Правильная схема — записать во временный файл на сервере, положить двоичные данные во временное хранилище и отдать пользователю с клиента.
&НаКлиенте
Процедура ВыгрузитьВXML(Команда)
Адрес = СформироватьФайлНаСервере();
ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, "catalog.xml");
КонецПроцедуры
&НаСервере
Функция СформироватьФайлНаСервере()
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
ВыгрузитьНоменклатуруВXML(ИмяВременногоФайла);
Данные = Новый ДвоичныеДанные(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);
Возврат ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
КонецФункции
ФайловаяСистемаКлиент.СохранитьФайл — процедура из Библиотеки стандартных подсистем. Она есть в типовых конфигурациях: БП 3.0, ЗУП 3.1, УТ 11. Пользователь увидит обычный диалог «Сохранить как».
В самописной конфигурации без БСП подойдёт платформенный метод ПолучитьФайл(Адрес, "catalog.xml", Истина). Он синхронный: если в свойствах конфигурации запрещены синхронные вызовы, используйте асинхронный вариант НачатьПолучениеФайлов.
Не удаляйте временный файл до чтения в ДвоичныеДанные и не забывайте удалить его после. На сервере с десятками пользователей забытые временные файлы за месяц занимают гигабайты.
Если сохраняете прямо в каталог
Для регламентного задания, которое кладёт выгрузку в общую папку, клиентская часть не нужна. Проверьте каталог перед записью:
Каталог = Новый Файл("\\fileserver\exchange\");
Если Не Каталог.Существует() Тогда
СоздатьКаталог("\\fileserver\exchange\");
КонецЕсли;
Учтите: на сервере 1С код выполняется от имени учётной записи службы (по умолчанию USR1CV8). У неё должны быть права на запись в эту сетевую папку, а не у пользователя, который нажал кнопку.
Выгрузка табличного документа в XML
Отчёт или печатная форма в 1С — это ТабличныйДокумент. Команда сохранения в интерфейсе предлагает MXL, XLSX, PDF, HTML, DOCX и другие форматы, но обычного XML с вашей структурой среди них нет. Поэтому ячейки обходят кодом и записывают через ЗаписьXML.
Пример: первая строка документа — заголовки колонок, дальше данные.
&НаСервере
Процедура ТабличныйДокументВXML(ТабДок, ИмяФайла)
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина));
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Таблица");
Ширина = ТабДок.ШиринаТаблицы;
Заголовки = Новый Массив;
Для НомерКолонки = 1 По Ширина Цикл
Заголовки.Добавить(ТабДок.Область(1, НомерКолонки, 1, НомерКолонки).Текст);
КонецЦикла;
Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
Запись.ЗаписатьНачалоЭлемента("Строка");
Для НомерКолонки = 1 По Ширина Цикл
Запись.ЗаписатьНачалоЭлемента("Ячейка");
Запись.ЗаписатьАтрибут("Колонка", Заголовки[НомерКолонки - 1]);
Запись.ЗаписатьТекст(ТабДок.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки).Текст);
Запись.ЗаписатьКонецЭлемента();
КонецЦикла;
Запись.ЗаписатьКонецЭлемента();
КонецЦикла;
Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();
КонецПроцедуры
Индекс массива сдвинут на единицу: колонки нумеруются с 1, элементы массива — с 0.
Заголовки колонок вынесены в атрибут, а не в имя тега. Имя элемента XML не может содержать пробелы и начинаться с цифры, а «Сумма с НДС» или «1 квартал» — обычные заголовки отчётов.
Если исходные данные приходят из запроса, выгружайте их напрямую из выборки, а не из готового отчёта. В ячейках табличного документа числа уже отформатированы: 1 250,50 вместо 1250.5, и для XML их придётся разбирать обратно.
Кодировка, BOM и спецсимволы
Какую кодировку выбрать
| Кодировка | Строка в коде | Когда нужна |
|---|---|---|
| UTF-8 | "UTF-8" | По умолчанию, для веб-сервисов, ЭДО, большинства систем |
| Windows-1251 | "windows-1251" | Старые программы, которые не читают Юникод |
| UTF-16 | "UTF-16" | Редко, только по прямому требованию получателя |
Строка объявления encoding="…" формируется автоматически по кодировке, которую вы передали в ОткрытьФайл. Вписывать её вручную через ЗаписатьБезОбработки не нужно: получится расхождение между объявлением и реальными байтами, и кириллица превратится в «кракозябры».
Отдельная история — метка порядка байтов (BOM) в начале UTF-8-файла. Часть внешних парсеров на ней спотыкается. У ОткрытьФайл есть третий параметр, который отвечает за запись этой сигнатуры: передайте Ложь, если получатель требует файл без BOM.
Спецсимволы
Символы <, >, & и кавычки в тексте и атрибутах ЗаписьXML экранирует сам. Наименование «ООО “Рога & Копыта”» запишется корректно, ничего заменять не надо.
Проблема в другом — управляющие символы с кодами от 0 до 31. Они попадают в базу при вставке из PDF или из чужих программ. XML 1.0 их не допускает (кроме табуляции, перевода строки и возврата каретки), и файл потом не прочитает ни 1С, ни внешний парсер. Перед записью почистите строку:
Функция ОчиститьДляXML(Знач Текст)
Для Код = 0 По 31 Цикл
Если Код = 9 Или Код = 10 Или Код = 13 Тогда
Продолжить;
КонецЕсли;
Текст = СтрЗаменить(Текст, Символ(Код), "");
КонецЦикла;
Возврат Текст;
КонецФункции
Если в поле лежит HTML-фрагмент или текст с разметкой, который надо сохранить как есть, используйте ЗаписатьСекциюCDATA(Текст). Только помните: внутри CDATA не может встречаться последовательность ]]>.
Ошибки при сохранении XML и проверка готового файла
Перехват ошибок
Оберните запись в Попытка … Исключение и обязательно закройте файл в обеих ветках. Иначе после ошибки он останется занят процессом 1С, и повторная выгрузка упадёт уже на открытии.
Запись = Новый ЗаписьXML;
Попытка
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
// ... запись данных ...
Запись.Закрыть();
Исключение
Запись.Закрыть();
ЗаписьЖурналаРегистрации("Выгрузка XML", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
Если ошибка случилась ещё до открытия файла, Закрыть() во второй ветке может сам вызвать исключение. Для надёжности его тоже можно обернуть в отдельную Попытку.
Как проверить результат
- Размер.
Новый Файл(ИмяФайла).Размер()больше нуля — минимальная проверка, что запись дошла до диска. - Корректность разметки. Прочитайте файл целиком через
ЧтениеXML. Если разметка битая, методПрочитать()вызовет исключение с номером строки:
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Пока Чтение.Прочитать() Цикл
КонецЦикла;
Чтение.Закрыть();
- Соответствие формату. Если у получателя есть XSD-схема, загрузите её в XDTO-пакет конфигурации и формируйте данные через
ФабрикаXDTO: значения, не подходящие под тип, вызовут ошибку уже при заполнении объекта. Для разовой проверки достаточно открыть файл в любом XML-редакторе с валидацией по схеме. - Глазами. Откройте файл в браузере: он покажет дерево элементов или строку, где ломается разметка.