Как программно получить файлы и их содержимое из 1С:Документооборот в 1С:Бухгалтерию?

Программист 1С v8.3 (Управляемые формы) 1С:Документооборот IT и автоматизация бизнеса
← На главную

Интеграция между конфигурациями «1С:Бухгалтерия» (БП) и «1С:Документооборот» (ДО) — распространенная задача. Часто возникает потребность не просто видеть карточку документа, но и программно скачивать прикрепленные файлы (например, сканы договоров или счетов) для сохранения их локально или обработки на стороне бухгалтерской системы. В некоторых случаях может потребоваться полная выгрузка данных в автономное дерево HTML для ознакомления с архивом вне системы 1С.

В этой статье мы подробно разберем, как получить данные из справочника Файлы и само содержимое файла (двоичные данные), используя стандартные механизмы веб-сервисов (DMService), а также рассмотрим альтернативный подход с созданием собственного HTTP-сервиса.

Способ 1. Использование стандартного веб-сервиса DMService

Основной способ взаимодействия с 1С:Документооборот — использование SOAP веб-сервиса DMService. Этот метод является стандартным для большинства типовых интеграций.

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

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


// Функция возвращает список файлов (XDTO) по объекту-владельцу из ДО
Функция ФайлыПоВладельцу(ИдентификаторВладельца, ИмяВладельца, ТипВладельца, ВключатьПомеченныеНаУдаление = Ложь) Экспорт
	
    // Получаем прокси (предполагается, что настройки соединения уже заданы в базе)
	Прокси = ИнтеграцияС1СДокументооборотБазоваяФункциональностьПовтИсп.ПолучитьПрокси();
	
    // Создаем запрос специального типа DMGetFileListByOwnerRequest
	Запрос = ИнтеграцияС1СДокументооборотБазоваяФункциональность.СоздатьОбъект(Прокси, "DMGetFileListByOwnerRequest");
	
    ПолучаемыеПоля = Запрос.columnSet; // Сюда мы добавим нужные нам поля
	Владельцы = Запрос.owners; 
	
    // Формируем объект-владельца (например, Внутренний документ)
	ОбъектВладелец = ИнтеграцияС1СДокументооборотБазоваяФункциональность.СоздатьОбъект(Прокси, "DMObject");
	ОбъектВладелец.name = ИмяВладельца;
	ОбъектВладелец.objectID = ИнтеграцияС1СДокументооборотБазоваяФункциональность.СоздатьObjectID(
		Прокси,
		Строка(ИдентификаторВладельца),
		ТипВладельца);
	
	Владельцы.Добавить(ОбъектВладелец);
	
    // Явно указываем, какие поля хотим вернуть
	ПолучаемыеПоля.Добавить("objectID");
	ПолучаемыеПоля.Добавить("name");        // Имя файла
	ПолучаемыеПоля.Добавить("size");        // Размер
	ПолучаемыеПоля.Добавить("extension");   // Расширение
	ПолучаемыеПоля.Добавить("modificationDateUniversal");
    
	// Самое важное: запрашиваем двоичные данные файла
	ПолучаемыеПоля.Добавить("binaryData");
	
	Если ВключатьПомеченныеНаУдаление Тогда
		Запрос.ignoreDeletionMark = Истина;
		ПолучаемыеПоля.Добавить("deletionMark");
	КонецЕсли;
	
    // Выполняем запрос к веб-сервису
	Файлы = ИнтеграцияС1СДокументооборотБазоваяФункциональность.ВыполнитьЗапрос(Прокси, Запрос);
	
    // Проверяем на ошибки
    ИнтеграцияС1СДокументооборотБазоваяФункциональность.ПроверитьВозвратВебСервиса(Прокси, Файлы);
	
	Возврат Файлы;
	
КонецФункции

Важные нюансы данного метода:

  1. Используйте тип запроса DMGetFileListByOwnerRequest, а не общий DMGetObjectListRequest, если вам нужны именно файлы, привязанные к документу.
  2. Если при получении файлов вам требуется привести их к единому стандарту, может быть полезна автоматическая конвертация doc в docx, которую можно настроить на стороне ДО.
  3. Для работы с полями используется свойство columnSet. Если вы попытаетесь обратиться к полям, которые не добавили в columnSet, они будут пустыми.

Способ 2. Собственный HTTP-сервис (для сложных случаев)

Иногда штатный механизм слишком громоздок или медленен. Например, если файлы попадают в систему через обработчик бизнес-события поступления почты и вам нужна сложная логика выборки по ИНН контрагента. В этом случае на стороне ДО создается свой HTTP-сервис.

Рассмотрим пример реализации метода GET, который принимает ИНН и возвращает JSON со списком файлов.

Код HTTP-сервиса на стороне ДО:


Функция ПолучитьФайлыGET(Запрос) 
    
    Попытка
        Ответ = Новый HTTPСервисОтвет(200);
        ИНН = Запрос.ПараметрыURL["inn"]; // Читаем параметр из URL
        
        // Получаем JSON строку с данными
        СтрокаJSON = ПолучитьФайлыПоИНН(ИНН);
        
        Ответ.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.Использовать);
    Исключение
        Ответ = Новый HTTPСервисОтвет(404);
        ТекстСообщения = СтрШаблон(НСтр("ru = 'Ошибка метода: %1'"), ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        Ответ.УстановитьТелоИзСтроки(ТекстСообщения);
    КонецПопытки;
    
    Возврат Ответ; 
    
КонецФункции

Вспомогательная функция ПолучитьФайлыПоИНН выполняет запрос к базе данных ДО, обращаясь к таблицам Справочник.ВнутренниеДокументы и Справочник.Файлы.


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

Преимущества этого подхода:

Рекомендации по оптимизации

  1. Разделяйте данные и метаданные. Не запрашивайте binaryData для списка из 100 файлов. Лучше сначала получить список ID и имен, а затем скачивать контент только для выбранного файла.
  2. Карточка файла vs Версия. Помните, что в ДО есть справочник Файлы (карточка) и ВерсииФайлов. Двоичные данные хранятся именно в версиях. При использовании запросов 1С обращайтесь к реквизитам ТекущаяВерсия....
  3. MTOM. Если вы используете стандартный веб-сервис и передаете файлы, убедитесь, что в настройках веб-сервера и клиента включена поддержка MTOM. Это позволит передавать бинарные данные эффективнее, чем просто Base64 строка внутри XML.
← На главную