Array in type

Theo Kouwenhoven
Theo Kouwenhoven used Ask the Experts™
on
Hi Experts,

I have an CSV file containing a specific structure, on this mement I use a split to an array to get the fields, but it would be great to do that with an object,

Current:
Dim a
a = Split(inp, ",")

The structure of the CSV is like this:
someText,a1,b1,c1,a2,b2,c2,a3,b3,c3,moreText

So to get it in an object, it should be look like this:
Type MyType
    sometext as string
    a1 as string
    b1 as string
    c1 as string
    a2 as string
    b2 as string
    c2 as string
etc

a,b,c has 15 repeats and there is also someting like d,e,f and x,y,z

Question:

Can I create:

Type Xabc
    a as string
    b as string
    c as string
EndType

Type MyType
    someText as string
    abc as Xabc
    moreText as string
    xyz as Xabc
End Type

some code...

b = MyType.abc(1).a


Is this possible and how can I move the CSV records to this object ?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Try

Private Type MyType
    sometext As String
    a1 As String
    b1 As String
    c1 As String
    a2 As String
    b2 As String
    c2 As String
End Type

Dim abc(19) As MyType

Private Sub Form_Load()
inp = "someText,a1,b1,c1,a2,b2,c2,a3,b3,c3,moreText"

cnt = 0
s = Split(inp, ",")
    abc(cnt).sometext = s(0)
    abc(cnt).a1 = s(1)
    abc(cnt).b1 = s(2)
    abc(cnt).c1 = s(3)
    abc(cnt).a2 = s(4)
    abc(cnt).b2 = s(5)
    abc(cnt).c2 = s(6)

    MsgBox abc(cnt).sometext
    MsgBox abc(cnt).a1
    MsgBox abc(cnt).b1
    MsgBox abc(cnt).c1
    MsgBox abc(cnt).a2
    MsgBox abc(cnt).b2
    MsgBox abc(cnt).c2

End Sub
Theo KouwenhovenApplication Consultant

Author

Commented:
Your Dim abc(19) As MyType, implicates that there is also 19 times "sometext As String"

on top of that, instead of your example, this should be much faster

    s = Split(inp, ",")
    MsgBox abc(cnt).s(0)
    MsgBox abc(cnt).s(1)
    MsgBox abc(cnt).s(2)
    MsgBox abc(cnt).s(3)
    MsgBox abc(cnt).s(4)
    MsgBox abc(cnt).s(5)
    MsgBox abc(cnt).s(6)

What I look for (using your MsgBox example) is an typeArray, a repeating group of variables:

Type Xabc
  a as string
  b as string
  c as string
End Type

Type MyType
    someText as string
    abc as Xabc
    moreText as string
    xyz as Xabc
End Type

Mt as MyType

Dim Mt
Mt = Split(inp, ",")

MsgBox Mt.someText
For f = 1 to 15
    MsgBox Mt.abc(f).a
    MsgBox Mt.abc(f).b
    MsgBox Mt.abc(f).c
next f
MsgBox Mt.moreText

But this is NOT working in this example/definition, so how to solve ?
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
If the data is FIXED WIDTH it's possible.  For variable length, comma delimited data it's generally not possible and you simply have to manually assign each field to the appropriate structure member.
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Theo KouwenhovenApplication Consultant

Author

Commented:
What if it is fixed? how to solve that in a structure with repeating filed-groups

Commented:
For repeating field groups use this :

Private Type MyType
    someText As String
    a1 As String
    b1 As String
    c1 As String
    a2 As String
    b2 As String
    c2 As String
    a3 As String
    b3 As String
    c3 As String
    moreText As String
End Type

Dim Mt(15) As MyType, inp(15)

Private Sub Form_Load()
inp(1) = "someText,a1,b1,c1,a2,b2,c2,a3,b3,c3,moreText"
inp(2) = "SOMETEXT,A1,B1,C1,A2,B2,C2,A3,B3,C3,MORETEXT"

For cnt = 1 To 2
s = Split(inp(cnt), ",")

    Mt(cnt).someText = s(0)
    Mt(cnt).a1 = s(1)
    Mt(cnt).b1 = s(2)
    Mt(cnt).c1 = s(3)
    Mt(cnt).a2 = s(4)
    Mt(cnt).b2 = s(5)
    Mt(cnt).c2 = s(6)
    Mt(cnt).a3 = s(7)
    Mt(cnt).b3 = s(8)
    Mt(cnt).c3 = s(9)
    Mt(cnt).moreText = s(10)

    MsgBox Mt(cnt).someText
    MsgBox Mt(cnt).a1
    MsgBox Mt(cnt).b1
    MsgBox Mt(cnt).c1
    MsgBox Mt(cnt).a2
    MsgBox Mt(cnt).b2
    MsgBox Mt(cnt).c2
    MsgBox Mt(cnt).a3
    MsgBox Mt(cnt).b3
    MsgBox Mt(cnt).c3
    MsgBox Mt(cnt).moreText
Next
End Sub
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Take a look at Random Access Files with UDTs in VB6:
http://www.vb6.us/tutorials/working-random-access-files-vb
Theo KouwenhovenApplication Consultant

Author

Commented:
Hi vb_elmar,

In that case I have an array with records, in stead of having an object with fields
the proicess is habdlin the file per record:

Do until eof(1)
     Input #1, in
     MyType = Split(in, ",")
    ProcessRec(MyType)
Loop

That is the idea

Commented:
I attached a sample VB6 Project.

abc.csv :
someText;a1;b1;c1;a2;b2;c2;a3;b3;c3;moreText
SOMETEXT;A1;B1;C1;A2;B2;C2;A3;B3;C3;MORETEXT

Open in new window

-CSV stands for "Comma Separated Values". In this case
we should use ";" as splitting separator (see sample CSV file in "1csv.zip").

Private Type MyType
    someText As String
    a1 As String
    b1 As String
    c1 As String
    a2 As String
    b2 As String
    c2 As String
    a3 As String
    b3 As String
    c3 As String
    moreText As String
End Type

Dim Mt() As MyType, Cnt As Long

Private Sub ProcessRec(ByVal i As String)

Cnt = Cnt + 1
ReDim Preserve Mt(Cnt)
s = Split(i, ";")

    Mt(Cnt).someText = s(0)
    Mt(Cnt).a1 = s(1)
    Mt(Cnt).b1 = s(2)
    Mt(Cnt).c1 = s(3)
    Mt(Cnt).a2 = s(4)
    Mt(Cnt).b2 = s(5)
    Mt(Cnt).c2 = s(6)
    Mt(Cnt).a3 = s(7)
    Mt(Cnt).b3 = s(8)
    Mt(Cnt).c3 = s(9)
    Mt(Cnt).moreText = s(10)

    Print Mt(Cnt).someText
    Print Mt(Cnt).a1
    Print Mt(Cnt).b1
    Print Mt(Cnt).c1
    Print Mt(Cnt).a2
    Print Mt(Cnt).b2
    Print Mt(Cnt).c2
    Print Mt(Cnt).a3
    Print Mt(Cnt).b3
    Print Mt(Cnt).c3
    Print Mt(Cnt).moreText

End Sub

Private Sub Form_Load()
    Cnt = 0
    hf = FreeFile
    Open App.Path & "\abc.csv" For Input As #hf
    Do Until EOF(hf)
        Line Input #hf, i
        ProcessRec i
        Loop
    Close #hf
End Sub

Open in new window

1csv.zip
Theo KouwenhovenApplication Consultant

Author

Commented:
Hi vb_elmar,

Can you explain why I should reDim Mt if I need only one record to process?

What I need is:

Mt.abc(Cnt).a
Mt.abc(Cnt).b
Mt.abc(Cnt).c

Commented:
If there's only one record to process no ReDim is needed and the code looks like this:
Private Type MyType
    someText As String
    a1 As String
    b1 As String
    c1 As String
    a2 As String
    b2 As String
    c2 As String
    a3 As String
    b3 As String
    c3 As String
    moreText As String
End Type

Dim Mt(0) As MyType, Cnt As Long

Private Sub ProcessRec(ByVal i As String)

s = Split(i, ";")

    Mt(Cnt).someText = s(0)
    Mt(Cnt).a1 = s(1)
    Mt(Cnt).b1 = s(2)
    Mt(Cnt).c1 = s(3)
    Mt(Cnt).a2 = s(4)
    Mt(Cnt).b2 = s(5)
    Mt(Cnt).c2 = s(6)
    Mt(Cnt).a3 = s(7)
    Mt(Cnt).b3 = s(8)
    Mt(Cnt).c3 = s(9)
    Mt(Cnt).moreText = s(10)

End Sub

Private Sub Form_Load()
    Cnt = 0
    hf = FreeFile
    Open App.Path & "\abc.csv" For Input As #hf
    Do Until EOF(hf)
        Line Input #hf, i
        ProcessRec i
        Loop
    Close #hf
End Sub

Open in new window

Theo KouwenhovenApplication Consultant

Author

Commented:
Hi,

Dim Mt As MyType  is enough, don't need an index

Still need an array within the type:
    Mt.someText = s(0)
    Mt.abc(1).a = s(1)
    Mt.abc(1).b = s(2)
    Mt.abc(1).c = s(3)
    Mt.abc(2).a = s(4)
    Mt.abc(2).b = s(5)
    Mt.abc(2).c = s(6)
    Mt.abc(3).a = s(7)
    Mt.abc(3).b = s(8)
    Mt.abc(3).c = s(9)
    Mt.moreText = s(10)

or if that is to complex:

    Mt.someText = s(0)
    Mt.a(1) = s(1)
    Mt.b(1) = s(2)
    Mt.c(1) = s(3)
    Mt.a(2) = s(4)
    Mt.b(2) = s(5)
    Mt.c(2) = s(6)
    Mt.a(3) = s(7)
    Mt.b(3) = s(8)
    Mt.c(3) = s(9)
    Mt.moreText = s(10)
Commented:
Here is a sample (containing Mt without an index) :

'##############################################
Private Type Xabc
    a As String
    b As String
    c As String
End Type

Private Type MyType
    someText As String
    Abc(1 To 3) As Xabc
    moreText As String
End Type

Dim Mt As MyType

Private Sub ProcessRec(ByVal i As String)
    s = Split(i, ";")

    Mt.someText = s(0)
    Mt.Abc(1).a = s(1)
    Mt.Abc(1).b = s(2)
    Mt.Abc(1).c = s(3)
    Mt.Abc(2).a = s(4)
    Mt.Abc(2).b = s(5)
    Mt.Abc(2).c = s(6)
    Mt.Abc(3).a = s(7)
    Mt.Abc(3).b = s(8)
    Mt.Abc(3).c = s(9)
    Mt.moreText = s(10)

    MsgBox Mt.someText
    MsgBox Mt.Abc(1).a
    MsgBox Mt.Abc(1).b
    MsgBox Mt.Abc(1).c
    MsgBox Mt.Abc(2).a
    MsgBox Mt.Abc(2).b
    MsgBox Mt.Abc(2).c
    MsgBox Mt.Abc(3).a
    MsgBox Mt.Abc(3).b
    MsgBox Mt.Abc(3).c
    MsgBox Mt.moreText
End Sub

Private Sub Form_Load()
    Open App.Path & "\abc.csv" For Binary Access Read As #1
    ProcessRec Input(LOF(1), 1)
    Close #1
End Sub
abc.csv
Theo KouwenhovenApplication Consultant

Author

Commented:
COOL Dude

This is what I looked for, Now I have a XML like simulation of a CSV GREAT.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial