User-Defined Type Question

  • Thread starter Montana DOJ Help Desk
  • Start date
M

Montana DOJ Help Desk

Word 2000

I've been working on creating my first user-defined, and using it to write
data to a file, and then to read data from the file. Here's my code (Please
excuse the extra stuff that I put in as examples for myself of how to use
the functions):

********************
Public Type Record ' Define user-defined type.
ID As Long
Name As String * 10
Text As String * 10
End Type

Public MyRecord As Record


Sub WriteRecords()

Dim Bytes As Long
Dim ElementIDSize As Long
Dim ElementNameSize As Long
Dim ElementTextSize As Long
Dim FileNumber As Long
Dim MyRecord As Record
Dim NewRecord As Long
Dim NumRecords As Long
Dim RecordNumber As Long
Dim TypeSize As Long

FileNumber = FreeFile

' LenB function examples.
TypeSize = LenB(MyRecord)
ElementIDSize = LenB(MyRecord.ID)
ElementNameSize = LenB(MyRecord.Name)
ElementTextSize = LenB(MyRecord.Text)

' Open file for random access.
Open "TESTFILE" For Random As FileNumber Len = TypeSize

' LOF function examples. Records are appended to random access files by
adding 1 to the last record number in
' the file. Therefore, finding NumRecords and setting NewRecord allows new
data to be appended to the file.
Bytes = LOF(FileNumber)
NumRecords = Bytes / TypeSize
NewRecord = NumRecords + 1

' Writes data to the file.
For RecordNumber = NewRecord To NewRecord + 4
MyRecord.ID = RecordNumber
MyRecord.Name = "My Name" & RecordNumber
MyRecord.Text = "Record" & RecordNumber
Put FileNumber, RecordNumber, MyRecord
Next

' Closes the file.
Close FileNumber

End Sub


Sub ReadRecords()

Dim CurrentRecord As Long
Dim FileNumber As Long
Dim mbMessage As String
Dim MyRecord As Record
Dim NextRecord As Long
Dim Position As Long
Dim PreviousRecord As Long
Dim TypeSize As Long

FileNumber = FreeFile
TypeSize = LenB(MyRecord)

' Opens a file for random access.
Open "TESTFILE" For Random As FileNumber Len = TypeSize

' Reads the file using the Get statement. Displays the value for each
element of each record.
For Position = 1 To 5
Get FileNumber, Position, MyRecord
mbMessage = "ID: " & MyRecord.ID & vbCr
mbMessage = mbMessage & "Name: " & Trim(MyRecord.Name) & vbCr
mbMessage = mbMessage & "Text: " & Trim(MyRecord.Text)
MsgBox mbMessage
CurrentRecord = Seek(FileNumber) - 1
NextRecord = Seek(FileNumber)
PreviousRecord = Seek(FileNumber) - 2
Next

' Closes the file.
Close FileNumber

End Sub
********************

This all works. However, it bothers me a little that I need to pad the
string values in my user-defined type (i.e. Name As String * 10) in order to
make it work. If I remove the "* 10" from the user-defined type
declaration, then the PUT statement generates:

Run-time error '59':
Bad record length

Is there any way to have variable length strings--and therefore, variable
length records--without running into the above error, or am I stuck with
using fixed length strings?

I suspect that the answer to my question is "No," or, "Yes, but it's so much
work that it's not worth it." Thought I'd ask the question anyway.

-- Tom

State of Montana
Department of Justice Help Desk

"Making the world a safer place."
 
J

Jay Freedman

Hi Tom,

I think the answer is, as you said, "Yes, but it's so much work that it's
not worth it."

The padding requirement comes from the fact that you're opening the file in
both procedures As Random. The whole idea of random file access is that all
the records are the same length, so the offset from the start of the file to
any record can be computed by multiplying the record length by the record
number. If the record lengths are variable, any record's offset would have
to be computed by adding the lengths of all the preceding records.

It is possible to store variable length records if you open the file As
Binary. You (the programmer) would then be responsible for computing any
offset you need, probably by creating and maintaining a table of all the
record offsets -- including keeping track of any operations that add,
delete, or change the records in the file.

The padding makes a big difference only in the situation where you have to
allow for large (say, 64K) records but most of the actual records are small
(< 1K), there are thousands of records, and disk space is tight. If you are
dealing with that sort of situation, you probably shouldn't be using Word
VBA anyway.
 
M

Montana DOJ Help Desk

Jay,

Thanks for the reply. That's pretty much what I figured, but since this is
the first time I've created a user-defined type, and the first time I've
used PUT and GET, I thought I would ask because it doesn't seem to be very
well documented in the online Help.

My application is just writing data from the Err object to a file, so the
file should remain very small. I figure that writing the data to the file
in records will make it easy to pull the data out of the file at some future
date. I've built a user form with First, Previous, Next, and Last buttons
that the user will be able to use to navigate the file. Once the user finds
the error that they want to lookup, they'll be able to click a Help button
and the online help for that error will open in another window.

Anyway, thanks for the info!

-- Tom

State of Montana
Department of Justice Help Desk

"Making the world a safer place."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top