VBFixedArray problem

D

David Scemama

Hi,

I'm trying to read a database file written from a turbo Pascal program. I've
set a structure to map the records in the file, but

I have problem reading the file when I use VBFixedArray in my structure
instead of VBFixedString.
Here is the original code that works:

Structure CCat
Public code As Short
<VBFixedString(17)> Public name As String
<VBFixedString(30*10)> Public myList As String ' in fact, array of
10 strings of 30 chars
End Structure

Dim cat as CCat
Dim value as ValueType = cat
FileGet (1, value)
cat = CType(value, CCat)

The size of the array my change depending on the customer, so I cannot use a
fixed size structure. I've tried to replace it this way:
Structure CCat
Public code As Short
<VBFixedString(17)> Public name As String
<VBFixedArray(30)> Public myList() As String
End Structure

Dim cat as CCat
redim cat.myList(9) ' from what I know, this is supposed to
create an array of 10 strings of 30 chars each.
Dim value as ValueType = cat
FileGet (1, value)
cat = CType(value, CCat)

The fileGet function raises an IOException: Bad record Length.

Can someone tell me what I did wrong ? Also, is there a way to get the
record length I'm requesting before the FileGet ?

Thanks a lot for your help
David
 
J

Jim Cantwell [MSFT]

The array of strings needs to include the VBFixedString attribute as well as the VBFixedArray attribute. Use the VB Len function to determine the size a structure would be if written using the VB file i/o functions.
Structure CCat
Public code As Short
<VBFixedString(17)> Public name As String
<VBFixedArray(9), VBFixedString(30)> Public myList() As String
End Structure

Sub Main()
Dim Size As Integer
Dim cat As CCat

Size = Len(cat)
Stop
End Sub
 
D

David Scemama

I've tried what you suggest, but is the ReDim possible on such a structure ?
I need to define the size of the array at runtime !

If I get the size of cat before and after the ReDim, I have the same result
!

Sub Main()
Dim Size As Integer
Dim cat As CCat

Size = Len(cat)
ReDim cat.myList(20)
Size = Len(cat) ' gives the same result !

Stop
End Sub

And a FileGet will raise an exception "Bad Record Length"

David

Jim Cantwell said:
The array of strings needs to include the VBFixedString attribute as well
as the VBFixedArray attribute. Use the VB Len function to determine the
size a structure would be if written using the VB file i/o functions.
Structure CCat
Public code As Short
<VBFixedString(17)> Public name As String
<VBFixedArray(9), VBFixedString(30)> Public myList() As String
End Structure

Sub Main()
Dim Size As Integer
Dim cat As CCat

Size = Len(cat)
Stop
End Sub
rights. Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
 
D

David Scemama

I've had a look in debug mode. The ReDim works perfectly, meaning that I can
see that the size of cat.myList changes after it occurs.

The problem is that the Len function does not report the correct size and
the FileGet does not like the structure length.

Is there any difference between
<VBFixedString(30*10)> Public myList As String
and
<VBFixedArray(9), VBFixedString(30)> Public myList() As String

for the FileGet function ? (the first occurence works perfectly)

David
 
J

Jim Cantwell [MSFT]

I have confirmed that there is a bug in the FileGet in both VB.NET 7.0 and 7.1. Below is an alternate method of writing the data using non-fixed length arrays.

You can calculate the size required at runtime when using non-fixed arrays, which are written to the file with additional array information for dimensions and dimension length and bounds. The string data will be written out using the string length. If you wish to keep them
at fixed sizes, additional code will be required to validate the member sets and add padding if necessary. But the string length prefix will still be written.

Option Explicit On

Module Module1
Structure CCat
Public code As Short
<VBFixedString(17)> Public name As String
Public myList As String()
End Structure

Sub Main()
Dim Size As Integer
Dim cat As CCat

Dim filename As String
filename = "c:\foo-workaround2.txt"
cat.code = 1
cat.name = "ABC"
ReDim cat.myList(9)

Dim i As Integer
'put something into the array to test
For i = 0 To 9
cat.myList(i) = StrDup(10, ChrW(AscW("A"c) + i))
Next

'Add the size for our dimensions
Size = 2 'Length of 'code' Short (2)
Size = Size + 17 'Lenght of 'name' Fixed String (17)
'Now calculate and add the size of 'myList'
Size = Size + 2 'Length of Short (for Dimension count)
Size = Size + (cat.myList.Rank * 8) 'For each dimension, 4 for array Length, 4 for Lower bound
'Now add the size of the string data (30 characters + 2 bytes for length prefix)
Size = Size + cat.myList.Length * (30 + 2)

FileOpen(1, filename, OpenMode.Random, OpenAccess.Default, OpenShare.Default, Size)
FilePut(1, cat, 1)
FileClose(1)

Dim cat2 As CCat
FileOpen(1, filename, OpenMode.Random, OpenAccess.Default, OpenShare.Default, Size)
FileGet(1, cat2, 1)
FileClose(1)

Stop
End Sub

End Module


--------------------
 

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