Reputation: 4467
UPDATED - I added 2 screen shots with 0.00 in the data and one with 1234.56 in the data
I am using an old VB6 set of code as 95% works to read a text file that gets converted and stored in MS SQL. The strings are all good however there are numbers mixed into the text binary file that I haven't figured out how to read. The original application the numbers are all currency however the hex dump of the numbers looks to be 4 byte numbers.
Either way I am not sure how to read the numbers into a local variable. Maybe I am not starting at the correct place in the data. In the example below I am starting at the <160>.
Here is a dump of the part of the binary file with 0.00 in the data:
Here is a dump of the part of the binary file with 1234.56 in the data:
Note the arrow point to where the data changed.
This is my last try but that doesnt work either.
Function ReadFloat(f As Integer, Optional ShowDB As Boolean = False) As String
On Error GoTo 0
Dim c As Single
Dim S(4) As Byte
Dim x As Integer
Dim flt As Single
Get f, , S
For x = 1 To 4
Debug.Print x & " " & S(x) & " " & Hex(S(x)); "='" & Chr(S(x)) & "'"
Next x
CopyMemory flt, S, 4
Upvotes: 0
Views: 1453
Reputation: 2216
My initial inspection suggests that the bytes starting:
40 E2 01
are what you're looking for. These are stored little endian, so 01E240 is hex for 123456 in decimal. So my guess would be 32 bit integers (4 byte long type). You can test this by using -0.01 as a value, this should give:
... FF FF FF FF ...
in the file.
If you're only interested in reading just these values then you can read and discard the first x values. Something like:
Dim yDiscard(123) As Byte
...
Get #1, ,yDiscard
Or alternatively, just seek to the position first before reading:
Seek #1, 123
To work out what byte values to expect in general, I found the following to be useful. Just run the code in a module:
Sub main()
Dim lValue As Long
Dim cValue As Currency
Dim nValue As Single
Dim dValue As Double
Dim sValue As String
Dim vValue As Variant
lValue = 123456
cValue = 1234.56
nValue = 1234.56
dValue = 1234.56
sValue = "1234.56"
vValue = CDec(1234.56)
Open "c:\test1.bin" For Binary As 1
Open "c:\test2.bin" For Binary As 2
Open "c:\test3.bin" For Binary As 3
Open "c:\test4.bin" For Binary As 4
Open "c:\test5.bin" For Binary As 5
Open "c:\test6.bin" For Binary As 6
Put #1, , lValue
Put #2, , cValue
Put #3, , nValue
Put #4, , dValue
Put #5, , sValue
Put #6, , vValue
Close #1
Close #2
Close #3
Close #4
Close #5
Close #6
End Sub
You can then inspect each file in a hex editor (I use MadEdit but anything will do).
It's probably useful to also try simple values like 1.00, 2.00, 10.00, -1.00 and see how the bytes differ each time.
This may also be informative (fairly in depth):
And to actually answer the question, something like the following will read a 32 bit integer and convert to currency:
Function ReadAmount(iFileHandle As Integer, lFileBytePosition As Long) As Currency
Dim lValue As Long
Seek #iFileHandle, lFileBytePosition
Get #iFileHandle, , lValue
ReadAmount = CCur(lValue) / 100
End Function
There's no need for an intermediate byte array.
Upvotes: 1
Reputation: 462
True floating point are bad when using currency, so actually your number is an integer with fixed point. First : put them in an integer variable (type Long) Second : divide by 100 to get back the decimal !
Straightforward method to convert it to single:
Dim S(4) As Byte 'your 4 bytes, like (1)=&H40, (2)=&HE2 (3)=&H01, (4)=&H00
Dim Buffer As Long
Buffer = S(4) * 16777116 Or S(3) * 65536 Or S(2) * 256 Or S(1)
Dim flt As Single
flt = Buffer / 100
Upvotes: 0