Creating a binary file via VBA

Banana

split with a cherry atop.
Local time
Today, 14:29
Joined
Sep 1, 2005
Messages
6,318
I need to create a binary file automagically which will be used by another program. I found a snippet that can read/write to binary file. I copied & pasted it into a module and it compile fine.

However it trips over the line:
Code:
Get #iFileNum, , vThisBlock

Which I get an error:
Code:
Variable uses an Automation type not supported in Visual Basic

There is no information on the 'Get' method in help so I'm at a loss as to how to resolve this.

Also, does VBA have any data type that can hold raw binary? No, I don't want to store it as OLE in an Access table, and there'd be no point in doing so as this will be completely executed within VBA.
 
I need to create a binary file automagically which will be used by another program. I found a snippet that can read/write to binary file. I copied & pasted it into a module and it compile fine.

However it trips over the line:
Code:
Get #iFileNum, , vThisBlock

Which I get an error:
Code:
Variable uses an Automation type not supported in Visual Basic

There is no information on the 'Get' method in help so I'm at a loss as to how to resolve this.

Also, does VBA have any data type that can hold raw binary? No, I don't want to store it as OLE in an Access table, and there'd be no point in doing so as this will be completely executed within VBA.


Need more information to help you

What does the open file statement you're using look like?
What data type is vThisBlock?

To hold the Raw binary data use a byte array.
 
:confused: How did that sad smiley get in the title?

Oh well..

Djkarl, you mean this line?

Code:
Open sFileName For Binary Access Read As #iFileNum

vThisBlock is a variant.

Notice that I simply copied and pasted the whole snippet from the link I posted in the first post. The only thing changed was the file name.

To hold the Raw binary data use a byte array.

So that explains why the snippet used array! I didn't make that connection.
 
:confused: How did that sad smiley get in the title?

Oh well..

Djkarl, you mean this line?

Code:
Open sFileName For Binary Access Read As #iFileNum

vThisBlock is a variant.

Notice that I simply copied and pasted the whole snippet from the link I posted in the first post. The only thing changed was the file name.



So that explains why the snippet used array! I didn't make that connection.

Ok the open line looks fine, you can't use a variant with the Get command

the synatx for Get is

Code:
Get #Filenumber,BytePositionToStartInFile,WhereToPutThedata

Now lets say you want to read in all data from a binary file and then do "something" with it.

I would use something like this.

Code:
dim sFileName as String
dim iFileNum as Double
dim btAR() as Byte

iFileNum = FreeFile

sFileName = "C:\Temp\MyBinaryFile.bin"

Redim btAR(1 to Filelen(sFileName))

Open sFileName For Binary Access Read As #iFileNum
     Get #iFileNum,1,btar()
Close iFileNum

'Do Stuff with your array

Now if the file is too big to read in all at once, you could dimension your array to say 20000 and read 20K at a time, and then the next time through the "get" instead of starting at byte position 1 you'd start at byte position 20001.
 
Excellent! That was a great explanation.

I have to admit, it was a bit odd that the 'Get', 'Put' and 'Open' is nowhere to be mentioned in the help files. But now I have a good idea of how to do this; my test binary file was successfully created and was readable by the program that needed it.

Just one more thing though... I want to make that byte array constant so it's saved persistently within the database. Is that doable? I ask because when I debug.print the byte array, I get lots of ???? and I very doubt it that a copy and paste would be a good idea with this.
 
Djkarl,

Once again, thanks for your insights!

I had figured that there's no such thing as a constant array so settled for a string and splitting it into a byte array when I need to create the file. Testing the created file worked like a treat. :)
 
Glad it worked for ya. You could also store the data in a table in a binary field, though this can get a bit messy because you have to store it in multiple records.

To create a binary field you need to use SQL as Access won't otherwise let you define the binary data type.

"CREATE TABLE [MyTest] (myField Binary)"
 
Okay, new problem.

I want to use a function that modifies the byte array. VBA cannot pass arrays to functions, so I have to flip flop between the byte array and variant.

Here is my reference detailing how one is to pass a byte array to function and receive the data.

However, the problem is that when I get the variant from the function and store it in a byte array:

Code:
Dim arByte() as Byte
Dim arInputByte() as Byte

arByte = SomeFunction (arInputBytes)

....

Private Function SomeFunction (InputData() as Byte) as Variant

....

The result is empty array with same bounds as the original array. I suspect I'm missing something obvious...

Any clue?
 
Banana.

Could you post your code to site please?

Chris.
 
VBA cannot pass arrays to functions

That's news to me, I pass arrays all the time in functions. You need to use the ByRef qualifier though to pass and return arrays.
 
which version of access have you got

i can get help for file writing - although you need to be editing a code module to get the correct help file

in a code module press F1 while on the word get or put .
 
ChrisO, the reason why I didn't put up the full code is because it's freaking huge, with several functions being called. Here's the source code I got from: Download the VB Blowfish Algorithm.

The only changes I made to that code was to consolidate all of them into one module instead of five modules, removing duplicate API calls and functions and changed the scopes for most routines from public to private now that they're in one module.

I'll post my edited module and the calling routine when I get to work.

Djkarl- Ah, yes, I remember reading a blurb about that... I could try this, though it doesn't seems to be recommended by the folks who contributed to the code...

Gemma-the-Husky, it's Access 2003. Thanks for letting me know- I will take a second look in VBA help files and see if it's truly there.
 
Here's my modified module as described in previous post.

The full calling function that initiates the whole module. It should be noted that this is only a test function, and not the final function that I will actually work. The final function will read a byte array stored in Access internally, then process to decrypt it and create a binary file with the decrypted message. Right now, it just takes in a non-encrypted binary file, read it to the array, and encrypt it, then replaces that file with the encryption.

Code:
Private Sub ReadKey()

Dim sFileName As String
Dim iFileNum As Double
Dim btar() As Byte
Dim tbyte As Variant
Dim i As Integer
Dim strConst As String
Dim enbyte() As Byte

iFileNum = FreeFile

sFileName = "C:\testfile"

ReDim btar(1 To FileLen(sFileName) - 1)

Open sFileName For Binary Access Read As #iFileNum
     Get #iFileNum, 1, btar()
Close iFileNum

For Each tbyte In btar
    strConst = strConst & tbyte & ";"
Next

strConst = Left(strConst, Len(strConst) - 1)

Debug.Print strConst

enbyte() = blf_BytesEnc(btar())

Debug.Print enbyte()

If FileWriteBinary(enbyte(), "C:\testfile", False) Then
 'do nothing
End If

End Sub

FileWriteBinary, a custom function, works just fine, BTW.
 

Attachments

Yep, it was an operator's error- the array in my calling function was dimensioned from 1 to len-1, when it should be 0 to len-1.

Works alright.
 

Users who are viewing this thread

Back
Top Bottom