TheSwamp
Code Red => VB(A) => Topic started by: Guest on May 02, 2008, 01:35:20 PM
-
I've got a program that I'm working on that I need to create a list of information. Based on the various searches I've done, I'm probably now more confused than ever before. I'm not sure what the best way to do this is (scripting dictionary, array, collection, etc...) but I'd like to learn how to do it using an arrray.
So here's the scoop...
The program I'm working on will create a series of drawings and add various layout tabs to them. And so for starters, I need to gather the drawing information based on file names and what layout tabs are associated with them.
For example: Drawing 'A' could have layout tabs 'A', 'B', 'C'. Drawing 'B' could have layout tabs 'A1', 'A2', 'A3', 'A4', 'A5' and so on and so forth.
I'm currently gathering the information from the listview box of my program (see attached DVB). When you click the "CREATE PROJECT FILES" button, it loops through the entries in the listview. But what I need to do is gather the information as follows:
Drawing 'A'
Layout tab 'A'
Layout tab 'B'
Layout tab 'C'
Drawing 'B'
Layout tab 'A1'
Layout tab 'A2'
Layout tab 'A3'
Layout tab 'A4'
Layout tab 'A5'
And so on....
So do I need to do an array of arrays (as if a simple array isn't giving me enough grief)?? I hope this makes sense.
-
One way to do it would be with a collection. You could create a DwgInfo object that has a Name (Drawing A) and has a collection where you could store the layout names.
Something like this:
In a class module called DwgInfo
Option Explicit
Private colLayouts As Collection
Private mName As String
Private Sub Class_Initialize()
Set colLayouts = New Collection
End Sub
Public Sub add(LayoutName As String)
colLayouts.add LayoutName
End Sub
Public Sub remove(LayoutName As String)
colLayouts.remove (LayoutName)
End Sub
Public Property Get Count() As Integer
Count = colLayouts.Count
End Property
Public Property Let Name(dwgName As String)
mName = dwgName
End Property
Public Property Get Name() As String
Name = mName
End Property
Public Function Item(index As Integer) As String
Item = colLayouts.Item(index)
End Function
Then in a code module:
Public Sub Test()
Dim dwg1 As DwgInfo
Dim dwg2 As DwgInfo
Dim colDwg As Collection
Dim i As Integer
Set colDwg = New Collection
Set dwg1 = New DwgInfo
Set dwg2 = New DwgInfo
dwg1.Name = "Drawing A"
dwg1.add ("A")
dwg1.add ("B")
dwg1.add ("C")
dwg2.Name = "Drawing B"
dwg2.add ("A1")
dwg2.add ("A2")
dwg2.add ("A3")
For i = 1 To dwg1.Count
'do your stuff here
Debug.Print dwg1.Item(i)
Next i
For i = 1 To dwg2.Count
'do your stuff here
Debug.Print dwg2.Item(i)
Next i
End Sub
Also, in your code module, you could have another collection to hold the dwgInfo objects and then iterate that collection to do your magic.
If you use arrays, you will have to resize them to add elements where collections might be slower, but they are easier to use for dynamically sized data.
Just my 2 cents.
-
I'm not sure collections would be the way to go because 1) the number of drawings/layout tabs will vary based and 2) how do you determine if an item is already in a collection? There is no EXISTS function. Would that be a separate function altogether?
I'd really like to figure out this array stuff. It's driving me crazy.
Thanks for your input.
-
Tuoni:
Here's the code behind the CREATE PROJECT FILES button.
Private Sub cmdSetup_Click()
Dim i As Integer
Dim intFileNumber As Integer
Dim strLayout As String, strFileName As String
For i = 1 To lvTech.ListItems.Count
intFileNumber = lvTech.ListItems(i)
strLayout = lvTech.ListItems(i).ListSubItems(1)
strFileName = lvTech.ListItems(i).ListSubItems(3)
Debug.Print strFileName
Debug.Print strLayout
Next i
End Sub
And this is what it spits out at the immediate window.
0004000-T-NOT.dwg
T-000
0004000-T-COMM-1.dwg
TC-101
0004000-T-COMM-1.dwg
TC-102
0004000-T-COMM-2.dwg
TC-201
0004000-T-COMM-2.dwg
TC-202
0004000-T-SECY-1.dwg
TS-101
0004000-T-SECY-1.dwg
TS-102
0004000-T-SECY-2.dwg
TS-201
0004000-T-SECY-2.dwg
TS-202
0004000-T-SITE.dwg
TS-000
0004000-T-PART.dwg
TC-301
0004000-T-PART.dwg
TC-302
0004000-T-RISR.dwg
TC-401
0004000-T-RISR.dwg
TC-402
0004000-T-DETL.dwg
TC-501
0004000-T-DETL.dwg
TC-502
0004000-T-DETL.dwg
TC-503
0004000-T-DETL.dwg
TC-504
This is based on what you see in the image in my first post.
-
If I'm understanding what you're aiming for correctly (which I'm possibly not...) the code posted by David Blackmon would appear to do exactly what you want - for each drawing, create a new DwgInfo object and add the layouts to it and then add it to a collection. You could write an exists property which loops through the collection if needs be?
-
If I'm understanding what you're aiming for correctly (which I'm possibly not...) the code posted by David Blackmon would appear to do exactly what you want - for each drawing, create a new DwgInfo object and add the layouts to it and then add it to a collection. You could write an exists property which loops through the collection if needs be?
Would a collection be the best way to go about doing this? Or would an array be better? Just curious.
-
And another question...
Dim dwg1 As DwgInfo
Dim dwg2 As DwgInfo
The code provided has 2 dimmed. How can I, I guess, "dim" more on the fly as I encounter more drawings?
It's been a long and I've been staring at this code for hours and it's all becoming a blur, so forgive me if I'm asking "stupid" questions. :oops:
-
If I'm understanding what you're aiming for correctly (which I'm possibly not...) the code posted by David Blackmon would appear to do exactly what you want - for each drawing, create a new DwgInfo object and add the layouts to it and then add it to a collection. You could write an exists property which loops through the collection if needs be?
Would a collection be the best way to go about doing this? Or would an array be better? Just curious.
Depends what you want to do with them, really. Collections have a couple of advantages over arrays - adding to them is easy enough and unlike arrays you don't have to worry about how full it is, whether you have space, whereabouts that space is; secondly you can refer to items in a collection by index or by key, arrays you can only use index... Collections are theoretically slower than arrays, however I doubt you'd notice. One thing to keep in mind, though, is that collections' indexing starts at 1, not 0
-
And another question...
Dim dwg1 As DwgInfo
Dim dwg2 As DwgInfo
The code provided has 2 dimmed. How can I, I guess, "dim" more on the fly as I encounter more drawings?
It's been a long and I've been staring at this code for hours and it's all becoming a blur, so forgive me if I'm asking "stupid" questions. :oops:
You should be able to create the object within the loop, like so: (note, untested)
Public Sub Test()
Dim dwg As DwgInfo
Dim colDwg As Collection
Dim i As Integer
Dim j As Integer
Set colDwg = New Collection
For i = 1 To lvTech.ListItems.Count
Set dwg = new DwgInfo
dwg.Name = lvTech.ListItems(i).ListSubItems(3)
For j = 1 To dwg.Count
dwg.add( -insert the code for the layout in here- )
Next j
colDwg.add(dwg)
Next i
End Sub
Something like that, anyways. You'll need to do some sanity checking on that - again, untested
-
You can dim one variable and use it over and over
Public Sub Test()
Dim dwg1 As DwgInfo
Dim dwg2 As DwgInfo
Dim colDwg As Collection
Dim i As Integer
Dim j As Integer
Set colDwg = New Collection
Set dwg1 = New DwgInfo
Set dwg2 = New DwgInfo
'loop thru the possible drawing names here and add them to the colDwg
For i = 1 To 5
Set dwg1 = New DwgInfo
'add another loop here to add each layout to the dwg1 object
dwg1.Name = "Drawing A" + Str(i)
dwg1.add ("A" + Str(i))
dwg1.add ("B" + Str(i))
dwg1.add ("C" + Str(i))
colDwg.add dwg1
Set dwg1 = Nothing
Next i
For i = 1 To 5
Set dwg2 = colDwg.Item(i)
For j = 1 To dwg2.Count
Debug.Print dwg2.Item(j)
Next j
Next i
End Sub
-
Oops. Tuoni beat me to it
-
Oops. Tuoni beat me to it
Good to see I wasn't imagining that process :-D Been a while since I've played with this here language!
-
..... Been a while since I've played with this here language!
Me too. I tried to put semi-colon at the end of every line :-D
-
..... Been a while since I've played with this here language!
Me too. I tried to put semi-colon at the end of every line :-D
:-)
-
..... Been a while since I've played with this here language!
Me too. I tried to put semi-colon at the end of every line :-D
I deleted mine just before I posted :lol:
-
Dear Matt,
another way is to use Type
something like (not tested, may some mistakes)
Option Explicit
Type FileInfoRecord
a As String
b As String
c As String
End Type
Sub FillArrayWithRecords()
Dim ListViewRow As FileInfoRecord
ReDim ListViewRows(5) As FileInfoRecord
Dim i, k
For i = 0 To 5
ListViewRow.a = "T-0" & CStr(i + 1)
ListViewRow.b = "Technology " & CStr(i + 1)
ListViewRow.c = "000400-" & CStr(i + 1) & ".dwg"
ListViewRows(i) = ListViewRow
Next
MsgBox "Last row is: " & vbCr & _
ListViewRows(i).a & vbCr & _
ListViewRows(i).b & vbCr & _
ListViewRows(i).c
i = UBound(ListViewRows)
ReDim Preserve ListViewRows(i + 5)
For k = i + 1 To i + 5
ListViewRow.a = "T-0" & CStr(k)
ListViewRow.b = "Technology " & CStr(k)
ListViewRow.c = "000400-" & CStr(k) & ".dwg"
ListViewRows(i) = ListViewRow
Next
MsgBox "Now Last row is: " & vbCr & _
ListViewRows(k).a & vbCr & _
ListViewRows(k).b & vbCr & _
ListViewRows(k).c
End Sub
Regards,
~'J'~
-
ARRRGH! I was just going to submit some UDT (User-Defined-Type) code, but was beaten to the punch. However, to build on that code, you can nest the TYPES, and have arrays within them ... (warning - code typed on the fly)
Type Layout
LayoutName as String
ParentDoc as AcadDocument
End type
Type DwgInfo
PathSpec as String
LayoutCount as Long
Layouts() as Layout
End Type
Dim DocCount as long
Dim DocArray(DocCount) as DwgInfo
; ... and you can access the properties like such...
Dim I as Long, J as Long
For I=0 to Ubound(DocArray)
Debug.print "Document:";DocCount(I).PathSpec
For J=0 to LayoutCount
Debug.print,,"Layout Name:";DocCount(I).Layouts(J).LayoutName
Next J
Next I
... of course, you'd have to check for/set empty arrays
-
Matt: where did you get to on this? Just curious :-)
-
Matt: where did you get to on this? Just curious :-)
Not very far. :-(
-
Matt: where did you get to on this? Just curious :-)
Not very far. :-(
:( Time constraints or still struggling with the code?
-
Matt: where did you get to on this? Just curious :-)
Not very far. :-(
:( Time constraints or still struggling with the code?
Yes. :-)
-
Matt: where did you get to on this? Just curious :-)
Not very far. :-(
:( Time constraints or still struggling with the code?
Yes. :-)
Good answer ;)
-
Matt, I generally use arrays to hold my arrays rather than collections (speed issues as previously noted) but it is because I generally don't have to handle specific items.
If you create a master array, you can call it that if you like, to keep them straight, then each of your subordinate arrays can be added dynamically and the array can grow as needed.
Although I have to admit I like the dwgInfo class ...
I guess my confusion is why you would want to store the drawing information when you could just as easily get the info from the drawing.
-
Matt, I generally use arrays to hold my arrays rather than collections (speed issues as previously noted) but it is because I generally don't have to handle specific items.
If you create a master array, you can call it that if you like, to keep them straight, then each of your subordinate arrays can be added dynamically and the array can grow as needed.
Although I have to admit I like the dwgInfo class ...
I guess my confusion is why you would want to store the drawing information when you could just as easily get the info from the drawing.
I can't get the info from the drawings because the drawings don't exist yet. Basically what the program will do is create each of the drawings listed in the File Name column and create the layout tab(s) listed in the Sheet No column. So for the details sheet (0004000-T-DETL.dwg) there would be four layout tabs within that drawing (TC-501 to TC-504). So what I'm envisioning is an array (or array of arrays) that will hold (1) the values in the File Name column - no duplicates and (2) the values in the Sheet No column that are associated with the values in the File Name column. Make sense? I'm thinking this will speed things up since I would be able to loop through the arrays and (1) open the newly created file (the value in the File Name column) and then (2) create the layout tabs associated with that file from the array.
I could simply loop through the values of the listview but that would mean opening the details drawing four times and adding a layout tab each time.
Do you understand what I'm getting at now? I hope I explained that clearly - of course, I know what I'm talking about (in my head). Sometimes I have problems conveying the information in a clear manner. :oops:
-
Ah .. very clear now .. You could use a treeview to organize each layout in under each drawing.
-
Ah .. very clear now .. You could use a treeview to organize each layout in under each drawing.
Hmmm..... might not be a bad idea. Although... I'm already THIS far along - I don't really feel like re-writing a whole bunch of stuff. Still... it's a good idea.
-
been there done that ...
-
This any good?
-
This any good?
I'm trying to piece this together (bear with me)... :-)
So you've got this code (which I think I'm starting to understand now).
Dim dwg As DwgInfo
Dim i As Integer
Dim j As Integer
Set colDwg = New Collection
For i = 1 To lvTech.ListItems.Count
'Check if the filename has already been made
If dwgInfoExists(lvTech.ListItems(i).ListSubItems(3)) = True Then
'Add this layout to the DwgInfo
colDwg.Item(dwgInfoIndex(lvTech.ListItems(i).ListSubItems(3))).add (lvTech.ListItems(i).ListSubItems(1))
Else
'Make a new one
Set dwg = New DwgInfo
dwg.Title = lvTech.ListItems(i).ListSubItems(2)
dwg.fileName = lvTech.ListItems(i).ListSubItems(3)
dwg.add (lvTech.ListItems(i).ListSubItems(1))
colDwg.add dwg
End If
Next i
The part that's throwing me for a loop (no pun intended - hehehe) is iterating through the info to show what belongs where.
I've got this (so far)...
Dim x As Integer
Dim y As Integer
For x = 1 To colDwg.Count
For y = 1 To dwg.Count
Debug.Print dwg.Item(y)
Next y
Next x
If I understand this correctly, I need to loop through 'colDwg' and then within that loop, loop through the 'dwg' info to determine the layout names that are associated with the file names, right?
And so when I run this I get a bunch of the same thing printed at the immediate window. What am I missing (besides the obvious probably)? :ugly:
-
<snip>
The part that's throwing me for a loop (no pun intended - hehehe) is iterating through the info to show what belongs where.
I've got this (so far)...
Dim x As Integer
Dim y As Integer
For x = 1 To colDwg.Count
For y = 1 To dwg.Count
Debug.Print dwg.Item(y)
Next y
Next x
If I understand this correctly, I need to loop through 'colDwg' and then within that loop, loop through the 'dwg' info to determine the layout names that are associated with the file names, right?
And so when I run this I get a bunch of the same thing printed at the immediate window. What am I missing (besides the obvious probably)? :ugly:
You're not reassigning "dwg" at any point in the loop - therefore dwg still refers to the last object you pushed into the collection (assuming, of course, you're running it in the button's sub)
-
You're not reassigning "dwg" at any point in the loop - therefore dwg still refers to the last object you pushed into the collection (assuming, of course, you're running it in the button's sub)
I think I've got it.
Dim x As Integer
Dim y As Integer
For x = 1 To colDwg.Count
Set dwg = colDwg.Item(x)
Debug.Print dwg.fileName
For y = 1 To dwg.Count
Debug.Print dwg.Item(y)
Next y
Next x
Which will give me...
0004000-T-NOT.dwg
T-000
0004000-T-COMM-1.dwg
TC-101
TC-102
0004000-T-SECY-1.dwg
TS-101
TS-102
0004000-T-SITE.dwg
TS-000
0004000-T-PART.dwg
TC-201
TC-202
0004000-T-RISR.dwg
TC-301
TC-302
0004000-T-DETL.dwg
TC-401
TC-402
TC-403
TC-404
Which is what I wanted to do from the beginning.
Man, I wasn't even CLOSE with what I was trying to do originally!! I had started with creating a collection and then trying to add arrays to each item which only got me more confused.
I'm going to continue to disect this stuff (especially 'dwgInfoExists' and 'dwgInfoIndex') to get a better understanding of what's going on so I won't have to ask/beg/plead for help with something like this in the future. I owe you one. Thanks.
-
You're not reassigning "dwg" at any point in the loop - therefore dwg still refers to the last object you pushed into the collection (assuming, of course, you're running it in the button's sub)
I think I've got it.
Dim x As Integer
Dim y As Integer
For x = 1 To colDwg.Count
Set dwg = colDwg.Item(x)
Debug.Print dwg.fileName
For y = 1 To dwg.Count
Debug.Print dwg.Item(y)
Next y
Next x
Which will give me...
0004000-T-NOT.dwg
T-000
0004000-T-COMM-1.dwg
TC-101
TC-102
0004000-T-SECY-1.dwg
TS-101
TS-102
0004000-T-SITE.dwg
TS-000
0004000-T-PART.dwg
TC-201
TC-202
0004000-T-RISR.dwg
TC-301
TC-302
0004000-T-DETL.dwg
TC-401
TC-402
TC-403
TC-404
Which is what I wanted to do from the beginning.
Man, I wasn't even CLOSE with what I was trying to do originally!! I had started with creating a collection and then trying to add arrays to each item which only got me more confused.
I'm going to continue to disect this stuff (especially 'dwgInfoExists' and 'dwgInfoIndex') to get a better understanding of what's going on so I won't have to ask/beg/plead for help with something like this in the future. I owe you one. Thanks.
Not a problem! Glad it works - the code I gave you could probably do with a clean up or there may be a more efficient way of doing what I'm doing or something (for instance, you could combine 'dwgInfoExists' and 'dwgInfoIndex' so that it returns just the index, or -1 if it's not in there, meaning you only iterate once)... but it works :) I'm glad it's what you were looking for, sorry it took me so long to help you out!