|
Расширение и хранение файлов | ☑ | ||
---|---|---|---|---|
0
Yogurt
14.09.22
✎
13:04
|
Столкнулся с задачей.
УНФ, делаем свой справочник в расширении, к нему нужно прицеплять файлы (сканы документов). Типовым способом через БСП "Определяемые типы" "ВладелецПрисоединенныхФайлов" добавить в расширение свой справочник можно либо с 20 платформы, либо тот еще квест. Как еще можно просто и быстро организовать хранение файлов в справочник из расширения? |
|||
1
Greeen
14.09.22
✎
13:49
|
Мой совет - обновить платформу и не париться (ИМХО - это из самого простого решение)
|
|||
2
H A D G E H O G s
14.09.22
✎
13:54
|
(0) Я запиливал регистр - копию и отдельные справочники
|
|||
3
DrZombi
гуру
14.09.22
✎
13:55
|
(0) Быстро, используя БСП - "ВладелецПрисоединенныхФайлов".
Имя справочника "ВладелецПрисоединенныхФайлов" - должно соответствовать правилу. Придется снять с поддержки. :) |
|||
4
Yogurt
14.09.22
✎
13:56
|
(1) Что бы добавить свой объект в "Определяемые типы", это надо добавить в расширение все объекты, которые там есть в изначальном виде?
Иначе мне свой не добавить, в расширении тип у "ВладелецПрисоединенныхФайлов" - "Произвольный" |
|||
5
Ryzeman
14.09.22
✎
14:02
|
(0) Можно неБСПшное сделать. Тебе по сути надо в реквизите хранить ссылку в хранилище да логику загрузки и получения прописать. В БСПшном просто всё красиво и универсально. Картиночки вон смотреть и редактировать можно)
|
|||
6
Ryzeman
14.09.22
✎
14:02
|
ну или снять с поддержки. Или затащить в расширение миллиард объектов)
|
|||
7
DrZombi
гуру
14.09.22
✎
14:59
|
(0) В общем описывать все долго, но через расширение тоже можно дописывать хранение файлов вида "ВладелецПрисоединенныхФайлов"
Список всего, что у меня потребовалось для доработок. Но так может, у вас это не предел... Там где "Форма", то надо все реквизиты формы с соответствующими типами так же менять. (и не забыть про вкладку Параметры формы "ПрисоединенныйФайл") И помни, от основной конфигурации все можно определить, как Любая ссылка, а ваш тип из расширения, указать как обычно, ибо увы тип расширения надо указывать Объект "Справочник.ВключениеВКадровыйРезервПрисоединенныеФайлы" использован в: ПодпискаНаСобытие.ОпределитьФормуПрисоединенногоФайлаВзаимодействия.Источник ПодпискаНаСобытие.СОГ_ВыполнитьДействияПередЗаписьюПрисоединенногоФайла.Источник ПодпискаНаСобытие.СОГ_ВыполнитьДействияПередУдалениемПрисоединенногоФайла.Источник ПодпискаНаСобытие.СОГ_ВыполнитьДействияПриЗаписиПрисоединенногоФайла.Источник Обработка.РаботаСФайлами.Форма.ПрисоединенныйФайл.Форма РегистрСведений.СОГ_ДвоичныеДанныеФайлов.Измерение.Файл.Тип РегистрСведений.СОГ_СведенияОФайлах.Измерение.Файл.Тип Общие модули: Создать общий модуль, с данными на время сеанса "СОГ_ДопФункцииПовторИсп" И там же функции: - ПолучитьОписаниеТипов_ОпределяемыеТипы_ВладелецПрисоединенныхФайлов - ПолучитьОписаниеТипов_ОпределяемыеТипы_ПредметНапоминания (Эти функции нужны для определения, какие Элементы принадлежат расширению и требуют индивидуальной обработки Ведь, тот же Регистр "СОГ_СведенияОФайлах" содержит ваш тип из расширения и не должен содержать типы из основной конфигурации) Кусочки коду, которые пришлось перетащить ОбщийМодуль.РаботаСФайлами // Возвращает двоичные данные файла из информационной базы. // // Параметры: // ФайлСсылка - ссылка на файл или его версию. // // Возвращаемое значение: // ХранилищеЗначения - двоичные данные файла. // &Вместо("ХранилищеФайлаИзИнформационнойБазы") Функция СОГ_ХранилищеФайлаИзИнформационнойБазы(ФайлСсылка) Экспорт УстановитьОтключениеБезопасногоРежима(Истина); УстановитьПривилегированныйРежим(Истина); ТипЗначенияРасширения = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_Расширения("АдаптацияКонфигурации"); //Типовой код, иначе не типовой... Если ТипЗначенияРасширения.СодержитТип(ТипЗнч(ФайлСсылка)) <> Истина Тогда Возврат ПродолжитьВызов(ФайлСсылка); КонецЕсли; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДвоичныеДанныеФайлов.Файл, | ДвоичныеДанныеФайлов.ДвоичныеДанныеФайла |ИЗ | РегистрСведений.СОГ_ДвоичныеДанныеФайлов КАК ДвоичныеДанныеФайлов |ГДЕ | ДвоичныеДанныеФайлов.Файл = &ФайлСсылка"; Запрос.УстановитьПараметр("ФайлСсылка", ФайлСсылка); Выборка = Запрос.Выполнить().Выбрать(); Возврат ?(Выборка.Следующий(), Выборка.ДвоичныеДанныеФайла, Неопределено); КонецФункции // Возвращает двоичные данные файла. // // Параметры: // ПрисоединенныйФайл - ОпределяемыйТип.ПрисоединенныйФайл - ссылка на элемент справочника с файлом. // // ВызыватьИсключение - Булево - если указать Ложь, то функция будет возвращать Неопределено // вместо вызова исключений, уровень записи журнала регистрации будет понижен до "Предупреждение". // Значение по умолчанию - Истина. // // Возвращаемое значение: // ДвоичныеДанные, Неопределено - двоичные данные присоединенного файла. Если двоичные данные файла не найдены // в информационной базе или в томах, вызывает исключение. Если двоичные данные не // найдены и параметр ВызыватьИсключение принимает значение Ложь, тогда // возвращаемое значение - Неопределено. // // Пример: // Сохранение данных файла на сервере: // ДанныеФайла = РаботаСФайлами.ДвоичныеДанныеФайла(Файл, Ложь); // Если ДанныеФайла <> Неопределено Тогда // ДанныеФайла.Записать(ПутьКФайлу); // КонецЕсли; // &Вместо("ДвоичныеДанныеФайла") Функция СОГ_ДвоичныеДанныеФайла(Знач ПрисоединенныйФайл, Знач ВызыватьИсключение = Истина) Экспорт ТипЗначенияРасширения = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_Расширения("АдаптацияКонфигурации"); //Типовой код, иначе не типовой... Если ТипЗначенияРасширения.СодержитТип(ТипЗнч(ПрисоединенныйФайл)) <> Истина Тогда Возврат ПродолжитьВызов(ПрисоединенныйФайл, ВызыватьИсключение); КонецЕсли; ПрисоединенныйФайл_Тип = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл(); //АдаптацияКонфигурации ОбщегоНазначенияКлиентСервер.ПроверитьПараметр("РаботаСФайлами.ДвоичныеДанныеФайла", "ПрисоединенныйФайл", ПрисоединенныйФайл, ПрисоединенныйФайл_Тип); ФайлОбъект = РаботаСФайламиСлужебный.ФайлОбъект(ПрисоединенныйФайл); Если (ФайлОбъект = Неопределено Или ФайлОбъект.ЭтоГруппа) И Не ВызыватьИсключение Тогда Возврат Неопределено; КонецЕсли; ОбщегоНазначенияКлиентСервер.Проверить(ФайлОбъект <> Неопределено, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимое значение параметра %1'"), "ПрисоединенныйФайл"), "РаботаСФайлами.ДвоичныеДанныеФайла"); ОбщегоНазначенияКлиентСервер.Проверить(Не ФайлОбъект.ЭтоГруппа, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимое значение параметра %1 (папка файлов ""%2"")'"), "ПрисоединенныйФайл", ОбщегоНазначения.ПредметСтрокой(ПрисоединенныйФайл)), "РаботаСФайлами.ДвоичныеДанныеФайла"); УстановитьОтключениеБезопасногоРежима(Истина); УстановитьПривилегированныйРежим(Истина); Если ФайлОбъект.ПометкаУдаления Тогда РаботаСФайламиСлужебный.СообщитьОбОшибкеФайлНеНайден(ФайлОбъект, ВызыватьИсключение); Возврат Неопределено; КонецЕсли; Если ФайлОбъект.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе Тогда Результат = ХранилищеФайлаИзИнформационнойБазы(ФайлОбъект.Ссылка); Если Результат <> Неопределено Тогда Результат = Результат.Получить(); Если Результат <> Неопределено Тогда Возврат Результат; КонецЕсли; КонецЕсли; РаботаСФайламиСлужебный.СообщитьОбОшибкеФайлНеНайден(ФайлОбъект, ВызыватьИсключение); Возврат Неопределено; Иначе Возврат РаботаСФайламиВТомахСлужебный.ДанныеФайла(ПрисоединенныйФайл, ВызыватьИсключение); КонецЕсли; КонецФункции Общий модуль = "СОГ_ДопФункцииПовторИсп" #Область Описание_Типа_Расширения Функция ПолучитьОписаниеТипов_Расширения(Знач ИмяРасширения=Неопределено) Экспорт МассивТипов = Новый Массив; Для Каждого Мета Из Метаданные.Справочники Цикл ИспользРасш = Мета.РасширениеКонфигурации(); Если ИспользРасш = Неопределено Тогда Продолжить; КонецЕсли; Если ИмяРасширения <> Неопределено и ИспользРасш.Имя <> ИмяРасширения Тогда Продолжить; КонецЕсли; МассивТипов.Добавить(Тип("СправочникСсылка."+Мета.Имя)); КонецЦикла; Для Каждого Мета Из Метаданные.Документы Цикл ИспользРасш = Мета.РасширениеКонфигурации(); Если ИспользРасш = Неопределено Тогда Продолжить; КонецЕсли; Если ИмяРасширения <> Неопределено и ИспользРасш.Имя <> ИмяРасширения Тогда Продолжить; КонецЕсли; МассивТипов.Добавить(Тип("ДокументСсылка."+Мета.Имя)); КонецЦикла; Для Каждого Мета Из Метаданные.ПланыОбмена Цикл ИспользРасш = Мета.РасширениеКонфигурации(); Если ИспользРасш = Неопределено Тогда Продолжить; КонецЕсли; Если ИмяРасширения <> Неопределено и ИспользРасш.Имя <> ИмяРасширения Тогда Продолжить; КонецЕсли; МассивТипов.Добавить(Тип("ПланОбменаСсылка."+Мета.Имя)); КонецЦикла; Для Каждого Мета Из Метаданные.Перечисления Цикл ИспользРасш = Мета.РасширениеКонфигурации(); Если ИспользРасш = Неопределено Тогда Продолжить; КонецЕсли; Если ИмяРасширения <> Неопределено и ИспользРасш.Имя <> ИмяРасширения Тогда Продолжить; КонецЕсли; МассивТипов.Добавить(Тип("ПеречислениеСсылка."+Мета.Имя)); КонецЦикла; Для Каждого Мета Из Метаданные.ПланыВидовХарактеристик Цикл ИспользРасш = Мета.РасширениеКонфигурации(); Если ИспользРасш = Неопределено Тогда Продолжить; КонецЕсли; Если ИмяРасширения <> Неопределено и ИспользРасш.Имя <> ИмяРасширения Тогда Продолжить; КонецЕсли; МассивТипов.Добавить(Тип("ПланВидовХарактеристикСсылка."+Мета.Имя)); КонецЦикла; ОписаниеТипов = Новый ОписаниеТипов(МассивТипов); Возврат ОписаниеТипов; КонецФункции #КонецОбласти //Метаданные.ОпределяемыеТипы.ПрисоединенныйФайл.Тип Функция ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл() Экспорт МассивТипов = Новый Массив; //МассивТипов.Добавить(Тип("СправочникСсылка.БроньПрисоединенныеФайлы")); ИмяРасширения = "АдаптацияКонфигурации"; Для Каждого Мета Из Метаданные.Справочники Цикл ИспользРасш = Мета.РасширениеКонфигурации(); Если ИспользРасш = Неопределено Тогда Продолжить; КонецЕсли; Если ИмяРасширения <> Неопределено и ИспользРасш.Имя <> ИмяРасширения Тогда Продолжить; КонецЕсли; Если Прав(Мета.Имя,19) <> "ПрисоединенныеФайлы" Тогда Продолжить; КонецЕсли; МассивТипов.Добавить(Тип("СправочникСсылка."+Мета.Имя)); КонецЦикла; ОписТипа = Новый ОписаниеТипов(МассивТипов); Возврат ОписТипа; КонецФункции Общий модуль = СОГ_РаботаСФайлами #Область СлужебныеПроцедурыИФункции // Обработчик подписки на событие ПередЗаписью владельца присоединенного файла. // Помечает на удаление связанные файлы. // // Параметры: // Источник - ДокументОбъект - владелец присоединенного файла. // Отказ - Булево - параметр, передаваемый в подписку на событие ПередЗаписью. // РежимЗаписи - Булево - параметр, передаваемый в подписку на событие ПередЗаписью. // РежимПроведения - Булево - параметр, передаваемый в подписку на событие ПередЗаписью. // Процедура УстановитьПометкуУдаленияПрисоединенныхФайловДокументов(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт РаботаСФайлами.УстановитьПометкуУдаленияПрисоединенныхФайловДокументов(Источник, Отказ, РежимЗаписи, РежимПроведения); КонецПроцедуры // Обработчик подписки на событие ПередЗаписью владельца присоединенного файла. // Помечает на удаление связанные файлы. // // Параметры: // Источник - ОпределяемыйТип.ВладелецПрисоединенныхФайловОбъект - владелец присоединенного файла, кроме ДокументОбъект. // Отказ - Булево - признак отказа от записи. // Процедура УстановитьПометкуУдаленияПрисоединенныхФайлов(Источник, Отказ) Экспорт РаботаСФайлами.УстановитьПометкуУдаленияПрисоединенныхФайлов(Источник, Отказ); КонецПроцедуры #КонецОбласти #Область СлужебныеПроцедурыИФункции //////////////////////////////////////////////////////////////////////////////// // Обработчики подписок на события. // Обработчик подписки на событие ПередЗаписью для заполнения авто реквизитов присоединенного файла. // // Параметры: // Источник - СправочникОбъект - объект справочника с именем "*ПрисоединенныеФайлы". // Отказ - Булево - параметр, передаваемый в подписку на событие ПередЗаписью. // Процедура ВыполнитьДействияПередЗаписьюПрисоединенногоФайла(Источник, Отказ) Экспорт Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; Если Источник.ДополнительныеСвойства.Свойство("КонвертацияФайлов") Тогда Возврат; КонецЕсли; //В расширении этот механизм не предусмотрен, так что при включении, автор, думай как быть :) Если ТипЗнч(Источник) = Тип("СправочникОбъект.ВерсииФайлов") Тогда Если Не Источник.ЭтоНовый() И Не Пользователи.ЭтоПолноправныйПользователь() Тогда ПрежниеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "Автор"); ПроверитьИзменениеАвтораФайла(ПрежниеЗначения, Источник); КонецЕсли; Возврат; КонецЕсли; Если Источник.ЭтоНовый() Тогда // Проверка права "Добавление". Если НЕ РаботаСФайламиСлужебный.ЕстьПраво("ДобавлениеФайлов", Источник.ВладелецФайла) Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недостаточно прав для добавления файлов в папку ""%1"".'"), Строка(Источник.ВладелецФайла)); КонецЕсли; Иначе //Проверим, может передали ошибочно объект из БД... // Тут обрабатывается только объект из хранилища... ТипЗначенияРасширения = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл(); Если ТипЗначенияРасширения.СодержитТип(ТипЗнч(Источник.Ссылка)) <> Истина Тогда Возврат; КонецЕсли; //... Если Пользователи.ЭтоПолноправныйПользователь() Тогда ПрежниеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "ПометкаУдаления"); Иначе ПрежниеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "ПометкаУдаления, Автор, Редактирует, Изменил"); ПроверитьИзменениеАвтораФайла(ПрежниеЗначения, Источник); КонецЕсли; ИзмененаПометкаУдаления = Источник.ПометкаУдаления <> ПрежниеЗначения.ПометкаУдаления; Если ИзмененаПометкаУдаления Тогда // Проверка права "Пометка на удаление". Если НЕ РаботаСФайламиСлужебный.ЕстьПраво("ПометкаУдаленияФайлов", Источник.ВладелецФайла) Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недостаточно прав для пометки файлов на удаление в папке ""%1"".'"), Строка(Источник.ВладелецФайла)); КонецЕсли; КонецЕсли; Если ИзмененаПометкаУдаления И ЗначениеЗаполнено(Источник.Редактирует) Тогда Если Источник.Редактирует = Пользователи.АвторизованныйПользователь() Тогда ТекстОшибки = НСтр("ru = 'Действие недоступно, так как файл ""%1"" занят для редактирования.'"); ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки, Источник.Наименование); Иначе ТекстОшибки = НСтр("ru = 'Действие недоступно, так как файл ""%1"" занят для редактирования |пользователем %2.'"); ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки, Источник.Наименование, Строка(Источник.Редактирует)); КонецЕсли; КонецЕсли; ЗаписьПодписанногоОбъекта = Ложь; Если Источник.ДополнительныеСвойства.Свойство("ЗаписьПодписанногоОбъекта") Тогда ЗаписьПодписанногоОбъекта = Источник.ДополнительныеСвойства.ЗаписьПодписанногоОбъекта; КонецЕсли; Если ЗаписьПодписанногоОбъекта <> Истина Тогда СтруктураРеквизитов = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "ПодписанЭП, Зашифрован, Редактирует"); СсылкаПодписан = СтруктураРеквизитов.ПодписанЭП; СсылкаЗашифрован = СтруктураРеквизитов.Зашифрован; СсылкаЗанят = ЗначениеЗаполнено(СтруктураРеквизитов.Редактирует); Занят = ЗначениеЗаполнено(Источник.Редактирует); Если Не Источник.ЭтоГруппа И Источник.ПодписанЭП И СсылкаПодписан И Занят И Не СсылкаЗанят Тогда ВызватьИсключение НСтр("ru = 'Подписанный файл нельзя редактировать.'"); КонецЕсли; Если Не Источник.ЭтоГруппа И Источник.Зашифрован И СсылкаЗашифрован И Источник.ПодписанЭП И НЕ СсылкаПодписан Тогда ВызватьИсключение НСтр("ru = 'Зашифрованный файл нельзя подписывать.'"); КонецЕсли; КонецЕсли; СправочникПоддерживаетВозможностьХранитьВерсии = ОбщегоНазначения.ЕстьРеквизитОбъекта("ТекущаяВерсия", Метаданные.НайтиПоТипу(ТипЗнч(Источник))); Если Не Источник.ЭтоГруппа И СправочникПоддерживаетВозможностьХранитьВерсии И ЗначениеЗаполнено(Источник.ТекущаяВерсия) Тогда РеквизитыТекущейВерсии = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.ТекущаяВерсия, "Наименование"); // Проверим равенство имени файла и его текущей версии. // Если имена отличаются - имя у версии должно стать как у карточки с файлом. Если РеквизитыТекущейВерсии.Наименование <> Источник.Наименование И ЗначениеЗаполнено(Источник.ТекущаяВерсия) Тогда БлокировкаДанных = Новый БлокировкаДанных; ЭлементБлокировкиДанных = БлокировкаДанных.Добавить( Метаданные.НайтиПоТипу(ТипЗнч(Источник.ТекущаяВерсия)).ПолноеИмя()); ЭлементБлокировкиДанных.УстановитьЗначение("Ссылка", Источник.ТекущаяВерсия); БлокировкаДанных.Заблокировать(); Объект = Источник.ТекущаяВерсия.ПолучитьОбъект(); Если Объект <> Неопределено Тогда УстановитьПривилегированныйРежим(Истина); Объект.Наименование = Источник.Наименование; // Чтобы не сработала подписка СкопироватьРеквизитыВерсииФайловВФайл. Объект.ДополнительныеСвойства.Вставить("ПереименованиеФайла", Истина); Объект.Записать(); УстановитьПривилегированныйРежим(Ложь); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(Источник.ВладелецФайла) Тогда ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не заполнен владелец в файле |""%1"".'"), Источник.Наименование); Если ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы() Тогда ЗаписьЖурналаРегистрации(НСтр("ru = 'Файлы.Ошибка записи файла при обновлении ИБ'", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,, Источник.Ссылка, ОписаниеОшибки); Иначе ВызватьИсключение ОписаниеОшибки; КонецЕсли; КонецЕсли; Если Источник.ЭтоГруппа Тогда Источник.ИндексКартинки = 2; Иначе Источник.ИндексКартинки = РаботаСФайламиСлужебныйКлиентСервер.ПолучитьИндексПиктограммыФайла(Источник.Расширение); КонецЕсли; Если Источник.ЭтоНовый() И Не ЗначениеЗаполнено(Источник.Автор) Тогда Источник.Автор = Пользователи.АвторизованныйПользователь(); КонецЕсли; КонецПроцедуры // Обработчик подписки на событие ПередУдалением для удаления данных, связанных с присоединенным файлом. // // Параметры: // Источник - СправочникОбъект - объект справочника с именем "*ПрисоединенныеФайлы". // Отказ - Булево - параметр, передаваемый в подписку на событие ПередЗаписью. // Процедура ВыполнитьДействияПередУдалениемПрисоединенногоФайла(Источник, Отказ) Экспорт Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; Если ТипЗнч(Источник) = Тип("СправочникОбъект.ВерсииФайлов") Тогда Возврат; КонецЕсли; //Проверим, может передали ошибочно объект из БД... // Тут обрабатывается только объект из хранилища... ТипЗначенияРасширения = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл(); Если ТипЗначенияРасширения.СодержитТип(ТипЗнч(Источник.Ссылка)) <> Истина Тогда Возврат; КонецЕсли; //... СОГ_РаботаСФайламиСлужебный.ПередУдалениемПрисоединенногоФайлаСервер( Источник.Ссылка, Источник.ВладелецФайла, Источник.Том, Источник.ТипХраненияФайла, Источник.ПутьКФайлу); КонецПроцедуры // Обработчик подписки на событие ПриЗаписи для обновления данных, связанных с присоединенным файлом. // // Параметры: // Источник - СправочникОбъект - объект справочника с именем "*ПрисоединенныеФайлы". // Отказ - Булево - параметр, передаваемый в подписку на событие ПередЗаписью. // Процедура ВыполнитьДействияПриЗаписиПрисоединенногоФайла(Источник, Отказ) Экспорт Если Источник.ОбменДанными.Загрузка Тогда ЗаписатьДанныеФайлаВРегистрПриОбмене(Источник); Возврат; КонецЕсли; Если ТипЗнч(Источник) = Тип("СправочникОбъект.ВерсииФайлов") Тогда Возврат; КонецЕсли; //Проверим, может передали ошибочно объект из БД... // Тут обрабатывается только объект из хранилища... ТипЗначенияРасширения = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл(); Если ТипЗначенияРасширения.СодержитТип(ТипЗнч(Источник.Ссылка)) <> Истина Тогда Возврат; КонецЕсли; //... РаботаСФайламиСлужебный.ПриЗаписиПрисоединенногоФайлаСервер(Источник.ВладелецФайла, Источник); РаботаСФайламиСлужебный.ОбновитьСостояниеОчередиИзвлеченияТекста( Источник.Ссылка, Источник.СтатусИзвлеченияТекста); КонецПроцедуры #КонецОбласти #Область Дополнительные_Функции Процедура ЗаписатьДанныеФайлаВРегистрПриОбмене(Знач Источник) Перем ДвоичныеДанныеФайла; Если Источник.ДополнительныеСвойства.Свойство("ДвоичныеДанныеФайла", ДвоичныеДанныеФайла) Тогда НаборЗаписей = РегистрыСведений.СОГ_ДвоичныеДанныеФайлов.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Файл.Использование = Истина; НаборЗаписей.Отбор.Файл.Значение = Источник.Ссылка; Запись = НаборЗаписей.Добавить(); Запись.Файл = Источник.Ссылка; Запись.ДвоичныеДанныеФайла = Новый ХранилищеЗначения(ДвоичныеДанныеФайла, Новый СжатиеДанных(9)); НаборЗаписей.ОбменДанными.Загрузка = Истина; НаборЗаписей.Записать(); Источник.ДополнительныеСвойства.Удалить("ДвоичныеДанныеФайла"); КонецЕсли; КонецПроцедуры Функция НедопустимыйАвтор(АвторСсылка, ТекущийПользователь) // Можно изменять только с пустого значения на себя и наоборот. Возврат АвторСсылка <> Неопределено И Не АвторСсылка.Пустая() И ТипЗнч(АвторСсылка) <> Тип("СправочникСсылка.УчетныеЗаписиСинхронизацииФайлов") И АвторСсылка <> ТекущийПользователь; КонецФункции Процедура ПроверитьИзменениеАвтораФайла(Знач ПрежниеЗначения, Знач Источник) ИзмененАвтор = Источник.Автор <> ПрежниеЗначения.Автор; Если ИзмененАвтор Тогда ВызватьИсключение НСтр("ru = 'Недостаточно прав для изменения автора файла.'"); КонецЕсли; Если ТипЗнч(Источник) = Тип("СправочникОбъект.ВерсииФайлов") Тогда Возврат; КонецЕсли; ТекущийПользователь = Пользователи.АвторизованныйПользователь(); Если Источник.Редактирует <> ПрежниеЗначения.Редактирует И (НедопустимыйАвтор(Источник.Редактирует, ТекущийПользователь) Или НедопустимыйАвтор(ПрежниеЗначения.Редактирует, ТекущийПользователь)) Тогда ВызватьИсключение НСтр("ru = 'Недостаточно прав для редактирования файла.'"); КонецЕсли; Если Источник.Изменил <> ПрежниеЗначения.Изменил И (НедопустимыйАвтор(Источник.Изменил, ТекущийПользователь) Или НедопустимыйАвтор(ПрежниеЗначения.Изменил, ТекущийПользователь)) Тогда ВызватьИсключение НСтр("ru = 'Недостаточно прав для редактирования файла.'"); КонецЕсли; КонецПроцедуры #КонецОбласти Общий модуль = СОГ_РаботаСФайламиСлужебный #Область ОбработчикиПодписокНаСобытия // Обработчик подписки на событие "Перед удалением" присоединенного файла. Процедура ПередУдалениемПрисоединенногоФайлаСервер(Знач Ссылка, Знач ВладелецФайлов, Знач Том, Знач ТипХраненияФайла, Знач ПутьКФайлу) Экспорт УстановитьПривилегированныйРежим(Истина); Если ВладелецФайлов <> Неопределено И Не ЕстьФайлыУВладельца(ВладелецФайлов, Ссылка) Тогда НачатьТранзакцию(); Попытка БлокировкаДанных = Новый БлокировкаДанных; ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(Метаданные.РегистрыСведений.СОГ_НаличиеФайлов.ПолноеИмя()); ЭлементБлокировкиДанных.УстановитьЗначение("ОбъектСФайлами", ВладелецФайлов); БлокировкаДанных.Заблокировать(); МенеджерЗаписи = РегистрыСведений.СОГ_НаличиеФайлов.СоздатьМенеджерЗаписи(); МенеджерЗаписи.ОбъектСФайлами = ВладелецФайлов; МенеджерЗаписи.Прочитать(); Если МенеджерЗаписи.Выбран() Тогда МенеджерЗаписи.ЕстьФайлы = Ложь; МенеджерЗаписи.Записать(); КонецЕсли; ЗафиксироватьТранзакцию(); Исключение ОтменитьТранзакцию(); ВызватьИсключение; КонецПопытки; КонецЕсли; КонецПроцедуры // Обработчик подписки "при записи" присоединенного файла. // Процедура ПриЗаписиПрисоединенногоФайлаСервер(ВладелецФайлов, Источник) Экспорт УстановитьПривилегированныйРежим(Истина); НачатьТранзакцию(); Попытка ЗаписьИзменилась = Ложь; БлокировкаДанных = Новый БлокировкаДанных; ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(Метаданные.РегистрыСведений.СОГ_НаличиеФайлов.ПолноеИмя()); ЭлементБлокировкиДанных.УстановитьЗначение("ОбъектСФайлами", ВладелецФайлов); БлокировкаДанных.Заблокировать(); МенеджерЗаписи = РегистрыСведений.СОГ_НаличиеФайлов.СоздатьМенеджерЗаписи(); МенеджерЗаписи.ОбъектСФайлами = ВладелецФайлов; МенеджерЗаписи.Прочитать(); Если НЕ ЗначениеЗаполнено(МенеджерЗаписи.ОбъектСФайлами) Тогда МенеджерЗаписи.ОбъектСФайлами = ВладелецФайлов; ЗаписьИзменилась = Истина; КонецЕсли; ЕстьФайлы = НЕ Источник.ПометкаУдаления ИЛИ ЕстьФайлыУВладельца(ВладелецФайлов); Если МенеджерЗаписи.ЕстьФайлы <> ЕстьФайлы Тогда МенеджерЗаписи.ЕстьФайлы = ЕстьФайлы; ЗаписьИзменилась = Истина; КонецЕсли; Если ПустаяСтрока(МенеджерЗаписи.ИдентификаторОбъекта) Тогда МенеджерЗаписи.ИдентификаторОбъекта = ПолучитьОчереднойИдентификаторОбъекта(); ЗаписьИзменилась = Истина; КонецЕсли; Если ЗаписьИзменилась Тогда МенеджерЗаписи.Записать(); КонецЕсли; Если Не Источник.ЭтоГруппа Тогда МенеджерЗаписи = РегистрыСведений.СОГ_СведенияОФайлах.СоздатьМенеджерЗаписи(); ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Источник); МенеджерЗаписи.Файл = Источник.Ссылка; Если Источник.ПодписанЭП И Источник.Зашифрован Тогда МенеджерЗаписи.НомерКартинкиПодписанЗашифрован = 2; ИначеЕсли Источник.Зашифрован Тогда МенеджерЗаписи.НомерКартинкиПодписанЗашифрован = 1; ИначеЕсли Источник.ПодписанЭП Тогда МенеджерЗаписи.НомерКартинкиПодписанЗашифрован = 0; Иначе МенеджерЗаписи.НомерКартинкиПодписанЗашифрован = -1; КонецЕсли; МенеджерЗаписи.Записать(); КонецЕсли; ЗафиксироватьТранзакцию(); Исключение ОтменитьТранзакцию(); ВызватьИсключение; КонецПопытки; КонецПроцедуры #КонецОбласти #Область Дополнительные_Функции Функция ЕстьФайлыУВладельца(Знач ВладелецФайлов, Знач ФайлИсключение = Неопределено) Запрос = Новый Запрос; ТекстЗапроса = "ВЫБРАТЬ | ПрисоединенныеФайлы.Ссылка |ИЗ | &ИмяСправочника КАК ПрисоединенныеФайлы |ГДЕ | НЕ ПрисоединенныеФайлы.ПометкаУдаления | И ПрисоединенныеФайлы.ВладелецФайла = &ВладелецФайлов | И &ФайлИсключение"; Запрос.Параметры.Вставить("ВладелецФайлов", ВладелецФайлов); Если ФайлИсключение <> Неопределено Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ФайлИсключение", "ПрисоединенныеФайлы.Ссылка <> &ФайлИсключение"); // @Query-part-2 Запрос.Параметры.Вставить("ФайлИсключение", ФайлИсключение); Иначе ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ФайлИсключение", "ИСТИНА"); // @Query-part-2 КонецЕсли; ИменаСправочников = РаботаСФайламиСлужебный.ИменаСправочниковХраненияФайлов(ВладелецФайлов); Для каждого КлючИЗначение Из ИменаСправочников Цикл Запрос.Текст = СтрЗаменить(ТекстЗапроса, "&ИмяСправочника", "Справочник." + КлючИЗначение.Ключ); УстановитьПривилегированныйРежим(Истина); Если НЕ Запрос.Выполнить().Пустой() Тогда Возврат Истина; КонецЕсли; УстановитьПривилегированныйРежим(Ложь); КонецЦикла; Возврат Ложь; КонецФункции // Возвращает новый идентификатор объекта. // Для получения нового идентификатора выбирает последний идентификатор объекта // из регистра НаличиеПрисоединенныхФайлов увеличивает его значение // на одну единицу и возвращает полученный результат. // // Возвращаемое значение: // Строка - строка (10) - новый идентификатор объекта. // Функция ПолучитьОчереднойИдентификаторОбъекта() Экспорт // Вычисление нового идентификатора объекта. Результат = "0000000000"; // По длине ресурса ИдентификаторОбъекта. ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ 1 | НаличиеФайлов.ИдентификаторОбъекта КАК ИдентификаторОбъекта |ИЗ | РегистрСведений.СОГ_НаличиеФайлов КАК НаличиеФайлов | |УПОРЯДОЧИТЬ ПО | ИдентификаторОбъекта УБЫВ"; Запрос = Новый Запрос; Запрос.Текст = ТекстЗапроса; Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Идентификатор = Выборка.ИдентификаторОбъекта; Если ПустаяСтрока(Идентификатор) Тогда Возврат Результат; КонецЕсли; // Правила вычисления, как в обычном сложении: при // заполнении текущего разряда следующий разряд увеличивается // на единицу, при этом, в текущем разряде значение становится // равным нулю. Значениями разрядов выступают символы // [0..9] и [a..z]. Таким образом один разряд может содержать // 36 значений. Позиция = 10; // 9- индекс 10-го символа Пока Позиция > 0 Цикл Символ = Сред(Идентификатор, Позиция, 1); Если Символ = "z" Тогда Идентификатор = Лев(Идентификатор, Позиция-1) + "0" + Прав(Идентификатор, 10 - Позиция); Позиция = Позиция - 1; Продолжить; ИначеЕсли Символ = "9" Тогда НовыйСимвол = "a"; Иначе НовыйСимвол = Символ(КодСимвола(Символ)+1); КонецЕсли; Идентификатор = Лев(Идентификатор, Позиция-1) + НовыйСимвол + Прав(Идентификатор, 10 - Позиция); Прервать; КонецЦикла; Результат = Идентификатор; КонецЕсли; Возврат Результат; КонецФункции #КонецОбласти |
|||
8
DrZombi
гуру
14.09.22
✎
15:01
|
+(7) "ПолучитьОписаниеТипов_ОпределяемыеТипы_ПредметНапоминания" это лишнее, вам же только фалы ;)
|
|||
9
DrZombi
гуру
14.09.22
✎
15:04
|
+ ПолучитьОписаниеТипов_ОпределяемыеТипы_ВладелецПрисоединенныхФайлов - для примера
//ОпределяемыйТип.ВладелецПрисоединенныхФайлов Функция ПолучитьОписаниеТипов_ОпределяемыеТипы_ВладелецПрисоединенныхФайлов() Экспорт МассивТипов = Новый Массив; МассивТипов.Добавить(Тип("СправочникСсылка.ШаблоныСообщений")); // МассивТипов.Добавить(Тип("ДокументСсылка.СообщениеSMS")); // МассивТипов.Добавить(Тип("ДокументСсылка.ВключениеВКадровыйРезерв")); // ОписТипа = Новый ОписаниеТипов(МассивТипов); Возврат ОписТипа; КонецФункции |
|||
10
sitex
naïve
14.09.22
✎
15:07
|
(0) Если не хочешь снимать с поддержки обновляй платформу и далее создать и хранить в расширении.
|
|||
11
DrZombi
гуру
14.09.22
✎
15:40
|
+(0) Для самого вашего объекта "Справочника" или "Документа" так же надо подписку на удаление файлов.
ПодпискаНаСобытие.СОГ_УстановитьПометкуУдаленияПрисоединенныхФайловДокументов.Источник //см. в общий модуль "СОГ_РаботаСФайлами.УстановитьПометкуУдаленияПрисоединенныхФайловДокументов" или Для справочника в "СОГ_РаботаСФайлами.УстановитьПометкуУдаленияПрисоединенныхФайлов" |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |