Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 7,247
Default Class Instance Identifier

Art,

You can create a class module, say Class1, with the properties
you need, including a field called Key. Then, add the instances
of the class to a Collection object, using the Key property of
the class as the key to the collection. E.g,

Dim Coll As Collection

Sub AAA()
Dim C1 As Class1
If Coll Is Nothing Then
Set Coll = New Collection
End If
Do Until somthing
Set C1 = New Class1
C1.Field1 = "whatever"
C1.Key = "KeyName"
Coll.Add C1, C1.Key
Loop
End Sub



--
Cordially,
Chip Pearson
Microsoft MVP - Excel
Pearson Software Consulting, LLC
www.cpearson.com



"Art" wrote in message
...
Hi,

I need a collection for about 50 things. I'm assuming that a

sensible way to do this is to create a class where I can have a
bunch of properties for each of the instances, and instantiate it
about 50 times.

I'd like to create each instance with a "key" so that I can

refer to specific instances as necessary.

It may be that there's a way to create a data structure instead

of a class or to create a collection.

Can anyone suggest anything?

Art



  #2   Report Post  
Posted to microsoft.public.excel.programming
Art Art is offline
external usenet poster
 
Posts: 587
Default Class Instance Identifier

Chip,

Thanks very much that was very helpful. Can I reference specific instances of the class without using the collection object? For example, I'm guessing that I could create a bunch of instances, then using a "for each" look for the one I want, and then extract the information. Assuming that would work, I'd still like to know if there's a better way.

Art

"Chip Pearson" wrote:

Art,

You can create a class module, say Class1, with the properties
you need, including a field called Key. Then, add the instances
of the class to a Collection object, using the Key property of
the class as the key to the collection. E.g,

Dim Coll As Collection

Sub AAA()
Dim C1 As Class1
If Coll Is Nothing Then
Set Coll = New Collection
End If
Do Until somthing
Set C1 = New Class1
C1.Field1 = "whatever"
C1.Key = "KeyName"
Coll.Add C1, C1.Key
Loop
End Sub



--
Cordially,
Chip Pearson
Microsoft MVP - Excel
Pearson Software Consulting, LLC
www.cpearson.com



"Art" wrote in message
...
Hi,

I need a collection for about 50 things. I'm assuming that a

sensible way to do this is to create a class where I can have a
bunch of properties for each of the instances, and instantiate it
about 50 times.

I'd like to create each instance with a "key" so that I can

refer to specific instances as necessary.

It may be that there's a way to create a data structure instead

of a class or to create a collection.

Can anyone suggest anything?

Art




  #3   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 593
Default Class Instance Identifier

Art wrote ...

Can I reference specific instances of the class without
using the collection object?


It depends on what your objects actually are (remember: software
development is about modelling reality).

The classic example is the Bicycle class. Should you have a collection
class called Wheels? The answer is no because all bicycles have only
two wheels. Best to have two members (e.g. Properties), FrontWheel and
BackWheel. On the other hand, a Spokes collection class is justified
because not all bicycle wheels have the same number of spokes. So the
general rule is, use a collection where the number of objects is
indeterminable and use individual members where the number is
predetermined.

However, this can be 'inconvenient' for the coder. If in your reality
you always have 50 distinct objects (I can only think you would be
modelling the Ways To Leave Your Lover <g), it may make more 'sense'
to have 50 individual object variables but easier to code if they
could be accessed collectively. For example, if I was modelling a card
game I might have a parent Deck object with an 52 internal instances
of my Card class, persists them in an array of type Card consisting 52
elements and probably have an enumeration to refer to the cards:
1ofSpades, 2ofSpades, and so on, plus methods to retrieve the next
card to be dealt etc.

If 'about 50 things' means the number of objects varies then a
collection is convenient because you can just keep adding objects as
needed, just like a stack. Note there are more complex container
objects available to the VBA programmer e.g. the Dictionary object
allows you to enumerate keys (a Collection does not and that's why I
assume Chip advised you to make Key a property of the class) and if
you want some advanced functionality such as filtering and sorting
then an fabricated (disconnected) ADO recordset works well (hint: for
objects set the Field.Type = IUnknown).

Even collections are 'complex' enough to justify wrapping in a custom
collection class. When you have a collection class, it's convenient to
also have a parent class. And before you know it you start building an
object hierarchy just like Excel's:

Application.Workbooks.Item("Book1").Worksheets.Ite m(1).Range("A1").Borders(xlEdgeLeft)

Application the parent object and is an instance of type
'Application', which has a Workbooks property, which returns a
collection class object of type 'Workbooks', which has an Item method
(i.e. wraps its internal Collection object's Item method), which
returns an object of type 'Workbook', which has a Worksheets property,
which returns a collection class object of type 'Worksheets' etc.

Workbooks is a collection because you can have an indeterminate number
of workbooks open within an Excel app. However Borders is a collection
even though the number of borders is predetermined and the Excel
developers have provided an enumeration for each border type (look in
the VBE's Object Browser for XLBordersIndex).

As I say, it all depends on what you are modelling.

Jamie.

--
  #4   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 599
Default Class Instance Identifier

Art

How do determine which one you want? By the key? Here's a short example of
how you might do it.

In a class module named Class1, key property and 3 other properties and a
ResetProps method.

Dim mKey As String
Dim mProp1 As String
Dim mProp2 As String
Dim mProp3 As String

Property Get Key() As String
Key = mKey
End Property

Property Let Key(sKey As String)
mKey = sKey
End Property

Property Get prop1() As String
prop1 = mProp1
End Property

Property Let prop1(sProp1 As String)
mProp1 = sProp1
End Property

Property Get Prop2() As String
Prop2 = mProp2
End Property

Property Let Prop2(sProp2 As String)
mProp2 = sProp2
End Property

Property Get Prop3() As String
Prop3 = mProp3
End Property

Property Let Prop3(sProp3 As String)
mProp3 = sProp3
End Property

Sub ResetProps()
mProp1 = ""
mProp2 = ""
mProp3 = ""
End Sub

In a standard module, a public collection variable, a sub to store your
class1 instances in the collection variable, a sub to create the class, and
a sub to work with the class

Public colClass As Collection

Sub CallInst()

Dim clsVar As Class1

Set clsVar = New Class1
clsVar.Key = "First"
StoreObject clsVar, clsVar.Key

End Sub

Sub StoreObject(cObject As Class1, sName As String)

If colClass Is Nothing Then
Set colClass = New Collection
End If

colClass.Add cObject, sName

End Sub

Sub WorkWithClass()

colClass("first").ResetProps

With colClass("first")
Debug.Print Len(.prop1), Len(.Prop2), Len(.Prop3)
End With

End Sub

The CallInst sub is just there to simulate whatever you're doing. Where
ever in your code that you create the class, you can call the StoreObject
sub to put it in the collection. You can get to collection elements using
the key, so you can use your class properties and methods directly from the
collection object as shown in WorkWithClass.

If you have a need to set some variables to empty string, you can set up a
method in your class, which is just a Sub procedure, to do that.

You can iterate through all your class instances by iterating through the
collection elements. If, for instance, you want all of you class instance
properties to be zero length strings,

Dim vItem As Variant

For Each vItem In colClass
vItem.ResetProps
Next vItem

--
Dick Kusleika
MVP - Excel
Excel Blog - Daily Dose of Excel
www.dicks-blog.com

"Art" wrote in message
...
Jamie,

Thanks for taking the time to put all of that information together. In my

particular case the number of things (members or objects) will vary from
month to month. Form what I've seen of the collection object, and from
Chip's post, it looks like I first have to structure my objects using a
class. Only then can I add them to my collection.

What the collection seems to be missing is "methods". For example I'd

like to take one instance (if I instantiated objects) and set 5 of the
properties to an empty string. I don't know how I'd do this with a
collection without iterating in my code whenever I want to do this - or of
course setting up a sub procedure that gets passes a parameter.

I was hoping I could create the class, instantiate as many times as I have

to, and then work with it that way. I would need to be able to "zero in" on
particular instances in order to carry out my work. The only way I know how
to do this (I think) is to iterate through the instances until I find the
one I want - then do whatever I need to do with that particular instance.

Thanks for the help

Art



  #5   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 593
Default Class Instance Identifier

"Dick Kusleika" wrote ...

How do determine which one you want? By the key? Here's a short example of
how you might do it. <snip


The key is usually the object's Name, isn't it?

As you could probably tell from my last post, I prefer the collection
code to be wrapped in a class too. Also, a parent class comes in handy
e.g. to run the same code on all the child objects.

I'll call my parent object a 'table' and each child object a 'column'
and I'll use a 'columns' collection class because a table can have
zero or more columns, making a total of three classes.

Columns aren't instantiated directly; instead the collection class has
an Add method that creates the child object for me. I'll borrow Dick
K's Prop1, Prop2 and Prop3 but make them writable only when creating a
column. I'll additionally have a ClearAll property at the parent
level i.e. to clear properties in all columns.

The extra code makes the code in the workbook simpler to write and
easier on the eye (can be made even nicer by make Item the default
property of the collection class and enable For Each loops but the
process is a bit controversial in this ng <g).


' ---<ThisWorkbook code module---
Option Explicit

Private m_Table As CTable

Private Sub Workbook_Open()

Dim oCol As CColumn

' Instantiate *only* the parent object
Set m_Table = New CTable

' Create columns by adding
m_Table.Columns.Add "ColA", "Norarules", "Hevitoxic", "Pipesagap"
m_Table.Columns.Add "ColB", "Luxasonic", "Katewudes"
Set oCol = m_Table.Columns.Add("ColC", "Tinatotac")

' Do things with the objects
MsgBox oCol.Name

MsgBox m_Table.Columns.Item(1).Prop1

MsgBox m_Table.Columns.Item("ColB").Prop2

m_Table.ClearAll

MsgBox m_Table.Columns.Item("ColB").Prop2

End Sub
' ---</ThisWorkbook code module---


' ---<Code in CTable class module---
Option Explicit

Private m_Columns As CColumns
Private m_strName As String

Private Sub Class_Initialize()
Set m_Columns = New CColumns
End Sub

Public Property Get Name() As String
Name = m_strName
End Property

Public Function Init( _
ByVal Name As String _
) As Boolean

m_strName = Name
Init = True
End Function

Public Property Get Columns() As CColumns
Set Columns = m_Columns
End Property

Public Function ClearAll() As Boolean
Dim lngCounter As Long
With m_Columns
For lngCounter = 1 To .Count
.Item(lngCounter).ClearAll
Next
End With
End Function
' ---<Code in CTable class module---


' ---<Code in CColumns class module---
Option Explicit

Private m_colColumns As Collection

Public Property Get Item(ByVal Index As Variant) As CColumn
On Error Resume Next
Set Item = m_colColumns.Item(Index)
End Property

Public Function Add( _
ByVal ColumnName As String, _
Optional ByVal Prop1 As String, _
Optional ByVal Prop2 As String, _
Optional ByVal Prop3 As String _
) As CColumn

Dim oColumn As CColumn

Set oColumn = New CColumn

On Error Resume Next

m_colColumns.Add oColumn, ColumnName

oColumn.Init ColumnName, _
Prop1, Prop2, Prop3

Set Add = oColumn

End Function

Public Property Get Count() As Long

Count = m_colColumns.Count

End Property

Public Function Remove(ByVal Index As Variant) As Boolean

On Error Resume Next
m_colColumns.Remove Index
Remove = (Err.Number = 0)
On Error GoTo 0

End Function

Private Sub Class_Initialize()
Set m_colColumns = New Collection
End Sub
' ---</Code in CColumns class module---


' ---<Code in CColumn class module---
Option Explicit

Private m_strName As String
Private m_strProp1 As String
Private m_strProp2 As String
Private m_strProp3 As String

Public Function Init( _
ByVal Name As String, _
Optional ByVal Prop1 As String, _
Optional ByVal Prop2 As String, _
Optional ByVal Prop3 As String _
) As Boolean

m_strName = Name
m_strProp1 = Prop1
m_strProp2 = Prop2
m_strProp3 = Prop3

Init = True
End Function

Public Property Get Name() As String
Name = m_strName
End Property

Public Property Get Prop1() As String
Prop1 = m_strProp1
End Property

Public Property Get Prop2() As String
Prop2 = m_strProp2
End Property

Public Property Get Prop3() As String
Prop3 = m_strProp3
End Property

Public Function ClearAll() As Boolean
m_strProp1 = vbNullString
m_strProp2 = vbNullString
m_strProp3 = vbNullString
End Function
' ---</Code in CColumn class module---


Jamie.

--


  #6   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 599
Default Class Instance Identifier

Jamie

The extra code makes the code in the workbook simpler to write and
easier on the eye (can be made even nicer by make Item the default
property of the collection class and enable For Each loops but the
process is a bit controversial in this ng <g).


Is it? I don't use it because I'm lazy. As soon as someone writes a
utility to add that attribute, I'll use if every time.

--
Dick Kusleika
MVP - Excel
Excel Blog - Daily Dose of Excel
www.dicks-blog.com


  #7   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 593
Default Class Instance Identifier

"Dick Kusleika" wrote ...

make Item the default
property of the collection class and enable For Each loops but the
process is a bit controversial in this ng <g


Is it?


I got 'told off' by a regular about this, something about Notepad not
being part of VBA. We're friends again now :-)

I don't use it because I'm lazy. As soon as someone writes a
utility to add that attribute, I'll use if every time.


I have a ready-rolled collection class (text) that I use as a
template. You see, I'm lazy too <g.

Jamie.

--
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Unique identifier Steve Barnett Excel Discussion (Misc queries) 19 January 6th 06 11:26 AM
Unique identifier Steve Barnett Excel Worksheet Functions 18 January 6th 06 11:26 AM
Sheet Protection Identifier CLR[_2_] Excel Programming 8 June 4th 04 11:53 AM
Unique Identifier? RPIJG[_3_] Excel Programming 1 May 11th 04 05:36 PM
RaiseEvent from a class contained in a 2nd class collection? Andrew[_16_] Excel Programming 2 January 6th 04 04:22 PM


All times are GMT +1. The time now is 03:32 AM.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright ©2004-2024 ExcelBanter.
The comments are property of their posters.
 

About Us

"It's about Microsoft Excel"