469,356 Members | 2,043 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,356 developers. It's quick & easy.

binary data and the OLE Object field

I need to unpack a bunch of values (Single data type) from an OLE Object
field. I think the Windows API has a CopyMemory function that could, for
example, get 4-byte chunks of the field which could then be put in an array
or table or something. Is there a way to do this in VBA? What I'd like to
end up with is a table with one field and N number of rows representing the
values unpacked from the binary data in the current OLE Object field.

Thanks in advance.
Nov 13 '05 #1
8 10625
*Air Code*
' Assumes OLE field is bound to an OLE Frame control named "olePicture"

Dim a() As Long
Dim lTemp As Long

lTemp = LenB(Me.olePicture.Value) / 4
ReDim a(0 To lTemp)

' Copy the contents of the OLE field to our array
a = Me.olePicture.Value

--

HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
"deko" <de**@hotmail.com> wrote in message
news:AC******************@newssvr13.news.prodigy.c om...
I need to unpack a bunch of values (Single data type) from an OLE Object field. I think the Windows API has a CopyMemory function that could, for example, get 4-byte chunks of the field which could then be put in an array or table or something. Is there a way to do this in VBA? What I'd like to end up with is a table with one field and N number of rows representing the values unpacked from the binary data in the current OLE Object field.

Thanks in advance.


Nov 13 '05 #2
> ' Assumes OLE field is bound to an OLE Frame control named "olePicture"

Dim a() As Long
Dim lTemp As Long

lTemp = LenB(Me.olePicture.Value) / 4
ReDim a(0 To lTemp)

' Copy the contents of the OLE field to our array
a = Me.olePicture.Value


Thanks for the reply.

The OLE field is just a field in a table, not bound to anything. Basically,
I just need to de-blob it and get the vaules.

I tried this:

Set rst = db.OpenRecordset("TableWithBlobField")
lngBlobSize = LenB(rst("BlobField"))
abytBlob = rst("BlobField").GetChunk(0, lngBlobSize)
For Each varItem In abytBlob
Debug.Print varItem
Next

the output of this is a bunch of Bytes, so it appears to be working, but the
data I'm looking for is a bunch of Singles. The VB App that did this before
had a "CopyMemory" function that returned a Single. Something like this:

CopyMemory sngBlobValue, abytBlob(lngBlobOffset), 4

I assume sngBlobValue is the return value, but I don't know what
lngBlobOffset is - unless it's 4.

Any ideas how to replicate this in VBA? How are the bytes in the byte array
converted into singles?
Nov 13 '05 #3
I think this is close to what I'm looking for -

Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (lpDest As Any, _
lpSource As Any, ByValcbCopy As Long)

Set rst = db.OpenRecordset("TableWithBlobField")
lngBlobSize = LenB(rst("BlobField"))
abytBlob = rst("BlobField").GetChunk(0, lngBlobSize)
Do While lngBlobOffset < lngBlobSize
CopyMemory sngBlobValue, abytBlob(lngBlobOffset), 4
Debug.Print sngBlobValue
Loop

but apparently I'm not declaring or using CopyMemory correctly - Access
quits pretty quickly when the code reaches the line that calls CopyMemory.
Why is CopyMemory crashing Access? How do I get CopyMemory to return the
values in memory to the single variable?
Nov 13 '05 #4
Typo in the declaration was the issue.

This is better but I'm still not sure I'm getting the right data.

Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (lpDest As Any, _
lpSource As Any, ByVal bytlen As Long)

Const cnsChunckSize = 4
Set rst = db.OpenRecordset("TableWithBlobField")
Do While Not rst.EOF
lngBlobOffset = 0
lngBlobSize = LenB(rst!BlobField)
abytBlob = rst!BlobField.GetChunk(0, lngBlobSize)
Do While lngBlobOffset < lngBlobSize
CopyMemory sngBlobValue, abytBlob(lngBlobOffset), 4
Debug.Print sngBlobValue
lngBlobOffset = lngBlobOffset + cnsChunckSize
Loop
rst.MoveNext
Loop

Am I using CopyMemory correctly?
Nov 13 '05 #5
I only use GetChunk when there are bandwidth issues to consider. Just
copy the entire field at once to a Byte array. No CopyMemory nor
GetChunk required.

I do not know if you can directly copy the 4 bytes to a VB Single
variable but I would guess not. If you search on GoogleGroups for
Convert Long to Single" in VB land you will find several examples of
code to coerce the 4 bytes into a Single.

--

HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
"deko" <de**@hotmail.com> wrote in message
news:bQ******************@newssvr13.news.prodigy.c om...
Typo in the declaration was the issue.

This is better but I'm still not sure I'm getting the right data.

Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (lpDest As Any, _
lpSource As Any, ByVal bytlen As Long)

Const cnsChunckSize = 4
Set rst = db.OpenRecordset("TableWithBlobField")
Do While Not rst.EOF
lngBlobOffset = 0
lngBlobSize = LenB(rst!BlobField)
abytBlob = rst!BlobField.GetChunk(0, lngBlobSize)
Do While lngBlobOffset < lngBlobSize
CopyMemory sngBlobValue, abytBlob(lngBlobOffset), 4
Debug.Print sngBlobValue
lngBlobOffset = lngBlobOffset + cnsChunckSize
Loop
rst.MoveNext
Loop

Am I using CopyMemory correctly?


Nov 13 '05 #6
I only use GetChunk when there are bandwidth issues to consider. Just
copy the entire field at once to a Byte array. No CopyMemory nor
GetChunk required.
But isn't each byte in the byte array a pointer to a location in memory?

Are you saying that this is the way to do it:

Set rst = db.OpenRecordset("TableWithBlobField")
Do While Not rst.EOF
abytBlob = rst!BlobField
For Each varItem In abytBlob
Debug.Print varItem
Next
rst.MoveNext
Loop

If I try this:

For Each varItem In abytBlob
CopyMemory sngBlobValue, abytBlob(varItem), 4
Debug.Print sngBlobValue
lngBlobOffset = lngBlobOffset + cnsChunckSize
Next

I get "Subscript out of range" after a few loops.
I do not know if you can directly copy the 4 bytes to a VB Single
variable but I would guess not. If you search on GoogleGroups for
Convert Long to Single" in VB land you will find several examples of
code to coerce the 4 bytes into a Single.


There's no reason I need to use a Single. The goal is to deBlob and dump
out the values to an Excel spreadsheet, so I don't think it matters.
Nov 13 '05 #7
This appears to be correct:

abytBlob = rst!BlobField

But comparing these two loops:

--loop 1--
For Each VarItem in abytBlob
Debug.Print vatItem
Next

[output]
68
67
188
94
68
67
174
93
68
67
....

--loop 2--
Do While Not rst.EOF
abytBlob = rst!BlobField
For i = LBound(abytBlob) To UBound(abytBlob)
CopyMemory sngBlobValue, abytBlob(i), 4
Debug.Print sngBlobValue
i = i + 1
Next
rst.MoveNext
Loop

[output]
196.3302
9.570064E+12
196.3322
1.421259E+14
196.3399
5.847288E+09
196.3112
2.580507E+10
196.3154
7.048431E+14
196.3442
....

The output of the second loop (with CopyMemory) returns vaules (e.g.
196.xxxx) that are consistent with what I'm looking for. But why is every
other value some huge number?
Nov 13 '05 #8
Success!!

Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (lpDest As Any, _
lpSource As Any, ByVal bytlen As Long)

Const CHUNKSZ = 4
Set rst = db.OpenRecordset("TableWithBlobField")
Do While Not rst.EOF
lngOffset = 0
lngBsize = LenB(rst!BlobField)
ReDim abytB(lngBsize)
abytB = rst!ScanData.GetChunk(0, lngBsize)
Do While lngOffset < lngBsize
CopyMemory sngBval, abytB(lngOffset), 4
Debug.Print sngBval
lngOffset = lngOffset + CHUNKSZ
Loop
rst.MoveNext
Loop

Nov 13 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Niko Korhonen | last post: by
3 posts views Thread by Randy | last post: by
1 post views Thread by stockblaster | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.