(odbc) Импорт Изображений Из Access

  • Автор темы admigator
  • Дата начала
A

admigator

Добрый день, Гуру!
Подскажите плз. как импортировать изображение из Access.
Подключение получилось. Текстовые данные импортирует нормально.
А вот изображение - ?
Смотрел YTRIA в поле пару крокозябок и все.
Google говорит что надо как-то файлы сперва сохранить на диск а потом - импорт.
Но база большая, долго будет.
Может кто решал вопрос. Подскажите плз.
Спасибо.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
542
Посмотри тут: link removed
Немного похоже.
P.S. Данным не занимался, но ADO должно работать, надо просто найти.
 
A

Anatoly

LS кнопки для получения фото из MS SQL через ADO (вывод в файл), - может поможет... :)
Код:
Sub Click(Source As Button)
Dim uiDoc As NotesUIDocument
Dim Conn As Variant, ADOCmd As Variant	, RecordSet As Variant, ADOStream As Variant, ADOField As Variant
Dim RecordsCnt As Long, intLoop As Long, FileLength As Long, NumBlocks As Long, LeftOver As Long
Dim strSQL As String, FileName As String
Dim ndSQLProfile As NotesDocument
Dim SQLUserID As String, SQLUserPass As String
Dim SQLSource As String, SQLDatebase As String

Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
Const Blocksize = 4096

Set wks =New NotesUIWorkspace	
Set Sess =New NotesSession

Set ndSQLProfile =sess.Currentdatabase.getProfileDocument("pf.Access.SQL")
SQLSource =ndSQLProfile.SourceName(0)
SQLUserID =ndSQLProfile.SQLLogin(0)
SQLUserPass =ndSQLProfile.SQLPassword(0)

Set uiDoc =wks.CurrentDocument	
Set CurDoc =uiDoc.Document
'	Call CurDoc.Save( False, False)

Set Conn = CreateObject( "ADODB.Connection" )	
Conn.Provider = "SQLOLEDB"
'	Conn.Open "Provider=SQLOLEDB; Integrated Security=SSPI; Persist Security Info=False; Initial Catalog=Images; Data Source=DARUMA\SQLEXPRESS;User ID=sa;Password=sa;"
Conn.Open "User ID=" + SQLUserID + "; Password=" + SQLUserPass +";Initial Catalog=Images; Data Source=" + SQLSource +";Persist Security Info=true;"

If Conn.State = 0 Then
Messagebox "Невозможно подключиться к серверу " & SQLSource & "!"
Exit Sub
End If

Set RecordSet = CreateObject( "ADODB.Recordset" )
strSQL =	"SELECT format, Image, Date FROM Images.dbo.Images WHERE type=4 and adrno=" & CurDoc.UnitCode(0)
RecordSet.Open strSQL, Conn

If RecordSet.State = 0 Then
Print "RecordSet.State = 0"
Goto l_finish
End If

If Not( ( RecordSet.BOF <> True ) Or ( RecordSet.EOF <> True ) ) Then
Goto l_finish
End If

'	RecordSet.Close	
'	strSQL =	"SELECT Image FROM Images.dbo.Images WHERE AdrNo=" & CurDoc.UnitCode(0)
'	RecordSet.Open strSQL, Conn

Set ADOStream = CreateObject( "ADODB.Stream" )
ADOStream.Type = adTypeBinary

RecordSet.MoveFirst

Do
RecordsCnt = RecordsCnt + 1			

Call ADOStream.Open		
Set ADOField = RecordSet.Fields( "Image" )

FileLength = ADOField.ActualSize
NumBlocks = FileLength \ BlockSize
LeftOver = FileLength Mod BlockSize

If LeftOver <> 0 Then
ADOStream.Write ADOField.getchunk( LeftOver )
End If

For intLoop = 1 To NumBlocks
ADOStream.Write ADOField.getchunk( BlockSize )
Next

'		Call ADOStream.SaveToFile( "C:\Work\AU" + Cstr( RecordSet( "AdrNo" ).value ) + ".jpg", adSaveCreateOverWrite )
FileName = "C:\Work\РК" & CurDoc.UnitCode(0) & ".jpg"
Call ADOStream.SaveToFile( FileName, adSaveCreateOverWrite )
Call ADOStream.Close

RecordSet.MoveNext
Loop	While RecordSet.EOF = False		 

l_finish:

RecordSet.Close	
Conn.Close
CurDoc.FileName =FileName
Call uiDoc.RefreshHideFormulas
'	Call AttachFile( "AUPhoto", FileName)
'	Dim r As Variant
'	r = Shell (FileName,1)
Exit Sub


onerr:
'	Call LogErrorEx( Cstr( Getthreadinfo(1) ), 1, Nothing )
Resume rez
rez:		
End Sub
 
A

admigator

В базе Access таблица Pharmacy с полем Duty в котором картинка.
Код для сохранения на диск одной записи из таблицы отрабатывает без ошибок. Все ок.
Только после этого файл не открывается. Исходный размер картинки до загрузки в Access - 227 559 байт,
а после импорта обратно на диск - 228 018 байт. 459 байт откуда-то лишних вылезают. В итоге картинка не открывается.
Такая странность, и колбасы нету на выходе.
Нашел похожее обсуждение
но ответа и там нету.
Код импорта на диск из Access
Код:
	Dim cn As Variant
Dim rs As Variant
Dim mstream As Variant
Dim field As Variant
Dim FileLength As Variant
Dim NumBlocks As Variant
Dim leftover As Variant
Dim strVer As String

'VB Constants
Const adOpenKeyset = 1
Const adLockOptimistic = 3
Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
Const adBlocksize = 4096

'Connect to the serve server
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Set mstream = CreateObject("ADODB.Stream")
Call cn.Open(|Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Pharmacy.mdb;Persist Security Info=False|)

Call rs.Open("Select * from Pharmacy", cn, adOpenKeyset, adLockOptimistic)

rs.movefirst 'if you need to process multiple records, you will need to put in a looping mechanism here

Set field = rs.fields("Duty")
FileLength = Field.ActualSize
NumBlocks = FileLength\adBlockSize

LeftOver = FileLength Mod adBlockSize


mstream.Type = adTypeBinary
Call mstream.Open

mstream.Write field.getchunk(leftover) 'This gathers the remainder portion of the stream first, you could do it last if you want

'Now loop through the majority of the stream
For intLoop = 1 To NumBlocks
mstream.Write field.getchunk(adBlockSize)
Next

Call mstream.SaveToFile("C:\hokol.jpg", adSaveCreateOverWrite) 'again. if you are dealing with multiple records with different blobs, you will need to adjust the output filename with each loop.

Call ADOStream.Close

Call rs.Close
Call cn.Close
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
542
Может пустые байты? А если так:
Код:
'Now loop through the majority of the stream
Dim buf as variant
For intLoop = 1 To NumBlocks
buf = field.GetChunk(adBlocksize)
If Not IsNull( buf ) Then mstream.Write buf
Next
И еще, есть вариант выгрузить картинку вручную из Access (не кодом) посмотреть какой размер? Может особенность сжатия.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
472
пройдитесь дифом по файлам
тогда будет ясно что лишнее
 
A

admigator

Прошелся. Вот результат.
Начало файла -
Конец файла -
При импорте из Access еще добавляются доп. данные в начало и конец картинки.
Если их удалить (в начале) то файл открывается!! Ура!!
Но правда удалил я это руками( 162 символа.)
А вот как узнать длину этого "добавочного" значения.
Ведь там хранится история, откуда файл попал в Access и еще всячина типа Package и т.д.
Буду искать. Помощь приветствуется.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
542
admigator
А где какой файл?
А все... Протупил

UPD: А если в xml выгрузить? чтобы крокозябр не было?
Да не, совсем туплю..
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
472
скорее всего (в соотв. с дебильной традицией МС) они хранят там в своих контейнерах - ОЛЕОбжект
и стрим надо подавать ему на вход, а уже оттудова вытаскивать...
как это в васике должно выглядеть - не знаю
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
542
Сами MS настаивают что там BLOB(Binary Large Objects) и работать надо с ним:
Код там не сильно отличается от кода admigator, но и различия есть, смещения по другому прописаны.
Стоит попробовать.
И вот еще:
А вот тут есть примеры с access:
 
A

admigator

Пока разбираюсь с ссылками и вариантами вместе с Googl-om может кто еще подключится
В аттаче база Access и лотусовая. Распаковать в корень на диск С:\ или меняйте пути в агенте.(import ADO)
Спасибо.
 

Вложения

  • Standard.rar
    460,6 КБ · Просмотры: 141
G

gpatron

Была у меня такая задача. Нужно было всю БД Access перегнать в лотус. С фотками не стал заморачиваться(писать свой код) и нашел готовую программку ExtractInventoryOLEver89, она выгружает OLE объекты на диск, ну а затем просто втянул с диска в документы фотки.
Может и подойдет все таки такой вариант.
Посмотреть вложение ExtractInventoryOLEver89.rar
 
A

admigator

Да, кстати хороший ресурс

Но при попытке экспорта на диск с помощью этой базы на диске сохраняет файл "1.bmp.pak"
На выходе - файл такой же что при работе агента "import ADO" в базе, что я приаттачил.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
542
admigator
Жесть... У меня только предложение написать выгрузку макросами Access и потом загрузить.
 
A

admigator

А тут нашел такой пост, на сколько могу разобрать по коду,он что "откусывает" 78 байт?


Быстрым пробегом по сайту и гуглу не нашел как "откусить" из файла допустим 78 байт на LotusScript.
Буду искать...
Нашел еще такое, может кто сможет перевести на LotusScript
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
472
Right и Left но как там с большими объемами - не знаю
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
542
admigator
Посмотри это:
Там есть описание OLE структуры и как работать, правда там Bitmap прямой, но думаю можно придумать что-то
 
A

admigator

Пошел по этому пути

ПОЛУЧИЛОСЬ!!!
Всем спасибо. В аттаче решение. Пользуйтесь.
Конечно там есть недостатки. Исходный и конечный файл не 100% идентичны,
но задача "откусить" OLE Header из изображения решена.
 

Вложения

  • Standard.rar
    467,3 КБ · Просмотры: 178

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
472
надо убеждать коллег слезать с МС технологий - уж больно гиморны они в интеграции :huh:

Добавлено: ну а различия они и понятны - хвост этой бяки не отрезается, а для самого имеджа не так критично (хотя могут и капризные проги попасться)
не уверен что ImageIcon его режет
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!