Results 1 to 10 of 10

Thread: I think I have everyone stumped with this one

  1. #1
    veebee
    Guest
    I have a class file that is basically a data record with all of the necessary property lets and property gets required for access. I also have methods for opening, closing, and writing the data record. The data record is a user-defined type.

    What I need to do, is write this user-defined type to a disk file (not a database). The situation is something like this (simplified, as my actual record consists of several layers of user-defined types):

    Public class dataRecord

    option explicit

    private type record
    field1 as string * 10
    field2 as string * 5
    end type

    dim rc_Record as record

    Property Lets, Property Gets, (etc. etc.)....

    Public Function Write_Rec() as Integer
    '* This is where my problem is
    End Function


    What I want to do in the Write_Rec function is to write rc_Record as a whole group to a text file on disk that I have opened as Append. Right now I am doing the following:
    Print #fnum, field1;field2;

    Does anyone know how I can do this?
    Also, along the same lines, I have an Initialize subroutine in this class to fill all fields on the record with spaces. I would like to move spaces to rc_Record instead of to each individual field. Can anyone tell me how this is done as well? And what if some of the items within the record eventually are integers, longs, etc?

  2. #2
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    The Put and Get statements are able to write and read user-defined types.
    Try:
    Code:
    Put #iFileNum, , MyUDT
    Get #iFileNum, , MyUDT
    Enjoy

  3. #3
    Lively Member
    Join Date
    Jul 1999
    Posts
    99

    Lightbulb Open file using Random Access

    Instead of opening the file for APPEND, I suggest you open your file using:

    Code:
    Open YourFile.txt For Random As FileNumber Len = RecordLength
    Opening your file using Random access will help.

  4. #4
    veebee
    Guest
    Yes, your suggestions worked. Never think the users of this board can be stumped. Thanks Tonio169 and Yonatan!!!!

    Does anyone have any idea about my last question, initializing all fields to spaces without setting each individual field on the record? Right now, I am doing the following:

    field1 = Space(Len(field1))
    field2 = Space(Len(field2))

    What I want to do is something like:

    rc_Record = Space(Len(rc_Record))

    but this gives me the following error at runtime:

    Compile error: Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions

  5. #5
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    I don't know if I have missunderstood your question but fixed length strings are initialized with spaces....
    Take the following simple UDT:
    Code:
    Type Person
        FirstName As String * 15
        LastName As String * 20
    End Type
    
    Public Sub SomeSub()
        Dim udtPerson As Person
        'the rest of the code
    End Sub
    In the procedure SomeSub the udtPerson.FirstName will be initilized with 15 spaces and udtPerson.LastName with 20 so you don't have to do that yourself.

    Best regards

  6. #6
    veebee
    Guest
    Joacim:

    That works fine for the first write, but I neglected to mention that I write more than one of these records based on data received on input. I wanted to re-initialize the user-defined type so data from the previous write was not written out to the next record. The input record is not the same format as the output record (input is XML, this project is parsing an XML document).

    The final output is x occurances of rc_Record written out to a single text file.

    Thanks for your input and any help you might be able to provide.

  7. #7
    Hyperactive Member
    Join Date
    Feb 2001
    Location
    LoCal
    Posts
    280
    You can try creating a dummy UDT the same byte-length as your UDT and initializing that to vbNullChars then setting your UDT to the dummy...

    Code:
    Private Type udtStuff
         Name as String * 10
         City as String * 20
    End Type
    
    Private Type udtBlank
         Buffer as String * 30
    End Type
    
    Dim uStuff as udtStuff
    Dim uBlank as udtBlank
    
    uBlank = String(30, vbNullChar)
    
    LSet uStuff = uBlank
    You would basically be copying memory locations. You initialize your blank variable to vbNullChars (0's) and then you copy that to the variable that has the stuff in it.

    There are some drawbacks, though, since you can't use this method with variable length strings and figuring out the byte-length of your udt is a pain in the *ss.

    I'd say write a sub that clears out the udt's.
    Achichincle

    VB6 (VSEE SP5, W2KPro)
    ASP
    HTML

  8. #8
    demirc
    Guest
    Joacim is 100% right, there is no need of reseting any values, as long as you declared the record type within a procedure, it will remain there, with initial value of nothing. I'm little rusty on the subject but, lets see:

    First create a function or a sub depending on your needs. I would go with a function though:

    maybe something like this

    Code:
    Function AddRec (Rec as Record, RecNo as Long) as Long
    
    If RecNo=0 then
    Seek#1,LOF(1) + 1  ' if you don't pass a record# it will seek the end of the file
    else
    seek#1,RecNo ' it will move to the record# you passed
    End if
    
    Put#1, ,Rec  ' this will write at the current position 
    
    'I think this will give you the number of records in that file, it has been a while since my QBasic days ;)
    
    Addrec=LOF(1)/len(rec) 
    
    'or Addrec=loc(1) will return the current record number
    
    End Function
    some thing like that. But if you are gonna write the whole thing in one shot and no mods are neccessary then, much shorter one:

    Code:
    Function AddRec (Rec as Record)
    
    Put#1,,REc
    
    End Function

  9. #9
    veebee
    Guest
    By the way, I found this out when I tried to implement the LSET stuff: The LSET won't work if you have a UDT with an array like this:

    Private Type udtMyRecord
    field1 as String * 10
    field2 (1 to 4) as String * 10
    End Type

    Private Type udtAnotherRec
    field1 as String * 50
    End Type

    LSet udtAnotherRec = udtMyRecord

    field2 causes a 'Type Mismatch' error on the LSet command. If (1 to 4) is removed, it works perfectly. Does anyone know a way around this?

  10. #10
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    Try using CopyMemory instead.
    Code:
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal cbSrc As Long)
    
    ' ...
    
    Call CopyMemory(udtAnotherRec, udtMyRecord, LenB(udtMyRecord))

Posting Permissions

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



Click Here to Expand Forum to Full Width