Рассмотрим алгоритм работы с файлами и картинками в новом интерфейсе 1С:Предприятие 8.3 «Такси».
Во-первых, почему я решил написать эту статью: Новая концепция 1С — отказ от модальных окон, следовательно все методы и объекты, которые порождали открытие модальных окон в новом интерфейсе работать не смогут, точнее смогут, только если в свойствах конфигурации разрешить модальные окна.
Однако, если разрешить модальные окна, то мы столкнемся с проблемами при работе в web-клиенте.
Во-вторых, о работе с картинками в управляемых формах часто спрашивают.
Итак, задача: в справочнике «Товары» необходимо сохранять и отображать в форме фотографию товара.
Исходная конфигурация не содержит ничего, кроме самого справочника с товарами, выкладывать ее не буду, просто создайте пустую конфигурацию в 8.3.
Для хранения самого графического файла, в справочнике создадим реквизит «ДанныеКартинки», с типом «Хранилище значений».
Если планируете выгружать картинку (файл) из информационной базы обратно в файловую систему, то добавьте еще реквизит, который будет хранить исходное имя файла и его тип.
Далее, займемся формой. Как видно на картинке, реквизит с типом хранилище значений в форме недоступен.
Как будем отображать картинку в форме? Нет, не декорацией с типом «картинка». А в виде реквизита формы с типом «строка». Да, да! Это очевидно, и странно, что мало кто об этом догадывается сам. 😉
Все дело в том, что если на форму вынести реквизит с типом «строка», который будет содержать навигационную ссылку на графические данные или адрес временного хранилища которое содержит такие данные, то форма сможет отобразить сами графические данные.
Добавим реквизит формы с именем «СсылкаНаКартинку», тип «строка», длина не ограничена. И поместим его в реквизиты формы.
По умолчанию, строка в форме будет выглядеть как поле ввода, нам нужно поменять это, в свойствах элемента формы. Выберем в свойстве «Вид» «Поле картинки».
Интерфейсная часть готова. Займемся кодингом. Создадим команду формы «ВыбратьФайлКартинки», в виде кнопки расположим ее на форме.
В модуле опишем обработчик события «Действие» для созданной команды формы:
Пару комментариев к вышеописанному коду:
Если бы мы не обращали внимание на режим модальности приложения, то могли вполне использовать метод «ПоместитьФайл», однако цель статьи показать работу с файлами именно в таком режиме.
Метод НачатьПомещениеФайла помещает выбранный файл во временное хранилище (если выбор файла был произведен) и вызывает процедуру «ОбработатьВыборФайла» в этом же модуле.
Обращаю внимание на выделенный «УникальныйИдентификатор», этим свойством мы связали временное хранилище с текущей формой. В противном случае файл в хранилище помещен будет, но само хранилище при серверном вызовет будет уничтожено, а нам оно еще понадобится, для записи файла в реквизит справочника.
Опишем процедуру «ОбработатьВыборФайла»:
Если пользователь не отказался от выбора файла, то в реквизит формы «СсылкаНаКартинку» помещаем адрес во временном хранилище, куда были помещены данные картинки.
Вуаля!
Так, осталось теперь при записи элемента справочника записать данные из временного хранилища в реквизит элемента справочника. Описываем событие ПередЗаписьюНаСервере:
Проверяем в реквизите формы у нас что? Если адрес временного хранилища, пишем данные в реквизит элемента справочника, обращаясь к «ТекущийОбъект», «ТекущийОбъект» — это сконвертированные данные формы, которые пишутся в базу в этот момент времени.
Осталось описать открытие формы, для отображения картинки уже сохраненной в реквизите элемента справочника.
Актуальную версию статьи и выгрузку базы с примером можно найти
тут.
Просто и доступно, спасибо!
что такое «модельных окон» ?
Опечатка.
(3) тогда исправляй везде, а не только в заголовке темы.
🙂
Вроде как диалоги открытия/закрытия файлов из браузера не требуют отключения блокировки всплывающих окон. Нафиг с ними то так заморочились?
Принцип остался тот же, что и для управляемых форм.
Так получается?
(6) YPermitin, да, такой же
Так это и есть управляемые формы.
— Как будем отображать картинку в форме? Нет, не декорацией с типом «картинка». А в виде реквизита формы с типом «строка»…
Суть этого реквизита — ссылка на ресурс внутри 1С. Если близко рассмотреть текст страницы это то что попадает в поле src
(9) [Суть этого реквизита — ссылка на ресурс внутри 1С.] sikuda, так я вроде как и написал…
Не только картинки, а вообще любые ХранилищаЗначения, которые нужно наполнять из управляемой формы требуют такого подхода. Суть проблемы — ХранилищеЗначения недоступно в данных формы. Если установить ему значение на сервере, то оно умрет при возврате на клиента. Нужно всегда использовать ВременноеХранилище, как промежуточный буфер, а в ПередЗаписьюНаСервере уже наполнять ТекущийОбъект нужными данными из временного хранилища.
Блин, я такой ложкой как на картинке в детстве борщи хлебал, ностальгия….
(12) OVladius, а я до сих пор! 🙂
(12) OVladius, я думал это намек на ложку дёгтя … )
(10) Увидел публикацию, не посмотрел на автора и подумал, что кто-то с Вашего мастер-класса, оказался шустрее автора)))
(12) OVladius, эта ложка которой 1С предлагает нам хлебануть г…на с «управляемыми» формами)))
Ложка весьма символично отражает тему статьи 🙂
а в обычной уф разве не так? причем тут такси?
(18) vano-ekt,
1. Такси это и есть УФ.
2. В Такси отказались от модальных окон.
(0) Спасибо за публикацию, актуальная тема
Желательно выложить базу пример.
Нужна функция очистить картинку
(11) Я думаю они это сделали специально. Они не предоставили API для работы с большим объемом данных, поэтому сделали это асинхронно, как загрузка картинок на html страницу. Это не проблема, это фича.
И есть повод понять что 1С внутри уже другое — Это же асинхронный код!!!
(21) sikuda, Нету там асинхронного кода. А не сделали они это да, специально. Я не говорю, что это косяк. Просто нужно понимать упр. форму и знать такую особенность с хранилищем значения.
А про асинхронку — ОбработкаОповещения — это не совсем то. Она не асинхронна в прямом смысле. Параллельно ничего не выполняется. Callback оповещения стоит в очереди и вызывается, когда это будет можно, но синхронно с остальным кодом.
Внутри 1С может быть и другое (я не видел), но нам, смертным, асинхронного исполнения не видать еще долго. Имхо.
(22) Согласен в текущем состоянии все загоняется в буфер и выпоняется последовательно. Какой то частью мы управляем, а какая-то(хранилище значений) делается без нас.
Я именно хочу обратить внимание, что выше приведенных код по сути своей асинхронный. И такой код будет все больше и больше проникать в типовые конфигурации, а дальше дело 1С как правильно включить паралельную работу. Асинхронный код это не подарок, это головная боль разработчика…
Говорить, что в 1С нет паралельной работы я бы не стал:
(23) sikuda,
Знаете, что тут происходит? Запускается отдельный сеанс с базой данных. Самостоятельный, управляемый планировщиком фоновых заданий. Да, по отношению к вашему коду он будет выполнен параллельно, но ограничений куча же. Все равно не понимаю, какое отношение имеет реквизит управляемой формы «ХранилищеЗначения» и асинхронное исполнение?
Пока транзакция записи объекта не завершится, ваш код не может ничего сделать, где тут асинхрон? асинхрон по отношению к чему?
(20) Evg-Lylyk, Зачем базу, тут 20 строк кода? Правда нужно?
(25) Думаю было бы полезно я вот хотел посмотреть как работает после Перечитать.
тоже в свое время брал пример из Профессиональной разработки»http://infostart.ru/public/185351/ с применением для БГУ, но можно и для прочего…
(24) Вернемся к асинхронному коду (11) Очень внимательно читаем справку:
«В тонком и толстом клиентах, в отличие от веб-клиента, метод блокирует исполнение кода языка. Тем не менее, по завершению помещения файла указанный обработчик оповещения также будет вызван, но до исполнения кода, размещенного после вызова метода.»
И в код после НачатьПомещениеФайла вставим бесконечный цикл. В Тонком клиенте сначала выбор файла. Потом цикл.
А в web-клиенте наоборот сначала зависаем (браузер просит остановить цикл), потом выбор файла.
То есть в web-клиенте Оповещение работает как чистый callback javascript.
Именно это я пытаюсь вложить в фразу «код по сути своей асинхронный». И именно такое поведение стандартное для javascript на web страницах.
(28) sikuda, понял, мы говорим о совсем разных вещах, поэтому не понимаем друг-друга 🙂
Спасибо за статью.
Замечание: про размещение на форме строки с видом Картинка и навигационной ссылкой на данные картинки следовало бы описать в статье, что это методика изначально Управляемого приложения, т.е. с 8.2 так работает. А нового здесь — только немодальные «модальные» методы с описанием оповещения.
Удалил про html5 (Не будем смущать неокрепшие умы 1С-ников)
(0) …(Убрал по просьбе автора)
(32) sikuda, на мой взгляд к моей статье это вообще только словом «картинка» привязать можно 🙂
(33)
Спасибо! Я всегда пользовалась как раз декарацией(в всяком случае в 8.2)
ну это уж даже самое главное ..
Правильно я понимаю, что если бы я сделала реквизит типа не строка, а хранилище значения, и указала бы у поля путь к нему.. Пришлось бы мучаться с таким функционалом, как ДанныеФормыВЗначение и ЗначениеВДанныеФормы?
Строка — это реквизит формы. Как Вы собрались реквизит формы с типом ХранилищеЗначения сделать?
Спасибо за прием работы с файлами!
Помогите разобраться с такой проблемой:
При активизации строки табличной части пытаюсь отобразить картинку на форме:
Показать
В момент присвоения СсылкаНаКартинку=ПолучитьКартинку(Элемент.ТекущиеДанные.НомерСтроки); платформа падает.
СсылкаНаКартинку в этот момент содержит текст:
«e1cib/data/БизнесПроцесс.СогласованиеДоговора.Файлы.ДанныеКартинки?ref=8711be1ed620b4fc11e38ca646b858c4&index=0»
В чем может быть проблема?
Все, разобрался. Может, кому-то пригодится. Надо было сначала считать картинки объекта и поместить их во временное хранилище:
Показать
(37) clev, зачем картинку во временное хранилище пихать? Это же физическая запись на диск. Достаточно навигационную ссылку получить.
(38) не могу разобраться, почему код из (36) не работает. Не подскажете, что не так?
(39) clev, я процедуру ПриЧтенииНаСервере() заменил на ПриСозданииНаСервере(). На форме предварительно сделал реквизит типа «ТаблицаЗначений» с колонкой «АдресВременногоХранилища». В ПриСозданииНаСервере() получал данные картинок из ТЧ файлов и клал их во временное хранилище(только надо не забыть преобразовать реквизит формы в значение и после всего обратно в реквизит формы). Адреса временных хранилищ положил в созданный реквизит построчно. А в процедуре ПриАктивизацииСтроки() присваивал СсылкеНаКартинку адреса временных хранилищ(индексы совпадают), полученные из реквизита формы. А изначально платформу тоже вышибало.
(40) alexkon, Так в (37) я почти так и делаю.
Только не создаю новую ТЗ, а в табличной части формы добавил реквизит c типом «строка».
И при ПриЧтенииНаСервере() в этот реквизит записываю адрес во временном хранилище.
В этом варианте все работает. Но GROOVY в (38) говорит, что так не правильно.
С файлом вроде более-менее понятно, но я не могу найти способ немодального «таксишного» выбора каталога. Может кто подскажет как это сделать?
Мне надо чтобы пользователь выбрал каталог, а после выбора строку каталога записать в реквизит справочника.
(42) alf2006x,
Вопрос снят.
А как в данном способе применить фильтр на тип файла (Расширение)?
(36) clev,
Вот тоже с похожим случаем столкнулся при изменении режима совместимости конфы:
Есть два случая — получаю файл из реквизита ссылки:
и получаю из реквизита табличной части ссылки:
Меняю режим совместимости с 8.2.13 на «не использовать» (для плафтормы 8.3.5), и первый код так и остаётся рабочим, зато второй начинает падать:
«Неправильный путь к файлу ‘e1c://server/SRV-1С:3541/TestGD/e1cib/data/Справочник.ВариантыДоговоров.ПечатныеФормы.Данные?ref=b5df0025900ab87711e233d403d247a3&index=0′»
помогает только если переписать с получения ссылки на помещение в хранилище, причем если не использовать метод Получить() (спасибо (37)), то полученный адрес тоже будет нерабочим. Отчего такая беда, непонятно (((
(45) Smallrat, ТекущаяСтрока элементов формы <> Индекс или номер строки данных. Нужно ссылаться именно на данные записанные в БД.
(46) Там в третьем параметре надо указать индекс строки. «Элементы.ПечатныеФормы.ТекущаяСтрока» у меня даёт 0 — вполне себе индекс. я и просто число указывал, всё равно не работает. Причём при включенном режиме совместимости ошибок нет.
(47) Smallrat, еще раз, ТекущаяСтрока это НЕ индекс. И есть ли данные на которые ссылается текущая строка в базе?
У меня такая же трабла. Кто может помоч ? При строке платформа проваливается
Объект.АдресКартинки=ПолучитьНавигационнуюСсылку(Объект.Ссылка,»ТЧПрикрепленныеФайлы.ПрикрепленныйФайл»,0);
Тут так и не разобрались. Т
(49) aseiduldayev, Какая «такая же»?
Куда проваливается платформа?
(48) Хорошо, действительно параметр ТекущаяСтрока некорректно использовать (хоть в моем случае это 0)
переписал так:
Показать
Всё равно валится с выключенным режимом совместимости, а с включенным 8.2 нет. Данные в базе есть — я могу их получить, поместить во временное хранилище и выгрузить на клиенте через адрес хранилища. Я покопал форумы — нигде решения нет, кроме как обходить.
У меня не получается, ошибка:
{Справочник.Лис_ТипыКонтейнеров.Форма.ФормаЭлемента.Форма(15)}: Ошибка при вызове конструктора (ОписаниеОповещения)
Оповещение = Новый ОписаниеОповещения(«ОбработатьВыборФайла», Объект);
по причине:
Не найден экспортируемый метод: ОбработатьВыборФайла
А ещё в процедуре «ВыбратьФайлКартинки» ругается на «ЭтотОбъект»
(53) 3762515, Надо, просто на 8.3 кодить.
пишу
ругается
ПолучитьФайл(Адрес, Объект.Наименование);
по причине:
Неправильный путь к файлу ‘e1c://filev/C/bases/desktopSD/e1cib/data/Справочник.sd_Файлы.ДанныеФайла?ref=bdda4487fca76d4611e4cd932712cf62’
ДанныеФайла — хранилище значений с данными файла
что я делаю не так? (8.3.5.1460)
П.С. Разобрался. Пытался поместить данные через реквизитформывзначение, запись в реквизит, затем значениевреквизитформы. так не правильно, потому что после обратного перехода в реквизит формы данные теряются. не повторяйте моих ошибок
(44) 911service,
Фильтр по расширению:
Показать
И получать картинки нужно в ПриЧтенииНаСервере
А как теперь можно ещё сделать функцию сохранения на диск картинки из базы?
Здравствуйте!
Сделала так, как у вас написано. Картинка добавляется, но при последующем открытии элемента пропадает. Подскажите, пожалуйста, в чем может быть проблема?
не получилось! вообще не чего. одни ошибки (((((
{Справочник.Товары.Форма.ФормаЭлемента.Форма(5,64)}: Переменная не определена (ЭтотОбъект)
Оповещание = Новый ОписаниеОповещения(«ОбработатьВыборФайла», <<?>>ЭтотОбъект); (Проверка: Толстый клиент (обычное приложение))
Всё работает без ошибок. только картинка не отображается.
Можете подсказать. всё написано как в посте, ничего своего.
Показать
Доброго времени суток,Коллеги.
Извиняюсь за некропостинг, но думаю новую тему не стоит ради такого пустяка заводить) Поясните ЧЯДНТ — есть самописка, с запрещенными модальными вызовами пишу а-ля:
Показать
СписокФайлов — соответственно список значений, где значения — файлы, представление — текстовой описание файла. Код отрабатывает, всё выполняется, но… выдает предупреждение, что использование синхронных методов запрещено… Кто и где синхронный-то?
(64) вы уверены, что предупреждение именно на этот фрагмент кода? попробуйте выделить весь текст модуля и через контекстное меню «рефакторинг» выполнить замену всех синхронных методов, посмотрите что получится
Спасибо за мануал. помог. Пытаюсь отобразить загруженный пдф док на форме в web-клиенте.
Показать
Поле появляется и пишет, что невозможно отобразить pdf документ. на толстом клиенте все работает изумительно