четверг, 31 января 2019 г.

Чтение/запись картинкок из 1С в MSSQL через ADO

Описание работы в УФ 1С 8.3.13 с картинками в MSSQL через ADO
1. Картинки пишем/читаем в MS SQL
2. user interface = 1C


Порядок настройки
1. Создать database в mssql,
2. таблица images: id(bigint, not null, identify), image (image), name (nvarchar 150), size (int)
3. хранимая процедура insert
4. на форме 1с поле ввода с типом Картинка, связанное с реквизитом строка
5. ado stream сохраняет в файл при чтении из SQL. Существенно быстрее, чем через память.
6. Процедуры ниже:

&НаКлиенте
Процедура b2b_КартинкаНажатие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ЗаблокироватьДанныеФормыДляРедактирования();

Если НЕ ЗначениеЗаполнено(Объект.Ссылка) Тогда
ТекстВопроса = НСтр("ru='Для выбора изображения необходимо записать объект. Записать?'");
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
Записать();
Иначе
Возврат
КонецЕсли;

КонецЕсли;

//СоединениеСБазой = MSSQL_CreateConnection();
////Картинка = Новый Картинка("D:\550\duomed.png");
//SetImage(Строка(Объект.Ссылка.УникальныйИдентификатор()), "duomed.png", "D:\550\duomed.png");

ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ВыборФайла.ПолноеИмяФайла = "";
Фильтр = НСтр("ru = 'Текст'; en = 'Text'") + "Формат PNG(*.png*)|*.png|Формат JPEG(*.jpeg;*.jpg)|*.jpeg;*.jpg|Все файлы(*.*)|*.*";
ВыборФайла.Фильтр = Фильтр;
ВыборФайла.МножественныйВыбор = Ложь;
ВыборФайла.Заголовок = "Выберите файлы";
Если ВыборФайла.Выбрать() Тогда
Файл = Новый Файл(ВыборФайла.ПолноеИмяФайла);
СоединениеСБазой = MSSQL_CreateConnection();
SetImage(Строка(Объект.Ссылка.УникальныйИдентификатор()), Файл.Имя, ВыборФайла.ПолноеИмяФайла);
Сообщить("Файл записан: " + ВыборФайла.ПолноеИмяФайла);
Иначе
//Предупреждение("Файл не найден!");
КонецЕсли;


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

&НаКлиенте
Функция MSSQL_CreateConnection()
Попытка
    ADOСоединение = Новый ComОбъект("ADODB.Connection");
    СтрокаСоединения =  "Provider=SQLOLEDB.1;
|Persist Security Info=False;
    |User ID=image;
    |Pwd=TZSGn5ZTZSGn5Z;
    |Data Source=fsb;
    |Initial Catalog=1C.Gate";
    ADOСоединение.Open(СтрокаСоединения);
    Возврат ADOСоединение;
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции

&НаКлиенте
Функция MSSQL_CloseConnection(Подключение)
Подключение.Close();
КонецФункции


&НаКлиенте
Функция SetImage(Source, Description, FileName)
Connection = MSSQL_CreateConnection();
Command = Новый COMОбъект("ADODB.Command");
Command.CommandTimeout = 100;
Command.ActiveConnection = Connection;
Command.CommandText = "insertImage";
Command.CommandType = 4;

Парам = Новый COMОбъект("ADODB.Parameter");
Парам.Name = "@description";
Парам.Direction = 1; //1 - adParamInput
Парам.Type = 201; //
Парам.Size = СтрДлина(Description);                 
Парам.Value = Description;
Command.Parameters.Append(Парам);

Парам = Новый COMОбъект("ADODB.Parameter");
Парам.Name = "@source";
Парам.Direction = 1; //1 - adParamInput
Парам.Type = 201; //
Парам.Size = СтрДлина(Source);                 
Парам.Value = Source;
Command.Parameters.Append(Парам);

Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1; //StreamTypeEnum.adTypeBinary = 1  StreamTypeEnum.adTypeText = 2
Поток.Open();
Поток.LoadFromFile(FileName);
локПотокБайт = Новый ComSafeArray(Поток.Read());

Парам = Новый COMОбъект("ADODB.Parameter");
Парам.Name = "@image";
Парам.Direction = 1; //1 - adParamInput
Парам.Type = 205; //205 - adLongVarBinary
Парам.Size = локПотокБайт.GetLength();
Парам.Value = локПотокБайт;
Command.Parameters.Append(Парам);

// размер картинки
Парам = Новый COMОбъект("ADODB.Parameter");
Парам.Name = "@size";
Парам.Direction = 1; //1 - adParamInput
Парам.Type = 3; //
//Парам.Size = СтрДлина(Size);                 
Парам.Value = локПотокБайт.GetLength();
Command.Parameters.Append(Парам);

Command.Execute();
MSSQL_CloseConnection(Connection);
КонецФункции

&НаКлиенте
Функция GetImage(FileName)
Connection = MSSQL_CreateConnection();
Попытка
НаборЗаписей = Новый COMОбъект("ADODB.Recordset");
НаборЗаписей.Open("select image, description from Images where id='" + FileName + "'", Connection);
Пока (НаборЗаписей.EOF = 0) Цикл
Изображение = НаборЗаписей.Fields("image").Value;
ПолноеИмяФайла = НаборЗаписей.Fields("description").Value;
//Возврат ConvertFromStream(Изображение.Выгрузить());
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1;
Поток.Open();
Поток.Write(Изображение);
ПолноеИмяФайла = "D:\" + ПолноеИмяФайла;
Файл = Новый Файл(ПолноеИмяФайла);
Если Не Файл.Существует() Тогда
Поток.SaveToFile(ПолноеИмяФайла);
КонецЕсли;
НаборЗаписей.MoveNext();
КонецЦикла;
Попытка
Возврат ПолноеИмяФайла;
//Данные = Новый ДвоичныеДанные(ПолноеИмяФайла);
//Возврат Данные;
Исключение
Возврат Неопределено;
КонецПопытки;
Исключение
#Если Клиент Тогда
Сообщить("Не удалось загрузить файл из хранилища через ADO соединение", СтатусСообщения.Важное);
#КонецЕсли
Возврат Неопределено;
КонецПопытки;
MSSQL_CloseConnection(Connection);
КонецФункции

&НаКлиенте
Процедура СтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)
Если ТекущаяСтраница.Имя = "b2b_Страница" Тогда
Картинка = Новый Картинка(GetImage(1));
Адрес = ПоместитьВоВременноеХранилище(Картинка);
b2b_Картинка = Адрес;
КонецЕсли;
КонецПроцедуры

Функция ConvertFromStream(Buffer)
Длина = Buffer.Количество();
Буфер = новый БуферДвоичныхДанных(Длина);
Для индекс = 0 по Длина - 1 Цикл
Буфер.Установить(индекс,Buffer[индекс]);
КонецЦикла;

Поток = новый ПотокВПамяти(Буфер);
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();

Возврат ДвоичныеДанные;
КонецФункции


Источники:
https://mudritskiy.blogspot.com/2013/05/1-adodb.html
https://victorz.ru/20170924638
https://infostart.ru/public/944348/
https://infostart.ru/public/74821/
https://infostart.ru/public/90126/
http://www.cyberforum.ru/sql-server/thread1023641.html

Комментариев нет:

Отправить комментарий