Загрузка файла в хранилище значения на управляемых формах
Загрузка файла в хранилище значений через управляемые формы осложняется тем, что реквизит с типом Хранилище значения недоступен в данных формы. То есть работать с ним напрямую не получится.
Начиная с версии 1С:Предприятие 8.3.15, доступна процедура НачатьПомещениеФайлаНаСервер(). Она позволяет с помощью диалога выбрать файл на клиенте и поместить его во Временное хранилище, чтобы потом на сервере поместить файл в Хранилище значения.
Рассмотрим пример работы с этой процедурой.
Во-первых, нам понадобится реквизит управляемой формы АдресВХранилище. Туда будет записан адрес файла во временном хранилище. Этот реквизит мы сможем прочитать и на клиенте, и на сервере.
После этого создаем кнопку, команду и процедуру НаКлиенте, которую вызывает эта кнопка (кнопку можно заменить на другой элемент управления). В процедуре размещаем следующий код:
Процедура ЗагрузитьПодпись ( Команда )
Фильтр = «Все картинки (*.bmp;*.dib;*.rle;*.jpg;*.jpeg;*.tif;*.gif;*.png;*.ico;*.wmf;*.emf)|*.bmp;*.dib;*.rle;*.jpg;*.jpeg;*.tif;*.gif;*.png;*.ico;*.wmf;*.emf|»
+ «Формат bmp (*.bmp;*.dib;*.rle)|*.bmp;*.dib;*.rle|»
+ «Формат JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|»
+ «Формат TIFF (*.tif)|*.tif|»
+ «Формат GIF (*.gif)|*.gif|»
+ «Формат PNG (*.png)|*.png|»
+ «Формат icon (*.ico)|*.ico|»
+ «Формат метафайл (*.wmf;*.emf)|*.wmf;*.emf|» ;
Диалог = новый ПараметрыДиалогаПомещенияФайлов ( «Выберите файл с подписью» , Ложь , Фильтр ) ;
Оповещение = новый ОписаниеОповещения ( «ПослеЗакрытияДиалогаВыбораПодписи» , ЭтаФорма ) ;
НачатьПомещениеФайлаНаСервер ( Оповещение , , , , Диалог , УникальныйИдентификатор ) ;
КонецПроцедуры
Здесь мы задали фильтр на тип (расширение) файла, в данном случае выбираем картинки всевозможных форматов. После этого создали Диалог помещения файла, где указали заголовок диалогового окна, запретили множественный выбор (второй параметр — Ложь) и установили заранее подготовленный фильтр. Далее создаем Описание оповещения, которое указывает на процедуру в модуле данной формы, которая будет вызвана после помещения файла во временное хранилище. При желании можно отдельными описаниями оповещения указать процедуры, которые будут вызываться в ходе выполнения помещения файла во временное хранилище, а также непосредственно перед помещением.
И, наконец, начинаем помещение файла на сервер. При этом вызывается диалоговое окно выбора файла с теми параметрами, которые мы указали.
Теперь создадим процедуру, которую будем вызывать после завершения помещения файла во временное хранилище:
v8: Хранение в хранилище обработок и файлов. Определение типа хранимого файла

К сожалению, 1С не позволяет хранить обработки и отчеты в переменных типа «Хранилище».
Приходится извращаться. Код основан на типовых конфигурациях (не мое изобретение).
Для начала рассмотрим две функции по сохранению файла в переменную хранилища и извлечения этого файла из хранилища.
//Сохраняет файл в хранилище значений Функция обФайлВХранилищеЗначений(ИмяФайла, СтепеньСжатия=9) Экспорт Попытка ОбъектДляХранилища = Новый ДвоичныеДанные(ИмяФайла); Исключение ВызватьИсключение "Не удалось загрузить файл:"+ИмяФайла; Возврат Неопределено; КонецПопытки; ФайлХранилище = Новый ХранилищеЗначения(ОбъектДляХранилища, Новый СжатиеДанных(9)); Возврат ФайлХранилище; КонецФункции //Распаковывает хранилище во временный файл и вовращает его имя Функция обФайлИзХранилищаЗначений(Хранилище, ПолноеИмяФайла=Неопределено, Расширение=Неопределено) Экспорт ХранимоеЗначение=Хранилище.Получить(); Если ХранимоеЗначение=Неопределено Тогда ВызватьИсключение "В хранилище пустое значение!"; КонецЕсли; Если ТипЗнч(ХранимоеЗначение)<>Тип("ДвоичныеДанные") Тогда ВызватьИсключение "В хранилище не хранится двоичный файл!"; Возврат Неопределено; КонецЕсли; Если ПолноеИмяФайла=Неопределено Тогда ВремФайл = ПолучитьИмяВременногоФайла(Расширение); Иначе Ф=Новый Файл(ПолноеИмяФайла); Если Ф.Существует() Тогда УдалитьФайлы(ПолноеИмяФайла); КонецЕсли; ВремФайл = ПолноеИмяФайла; КонецЕсли; ХранимоеЗначение.Записать(ВремФайл); Возврат ВремФайл; КонецФункции
Теперь методика сохранения обработок в хранилище понятна — используем временный файл, распаковываем в него обработку и запускаем внешнюю обработку.
Вот код:
//fixin 20061006 Для сохранения внешних обработок в хранилище значений Функция обВнешняяОбработкаИзХранилищаЗначений(Хранилище) Экспорт ХранимоеЗначение=Хранилище.Получить(); Если ХранимоеЗначение=Неопределено Тогда Сообщить("В хранилище пустое значение!"); Возврат Неопределено; КонецЕсли; Если ТипЗнч(ХранимоеЗначение)<>Тип("ДвоичныеДанные") Тогда Сообщить("В хранилище не хранится двоичный файл!"); Возврат Неопределено; КонецЕсли; ВремФайлВнешнегоОтчета = ПолучитьИмяВременногоФайла(); Попытка ХранимоеЗначение.Записать(ВремФайлВнешнегоОтчета); ВнешняяОбработка=ВнешниеОбработки.Создать(ВремФайлВнешнегоОтчета); Возврат ВнешняяОбработка; Исключение ОписаниеОшибки=ОписаниеОшибки(); Сообщить("При чтении файла обработки произошла ошибка: "+ОписаниеОшибки); КонецПопытки; Возврат Неопределено; КонецФункции //fixin 20061006 Для сохранения внешних обработок в хранилище значений Функция обВнешняяОбработкаВХранилищеЗначений(ИмяФайла, СтепеньСжатия=9) Экспорт Попытка ОбъектДляХранилища = Новый ДвоичныеДанные(ИмяФайла); Исключение Сообщить("Не удалось загрузить внешний отчет!"); Возврат Неопределено; КонецПопытки; ФайлХранилище = Новый ХранилищеЗначения(ОбъектДляХранилища, Новый СжатиеДанных(9)); Возврат ФайлХранилище; КонецФункции
Buran:
На одном из внедрений надо было вместе с обработками подключать справку по программе непосредственно к форме, также другие действия, связанные именно с открытой формой. Поэтому в хранилище находились и обработки и файлы других типов. Но типовые конфигурации старых редакций не позволяли хранить имя(и расширение файла).
Поэтому тип файла в хранилище мы определяли по «сигнатуре»(характерному набору байтов в заголовке).
Вот пример:
// Проверка сигнатур ФайлОбработки = Новый ТекстовыйДокумент; ФайлОбработки.Прочитать(ИмяФайла, КодировкаТекста.ANSI); ЗаголовокФайла = ФайлОбработки.ПолучитьСтроку(1); СигнатураОбработки = Строка(Символ(1103)+Символ(1103)+Символ(1103)+Символ(127)+Символ(0)+Символ(2)+Символ(0)); СигнатураSWF = Строка(Символ(70)+Символ(87)+Символ(83)+Символ(5)); //. Если Найти(ЗаголовокФайла,СигнатураОбработки)=1 Тогда Попытка Форма = ВнешниеОбработки.Создать(ИмяФайла).ПолучитьФорму(); Если НЕ ФормаВладелец = "" И ТипЗнч(ФормаВладелец) = Тип("Форма") Тогда Форма.ВладелецФормы = ФормаВладелец; КонецЕсли; Форма.Открыть(); Возврат Форма; Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; ИначеЕсли Найти(ЗаголовокФайла,СигнатураSWF)=1 Тогда ИмяФайла = КаталогВременныхФайлов() + "1c_help.swf"; Попытка ДвоичныеДанные = ХранилищеВнешнейОбработки.Получить(); ДвоичныеДанные.Записать(ИмяФайла); Форма = ПолучитьФорму("Демо"); Форма.ЭлементыФормы.ПолеHTMLДокумента1.Перейти(ИмяФайла); Форма.Открыть(); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; // ИначеЕсли. Иначе Сообщить("Неизвестный формат файла"); Возврат Неопределено; КонецЕсли;
Развить это решение можно например включением поиска по регулярным выражениям В 1С есть возможность искать строки вида «Ив*нов*», *-любой символ)
От Гения1С:
Для того, чтобы хранить не только сам файл, но и его описание (имя, расширение и т.п.) можно попробовать (за результат правда не ручаюсь), использовать примерно такой код:
Стр=Новый Структура(); Стр.Вставить("ДвоичныеДанные",ДвоичныеДанные); Стр.Вставить("ИмяФайла",ИмяФайла); Стр.Вставить("Расширение",Расширение); Возврат Новый ХранилищеЗначения(Стр);
Т.е. хранить не просто файл, а структуру, которая описывает и включает файл. Правда нужно проверить, сумеет ли 1С упаковать в хранилище подобную струтуру!
Сохранение и восстановление данных в Хранилище значений.
Хранилище значений — это тип, который появился в 8-ой версии 1С позволяющий сохранять прямо в базе различные данные, включая двоичные данные (произвольные файлы). Например, так можно хранить в базе данных JPG-картинки, Word-документы и т.д. Причем данные будут храниться в самой базе (файле 1CD или в таблицах на SQL-сервере) и будут включены в штатную выгрузку базы или резервную копию средствами SQL Server.
Тип Хранилище значения может быть назначен реквизиту справочника, документа, ресурсу регистра сведений и т.д.
//Изображение, картинки (фотки):
ТекИзображение.Объект = СпрТкани.Ссылка;
ТекИзображение.ВидДанных = Перечисления.ВидыДополнительнойИнформацииОбъектов.Изображение;
Хранилище = Новый ХранилищеЗначения(НоваяКартинка, Новый СжатиеДанных());
ТекИзображение.Хранилище = Хранилище.Получить();
// в этом месте он все выводит .
ЭлементыФормы.ПолеКартинки1.Картинка = Хранилище.Получить();
ТекИзображение.Записать();
//Табличный документ:
Процедура СохранитьВХранилищеНажатие(Элемент)
ТабДок=Новый ТабличныйДокумент;
ТабДок.Вывести(ЭлементыФормы.ПолеТабличногоДокумента1);
Хранилище=Новый ХранилищеЗначения(ТабДок);
Записать();
КонецПроцедуры
Процедура ВосстановитьИзХранилищаНажатие(Элемент)
ТабДок=Хранилище.Получить();
Если ТабДок<>Неопределено Тогда
ЭлементыФормы.ПолеТабличногоДокумента1.Вывести(ТабДок);
КонецЕсли;
КонецПроцедуры
//Произвольные файлы (двоичные данные):
ХЗ = Новый ХранилищеЗначения(Новый ДвоичныеДанные(файл));
Восьмерка поддерживает сжатие данных, помещаемых в хранилище:
ХЗ = Новый ХранилищеЗначения(Новый ДвоичныеДанные(файл),Новый СжатиеДанных(9));
//Внешние обработки и отчеты:
Процедура ЗагрузитьОбработкуВХранилище(РеквизитТипХранилище)
СтепеньСжатия = Новый СжатиеДанных(9); //9 максимум
РеквизитТипХранилище = Новый ХранилищеЗначения(Новый ДвоичныеДанные("c:\отчеты\отчет.epf", СтепеньСжатия));
КонецПроцедуры
Процедура ЗапуститьОбработкуИзХранилища(РеквизитТипХранилище)
ИмяВременногоФайла = КаталогВременныхФайлов()+"отчет.epf";
ДвоичныеДанные = РеквизитТипХранилище.Получить();
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяВременногоФайла);
ВнешняяОбработка.ПолучитьФорму().Открыть();
КонецПроцедуры
Если это были ДвоичныеДанные, то их можно восстановить из хранилища значения методом Получить и записать в файл методом Записать().

Если ТипЗнч(Хранилище) <> Тип("ДвоичныеДанные") Тогда
ДвоичныеДанные = Хранилище.Получить();
Иначе
ДвоичныеДанные = Хранилище;
КонецЕсли;
ДвоичныеДанные.Записать(ИмяФайла);
Если это был, например, Word-документ (doc-файл, или другой файл зарегистрированного типа), то его можно открыть так:
ЗапуститьПриложение(ИмяФайла);
Чтобы очистить поле типа Хранилище значения, нужно присвоить ему Неопределено:
Код 1C v 8.х
РеквизитХранилище = Неопределено;
Если в Хранилище значений содержались какие-то ссылки, то они не будут контролироваться при контроле ссылочной целостности (операция Удаление помеченных объектов или метод НайтиПоСсылкам).
К сожалению, 1С не содержит встроенных методов для проверки того, заполнено хранилище или нет.
Такой вариант не работает:
Код 1C v 8.х
фл=Хранилище<>Неопределено;
Работает только такой вариант:
Код 1C v 8.х
фл=Хранилище.Получить()<>Неопределено;
Но он требует затрат времени на извлечение данных из хранилища.
Поэтому, если это критично, нужно заводить еще один флаг, который указывает, содержит ли хранилище значение.
Загрузить файл в хранилище значений
Здравствуйте, пытаюсь загрузить файл в хранилище 1с
нашел справочник — Файлы, там по кнопочке создать вылезает диалог выбора, выбираем файл и все.
Пытаюсь программно это дело сделать и ошибки нет,но и ничего не записывает.
Код такой
//Загружаем файл в справочник файлы файл = Новый ЧтениеТекста(НовыйПутьКфайлу); Знч = Новый ТаблицаЗначений(); текстданные= файл.Прочитать(); Хранилище = Новый ХранилищеЗначения(Знч, Новый СжатиеДанных(9)); КопияФайла = Справочники.Файлы.СоздатьЭлемент(); КопияФайла.ТекстХранилище = Хранилище; КопияФайла.Записать();
Чего возможно не хватает?
По теме из базы знаний
- Файловые базы *.1CD. Физическая структура. Восстановление.
- Работа с файлами в 8.3
- Работа с файлами в управляемых формах клиент серверной версии 8.3 и выше
- Работа с файлами (обычная и управляемая форма)
- Наука о чеках. Глава 2. Обработка для просмотра структуры и значений параметров кассовых чеков в json-файле
Найденные решения
10. bulas 211 14.04.17 11:13 Сейчас в теме
ПутьКФайлу = "D:\Test.xlsx"; ДФайл = Новый ДвоичныеДанные(ПутьКФайлу); ХЗ = Новый ХранилищеЗначения(ДФайл); ХЗ.Записать(); КонецПроцедуры
cleaner_it; + 1 – Ответить
Остальные ответы
- Дата
- Дата
- Рейтинг всех уровней
- Рейтинг 1-го уровня
- Древо развёрнутое
- Древо свернутое
Свернуть все
2. spacecraft 04.10.16 17:10 Сейчас в теме
(1) Гость, если код разобрать своими словами:
1. Создаем объект для чтения текста из файла;
2. Создаем таблицу значений (пустую);
3. читаем текст в переменную «текстданные»;
4. создаем хранилище на основании пустой таблицы значений;
5. Создаем элемент справочника Файлы;
6. Помещаем в реквизит элемента справочника созданное ранее хранилище значений;
7. Записываем элемент справочника;
Как вариант, возможно ошибка в логике 4 пункта.
Это решение
7. корум 287 06.10.16 11:00 Сейчас в теме
Хранилище = Новый ХранилищеЗначения(текстданные, Новый СжатиеДанных(9));
Это решение
8. user606894_schana1w3 06.10.16 12:22 Сейчас в теме
Это решение
11. ResetAtreides 14.04.17 11:47 Сейчас в теме
(1) А вы там с хранилищем не зря заморачиваетесь? Судя по названию реквизита КопияФайла. ТекстХранилище там текст ожидается. Как вообще определяете, что ничего не записалось?
Это решение
3. Гость 05.10.16 11:06
Окей, пытаюсь сделать немножко подругому. нашел функцию которая загружает файл и читает и т.д
обработка = Справочники.Файлы.ПолучитьФорму("Файлы"); обработка.Открыть(); Файл = Новый ЧтениеТекста(НовыйПутьКфайлу); ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Свойство(файл); ПараметрыВыполнения.Вставить(файл); ФайлКлиента = Новый Файл(ПараметрыВыполнения); обработка.ДобавитьИзФайловойСистемыСРасширениемСинхронно(ПараметрыВыполнения); Обработка.Закрыть();
это сама функция — ДобавитьИзФайловойСистемыСРасширениемСинхронно(ПараметрыВыполнения)
Правильно вообще ее вызываю?тоесть из внешней обработки обратиться к функции которая в форме справочника.
пишет ошибку : Метод объекта не обнаружен (ДобавитьИзФайловойСистемыСРасширениемСинхронно)
Это решение
4. Гость 05.10.16 11:39
Даже не так, функция находится в общем модуле.написал так. — РаботаСФайламиСлужебныйКлиент.ДобавитьИзФайловойСистемыСРасширениемСинхронно(ПараметрыВыполнения);так называется общий модуль — РаботаСФайламиСлужебныйКлиентошибка — Переменная не определена (РаботаСФайламиСлужебныйКлиент)
Это решение
5. DrBlack 23 05.10.16 14:24 Сейчас в теме
Надо было так:
файл = Новый ЧтениеТекста(НовыйПутьКфайлу); текстданные= файл.Прочитать(); Хранилище = Новый ХранилищеЗначения(текстданные, Новый СжатиеДанных(9)); КопияФайла = Справочники.Файлы.СоздатьЭлемент(); КопияФайла.ТекстХранилище = Хранилище; КопияФайла.Записать();
Это решение
6. user606894_schana1w3 06.10.16 10:32 Сейчас в теме
Не не вариант, создает пустую запись, тоесть пустой файл без данных, нет чтения, надо процедуру вызывать.
И еще такой вопрос не по теме, можно ли файл xlsx(xml) загрузить в таблицу значений? там же получается если в файле есть такая хрень как объединение строк, и как ее там потом передавать в тз.
Это решение
9. user606894_schana1w3 03.04.17 17:16 Сейчас в теме
А как реализовать такую штучку с нуля? тобишь пустая конфигурация и нужно по кнопочке или по реквизиту загружать файл в хранилище значений.
Это решение
10. bulas 211 14.04.17 11:13 Сейчас в теме
ПутьКФайлу = "D:\Test.xlsx"; ДФайл = Новый ДвоичныеДанные(ПутьКФайлу); ХЗ = Новый ХранилищеЗначения(ДФайл); ХЗ.Записать(); КонецПроцедуры
