Загрузка данных
#Область ПрограммныйИнтерфейс
// Функция выполняет действие:
// Записать Файлы Из Формы Предпросмотра
//
// Параметры:
// Таб - Произвольный
// СсылкаНаДокумент - Произвольный
Процедура ЗаписатьФайлыИзФормыПредпросмотра(Таб, СсылкаНаДокумент) Экспорт
// Определим, есть ли файлы к записи
ЕстьФайлыНовые = ЛОЖЬ;
Для Каждого Строка Из Таб Цикл
Если Строка.ЭтоНовыйФайл Тогда
ЕстьФайлыНовые = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЕстьФайлыНовые Тогда
Возврат;
КонецЕсли;
СтруктураСпособаХранения = ПолучитьСпособХранения();
Если СтруктураСпособаХранения = Неопределено Тогда
МассивКУдалению = Новый Массив;
// Уберем все прикрепленные в предпросмотре файлы
Для Каждого Строка Из Таб Цикл
Если Строка.ЭтоНовыйФайл Тогда
Если ЭтоАдресВременногоХранилища(Строка.Путь) Тогда
УдалитьИзВременногоХранилища(Строка.Путь);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого Строка Из МассивКУдалению Цикл
Таб.Удалить(Строка);
КонецЦикла;
КонецЕсли;
Набор = РегистрыСведений.ПрикрепленныеФайлы.СоздатьНаборЗаписей();
Набор.Отбор.ИспользуемыйДокумент.Установить( СсылкаНаДокумент );
ТекДата = ЧасовыеПоясаСервер.ТекущееВремяИБ();
Для Каждого Строка Из Таб Цикл
Если Строка.ЭтоНовыйФайл Тогда
НоваяЗапись = Набор.Добавить();
ЗаполнитьСтрокуИМенеджерЗаписиИзФормыПредпросмотра(НоваяЗапись, Строка, СтруктураСпособаХранения, СсылкаНаДокумент, ТекДата);
КонецЕсли;
КонецЦикла;
Набор.Записать( ЛОЖЬ );
КонецПроцедуры
// Процедура выполняет действие:
// Получить Массив Структур Файлов Документа
//
// Параметры:
// Документ - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьМассивСтруктурФайловДокумента(Документ) Экспорт
МассивРезультат = Новый Массив;
ТипДокумента = Метаданные.НайтиПоТипу(ТипЗнч(Документ)).Имя;
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ
| ПрикрепленныеФайлы.UUID,
| ПрикрепленныеФайлы.Название
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| Выразить(ПрикрепленныеФайлы.ИспользуемыйДокумент КАК %2.%1)= &Документ";
Если ТипЗнч(Документ) = Тип("СправочникСсылка.ШаблоныСообщений") Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "%2", "Справочник");
Иначе
Запрос.Текст = СтрЗаменить(Запрос.Текст, "%2", "Документ");
КонецЕсли;
Запрос.Текст = СтрЗаменить(Запрос.Текст, "%1", ТипДокумента);
Запрос.УстановитьПараметр("Документ", Документ);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
МассивРезультат.Добавить(Новый Структура("ИмяФайла,ИдФайла",ВыборкаДетальныеЗаписи.Название, ВыборкаДетальныеЗаписи.UUID));
КонецЦикла;
Возврат МассивРезультат;
КонецФункции
// Процедура выполняет действие:
// Получить Количество Файлов Документа
//
// Параметры:
// СсылкаНаДокумент - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьКоличествоФайловДокумента(СсылкаНаДокумент)Экспорт
ИмяТипа = Метаданные.НайтиПоТипу(ТипЗнч(СсылкаНаДокумент)).Имя;
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ
| КОЛИЧЕСТВО(ПрикрепленныеФайлы.UUID) КАК UUID
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| Выразить(ПрикрепленныеФайлы.ИспользуемыйДокумент КАК Документ.%1) = &Документ";
Запрос.УстановитьПараметр("Документ", СсылкаНаДокумент);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "%1", ИмяТипа);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Возврат ВыборкаДетальныеЗаписи.UUID;
КонецЦикла;
Возврат 0;
КонецФункции
// Процедура выполняет действие:
// Записать Файлы По Списку Помеченных
//
// Параметры:
// УникальныйИдентификатор - Произвольный
// СписокПрикрепленныхФайлов - Произвольный
// СсылкаНаДокумент - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ЗаписатьФайлыПоСпискуПомеченных(УникальныйИдентификатор, СписокПрикрепленныхФайлов, СсылкаНаДокумент)Экспорт
тзПрикрепленныеФайлы = Новый ТаблицаЗначений;
тзПрикрепленныеФайлы.Колонки.Добавить("UUID");
тзПрикрепленныеФайлы.Колонки.Добавить("Дата");
тзПрикрепленныеФайлы.Колонки.Добавить("Название");
тзПрикрепленныеФайлы.Колонки.Добавить("Описание");
тзПрикрепленныеФайлы.Колонки.Добавить("СпособХранения");
тзПрикрепленныеФайлы.Колонки.Добавить("ПометкаУдаления");
тзПрикрепленныеФайлы.Колонки.Добавить("ТипФайла");
тзПрикрепленныеФайлы.Колонки.Добавить("Путь");
ТекДата = ЧасовыеПоясаСервер.ТекущееВремяИБ();
Кол = 0;
Для Каждого ЭлСписка Из СписокПрикрепленныхФайлов Цикл
Если ЭлСписка.Пометка Тогда
Кол = Кол + 1;
НСТр = ТЗПрикрепленныеФайлы.Добавить();
ЗаполнитьЗначенияСвойств(НСТр,ЭлСписка.Значение,,"UUID");
Нстр.Дата = ТекДата;
Если Нстр.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.УдаленнаяДиректория")
ИЛИ Нстр.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.ИнформационнаяБаза") Тогда
Нстр.Путь = ИТ_ОбщиеФункцииФормДокументовСервер
.ПолучитьПутьДоФайлаИзУдаленнойДиректорииНаСервере(
ЭлСписка.Значение.UUID,
НСтр.Название,
ЭлСписка.Значение.Хранилище,
УникальныйИдентификатор,
Нстр.СпособХранения);
КонецЕсли;
Если Нстр.Путь = Неопределено Тогда
ТЗПрикрепленныеФайлы.Удалить(Нстр);
КонецЕсли;
КонецЕсли;
КонецЦикла;
пфЗаписатьПрикрепленныеФайлы(СсылкаНаДокумент , тзПрикрепленныеФайлы,,ЛОЖЬ);
Возврат Кол;
КонецФункции
// Процедура выполняет действие:
// Получить Массив Структур Для Списка Идентификаторов
//
// Параметры:
// СсылкаНаДокумент - Произвольный
//
// Возвращаемое значение:
// Произвольный
функция ПолучитьМассивСтруктурДляСпискаИдентификаторов(СсылкаНаДокумент) Экспорт
Таблица = ДобавитьПолеКартинкиВТаблицуФайлов(ПрикрепленныеФайлыСервер.пфПолучитьСписокПрикрепленныхФайлов(СсылкаНаДокумент));
Массив = Новый Массив;
Для Каждого Строка Из Таблица Цикл
Стр = Новый Структура("UUID, Название, Картинка");
ЗаполнитьЗначенияСвойств( Стр , Строка);
Массив.Добавить(Стр);
КонецЦикла;
Возврат Массив;
КонецФункции
// Составляет полное имя файла из имени каталога и имени файла.
//
// ИмяКаталога – Строка, содержащая путь к каталогу файла на диске.
// ИмяФайла – Строка, содержащая имя файла, без имени каталога.
// :
// Строка – полное имя файла с учетом каталога.
//
// Параметры:
// ИмяКаталога - Произвольный
// ИмяФайла - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьИмяФайла(ИмяКаталога, ИмяФайла) Экспорт
Если Не ПустаяСтрока(ИмяФайла) Тогда
Возврат ИмяКаталога + ?(Прав(ИмяКаталога, 1) = "\", "", "\") + ИмяФайла;
Иначе
Возврат ИмяКаталога;
КонецЕсли;
КонецФункции // ПолучитьИмяФайла()
// Формирует имя каталога для сохранения/чтения файлов. Для различных типов объектов возможны
// различные алгоритмы определения каталога.
//
// ОбъектФайла – Ссылка на объект данных, для которого прикрепляются файлы.
// :
// Строка – каталог файлов для указанного объекта и пользователя.
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьИмяКаталога() Экспорт
// Получим рабочий каталог из свойств пользователя.
// РабочийКаталог = ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнойКаталогФайлов");
РабочийКаталог = "";
// Если рабочий каталог не указан получим каталог временных файлов прогаммы
Если ПустаяСтрока(РабочийКаталог) Тогда
РабочийКаталог = КаталогВременныхФайлов();
КонецЕсли;
// Так как при различных указаниях рабочего каталога возможно наличие или отсутствие
// последнего слеша, приведем строку каталога к унифицированному виду - без слеша на конце.
Если Прав(РабочийКаталог, 1) = "\" Тогда
РабочийКаталог = Лев(РабочийКаталог, СтрДлина(РабочийКаталог) - 1);
КонецЕсли;
Возврат РабочийКаталог;
КонецФункции // ПолучитьИмяКаталога()
// ////////////////////////////////////////////////////////////////////////////////
// Модуль описывает работу системы с прикрепленными файлами
// Функция проверки существования указанной директории
// :
// - Директория
//
// - Структура с кодом ошибки.
//
// Параметры:
// Директория - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция пфПроверитьДиректорию(Директория) Экспорт
КодОшибки = Новый Структура("КодОшибки");
ВыбКаталог = Новый Файл(Директория);
// Проверяем существует ли выбранный каталог
Если Не ВыбКаталог.Существует() Тогда
КодОшибки.КодОшибки = "Выбранный каталог недоступен с сервера 1С:Предприятия.";
ИначеЕсли Не ВыбКаталог.ЭтоКаталог() Тогда
КодОшибки.КодОшибки = "Каталог не существует (выбранный путь указывает на файл).";
КонецЕсли;
Возврат КодОшибки;
КонецФункции
// Функция заполняющая и инициализирующая таблицу значений для документа
// Передаваемое значение:
// - Документ - ссылка на документ, для которого требуется получить список файлов
// - Таблица, параметр указывающий дополнительную табличную часть
// :
// Структура описывающая таблицу данных отображающая файлы
//
// Параметры:
// Документ - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция пфПолучитьСписокПрикрепленныхФайлов(Документ) Экспорт
Если Не ЗначениеЗаполнено(Документ) Тогда
// Возвращаем только файловую структуру
тзПрикрепленныеФайлы = Новый ТаблицаЗначений;
тзПрикрепленныеФайлы.Колонки.Добавить("UUID");
тзПрикрепленныеФайлы.Колонки.Добавить("Дата");
тзПрикрепленныеФайлы.Колонки.Добавить("Название");
тзПрикрепленныеФайлы.Колонки.Добавить("Описание");
тзПрикрепленныеФайлы.Колонки.Добавить("СпособХранения");
тзПрикрепленныеФайлы.Колонки.Добавить("ПометкаУдаления");
тзПрикрепленныеФайлы.Колонки.Добавить("ТипФайла");
тзПрикрепленныеФайлы.Колонки.Добавить("Путь");
Иначе // Если ЗначениеНеЗаполнено(Документ) Тогда ...
// Формируем запрос, получающий значение по регистратору
ЗапросСсылкаНаДокумент= "";
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Документ)) Тогда
ЗапросСсылкаНаДокумент = " ПрикрепленныеФайлы.ИспользуемыйДокумент ССЫЛКА Справочник." + Документ.Метаданные().Имя + " И ";
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Документ)) Тогда
ЗапросСсылкаНаДокумент = " ПрикрепленныеФайлы.ИспользуемыйДокумент ССЫЛКА Документ." + Документ.Метаданные().Имя+ " И ";
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка", Документ);
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.UUID,
| ПрикрепленныеФайлы.Название,
| ПрикрепленныеФайлы.Описание,
| ПрикрепленныеФайлы.ТипФайла КАК ТипФайла,
| ПрикрепленныеФайлы.ДатаИзменения КАК Дата,
| ПрикрепленныеФайлы.СпособХранения,
// | ПрикрепленныеФайлы.ПутьДоФайла КАК Путь, не открывать, в противном случае прикрепеление файлов ПО почте НЕ работ
// ает
| ЛОЖЬ КАК ПометкаУдаления
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| "+ ЗапросСсылкаНаДокумент + " ПрикрепленныеФайлы.ИспользуемыйДокумент = &Ссылка" ;
тзПрикрепленныеФайлы = Запрос.Выполнить().Выгрузить();
// Добавляем дополнительные колонки
тзПрикрепленныеФайлы.Колонки.Добавить("Путь");
тзПрикрепленныеФайлы.Колонки.Добавить("Отметка");
КонецЕсли; // Если ЗначениеНеЗаполнено(Документ) Тогда ... Иначе ...
Возврат тзПрикрепленныеФайлы;
КонецФункции
// Процедура удаляетя привязанные к документу прикрепленные файлы
// Параметр:
// Документ - ссылка на документ
//
// Параметры:
// Документ - Произвольный
//
// Возвращаемое значение:
// Произвольный
Процедура пфУдалитьПрикрепленныеФайлы(Документ) Экспорт
// Получаем набор записей
НаборЗаписей = РегистрыСведений.ПрикрепленныеФайлы.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ИспользуемыйДокумент.Установить(Документ);
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
// Если храним файл в удаленной директории, тогда удаляем файл из удаленной директории
Если Запись.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Тогда
Попытка
УдалитьФайлы(ПолучитьУдаленнуюДиректорию(),Запись.Название);
Исключение
Ошибка = ОписаниеОшибки();
КонецПопытки;
// Иначе ничего не делаем
// не удаляем ссылки на файлы на сервере
// и чуть позже удалять и файлы содержащиеся в базе данных
КонецЕсли;
КонецЦикла;
НаборЗаписей.Очистить();
НаборЗаписей.Записать();
КонецПроцедуры
// Процедура выполняет действие:
// Записать Файлы По Списку Отмеченных
//
// Параметры:
// Результат - Произвольный
// СсылкаНаДокумент - Произвольный
// СписокФайловДляВыбора - Произвольный
// УИ - Произвольный
// Решение - Произвольный
// Очищать - Произвольный
//
// Возвращаемое значение:
// Произвольный
функция ЗаписатьФайлыПоСпискуОтмеченных(Результат, СсылкаНаДокумент, СписокФайловДляВыбора, УИ, Решение, Очищать = Истина) Экспорт
тзПрикрепленныеФайлы = Новый ТаблицаЗначений;
тзПрикрепленныеФайлы.Колонки.Добавить("Дата");
тзПрикрепленныеФайлы.Колонки.Добавить("Название");
тзПрикрепленныеФайлы.Колонки.Добавить("Описание");
тзПрикрепленныеФайлы.Колонки.Добавить("ТипФайла");
тзПрикрепленныеФайлы.Колонки.Добавить("UUID");
тзПрикрепленныеФайлы.Колонки.Добавить("СпособХранения");
тзПрикрепленныеФайлы.Колонки.Добавить("ПометкаУдаления");
тзПрикрепленныеФайлы.Колонки.Добавить("Путь");
тзПрикрепленныеФайлы.Колонки.Добавить("Картинка");
Для Каждого ФайлИзСписка Из СписокФайловДляВыбора Цикл
Если ФайлИзСписка.Пометка Тогда
НС = тзПрикрепленныеФайлы.Добавить();
НС.Дата = ЧасовыеПоясаСервер.ТекущееВремяИБ();
ЗаполнитьЗначенияСвойств(НС, Результат.Получить(ФайлИзСписка.Значение));
НС.UUID = ФайлИзСписка.Значение;
Если НС.СпособХранения <> Неопределено Тогда
Если НС.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.ИнформационнаяБаза") Тогда
НС.Картинка = БиблиотекаКартинок.ВложениеХранилище;
НС.Путь = ИТ_ОбщиеФункцииФормДокументовСервер.ПолучитьПутьДоФайлаИзУдаленнойДиректорииНаСервере(ФайлИзСписка.Значение,
НС.Название,
Неопределено,
УИ,
НС.СпособХранения,
Решение);
ИначеЕсли НС.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.УдаленнаяДиректория") Тогда
НС.Картинка = БиблиотекаКартинок.ВложениеУдаленное;
НС.Путь = ИТ_ОбщиеФункцииФормДокументовСервер.ПолучитьПутьДоФайлаИзУдаленнойДиректорииНаСервере(ФайлИзСписка.Значение,
НС.Название,
Неопределено,
УИ,
НС.СпособХранения);
ИначеЕсли НС.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.ПроизвольнаяДиректория") Тогда
НС.Картинка = БиблиотекаКартинок.ВложениеВнешнее;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
пфЗаписатьПрикрепленныеФайлы(СсылкаНаДокумент , тзПрикрепленныеФайлы,,Очищать);
Возврат тзПрикрепленныеФайлы.Количество();
КонецФункции
// Процедура записи табличной части файлов
// :
// Документ - документ, к которому прикрепляются файлы
// ТаблицаЗначений - Таблица, для которой записываются файлы
// Таблица - Дополнительная таблица, используемая для хранения файлов в разных разрезах
// Запись файлов делиться на три этапа:
// 1. Поиск изменений
// 2. Удаление удаленных файлов
// 3. Добавление новых файлов
//
// Параметры:
// Документ - Произвольный
// ТаблицаЗначений - Произвольный
// ТекущийПользователь - Произвольный
// Очищать - Произвольный
// ЭлектронноеПисьмо - Произвольный
// МассивUUIDФайлов - Произвольный
// ПерезаписыватьУжеСуществующие - Булево
Процедура пфЗаписатьПрикрепленныеФайлы(Документ, ТаблицаЗначений,
ТекущийПользователь = Неопределено,
Очищать = Истина,
ЭлектронноеПисьмо = Неопределено,
МассивUUIDФайлов = Неопределено,
ПерезаписыватьУжеСуществующие = Истина) Экспорт
// Создаем набор записей
НаборЗаписей = РегистрыСведений.ПрикрепленныеФайлы.СоздатьНаборЗаписей();
// Текущий пользователь
Если Не ЗначениеЗаполнено(ТекущийПользователь) Тогда
ТекущийПользователь = ИТ_ГлобальныйМодульСервер.ИТ_глЗначениеПеременной("глТекущийПользователь");
КонецЕсли;
ТекДата = ТекущаяДата();
// Читаем набор записей из базы, для указанного документа
НаборЗаписей.Отбор.ИспользуемыйДокумент.Установить(Документ);
НаборЗаписей.Прочитать();
Инд = НаборЗаписей.Количество() - 1;
// ЭтоНовый = Ложь;
//
// Если Инд<0 Тогда
// ЭтоНовый = Истина;
// КонецЕсли;
Изменено = Ложь;
// Перебираем элементы коллекции
Пока Инд >= 0 И ПерезаписыватьУжеСуществующие Цикл
Запись = НаборЗаписей.Получить(Инд);
// Ищем запись в таблице значений
СтрокаТаблицы = ТаблицаЗначений.Найти(Запись.UUID, "UUID");
// Если запись не найдена, тогда удаляем запись
Если СтрокаТаблицы = Неопределено Тогда
// УДАЛЕНИЕ ЗАПИСИ
//
Если Очищать Тогда
// Удаляем файл, только в том случае, если тип записи был в удаленную директорию
Если Запись.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Тогда
Попытка
УдалитьФайлы(ПолучитьУдаленнуюДиректорию(), ПолучитьСкрытоеНазвание(Запись.Название, Запись.UUID));
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
НаборЗаписей.Удалить(Инд);
Изменено = Истина;
КонецЕсли;
Иначе // Если СтрокаТаблицы = Неопределено Тогда ...
// РЕДАКТИРОВАНИЕ ЗАПИСИ
//
// Редактируем запись, если содержание таблицы отличается
Если ЗначениеЗаполнено(СтрокаТаблицы.Путь) Тогда
Запись.Название = СтрокаТаблицы.Название;
Запись.Описание = СтрокаТаблицы.Описание;
Запись.Редактор = ТекущийПользователь;
Запись.ТипФайла = СтрокаТаблицы.ТипФайла;
Запись.ДатаИзменения = ТекДата;
// Процедура записи файла
// если файл требуется хранить в произвольном месте
Если СтрокаТаблицы.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория;
Запись.ПутьДоФайла = СтрокаТаблицы.Путь;
Запись.Хранилище = Неопределено;
ИначеЕсли СтрокаТаблицы.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Или ПолучениеЗначенийСервер.ПолучитьПараметр("ХранитьФайлыВПапке") = ИСТИНА Тогда // Если ... = ПроизвольнаяДиректория Тогда
// Указываем способ записи файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
Запись.Хранилище = Неопределено;
// Сохраняем файлы в указанной папке
Если ТипЗнч(СтрокаТаблицы.Путь) = Тип("ХранилищеЗначения") Тогда
Хранилище = СтрокаТаблицы.Путь;
Иначе
Хранилище = ПолучитьЗначениеДляХранилища(СтрокаТаблицы.Путь);
КонецЕсли;
ЗаписатьФайлВПапку(Хранилище, СтрокаТаблицы.Название, СтрокаТаблицы.UUID, СтрокаТаблицы.Путь);
Иначе // Если ... = УдаленнаяДиректория Тогда
// Указываем способ записи файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
// Записываем файл в хранилище
// Если файл уже содержит ссылку на хранилище, тогда записываем хранилище
Если ТипЗнч(СтрокаТаблицы.Путь) = Тип("ХранилищеЗначения") Тогда
Запись.Хранилище = СтрокаТаблицы.Путь;
Иначе
Запись.Хранилище = ПолучитьЗначениеДляХранилища(СтрокаТаблицы.Путь);
КонецЕсли;
КонецЕсли; // Если ... = ИнформационнаяБаза Тогда
Изменено = Истина;
КонецЕсли; // Если Не ЗначениеНеЗаполнено(СтрокаТаблицы.Путь) Тогда
// Проверяем изменилось ли описание
Если Запись.Описание <> СтрокаТаблицы.Описание Тогда
Запись.Описание = СтрокаТаблицы.Описание;
Изменено = Истина;
КонецЕсли;
Если Запись.ТипФайла <> СтрокаТаблицы.ТипФайла Тогда
Запись.ТипФайла = СтрокаТаблицы.ТипФайла;
Изменено = Истина;
КонецЕсли;
// Проверяем изменилось ли название
Если Запись.Название <> СтрокаТаблицы.Название Тогда
Запись.Название = СтрокаТаблицы.Название;
Изменено = Истина;
КонецЕсли;
КонецЕсли; // Если СтрокаТаблицы = Неопределено Тогда ... Иначе ...
// Переходим к следующей записи
Инд = Инд -1;
КонецЦикла;
// Если были изменения, тогда их записываем
Если Изменено Тогда
НаборЗаписей.Записать();
НаборЗаписей.Отбор.ИспользуемыйДокумент.Установить(Документ);
КонецЕсли;
Если Очищать Тогда
НаборЗаписей.Очистить();
КонецЕсли;
// ДОБАВЛЕНИЕ НОВЫХ ФАЙЛОВ
//
// Выбираем из таблицы ТОЛЬКО новые значения
Изменено = Ложь;
МассивUUIDФайлов = Новый Массив;
Для Каждого Файл Из ТаблицаЗначений Цикл
// Предварительно сохраним в текстовый файл аттач
Если ТипЗнч(Файл.Путь) = Тип("ИнтернетПочтовоеСообщение") Тогда
СохранитьВложенныеПисьма(Документ,
ТекущийПользователь,
ТекДата,
НаборЗаписей,
Файл.Путь,
ЭлектронноеПисьмо);
Изменено = Истина;
Иначе
// Если добавляется новый файл, тогда
Если ЗначениеЗаполнено(Файл.UUID) И ЗначениеЗаполнено(Файл.Название) И ПерезаписыватьУжеСуществующие Тогда
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.ИспользуемыйДокумент КАК Документ,
| ПрикрепленныеФайлы.UUID,
| ПрикрепленныеФайлы.СпособХранения
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.ИспользуемыйДокумент = &Документ
| И ПрикрепленныеФайлы.UUID = &UUID";
Запрос.УстановитьПараметр("UUID", Файл.UUID);
Запрос.УстановитьПараметр("Документ", Документ);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
ЗаписатьФайл(Документ, ТекущийПользователь, ТекДата, НаборЗаписей, Файл, ЭлектронноеПисьмо);
Изменено = Истина;
КонецЕсли
КонецЕсли;
Если Не ЗначениеЗаполнено(Файл.UUID) И ЗначениеЗаполнено(Файл.Название) Тогда
НовыйUUID = Неопределено;
ЗаписатьФайл(Документ, ТекущийПользователь, ТекДата, НаборЗаписей, Файл, ЭлектронноеПисьмо, НовыйUUID);
Файл.UUID = НовыйUUID;
Изменено = Истина;
КонецЕсли; // Если ЗначениеНеЗаполнено(Файл.UUID) Тогда ...
МассивUUIDФайлов.Добавить(Файл.UUID);
КонецЕсли;
КонецЦикла; // Для Каждого Файл Из ТаблицаЗначений Цикл ...
// Если были изменения, тогда их записываем
Если Изменено Тогда
Попытка
Если Очищать Тогда
НаборЗаписей.Записать(ЛОЖЬ);
Иначе
НаборЗаписей.Записать(Истина);
КонецЕсли;
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
НаборЗаписей.Очистить();
КонецПроцедуры
// Функция получения пустой структуры хранения файла
//
// Параметры:
// UUID - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция пфПолучитьСтруктуруЗаписи(UUID = Неопределено) Экспорт
// Создаем структуру
Результат = Новый Структура;
Результат.Вставить("КодОшибки", "");
Результат.Вставить("UUID");
Результат.Вставить("Дата");
Результат.Вставить("Название");
Результат.Вставить("Описание");
Результат.Вставить("ТипФайла");
Результат.Вставить("СпособХранения");
Результат.Вставить("ПометкаУдаления");
Результат.Вставить("Путь");
Если Не ЗначениеЗаполнено(UUID) Тогда
Результат.ПометкаУдаления = Ложь;
Результат.UUID = "";
Иначе
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.UUID,
| ПрикрепленныеФайлы.ДатаСоздания КАК Дата,
| ПрикрепленныеФайлы.ТипФайла,
| ПрикрепленныеФайлы.Описание,
| ПрикрепленныеФайлы.ПутьДоФайла КАК Путь,
| ПрикрепленныеФайлы.СпособХранения,
| ПрикрепленныеФайлы.Название
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.UUID = &UUID";
Запрос.УстановитьПараметр("UUID", UUID);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Результат.UUID = Выборка.UUID;
Результат.Дата = Выборка.Дата;
Результат.Название = Выборка.Название;
Результат.Описание = Выборка.Описание;
Результат.ТипФайла = Выборка.ТипФайла;
Результат.СпособХранения = Выборка.СпособХранения;
Результат.Путь = "";
Результат.ПометкаУдаления = Ложь;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Записать одиночный файл
//
// Параметры:
// СтруктураЗаписи - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция пфЗаписатьФайл(СтруктураЗаписи) Экспорт
// Проверяем заполнена ли струкрута
Если Не ЗначениеЗаполнено(СтруктураЗаписи.Название) Тогда
// Возвращаем пустую запись
Возврат "";
КонецЕсли;
// Текущий пользователь
ТекущийПользователь = ИТ_ГлобальныйМодульСервер.ИТ_глЗначениеПеременной("глТекущийСотрудник");
ТекДата = ТекущаяДата();
// Действия выполняемые при добавлении записи
Если Не ЗначениеЗаполнено(СтруктураЗаписи.UUID) Тогда
ПустаяСсылка = Документы.Релиз.ПустаяСсылка();
НаборЗаписей = РегистрыСведений.ПрикрепленныеФайлы.СоздатьНаборЗаписей();
// Устанавливаем пустую ссылку на документ;
НаборЗаписей.Отбор.ИспользуемыйДокумент.Установить(ПустаяСсылка);
СтруктураЗаписи.UUID = ПолучитьUUID();
Запись = НаборЗаписей.Добавить();
// Записываем измерения
Запись.UUID = СтруктураЗаписи.UUID;
Запись.ИспользуемыйДокумент = ПустаяСсылка;
// Записываем ресурсы
Запись.Название = СтруктураЗаписи.Название;
Запись.Автор = ТекущийПользователь;
Запись.ДатаСоздания = ТекДата;
Запись.Редактор = ТекущийПользователь;
Запись.ДатаИзменения = ТекДата;
Запись.Описание = СтруктураЗаписи.Описание;
Запись.ТипФайла = СтруктураЗаписи.ТипФайла;
// Если файл требуется хранить в произвольном месте
Если СтруктураЗаписи.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория;
Запись.ПутьДоФайла = СтруктураЗаписи.Путь;
ИначеЕсли СтруктураЗаписи.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Или
(Не ЗначениеЗаполнено(СтруктураЗаписи.СпособХранения) И ПолучениеЗначенийСервер.ПолучитьПараметр("ХранитьФайлыВПапке")) = ИСТИНА Тогда
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
// Сохраняем файлы в указанной папке
Если ТипЗнч(СтруктураЗаписи.Путь) = Тип("ХранилищеЗначения") Тогда
Хранилище = СтруктураЗаписи.Путь;
Иначе
Хранилище = ПолучитьЗначениеДляХранилища(СтруктураЗаписи.Путь);
КонецЕсли;
ЗаписатьФайлВПапку(Хранилище, СтруктураЗаписи.Название, СтруктураЗаписи.UUID, СтруктураЗаписи.Путь);
Иначе
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
// Записываем файл в хранилище
Запись.Хранилище = ПолучитьЗначениеДляХранилища(СтруктураЗаписи.Путь);
КонецЕсли;
НаборЗаписей.Записать(Ложь);
ИначеЕсли ЗначениеЗаполнено(СтруктураЗаписи.Путь) Тогда // Определяем была ли запись изменена (у такой записи должен поменяться путь
ПустаяСсылка = Документы.Релиз.ПустаяСсылка();
НаборЗаписей = РегистрыСведений.ПрикрепленныеФайлы.СоздатьНаборЗаписей();
// Устанавливаем пустую ссылку на документ;
НаборЗаписей.Отбор.ИспользуемыйДокумент.Установить(ПустаяСсылка);
НаборЗаписей.Отбор.UUID.Установить(СтруктураЗаписи.UUID);
Запись = НаборЗаписей.Добавить();
// Записываем измерения
Запись.UUID = СтруктураЗаписи.UUID;
Запись.ИспользуемыйДокумент = ПустаяСсылка;
// Записываем ресурсы
Запись.Название = СтруктураЗаписи.Название;
Запись.Автор = ТекущийПользователь;
Запись.ДатаСоздания = ТекДата;
Запись.Редактор = ТекущийПользователь;
Запись.ДатаИзменения = ТекДата;
Запись.Описание = СтруктураЗаписи.Описание;
// Если файл требуется хранить в произвольном месте
Если СтруктураЗаписи.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория;
Запись.ПутьДоФайла = СтруктураЗаписи.Путь;
ИначеЕсли СтруктураЗаписи.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Или
(Не ЗначениеЗаполнено(СтруктураЗаписи.СпособХранения) И ПолучениеЗначенийСервер.ПолучитьПараметр("ХранитьФайлыВПапке")) = ИСТИНА Тогда
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
// Сохраняем файлы в указанной папке
Если ТипЗнч(СтруктураЗаписи.Путь) = Тип("ХранилищеЗначения") Тогда
Хранилище = СтруктураЗаписи.Путь;
Иначе
Хранилище = ПолучитьЗначениеДляХранилища(СтруктураЗаписи.Путь);
КонецЕсли;
ЗаписатьФайлВПапку(Хранилище, СтруктураЗаписи.Название, СтруктураЗаписи.UUID, СтруктураЗаписи.Путь);
Иначе
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
// Записываем файл в хранилище
Запись.Хранилище = ПолучитьЗначениеДляХранилища(СтруктураЗаписи.Путь);
КонецЕсли;
// Удаляем предыдующие записи
НаборЗаписей.Записать(Истина);
КонецЕсли; // Если ЗначениеНеЗаполнено(СтруктураЗаписи.UUID) Тогда ...
// Проверяем не нужно ли удалить запись
// запись удаляем в том случае, если не указан СпособХранения
Если СтруктураЗаписи.ПометкаУдаления = Истина Тогда
НаборЗаписей = РегистрыСведений.ПрикрепленныеФайлы.СоздатьНаборЗаписей();
ПустаяСсылка = Документы.Релиз.ПустаяСсылка();
// Устанавливаем пустую ссылку на документ;
НаборЗаписей.Отбор.ИспользуемыйДокумент.Установить(ПустаяСсылка);
НаборЗаписей.Отбор.UUID.Установить(СтруктураЗаписи.UUID);
// Удаляем предыдующие записи
НаборЗаписей.Записать(Истина);
// После удаления очищаем структуру записи
СтруктураЗаписи = пфПолучитьСтруктуруЗаписи();
КонецЕсли;
Возврат СтруктураЗаписи.UUID;
КонецФункции
// Функция генерирования UUID
//
// Возвращаемое значение:
// Произвольный
Функция пфПолучитьUUID() Экспорт
Возврат ПолучитьUUID();
КонецФункции
// Функция добавляет в переданную таблицу значений колонку "Картинка" И
// заполняет ее согласно правилу:
// ТЗДокументы - Таблица значений, в которую необходимо добавить и заполнить колонку "Картника"
// Таблица значений с заполненой колонкой Картинка
//
// Параметры:
// ТаблицаФайлов - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ДобавитьПолеКартинкиВТаблицуФайлов(ТаблицаФайлов) Экспорт
Если ТаблицаФайлов.Колонки.Найти("Картинка") = Неопределено Тогда
ТаблицаФайлов.Колонки.Добавить("Картинка");
КонецЕсли;
Для Каждого ТекСтрока Из ТаблицаФайлов Цикл
Если ТекСтрока.СпособХранения <> Неопределено Тогда
Если ТекСтрока.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза Тогда
ТекСтрока.Картинка = БиблиотекаКартинок.ВложениеХранилище;
ИначеЕсли ТекСтрока.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Тогда
ТекСтрока.Картинка = БиблиотекаКартинок.ВложениеУдаленное;
ИначеЕсли ТекСтрока.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда
ТекСтрока.Картинка = БиблиотекаКартинок.ВложениеВнешнее;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаФайлов;
КонецФункции
// /////////////////////////////////////////////////////////////////////
// ЛОКАЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ
//
// Параметры:
// ТаблицаЗначений - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ДополнитьТаблицаДаннымиПриКопированиДокументов(ТаблицаЗначений) Экспорт
Для Каждого Стр Из ТаблицаЗначений Цикл
ДанныеФайла = ПолучитьСтруктуруДанныхФайла(Стр.UUID);
Если ДанныеФайла.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.ИнформационнаяБаза") Тогда
Стр.Путь = ПоместитьВоВременноеХранилище( ДанныеФайла.Хранилище.Получить(), Новый УникальныйИдентификатор);
ИначеЕсли ДанныеФайла.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.ПроизвольнаяДиректория") Тогда
Стр.Путь = ДанныеФайла.ПутьДоФайла;
ИначеЕсли ДанныеФайла.СпособХранения = ПредопределенноеЗначение("Перечисление.СпособХраненияФайла.УдаленнаяДиректория") Тогда
Стр.Путь = ПолучитьУдаленнуюДиректорию() + ДанныеФайла.ПутьДоФайла;
КонецЕсли;
КонецЦикла;
ТаблицаЗначений.ЗаполнитьЗначения( "","UUID");
Возврат ТаблицаЗначений;
КонецФункции // ДополнитьТаблицаДаннымиПриКопированиДокументов(ТаблицаЗначений)
// Процедура выполняет действие:
// Получить Структуру Данных Файла
//
// Параметры:
// УИД - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьСтруктуруДанныхФайла(УИД) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.ИспользуемыйДокумент КАК Документ,
| ПрикрепленныеФайлы.UUID,
| ПрикрепленныеФайлы.СпособХранения,
| ПрикрепленныеФайлы.Автор,
| ПрикрепленныеФайлы.ДатаИзменения,
| ПрикрепленныеФайлы.ДатаСоздания,
| ПрикрепленныеФайлы.Название,
| ПрикрепленныеФайлы.Описание,
| ПрикрепленныеФайлы.Редактор,
| ПрикрепленныеФайлы.Хранилище,
| ПрикрепленныеФайлы.ПутьДоФайла,
| ПрикрепленныеФайлы.ТипФайла
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.UUID = &UUID";
Запрос.УстановитьПараметр("UUID", УИД);
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Структура = Новый Структура;
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
Для ш = 0 по Результат.Колонки.Количество() - 1 Цикл;
Структура.Вставить(Результат.Колонки[ш].Имя, ВыборкаДетальныеЗаписи[Результат.Колонки[ш].Имя] );
КонецЦикла;
КонецЕсли;
Возврат Структура;
КонецФункции // ПолучитьСтруктуруДанныхФайла
// Функция генерирования UUID
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьUUID() Экспорт
UUID = Новый УникальныйИдентификатор;
Возврат Строка(UUID);
КонецФункции
// Функция получения названия файла из его имени и UUID
//
// Параметры:
// Название - Строка
// UUID - Строка
// ШифрованноеИмя - Строка
//
// Возвращаемое значение:
// Строка
//
Функция ПолучитьСкрытоеНазвание(Название, UUID, ШифрованноеИмя = "", ЭтоКартинкаВходящейПочты = Ложь, СоздаватьКаталог = Истина) Экспорт
сокрUUID = UUID;
Если ШифрованноеИмя = "" Тогда
ПредставлениеИмени = "";
Шифрованное = ПолучитьШифрованноеИмя(Название, сокрUUID, ПредставлениеИмени);
РасширениеФайла = СтрПолучитьСтроку(ПредставлениеИмени,СтрЧислоСтрок(ПредставлениеИмени));
Иначе
Шифрованное = ШифрованноеИмя;
РасширениеФайла = Лев(ШифрованноеИмя, СтрНайти(ШифрованноеИмя, "_")-1);
КонецЕсли;
МассивПодПутей = Новый Массив();
МассивПодПутей.Добавить(РасширениеФайла);
ДваСимволаКоличество = 2;
сокрUUID = СокрЛП(сокрUUID);
Длина = СтрДлина(сокрUUID);
Для Счетчик = 1 По Длина Цикл
ДваСимвола = СокрЛП(Сред(сокрUUID, Счетчик, ДваСимволаКоличество));
Если ДваСимвола <> "" Тогда
МассивПодПутей.Добавить(ДваСимвола);
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
Каталог = ?(ЭтоКартинкаВходящейПочты, ПолучитьУдаленнуюДиректориюДляКартинокПочты(), ПолучитьУдаленнуюДиректорию());
Если НЕ ПроверитьСуществованиеКаталога(Каталог, СоздаватьКаталог) Тогда
Возврат ПолучитьСкрытоеНазваниеСтарая(Название, UUID, ЭтоКартинкаВходящейПочты);
КонецЕсли;
Подкаталог = "";
Для Каждого Элемент Из МассивПодПутей Цикл
Подкаталог = Подкаталог + Элемент + "\";
Если НЕ ПроверитьСуществованиеКаталога(Каталог + Подкаталог, СоздаватьКаталог) Тогда
Возврат ПолучитьСкрытоеНазваниеСтарая(Название, UUID, ЭтоКартинкаВходящейПочты);
КонецЕсли;
КонецЦикла;
Возврат Подкаталог + Шифрованное;
КонецФункции
// Функция - Получить шифрованное имя
//
// Параметры:
// Название - Строка
// сокрUUID - Строка
// ПредставлениеИмени - Строка
//
// Возвращаемое значение:
// Строка
//
Функция ПолучитьШифрованноеИмя(Название, сокрUUID, ПредставлениеИмени = "") Экспорт
// Удаляем черточки в UUID
сокрUUID = СтрЗаменить(сокрUUID,"-","");
ПредставлениеИмени = СтрЗаменить(Название,".",символы.ПС);
ШифрованноеИмя = СтрПолучитьСтроку(ПредставлениеИмени,СтрЧислоСтрок(ПредставлениеИмени)) + "_" + сокрUUID;
Возврат ШифрованноеИмя;
КонецФункции
// Функция - Проверить существование каталога
//
// Параметры:
// ИмяКаталога - Произвольный
//
// Возвращаемое значение:
// Произвольный
//
Функция ПроверитьСуществованиеКаталога(ИмяКаталога, СоздаватьКаталог = Истина) Экспорт
КаталогНаДиске = Новый Файл(ИмяКаталога);
Если КаталогНаДиске.Существует() Тогда
Возврат Истина;
Иначе
Если Не СоздаватьКаталог Тогда
Возврат Ложь;
КонецЕсли;
СоздатьКаталог(ИмяКаталога);
Если КаталогНаДиске.Существует() Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецФункции
// Функция получения названия файла из его имени и UUID
//
// Параметры:
// Название - Произвольный
// UUID - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьСкрытоеНазваниеСтарая(Название, UUID, ЭтоКартинкаВходящегоПисьма = Ложь) Экспорт
Если ЭтоКартинкаВходящегоПисьма Тогда
Возврат ПолучитьСтароеНазваниеДляКартинокПочты(UUID);
Иначе
Возврат ПолучитьСтароеНазваниеДляФайлаХранилища(UUID, Название);
КонецЕсли;
КонецФункции
Функция ПолучитьСтароеНазваниеДляФайлаХранилища(UUID, Название)
// Удаляем черточки в UUID
сокрUUID = СтрЗаменить(UUID,"-","");
ПредставлениеИмени = СтрЗаменить(Название,".",символы.ПС);
Шифрованное = СтрПолучитьСтроку(ПредставлениеИмени,СтрЧислоСтрок(ПредставлениеИмени)) + "_" + сокрUUID;
Возврат Шифрованное;
КонецФункции
// Функция - Получить старое название для картинок почты
//
// Параметры:
// Имя - Строка
//
// Возвращаемое значение:
// Строка
//
Функция ПолучитьСтароеНазваниеДляКартинокПочты(Имя) Экспорт
Имя = "_" + СтрЗаменить(Имя, "-", "");
Возврат Имя;
КонецФункции
// Функция получения двоичных данных
//
// Параметры:
// UUID - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьДвоичныеДанныеФайла(UUID) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.Хранилище,
| ПрикрепленныеФайлы.Название,
| ПрикрепленныеФайлы.СпособХранения,
| ПрикрепленныеФайлы.ПутьДоФайла
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.UUID = &UUID";
Запрос.УстановитьПараметр("UUID", UUID);
Выборка = Запрос.Выполнить().Выбрать();
// Получаем двоичные данные
ДвоичныеДанные = Неопределено;
// Если не найдены файлы, тогд выходим из функции
Если Не Выборка.Следующий() Тогда
Возврат ДвоичныеДанные;
КонецЕсли; // Если Не Выборка.Следующий() Тогда
// Выбираем файл, если он сохранился в информационной базе
Если Выборка.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза Тогда
// Получаем адрес временного файла
ВрФайл = КаталогВременныхФайлов() + Выборка.Название;
// Записываем временный файл во временный каталог
Попытка
ДвоичныеДанные = Выборка.Хранилище.Получить();
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
ИначеЕсли Выборка.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Тогда // Если ... = ИнформационнаяБаза Тогда
// Получаем параметры удаленной директории
УдаленнаяДиректория = ПолучитьУдаленнуюДиректорию();
// Получаем двоичные данные файла
Попытка
ДвоичныеДанные = Новый ДвоичныеДанные( УдаленнаяДиректория + ?(Выборка.ПутьДоФайла = "",ПолучитьСкрытоеНазвание(Выборка.Название, UUID), Выборка.ПутьДоФайла ));
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
ИначеЕсли Выборка.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда // Если ... = УдаленнаяДиректория Тогда
// Читаем удаленный файл
Попытка
ДвоичныеДанные = Новый ДвоичныеДанные( Выборка.ПутьДоФайла);
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
КонецЕсли; // Если ... = ПроизвольнаяДиректория Тогда
Возврат ДвоичныеДанные;
КонецФункции // Функция ПолучитьДвоичныеДанныеФайла(UUID)
// Функция получения удаленной директории
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьУдаленнуюДиректорию() Экспорт
УдаленнаяДиректория = ПолучениеЗначенийСервер.ПолучитьПараметр("ПутьКХранилищу");
УдаленнаяДиректория = УдаленнаяДиректория + ?(Прав(УдаленнаяДиректория,1)="\","","\");
Возврат УдаленнаяДиректория;
КонецФункции
Функция ПолучитьУдаленнуюДиректориюДляКартинокПочты()
УдаленнаяДиректория = ПолучениеЗначенийСервер.ПолучитьПараметр("ИТ_ПутьККартинкамВходящейПочты");
УдаленнаяДиректория = УдаленнаяДиректория + ?(Прав(УдаленнаяДиректория,1)="\","","\");
Возврат УдаленнаяДиректория;
КонецФункции
// Функция получения имени файла по его uuid
//
// Параметры:
// uuid - Произвольный
//
// Возвращаемое значение:
// Произвольный
функция пфПолучитьИмяФайла(uuid) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.Название
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.UUID = &UUID";
Запрос.УстановитьПараметр("UUID", uuid);
Выборка = Запрос.Выполнить().Выбрать();
Если Не Выборка.Следующий() Тогда
Возврат "";
КонецЕсли;
Возврат Выборка.Название;
КонецФункции
// Функция добавления файлов
// :
// - стрНеУдалить - UUID файлов (разделённые '\r\n'), которые не надо удалять. Те файлы чьих uuid тут нету - УДАЛЯТС
// Я.
// параметры удаляемых файлов - многострочная строка в виде (UUID \r\n UUID...)
// - стрДобавить - параметры добавляемых файлов - многострочная строка в виде (путь \r\n имя \r\n путь \r\n имя ...
// )
// :
// пустая строка :)
//
// Параметры:
// стрНеУдалять - Произвольный
// стрДобавить - Произвольный
// Документ - Произвольный
// Автор - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция пфЗагрузитьФайлы(стрНеУдалять, стрДобавить, Документ, Автор = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(Автор) Или ТипЗнч(Автор) = Тип("СправочникСсылка.Пользователи") Тогда
Автор = ИТ_ГлобальныйМодульСервер.ИТ_глЗначениеПеременной("глТекущийПользователь");
КонецЕсли;
// Получаем все файлы прикреплённые к документу
тзПрикрепленныеФайлы = пфПолучитьСписокПрикрепленныхФайлов(Документ);
// Ищем строки для удаления
удалять = Новый Массив;
Для Каждого строка Из тзПрикрепленныеФайлы Цикл
// Если uuid файла не найден в строке стрНеУдалять, то удаляем его
Если Найти(стрНеУдалять, строка["UUID"]) = 0 Тогда
// ТзПрикрепленныеФайлы.Удалить(строка);
удалять.Добавить(Истина);
Иначе
удалять.Добавить(Ложь);
КонецЕсли;
КонецЦикла;
// Удаляем файлы
инд = удалять.Количество()-1;
Пока инд >= 0 Цикл
Если Булево(удалять[инд]) Тогда
тзПрикрепленныеФайлы.Удалить(инд);
КонецЕсли;
инд = инд-1;
КонецЦикла;
Инкремент = 2;
// Добавляем новые файлы
Если Не ПустаяСтрока(стрДобавить) Тогда
способХранения = ?(Константы.ХранитьФайлыВПапке.Получить(), Перечисления.СпособХраненияФайла.УдаленнаяДиректория, Перечисления.СпособХраненияФайла.ИнформационнаяБаза);
индекс = 1;
Пока индекс<СтрЧислоСтрок(стрДобавить) Цикл
НоваяСтрока = тзПрикрепленныеФайлы.Добавить();
НоваяСтрока.Путь = СокрЛП(СтрПолучитьСтроку(стрДобавить, индекс));
НоваяСтрока.Название = СокрЛП(СтрПолучитьСтроку(стрДобавить, индекс + 1));
НоваяСтрока.Описание = "";
НоваяСтрока.СпособХранения = способХранения;
индекс = индекс + Инкремент;
КонецЦикла;
КонецЕсли;
// Записываем изменения
пфЗаписатьПрикрепленныеФайлы(Документ, тзПрикрепленныеФайлы, Автор);
Возврат "";
КонецФункции
// Процедура выполняет действие:
// Получить Данные Файла По G U I D
//
// Параметры:
// GUID - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьДанныеФайлаПоGUID(GUID) Экспорт
// Если GUID не заполнен, тогда выходим из процедуры
Если Не ЗначениеЗаполнено(GUID) Тогда
Возврат Неопределено;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПрикрепленныеФайлы.Хранилище,
| ПрикрепленныеФайлы.Название,
| ПрикрепленныеФайлы.СпособХранения,
| ПрикрепленныеФайлы.ПутьДоФайла
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.UUID = &GUID";
Запрос.УстановитьПараметр("GUID", GUID);
Выборка = Запрос.Выполнить().Выбрать();
Если Не Выборка.Следующий() Тогда
Возврат Неопределено;
КонецЕсли;
// Получаем двоичные данные
ДвоичныеДанные = Неопределено;
// Выбираем файл, если он сохранился в информационной базе
Если Выборка.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза Тогда
// Записываем временный файл во временный каталог
Попытка
ДвоичныеДанные = Выборка.Хранилище.Получить();
Исключение
Возврат Неопределено;
КонецПопытки;
ИначеЕсли Выборка.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Тогда // Если ... = ИнформационнаяБаза Тогда
// Получаем параметры удаленной директории
УдаленнаяДиректория = Константы.ПутьКХранилищу.Получить();
УдаленнаяДиректория = УдаленнаяДиректория + ?(Прав(УдаленнаяДиректория,1)="\","","\");
Подкаталог = СокрЛП(ПрикрепленныеФайлыСервер.ПолучитьСкрытоеНазвание(Выборка.Название, GUID));
ПутьДоХранилища = ПрикрепленныеФайлыСервер.ПолучитьУдаленнуюДиректорию() + Подкаталог;
// Получаем двоичные данные файла
Попытка
ДвоичныеДанные = Новый ДвоичныеДанные( ПутьДоХранилища);
Исключение
Возврат Неопределено;
КонецПопытки;
ИначеЕсли Выборка.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда // Если ... = УдаленнаяДиректория Тогда
// Читаем удаленный файл
Попытка
Если НЕ ЭтоАдресВременногоХранилища(Выборка.ПутьДоФайла) Тогда
ДвоичныеДанные = Новый ДвоичныеДанные(Выборка.ПутьДоФайла);
Иначе
ДвоичныеДанные = Выборка.ПутьДоФайла;
КонецЕсли;
Исключение
Возврат Неопределено;
КонецПопытки;
КонецЕсли; // Если ... = ПроизвольнаяДиректория Тогда
Если Не ДвоичныеДанные = Неопределено Тогда
Возврат Новый Структура("ДвоичныеДанные, ИмяФайла",
ДвоичныеДанные, Выборка.Название);
КонецЕсли;
Возврат ДвоичныеДанные;
КонецФункции
// Процедура выполняет действие:
// Получить Список Выбора Мест Хранения
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьСписокВыбораМестХранения() Экспорт
СписокВыбора = Новый СписокЗначений;
Если РольДоступна(Метаданные.Роли.ПотребительУслуг) или РольДоступна(Метаданные.Роли.ПотребительУслугКуратор) Тогда
ЗначениеПотребителя = ПолучениеЗначенийСервер.ПолучитьПараметр("ИТ_СпособХраненияФайловПотребителяУслуг");
Если ТипЗнч(ЗначениеПотребителя) = Тип("ПеречислениеСсылка.СпособХраненияФайла") И
ЗначениеЗаполнено(ЗначениеПотребителя) Тогда
СписокВыбора.Добавить( ЗначениеПотребителя );
ПоУмолчанию = ЗначениеПотребителя;
Возврат Новый Структура("СписокВыбора, ПоУмолчанию", СписокВыбора, ПоУмолчанию);
КонецЕсли;
КонецЕсли;
// Заполняем список выбора
Если Константы.ИТ_ХранитьФайлыСохранятьПуть.Получить() = ИСТИНА Тогда
СписокВыбора.Добавить(Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория,,, БиблиотекаКартинок.ВложениеВнешнее);
ПоУмолчанию = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория;
КонецЕсли;
Если Константы.ИТ_ХранитьФайлыВИБ.Получить() = ИСТИНА Тогда
СписокВыбора.Добавить(Перечисления.СпособХраненияФайла.ИнформационнаяБаза,,, БиблиотекаКартинок.ВложениеХранилище);
ПоУмолчанию = Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
КонецЕсли;
Если Константы.ХранитьФайлыВПапке.Получить() = Истина Тогда
СписокВыбора.Добавить(Перечисления.СпособХраненияФайла.УдаленнаяДиректория,,, БиблиотекаКартинок.ВложениеУдаленное);
ПоУмолчанию = Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
КонецЕсли;
Возврат Новый Структура("СписокВыбора, ПоУмолчанию", СписокВыбора, ПоУмолчанию);
КонецФункции
// Формирует строку фильтра для диалога выбора картинки с типами файлов.
//
// Нет.
// :
// Строка – фильтр по типам файлов для диалога выбора картинки.
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьФильтрИзображений() Экспорт
Возврат "Все картинки (*.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|";
КонецФункции // ПолучитьФильтрИзображений()
// Процедура выполняет действие:
// Макс Размер Файла
//
// Возвращаемое значение:
// Произвольный
Функция МаксРазмерФайла() Экспорт
ЗначениеВМебибайтах = ИТ_ОбщегоНазначения.ПолучитьЗначениеКонстанты("ИТ_МаксимальныйРазмерФайла");
Если ЗначениеВМебибайтах = Неопределено Тогда
ЗначениеВМебибайтах = 0;
КонецЕсли;
МножительБайтов = 1048576;
МножительКибиБайтов = 1024;
Возврат Новый Структура("ВБайтах, ВКибиБайтах, ВМебибайтах", ЗначениеВМебибайтах * МножительБайтов, ЗначениеВМебибайтах * МножительКибиБайтов, ЗначениеВМебибайтах);
КонецФункции
// Процедура выполняет действие:
// Тип Хранения Файла По Умолчанию
//
// Возвращаемое значение:
// Произвольный
Функция ТипХраненияФайлаПоУмолчанию() Экспорт
МассивРазрешенныхСпособов = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Константы.ИТ_ХранитьФайлыВИБ КАК ХранитьФайлыВИБ,
| Константы.ИТ_ХранитьФайлыСохранятьПуть КАК ХранитьФайлыСохранятьПуть,
| Константы.ХранитьФайлыВПапке КАК ХранитьФайлыВХранилище
| ИЗ
| Константы КАК Константы";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
Если Выборка.ХранитьФайлыВИБ = ИСТИНА Тогда
МассивРазрешенныхСпособов.Добавить(Перечисления.СпособХраненияФайла.ИнформационнаяБаза);
КонецЕсли;
Если Выборка.ХранитьФайлыСохранятьПуть = ИСТИНА Тогда
МассивРазрешенныхСпособов.Добавить(Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория);
КонецЕсли;
Если Выборка.ХранитьФайлыВХранилище = ИСТИНА Тогда
МассивРазрешенныхСпособов.Добавить(Перечисления.СпособХраненияФайла.УдаленнаяДиректория);
КонецЕсли;
КонецЕсли;
Если МассивРазрешенныхСпособов.Количество() = 0 Тогда // Нет разрешенных способов хранения
Возврат Неопределено;
ИначеЕсли МассивРазрешенныхСпособов.Количество() = 1 Тогда // Способ хранения только один. Его и вернем.
Возврат МассивРазрешенныхСпособов[0];
Иначе // Если разрешено хранение в хранилище, используем его по умолчанию. Если нет — сохраним в информ. базе
Если МассивРазрешенныхСпособов.Найти(Перечисления.СпособХраненияФайла.УдаленнаяДиректория) <> Неопределено Тогда
Возврат Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
Иначе
Возврат Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
КонецЕсли;
КонецЕсли;
КонецФункции
// Функция, вызываемая в событии ПриСозданииНаСервере модуля формы объекта.
// Позволяет для существующего объекта заполнить таблицу прикрепленных файлов, а для нового объекта —
// заполнить таблицу по ссылке значения копирования. Заполняем безусловно. Для новых объектов будет шанс очистить табл
// ицу ПриОткрытии формы
//
// Параметры:
// Форма - Произвольный
// ИмяТаблицы - Произвольный
// ОсобыйВладелец - Произвольный
// ИмяОсобойТаблицы - Произвольный
// СсылкаСФормы - Произвольный
Процедура ПриСозданииНаСервере(Форма, ИмяТаблицы, ОсобыйВладелец = Неопределено, ИмяОсобойТаблицы = Неопределено, СсылкаСФормы = Неопределено) Экспорт
Если НЕ ПолучитьФункциональнуюОпцию("Использовать_ПрикрепленныеФайлы") Тогда
Возврат;
КонецЕсли;
Если ОсобыйВладелец <> Неопределено И ИмяОсобойТаблицы <> Неопределено Тогда
Форма.ЗначениеВРеквизитФормы(ДобавитьПолеКартинкиВТаблицуФайлов(пфПолучитьСписокПрикрепленныхФайлов(ОсобыйВладелец)), ИмяОсобойТаблицы);
КонецЕсли;
Если СсылкаСФормы = Неопределено Тогда
СсылкаСФормы = Форма.Объект.Ссылка;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(СсылкаСФормы) Тогда // Новый объект
Если Форма.Параметры.Свойство("ЗначениеКопирования") И ЗначениеЗаполнено(Форма.Параметры.ЗначениеКопирования) Тогда
Форма.ЗначениеВРеквизитФормы(ДобавитьПолеКартинкиВТаблицуФайлов(пфПолучитьСписокПрикрепленныхФайлов(Форма.Параметры.ЗначениеКопирования)), ИмяТаблицы);
КонецЕсли;
Иначе // Существующий объект
Форма.ЗначениеВРеквизитФормы(ДобавитьПолеКартинкиВТаблицуФайлов(пфПолучитьСписокПрикрепленныхФайлов(СсылкаСФормы)), ИмяТаблицы);
КонецЕсли;
КонецПроцедуры
// Функция выполняет действие:
// При Записи На Сервере
//
// Параметры:
// Форма - Произвольный
// ЗаписываемыйОбъект - Произвольный
// ИмяТаблицы - Произвольный
// ОсобыйВладелец - Произвольный
// ИмяОсобойТаблицы - Произвольный
Процедура ПриЗаписиНаСервере(Форма, ЗаписываемыйОбъект, ИмяТаблицы, ОсобыйВладелец = Неопределено, ИмяОсобойТаблицы = Неопределено) Экспорт
Если НЕ ПолучитьФункциональнуюОпцию("Использовать_ПрикрепленныеФайлы") Тогда
Возврат;
КонецЕсли;
Если ОсобыйВладелец <> Неопределено И ИмяОсобойТаблицы <> Неопределено Тогда
ТЗ = Форма.РеквизитФормыВЗначение(ИмяОсобойТаблицы);
пфЗаписатьПрикрепленныеФайлы(ОсобыйВладелец, ТЗ);
Форма.ЗначениеВРеквизитФормы(ТЗ, ИмяОсобойТаблицы);
КонецЕсли;
ТЗ = Форма.РеквизитФормыВЗначение(ИмяТаблицы);
пфЗаписатьПрикрепленныеФайлы(ЗаписываемыйОбъект.Ссылка, ТЗ);
Форма.ЗначениеВРеквизитФормы(ТЗ, ИмяТаблицы);
КонецПроцедуры
// Процедура выполняет действие:
// Получить Размер Файла
//
// Параметры:
// АдресФайла - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ПолучитьРазмерФайла(АдресФайла) Экспорт
РазмерФайла = 0;
ЗначениеИзХранилища = ПолучитьИзВременногоХранилища(АдресФайла);
Если ТипЗнч(ЗначениеИзХранилища) = Тип("ДвоичныеДанные") ИЛИ ТипЗнч(ЗначениеИзХранилища) = Тип("Файл") Тогда
РазмерФайла = ЗначениеИзХранилища.Размер();
КонецЕсли;
Возврат РазмерФайла;
КонецФункции
// Процедура выполняет действие:
// Файл Доступен С Сервера Предприятия
//
// Параметры:
// ПутьКФайлу - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция ФайлДоступенССервераПредприятия(ПутьКФайлу) Экспорт
ПроверяемыйФайл = Новый Файл(ПутьКФайлу);
Если ПроверяемыйФайл.Существует() Тогда
Возврат ИСТИНА;
Иначе
Возврат ЛОЖЬ;
КонецЕсли;
КонецФункции
// Процедура выполняет действие:
// Перенести Файлы Картинок Почты Во Внешнее Хранилище
//
// Параметры:
// Хранилище - Произвольный
//
// Возвращаемое значение:
// Произвольный
Процедура ПеренестиФайлыКартинокПочтыВоВнешнееХранилище(Хранилище = Неопределено) экспорт
Если Хранилище = Неопределено Тогда
Путь = ПолучениеЗначенийСервер.ПолучитьПараметр("ИТ_ПутьККартинкамВходящейПочты");
Иначе
Путь = Хранилище;
КонецЕсли;
Если Не ПустаяСтрока(Путь) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
" ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЭлектронноеПисьмоВходящее.СтруктураКартинок,
| ЭлектронноеПисьмоВходящее.Ссылка
| ИЗ
| Документ.ЭлектронноеПисьмоВходящее КАК ЭлектронноеПисьмоВходящее";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Структура = ВыборкаДетальныеЗаписи.СтруктураКартинок.Получить();
Если Структура = Неопределено Тогда
Продолжить;
КонецЕсли;
НадоЗаписатьДокумент = Ложь;
Для Каждого Пара Из Структура Цикл
Если ТипЗнч(Пара.Значение.Картинка) = Тип("Картинка") Тогда
НадоЗаписатьДокумент = Истина;
Идентификатор = Строка(Новый УникальныйИдентификатор);
СокращенныйИдентификатор = СтрЗаменить(Идентификатор, "-", "");
Имя = Пара.Значение.Расширение + "_" + СокращенныйИдентификатор;
Подкаталог = ПрикрепленныеФайлыСервер.ПолучитьСкрытоеНазвание(Имя, Идентификатор, Имя, Истина, Истина);
ИмяПолное = ПрикрепленныеФайлыСервер.ПолучитьИмяФайла( Путь, Подкаталог );
Попытка
Пара.Значение.Картинка.Записать( ИмяПолное );
Пара.Значение.Картинка = Имя;
Исключение
ВызватьИсключение "Не удалось сохранить картинки по письму";
КонецПопытки;
КонецЕсли;
КонецЦикла;
Если НадоЗаписатьДокумент Тогда
Документ = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
Документ.СтруктураКартинок = Новый ХранилищеЗначения(Структура);
Документ.Записать();
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры // ()
// Функция получающая перечень файлов по перечню документов и спискуID
//
// Параметры:
// ДокументыПеречень - Произвольный
// МассивUUID - Произвольный
//
// Возвращаемое значение:
// Произвольный
Функция пфПолучитьСписокПрикрепленныхФайловПоПеречнюДокументовИСпискуID(ДокументыПеречень, МассивUUID) Экспорт
Запрос = Новый Запрос;
НомерДокумента = 1;
Для Каждого Документ Из ДокументыПеречень Цикл
ЗапросСсылкаНаДокумент= "";
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Документ)) Тогда
ЗапросСсылкаНаДокумент = " ПрикрепленныеФайлы.ИспользуемыйДокумент ССЫЛКА Справочник." + Документ.Метаданные().Имя + " И ";
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Документ)) Тогда
ЗапросСсылкаНаДокумент = " ПрикрепленныеФайлы.ИспользуемыйДокумент ССЫЛКА Документ." + Документ.Метаданные().Имя+ " И ";
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка"+ НомерДокумента, Документ);
Запрос.Текст = Запрос.Текст + ?(Запрос.Текст = "", " ВЫБРАТЬ РАЗРЕШЕННЫЕ ", " ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ") +
" ПрикрепленныеФайлы.UUID,
| ПрикрепленныеФайлы.Название,
| ПрикрепленныеФайлы.Описание,
| ПрикрепленныеФайлы.ТипФайла КАК ТипФайла,
| ПрикрепленныеФайлы.ДатаИзменения КАК Дата,
| ПрикрепленныеФайлы.СпособХранения,
| ЛОЖЬ КАК ПометкаУдаления
| ИЗ
| РегистрСведений.ПрикрепленныеФайлы КАК ПрикрепленныеФайлы
| ГДЕ
| ПрикрепленныеФайлы.UUID В (&МассивUUID) И
| "+ ЗапросСсылкаНаДокумент + " ПрикрепленныеФайлы.ИспользуемыйДокумент = &Ссылка" + НомерДокумента ;
НомерДокумента = НомерДокумента + 1;
КонецЦикла;
Запрос.УстановитьПараметр("МассивUUID",МассивUUID);
тзПрикрепленныеФайлы = Запрос.Выполнить().Выгрузить();
тзПрикрепленныеФайлы.Колонки.Добавить("Путь");
Возврат тзПрикрепленныеФайлы;
КонецФункции
#КонецОбласти
#Область СлужебныйПрограммныйИнтерфейс
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// ПРОЦЕДУРЫ И ФУНКЦИИ РАБОТАЮЩИЕ С ФАЙЛАМИ
Функция ПолучитьСпособХранения()
СпособХранения = Неопределено;
Путь = "";
Если ПолучениеЗначенийСервер.ПолучитьПараметр("ХранитьФайлыВПапке") Тогда
Путь = ПолучениеЗначенийСервер.ПолучитьПараметр("ПутьКХранилищу");
Если Не ПустаяСтрока(Путь) Тогда
СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
КонецЕсли;
КонецЕсли;
Если СпособХранения = Неопределено Тогда
Если ПолучениеЗначенийСервер.ПолучитьПараметр("ИТ_ХранитьФайлыВИБ") Тогда
СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
КонецЕсли;
КонецЕсли;
Если СпособХранения = Неопределено Тогда
Если ПолучениеЗначенийСервер.ПолучитьПараметр("ИТ_ХранитьФайлыСохранятьПуть") Тогда
СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория;
КонецЕсли;
КонецЕсли;
Если СпособХранения = Неопределено Тогда // Нет способов хранения файлов
Возврат Неопределено;
КонецЕсли;
Возврат Новый Структура("СпособХранения,Путь", СпособХранения, Путь);
КонецФункции
Процедура ЗаполнитьСтрокуИМенеджерЗаписиИзФормыПредпросмотра(Менеджер, СтрокаТаблицыФайлов, СтруктураСпособаХранения, СсылкаНаДокумент, ТекДата)
Если ЛОЖЬ ТОГДА Менеджер = РегистрыСведений.ПрикрепленныеФайлы.СоздатьМенеджерЗаписи(); КонецЕсли;
// ИмяФайла
// ИДФайла
// Действие
// Путь
// ЭтоНовыйФайл
// АдресВХранилище
// Документ
// UUID
// СпособХранения
// Автор
// ДатаИзменения
// ДатаСоздания
// Название
// Описание
// Редактор
// Хранилище
// ПутьДоФайла
// ТипФайла
ТекПользователь = ИТ_ГлобальныйМодульСервер.ИТ_глЗначениеПеременной("глТекущийПользователь");
Менеджер.UUID = Строка(Новый УникальныйИдентификатор);
Менеджер.ИспользуемыйДокумент = СсылкаНаДокумент;
Менеджер.СпособХранения = СтруктураСпособаХранения.СпособХранения;
Менеджер.Автор = ТекПользователь;
Менеджер.ДатаИзменения = ТекДата;
Менеджер.ДатаСоздания = ТекДата;
Менеджер.Название = СтрокаТаблицыФайлов.ИмяФайла;
Менеджер.Описание = "Файл прикреплен при предпросмотре отправляемого сообщения";
Менеджер.Редактор = ТекПользователь;
// Пока не заполняется.
// Менеджер.ТипФайла = Справочники.ИТ_ТипыФайлов.
СтрокаТаблицыФайлов.ИДФайла = Менеджер.UUID;
СтрокаТаблицыФайлов.ЭтоНовыйФайл = ЛОЖЬ;
СтепеньСжатия6 = 6;
Если СтруктураСпособаХранения.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза Тогда
// Тут всегда должен быть только адрес. иначе опять будет каша
Если ЭтоАдресВременногоХранилища( СтрокаТаблицыФайлов.АдресВХранилище ) Тогда
Менеджер.Хранилище = Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(СтрокаТаблицыФайлов.АдресВХранилище), Новый СжатиеДанных(СтепеньСжатия6));
Иначе
ВызватьИсключение "Не переданны двоичные данные в запись файлов при предпросмотре отправляемого сообщения"
КонецЕсли;
ИначеЕсли СтруктураСпособаХранения.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Тогда
Менеджер.ПутьДоФайла = "";
Менеджер.Хранилище = Неопределено;
// Тут всегда должен быть только адрес. иначе опять будет каша
Если ЭтоАдресВременногоХранилища( СтрокаТаблицыФайлов.АдресВХранилище ) Тогда
Хранилище = Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(СтрокаТаблицыФайлов.АдресВХранилище), Новый СжатиеДанных(СтепеньСжатия6));
ЗаписатьФайлВПапку( Хранилище, Менеджер.Название, Менеджер.UUID, "" );
Иначе
ВызватьИсключение "Не переданны двоичные данные в запись файлов при предпросмотре отправляемого сообщения"
КонецЕсли;
ИначеЕсли СтруктураСпособаХранения.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда
Менеджер.ПутьДоФайла = СтрокаТаблицыФайлов.Путь;
Менеджер.Хранилище = Неопределено;
КонецЕсли;
КонецПроцедуры
// Возвращает имя файла, содержащего только допустимые символы
Функция пфПодготовитьИмяФайла(ИмяФайла)
СокрИмяФайла = СокрП(ИмяФайла);
НовоеИмя = "";
Длина = СтрДлина(СокрИмяФайла);
Позиция = 1;
Пока Позиция <= Длина Цикл
Символ = НРег(Сред(СокрИмяФайла, Позиция, 1));
Если Найти("qwertyuiopasdfghjklzxcvbnmйцукенгшщзхъфывапролджэячсмитьбюё1234567890_ ", Символ) > 0 Тогда
НовоеИмя = НовоеИмя + Символ;
КонецЕсли;
Позиция = Позиция + 1;
КонецЦикла;
Если ПустаяСтрока(НовоеИмя) Тогда
НовоеИмя = "Стандартное имя файла";
КонецЕсли;
Возврат НовоеИмя;
КонецФункции
// Обрабатывает объект ИнтернетПочтовоеСообщение и подготовливает текстовый файл
Процедура пфОбработатьПисьмоКакФайл(Письмо, Файл, Источник)
Имя = ?(Не ПустаяСтрока(Письмо.Тема), Письмо.Тема, Письмо.ИдентификаторСообщения);
Получатели = "";
Отправитель = Письмо.Отправитель.ОтображаемоеИмя + " <" + Письмо.Отправитель.Адрес + ">";
ТекстПисьма = "";
ДатаПолучения = Письмо.ДатаПолучения;
ДатаОтправления = Письмо.ДатаОтправления;
Важность = Строка(Письмо.Важность);
Кодировка = Письмо.Кодировка;
Копии = "";
Вложения = "";
Для Каждого Получатель Из Письмо.Получатели Цикл
Получатели = Получатели + ?(Получатели <> "", ";", "") + Получатель.ОтображаемоеИмя + " <" + Получатель.Адрес + ">";
КонецЦикла;
Для Каждого Копия Из Письмо.Копии Цикл
Копии = Копии + ?(Копии <> "", ";", "") + Копия.ОтображаемоеИмя + " <" + Копия.Адрес + ">";
КонецЦикла;
Для Каждого Вложение Из Письмо.Вложения Цикл
Если ТипЗнч(Вложение.Данные) = Тип("ИнтернетПочтовоеСообщение") Тогда
Вложения = Вложения + ?(Вложения <> "", ";", "") + пфПодготовитьИмяФайла(?(Не ПустаяСтрока(Вложение.Данные.Тема), Вложение.Данные.Тема, Вложение.Данные.ИдентификаторСообщения)) + ".txt";
Иначе
Вложения = Вложения + ?(Вложения <> "", ";", "") + Вложение.Имя;
КонецЕсли;
КонецЦикла;
КодировкаФайла = "koi8-r";
Для Каждого Текст Из Письмо.Тексты Цикл
Если Текст.ТипТекста = ТипТекстаПочтовогоСообщения.HTML Тогда
ТекстПисьма = ТекстПисьма + Символы.ПС + СокрЛП(ФормированиеСообщенийСервер.ВернутьТекстПисьмаВТекстовомФормате(Текст.Текст));
Прервать; // Обрабатываем загрузку сообщений, только один раз
ИначеЕсли Текст.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст Тогда
ТекстПисьма = ТекстПисьма + Символы.ПС + СокрЛП(Текст.Текст);
ТекстПисьма = ПерестроитьМногострочныйТекст(ТекстПисьма);
Прервать; // Обрабатываем загрузку сообщений, только один раз
ИначеЕсли Текст.ТипТекста = ТипТекстаПочтовогоСообщения.РазмеченныйТекст Тогда
ТекстПисьма = ТекстПисьма + Символы.ПС + Текст.Текст;
Прервать; // Обрабатываем загрузку сообщений, только один раз
КонецЕсли;
КонецЦикла;
ИмяФайла = КаталогВременныхФайлов() + пфПодготовитьИмяФайла(Имя) + ".eml";//".txt";
Текст = Новый ЗаписьТекста(ИмяФайла, КодировкаФайла);
Текст.ЗаписатьСтроку("Тема: " + Письмо.Тема);
Текст.ЗаписатьСтроку("----------------");
Текст.ЗаписатьСтроку("Отправитель: " + Отправитель);
Текст.ЗаписатьСтроку("Получатели: " + Получатели);
Текст.ЗаписатьСтроку("Получатели (копия): " + Копии);
Текст.ЗаписатьСтроку("Дата отправления: " + ДатаОтправления);
Текст.ЗаписатьСтроку("Дата получения: " + ДатаПолучения);
Текст.ЗаписатьСтроку("Важность: " + Важность);
Текст.ЗаписатьСтроку("----------------");
Текст.ЗаписатьСтроку("Источник-вложение: " + Источник);
Текст.ЗаписатьСтроку("Вложения: " + Вложения);
Текст.ЗаписатьСтроку("----------------");
Текст.ЗаписатьСтроку(ТекстПисьма);
Текст.Закрыть();
Файл.Описание = Имя;
Файл.Название = пфПодготовитьИмяФайла(Имя) + ".eml";//".txt";
Файл.Путь = ИмяФайла;
КонецПроцедуры
Функция ПерестроитьМногострочныйТекст(Текст) Экспорт
МассивСимволов = Новый Массив;
МассивСимволов.Добавить(Текст);
ФормСтрока = Новый ФорматированнаяСтрока(МассивСимволов);
ФормДок = Новый ФорматированныйДокумент;
ФормДок.УстановитьФорматированнуюСтроку(ФормСтрока);
Текст = ФормДок.ПолучитьТекст();
Возврат Текст
КонецФункции
Процедура СохранитьВложенныеПисьма(Документ,
ТекущийПользователь,
ТекДата,
НаборЗаписей,
Письмо,
Источник = "",
ЭлектронноеПисьмо = Неопределено)
Файл = пфПолучитьСтруктуруЗаписи();
пфОбработатьПисьмоКакФайл(Письмо, Файл, Источник);
ЗаписатьФайл(Документ, ТекущийПользователь, ТекДата, НаборЗаписей, Файл, ЭлектронноеПисьмо);
Для Каждого Вложение Из Письмо.Вложения Цикл
Если ТипЗнч(Вложение.Данные) = Тип("ИнтернетПочтовоеСообщение") Тогда
СохранитьВложенныеПисьма(Документ,
ТекущийПользователь,
ТекДата,
НаборЗаписей,
Вложение.Данные,
Файл.Название,
ЭлектронноеПисьмо)
Иначе
СтепеньСжатия = 6;
Файл.Описание = Вложение.Имя;
Файл.Название = Вложение.ИмяФайла;
Файл.Путь = Новый ХранилищеЗначения(Вложение.Данные, Новый СжатиеДанных(СтепеньСжатия));
Файл.UUID = ПолучитьUUID();
ЗаписатьФайл(Документ, ТекущийПользователь, ТекДата, НаборЗаписей, Файл);
КонецЕсли;
КонецЦикла;
// Удаляем временный файл
Попытка
УдалитьФайлы(КаталогВременныхФайлов(), Файл.Название);
Исключение
Возврат;
КонецПопытки;
КонецПроцедуры
Процедура ЗаписатьФайл(Документ,
ТекущийПользователь,
ТекДата,
НаборЗаписей,
Файл,
ЭлектронноеПисьмо = Неопределено,
НовыйUUID = Неопределено)
// Формируем новый UUID, если необходимо
Если Файл.UUID = Неопределено ИЛИ Файл.UUID = "" Тогда
Файл.UUID = ПолучитьUUID();
КонецЕсли;
Запись = НаборЗаписей.Добавить();
// Записываем измерения
НовыйUUID = Файл.UUID;
Запись.UUID = Файл.UUID;
Запись.ИспользуемыйДокумент = Документ;
// Записываем ресурсы
Запись.Название = Файл.Название;
Запись.Автор = ТекущийПользователь;
Запись.ДатаСоздания = ТекДата;
Запись.Редактор = ТекущийПользователь;
Запись.ДатаИзменения = ТекДата;
Запись.Описание = Файл.Описание;
Запись.ТипФайла = Файл.ТипФайла;
Запись.ЭлектронноеПисьмо = ЭлектронноеПисьмо;
// Если файл требуется хранить в произвольном месте
Если Файл.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория Тогда
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ПроизвольнаяДиректория;
Запись.ПутьДоФайла = Файл.Путь;
ИначеЕсли Файл.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория Или
(Не ЗначениеЗаполнено(Файл.СпособХранения) И ПолучениеЗначенийСервер.ПолучитьПараметр("ХранитьФайлыВПапке")) = ИСТИНА Тогда
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.УдаленнаяДиректория;
ПутьДоФайла = "";
// Сохраняем файлы в указанной папке
Если ТипЗнч(Файл.Путь) = Тип("ХранилищеЗначения") Тогда
Хранилище = Файл.Путь;
Иначе
Если Не ПустаяСтрока(Файл.Путь) Тогда
Хранилище = ПолучитьЗначениеДляХранилища(Файл.Путь);
Иначе
ПутьДоФайла = ПолучениеЗначенийСервер.ПолучитьПараметр("ПутьКХранилищу") + "\" + ПолучитьСкрытоеНазвание(Запись.Название, Запись.UUID);
КонецЕсли;
КонецЕсли;
Если Не ПустаяСтрока(ПутьДоФайла) Тогда
ЗаписатьФайлВПапку(Хранилище, Файл.Название, Запись.UUID, ПутьДоФайла);
Иначе
ЗаписатьФайлВПапку(Хранилище, Файл.Название, Запись.UUID, Файл.Путь);
КонецЕсли;
Запись.ПутьДоФайла = ПолучитьСкрытоеНазвание(Файл.Название, Запись.UUID);
Иначе
// Указываем способ хранения файла
Запись.СпособХранения = Перечисления.СпособХраненияФайла.ИнформационнаяБаза;
// Записываем файл в хранилище
// Если файл уже содержит ссылку на хранилище, тогда записываем хранилище
Если ТипЗнч(Файл.Путь) = Тип("ХранилищеЗначения") Тогда
Запись.Хранилище = Файл.Путь;
Иначе
Запись.Хранилище = ПолучитьЗначениеДляХранилища(Файл.Путь);
// Запись.Хранилище = ПолучитьЗначениеДляХранилища(Файл.Путь);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Функция записи файла в хранилище значений
Функция ПолучитьЗначениеДляХранилища(ПолноеИмяФайла)
Хранилище = Неопределено;
Если Не ПолноеИмяФайла = "" Тогда
ДлинаСтроки = СтрДлина(ПолноеИмяФайла);
Для НомерСтроки = 0 По ДлинаСтроки - 1 Цикл
СимволСтроки = Сред(ПолноеИмяФайла, ДлинаСтроки - НомерСтроки, 1);
Если СимволСтроки = "\" ИЛИ СимволСтроки = "/" Тогда
НачСимвол = ДлинаСтроки - НомерСтроки + 1;
// Заполняем хранилище
Попытка
Данные = ПолучитьИзВременногоХранилища(ПолноеИмяФайла);
Исключение
Данные = Новый ДвоичныеДанные(ПолноеИмяФайла);
КонецПопытки;
СтепеньСжатия = 6;
Хранилище = Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(СтепеньСжатия));
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Хранилище;
КонецФункции
// Процедура записи файла в предопределенную папку
Процедура ЗаписатьФайлВПапку(Хранилище, ИмяФайла, UUID, ПолныйПутьДоФайла)
Если ТипЗнч(Хранилище) = Тип("ХранилищеЗначения") Тогда
ДвоичныеДанные = Хранилище.Получить();
// Указываем путь до хранилища
ПутьДоХранилища = ПолучитьУдаленнуюДиректорию() + ПолучитьСкрытоеНазвание(ИмяФайла, UUID);
Попытка
ДвоичныеДанные.Записать(ПутьДоХранилища);
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Иначе
// Указываем путь до хранилища
ПутьДоХранилища = ПолучитьУдаленнуюДиректорию() + ПолучитьСкрытоеНазвание(ИмяФайла, UUID);
// Записываем файл в папку
Если ТипЗнч(ПолныйПутьДоФайла) = Тип("ХранилищеЗначения") Тогда
ДвоичныеДанные = ПолныйПутьДоФайла.Получить();
Иначе
СтруктураФайла = ПрикрепленныеФайлыСервер.ПолучитьДанныеФайлаПоGUID(UUID);
ДвоичныеДанные = СтруктураФайла.ДвоичныеДанные;
КонецЕсли;
Попытка
ДвоичныеДанные.Записать(ПутьДоХранилища);
Исключение
ИТ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
#КонецОбласти