> ...
> > Does anyone know of a way to convert a variant variable to a word
[quoted text clipped - 6 lines]
> Murphy
> www.ConstantThought.com
(Reply inline)
...
> it returns an integer 8209, in my documentation that number is not listed.
> Do you know of a complete list of datatypes and their correlating vartype
> values?
8209 is vbArray logically ORed against vbByte -- a byte array.
...
> > > Does anyone know of a way to convert a variant variable to a word
> > document?
...
Using my libraries (available on my site), you can do this in four lines of
code...
Require VarType(V) = (vbArray Or vbByte), "Operation only valid on Byte
Array Variants", vbeTypeMismatch
Dim F As New CFile
F.OpenFile "out.doc", fatGenericWrite, fcdCreateAlways
F.WriteData PeekLong(PeekLong(VarPtr(V) + 8) + 12), UBound(V) - LBound(V) +
1
(Where V is the Variant holding the blob)
Otherwise, you can use the following:
Private Const GENERIC_WRITE = &H40000000
Private Const CREATE_ALWAYS = 2
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA"
(ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal
dwShareMode As Long, lpSecurityAttributes As Any, ByVal
dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal
hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long)
As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long,
lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten
As Long, lpOverlapped As Any) As Long
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory"
(Destination As Any, Source As Any, ByVal Length As Long)
Sub SaveVariantByteArray(FileName As String, Data As Variant)
If VarType(Data) <> (vbArray Or vbByte) Then
Err.Raise 5
End If
Dim hFile As Long
hFile = CreateFile(FileName, GENERIC_WRITE, 0, ByVal 0&, CREATE_ALWAYS,
0, 0)
If hFile = 0 Then
Err.Raise 10101
End If
Dim TempL As Long
MoveMemory TempL, ByVal VarPtr(Data) + 8, 4
MoveMemory TempL, ByVal TempL + 12, 4
WriteFile hFile, ByVal TempL, UBound(Data) - LBound(Data) + 1, 0, ByVal
0&
CloseHandle hFile
End Sub
This should all be fairly clear, except the two MoveMemory() lines. A quick
explaination of them:
A Variant is a VARIANT structure (see MSDN).
Offset 8 bytes into the structure is the real data that the Variant is
holding. In the case of a byte array, it's the address of a SAFEARRAY
structure (see MSDN).
Offset 12 bytes into the SAFEARRAY structure is the address of the array's
data, which is what you want to write to disk.
Murphy
www.ConstantThought.com
Murphy McCauley - 29 Sep 2003 18:16 GMT
Oh. I forgot to mention the simple, terrible, slow, but nonetheless working
method of simply iterating through the array writing each element
individually using the Put statement. You could probably do similar with
the FSO using Chr$(), but at the risk of Byte->UnicodeChar->ASCIIChar
conversion problems (not to mention that it'd be even slower).
This is certainly a much simpler solution than the one I gave in the
previous post, but I would never use it.
Murphy
www.ConstantThought.com