|   |   | 
| 
 | Сохранение PDF-файла из сторонней SQL базы. | ☑ | ||
|---|---|---|---|---|
| 0
    
        sergejkonet 03.02.14✎ 09:57 | 
        Добрый день!
 Нужно реализовать сохранение или открытие pdf-файлов из сторонней sql-базы. в sql хранится одна таблица с двумя параметрами: номер и само изображение(бинарник), К базе подключается, запись нужную находит, а вот открыть не получается. Выдает ошибку "Неправильный путь к файлу '25 50 44 46 2D 31 2E....." и дальше содержание бинарника. Я так пониманию нужно указать в ОписанииПердаваемогоФайла, другие параметры. Но какие что-то не пойму. Пробовал ссылку на ВнешниеИсточникиДанных, не проходит. Да. при нажатии кнопки запускающей процедуру, предлагает сохранить или открыть, при сохранении выдает ошибку, но в папке qw появляется файл pdf 0байт..Прошу подсказать с решением данной проблемы. Процедура VievНажатие(Элемент) НомерЧертежа = СокрЛП(ЭлементыФормы.СправочникСписок.ТекущаяСтрока.Код); Параметры = ВнешниеИсточникиДанных.Чертежи.ПолучитьОбщиеПараметрыСоединения(); Параметры.АутентификацияСтандартная = Истина; Параметры.ИмяПользователя = "sa"; Параметры.Пароль = "1"; Параметры.СтрокаСоединения = "DRIVER={SQL Server};SERVER=(local);UID=sa;PWD=1;DATABASE=Fotos"; Параметры.СУБД = "MSSQLServer"; ВнешниеИсточникиДанных.Чертежи.УстановитьОбщиеПараметрыСоединения(Параметры); ВнешниеИсточникиДанных.Чертежи.УстановитьПараметрыСоединенияПользователя(ИмяПользователя(), Параметры); ВнешниеИсточникиДанных.Чертежи.УстановитьПараметрыСоединенияСеанса(Параметры); ВнешниеИсточникиДанных.Чертежи.УстановитьСоединение(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | dbo_Chertezhi.image |ИЗ | ВнешнийИсточникДанных.Чертежи.Таблица.dbo_Chertezhi КАК dbo_Chertezhi ГДЕ dbo_Chertezhi.number = &НомерЧертежа" ; Запрос.УстановитьПараметр("НомерЧертежа",НомерЧертежа); Рез=Запрос.Выполнить().Выбрать(); Если Рез.Следующий() Тогда ПолучаемыйФайл = Новый ОписаниеПередаваемогоФайла("D:\qw\" + "scan.pdf", Рез.image); ПолучаемыеФайлы = Новый Массив; ПолучаемыеФайлы.Добавить(ПолучаемыйФайл); ПолученныеФайлы = Новый Массив; ПолучитьФайлы(ПолучаемыеФайлы, ПолученныеФайлы) ; КонецЕсли; КонецПроцедуры | |||
| 1
    
        sapphire 03.02.14✎ 10:00 | 
        видимо, надо через ADO DB Stream :)     | |||
| 2
    
        sergejkonet 03.02.14✎ 10:02 | 
        Так. пойду гуглить. Но если не затруднит, можно немного подробнее описать что к чему.     | |||
| 3
    
        sapphire 03.02.14✎ 10:06 | 
        (2) Че там описывать - открываешь поток, сохраняешь в файл.     | |||
| 4
    
        golden-pack 03.02.14✎ 10:07 | 
        StreamOut = Новый COMОбъект("ADODB.Stream");
 StreamOut.Type = 1; StreamOut.Mode = 3; //Нужны и чтение и запись. StreamOut.Open(); //Открыли на чтение и запись StreamOut.Write(COMSafeArray); StreamOut.SaveToFile(ИмяВременногоФайла, 2); StreamOut.Close(); | |||
| 5
    
        sergejkonet 03.02.14✎ 13:27 | 
        Что-то я торможу. не могу никак разобраться что куда. Пытался вставить поток но при выполнении вылетает ошибка 
 "Ошибка при вызове метода контекста (Write) Stream.Write(p); по причине: Произошла исключительная ситуация (ADODB.Stream): Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом." Может есть у кого-то рабочие примеры, что бы можно было разбираться по аналогии, что куда, или здесь ткните пальцем. А то в инете в основном обще примеры, и внять им не получается:( Процедура VievНажатие(Элемент) НомерЧертежа = СокрЛП(ЭлементыФормы.СправочникСписок.ТекущаяСтрока.Код); Параметры = ВнешниеИсточникиДанных.Чертежи.ПолучитьОбщиеПараметрыСоединения(); Параметры.АутентификацияСтандартная = Истина; Параметры.ИмяПользователя = "sa"; Параметры.Пароль = "1"; Параметры.СтрокаСоединения = "DRIVER={SQL Server};SERVER=(local);UID=sa;PWD=1;DATABASE=Fotos"; Параметры.СУБД = "MSSQLServer"; ВнешниеИсточникиДанных.Чертежи.УстановитьОбщиеПараметрыСоединения(Параметры); ВнешниеИсточникиДанных.Чертежи.УстановитьПараметрыСоединенияПользователя(ИмяПользователя(), Параметры); ВнешниеИсточникиДанных.Чертежи.УстановитьПараметрыСоединенияСеанса(Параметры); ВнешниеИсточникиДанных.Чертежи.УстановитьСоединение(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | dbo_Chertezhi.image |ИЗ | ВнешнийИсточникДанных.Чертежи.Таблица.dbo_Chertezhi КАК dbo_Chertezhi ГДЕ dbo_Chertezhi.number = &НомерЧертежа" ; Запрос.УстановитьПараметр("НомерЧертежа",НомерЧертежа); Рез=Запрос.Выполнить().Выбрать(); Stream=Новый COMОбъект("ADODB.Stream"); Stream.Mode=3; Stream.Type=1; Stream.Open(); p=image; Stream.Write(p); ИмяРисунка="pic"+НомерЧертежа+".pdf"; Stream.SaveToFile(КаталогВременныхФайлов()+ИмяРисунка,2); Stream.Close(); ВрХран=ПоместитьВоВременноеХранилище(Stream); Если Рез.Следующий() Тогда ПолучаемыйФайл = Новый ОписаниеПередаваемогоФайла("D:\qw\" + "scan.pdf", ВрХран ); ПолучаемыеФайлы = Новый Массив; ПолучаемыеФайлы.Добавить(ПолучаемыйФайл); ПолученныеФайлы = Новый Массив; ПолучитьФайлы(ПолучаемыеФайлы, ПолученныеФайлы) ; КонецЕсли; КонецПроцедуры | |||
| 6
    
        sergejkonet 04.02.14✎ 08:20 | 
        Вот что получилось в новом запросе: 
 Процедура VievНажатие(Элемент) НомерЧертежа = СокрЛП(ЭлементыФормы.СправочникСписок.ТекущаяСтрока.Код); стрПодключения = "Data Source=MICROSOF-B31904;Initial Catalog=Fotos; Persist Security Info=True;User ID=sa; Password=1"; Connection = Новый COMОбъект("ADODB.Connection"); Connection.Provider = "SQL Server Native Client 10.0"; Connection.ConnectionString = стрПодключения; Попытка Connection.Open(); Сообщить ("Соединение установлено" ); Исключение Сообщить ("Проблемы с подключением к InterBase" ); Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; Stream = Новый COMОбъект("ADODB.Stream"); Stream.Type = 1; Stream.Open(); RecordSet = Новый COMОбъект("ADODB.RecordSet"); RecordSet.CursorLocation = 3; RecordSet.LockType = 2; Запрос = "SELECT image FROM dbo.Chertezhi WHERE number = НомерЧертежа"; RecordSet.Open(Запрос,Connection); RecordSet.MoveFirst(); Stream.Write(RecordSet.Fields("image").Value); ИмяФайла = RecordSet.Fields("number").Name; фрис = КаталогВременныхФайлов() + ИмяФайла + ".pdf"; Stream.SaveToFile(фрис); ЗапуститьПриложение(фрис); Stream.Close(); RecordSet.Close(); Файл = Новый ДвоичныеДанные(фрис); УдалитьФайлы(фрис); Connection.Close(); КонецПроцедцры Но здесь новая проблема. Как обяснить SQL что переменная НомерЧертежа, заданная первой строкой и Значение НомерЧертежа в самом запросе, есть одно и то же. 1С при отладке это понимает, присваиет нужное значение, но вот SQL выдает ошибку: Ошибка при вызове метода контекста (Open) RecordSet.Open(Запрос,Connection); по причине: Произошла исключительная ситуация (Microsoft SQL Server Native Client 10.0): Недопустимое имя столбца "НомерЧертежа". Но здесь и в самом запросе очевидно какой-то косяк, т.к. когда подставлял в запрос значение номера, существующего в базе он ругался что не может найти такую запись в таблице. | |||
| 7
    
        shuhard 04.02.14✎ 08:29 | 
        (6)[SELECT image FROM dbo.Chertezhi WHERE number = НомерЧертежа]
 феерично | |||
| 8
    
        sergejkonet 04.02.14✎ 08:36 | 
        (7) О да(((Я просто реально впервые с 1С сталкиваюсь, поэтому извините за такие тупые ошибки и если можно подскажите как поправить.     | |||
| 9
    
        sergejkonet 04.02.14✎ 10:38 | 
        Так-с. докопался. Вот этот код робит. 
 Процедура VievНажатие(Элемент) НомерЧертежа = СокрЛП(ЭлементыФормы.СправочникСписок.ТекущаяСтрока.Код); стрПодключения = "Data Source=MICROSOF-B31904;Initial Catalog=Fotos; Persist Security Info=True;User ID=sa; Password=1"; Connection = Новый COMОбъект("ADODB.Connection"); Connection.Provider = "SQL Server Native Client 10.0"; Connection.ConnectionString = стрПодключения; Попытка Connection.Open(); Сообщить ("Соединение установлено" ); Исключение Сообщить ("Проблемы с подключением к InterBase" ); Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; Stream = Новый COMОбъект("ADODB.Stream"); Stream.Type = 1; Stream.Open(); RecordSet = Новый COMОбъект("ADODB.RecordSet"); RecordSet.CursorLocation = 3; RecordSet.LockType = 2; Запрос = "SELECT [image] FROM [Fotos].[dbo].[Chertezhi] WHERE [number] = '" + НомерЧертежа + "'"; RecordSet.Open(Запрос,Connection); RecordSet.MoveFirst(); Stream.Write(RecordSet.Fields("image").Value); ИмяФайла = НомерЧертежа; фрис = КаталогВременныхФайлов() + ИмяФайла + ".pdf"; Stream.SaveToFile(фрис); ЗапуститьПриложение(фрис); Stream.Close(); RecordSet.Close(); Файл = Новый ДвоичныеДанные(фрис); УдалитьФайлы(фрис); Connection.Close(); Если исполнять весь код, то открывается пустой пдф-ридер, если же удалить последние 3 строчки, то открывается с изображением. все как надо. все открывается,но как удалять из временной папки после закрытий пдф-ридера? Есть какие-то идеи может? | |||
| 10
    
        sergejkonet 04.02.14✎ 11:02 | 
        Было бы допустимо просто при совпадении имен перезаписывать файл, т.к. все файлы будут во временной папке, а компы выключаются каждый день, то пользователи немного места отхватят, я так понимаю здесь нужно указать параметр какой-то. но где и какой?     | |||
| 11
    
        sergejkonet 04.02.14✎ 11:59 | 
        Решилась проблема введением параметра adSaveCreateOverWrite, но правда перед этим пришлось присвоить ему значение 2. 
 adSaveCreateOverWrite = 2; Stream.SaveToFile(фрис, adSaveCreateOverWrite); Не знаю правда насколько это правильное решение, но вроде как все работает. Прошу проконсультировать по степени кривости такого подхода. | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |