Click to See Complete Forum and Search --> : An array, collection, or object??? Need help!


mskvarenina
February 27th, 2000, 09:33 AM
I am writing an app that will load a matrix of accounts and document types from a detail file which may contain many accounts and many documents of the same type for each account. Basically all this will be loaded into a treeview with each account showing up only once as a parent, then each document type (only once) under that, and finally every document record read, stored uder the correct account and document type. So for example, I may have some raw data that may come in like this:

Account#, DocType, Date created
55555555, 2, 2/2/00
22222222, 1, 1/31/99
33333333, 1, 1/25/00
55555555, 2, 12/31/99
55555555, 2, 2/1/00
55555555, 1, 11/30/98

The ultimate goal would be to have the tree something like this:

22222222
---1
------1/31/99
33333333
---1
------1/25/00
55555555
---1
------11/30/98
---2
------12/31/99
------2/1/00
------2/2/00

So I am looking for the proper way to store this stuff so A)I can properly load the treeview without adding duplicates and B)so I can access the data at the document level (I simplifed this example, for the purposes of asking for help).

At first I thought I could use a multidimensional array. I would have a single dimension array with just accounts in it and search that array first to see what index a particular account is in. I would use the 2nd dimension to hold the document type. Problem is I don't know ahead of time if I will have 1 or 100 document types for a particular account and I don't want to make a big fixed size array and waste alot of memory.

What I really have here or would like I suppose is an array inside an array. In this approach I would have the account array holding the document type array (which could be a different size for each account).

So my actual question here is how would you implement this situation? I suppose the easiest would be to declare a large multi-dim array, but I wonder if I could use a collection or several collections, or even better, an object. I don't know much about objects yet but maybe there is some way to create one object for each account. I could still have my account array to determine if I 'have' that account already and if not create a new object with it's own array. Even with this approach however, how would I get down to that level, the array within the particular object when desired?

Thanks for taking the time to read all this and I hope you can help me find a solution!

Johnny101
February 27th, 2000, 04:29 PM
This scenario is saying to me - "User Defined Types". Any time i think i might have to a multidimensional array - i change it to a UDT. This way, you could even have one of the fields in the type, an array, say for the document list. You can not declare the size of the array and then when you are building the list use Redim Preserve (to preserve the data already in the array) and then just up the count by one each time. You could even then use an array of UDTs to hold all of the records to be inserted into the tree view control. Maybe a structure similar to this:

Type DocTypeStructure
Document as Integer
DateCreated() as date
End Type

Type TreeViewStrucure
AccountNo as string
DocType() as DocTypeStructure
End Type

public gudtTVWList() as TreeViewStructure




You would reference each property like you would a class object's properties:

Dim iUpBnd as Integer

'set the account number
gudtTVWList(index).AccountNo = "5555555"

'now get the count of items in the doctype array
iUpBnd = UBound(gudtTVWList(index).DocType)
iUpBnd = iUpBnd + 1

'stretch the array one more
ReDim Preserve gudtTVWList(index).DocType(iUpBnd)

'give it a value
gudtTVWList(index).DocType(inx2).Document = 2

'now this new item's date created values
iUpBnd = UBound(gudtTVWList(index).DocType(inx2).DateCreated)
iUpBnd = iUpBnd + 1

'stretch this array by one
ReDim Preserve gudtTVWList(index).DocType(inx2).DateCreated(iUpBnd)

'populate it.
gudtTVWList(index).DocType(inx2).DateCreated(iUpBnd) = "2/2/00"

'get the next create date for this doc type
iUpBnd = UBound(gudtTVWList(index).DocType(inx2).DateCreated)
iUpBnd = iUpBnd + 1

'stretch it by one
ReDim Preserve gudtTVWList(index).DocType(inx2).DateCreated(iUpBnd)

'give it a value
gudtTVWList(index).DocType(inx2).DateCreated(iUpBnd) = "12/31/99"



Or something like that. Obviously you want to put this in some sort of loop to fill the array.

Then to read the info back out to fill the treeview, start at the beginning of the array and go through all the records and read them in. The account number is the parent, then each array item with that account number is a child, the doctype is a child relationship to the account number parent. but each doctype is a parent to the date created field. you would have three nested loops to fill the tree view. one to go through the account numbers (the outermost loop), then one to go through the doctype array (first inner loop), and then one to go through the array of createdates (the inner most loop). Probably a series of For ... Next loops would be best, sine you can get the UBound of each array.

I hope this makes some sense. If i get some time to play with this, i see what i can do with some real code. The above was the first idea that i thought of.

Good luck,
john

John Pirkey
MCSD
www.ShallowWaterSystems.com

Ravi Kiran
February 27th, 2000, 07:34 PM
> I don't want to make a big fixed size array and waste alot of memory.

While a Doc class is a good idea, why have another copy of same data? i.e your recordset (or where ever you are storing the data) is one, then the treeview control which is going to hold the data is two, and then why the third?

By the way tree-view active x control is not all too optimised for memory. It is usually said that treeview and listview act.x controls, (that come with VB, which are a little different if you were to use the Common Control library directly, and create run-time ), actualy have 2 copies of the data.

So you could design a set of rules (ie functions) that take a treeview as a input, and assume the data would be present in a fashion, so that the data can be transformed back & forth. using treeview itself as data-storage. Each node has a tag property which is of Variant type. you can use this as placeholder for your data (of that node)

---

If you still want to have a Doc class, then
1. You can design each data set as Collection and have an array of collections.
ie each node data is Collection. and all the node data is a array.

'' module level
dim treedata() as Collection
'' local
Dim nddata as Collection
ReDim treedata(9) ' for ex.
for i = 0 to 9
set nddata = new Collection
nddata.Add string(5, Format(i))
nddata.Add 10 + i
nddata.Add CDate("1999/12/20") + i
set treedata(i) = nddata
next i




or simple: just a collection of collections also will do. This probably will give max benifit on memory ( assuming collection's header for vb's use, doesnt take much memory!)
ie above code will go as:
dim treedata as COllection
dim nddata as collection..
..
treedata.add nddata
--
The advantage in above technique is that you can have a different structure for each record, if required.

2. UDT will be faster, if you know the structure before hand, and if it going to remain same for all.

See the other post. gives a good example.

3. Array of vairants also can be tried, which is almost as array of Collection, with less programing hassels!.
dim treedata() as variant is a array of vaiants. so that each element itself can be an array of varying lengths.
same example above :

'in Declarations
Dim treedata1() as Variant
'' elsewhere
Dim ar1(9) as string
Dim ar2(15) as Integer, ar3(5) as date
for i = 0 to 9
ar1(i) = string(5, Format(i))
next i
for i = 0 to 15
ar2(i) = 10 + i
next i
for i = 0 to 5
ar3(i) = CDate("1999/12/20") + i
next i
ReDim treedata1(3) as Variant
treedata1(0) = ar1
treedata1(1) = ar2
treedata1(2) = ar3





RK