| 
    
            
         
         | 
    
  | 
Сохранение 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); Не знаю правда насколько это правильное решение, но вроде как все работает. Прошу проконсультировать по степени кривости такого подхода.  | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |