Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem reading in Binary file- Very strange, offset by 1 byte

Status
Not open for further replies.

shayneham

Programmer
Oct 16, 2002
5
US
I am running into one of the strangest issues I have seen in a long time. I have a user defined type that I utilize in VB6 and write out to a binary file.

The Type is...

Code:
Type SECTIONDB                      ' Job Section List Database
    SectionNum As Integer               ' Section number
    Multiplier As Long                  ' Multiplier
    SpecName As String * 8              ' Spec name
    ZoneName As String * 60             ' Zone name
    Division As String * 20             ' Variable Zone Identifier
    Subzone As String * 40              ' Subzone description
    AssemblyName As String * 60         ' Assembly name
    Notes As String * 100               ' User notes (remarks)
    Flags As Integer                    ' Section flags
    BaseHours As Double                 ' Base hours for section
    AdjustHoursV(3) As Double           ' Adjusted hours for section
    FactorV(3) As Single                ' User labor factor for section
    JobHoursV(3) As Double              ' Total job hours
    ExceptCnt As Integer                ' Exception count
    ScaleFactor As Long                 ' Scale (1"=x')
    RefSizeV(13) As Integer             ' Reference sizes
    VarDesc(13) As String * 16          ' Variable Size Descriptions
    OrderNum As Integer                 ' Zone Order
    RFU As String * 60                  ' Reserved space for future use
End Type


The file is written in VB as such..
Code:
    Dim I As Integer
    Dim FD As Integer
    Dim Magic As Integer

    On Error Resume Next
    DeleteFile Path
    FD = FreeFile
    Open Path For Binary Access Write As FD
    If Err <> ERR_NONE And Err <> ERR_NOTFOUND Then GoTo StoreSectionDB_Error
    On Error GoTo StoreSectionDB_Error
    Magic = SECTIONDB_MAGIC
    Put FD, 1, Magic
    Put FD, , SectionVCnt
    Put FD, , SectionNum
    For I = 0 To SectionVCnt - 1
        Put FD, , SectionV(I)
    Next I
    Close FD

The Magic,SectionVcnt,SectionNum are simply integers, so the file created is 3 integers then as many of these user types as needed.

In excel I read this in as one would expect...

Code:
    FD = FreeFile()
    Open PathName For Binary Access Read As FD
    Get FD, 1, Magic
    Get FD, , SectionVCnt
    Get FD, , SectionNum
    ReDim SectionV(SectionNum)
    For i = 0 To SectionVCnt - 1
            Get FD, , SectionRec
    next i


This has worked without issue for many years. However, after my last upgrade to the SectionDB user type, suddenly when I read in the sections, they are offset by 1 byte, for no reason that I can find, the header of the files is still those 3 integers. The first section read's in just fine, but the rest are offset. I can succesfully read them in only if I alter the code to...

Code:
            Get FD, Len(Magic) + Len(SectionVCnt) + Len(SectionNum) + Len(SectionRec) * i + 1, SectionRec

which I really don't want to do. I know that when reading in Variant types you need a 2 byte descriptor, but I am not using any variants, I am completely at a loss for what could be happening here.

And this file reads in exactly right in VB6.

Any insight would be greatly appreciated.

Thanks
 
After a little more digging, I find the offset is actually 2 bytes. What I did was set up both VB and VBA to show me the file position as it was being read in. With the exact same file the following is reported. Keep in mind there are 3 integers at the start of the file, and the SectionDB is 704bytes, verfified in both VB and VBA using a len(SectionRec) call.

VB VBA
Get FD, 1, Magic 3 3
Get FD, , SectionVCnt 5 5
Get FD, , SectionNum 7 7
Get FD, , SectionRec 711 713
Get FD, , SectionRec 1415 1419
Get FD, , SectionRec 2119 2125

So each call in VBA adds another 2 bytes to the offset, VBA knows the length of the SectionRec type is 704, so why the heck is it getting these extra two bytes for?

Any Help would be appreciated

 

I can't reproduce this purely in VBA and don't have VB6 installed at the moment. All I can do is try to suggest something you haven't thought of.

What was your last update to the UDT? Always a good place to start when something goes wrong. It looks like it might be an alignment issue. I don't know much about VB6 but I would expect it to behave in the same way as VBA - does it have any options in this area? If you look at the file with a hex editor are the sections 704 bytes or 706?



Enjoy,
Tony

--------------------------------------------------------------------------------------------
We want to help you; help us to do it by reading this: Before you ask a question.

Professional Office Developers Association
 
Thanks for your reply Tony. The file itself is correct when looked at in a hex editor, and VB and VBA should work exactly the same in this regard. My only guess at this point, is from looking at the help files between VB and VBA, on the Get function, VBA mentions something that VB doesn't, other than it, the files are word for word at the beggining. VBA says that when reading into a variant 2 bytes need to be present to set the type of the Variant. I am not using any variants in my type as you saw, so my only guess at this point is that somehow vba is somehow being triggerd to grab those two bytes when it shouldn't or is misinterpreting the type to contain a variant... ughhh
 
Here is what the VBA help says related to above...

-------------------------
If the variable being read into is a variable-length string, Get reads a 2-byte descriptor containing the string length and then reads the data that goes into the variable. Therefore, the record length specified by the Len clause in the Open statement must be at least 2 bytes greater than the actual length of the string.


If the variable being read into is a Variant of numeric type, Get reads 2 bytes identifying the VarType of the Variant and then the data that goes into the variable. For example, when reading a Variant of VarType 3, Get reads 6 bytes: 2 bytes identifying the Variant as VarType 3 (Long) and 4 bytes containing the Long data. The record length specified by the Len clause in the Open statement must be at least 2 bytes greater than the actual number of bytes required to store the variable.
------------------------------

I am currently at a point where I can't repro this problem, although this happened before with no changes, then a day later it came back.
 

Interesting that the Help says different things as either the two bytes are on the file or they aren't - the language used to read can't make that kind of difference.

I don't, however, have any more real ideas and if you can't reproduce it, it's hard to take further, frustrating though it must be for you.

Enjoy,
Tony

--------------------------------------------------------------------------------------------
We want to help you; help us to do it by reading this: Before you ask a question.

Professional Office Developers Association
 
Quick follow up, I still can't reliably repro this every time, however when I do get it, I can get it continuously in that session, until I close excel, and I have found I can reliably get it to stop happening if I rename the Vardesc array in the SectionDB type to AckDesc. I can only guess that the name Vardesc is somehow triggering excel to think their is a Variant variable when there is not.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top