Файлы внутри информационной базы: загрузка, хранение и выгрузка обратно

· 10 мин

Содержание

Сохранить файл в базу 1С можно двумя путями. В типовой конфигурации (БП 3.0, ЗУП 3.1, УТ 11) откройте документ или карточку и нажмите кнопку со скрепкой — «Присоединенные файлы»: файл ляжет в базу или в том на диске, в зависимости от настроек. В своей разработке файл кладут в реквизит типа ХранилищеЗначения: на клиенте помещают его во временное хранилище, а на сервере записывают в объект.

Где в 1С живут файлы: ХранилищеЗначения, тома и справочники вложений

Платформа 1С:Предприятие 8.3 не имеет отдельного типа «файл». Файл в базе — это двоичные данные, упакованные в значение одного из типов:

  • 📦 ХранилищеЗначения — единственный тип реквизита, который можно записать в базу вместе с содержимым файла. Внутри лежит любое сериализуемое значение, чаще всего ДвоичныеДанные. Поддерживает сжатие.
  • 🧩 ДвоичныеДанные — содержимое файла в памяти. В реквизит объекта напрямую не записывается, это рабочий тип для кода.
  • 🔗 Строка с путём — в базе хранится только путь к файлу на сетевом диске. Сам файл живёт снаружи.

Типовые конфигурации построены на Библиотеке стандартных подсистем (БСП). В ней есть подсистема «Работа с файлами». Для каждого владельца, у которого есть вложения, заведён свой справочник: например, у документа реализации это справочник с именем вида РеализацияТоваровУслугПрисоединенныеФайлы. Каждый элемент — один файл с именем, расширением, автором, размером и историей версий.

СпособГде лежит содержимоеКогда подходит
Реквизит ХранилищеЗначенияВ таблице базыСвои справочники, мелкие файлы, нужна целостность с объектом
Присоединённые файлы БСП в базеВ таблице базыТиповые конфигурации, небольшой объём вложений
Присоединённые файлы БСП в томахКаталог на диске, в базе — ссылкаСканы, договоры, тысячи файлов
Строка с путёмСетевая папкаФайлы уже лежат в общем архиве и меняются вне 1С

Как сохранить файл в базу 1С через типовой интерфейс

Этот способ не требует конфигуратора. Работает в БП 3.0, ЗУП 3.1, УТ 11 и других конфигурациях на БСП.

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

Файл можно просто перетащить мышью из проводника в список присоединённых файлов. В тонком клиенте под Windows это быстрее диалога выбора.

Где включаются тома хранения

По умолчанию файлы кладутся внутрь информационной базы. Перенести их на диск может администратор: в разделе Администрирование → Общие настройки есть блок работы с файлами. Там включается флажок хранения файлов в томах на диске, задаются сами тома (каталоги) и максимальный размер загружаемого файла.

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

Каталог тома должен быть доступен на запись той учётной записи, от имени которой работает сервер 1С (в клиент-серверном варианте) или пользователь (в файловом). Иначе загрузка закончится ошибкой доступа.

Как загрузить файл в базу 1С программно

Задача: у справочника Документы есть реквизиты Файл (тип ХранилищеЗначения), ИмяФайла (строка) и РазмерФайла (число). Нужна кнопка «Загрузить» на форме элемента.

Главный приём, о котором спотыкаются новички: реквизит типа ХранилищеЗначения не передаётся в данные формы. В Объект.Файл на клиенте ничего не записать. Файл передают через временное хранилище, а в реквизит пишут в ПередЗаписьюНаСервере, где доступен настоящий объект.

На форме создайте реквизит формы АдресФайла (строка) и команду ЗагрузитьФайл. Модуль формы:

&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
	Оповещение = Новый ОписаниеОповещения("ЗагрузитьФайлЗавершение", ЭтотОбъект);
	НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
	Если Не Результат Тогда
		Возврат; // пользователь закрыл диалог
	КонецЕсли;
	АдресФайла = Адрес;
	Объект.ИмяФайла = Новый Файл(ВыбранноеИмяФайла).Имя;
	Модифицированность = Истина;
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
	Если ЗначениеЗаполнено(АдресФайла) Тогда
		ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайла);
		ТекущийОбъект.Файл = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
		ТекущийОбъект.РазмерФайла = ДвоичныеДанные.Размер();
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	Если ЗначениеЗаполнено(АдресФайла) Тогда
		УдалитьИзВременногоХранилища(АдресФайла);
		АдресФайла = "";
	КонецЕсли;
КонецПроцедуры

Что здесь важно:

  • 🔑 УникальныйИдентификатор формы привязывает временное хранилище к форме. Данные живут, пока форма открыта, и не пропадут до записи.
  • 🗜 Новый СжатиеДанных(9) — максимальное сжатие. Для .docx, .pdf, .jpg, .zip выигрыша почти нет: эти форматы уже сжаты. Для .txt, .xml, .csv размер падает в разы.
  • 🧹 Адрес очищается только после успешной записи. Если запись сорвётся, файл не потеряется и пользователь сможет записать ещё раз.

Загрузка без диалога: обработка или регламентное задание

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

&НаСервереБезКонтекста
Процедура ЗагрузитьИзКаталога(ПутьККаталогу)
	НайденныеФайлы = НайтиФайлы(ПутьККаталогу, "*.pdf");
	Для Каждого НайденныйФайл Из НайденныеФайлы Цикл
		Элемент = Справочники.Документы.СоздатьЭлемент();
		Элемент.Наименование = НайденныйФайл.ИмяБезРасширения;
		Элемент.ИмяФайла = НайденныйФайл.Имя;
		ДвоичныеДанные = Новый ДвоичныеДанные(НайденныйФайл.ПолноеИмя);
		Элемент.Файл = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
		Элемент.РазмерФайла = ДвоичныеДанные.Размер();
		Элемент.Записать();
	КонецЦикла;
КонецПроцедуры

Новый ДвоичныеДанные(Путь) на сервере читает диск сервера 1С, а не компьютера пользователя. Путь C:\Users\buh\Desktop\scan.pdf с рабочего места пользователя сервер не увидит. Для общих папок используйте UNC-путь вида \\fileserver\scan\ и дайте права службе сервера 1С.

Загрузка в присоединённые файлы типовой конфигурации

В конфигурациях на БСП не пишите в справочник ...ПрисоединенныеФайлы напрямую — так теряются версии, размер и признак тома. Используйте программный интерфейс подсистемы:

ДвоичныеДанные = Новый ДвоичныеДанные("\\fileserver\scan\Договор_15.pdf");
АдресФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные);

ПараметрыФайла = РаботаСФайлами.ПараметрыДобавленияФайла();
ПараметрыФайла.ВладелецФайлов = ДоговорСсылка;
ПараметрыФайла.ИмяБезРасширения = "Договор_15";
ПараметрыФайла.РасширениеБезТочки = "pdf";

ПрисоединенныйФайл = РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, АдресФайла);

Этот вызов сам решит, класть файл в базу или в том. Состав полей ПараметрыДобавленияФайла сверяйте с описанием общего модуля РаботаСФайлами в вашей версии БСП.

Несколько вложений к одному объекту: табличная часть или отдельный справочник

Один реквизит — один файл. Если к заявке надо приложить три скана, есть два варианта.

Вариант 1. Табличная часть. Создайте у документа табличную часть Вложения с колонками Файл (ХранилищеЗначения), ИмяФайла, РазмерФайла. Загрузка та же, только в ПередЗаписьюНаСервере добавляйте строки в ТекущийОбъект.Вложения.

Вариант 2. Подчинённый справочник. Справочник ФайлыЗаявок с владельцем — документом или реквизитом-ссылкой на него. Каждый файл — отдельный элемент.

КритерийТабличная частьПодчинённый справочник
СложностьМинимальнаяНужен отдельный объект и форма
Открытие документаЧитаются все файлы сразуДокумент лёгкий, файлы — по требованию
Права доступаКак у документаМожно настроить отдельно
Подходит для1–3 небольших файлаМного файлов или крупные сканы

Главный аргумент в пользу справочника — скорость. Когда платформа читает объект, она читает его целиком, включая табличные части с хранилищами. Документ с пятью сканами по 5 МБ при каждом открытии тянет с сервера 25 МБ. Подчинённый справочник этого избегает: форма документа показывает только список имён.

Тот же эффект бывает при обращении через точку: ДокументСсылка.Вложения в коде загружает весь объект. Нужное поле лучше получать запросом.

Как достать сохранённый файл из базы и показать пользователю

Выгрузка — зеркало загрузки: сервер извлекает двоичные данные и кладёт их во временное хранилище, клиент получает файл по адресу.

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

&НаКлиенте
Процедура СохранитьНаДиск(Команда)
	Адрес = АдресФайлаДляВыгрузки();
	Если ПустаяСтрока(Адрес) Тогда
		ПоказатьПредупреждение(, "В элементе нет сохранённого файла.");
		Возврат;
	КонецЕсли;
	ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, Объект.ИмяФайла);
КонецПроцедуры

ФайловаяСистемаКлиент — модуль БСП. В конфигурации без библиотеки используйте платформенный метод НачатьПолучениеФайлов с массивом объектов ОписаниеПередаваемогоФайла.

Показ картинки прямо на форме

Если в хранилище лежит изображение, его не обязательно выгружать. Добавьте на форму реквизит-строку АдресКартинки и поле картинки, связанное с ним. При открытии формы на сервере:

АдресКартинки = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "Файл");

Платформа сама отдаст содержимое реквизита полю картинки. Работает для записанного объекта; у нового элемента ссылки ещё нет.

Размер базы и ограничения: когда файлы лучше вынести

Каждый мегабайт вложений — это мегабайт в базе, в каждой выгрузке .dt и в каждой резервной копии. Скан договора на 2 МБ × 30 договоров в день × 250 рабочих дней = около 15 ГБ в год. База бухгалтерии без вложений часто весит меньше.

Когда пора переходить на тома или внешнее хранение:

  • 📈 вложения занимают заметную долю размера базы, и резервное копирование стало долгим;
  • 🐢 выгрузка в .dt и загрузка копии для тестов занимают больше часа;
  • ☁️ база работает в облаке или по тарифу с ограничением объёма;
  • 🖨 файлы — сканы и фото в высоком разрешении, а не мелкие документы.

Ограничения, которые стоит знать заранее:

  1. Память. Получить() поднимает весь файл в память рабочего процесса. Видеофайл на 1 ГБ в хранилище — плохая идея: сервер будет держать гигабайт на каждый одновременный запрос.
  2. Файловая база. Все файлы оказываются внутри 1Cv8.1CD. Большой файл базы дольше копируется и чаще страдает при сбое питания. Тома снимают эту проблему.
  3. Запросы. По полю ХранилищеЗначения нельзя отбирать, сортировать и группировать. Всё, по чему нужен поиск — имя, размер, дату, — храните в отдельных реквизитах.
  4. Тома и резервные копии. Если файлы в томах, бэкап базы их не содержит. Каталоги томов копируйте отдельно и в то же время, что и базу, иначе после восстановления часть ссылок будет вести в пустоту.
Где хранить файлы в вашем случае?

Частые ошибки при сохранении файлов в базу

  • ❌ Пишут в Объект.Файл на клиенте. Реквизита-хранилища в данных формы нет, запись либо падает с ошибкой, либо молча ничего не сохраняет. Решение — временное хранилище и ПередЗаписьюНаСервере.
  • ❌ Кладут в хранилище путь вместо содержимого. Новый ХранилищеЗначения("C:\scan.pdf") сохранит строку с путём, а не файл. Сначала Новый ДвоичныеДанные(Путь), затем хранилище.
  • ❌ Помещают во временное хранилище без идентификатора формы. Без УникальныйИдентификатор данные могут быть удалены раньше, чем пользователь нажмёт «Записать».
  • ❌ Не сохраняют имя и расширение. Хранилище хранит только байты. Без ИмяФайла при выгрузке непонятно, это .pdf или .xlsx, и ОС не откроет файл нужной программой.
  • ❌ Обновляют типовую конфигурацию после правки справочника вложений. Добавленные в типовой справочник реквизиты конфликтуют при обновлении. Свои реквизиты и формы делайте в расширении конфигурации.

Частые вопросы

Можно ли хранить файл в регистре сведений?
Да. Ресурс или реквизит регистра сведений тоже может иметь тип ХранилищеЗначения. Это удобно для настроек и файлов, привязанных к комбинации измерений, например «организация + вид документа».
Как узнать, сколько места занимают файлы в базе?
В клиент-серверной базе размер таблиц покажет СУБД. В файловой — сравните размер файла 1Cv8.1CD до и после переноса вложений в тома. Для своих справочников храните размер в отдельном реквизите и суммируйте его запросом.
Сохранится ли файл при выгрузке базы в .dt?
Да, если он хранится в базе: реквизиты ХранилищеЗначения попадают в выгрузку. Файлы из томов на диске в .dt не попадают, их копируют отдельно.
Работает ли загрузка файлов в веб-клиенте?
Да. Асинхронные методы НачатьПомещениеФайла и НачатьПолучениеФайлов работают в веб-клиенте. Синхронные методы с модальными диалогами при отключённой модальности использовать нельзя.
Можно ли шифровать файлы внутри базы?
В БСП есть подсистема электронной подписи и шифрования: присоединённый файл можно зашифровать сертификатом. Для своих реквизитов шифрование придётся реализовать вручную через менеджер криптографии до записи в хранилище.