Работа с файлами (картинками) в интерфейсе Такси
(бесплатная статья по Программированию в 1С)

О чем эта статья

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

Применимость

В статье рассматривается платформа «1С:Предприятие» редакции 8.3. Представленная информация актуальна для текущих релизов платформы.

Работа с файлами (картинками) в интерфейсе Такси

Рассмотрим алгоритм работы с файлами и картинками в новом интерфейсе 1С:Предприятие 8.3 “Такси”.

Во-первых, почему я решил написать эту статью: Новая концепция 1С – отказ от модальных окон, следовательно все методы и объекты, которые порождали открытие модальных окон в новом интерфейсе работать не смогут, точнее смогут, только если в свойствах конфигурации разрешить модальные окна.
Режим использования модальности в интерфейсе Такси

Для увеличения нажмите на изображение.

Однако, если разрешить модальные окна, то мы столкнемся с проблемами при работе в web-клиенте.

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

Итак, задача: в справочнике “Товары” необходимо сохранять и отображать в форме фотографию товара.
Исходная конфигурация не содержит ничего, кроме самого справочника с товарами, выкладывать ее не буду, просто создайте пустую конфигурацию в 8.3.

Для хранения самого графического файла, в справочнике создадим реквизит “ДанныеКартинки”, с типом “Хранилище значений”.
Отображение фотографий товаров в 1С

Для увеличения нажмите на изображение.

Если планируете выгружать картинку (файл) из информационной базы обратно в файловую систему, то добавьте еще реквизит, который будет хранить исходное имя файла и его тип.

Далее, займемся формой. Как видно на картинке, реквизит с типом хранилище значений в форме недоступен.

Форма элемента - ХранилищеЗначения

Для увеличения нажмите на изображение.

Как будем отображать картинку в форме? Нет, не декорацией с типом “картинка”. А в виде реквизита формы с типом “строка”. Да, да! Это очевидно, и странно, что мало кто об этом догадывается сам.

Все дело в том, что если на форму вынести реквизит с типом “строка”, который будет содержать навигационную ссылку на графические данные или адрес временного хранилища которое содержит такие данные, то форма сможет отобразить сами графические данные.
Добавим реквизит формы с именем “СсылкаНаКартинку”, тип “строка”, длина не ограничена. И поместим его в реквизиты формы.
Ссылка на картинку в реквизитах формы 1С

Для увеличения нажмите на изображение.

По умолчанию, строка в форме будет выглядеть как поле ввода, нам нужно поменять это, в свойствах элемента формы. Выберем в свойстве “Вид” “Поле картинки”.
Свойства: Поле - изменить поле ввода, на поле картинки

Для увеличения нажмите на изображение.

Интерфейсная часть готова. Займемся кодингом. Создадим команду формы “ВыбратьФайлКартинки”, в виде кнопки расположим ее на форме.
1С Выбрать файл картинки

Для увеличения нажмите на изображение.

В модуле опишем обработчик события “Действие” для созданной команды формы:
Процедура ВыбратьФайлКартинки

Для увеличения нажмите на изображение.

Пару комментариев к вышеописанному коду:

Если бы мы не обращали внимание на режим модальности приложения, то могли вполне использовать метод “ПоместитьФайл”, однако цель статьи показать работу с файлами именно в таком режиме.
Метод НачатьПомещениеФайла помещает выбранный файл во временное хранилище (если выбор файла был произведен) и вызывает процедуру “ОбработатьВыборФайла” в этом же модуле.

Обращаю внимание на выделенный “УникальныйИдентификатор”, этим свойством мы связали временное хранилище с текущей формой. В противном случае файл в хранилище помещен будет, но само хранилище при серверном вызовет будет уничтожено, а нам оно еще понадобится, для записи файла в реквизит справочника.

Опишем процедуру “ОбработатьВыборФайла”:
ОбработатьВыборФайла

Для увеличения нажмите на изображение.

Если пользователь не отказался от выбора файла, то в реквизит формы “СсылкаНаКартинку” помещаем адрес во временном хранилище, куда были помещены данные картинки.

Вуаля!
Добавление фотографий в 1С

Так, осталось теперь при записи элемента справочника записать данные из временного хранилища в реквизит элемента справочника. Описываем событие ПередЗаписьюНаСервере:
Процедура ПередЗаписьюНаСервере

Для увеличения нажмите на изображение.

Проверяем в реквизите формы у нас что? Если адрес временного хранилища, пишем данные в реквизит элемента справочника, обращаясь к “ТекущийОбъект”, “ТекущийОбъект” – это сконвертированные данные формы, которые пишутся в базу в этот момент времени.

Осталось описать открытие формы, для отображения картинки уже сохраненной в реквизите элемента справочника.
Процедура ПриСозданииНаСервере

Для увеличения нажмите на изображение.

Вот и все. Готовую базу можно взять тут.

Павел Чистов

PDF-версия статьи для участников группы ВКонтакте

Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.

Если Вы еще не вступили в группу – сделайте это сейчас и в блоке ниже (на этой странице) появятся ссылка на скачивание материалов.

Статья в PDF-формате

Статья в PDF-формате

Вы можете скачать эту статью в формате PDF по следующей ссылке: Курсы-по-1С.рф – Новое в редакции 8.3 – Работа с файлами (картинками) в интерфейсе Такси.pdf

Если Вы уже участник группы – нужно просто повторно авторизоваться в ВКонтакте, чтобы скрипт Вас узнал. В случае проблем решение стандартное: очистить кеш браузера или подписаться через другой браузер.

Комментарии / обсуждение (66):

  1. Сергей

    Добрый день, а можно пример
    Работа с файлами (картинками) в интерфейсе Такси
    только БЕЗ Хранилище значений, не надо сохранить в базе. Просто открыть с диска.

  2. Ivan

    Подскажыте плз а как зделать штоб к 1 товару из справочника номенклатура можна привязать несколько картинок товара не обезательно штоб оны отображались просто штоб были привязаны к одному товару. Вот пример кода который помещает одну картинку как из него зделать несколько картинок ?
    &НаКлиенте
    Процедура ПрикрепитьФайл(Команда)
    // ОбъектТекущий = РеквизитФормыВЗначение(“Объект”);
    Режим = РежимДиалогаВыбораФайла.Открытие;
    ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
    ДиалогОткрытияФайла.ПолноеИмяФайла = “”;
    ДиалогОткрытияФайла.Расширение = “”;
    ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
    // ДиалогОткрытияФайла.ВыбранныеФайлы = “”;
    ДиалогОткрытияФайла.Заголовок = “Выберите файлы”;
    Если ДиалогОткрытияФайла.Выбрать() Тогда
    ПутьКФайлу = ДиалогОткрытияФайла.ПолноеИмяФайла;
    // Получение двоичные данные файла
    //ПутьКФайлу = ДиалогОткрытияФайла.Расширение;

    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
    // Имя = Новый ДвоичныеДанные(ПутьКФайлу);
    //Разширение = Новый ДвоичныеДанные(ПутьКФайлу);
    // Передача двоичных данные на сервер
    ПрикрепитьФайлНаСервере(ДвоичныеДанные);
    Иначе
    Текст = “ru = “”Файл(ы) не выбран!””; en = “”File(s) not selected!”””;
    Предупреждение(НСтр(Текст));
    КонецЕсли;

    КонецПроцедуры
    &НаСервере
    Процедура ПрикрепитьФайлНаСервере(ДвоичныеДанные)
    // Трансформируем объект формы в справочник-объект
    ОбъектТекущий = РеквизитФормыВЗначение(“Объект”);
    // Присваиваем новое значение реквизиту “Данные”
    //РегистрыСведений.СопоставлениеДанных. = Новый ХранилищеЗначения(ДвоичныеДанные);
    ОбъектТекущий.Картинка = Новый ХранилищеЗначения(ДвоичныеДанные);
    //ОбъектТекущий.КартинкаИмя = Новый ХранилищеЗначения(Имя);
    //ОбъектТекущий.КартинкаРазширение = Новый ХранилищеЗначения(Разширение);
    //ОбъектТекущий.Данные = Новый ХранилищеЗначения(ДвоичныеДанные);
    //ОбъектТекущий.РегистрыСведений.СопоставлениеДанных.Данные = Новый ХранилищеЗначения(ДвоичныеДанные);
    // Сохраняем изменения
    ОбъектТекущий.Записать();

    // Данные = РегистрыСведений.СопоставлениеДанных.Данные;
    КонецПроцедуры

    • Василий Ханевич

      Добрый день!
      Например, можно создать для хранения картинок справочник, подчиненный справочнику Номенклатура. Каждый элемент такого справочника – это отдельная картинка. Получится, что для одного элемента справочника Номенклатура можно хранить несколько картинок.

      • Ivan

        А как ето зделать ? Какие елементы формы должны присутвовать ? Может ето и без етого справочника можно зделать ?

        • Василий Ханевич

          1. Создаем в конфигураторе новый справочник, подчиненный Номенклатуре (например, назовем его ПрисоединенныеКартинки). Добавляем для него реквизит ДанныеКартинки. Добавление картинки выполняем аналогично, как в статье, только работаем не со справочником Номенклатура, а с новым справочником ПрисоединенныеКартинки. Получится, что для одного элемента справочника Номенклатура можно создать несколько подчиненных элементов в справочнике ПрисоединенныеКартинки, в каждом из которых будет храниться своя картинка.
          2. Вместо справочника можно использовать, например, регистр сведений для хранения данных картинок.

          • Ivan

            Так еслы не сложно ищо такой вопрос. Внешный модуль который отправляет еты картинки работает с ДвоичныеДанные. Вот пример роботы.
            Данные = РегистрыСведений.СопоставлениеДанных.ПолучитьДанныеПоСсылке(Перечисления.Сущности.Image, Ссылка);
            Если Данные = Неопределено ИЛИ НЕ ЗначениеЗаполнено(Данные) Тогда
            Данные = ОтправитьКартинку(Ссылка);
            КонецЕсли;
            СтруктураДанных = Новый Структура;
            СтруктураДанных.Вставить(“src”,Данные);
            МассивКартинок = Новый Массив;
            МассивКартинок.Добавить(СтруктураДанных);
            Возврат МассивКартинок;
            КонецФункции

            Функция ОтправитьКартинку(Ссылка) Экспорт

            //ДвоичныеДанные = Новый ДвоичныеДанные(“R:\BMW.jpg”);

            //SDK_WC_API.ОтправитьКартинку(ДвоичныеДанные);

            ДвоичныеДанные = Ссылка.Картинка.Получить();

            Результат = SDK_WC_API.ОтправитьКартинку(ДвоичныеДанные, Ссылка.КартинкаИмя,Ссылка.КартинкаРазширение);
            Если Результат = Неопределено Тогда
            Возврат Неопределено;
            КонецЕсли;
            РегистрыСведений.СопоставлениеДанных.СопоставитьДанные(Перечисления.Сущности.Image, Ссылка, Результат[“id”],Результат[“source_url”]);
            //РегистрыСведений.СопоставлениеДанных.СопоставитьДанные(Перечисления.Сущности.Image, Ссылка, Результат[“id”]);

            Возврат Результат[“source_url”];

            КонецФункции

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

            &НаКлиенте
            Процедура СсылкаНаКартинкуНажатие(Элемент, СтандартнаяОбработка)
            СтандартнаяОбработка = Ложь;
            Режим = РежимДиалогаВыбораФайла.Открытие;
            ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
            ДиалогОткрытия.ПолноеИмяФайла = “”;
            Фильтр = “Файл Jpg (*.jpg)|*.jpg”;
            ДиалогОткрытия.Фильтр = Фильтр;
            ДиалогОткрытия.МножественныйВыбор = Ложь;
            ДиалогОткрытия.Заголовок = “Выберете файл для загрузки”;
            ОписаниеОповещения = Новый ОписаниеОповещения(“ПослеЗагрузкиФайла”,ЭтаФорма);
            ДиалогОткрытия.Показать(ОписаниеОповещения);

            КонецПроцедуры
            &НаКлиенте
            Процедура ПослеЗагрузкиФайла(ВыбранныйФайл,ДопПараметр) Экспорт
            Если ВыбранныйФайл = Неопределено Тогда
            Возврат;
            КонецЕсли;
            ОписаниеОповещения = Новый ОписаниеОповещения(“ПослеПомещенияФайла”, ЭтаФорма);
            НачатьПомещениеФайла(ОписаниеОповещения,, ВыбранныйФайл[0], Ложь, УникальныйИдентификатор);
            КонецПроцедуры
            &НаКлиенте
            Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла,ДопПараметры) Экспорт
            Если Не Результат Тогда
            Возврат;
            КонецЕсли;
            СсылкаНаКартинку = Адрес;
            Модифицированность = Истина;
            КонецПроцедуры

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

            &НаСервере
            Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка,Ссылка,ДвоичныеДанные)
            СсылкаНаКартинку = РегистрыСведений.СопоставлениеДанных.ПолучитьДанныеПоСсылке(Перечисления.Сущности.Image, Ссылка);
            ОбъектТекущий = РеквизитФормыВЗначение(“Объект”);
            ОбъектТекущий.Данные = Новый ХранилищеЗначения(ДвоичныеДанные);
            ОбъектТекущий.Записать();
            КонецПроцедуры

            • Василий Ханевич

              Добрый день!
              По описанию понял, что данные картинки номенклатуры нужно передать в функцию ОтправитьКартинку общего модуля SDK_WC_API. В таком случае можно разместить на форме кнопку, при нажатии на которую получать из хранилища значения данные (например, реквизит ДанныеКартинки имеет тип ХранилищеЗначения), передавать их в функцию:

              ДвоичныеДанные = Объект.ДанныеКартинки.Получить();
              Результат = SDK_WC_API.ОтправитьКартинку(ДвоичныеДанные);
              • Ivan

                Ну я так и делаю и еслы прикреплять одну картинку то все работает а как зделать штоб не одну картинку прикрепляло а несколько ?

                • Василий Ханевич

                  Я предлагал вариант с подчиненным номенклатуре справочником. Например, программно в цикле на каждый файл с картинкой создавать отдельный элемент справочника, прикреплять эту картинку к созданному элементу справочника. И для каждой картинки вызывать функцию общего модуля с отправкой.

              • Ivan

                У меня есть кнопка на форме номенклатуры и реквезит ХранилищеЗначения – Картинка.
                &НаСервере
                Процедура ПрикрепитьФайлНаСервере(ДвоичныеДанные)

                ОбъектТекущий = РеквизитФормыВЗначение(“Объект”);

                ОбъектТекущий.Картинка = Новый ХранилищеЗначения(ДвоичныеДанные);

                ОбъектТекущий.Записать();

                КонецПроцедуры

                • Василий Ханевич

                  Если нужно прикрепить одну картинку – можно делать, как описано в статье. Если нужно несколько картинок прикреплять, пробуем сделать через подчиненный справочник, как я предлагал выше. В нем храним картинки.

              • Ivan

                Я так понял мне надо типа зделать как в УТ но у меня нет такой конфигурации а та што есть она на простых формах и зделано оно через регистр свединей но код там громадный и штоб его переписать под управляяму форму ето много времени. Может у когото есть робота с файламы номенклатуры как УТ или вкурсе как оно работает.

                • Василий Ханевич

                  В УТ и других типовых конфигурациях на базе БСП будет реализовано слишком универсально и сложно для понимания. Поэтому для начала, особенно если конфигурация пишется с нуля, это будет избыточно.
                  Если есть готовый образец кода, который нужно повторить, наверное, проще будет его адаптировать. Если это код, который будет выполняться на сервере, без интерактивных действий пользователя, то доработки должны быть минимальны.

                  • Ivan

                    ДвоичныеДанные = Объект.ДанныеКартинки.Получить(); Результат = SDK_WC_API.ОтправитьКартинку(ДвоичныеДанные);
                    А еслы зделать ето справочник или регистр как мне тут тогда передать еты данные ? ДанныеКартинки ето реквезит с типом Хранилище Значение. А когда создать регист или справочник как потом еты данные передать сюда в ету функцию ?

                    • Василий Ханевич

                      Пример кода по созданию элементов справочника:

                      МассивКартинок = Новый Массив;
                      МассивКартинок.Добавить("c:\1.png");
                      МассивКартинок.Добавить("c:\2.png");
                      //...

                      Для каждого ТекКартинка Из МассивКартинок Цикл

                          ПрисоединенныйФайл = Справочники.ПрисоединенныеФайлы.СоздатьЭлемент();
                          ПрисоединенныйФайл.Наименование = "...";
                          ПрисоединенныйФайл.Владелец = Номенклатура;
                          ДД = Новый ДвоичныеДанные(ТекКартинка);
                          ПрисоединенныйФайл.ДанныеКартинки = Новый ХранилищеЗначения(ДД);
                          ПрисоединенныйФайл.Записать();
                         
                          //передаем картинки в Ваш метод
                          Результат = SDK_WC_API.ОтправитьКартинку(ДД);
                          //...

                      КонецЦикла;
  3. Дмитрий

    Подскажите, а как провернуть такую же операцию, но с регистром сведений?

    • Василий Ханевич

      Добрый день!
      В регистре сведений можно создать измерение Объект (тип – СправочникСсылка.Товары) и ресурс типа ХранилищеЗначения. В нем и будут храниться двоичные данные картинки.
      При выборе файла картинки можно записывать элемент справочника Товары и добавлять запись в регистр сведений.

      • Дмитрий

        Спасибо! И ещё вопрос.
        Как я могу загрузить целую папку изображений в РС? Чтоб не по одной штуке, а сразу все. Возможно ли это?

        • Василий Ханевич

          Для записи в регистр сведений можно использовать разные объекты встроенного языка. РегистрСведенийМенеджерЗаписи – для одиночной записи, РегистрСведенийНаборЗаписей – для сохранения группы записей. Для набора записей можно использовать отборы по значениям измерений (и по периоду, если регистр сведений периодический).

          • Дмитрий

            Василий, подскажите ещё.Как мне во внешней обработке отобразить на форме картинки, пути на которые у меня находятся в регистре сведений?

            • Василий Ханевич

              Подход будет аналогичный – создаем в форме обработки строковый реквизит АдресКартинки, располагаем его на форме. Помещаем картинку с диска во временное хранилище, заполняем реквизит АдресКартинки.
              Пример кода:

              &НаКлиенте
              Процедура ПриОткрытии(Отказ)
                 
                  Оповещение = Новый ОписаниеОповещения("ОткрытьКартинкуЗавершение", ЭтотОбъект);
                  НачатьПомещениеФайла(Оповещение, , ПолучитьПутьКФайлуКартинки(), Ложь, УникальныйИдентификатор);
                 
              КонецПроцедуры

              &НаКлиенте
              Процедура ОткрытьКартинкуЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
                 
                  Если НЕ Результат Тогда
                      Возврат;
                  КонецЕсли;
                 
                  АдресКартинки = Адрес;
                 
              КонецПроцедуры

              &НаСервереБезКонтекста
              Функция ПолучитьПутьКФайлуКартинки()
                 
                  Результат = "";

                  Запрос = Новый Запрос;
                  Запрос.Текст =
                      "ВЫБРАТЬ ПЕРВЫЕ 1
                      |   Рег.ПутьКФайлуКартинки КАК ПутьКФайлуКартинки
                      |ИЗ
                      |   РегистрСведений.КартинкиНоменклатуры КАК Рег";
                 
                  Выборка = Запрос.Выполнить().Выбрать();
                 
                  Если Выборка.Следующий() Тогда
                      Результат = Выборка.ПутьКФайлуКартинки;
                  КонецЕсли;
                 
                  Возврат Результат;

              КонецФункции
              • Дмитрий

                В таком случае он открывает только последний файл.А как его останавливать на каждом файле и просматривать по-одному?

                • Дмитрий

                  При этом изменять булевское значение в отдельной колонке “Качество”РС, в зависимости от нажатой кнопки “Одобрить” или “Забраковать”.

                  • Дмитрий

                    У меня в РС есть реквизит “Качество” булевый. На форме я отображаю картинку и есть 2 кнопки “Одобрить” и “Забраковать”. Я во внешней обработке пускаю цикл, который пробегает все фотографии из РС. Как мне останавливать его на на каждой фотографии и совершать этот выбор по качеству?Спасибо!

                    • Василий Ханевич

                      Можно на форме создать таблицу значений (или список значений). Заполнить таблицу значений всеми путями к картинкам, которые требуется обработать. По нажатию на кнопку Следующая картинка переходить к следующей строке таблицы значений, отображать на форме очередную картинку. При нажатии на кнопку Одобрить производить запись в регистр сведений. Поскольку мы знаем, с какой картинкой в данный момент работаем, можем корректно определить, какую именно запись в регистре требуется изменять.

                • Василий Ханевич

                  Создать кнопку на форме. При нажатии на неё из базы выбирается путь к файлу, который требуется отобразить в данный момент (для этого может потребоваться, например, модифицировать запрос в приведенном образце программного кода), картинка из этого файла отображается на форме.

                  • Дмитрий

                    Можете приложить вариант кода?Не до конца понимаю как это реализовать.

                    • Василий Ханевич

                      Нет, готовое решение подготовить не смогу, только ответить на Ваши вопросы по теме.
                      Поэтому разделите задачу на подзадачи, распишите себе по пунктам, что и в какой последовательности будете делать.
                      1. Создать таблицу значений на форме, заполнить её всеми путями к картинкам, которые нужно показать.
                      2. Добавить команды Предыдущая картинка и Следующая картинка. Создать вспомогательный реквизит формы, где будете хранить текущую выводимую строку таблицы значений (чтобы далее было понятно, что именно записывать в базу). При нажатии на кнопки переходим к предыдущей или следующей строке таблицы.
                      3. Добавить команду формы Одобрить. При нажатии на кнопку производить запись в базу.
                      Примерно такая последовательность шагов.

  4. AlexeyNV

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

    не работает, поскажите что не так плз

    • Василий Ханевич

      Добрый день!
      Для очистки хранилища значения можно использовать код:

      ТекущийОбъект.ДанныеКартинки = Неопределено;
    • Василий Ханевич

      Добрый день!
      Сейчас проверил – файл сохраняется. Проверьте, что в Вашем программном коде реализован обработчик события формы ПередЗаписьюНаСервере.
      Также можно скачать выгрузку базы, сравнить со своим кодом.

  5. Макс

    Подскажите как быть. Если нужно чтобы сохранялся в базе просто путь к файлу на диске, а не весь файл(картинка). Чтобы база 1с не росла.

    • Василий Ханевич

      Добрый день!
      В таком случае можно в справочнике создать строковый реквизит ИмяФайлаКартинки. И при открытии формы помещать во временное хранилище двоичные данные картинки с диска:

      АдресКартинки = ПоместитьВоВременноеХранилище(Новый Картинка(Объект.ИмяФайлаКартинки));

      Для загрузки файла с диска можно использовать следующий код:

      &НаКлиенте
      Процедура ЗагрузитьКартинку(Команда)
         
          Оповещение = Новый ОписаниеОповещения("ЗагрузитьКартинкуЗавершение", ЭтотОбъект);
          НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
         
      КонецПроцедуры

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

      В этом коде отображается диалог выбора файла с картинкой, выбранное пользователем изображение помещается во временное хранилище. Поскольку необходимо сохранить в базе расположение файла картинки, в реквизит объекта ПутьКФайлуКартинки записываем путь к выбранному файлу.

      При открытии формы можно также воспользоваться методом глобального контекста НачатьПомещениеФайла, который поместит файл с диска во временное хранилище для отображения на форме:

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

      &НаКлиенте
      Процедура ОткрытьКартинкуЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
         
          Если НЕ Результат Тогда
              Возврат;
          КонецЕсли;
         
          АдресКартинки = Адрес;
         
      КонецПроцедуры
  6. howard_od

    Подскажите, ка быть с pdf файлами. Тип “поле картинка” не подходит. Как и html. Pdf очень востребован для отображения, например, договора с контрагентами.

    • Василий Ханевич

      Добрый день!
      Отобразить PDF-документ на форме не получится.
      Можно сохранить PDF-документ в файл на диске, затем открыть его приложением, которое установлено в системе как приложение по умолчанию для PDF-файлов:

      ЗапуститьПриложение(ИмяВременногоФайла);
    • Василий Ханевич

      Добрый день!
      Например, при помощи внедрения в HTML картинки, закодированной в base64:

      <img src="data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7" width="16" height="14" alt="внедренная картинка"/>

      Т.е. происходит внедрение картинки при помощи data:URI, что позволяет вставить код картинок прямо в HTML-страницу без обращений к внешним файлам.

  7. Бестужев Сергей

    А как быть если картинка (ХранилищеДанных) это ресурс регистра сведений, а его измерение это ссылка на объект которому принадлежит эта картинка? Например так в Бухгалтерия 3.0 Регистр ХранимыеФайлыВерсий, а “владельцем” картинки является элемент справочника ВерсииФайлов?

    • Сергей Калинкин

      Добрый день!

      Если картинка хранится в регистре сведений, тогда код необходимо модернизировать следующим образом:

      &НаСервере
      Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
         
          ЗначениеКлюча = Новый Структура;
          ЗначениеКлюча.Вставить("ИмяИзмерения", Ссылка);
          КлючЗаписи = РегистрыСведений.ИмяРегистраСведений.СоздатьКлючЗаписи(ЗначениеКлюча);
         
          СсылкаНаКартинку = ПолучитьНавигационнуюСсылку(КлючЗаписи, "ИмяРесурса");       
         
      КонецПроцедуры

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

    Хорошая статья. Но у меня один вопрос. Я также добавил кнопку “Открыть картинку” при нажатии которой открывается картинка, но в отдельной форме. Вопрос: подскажите способ, как проверить была ли помещена картинка в хранилище, если нет то скрыть кнопку “Открыть картинку”. Заранее спасибо

    • GROOVY

      Так в статье же есть проверка на временное хранилище Если ЭтоАдресВременногоХранилища() Тогда Элементы.Кнопка.Видимость = Ложь

  9. Олег

    Павел, подскажите, а данный способ будет работать для документов, а не справочников?
    Спасибо!

  10. Денис

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

    • GROOVY

      Не указали идентификатор формы при помещении файла в ВХ. ВХ было уничтодено при клиент-серверном вызове.

        • Василий Ханевич

          В методе НачатьПомещениеФайла:

          НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
          • поля

            Все прописано, но не работает, в режиме предприятия картинка загружается и записывается, но при открытии этого объекта картинки нет

            • Василий Ханевич

              Проверьте в таком случае, что процедура ПриСозданииНаСервере отрабатывает (можно в отладке проверить, происходит ли в ней остановка на точке). Возможно, в модуле сама процедура есть, но она не назначена в свойствах формы как обработчик события.
              Также к статье приложен файл с выгрузкой базы. На ней работает корректно? Сравните со своими доработками. Можно использовать Сравнить, объединить с конфигурацией из файла.

  11. silv

    Павел спасибо Вам за статью, у меня выдает ошибку “Переменная не определена (ЭтотОбъект)” подскажите пожалуйста где моя ошибка.

  12. Igorok

    Павел, подскажите, как узнать (чтобы не ошибиться) список необходимых параметров для процедуры примера “ОбработатьВыборФайла” ?

    • GROOVY

      В синтаксис-помощнике подробно указаны параметры процедур которые необходимо описать в обработчике оповещения. Ищите метод НачатьПомещениеФайла.

  13. Ivan

    Классная стать! Подскажите как сохранить эту картинку обратно в файловую систему?

  14. Павел

    Спасибо за статью, Подскажите как вывести произвольную картинку в форме списка?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Вход на сайт

Зарегистрироваться

Подтверждение регистрации будет отправлено на указанный e-mail.

Я подтверждаю, что ознакомлен(а) с Пользовательским соглашением, принимаю его условия и даю свое согласие на обработку моих персональных данных.

Восстановить доступ

E-mail или логин

Ссылка на создание нового пароля будет отправлена на указанный e-mail.