Разработка и Конфигурация · 10 мин
Как получить двоичные данные из макета в 1С
Как получить двоичные данные из макета в 1С 8.3: методы ПолучитьМакет, работа с двоичными макетами, временное хранилище, запись файла на диск.
Макеты в конфигурации 1С могут хранить не только табличные документы, но и произвольные файлы: картинки, архивы, XSD-схемы, внешние компоненты. Чтобы программно извлечь такой файл в виде двоичных данных, используется метод ПолучитьМакет(), который для макета типа «Двоичные данные» возвращает объект типа ДвоичныеДанные. Дальше эти данные можно записать на диск, поместить во временное хранилище или передать в другой механизм.
Типичная цепочка выглядит так: в конфигураторе создаётся макет с типом «Двоичные данные», в него загружается файл, а в коде вызывается ПолучитьОбщийМакет("ИмяМакета") или ЭтотОбъект.ПолучитьМакет("ИмяМакета") — в зависимости от того, где лежит макет. Результат уже готов к использованию без дополнительных преобразований.
Важно понимать разницу: если макет имеет тип «Табличный документ» или «Текстовый документ», ПолучитьМакет() вернёт ТабличныйДокумент или ТекстовыйДокумент, и попытка записать его как файл даст ошибку. Двоичные данные возвращаются только для макетов соответствующего типа.
Типы макетов и что возвращает ПолучитьМакет
При создании макета в конфигураторе платформа предлагает выбрать тип: табличный документ, текстовый документ, двоичные данные, схема компоновки данных, макет оформления и другие. Именно тип определяет, что вернёт метод получения макета. Для типа «Двоичные данные» результатом будет объект ДвоичныеДанные — неизменяемый набор байтов, доступный только для чтения и записи в файл.
Чтобы загрузить файл в макет, откройте макет в конфигураторе и используйте команду загрузки из файла (пункт в меню макета или контекстном меню). Платформа сохранит содержимое файла внутри конфигурации, и дальше файл не нужен — данные живут в базе.
Если макет создан с неправильным типом (например, картинку загрузили в табличный документ), получить из него двоичные данные штатно не выйдет. Проверьте тип макета в свойствах и при необходимости пересоздайте макет с типом «Двоичные данные».
Базовый код: получение и запись в файл
Минимальный пример для общего макета выглядит так:
ДвоичныеДанные = ПолучитьОбщийМакет("МояКартинка");
ДвоичныеДанные.Записать("C:\Temp\image.png");
Если макет лежит не в ветке «Общие макеты», а внутри объекта (справочника, документа, обработки), обращение идёт через менеджер объекта или через модуль самого объекта:
// Из модуля объекта обработки
ДвоичныеДанные = ЭтотОбъект.ПолучитьМакет("ШаблонАрхива");
// С сервера через менеджер объекта
ДвоичныеДанные = Справочники.Номенклатура.ПолучитьМакет("Пиктограмма");
Метод Записать() создаёт файл по указанному пути. Если файл существует, он будет перезаписан без предупреждения. Убедитесь, что каталог существует и у процесса (сервера 1С или клиентского сеанса) есть права на запись — иначе получите исключение «Ошибка доступа к файлу».
- 1Создайте макет с типом «Двоичные данные» и загрузите в него файл
- 2Вызовите ПолучитьОбщийМакет() или ПолучитьМакет() в коде
- 3Проверьте тип результата через ТипЗнч() при отладке
- 4Запишите данные методом Записать() или передайте в хранилище
- 5Проверьте размер и содержимое полученного файла
Работа на сервере и передача на клиент
В клиент-серверном режиме макет обычно читается на сервере, а файл нужен пользователю на клиенте. Напрямую передать объект ДвоичныеДанные между сервером и клиентом нельзя — его помещают во временное хранилище:
&НаСервере
Функция ПолучитьАдресМакета()
Данные = ПолучитьОбщийМакет("ОтчетШаблон");
Возврат ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификаторФормы);
КонецФункции
&НаКлиенте
Процедура СохранитьФайл(Команда)
Адрес = ПолучитьАдресМакета();
Данные = ПолучитьИзВременногоХранилища(Адрес);
Данные.Записать("C:\Users\User\Documents\shablon.xlsx");
КонецПроцедуры
Второй параметр ПоместитьВоВременноеХранилище — уникальный идентификатор формы — привязывает данные к времени жизни формы. Без него хранилище очистится после завершения серверного вызова, и на клиенте вы получите пустоту или ошибку.
Для передачи пользователю на скачивание в браузере (тонкий/веб-клиент) используйте ПолучитьФайл(Адрес, ИмяФайла, Истина) вместо прямой записи на диск — у клиента может не быть доступа к файловой системе в интерактивном режиме.
Как проверить, что данные получены корректно
Первый признак успеха — тип возвращаемого значения. В отладчике или через ТипЗнч(Результат) = Тип("ДвоичныеДанные") убедитесь, что получили именно двоичные данные, а не табличный документ. Второй признак — размер: метод Размер() возвращает количество байт, оно должно совпадать с размером исходного файла.
После записи на диск откройте файл штатным приложением: картинка должна отображаться, архив — распаковываться, схема XSD — проходить валидацию. Если файл «битый», чаще всего причина в том, что в макет загрузили не тот файл или макет создан с неверным типом.
Как проверить результат
Тип("ДвоичныеДанные")
ТабличныйДокумент или Неопределено — неверный тип макета или имя
Совпадает с размером исходного файла
0 байт или заметно меньше ожидаемого
Файл открывается штатным приложением
Ошибка формата — данные повреждены или тип макета неверный
Получение двоичных данных из макета другого типа
Иногда файл хранится не в макете типа «Двоичные данные», а, например, в табличном документе (макет печатной формы с картинкой) или в активном документе. Штатного прямого пути нет, но есть обходные варианты: табличный документ можно сохранить во временный файл через Записать(ИмяФайла, ТипФайлаТабличногоДокумента), а затем прочитать как двоичные данные конструктором Новый ДвоичныеДанные(ИмяФайла).
Для картинок из библиотеки картинок платформы объект Картинка тоже умеет преобразовываться: метод ПолучитьДвоичныеДанные() у картинки возвращает нужный объект. Это удобно, когда пиктограмма нужна в виде массива байтов для отправки по HTTP или веб-сервису.
Картинка = БиблиотекаКартинок.Информация;
ДвоичныеДанные = Картинка.ПолучитьДвоичныеДанные();
Размер = ДвоичныеДанные.Размер();Типичные ошибки и ограничения
Самая частая ошибка — обращение к макету по неправильному имени или из неправильного контекста. ПолучитьОбщийМакет() ищет только в общих макетах; для макета объекта нужен менеджер этого объекта. Ошибка «Макет не найден» почти всегда означает опечатку в имени или неверную ветку дерева конфигурации.
Вторая группа проблем — права и контекст исполнения. Запись файла на сервере выполняется под учётной записью агента сервера 1С, а не пользователя. Пути вроде C:\Users\Иванов\... на сервере не существуют. Используйте КаталогВременныхФайлов() или заранее согласованный сетевой каталог.
Третья типичная ситуация — попытка передать ДвоичныеДанные в параметре между клиентом и сервером напрямую. Платформа это запрещает: только через временное хранилище или через файл.
Когда макет — не лучший вариант хранения
Макеты подходят для статичных ресурсов: шаблонов, схем, компонент, которые меняются только вместе с конфигурацией. Если файл должен обновляться пользователями без обновления конфигурации, правильнее хранить его в справочнике с реквизитом типа ХранилищеЗначения или в присоединённых файлах (в типовых конфигурациях — механизм БСП «Работа с файлами»).
Учтите и объём: крупные файлы в макетах раздувают конфигурацию и замедляют обновление. Для файлов в десятки мегабайт макет — плохое решение, лучше внешнее хранилище или каталог на сервере с регламентной доставкой.
Как выбрать действие
Что важно запомнить
Для макета типа «Двоичные данные» ПолучитьМакет/ПолучитьОбщийМакет сразу возвращает объект ДвоичныеДанные. Запись — методом Записать(), передача на клиент — через временное хранилище с привязкой к форме. Проверяйте тип макета, имя и права на каталог записи.
Частые вопросы
Можно ли получить двоичные данные из макета, не записывая файл на диск?
Да. Метод ПолучитьМакет() для макета типа «Двоичные данные» сразу возвращает объект в памяти. Записывать файл нужно только если он требуется сторонней программе или пользователю. Для передачи по HTTP, в веб-сервис или в хранилище значений объект используется напрямую.
Почему ПолучитьОбщийМакет возвращает табличный документ вместо двоичных данных?
Тип возвращаемого значения определяется типом макета в конфигураторе. Откройте свойства макета: если там «Табличный документ», пересоздайте макет с типом «Двоичные данные» и заново загрузите файл. Изменить тип существующего макета штатно нельзя.
Как получить макет обработки на сервере, если код выполняется в модуле формы?
Из модуля формы обработки на сервере используйте РеквизитФормыВЗначение("Объект").ПолучитьМакет("ИмяМакета"). Альтернатива — вынести получение макета в модуль объекта обработки и вызывать оттуда, а в форму возвращать адрес временного хранилища.
Есть ли ограничение на размер макета с двоичными данными?
Жёсткого документированного лимита платформа не задаёт, но на практике большие файлы увеличивают размер конфигурации, замедляют обновление и загрузку. Файлы свыше нескольких мегабайт разумнее хранить вне макетов — в базе через ХранилищеЗначения или во внешнем каталоге.
Как извлечь картинку из макета табличного документа?
Прямого способа нет. Варианты: сохранить табличный документ во временный файл и прочитать его как ДвоичныеДанные, либо заранее хранить картинку отдельным макетом типа «Двоичные данные» и вставлять в табличный документ программно через область рисунка.
Работает ли ПолучитьМакет в фоновом задании?
Да, фоновое задание выполняется на сервере, и чтение макета доступно. Ограничение касается только передачи результата наружу: вернуть ДвоичныеДанные из фонового задания можно через временное хранилище, адрес которого передаётся в параметрах или сохраняется в регистре.