При внедрении 1С: ДО КОРП 2.1 у одного из заказчиков было принято решение внедрить механизм виртуальной ЭП (электронной подписи) для визуализации наличия подписи (грифа утверждения) в документах.
Работает на релизе 1С: ДО КОРП 2.1.19.22.
1. В шаблон документа doc необходимо вставить тэг "ВставитьФаксимиле".
2. В архиве ECP_Emul.rar макет цифровой подписи в формате png и psd (Adobe Photoshop CC 2019) + файл конфигурации с изменениями.
3. Добавить два общих макета "ШаблонОтметкиПодписано", "ШаблонОтметкиУтверждено".
4. Добавить глобальные модули "ОбщийБизнес" и "ОбщийБизнесКлиент".
5. Добавить в справочник "Файлы" новый реквизит "ПодписанФаксимиле" (тип булево).
6. Доработать глобальные модули "РаботаСКартинками", "РаботаСФайламиКлиент", "РаботаСФайламиВызовСервера". В коде поиск по комментарию "виртуальная цифровая подпись".
В модуль "РаботаСКартинками" добавить функцию:
//виртуальная цифровая подпись
Функция СформироватьЭмуляторПодписи(ОписаниеЭП, МакетСертификат, Формат = "PNG") Экспорт
ФайлыКУдалению = Новый Массив;
ПутьФайлаШаблона = ПолучитьИмяВременногоФайла(Формат);
МакетСертификат.Записать(ПутьФайлаШаблона);
ФайлыКУдалению.Добавить(ПутьФайлаШаблона);
ПараметрыDraw = Новый Массив;
ПараметрыDraw.Добавить(
СтрШаблон(
"text %1, %2 '%3'",
205,
105,
ОписаниеЭП.Фамилия));
ПараметрыDraw.Добавить(
СтрШаблон(
"text %1, %2 '%3'",
10,
140,
ОписаниеЭП.Имя + " " + ОписаниеЭП.Отчество));
ПараметрыDraw.Добавить(
СтрШаблон(
"text %1, %2 '%3'",
90,
227,
Формат(ОписаниеЭП.ДатаПодписи, "ДЛФ=DT")));
ПараметрыСоздания = Новый Массив;
ПараметрыСоздания.Добавить(
СтрШаблон("convert %1", ПутьФайлаШаблона));
ПараметрыСоздания.Добавить(
СтрШаблон(" -fill ""#536AC2"" -pointsize 32 -draw ""%1""",
СтрСоединить(ПараметрыDraw, " ")));
ПараметрыDraw = Новый Массив;
ПараметрыDraw.Добавить(
СтрШаблон(
"text %1, %2 '%3'",
80,
185,
ОписаниеЭП.Хэш));
ПараметрыСоздания.Добавить(
СтрШаблон(" -fill ""#536AC2"" -pointsize 22 -draw ""%1""",
СтрСоединить(ПараметрыDraw, " ")));
ПараметрыСоздания.Добавить("-resize 35%");
ПутьНовогоФайла = ПолучитьИмяВременногоФайла("PNG");
ПараметрыСоздания.Добавить(ПутьНовогоФайла);
ПараметрыImageMagick = СтрСоединить(ПараметрыСоздания, " ");
ЗапуститьImageMagick(ПараметрыImageMagick, ФайлыКУдалению);
Возврат Новый ДвоичныеДанные(ПутьНовогоФайла);
КонецФункции
//виртуальная цифровая подпись
В Модуле "РаботаСФайламиКлиент" изменить код процедур и функций:
// Сохранение файлов
//
// Параметры
// ДанныеСохраняемыхФайлов - структура, со список значений с данными файлов и общей информацией о файлах
// УникальныйИдентификатор - уникальный идентификатор формы
// ТипПапки - пользовательская настройка, в которую будет сохранена папка
// СохранитьБезДиалогаПользователя - не спрашивать у пользователя путь сохранения файла.
// Путь будет взят из ДанныеСохраняемыхФайлов.ПутьВыбора.
// НеСпрашиватьВариантСохранения - автоматически сохранять файл с именем типа
// "Имя файла(1).Расширение файла" в случае совпадения имен.
// В противном случае будет выдан диалог пользователя для
// выбора варианта сохранения.
Функция СохранитьФайлы(
ОписаниеОповещения,
ДанныеСохраняемыхФайлов,
УникальныйИдентификатор,
ТипПапки = "ПапкаДляСохраненияФайлов",
СохранитьБезДиалогаПользователя = Ложь,
НеСпрашиватьВариантСохранения = Ложь) Экспорт
#Если ВебКлиент Тогда
ПоказатьПредупреждение(, НСтр("ru = 'В Веб-клиенте сохранение файлов не поддерживается.'"));
Возврат "";
#КонецЕсли
ПутьВыбора = ДанныеСохраняемыхФайлов.ПутьВыбора;
Если Не СохранитьБезДиалогаПользователя Тогда
ВыборКаталога = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборКаталога.Каталог = ПутьВыбора;
Если ВыборКаталога.Выбрать() Тогда
ПутьВыбораПрежний = ПутьВыбора;
ПутьВыбора = ВыборКаталога.Каталог;
ПутьВыбора = ФайловыеФункцииКлиент.НормализоватьКаталог(ПутьВыбора);
ПутьВыбора = ФайловыеФункцииКлиент.НормализоватьКаталог(ПутьВыбора);
Если ПутьВыбораПрежний <> ПутьВыбора Тогда
ОбщегоНазначенияВызовСервера.ХранилищеОбщихНастроекСохранить("НастройкиПрограммы", ТипПапки, ПутьВыбора);
КонецЕсли;
Иначе
ВыполнитьОбработкуОповещения(ОписаниеОповещения, Ложь);
Возврат "";
КонецЕсли;
КонецЕсли;
Номер = 0;
Для Каждого СписокСтрока Из ДанныеСохраняемыхФайлов.СписокДанныхФайлов Цикл
ДанныеФайла = СписокСтрока.Значение;
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюЭП
И ДанныеФайла.ВизуализацияЭПДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
СоздатьВизуализациюЭПВФайлеDoc(ДанныеФайла, УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюФаксимиле
И ДанныеФайла.ВизуализацияФаксимилеДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
ОбщийБизнесКлиент.СоздатьВизуализациюФаксимилеВФайлеDoc(ДанныеФайла, УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
ДанныеСохраняемыхФайлов.СписокДанныхФайлов[Номер].Значение = ДанныеФайла;
Номер = Номер + 1;
КонецЦикла;
КоличествоФайлов = ДанныеСохраняемыхФайлов.КоличествоФайлов;
ОбщийРазмерВМб = ДанныеСохраняемыхФайлов.ОбщийРазмер / (1024 * 1024);
#Если Не ВебКлиент Тогда
ТекстПояснения =
СтрШаблон(
НСтр("ru = 'Выполняется сохранение %1 файлов (%2 Мб)...
|Пожалуйста, подождите.'"),
КоличествоФайлов,
ФайловыеФункцииКлиентСервер.ПолучитьСтрокуСРазмеромФайла(ОбщийРазмерВМб));
Состояние(ТекстПояснения);
#КонецЕсли
ПутьВыбора = ФайловыеФункцииКлиент.НормализоватьКаталог(ПутьВыбора);
ПараметрыВыполнения = Новый Структура;
ПараметрыВыполнения.Вставить("НомерФайла", 0);
ПараметрыВыполнения.Вставить("УникальныйИдентификатор", УникальныйИдентификатор);
ПараметрыВыполнения.Вставить("ОписаниеОповещения", ОписаниеОповещения);
ПараметрыВыполнения.Вставить("ДанныеСохраняемыхФайлов", ДанныеСохраняемыхФайлов);
ПараметрыВыполнения.Вставить("ТипПапки", ТипПапки);
ПараметрыВыполнения.Вставить("СохранитьБезДиалогаПользователя", СохранитьБезДиалогаПользователя);
ПараметрыВыполнения.Вставить("НеСпрашиватьВариантСохранения", НеСпрашиватьВариантСохранения);
ПараметрыВыполнения.Вставить("ПутьВыбора", ПутьВыбора);
Обработчик = Новый ОписаниеОповещения("СохранитьФайлыМассивФайловТонкийКлиент", ЭтотОбъект, ПараметрыВыполнения);
ВыполнитьОбработкуОповещения(Обработчик);
Возврат "";
КонецФункции
// Процедура печати Файла
//
// Параметры
// ДанныеФайлов - массив структур с данными файла
// УникальныйИдентификатор - уникальный идентификатор формы
//
Процедура НапечататьФайлы(ДанныеФайлов, УникальныйИдентификатор = Неопределено) Экспорт
Оповестить("ОбновитьСписокПоследних");
Номер = 0;
Для Каждого ДанныеФайла Из ДанныеФайлов Цикл
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюЭП
И ДанныеФайла.ВизуализацияЭПДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
СоздатьВизуализациюЭПВФайлеDoc(ДанныеФайла, УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюФаксимиле
И ДанныеФайла.ВизуализацияФаксимилеДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
ОбщийБизнесКлиент.СоздатьВизуализациюФаксимилеВФайлеDoc(ДанныеФайла, УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
ДанныеФайлов[Номер] = ДанныеФайла;
Номер = Номер + 1;
КонецЦикла;
ПараметрыВыполнения = Новый Структура;
ПараметрыВыполнения.Вставить("НомерФайла", 0);
ПараметрыВыполнения.Вставить("ДанныеФайлов", ДанныеФайлов);
ПараметрыВыполнения.Вставить("УникальныйИдентификатор", УникальныйИдентификатор);
Обработчик = Новый ОписаниеОповещения("НапечататьФайлыВыполнение", ЭтотОбъект, ПараметрыВыполнения);
ВыполнитьОбработкуОповещения(Обработчик);
КонецПроцедуры
// Сохранение на диск Файла
//
// Параметры:
// ОбработчикРезультата - ОписаниеОповещения, Неопределено - Описание процедуры, принимающей результат работы метода.
// ДанныеФайла - структура с данными файла.
// УникальныйИдентификатор - уникальный идентификатор формы.
//
// Возвращаемое значение:
// Строка - выбранный полный путь файла.
//
Процедура СохранитьКак(ОбработчикРезультата, ДанныеФайла, УникальныйИдентификатор) Экспорт
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюЭП
И ДанныеФайла.ВизуализацияЭПДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
СоздатьВизуализациюЭПВФайлеDoc(ДанныеФайла, УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюФаксимиле
И ДанныеФайла.ВизуализацияФаксимилеДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
ОбщийБизнесКлиент.СоздатьВизуализациюФаксимилеВФайлеDoc(ДанныеФайла, УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
ПараметрыВыполнения = Новый Структура;
ПараметрыВыполнения.Вставить("ОбработчикРезультата", ОбработчикРезультата);
ПараметрыВыполнения.Вставить("ДанныеФайла", ДанныеФайла);
ПараметрыВыполнения.Вставить("УникальныйИдентификатор", УникальныйИдентификатор);
Если ФайловыеФункцииСлужебныйКлиент.РасширениеРаботыСФайламиПодключено() Тогда
СохранитьКакСРасширением(ПараметрыВыполнения);
Иначе
СохранитьКакБезРасширения(ПараметрыВыполнения);
КонецЕсли;
КонецПроцедуры
// Открыть файл для просмотра из карточки документа
Процедура ОткрытьФайлДокумента(Файл, Форма) Экспорт
Если Не ЗначениеЗаполнено(Файл) Тогда
Возврат;
КонецЕсли;
Если Форма.Модифицированность И
Форма.Параметры.Свойство("Ключ") И
ЗначениеЗаполнено(Форма.Параметры.Ключ) Тогда
Если НЕ Форма.Записать() Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Попытка
ПредыдущийАдресФайла = Форма.ПредыдущийАдресФайла;
Исключение
ПредыдущийАдресФайла = Неопределено;
КонецПопытки;
ДанныеФайла = РаботаСФайламиВызовСервера.ДанныеФайлаДляОткрытия(
Файл,
Неопределено,
Форма.УникальныйИдентификатор,
Неопределено,
ПредыдущийАдресФайла);
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюЭП
И ДанныеФайла.ВизуализацияЭПДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
СоздатьВизуализациюЭПВФайлеDoc(ДанныеФайла, Форма.УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
Если ДанныеФайла.ТребуетсяСоздатьВизуализациюФаксимиле
И ДанныеФайла.ВизуализацияФаксимилеДобавлена = Ложь Тогда
#Если Не ВебКлиент И Не МобильныйКлиент Тогда
// для doc файла заполним на клиенте - если не веб клиент
ОбщийБизнесКлиент.СоздатьВизуализациюФаксимилеВФайлеDoc(ДанныеФайла, Форма.УникальныйИдентификатор);
#КонецЕсли
КонецЕсли;
//виртуальная цифровая подпись
КомандыРаботыСФайламиКлиент.Открыть(ДанныеФайла);
КонецПроцедуры
В модуле "РаботаСФайламиВызовСервера" изменить код процедур и функций:
// Функция возвращает структуру, содержащую различные сведения о Файле и версии
// Параметры
// ФайлСсылка - СправочникСсылка.Файлы - файл
// ВерсияСсылка - СправочникСсылка.ВерсииФайлов - версия файла
// ИдентификаторКлиента - Строка - переданный ИдентификаторКлиента
//
// Возвращаемое значение:
// Структура - структура с данными файла
Функция ДанныеФайла(ФайлСсылка, ВерсияСсылка = Неопределено, ИдентификаторКлиента = Неопределено) Экспорт
Запрос = Новый Запрос;
Если ВерсияСсылка = Справочники.ВерсииФайлов.ПустаяСсылка() Тогда
ВерсияСсылка = Неопределено;
КонецЕсли;
Если ВерсияСсылка = Неопределено Тогда
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Файлы.Ссылка КАК Ссылка,
| Файлы.Код КАК Код,
| Файлы.Редактирует КАК Редактирует,
| Файлы.ТекущаяВерсия КАК ТекущаяВерсия,
| Файлы.ВладелецФайла КАК ВладелецФайла,
| Файлы.ХранитьВерсии КАК ХранитьВерсии,
| Файлы.ПометкаУдаления КАК ПометкаУдаления,
| Файлы.ДатаЗаема КАК ДатаЗаема,
| Файлы.Зашифрован КАК Зашифрован,
| Файлы.ПодписанЭП КАК ПодписанЭП,
| ЕСТЬNULL(ВерсииФайлов.ПолноеНаименование, """") КАК ПолноеНаименование,
| ЕСТЬNULL(ВерсииФайлов.Расширение, """") КАК Расширение,
| ЕСТЬNULL(ВерсииФайлов.Размер, 0) КАК Размер,
| ЕСТЬNULL(ВерсииФайлов.НомерВерсии, 0) КАК НомерВерсии,
| ЕСТЬNULL(ВерсииФайлов.ПутьКФайлу, """") КАК ПутьКФайлу,
| ЕСТЬNULL(ВерсииФайлов.Том, ЗНАЧЕНИЕ(Справочник.ТомаХраненияФайлов.ПустаяСсылка)) КАК Том,
| ЕСТЬNULL(ВерсииФайлов.ДатаМодификацииУниверсальная, ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)) КАК ДатаМодификацииУниверсальная,
| ЕСТЬNULL(ВерсииФайлов.Автор, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)) КАК Автор,
| ЕСТЬNULL(ВерсииФайлов.СтатусИзвлеченияТекста, ЗНАЧЕНИЕ(Перечисление.СтатусыИзвлеченияТекстаФайлов.ПустаяСсылка)) КАК СтатусИзвлеченияТекста,
| ЕСТЬNULL(ВерсииФайлов.СтатусРаспознаванияТекста, ЗНАЧЕНИЕ(Перечисление.СтатусыРаспознаванияТекста.ПустаяСсылка)) КАК СтатусРаспознаванияТекста,
| ЕСТЬNULL(ВерсииФайлов.ТипХраненияФайла, ЗНАЧЕНИЕ(Перечисление.ТипыХраненияФайлов.ПустаяСсылка)) КАК ТипХраненияФайла
|ИЗ
| Справочник.Файлы КАК Файлы
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВерсииФайлов КАК ВерсииФайлов
| ПО Файлы.ТекущаяВерсия = ВерсииФайлов.Ссылка";
Если ТипЗнч(ФайлСсылка) = Тип("Массив") Тогда
Запрос.Текст = Запрос.Текст + " ГДЕ Файлы.Ссылка В (&Файл) ";
Иначе
Запрос.Текст = Запрос.Текст + " ГДЕ Файлы.Ссылка = &Файл ";
КонецЕсли;
Запрос.Параметры.Вставить("Файл", ФайлСсылка);
Иначе
Если ФайлСсылка <> Неопределено Тогда
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Файлы.Ссылка КАК Ссылка,
| Файлы.Код КАК Код,
| Файлы.Редактирует КАК Редактирует,
| Файлы.ТекущаяВерсия КАК ТекущаяВерсия,
| Файлы.ВладелецФайла КАК ВладелецФайла,
| Файлы.ХранитьВерсии КАК ХранитьВерсии,
| Файлы.ПометкаУдаления КАК ПометкаУдаления,
| Файлы.ДатаЗаема КАК ДатаЗаема,
| Файлы.Зашифрован КАК Зашифрован,
| Файлы.ПодписанЭП КАК ПодписанЭП,
| ЕСТЬNULL(ВерсииФайлов.ПолноеНаименование, """") КАК ПолноеНаименование,
| ЕСТЬNULL(ВерсииФайлов.Расширение, """") КАК Расширение,
| ЕСТЬNULL(ВерсииФайлов.Размер, 0) КАК Размер,
| ЕСТЬNULL(ВерсииФайлов.НомерВерсии, 0) КАК НомерВерсии,
| ЕСТЬNULL(ВерсииФайлов.ПутьКФайлу, """") КАК ПутьКФайлу,
| ЕСТЬNULL(ВерсииФайлов.Том, ЗНАЧЕНИЕ(Справочник.ТомаХраненияФайлов.ПустаяСсылка)) КАК Том,
| ЕСТЬNULL(ВерсииФайлов.ДатаМодификацииУниверсальная, ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)) КАК ДатаМодификацииУниверсальная,
| ЕСТЬNULL(ВерсииФайлов.Автор, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)) КАК Автор,
| ЕСТЬNULL(ВерсииФайлов.СтатусИзвлеченияТекста, ЗНАЧЕНИЕ(Перечисление.СтатусыИзвлеченияТекстаФайлов.ПустаяСсылка)) КАК СтатусИзвлеченияТекста,
| ЕСТЬNULL(ВерсииФайлов.СтатусРаспознаванияТекста, ЗНАЧЕНИЕ(Перечисление.СтатусыРаспознаванияТекста.ПустаяСсылка)) КАК СтатусРаспознаванияТекста,
| ЕСТЬNULL(ВерсииФайлов.ТипХраненияФайла, ЗНАЧЕНИЕ(Перечисление.ТипыХраненияФайлов.ПустаяСсылка)) КАК ТипХраненияФайла
|ИЗ
| Справочник.Файлы КАК Файлы
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ВерсииФайлов КАК ВерсииФайлов
| ПО (ИСТИНА)
|ГДЕ
| Файлы.Ссылка = &Файл
| И ВерсииФайлов.Ссылка = &Версия";
Запрос.Параметры.Вставить("Файл", ФайлСсылка);
Запрос.Параметры.Вставить("Версия", ВерсияСсылка);
Иначе
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Файлы.Ссылка КАК Ссылка,
| Файлы.Код КАК Код,
| Файлы.Редактирует КАК Редактирует,
| Файлы.ТекущаяВерсия КАК ТекущаяВерсия,
| Файлы.ВладелецФайла КАК ВладелецФайла,
| Файлы.ХранитьВерсии КАК ХранитьВерсии,
| Файлы.ПометкаУдаления КАК ПометкаУдаления,
| Файлы.ДатаЗаема КАК ДатаЗаема,
| Файлы.Зашифрован КАК Зашифрован,
| Файлы.ПодписанЭП КАК ПодписанЭП,
| ЕСТЬNULL(ВерсииФайлов.ПолноеНаименование, """") КАК ПолноеНаименование,
| ЕСТЬNULL(ВерсииФайлов.Расширение, """") КАК Расширение,
| ЕСТЬNULL(ВерсииФайлов.Размер, 0) КАК Размер,
| ЕСТЬNULL(ВерсииФайлов.НомерВерсии, 0) КАК НомерВерсии,
| ЕСТЬNULL(ВерсииФайлов.ПутьКФайлу, """") КАК ПутьКФайлу,
| ЕСТЬNULL(ВерсииФайлов.Том, ЗНАЧЕНИЕ(Справочник.ТомаХраненияФайлов.ПустаяСсылка)) КАК Том,
| ЕСТЬNULL(ВерсииФайлов.ДатаМодификацииУниверсальная, ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)) КАК ДатаМодификацииУниверсальная,
| ЕСТЬNULL(ВерсииФайлов.Автор, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)) КАК Автор,
| ЕСТЬNULL(ВерсииФайлов.СтатусИзвлеченияТекста, ЗНАЧЕНИЕ(Перечисление.СтатусыИзвлеченияТекстаФайлов.ПустаяСсылка)) КАК СтатусИзвлеченияТекста,
| ЕСТЬNULL(ВерсииФайлов.СтатусРаспознаванияТекста, ЗНАЧЕНИЕ(Перечисление.СтатусыРаспознаванияТекста.ПустаяСсылка)) КАК СтатусРаспознаванияТекста,
| ЕСТЬNULL(ВерсииФайлов.ТипХраненияФайла, ЗНАЧЕНИЕ(Перечисление.ТипыХраненияФайлов.ПустаяСсылка)) КАК ТипХраненияФайла
|ИЗ
| Справочник.Файлы КАК Файлы
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ВерсииФайлов КАК ВерсииФайлов
| ПО (ИСТИНА)
|ГДЕ
| ВерсииФайлов.Ссылка = &Версия
| И Файлы.Ссылка = ВерсииФайлов.Владелец";
Запрос.Параметры.Вставить("Версия", ВерсияСсылка);
КонецЕсли;
КонецЕсли;
МассивДанныеФайла = Новый Массив;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДанныеФайла = Новый Структура;
ДанныеФайла.Вставить("Ссылка", Выборка.Ссылка);
ДанныеФайла.Вставить("КодФайла", Выборка.Код);
ДанныеФайла.Вставить("Редактирует", Выборка.Редактирует);
ДанныеФайла.Вставить("Владелец", Выборка.ВладелецФайла);
ДанныеФайла.Вставить("НавигационнаяСсылка", ПолучитьНавигационнуюСсылку(Выборка.Ссылка));
ДанныеФайла.Вставить("КоличествоЗанятыхФайлов", -1); // -1 - значит не задано
Если ВерсияСсылка <> Неопределено Тогда
ДанныеФайла.Вставить("Версия", ВерсияСсылка);
Иначе
ДанныеФайла.Вставить("Версия", Выборка.ТекущаяВерсия);
КонецЕсли;
ДанныеФайла.Вставить("ТекущаяВерсия", Выборка.ТекущаяВерсия);
СтруктураКлюча = Новый Структура("Файл", ДанныеФайла.ТекущаяВерсия);
КлючЗаписи = РегистрыСведений.ДвоичныеДанныеФайлов.СоздатьКлючЗаписи(СтруктураКлюча);
НавигационнаяСсылкаТекущейВерсии = ПолучитьНавигационнуюСсылку(КлючЗаписи, "ДвоичныеДанныеФайла");
ДанныеФайла.Вставить("НавигационнаяСсылкаТекущейВерсии", НавигационнаяСсылкаТекущейВерсии);
КодировкаТекущейВерсии = ПолучитьКодировкуВерсииФайла(ДанныеФайла.ТекущаяВерсия);
ДанныеФайла.Вставить("КодировкаТекущейВерсии", КодировкаТекущейВерсии);
ДанныеФайла.Вставить("Размер", Выборка.Размер);
ДанныеФайла.Вставить("НомерВерсии", Выборка.НомерВерсии);
ДанныеФайла.Вставить("ДатаМодификацииУниверсальная", Выборка.ДатаМодификацииУниверсальная);
ДанныеФайла.Вставить("Расширение", Выборка.Расширение);
ДанныеФайла.Вставить("ПолноеНаименованиеВерсии", СокрЛП(Выборка.ПолноеНаименование));
ДанныеФайла.Вставить("ХранитьВерсии", Выборка.ХранитьВерсии);
ДанныеФайла.Вставить("ПометкаУдаления", Выборка.ПометкаУдаления);
ДанныеФайла.Вставить("АвторТекущейВерсии", Выборка.Автор);
ДанныеФайла.Вставить("Зашифрован", Выборка.Зашифрован);
ДанныеФайла.Вставить("ПодписанЭП", Выборка.ПодписанЭП);
ДанныеФайла.Вставить("ДатаЗаема", Выборка.ДатаЗаема);
ДанныеФайла.Вставить("ПутьКФайлу", Выборка.ПутьКФайлу);
ДанныеФайла.Вставить("Том", Выборка.Том);
ДанныеФайла.Вставить("ТипХраненияФайла", Выборка.ТипХраненияФайла);
Если ДанныеФайла.Зашифрован Тогда
МассивСертификатовШифрования = ПолучитьМассивСертификатовШифрования(ДанныеФайла.Ссылка);
ДанныеФайла.Вставить("МассивСертификатовШифрования", МассивСертификатовШифрования);
КонецЕсли;
НаЧтение = ДанныеФайла.Редактирует <> Пользователи.ТекущийПользователь();
ДанныеФайла.Вставить("НаЧтение", НаЧтение);
ДанныеФайла.Вставить("ЗанятСДругогоКомпьютера", Ложь);
ДанныеФайла.Вставить("ИмяДругогоКомпьютера", "");
Если ДанныеФайла.Редактирует = Пользователи.ТекущийПользователь() Тогда
Если Не ФайловыеФункции.ЕстьЗаписьДляТекущегоИдентификатора(ДанныеФайла.Версия, ИдентификаторКлиента) Тогда
ИмяКомпьютера = "";
Если ФайловыеФункции.ЕстьДанныеЗаемаСДругогоКомпьютера(ДанныеФайла.Версия,
ИмяКомпьютера, ИдентификаторКлиента) Тогда
ДанныеФайла.ЗанятСДругогоКомпьютера = Истина;
ДанныеФайла.ИмяДругогоКомпьютера = ИмяКомпьютера;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ВРабочемКаталогеНаЧтение = Истина;
ВРабочемКаталогеВладельца = Ложь;
ИмяКаталога = ФайловыеФункции.ПолучитьПутьКРабочемуКаталогуПользователя();
Если ИмяКаталога = Неопределено Тогда
ИмяКаталога = "";
КонецЕсли;
Если ВерсияСсылка <> Неопределено Тогда
ИмяФайлаСПутемВРабочемКаталоге = ПолучитьИмяФайлаСПутемИзРегистра(ВерсияСсылка, ИмяКаталога, ВРабочемКаталогеНаЧтение, ВРабочемКаталогеВладельца);
Иначе
ИмяФайлаСПутемВРабочемКаталоге = ПолучитьИмяФайлаСПутемИзРегистра(Выборка.ТекущаяВерсия, ИмяКаталога, ВРабочемКаталогеНаЧтение, ВРабочемКаталогеВладельца);
КонецЕсли;
ДанныеФайла.Вставить("ПолноеИмяФайлаВРабочемКаталоге", ИмяФайлаСПутемВРабочемКаталоге);
ДанныеФайла.Вставить("ВРабочемКаталогеНаЧтение", ВРабочемКаталогеНаЧтение);
ДанныеФайла.Вставить("РабочийКаталогВладельца", "");
РедактируетТекущийПользователь = (ДанныеФайла.Редактирует = Пользователи.ТекущийПользователь());
ДанныеФайла.Вставить("РедактируетТекущийПользователь", РедактируетТекущийПользователь);
СтатусИзвлеченияТекстаСтрока = "НеИзвлечен";
Если Выборка.СтатусИзвлеченияТекста = Перечисления.СтатусыИзвлеченияТекстаФайлов.НеИзвлечен Тогда
СтатусИзвлеченияТекстаСтрока = "НеИзвлечен";
ИначеЕсли Выборка.СтатусИзвлеченияТекста = Перечисления.СтатусыИзвлеченияТекстаФайлов.Извлечен Тогда
СтатусИзвлеченияТекстаСтрока = "Извлечен";
ИначеЕсли Выборка.СтатусИзвлеченияТекста = Перечисления.СтатусыИзвлеченияТекстаФайлов.ИзвлечьНеУдалось Тогда
СтатусИзвлеченияТекстаСтрока = "ИзвлечьНеУдалось";
КонецЕсли;
ДанныеФайла.Вставить("СтатусИзвлеченияТекста", СтатусИзвлеченияТекстаСтрока);
СтатусРаспознаванияТекстаСтрока = "НеНужноРаспознавать";
Если Выборка.СтатусРаспознаванияТекста = Перечисления.СтатусыРаспознаванияТекста.НеРаспознано Тогда
СтатусРаспознаванияТекстаСтрока = "НеРаспознано";
ИначеЕсли Выборка.СтатусРаспознаванияТекста = Перечисления.СтатусыРаспознаванияТекста.НужноРаспознать Тогда
СтатусРаспознаванияТекстаСтрока = "НужноРаспознать";
ИначеЕсли Выборка.СтатусРаспознаванияТекста = Перечисления.СтатусыРаспознаванияТекста.Распознано Тогда
СтатусРаспознаванияТекстаСтрока = "Распознано";
ИначеЕсли Выборка.СтатусРаспознаванияТекста = Перечисления.СтатусыРаспознаванияТекста.Распознается Тогда
СтатусРаспознаванияТекстаСтрока = "Распознается";
ИначеЕсли Выборка.СтатусРаспознаванияТекста = Перечисления.СтатусыРаспознаванияТекста.НеНужноРаспознавать Тогда
СтатусРаспознаванияТекстаСтрока = "НеНужноРаспознавать";
КонецЕсли;
ДанныеФайла.Вставить("СтатусРаспознаванияТекста", СтатусРаспознаванияТекстаСтрока);
ДанныеФайла.Вставить("ПодписанФаксимиле", Выборка.Ссылка.ПодписанФаксимиле);//виртуальная цифровая подпись
МассивДанныеФайла.Добавить(ДанныеФайла);
КонецЦикла;
// если был передан массив - возвращаем массив
Если ТипЗнч(ФайлСсылка) = Тип("Массив") Тогда
Возврат МассивДанныеФайла;
КонецЕсли;
Если МассивДанныеФайла.Количество() > 0 Тогда
Возврат МассивДанныеФайла[0];
Иначе
ВызватьИсключение НСтр("ru = 'У пользователя недостаточно прав на исполнение операции над базой данных.'");
КонецЕсли;
КонецФункции
// Функция возвращает структуру, содержащую различные сведения о Файле и версии.
//
// Параметры:
// ФайлВерсияСсылка - СправочникСсылка.Файлы, СправочникСсылка.ВерсииФайлов - файл или версия файла.
// ИдентификаторФормы - УникальныйИдентификатор - уникальный идентификатор формы.
// РабочийКаталогВладельца - Строка - в ней возвращается рабочий каталог владельца файла.
// ПредыдущийАдресФайла - Строка - в ней возвращается рабочий каталог владельца файла.
//
// Возвращаемое значение:
// Структура - структура с данными файла. См. ПолучитьДанныеФайла.
//
Функция ДанныеФайлаДляОткрытия(ФайлСсылка, ВерсияСсылка = Неопределено, ИдентификаторФормы = Неопределено,
РабочийКаталогВладельца = Неопределено, ПредыдущийАдресФайла = Неопределено,
НеПолучатьВизуализациюЭП = Ложь) Экспорт
Если ПредыдущийАдресФайла <> Неопределено Тогда
Если НЕ ПустаяСтрока(ПредыдущийАдресФайла) И ЭтоАдресВременногоХранилища(ПредыдущийАдресФайла) Тогда
УдалитьИзВременногоХранилища(ПредыдущийАдресФайла);
КонецЕсли;
КонецЕсли;
ДанныеФайла = ДанныеФайла(ФайлСсылка, ВерсияСсылка);
Если РабочийКаталогВладельца = Неопределено Тогда
РабочийКаталогВладельца = РабочийКаталогПапки(ДанныеФайла.Владелец);
КонецЕсли;
ДанныеФайла.Вставить("РабочийКаталогВладельца", РабочийКаталогВладельца);
Если ДанныеФайла.РабочийКаталогВладельца <> "" Тогда
ИмяФайла = ОбщегоНазначенияКлиентСервер.ПолучитьИмяСРасширением(
ДанныеФайла.ПолноеНаименованиеВерсии, ДанныеФайла.Расширение);
ПолноеИмяФайлаВРабочемКаталоге = РабочийКаталогВладельца + ИмяФайла;
ДанныеФайла.Вставить("ПолноеИмяФайлаВРабочемКаталоге", ПолноеИмяФайлаВРабочемКаталоге);
КонецЕсли;
ПредыдущийАдресФайла = ДанныеФайла.НавигационнаяСсылкаТекущейВерсии;
ПротоколированиеРаботыПользователей.ЗаписатьПолучениеФайла(ДанныеФайла.Ссылка);
ЗаписатьОбращениеКВерсииФайла(ДанныеФайла.Версия);
РаботаСПоследнимиОбъектами.ЗаписатьОбращениеКОбъекту(ДанныеФайла.Ссылка);
ОбщийБизнес.ДобавитьВизуализациюФаксимиле(ДанныеФайла, ИдентификаторФормы);//виртуальная цифровая подпись
Если НеПолучатьВизуализациюЭП = Ложь Тогда
ДобавитьВизуализациюЭП(ДанныеФайла, ИдентификаторФормы);
Если ДанныеФайла.ВизуализацияЭПДобавлена = Истина Тогда
ДанныеФайла.ПолноеИмяФайлаВРабочемКаталоге = ""; // не берем из кеша
УдалитьИзРегистра(ДанныеФайла.Версия); // удалим инфо из кеша
Возврат ДанныеФайла;
КонецЕсли;
Иначе
ДанныеФайла.ПолноеИмяФайлаВРабочемКаталоге = ""; // не берем из кеша
УдалитьИзРегистра(ДанныеФайла.Версия); // удалим инфо из кеша
КонецЕсли;
ТипХраненияФайла = ДанныеФайла.Версия.ТипХраненияФайла;
Если ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВТомахНаДиске И ДанныеФайла.Версия <> Неопределено Тогда
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВерсииФайлов.ПутьКФайлу КАК ПутьКФайлу,
| ВерсииФайлов.Том КАК Том
|ИЗ
| Справочник.ВерсииФайлов КАК ВерсииФайлов
|ГДЕ
| ВерсииФайлов.Ссылка = &Версия";
Запрос.Параметры.Вставить("Версия", ДанныеФайла.Версия);
ДанныеФайлаТом = Справочники.ТомаХраненияФайлов.ПустаяСсылка();
ДанныеФайлаПутьКФайлу = "";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ДанныеФайлаТом = Выборка.Том;
ДанныеФайлаПутьКФайлу = Выборка.ПутьКФайлу;
КонецЕсли;
Если НЕ ДанныеФайлаТом.Пустая() Тогда
ПолныйПуть = ФайловыеФункцииСлужебный.ПолныйПутьТома(ДанныеФайлаТом) + ДанныеФайлаПутьКФайлу;
Попытка
ДвоичныеДанные = Новый ДвоичныеДанные(ПолныйПуть);
// Работаем только с текущей версией - для не-текущей ссылку получаем в ПолучитьНавигационнуюСсылкуДляОткрытия.
ДанныеФайла.НавигационнаяСсылкаТекущейВерсии = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ИдентификаторФормы);
Исключение
// Запись в журнал регистрации.
СсылкаНаФайл = ?(ФайлСсылка <> Неопределено, ФайлСсылка, ВерсияСсылка);
СообщениеОбОшибке = СформироватьТекстОшибкиПолученияФайлСТомаДляАдминистратора(
ИнформацияОбОшибке(), СсылкаНаФайл);
ЗаписьЖурналаРегистрации(
НСтр("ru = 'Файлы.Открытие файла'",
ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,
Метаданные.Справочники.Файлы,
ФайлСсылка,
СообщениеОбОшибке);
ТипВладельцаФайла = ТипЗнч(ДанныеФайла.Владелец);
Если ТипВладельцаФайла = Тип("СправочникСсылка.ПапкиФайлов") Тогда
ПредставлениеВладельца = ПолныйПутьПапки(ДанныеФайла.Владелец);
Иначе
ПредставлениеВладельца = ДанныеФайла.Владелец;
КонецЕсли;
ПредставлениеВладельцаФайла = СтрШаблон(
НСтр("ru = 'Присоединен к %1 : %2'"),
Строка(ТипВладельцаФайла),
ПредставлениеВладельца);
ВызватьИсключение ФайловыеФункцииСлужебныйКлиентСервер.ОшибкаФайлНеНайденВХранилищеФайлов(
ДанныеФайла.ПолноеНаименованиеВерсии + "." + ДанныеФайла.Расширение,
,
ПредставлениеВладельцаФайла);
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ДанныеФайла.ПолноеИмяФайлаВРабочемКаталоге) Тогда
ОбновитьДатуОбращенияФайлыВРабочемКаталогеКомпьютера(ДанныеФайла.Версия);
КонецЕсли;
Возврат ДанныеФайла;
КонецФункции // ДанныеФайлаДляОткрытия()
//
Функция ДанныеФайловДляОткрытия(
МассивФайлов,
ИдентификаторФормы = Неопределено) Экспорт
ДанныеФайлов = ДанныеФайла(МассивФайлов);
СоответствиеФайлов = Новый Соответствие;
Для Каждого ДанныеФайла Из ДанныеФайлов Цикл
СоответствиеФайлов.Вставить(ДанныеФайла.Ссылка, ДанныеФайла);
КонецЦикла;
Для Каждого Файл Из МассивФайлов Цикл
ДанныеФайла = СоответствиеФайлов.Получить(Файл);
ЗаписатьОбращениеКВерсииФайла(ДанныеФайла.Версия);
РаботаСПоследнимиОбъектами.ЗаписатьОбращениеКОбъекту(ДанныеФайла.Ссылка);
РабочийКаталогВладельца = РабочийКаталогПапки(ДанныеФайла.Владелец);
ДанныеФайла.Вставить("РабочийКаталогВладельца", РабочийКаталогВладельца);
Если ДанныеФайла.РабочийКаталогВладельца <> "" Тогда
ИмяФайла = ФайловыеФункцииКлиентСервер.ПолучитьИмяСРасширением(ДанныеФайла.ПолноеНаименованиеВерсии, ДанныеФайла.Расширение);
ИмяФайлаСПутемВРабочемКаталоге = РабочийКаталогВладельца + ИмяФайла;
ДанныеФайла.Вставить("ПолноеИмяФайлаВРабочемКаталоге", ИмяФайлаСПутемВРабочемКаталоге);
КонецЕсли;
ДобавитьВизуализациюЭП(ДанныеФайла, ИдентификаторФормы);
ОбщийБизнес.ДобавитьВизуализациюФаксимиле(ДанныеФайла, ИдентификаторФормы);//виртуальная цифровая подпись
Если ДанныеФайла.ВизуализацияЭПДобавлена = Истина Тогда
ДанныеФайла.ПолноеИмяФайлаВРабочемКаталоге = ""; // не берем из кеша
УдалитьИзРегистра(ДанныеФайла.Версия); // удалим инфо из кеша
Продолжить;
КонецЕсли;
РабочийКаталогВладельца = РабочийКаталогПапки(ДанныеФайла.Владелец);
ДанныеФайла.Вставить("РабочийКаталогВладельца", РабочийКаталогВладельца);
Если ДанныеФайла.РабочийКаталогВладельца <> "" Тогда
ИмяФайла = ФайловыеФункцииКлиентСервер.ПолучитьИмяСРасширением(ДанныеФайла.ПолноеНаименованиеВерсии, ДанныеФайла.Расширение);
ИмяФайлаСПутемВРабочемКаталоге = РабочийКаталогВладельца + ИмяФайла;
ДанныеФайла.Вставить("ПолноеИмяФайлаВРабочемКаталоге", ИмяФайлаСПутемВРабочемКаталоге);
КонецЕсли;
ТипХраненияФайла = ДанныеФайла.ТипХраненияФайла;
Если ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВТомахНаДиске И ДанныеФайла.Версия <> Неопределено Тогда
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВерсииФайлов.ПутьКФайлу КАК ПутьКФайлу,
| ВерсииФайлов.Том КАК Том
|ИЗ
| Справочник.ВерсииФайлов КАК ВерсииФайлов
|ГДЕ
| ВерсииФайлов.Ссылка = &Версия";
Запрос.Параметры.Вставить("Версия", ДанныеФайла.Версия);
ДанныеФайлаТом = Справочники.ТомаХраненияФайлов.ПустаяСсылка();
ДанныеФайлаПутьКФайлу = "";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ДанныеФайлаТом = Выборка.Том;
ДанныеФайлаПутьКФайлу = Выборка.ПутьКФайлу;
КонецЕсли;
Если НЕ ДанныеФайлаТом.Пустая() Тогда
ПолныйПуть = ФайловыеФункции.ПолныйПутьТома(ДанныеФайлаТом) + ДанныеФайлаПутьКФайлу;
Попытка
ДвоичныеДанные = Новый ДвоичныеДанные(ПолныйПуть);
// Работаем только с текущей версией - для не-текущей ссылку получаем в ПолучитьНавигационнуюСсылкуДляОткрытия.
ДанныеФайла.НавигационнаяСсылкаТекущейВерсии = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ИдентификаторФормы);
Исключение
// запись в журнал регистрации
СообщениеОбОшибке = СформироватьТекстОшибкиПолученияФайлСТомаДляАдминистратора(ИнформацияОбОшибке(), ДанныеФайла.Ссылка);
ЗаписьЖурналаРегистрации("Получение данных файла для открытия", УровеньЖурналаРегистрации.Ошибка, Метаданные.Справочники.Файлы, ДанныеФайла.Ссылка, СообщениеОбОшибке);
ВызватьИсключение ФайловыеФункцииСлужебныйКлиентСервер.ОшибкаФайлНеНайденВХранилищеФайлов(
ДанныеФайла.ПолноеНаименованиеВерсии + "." + ДанныеФайла.Расширение);
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ДанныеФайлов;
КонецФункции // ДанныеФайлаДляОткрытия()
7. Финиш.