v8: Хранение в хранилище обработок и файлов. Определение типа хранимого файла
Описана методика хранения в хранилище обработок(отчетов) и файлов. | Автор статьи: Гений 1С | Редакторы: Buran Последняя редакция №3 от 19.01.07 | URL: |
Ключевые слова: хранилище,обработка,отчет,файл
К сожалению, 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С упаковать в хранилище подобную струтуру!