dcsimg
Results 1 to 7 of 7

Thread: [RESOLVED] load and save udt EOF issues

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    811

    Resolved [RESOLVED] load and save udt EOF issues

    I would like to ask about this issue, theres a workaround but i dont get it why it happens at all.
    I use two function, one to Load and one to Save, using the "Open file For Binary Access Read or Access Write"

    Loading:
    Code:
    Do
    Index = Index + 1
    ReDim Preserve MyUDT(Index)
    Get #ff, , MyUDT(Index)
    Loop Until EOF(ff)
    Saving:
    Code:
    For i = 1 To Index
    Put #ff, , MyUDT(i)
    Next i
    this works, sure, it can load and save the array, and the array can increase or decrease.
    but the loading will always return one additional index. the last array is empty.

    if we examine the the file im using (the first time I save), it says 682 bytes.
    using LOC, after the first Get, it says 682, meaning the entire file is done,
    still EOF will not trigger and exit the loop, instead looping one more time. why is that?

    if we replace EOF with LOC:
    Code:
    size = FileLen(file)
    Do
    Index = Index + 1
    ReDim Preserve MyUDT(Index)
    Get #ff, , MyUDT(Index)
    Loop Until Loc(ff) = size
    it works without giving the extra array.
    shouldn't EOF work like Loc as its the end of the file?

  2. #2
    Frenzied Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    1,297

    Re: load and save udt EOF issues

    MSDN says this about EOF:
    With files opened for Random or Binary access, EOF returns False until the last executed Get statement is unable to read an entire record.
    So EOF won't be TRUE until a read fails (hence the extra dimension). I think you are also getting an extra dimension at the front of your array since you don't specify a lower bound of 1 when you redim.

  3. #3
    Frenzied Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    1,297

    Re: load and save udt EOF issues

    You could try something like this instead:

    Code:
    Option Explicit
    
    Public Type UDT
       Test1 As Long
       Test2 As Double
    End Type
    
    Sub Load(ByVal p_FilePath As String)
       Dim MyUdt() As UDT
       Dim ff As Integer
       Dim ii As Long
       Dim l_Lof As Long
       Dim l_Eof As Boolean
       
       ff = FreeFile
       
       Open p_FilePath For Binary Access Read As #ff
       l_Lof = LOF(ff)
       
       ReDim MyUdt(100)
       
       Do
          If UBound(MyUdt) < ii Then
             ReDim Preserve MyUdt((UBound(MyUdt) - LBound(MyUdt) + 1) * 2)
          End If
          
          Get #ff, , MyUdt(ii)
          l_Eof = (Seek(ff) > l_Lof) ' If the Seek position > length of file, then we are finished reading
          
          If l_Eof Then
             ReDim Preserve MyUdt(ii)
          Else
             ii = ii + 1
          End If
       Loop While Not l_Eof
       Close #ff
       
       ' Output UDT array elements to debug to see that we read only what we need
       For ii = LBound(MyUdt) To UBound(MyUdt)
          Debug.Print MyUdt(ii).Test1
       Next ii
    End Sub
    
    Sub Save(ByVal p_FilePath As String)
       Dim MyUdt As UDT
       Dim ff As Integer
    
       ff = FreeFile
       
       Open p_FilePath For Binary Access Write As #ff
       MyUdt.Test1 = 1
       Put #ff, , MyUdt
       MyUdt.Test1 = 2
       Put #ff, , MyUdt
       MyUdt.Test1 = 3
       Put #ff, , MyUdt
       MyUdt.Test1 = 4
       Put #ff, , MyUdt
       MyUdt.Test1 = 5
       Put #ff, , MyUdt
       MyUdt.Test1 = 6
       Put #ff, , MyUdt
       Close #ff
    End Sub
    Note that it pre-Redims the array to a large-ish size to avoid frequent Redim. It increases the buffer as necessary and then Redims at the end to required size. It also determines EOF by checking the seek position vs. the length of the file.

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    811

    Re: load and save udt EOF issues

    Loc(ff) works fine, also, in my own code i redim using (1 to x) as im not using 0.
    since im using a bunch of undimmed variables inside the UDT, the size of each array can change, so i can't determine the amount of arrays.
    i think i could reach over 1000 in the future.

    thx for the code and the info, i will look into it and maybe use something. the redim could be a good idea to pre-redim.
    also, quite odd that EOF need to fail to read to trigger. but since we got Loc/Seek we can use that instead.

  5. #5
    Addicted Member
    Join Date
    Nov 2011
    Posts
    130

    Re: [RESOLVED] load and save udt EOF issues

    Try the following.


    Code:
    Private Type UDT
       Test1 As Long
       Test2 As Double
    End Type
    
    
    
    Private Sub cmdSave_Click()
    
        Dim p_FilePath As String
        Dim Index As Integer
        p_FilePath = App.Path & "\test.dat"
    
        Dim MyUdt(2) As UDT
    
        MyUdt(0).Test1 = 1
        MyUdt(0).Test2 = 1#
        MyUdt(1).Test1 = 2
        MyUdt(1).Test2 = 2#
        MyUdt(2).Test1 = 3
        MyUdt(2).Test2 = 3#
        Index = 2 '  sets how many in array
    
        Dim ff As Integer
        ff = FreeFile
    
        Open p_FilePath For Binary Access Write As #ff
        Put #ff, 1, Index
        Put #ff, , MyUdt
    
        Close #ff
    
    
    End Sub
    
    Private Sub cmdRead_Click()
    
        Dim p_FilePath As String
        Dim Index As Integer
    
        p_FilePath = App.Path & "\test.dat"
    
        Dim MyUdt() As UDT
        Dim ff As Integer
        Dim ii As Long
    
        ff = FreeFile
    
        Open p_FilePath For Binary Access Read As #ff
        Get #ff, 1, Index
        ReDim MyUdt(Index) As UDT
        Get #ff, , MyUdt
        Close #ff
    
    
        Dim X As Integer
        For X = 0 To Index
    
            Debug.Print MyUdt(X).Test1
            Debug.Print MyUdt(X).Test2
        Next X
    
    
    End Sub

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    811

    Re: [RESOLVED] load and save udt EOF issues

    thx k_zeon, yeah, i have used this method, to have a header with some info or simply the amount of arrays,
    doing so we know the amount of items in the array and can redim accordingly, not a bad idea to skip the eof/loc with that.
    the thread was about the EOF that didnt tell you when end of file, instead as jpbro posted need to fail to trigger and its something i can't understand the logic of.
    nothing i can do about anyway, so its better to skip the usage of eof and instead use a header or the loc/seek method.

  7. #7
    Addicted Member
    Join Date
    Nov 2011
    Posts
    130

    Re: [RESOLVED] load and save udt EOF issues

    Quote Originally Posted by baka View Post
    thx k_zeon, yeah, i have used this method, to have a header with some info or simply the amount of arrays,
    doing so we know the amount of items in the array and can redim accordingly, not a bad idea to skip the eof/loc with that.
    the thread was about the EOF that didnt tell you when end of file, instead as jpbro posted need to fail to trigger and its something i can't understand the logic of.
    nothing i can do about anyway, so its better to skip the usage of eof and instead use a header or the loc/seek method.
    only thing i can think of without trying it is to change the Do .... Loop to something else. ie Do While Not EOF(ff) or something like that
    so the loop wont process on EOF

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width