Имя: Пароль:
1C
1С v8
Программное прикрепление файлов 1С Документооборот
,
0 Иванов Иван Иваныч
 
05.01.22
13:25
Доброго времени суток, подскажите как программно прикрепить файл в 1С документооборот 8? Программно создается док-т и необходимо по определенным критериям найти и прикрепить файл к только что созданному внутреннему док-ту. Не могу найти процедуру прикрепления файла. Буду благодарен за подсказку
1 Garykom
 
гуру
05.01.22
13:51
Замер и отладка
2 Garykom
 
гуру
05.01.22
13:52
3 серый КТУЛХУ
 
05.01.22
14:15
типа так?..
СведенияОФайле = РаботаСФайламиКлиентСервер.СведенияОФайле();
// ну или = РаботаСФайламиКлиентСервер.СведенияОФайле("ФайлСВерсией");
//СведенияОФайле.АдресВременногоХранилищаФайла = ...; СведенияОФайле.АдресВременногоХранилищаТекста = ...;
//СведенияОФайле.ВремяИзменения = ...; СведенияОФайле.ВремяИзмененияУниверсальное = ...;
//СведенияОФайле.Размер = ...; СведенияОФайле.ИмяБезРасширения = ...; СведенияОФайле.РасширениеБезТочки = ...;
ФайлСсылка = РаботаСФайламиВызовСервера.СоздатьФайл(ВладелецСсылка, СведенияОФайле);
// ну или = РаботаСФайламиВызовСервера.СоздатьФайлСВерсией(ВладелецСсылка, СведенияОФайле);
4 серый КТУЛХУ
 
05.01.22
14:16
прим.: прикреплять - само собой к уже записанному
5 Иванов Иван Иваныч
 
10.01.22
07:30
(3) предполагаю что как-то так, буду пробовать, но код выглядит многообещающе)
6 osa1C
 
10.01.22
08:21
(1) при чем здесь Замер и Отладка?
7 Масянька
 
10.01.22
08:26
(0) Случайно речь не о шаблонах?
8 osa1C
 
10.01.22
08:44
(7) По моему нет.... Программно создавая документ ТС хочет к нем у прикрепить файл типа pdf, doc, xls. Во всяком случае я так понял )))
9 Масянька
 
10.01.22
08:51
(8) Мне вообще не понятно - зачем при создании (новый документ!) прикреплять не шаблон. Но это - моё ИМХО.
10 osa1C
 
10.01.22
09:21
(9) >> Программно создается док-т и необходимо по определенным критериям найти и прикрепить файл к только что созданному внутреннему док-ту.
    не совсем понял из этого при чем тут шаблон? Если ТС хочет НАЙТИ И ПРИКРЕПИТЬ ФАЙЛ
о каком шаблоне речь?
11 Иванов Иван Иваныч
 
12.01.22
13:40
(8) да, всё верно, вроде разобрался с вызываемой процедурой, осталось реализовать)
судя по всему имеется в виду шаблон создаваемого документа (типа шаблон внутреннего документа Служебная записка)
но (7) и (9) не прав, шаблоны тут вообще не при делах
12 spiller26
 
12.01.22
14:49
Вот я делал реализацию автоматической загрузки файлов.

#Region Блок_Загрузка_Входящих_документов

Процедура ЗагрузитьВходящиеДокументы() Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ВидыВходящихДокументов.абтПапкаАвтоматическойЗагрузкиДокументов КАК ПапкаЗагрузки,
    |    ВидыВходящихДокументов.Ссылка КАК СсылкаВидВД,
    |    ВидыВходящихДокументов.абтУдалятьЗагруженныеДокументы КАК НомерУдаления
    |ИЗ
    |    Справочник.ВидыВходящихДокументов КАК ВидыВходящихДокументов
    |ГДЕ
    |    ВидыВходящихДокументов.абтЗагружатьДокументыИзПапки = ИСТИНА
    |    И ВидыВходящихДокументов.ЭтоГруппа = ЛОЖЬ
    |    И ВидыВходящихДокументов.ПометкаУдаления = ЛОЖЬ";
    РезультатЗапроса = Запрос.Выполнить().Выбрать();
    Пока РезультатЗапроса.Следующий() Цикл
        
        ПапкаЗагрузки = РезультатЗапроса.ПапкаЗагрузки;            
        ВидДокумента  = РезультатЗапроса.СсылкаВидВД;
        НомерУдаления = РезультатЗапроса.НомерУдаления;
        
        КаталогНаДиске = ПапкаЗагрузки;
                
        СтратегияРаспознавания = Неопределено;
        ЯзыкРаспознавания = Неопределено;
        УдалятьФайлыПослеДобавления = Истина;
        
        СтратегияРаспознавания = Перечисления.СтратегииРаспознаванияТекста.ПоместитьТолькоВТекстовыйОбраз;
        ЯзыкРаспознавания = РаботаСФайламиВызовСервера.ПолучитьЯзыкРаспознавания();
        
        Если ПустаяСтрока(КаталогНаДиске) Тогда
            ЗаписьЖурналаРегистрации(
                НСтр("ru = 'Автоматическая загрузка файлов (Входящие документы)'", Метаданные.ОсновнойЯзык.КодЯзыка),
                УровеньЖурналаРегистрации.Ошибка, , ,
                НСтр("ru = 'Не указан каталог на диске'"));
            Продолжить;
        КонецЕсли;
        
        ФайлКаталога = Новый Файл(КаталогНаДиске);
        Если Не ФайлКаталога.Существует() Тогда
            
            ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                    НСтр("ru = 'Неверный путь к каталогу на диске: ""%1""'"),
                    КаталогНаДиске);            
                    
            ЗаписьЖурналаРегистрации(
                НСтр("ru = 'Автоматическая загрузка файлов (Входящие документы)'", Метаданные.ОсновнойЯзык.КодЯзыка),
                УровеньЖурналаРегистрации.Ошибка, , ,
                ТекстОшибки);
                
            Продолжить;
        КонецЕсли;    
                
        Попытка
            
            ВыбранныеФайлы = Новый СписокЗначений;
            
            НайденныеФайлы = НайтиФайлы(КаталогНаДиске, "*.*");
            Для Каждого ФайлВложенный Из НайденныеФайлы Цикл
                ВыбранныеФайлы.Добавить(ФайлВложенный.ПолноеИмя);
            КонецЦикла;
            
            ПсевдоФайловаяСистема = Новый Соответствие; // соответствие путь к директории - файлы и папки в ней
            ДобавленныеФайлы = Новый Массив;
            МассивИменФайловСОшибками = Новый Массив;
            
            Описание = "";
            ХранитьВерсии = Истина;
            
            Если НомерУдаления = 0 Тогда
                УдалятьФайлыПослеДобавления = Ложь;
            Иначе
                УдалятьФайлыПослеДобавления = Истина;
            КонецЕсли;    
            
            ПапкаДляДобавленияТекущая = ИмпортФайловВходящихДокументовВыполнить(
                ВидДокумента,
                ВыбранныеФайлы,
                Описание,
                ХранитьВерсии,
                ДобавленныеФайлы,
                МассивИменФайловСОшибками,
                УдалятьФайлыПослеДобавления,
                Неопределено, //УникальныйИдентификатор,
                СтратегияРаспознавания,      
                ЯзыкРаспознавания,
                Неопределено,
                НомерУдаления,
                КаталогНаДиске);

            ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                    НСтр("ru = 'Закончена автоматическая загрузка файлов (Входящие документы) из каталога ""%1"". Загружено файлов: %2. Не удалось загрузить файлов: %3.'"),
                    КаталогНаДиске, ДобавленныеФайлы.Количество(), МассивИменФайловСОшибками.Количество());
            ЗаписьЖурналаРегистрации(
                НСтр("ru = 'Автоматическая загрузка файлов (Входящие документы)'", Метаданные.ОсновнойЯзык.КодЯзыка),
                УровеньЖурналаРегистрации.Информация, , ,
                ТекстСообщения);
                
        Исключение
            // запись в журнал регистрации
            
            ОписаниеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
            ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                    НСтр("ru = 'Ошибка автоматической загрузки файлов (Входящие документы): ""%1""  из каталога ""%2""'"),
                    ОписаниеОшибки, КаталогНаДиске);
            
            ЗаписьЖурналаРегистрации(
                НСтр("ru = 'Автоматическая загрузка файлов (Входящие документы)'", Метаданные.ОсновнойЯзык.КодЯзыка),
                УровеньЖурналаРегистрации.Ошибка, , ,
                ТекстСообщения);
        КонецПопытки;    
    КонецЦикла;
    
КонецПроцедуры

Функция ИмпортФайловВходящихДокументовВыполнить(
    ВидДокумента,
    ВыбранныеФайлы,
    Комментарий,
    ХранитьВерсии,
    ДобавленныеФайлы,
    МассивИменФайловСОшибкам,
    УдалятьФайлыПослеДобавления,
    ИдентификаторФормы,
    СтратегияРаспознавания,      
    ЯзыкРаспознавания,
    Категории,
    НомерУдаления,
    ПутьКФайлам)
    
    МассивФайлов = Новый Массив;
    Счетчик = 0;
    МассивФайловЗагрузки = Новый Массив;
    РежимЗагрузки = Истина;
    
    МассивСтруктурВсехФайлов = Новый Массив;
    МассивВсехПапок = Новый Массив;
    
    Для Каждого ИмяФайла Из ВыбранныеФайлы Цикл
        Попытка
            ВыбранныйФайл = Новый Файл(ИмяФайла.Значение);
            
            ВыбранКаталог = Ложь;
            Если ВыбранныйФайл.Существует() Тогда
                ВыбранКаталог = ВыбранныйФайл.ЭтоКаталог();
            КонецЕсли;
            
            Если НЕ ВыбранКаталог Тогда
                МассивФайлов.Добавить(ВыбранныйФайл);
            КонецЕсли;
        Исключение
            // запись в журнал регистрации
            ОписаниеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
            ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                    НСтр("ru = 'Ошибка автоматической загрузки файлов (Входящие документы): ""%1""'"),
                    ОписаниеОшибки);            
            ЗаписьЖурналаРегистрации(
                НСтр("ru = 'Автоматическая загрузка файлов (Входящие документы)'", Метаданные.ОсновнойЯзык.КодЯзыка),
                УровеньЖурналаРегистрации.Ошибка, , ,
                ТекстСообщения);
        КонецПопытки;
    КонецЦикла;
    
    // параметры распознавания по умолчанию    
    РаспознатьПослеДобавления = Истина;
    Если СтратегияРаспознавания = Перечисления.СтратегииРаспознаванияТекста.НеРаспознавать Тогда
        РаспознатьПослеДобавления = Ложь;
    КонецЕсли;
    
    ПараметрыРаспознавания = Новый Структура("СтратегияРаспознавания, ЯзыкРаспознавания, РаспознатьПослеДобавления",
        СтратегияРаспознавания, ЯзыкРаспознавания, РаспознатьПослеДобавления);
        
    Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
        
    Если МассивФайлов.Количество() <> 0 Тогда
        // Собственно импорт
        ИмпортФайловВходящихДокументов(
            ВидДокумента,
            МассивФайлов,
            Счетчик,
            ИдентификаторФормы,
            МассивФайловЗагрузки,
            МассивИменФайловСОшибкам,
            МассивСтруктурВсехФайлов,
            Комментарий,
            ДобавленныеФайлы,
            ХранитьВерсии,
            РежимЗагрузки,
            Пользователь,
            ПараметрыРаспознавания,
            Категории);
    КонецЕсли;
    
    Если УдалятьФайлыПослеДобавления Тогда
        УдалитьФайлыПослеДобавления(ДобавленныеФайлы, НомерУдаления, ПутьКФайлам);
    КонецЕсли;
    
    Если ВыбранныеФайлы.Количество() <> 1 Тогда
        ПапкаДляДобавленияТекущая = Неопределено;
    КонецЕсли;    
    
    Возврат ПапкаДляДобавленияТекущая;
    
КонецФункции    

Процедура ИмпортФайловВходящихДокументов(
    ВидДокумента,
    ФайлыАргумент,
    Счетчик,
    ИдентификаторФормы,
    МассивФайловЗагрузки,
    МассивИменФайловСОшибками,
    МассивСтруктурВсехФайлов,
    Комментарий,
    ДобавленныеФайлы,
    ХранитьВерсии,
    РежимЗагрузки,
    Пользователь,
    ПараметрыРаспознавания,
    Категории)
    
    МаксРазмерФайла = ФайловыеФункции.ПолучитьМаксимальныйРазмерФайла();
    ЗапретЗагрузкиФайловПоРасширению = ФайловыеФункции.ПолучитьЗапретЗагрузкиФайловПоРасширению();
    СписокЗапрещенныхРасширений = ФайловыеФункции.ПолучитьСписокЗапрещенныхРасширений();

    Для Каждого ВыбранныйФайл Из ФайлыАргумент Цикл
        
        Попытка

            Если ВыбранныйФайл.Существует() Тогда

                Если ВыбранныйФайл.Расширение = ".lnk" Тогда
                    ВыбранныйФайл = РазыменоватьLnkФайл(ВыбранныйФайл);
                КонецЕсли;
                
                Если Не ФайловыеФункцииКлиентСервер.ФайлМожноЗагружать(ВыбранныйФайл, МаксРазмерФайла, ЗапретЗагрузкиФайловПоРасширению, СписокЗапрещенныхРасширений, МассивИменФайловСОшибками) Тогда
                    Продолжить;
                КонецЕсли;    
                
                // Создаем Элемент справочника Файлы
                ИмяБезРасширения = ВыбранныйФайл.ИмяБезРасширения;
                Расширение = ВыбранныйФайл.Расширение;
                
                Если РежимЗагрузки Тогда
                    Если ЕстьФайлСТакимИменем(ИмяБезРасширения) Тогда
                        Запись = Новый Структура;
                        Запись.Вставить("ИмяФайла", ВыбранныйФайл.ПолноеИмя);
                        ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                            НСтр("ru = 'Файл с таким именем уже есть в информационной базе во входящих документах ""%1""'"),
                            Строка(""));            
                        Запись.Вставить("Ошибка", ТекстОшибки);
                        МассивИменФайловСОшибками.Добавить(Запись);
                        Продолжить;
                    КонецЕсли;    
                КонецЕсли;    
                
                АдресВременногоХранилищаФайла = ВыбранныйФайл.ПолноеИмя;
                
                АдресВременногоХранилищаТекста = ИзвлечьТекстВХранилищеЗначения(
                    ВыбранныйФайл.ПолноеИмя);
                    
                //Нужно создать владельца
                ОбъектВладелец = Справочники.ВходящиеДокументы.СоздатьЭлемент();
                ОбъектВладелец.Наименование = СокрЛП(ИмяБезРасширения);
                ОбъектВладелец.ВидДокумента = ВидДокумента;
                ОбъектВладелец.Заголовок = СокрЛП(ИмяБезРасширения);
                ОбъектВладелец.КоличествоЛистов = 1;
                ОбъектВладелец.КоличествоЭкземпляров = 1;
                ОбъектВладелец.Создал = Пользователь;
                ОбъектВладелец.ДатаСоздания = ТекущаяДатаСеанса();
                ОбъектВладелец.Записать();
                Владелец = ОбъектВладелец.Ссылка;
                
                // Создаем элемент справочника Файлы
                РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы(ВыбранныйФайл, МассивСтруктурВсехФайлов,
                    Владелец, ИдентификаторФормы, Комментарий, ХранитьВерсии, ДобавленныеФайлы,
                    АдресВременногоХранилищаФайла, АдресВременногоХранилищаТекста, Пользователь,
                    ПараметрыРаспознавания, Категории);
                
            Иначе
                Запись = Новый Структура;
                Запись.Вставить("ИмяФайла", ВыбранныйФайл.ПолноеИмя);
                Запись.Вставить("Ошибка", НСтр("ru = 'Файл отсутствует на диске'"));
                МассивИменФайловСОшибками.Добавить(Запись);
            КонецЕсли;

        Исключение
            ОшибкаИнфо = ИнформацияОбОшибке();
            СообщениеОбОшибке = "";
            Если ОшибкаИнфо.Причина = Неопределено Тогда
                СообщениеОбОшибке =ОшибкаИнфо.Описание;
            Иначе
                СообщениеОбОшибке = ОшибкаИнфо.Причина.Описание;
            КонецЕсли;
            
            Запись = Новый Структура;
            Запись.Вставить("ИмяФайла", ВыбранныйФайл.ПолноеИмя);
            Запись.Вставить("Ошибка", СообщениеОбОшибке);
            МассивИменФайловСОшибками.Добавить(Запись);
        
        КонецПопытки;
        
    КонецЦикла;
    
КонецПроцедуры    

// удаляет файлы после загрузки
//Не удалять(0), Сразу после загрузки(5), Через неделю(1), Через 2 недели(2), Через 3 недели(3), Через месяц(4)
Процедура УдалитьФайлыПослеДобавления(ДобавленныеФайлы, НомерУдаления, ПутьКФайлам)
    
    Если НомерУдаления = 5 Тогда
        Для Каждого Элемент Из ДобавленныеФайлы Цикл
            Попытка
                ВыбранныйФайл = Новый Файл(Элемент.ПолноеИмя);
                ВыбранныйФайл.УстановитьТолькоЧтение(Ложь);
                УдалитьФайлы(ВыбранныйФайл.ПолноеИмя);
            Исключение
            КонецПопытки;    
        КонецЦикла;
    Иначе
        //соберем файлы
        ВыбранныеФайлы = Новый СписокЗначений;
        НайденныеФайлы = НайтиФайлы(ПутьКФайлам, "*.*");
        Для Каждого ФайлВложенный Из НайденныеФайлы Цикл
            ВыбранныеФайлы.Добавить(ФайлВложенный.ПолноеИмя);
        КонецЦикла;
        //
        ДатаЗапретаУдаления = НачалоДня(ТекущаяДатаСеанса());
        Если НомерУдаления = 4 Тогда
            ДатаЗапретаУдаления = ДобавитьМесяц(ТекущаяДатаСеанса(), -1); //месяц
        ИначеЕсли НомерУдаления = 3 Тогда
            ДатаЗапретаУдаления = НачалоДня(ТекущаяДатаСеанса()) - (21*86400);  //3 недели
        ИначеЕсли НомерУдаления = 2 Тогда
            ДатаЗапретаУдаления = НачалоДня(ТекущаяДатаСеанса()) - (14*86400);  //2 недели
        ИначеЕсли НомерУдаления = 1 Тогда
            ДатаЗапретаУдаления = НачалоДня(ТекущаяДатаСеанса()) - (7*86400);   //1 неделя
        КонецЕсли;    
        Для Каждого ИмяФайла Из ВыбранныеФайлы Цикл
            Попытка
                ВыбранныйФайл = Новый Файл(ИмяФайла.Значение);
                
                ВыбранКаталог = Ложь;
                Если ВыбранныйФайл.Существует() Тогда
                    ВыбранКаталог = ВыбранныйФайл.ЭтоКаталог();
                КонецЕсли;
                
                Если НЕ ВыбранКаталог Тогда
                    //МассивФайлов.Добавить(ВыбранныйФайл);
                    ДатаПоследнегоИзменения = ВыбранныйФайл.ПолучитьУниверсальноеВремяИзменения();
                    Если ДатаПоследнегоИзменения < ДатаЗапретаУдаления Тогда
                        ВыбранныйФайл.УстановитьТолькоЧтение(Ложь);
                        УдалитьФайлы(ВыбранныйФайл.ПолноеИмя);
                    КонецЕсли;    
                КонецЕсли;
            Исключение
            КонецПопытки;
        КонецЦикла;
    
    КонецЕсли;     
    
КонецПроцедуры    

Функция ЕстьФайлСТакимИменем(ИмяФайла)
    
    ЗапросВПапки = Новый Запрос;
    ЗапросВПапки.УстановитьПараметр("Наименование", ИмяФайла);
    ЗапросВПапки.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
                         |    Файлы.Ссылка КАК Ссылка
                         |ИЗ
                         |    Справочник.Файлы КАК Файлы
                         |ГДЕ
                         |    Файлы.ПолноеНаименование = &Наименование
                         |    И ТИПЗНАЧЕНИЯ(Файлы.ВладелецФайла) = ТИП(Справочник.ВходящиеДокументы)";
    
    РезультатЗапроса = ЗапросВПапки.Выполнить();
    
    Если НЕ РезультатЗапроса.Пустой() Тогда
        Возврат Истина;
    КонецЕсли;
    
    Возврат Ложь;
    
КонецФункции

// Извлечь текст из файла и поместить в ХранилищеЗначения
Функция ИзвлечьТекстВХранилищеЗначения(ПолноеИмяФайла)
    
    Текст = "";
    
    ИзвлекатьТекстыФайловНаСервере = Константы.ИзвлекатьТекстыФайловНаСервере.Получить();
    Если Не ИзвлекатьТекстыФайловНаСервере Тогда
        
        ТипПлатформыСервера = ОбщегоНазначенияДокументооборотПовтИсп.ТипПлатформыСервера();
        Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда
            
            Текст = ФайловыеФункцииСлужебныйКлиентСервер.ИзвлечьТекст(ПолноеИмяФайла);
            
        КонецЕсли;            
        
    КонецЕсли;

    Если ПустаяСтрока(Текст) Тогда
        Возврат Новый ХранилищеЗначения("");
    КонецЕсли;

    ХранилищеЗначения = Новый ХранилищеЗначения(Текст);
    
    Возврат ХранилищеЗначения;
    
КонецФункции

// Разыменовать lnk файл
Функция РазыменоватьLnkФайл(ВыбранныйФайл)
    
    ТипПлатформыСервера = ОбщегоНазначенияДокументооборотПовтИсп.ТипПлатформыСервера();
    
    Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда
    
        ShellApp = Новый COMОбъект("shell.application");
        FolderObj = ShellApp.NameSpace(ВыбранныйФайл.Путь);        // полный (только) путь на lnk-файл
        FolderObjItem = FolderObj.items().item(ВыбранныйФайл.Имя);     // только имя lnk-файла
        Link = FolderObjItem.GetLink();
        Возврат Новый Файл(Link.path);
        
    КонецЕсли;
    
    Возврат ВыбранныйФайл;
КонецФункции

#EndRegion
13 Иванов Иван Иваныч
 
21.01.22
15:01
нашел решение, если кому нужно будет программно прикрепить файл к внутреннему документу в Документообороте 8 КОРП 2.1, то копайте в сторону следующей функции:

РаботаСФайламиВнешнийВызов.СоздатьФайлНаОсновеФайлаНаДиске(СсылкаНаВнутреннийДокумент, ПутьКФайлу);

Если в той же транзакции программно создается внутренний документ, то не забудьте его записать, чтобы иметь возможность получить на него ссылку
ПутьКФайлу должен содержать в т.ч. имя и формат файла, вид будет примерно следующий: Файл.ПолныйПуть