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С упаковать в хранилище подобную струтуру! |