gifts2017

Прикрепление внешних файлов к документам и справочникам 1С 8.3 (управляемые формы)

Опубликовал Николай Борисов (omenfarsh) в раздел Программирование - Практика программирования

В данной статье мы рассмотрим, как просто и быстро в любую конфигурацию на базе управляемых форм добавить функционал прикрепления внешних файлов к документам и справочникам.
Я начну описание с нуля, т.е. с создания пустой конфигурации. Так что даже  любой малоопытный разработчик (вроде меня =) ) сможет реализовать данный функционал в своей или уже написанной конфигурации.
Если Вам не хочется разбираться с ниже написанной инструкцией, можете скачать файл*.doc с описанием и скриншотами, либо уже саму готовую конфигурацию.

1. Создание информационной базы:

 - Запустим 1С и в окне "Список информационных баз" выберем «Добавить»:

 - в открывшемся окне ставим переключатель на «Создание информационной базы без конфигурации…»:

 - далее выбираем «Создание новой информационной базы» и нажимаем «Далее»:

 - Указываем имя информационной базы, нажимаем «Далее»:

 - Указываем папку, где будет храниться информационная база (желательно создать папку заранее), нажимаем «Далее»:

 - В открывшемся окне нажимаем «Готово»:

 Информационная база с указанным именем появится в списке.

 

2. Открытие конфигурации:

 Выбираем данную базу и нажимаем «Конфигуратор»:

- в открывшемся окне для простоты можно нажать в левом верхнем углу кнопку «Открыть конфигурацию»:

 

 3. Создание справочника «Файлы»:

Сразу оговоримся, что рассматриваемый пример упрощен и произвольный файл мы будем хранить в одном из реквизитов самого справочника.

Итак, справочник «Файлы» будет содержать два реквизита: Файл (для хранения двоичных данных),  ИмяФайла (для хранения имени загруженного файла) и СсылкаНаВладельца (для привязки файла к нужному для нас документу).

 - Создадим две подсистемы «Справочники» и «Документы»:

 - Создадим новый справочник и назовем его «Файлы»:

 - Перейдем на закладку «Подсистемы» и добавим данный справочник к подсистеме «Справочники»:

 - Перейдем на закладку «Данные» и добавим новый реквизит, назовем  его «Файл» и укажем Тип «ХранилищеЗначения»:

 - Добавим еще один реквизит, назовем  его «ИмяФайла» и укажем Тип «Строка», поставим галочку «Неограниченная длина»:

 - Добавим еще один реквизит, назовем  его «СсылкаНаВладельца» и укажем Тип «ДокументСсылка»:

- Переходим на закладку «Формы» и в поле Формы элемента нажимаем кнопку «Открыть»:

 - В открывшемся окне можно ничего не менять и нажать кнопку «Готово»:

 - Далее создадим Форму списка, в поле Формы списка нажимаем кнопку «Открыть»:

- В открывшемся окне теперь нажимаем «Далее»:

 - Теперь указываем какие колонки должны отображаться в Форме списка, поставим галочку напротив «СсылкаНаВладельца» и нажимаем «Готово»:

 - В открывшейся форме для красоты столбец «Код» переместим на верх (т.е.в начало таблицы):

 Форма элемента справочника "Файлы", помимо данных самого объекта, будет содержать два дополнительных реквизита: "Имя" и "СсылкаНаФайлВоВременномХранилище"

 - В правой части под "Объектом" добавим реквизит и назовем  его «Имя» и укажем Тип «Строка»:

 - Добавим еще один реквизит, назовем  его «СсылкаНаФайлВоВременномХранилище» и укажем Тип «Строка»:

 

Для загрузки файла с диска в информационную базу и для сохранения его на диск в форме элемента создадим две локальные команды:  "ЗагрузитьСДиска" и "СохранитьНаДиск"

 - Перейдем на вкладку «Команды» и создадим новую локальную команду «ЗагрузитьСДиска»:

 - На вкладке «Команды» создадим еще одну локальную команду «СохранитьНаДиск»:

 - На вкладке «Элементы» добавим группу «Обычная группа»:

 - Теперь перетащим в созданную группу наши локальные команды:

 - Установим горизонтальное положение кнопок на форме и снимем галочку «ОтображатьЗаголовок»:

 - И для красоты создадим еще в этой группе «Декорацию-надпись»:

 - Щелкаем правой мышкой на кнопке «Загрузить с диска» и выбираем «Действие команды»:

 - оставляем «Создать на клиенте», нажимаем «ОК»:

- Вставляем код:

 

&НаКлиенте
Процедура ЗагрузитьСДиска(Команда)      
АдресВХранилище = "";
ВыбранноеИмяФайла = "";
Если ПоместитьФайл(АдресВХранилище, , ВыбранноеИмяФайла, , УникальныйИдентификатор) Тогда
Файл = Новый Файл(ВыбранноеИмяФайла);
Имя = Файл.Имя;
СсылкаНаФайлВоВременномХранилище = АдресВХранилище;
Объект.Наименование = Файл.Имя;
Модифицированность = Истина; 
Объект.ИмяФайла = Имя;
КонецЕсли;                
КонецПроцедуры

 

-  Повторяем ситуацию с кнопкой «Сохранить на диск», только теперь вставляем следующий код:

 

&НаКлиенте
Процедура СохранитьНаДиск(Команда)
Если Объект.ИмяФайла = "" Тогда
Предупреждение("У поставщика нет сохраненного в базе договора");
Иначе
СсылкаНаФайлВИБ = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "Файл");
ПолучитьФайл(СсылкаНаФайлВИБ, Объект.ИмяФайла);
КонецЕсли;        
КонецПроцедуры

 

- В свойствах формы создаем следующие процедуры: "ПередЗаписьюНаСервере", "ПриЗаписиНаСервере" и "ПриОткрытии и подставляем код":

  

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)       
// Получить файл из хранилища и поместить его в объект.
Если ЭтоАдресВременногоХранилища(СсылкаНаФайлВоВременномХранилище) Тогда
ДвоичныеДанные = ПолучитьИзВременногоХранилища(СсылкаНаФайлВоВременномХранилище);
ТекущийОбъект.Файл = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
//ТекущийОбъект.ИмяФайла = ИмяФайлаКонтрагента;
ТекущийОбъект.ИмяФайла = Имя;       
КонецЕсли;       
КонецПроцедуры
 
&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
//Удалить файл из временного хранилища
Если ЭтоАдресВременногоХранилища(СсылкаНаФайлВоВременномХранилище) Тогда
УдалитьИзВременногоХранилища(СсылкаНаФайлВоВременномХранилище);
КонецЕсли;
КонецПроцедуры
 
&НаКлиенте
Процедура ПриОткрытии(Отказ)      
Имя = Объект.ИмяФайла;          
КонецПроцедуры

 

- теперь запускаем "Предприятие":

- Пытаемся создать элемент справочника, если выскакивает ошибка «Использование модальных окон в данном режиме запрещено!:

Сделаем не очень хорошую вещь:

В конфигураторе правой кнопкой мышки на назвони конфигурации щелкаем и выбираем «Свойства», где в самом низу в строке «Режим использования модальности» ставим «Использовать» и перезапускаем базу.

Теперь все должно заработать!

 

4. Создание Критерия отбор «СвязанныеДокументы»:

В дальнейшем данный критерий отбора нам понадобится, чтобы отобрать в табличную часть документа файлы, которые с ним связаны.

- Создадим новый критерий отбора и назовем его «СвязанныеДокументы»:

- Перейдем на закладку «Подсистемы» и добавим данный критерий отбора к подсистеме «Документы»:

- Перейдем на закладку «Данные» и установим Тип «ДокументСсылка»:

- Перейдем на закладку «Состав» и выберем реквизит справочника «Файлы» «СылкаНаВладельца»:

- Перейдем на закладку «Формы» и создадим Форму списка:

- В форму списка перетаскиваем реквизит Объекта «СсылкаНаименование»:

 

5. Создание документа «Продажи»:

Теперь создадим простенький документ с целью прикрепить к нему файлы.

- Создадим новый документ и назовем его «Продажи»:

- Перейдем на закладку «Подсистемы» и добавим данный документ к подсистеме «Документы»:

- Перейдем на закладку «Данные» и добавим данный какой-нибудь реквизит, к примеру,  «Описание» с Типом «Строка» неограниченной длины и в многострочном режиме:

- На закладке «Данные» добавим табличную часть, назовем ее «СписокДокументов»:

- На закладке «Данные» в табличную часть добавим реквизит и именем «Файл» и Типом «СправочникСсылка.Файлы»:

- На закладке «Данные» в табличную часть добавим реквизит и именем «Документ» и Типом «ДокументСсылка»:

- Перейдем на закладку «Формы» и создадим форму списка:

- В открывшемся окне нажимаем кнопку «Далее»:

 - В открывшемся окне выбираем реквизит «Ссылка» и нажимаем кнопку «Готово»:

- Перейдем на закладку «Формы» и создадим форму документа:

- В открывшемся окне нажимаем кнопку «Готово»:

- В открывшейся форме документа добавляем Группу «Обычная группа» и назовем ее «Документы»:

- И перетаскиваем в нее реквизиты так как показано на картинке ниже. Аналогично создаем еще одну такую группу с названием «Файлы» и перетаскиваем в нее «Список Документов»:

- Добавляем новую Группу «Страницы» и перетаскиваем в нее группы «Документы» и «Файлы»:

- На вкладке «Команды» создадим новую локальную команду с именем «ПолучитьСписок» и перетащим ее в папку Файлы:

- На появившейся кнопке на форме документа кликаем правой кнопкой мышки выбираем «Действие команды»:

- Создаем на клиенте:

- Добавляем следующий код:

 

&НаКлиенте
Процедура ПолучитьСписок(Команда)               
ЭтаФорма.Объект.СписокДокументов.Очистить();      
МасивДокументов = ПолучитьСписокПодчиненныхДокументов(Объект.Ссылка);
Для Каждого Строка Из МасивДокументов Цикл
                   НоваяСтрока = Объект.СписокДокументов.Добавить();
                   НоваяСтрока.Файл = Строка.Файл;
                   НоваяСтрока.Документ = Строка.Документ;
КонецЦикла;     
КонецПроцедуры

 

- Также добавляем функцию:

 

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


- Переходим к справочнику «Файлы» на закладку «Ввод на основании», в верхней части кликаем на карандаш и выбираем Документ «Продажи» и нажимаем «ОК»:

- После этого кликаем «Конструктор ввода на основании»:

- В открывшейся форме напротив Поля «СсылкаНаВладельца» кликаем и выбираем вверху «Ссылка», потом жмем «ОК»:

- Теперь всё должно заработать!

 

В документе через «Создать на основании» прикрепляем файлы, а список получаем, переходя на страницу «Файлы» и нажав на кнопку «Получить список». После записи документа список сохраняется.

- Все файлы записываются в справочник «Файлы»

Скачать файлы

Наименование Файл Версия Размер
Конфигурация 31
.cf 25,64Kb
15.10.15
31
.cf 25,64Kb Скачать
Статья "Прикрепление файлов" (со скриншетами) 9
.docx 3,12Mb
15.10.15
9
.docx 3,12Mb Скачать

См. также

Вознаграждение за ответ
Сумма: 0 $m
Добавили:
Райса Хамитова (HamitovaRaisa) (0.10 $m)
Подписаться Добавить вознаграждение
Комментарии
1. борян петров (TODD22) 15.10.15 18:57
Так что даже любой малоопытный разработчик (вроде меня =) ) сможет реализовать данный функционал в своей или уже написанной конфигурации.

Хранение произвольных данных в конфигурации(сканов, фотографий, документов и тд) не самый хороший вариант.

Я бы сказал что даже очень не хороший. Прихожу как то в одну компанию. А они говорят у нас база тормозит.
Смотрю базу размер 76 Гб. База на SQL сервере. Какой то талантливый парень дописал хранение документов в реквизит объекта.
Начинаю разбираться... в итоге вес учётных данных в базе 1.5 Гб. А всё остальное натолкали пользователи, сканов, фотографий и тд . Пришлось выносить во внешнее хранилище....
Вес некоторых фотографий доходил до 7 Мб. Натолкают 10-15 фотографий в базу... а потом у них тормозит всё....
Lena272; omenfarsh; zqzq; +3 Ответить 2
2. Николай Борисов (omenfarsh) 16.10.15 12:59
(1) TODD22, согласен с вами полностью! Но я столкнулся с другой ситуацией, когда надо было написать конфигурацию для учета заявок и к каждой заявке прикреплять несколько документов (решения, отчет по выполнению и т.д.). При этом базу часто переносят с компьютера на компьютер и прикрепленные файлы могут просто остаться в другом месте. Т.к. конфа была самописная и весила менее 10Мб, то мое решение оказалось вполне уместным.
3. Владимир Чепурной (91197ch) 16.10.15 15:15
А мы в этих же управляемых формах сделали так: есть закладка "Файлы" в нее добавляешь файл, а он передает этот файл в секретный каталог на сервере и сохраняет внутри программы путь к этому файлу. В итоге в Базе хранятся лишь ссылка на файлы. Сами файлы в каталоге на сервере, который архивируется каждый день. И база не растет и ограничений на файлы нет. Есть правда пока нюанс. Работает только внутри сети. Если кто-то заходит через Web сервер то доступ к файлам не дается.
4. Франко Деллиани (Franco) 16.10.15 15:17
1.Скриншот через «о». Но это так, к слову
2.Хорошо было бы не привязывать 1 одному дркументу или справочнику владельцу. Сделать регистр сведений, измерения: «Ссылка на владельца» и «Ссылка на файл».
Тогда можно 1 хранимый файл привязывать к нескольким. Это кажется лишним? Ничего подобного - у меня уже такая необходимость случилась.
Тогда при добавлении справочника, допустим, «Номенклатура» его тип можно добавить в тип измерения.
3.Да, программа будет жутко торможить при считывании об'екта. Но при указании ссылки на справочник файлов или при испролльзовании связывающего регистра - никак. У меня ещё и не такие монстры в наследство достались...
4.И всё же файлы лучше хранить на диске - в справочнике файлы указывать ссылку на местоположение на сетевом диске. (у этого местоположения доступ пользователя, от которого запущен сервер 1С и недоступность пользователей). И - самое интересное - файлы легко архивировать
5.А вот шаблоны, бланки договоров и прочее «редкое и маломеняемое» - это да, самые что ни на есть хранимые файлы
6.Адрес временного хранилища в реквизите хранить не имеет смысла. Файл во временном хранилище живёт пока открыта форма, где он загружен.
5. Франко Деллиани (Franco) 16.10.15 15:21
Забыл
Откажитесь от «ПолучитьФайлы» и «ПоместитьФайлы» в пользу «НачатьПолучениеФайлов» и «НачатьПомещениеФайлов». Рефакторинг в конфигурации в помощь.
6. Николай Борисов (omenfarsh) 17.10.15 09:26
Спасибо всем за комментарии! Буду улучшать свой "шаблон" дальше и по возможности им поделюсь!
7. борян петров (TODD22) 18.10.15 10:47
&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
//Удалить файл из временного хранилища
Если ЭтоАдресВременногоХранилища(СсылкаНаФайлВоВременномХранилище) Тогда
УдалитьИзВременногоХранилища(СсылкаНаФайлВоВременномХранилище);
КонецЕсли;
КонецПроцедуры
 
...Показать Скрыть

Мне кажется вот эта часть кода не нужна. Если временное хранилище привязано к форме то после закрытия формы оно будет очищено автоматически.
И принудительно при записи объекта его большого смысла очищать нет.
8. Ловыгин Антон (wunderland) 21.10.15 09:31
Все равно коллега - молодец. Сделал, оформил, выложил... Понятно и доступно. А набор напильников у каждого свой :)
9. Павел Малахов (sermalp) 28.10.15 17:54
(3) 91197ch, А есть ли доступ к секретному каталогу для пользователя от которого агент 1С работает?
10. Павел Малахов (sermalp) 28.10.15 18:01
(1) TODD22, можете сказать оптимальное, на ваш взгляд, решение задачи - хранение файлов в локальном каталоге; и как их потом отдавать (скачать) пользователю при клике по гиперссылке, например?
11. Александр Отт (MeatCrash) 24.02.16 09:52
А нет ли у Вас случайно такого же примера, в котором ссылки на файлы были помещены в табличную часть документа? И где их можно было выбирать и видеть куда эти ссылки указывают (с указанием пути до файла и его имени)?
12. Райса Хамитова (HamitovaRaisa) 18.05.16 08:26
Спасибо за подробную раскладку, а то зависла я с добавлением файла в управляемой форме уже продолжительное время. Попробую реализовать по этому алгоритму. А вместо справочника регистр сведений можно использовать?
13. Николай Борисов (omenfarsh) 18.05.16 11:46
(12) HamitovaRaisa, справочник с файлами не обязательно делать доступным для клиента, можно лишь оставить переход по ссылкам из формы документа или справочника. С Регистрами, если честно, не пробывал, но как минимум в Измерения нельзя добавить ХранилищеЗначения.
14. anry mc (AnryMc) 07.07.16 09:44
Итак, справочник «Файлы» будет содержать два реквизита: Файл (для хранения двоичных данных), ИмяФайла (для хранения имени загруженного файла) и СсылкаНаВладельца (для привязки файла к нужному для нас документу).


Файл + ИмяФайла + СсылкаНаВладельца <> 2 реквизита