Работа с электронным документооборотом (ЭДО) в 1С часто требует от разработчика не просто видеть документ в интерфейсе, но и программно извлекать из него данные. Например, для автоматического заполнения документов «Поступление товаров и услуг» на основании входящих XML-файлов. В этой статье мы разберем, где именно хранятся файлы ЭДО, как их правильно извлечь из базы данных и как расшифровать их содержимое с помощью механизмов XDTO.
В современных конфигурациях 1С (использующих Библиотеку стандартных подсистем — БСП) файлы не хранятся напрямую в реквизитах документов. Даже если вы нашли справочник ЭДПрисоединенныеФайлы, обращение к его реквизитам вроде ФайлХранилище или ТекстХранилища часто может вернуть Неопределено или пустую строку. Это происходит потому, что система оптимизирует хранение данных.
Проанализируем структуру хранения:
Файл, которое ссылается на элемент справочника присоединенных файлов.Рассмотрим ситуацию, когда у нас есть ссылка на файл или на его владельца (например, электронный документ). Чтобы получить содержимое файла для дальнейшей обработки, мы можем воспользоваться запросом к регистру сведений. Разберем пример кода, который позволяет выгрузить данные во временный файл на диске:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДвоичныеДанныеФайлов.ДвоичныеДанныеФайла КАК Данные
|ИЗ
| РегистрСведений.ДвоичныеДанныеФайлов КАК ДвоичныеДанныеФайлов
|ГДЕ
| ДвоичныеДанныеФайлов.Файл = &СсылкаНаФайл";
Запрос.УстановитьПараметр("СсылкаНаФайл", СсылкаНаПрисоединенныйФайл);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
// Получаем ХранилищеЗначения и извлекаем ДвоичныеДанные
ДвоичныеДанные = Выборка.Данные.Получить();
Если ТипЗнч(ДвоичныеДанные) = Тип("ДвоичныеДанные") Тогда
ПутьКФайлу = "C:\temp\document.xml";
ДвоичныеДанные.Записать(ПутьКФайлу);
Сообщить("Файл успешно сохранен: " + ПутьКФайлу);
КонецЕсли;
КонецЕсли;
Если же мы работаем через объектную модель (например, в модуле менеджера), можно использовать метод Получить() напрямую из менеджера регистра сведений, предварительно подготовив структуру отбора по ключевому полю Файл.
Важно понимать, что один электронный документ (УПД или Счет-фактура) в ЭДО — это не один файл, а целый пакет (транспортный контейнер). В нем могут находиться:
Если вы попытаетесь прочитать «первый попавшийся» файл из владельца, вы рискуете получить служебное сообщение, в котором нет данных о номенклатуре. Выясним причину: служебные файлы также регистрируются в справочнике присоединенных файлов. Чтобы найти основной файл УПД, нужно анализировать имя файла (оно обычно начинается с ON_NSCHFDOPPR или ON_SCHFDOPPR) или проверять тип содержимого в метаданных электронного документа.
После того как мы получили ДвоичныеДанные нужного XML-файла, их необходимо преобразовать в структуру, с которой удобно работать в коде 1С. Для этого лучше всего подходит механизм XDTO. Рассмотрим, как прочитать XML без предварительного сохранения на диск:
// 1. Преобразуем двоичные данные в строку XML (учитываем кодировку, обычно UTF-8)
СтрокаXML = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные);
// 2. Используем ЧтениеXML для разбора строки
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
// 3. Читаем данные через фабрику XDTO
// Можно использовать системную ФабрикаXDTO или создать свою на основе схемы
Попытка
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
// Теперь мы можем обращаться к свойствам объекта, например, к табличной части
// Структура зависит от версии формата ФНС (5.01, 5.02 и т.д.)
Для Каждого СтрокаТовара Из ОбъектXDTO.Документ.ТаблЧасть Цикл
Наименование = СтрокаТовара.НаимТов;
Количество = СтрокаТовара.КолТов;
Цена = СтрокаТовара.ЦенаТов;
Сообщить("Обработка товара: " + Наименование + " в количестве " + Количество);
КонецЦикла;
Исключение
Сообщить("Ошибка при разборе XML: " + ОписаниеОшибки());
КонецПопытки;
Если ваша конфигурация построена на БСП (УТ 11, БП 3.0, ERP), рекомендуется избегать прямых запросов к регистру ДвоичныеДанныеФайлов. Вместо этого лучше использовать функции общего модуля РаботаСФайлами. Это обеспечит корректную работу кода даже в том случае, если файлы перенесены в тома на диске. При необходимости быстро извлечь файлы объектов БСП вручную можно использовать обработку для выгрузки прикрепленных файлов.
Пример использования БСП:
// Получение двоичных данных через штатный механизм БСП
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
Если ДвоичныеДанные <> Неопределено Тогда
// Дальнейшая логика обработки
КонецЕсли;
Резюмируем: для успешного извлечения данных из ЭДО мы должны сначала определить владельца файла, найти среди присоединенных файлов именно основной XML-документ (игнорируя подписи и извещения), получить его содержимое из регистра ДвоичныеДанныеФайлов и десериализовать его с помощью ФабрикиXDTO. Такой подход позволяет автоматизировать обработку любых входящих электронных документов независимо от их сложности. Для автоматической обработки и пакетного обмена такими файлами без написания собственного кода можно использовать готовое решение для групповой выгрузки и загрузки XML-файлов ЭДО.