-
August 16th, 2005, 04:19 AM
#1
Array inside a collection
Hi,
I have a class which is used to store customer information. For each customer there may be multiple contacts. How can I record this in a collection class. I've tried to do so as follows:
Code:
' CCustomerInfo -> stores one customer record
Public CompanyID As Long
Public CompanyName As String
Public CompanyAddress As String
Public CompanyFaxNumber As String
Public GeneralSupportExpiryDate As String
Public HardwareSupportExpiryDate As String
Public Contacts() as String <---- Error here
Code:
' CCustomerInfos -> collection of CCustomerInfo objects
' this is how I add objects to the collection to the class
' not trying to add contacts() yet as I can't declare it correctly
Public Function Add(CompanyID As Long, CompanyName As String, CompanyAddress As String, CompanyFaxNumber As String, GeneralSupportExpiryDate As String, HardwareSupportExpiryDate As String, Optional sKey As String) As CCustomerInfo
Dim objNewMember As CCustomerInfo
Set objNewMember = New CCustomerInfo
With objNewMember
.CompanyID = CompanyID
.CompanyName = CompanyName
.CompanyAddress = CompanyAddress
.CompanyFaxNumber = CompanyFaxNumber
.GeneralSupportExpiryDate = GeneralSupportExpiryDate
.HardwareSupportExpiryDate = HardwareSupportExpiryDate
End With
If Len(sKey) = 0 Then
mCol.Add objNewMember
Else
mCol.Add objNewMember, sKey
End If
Set Add = objNewMember
Set objNewMember = Nothing
End Function
The error message is as follows
Code:
"Constants, fixed-length strings, arrays, user-defined types and Declare statements not allowed as Public members of object modules"
Can anyone suggest a way to make this work? Thanks very much in advance.
Sorry for the lengthy post!
dhartigan
-
August 16th, 2005, 05:51 AM
#2
Re: Array inside a collection
What I normally do is use a UDT, and declare it as an array. However, if you need access to the data from outside the project, as in a dll or ActiveX component that other programs can use, then you can put the UDT into a class.
If you want to use a class, then you can make the variables Private, and provide access to the values via Public properties. This also has the benefit of being able to validate the values before assigning to the member, so as to avoid invalid data.
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
-
August 16th, 2005, 05:57 AM
#3
Re: Array inside a collection
make contacts a collection of properties in it's own class.
Otherwise try:
private m_strContacts() as string
Public Property Let Contacts(ByVal vNewValue As String)
'need to test here for presence of at least 1 element though otherwise
'redim preserve will error
redim preserve m_strContacts(ubound(m_strContacts) + 1)
m_strContacts(ubound(m_strContacts)) = vNewValue
End Property
Public Property Get Contacts() As String
'where i below will be the element you want to pass back and probably set somewhere else in code.
Contacts = m_strContacts(i)
End Property
also for encapsulation purposes you should not declare your variables as public, but instead expose them through properties.
Last edited by Bill Crawley; August 16th, 2005 at 05:59 AM.
If you find my answers helpful, dont forget to rate me
-
August 16th, 2005, 09:19 AM
#4
Re: Array inside a collection
Hi,
Thanks for the quick responses.
I now have the following in a module:
Code:
Public Type Contact
Name As String
PhoneNumber As String
Email As String
End Type
I have this in my Customer class:
Code:
Private m_objContacts() As Contact
Public Property Get Contacts() As Contact() <--- Error here
Set Contacts = m_objContacts()
End Property
Public Property Set Contacts(objcontacts() As Contact)
Set m_objContacts() = objcontacts
End Property
Now I get an error saying:
Code:
Only public user defined types defined in public object modules can be used as parameters or return types for public procedures of class modules or as fields of public user defined types
Can someone tell me what I've done wrong or how to correct the mistake?
Thanks very much,
dhartigan
-
August 16th, 2005, 10:31 AM
#5
Re: Array inside a collection
This looks like a problem of handling the classes.
I would recommend this
- create for every class (Prefix cls here) that is / would be used in a 1:n relationship in Database tables an additional collection class (I usually use the additional prefix col); you can let the class builder do that for you.
So then you have
- clsCompany
- clsContact
- ClsColContact (Collection class)
In the clsCompany you add
private m_ColContact as clscolContact
Public property get Contacts() as clscolContact
set Contacts= m_ColContact
end property
Public Property Set Contacts(byval vdata as clscolContact)
set m_ColContact = vdata
end property
Then you can fill a collection of the contacts somewhere in your code and
then pass it to your Company class with
dim ccompany as clscompany
dim ccolContact as clscolcontact
...
' add item to collection
colcontact.additem(name, phone, email)
....
' Pass to Company
set ccompany.Contacts = ccolcontact
or if you want to get the collection from the class
set ccolcontact = ccompany.Contacts
IMHO this is a much better way to handle the problem than working with arrays.
have a nice day
Patzer
_____________________________
Philo will never be forgotten
-
August 17th, 2005, 05:16 AM
#6
Re: Array inside a collection
If I'm not mistaken, I addressed this type of concept in another thread, in which I posted an example of how I might do it. Here's the link: http://www.codeguru.com/forum/showth...303#post984151
Basically, using a class and a UDT array eliminates the need for a collection object. Having a collection of class objects would use far more resources from what I can see.
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
-
August 17th, 2005, 07:13 AM
#7
Re: Array inside a collection
Hi Wizbang,
Basically, using a class and a UDT array eliminates the need for a collection object. Having a collection of class objects would use far more resources from what I can see.
AFAIK you're absolutely correct.
But to be honest, nowadays I just do not consider the need to check the resources having a high priority.
IMHO it is just a matter of concept,
but one thing AFAIK is clear: as in VB you cannot return an array that is not of type variant from a function, you can not create methods in classes that return parts of the current array due to given criteria.
So lets assume you have an instance of a class that is filled, and has an array for the contacts as you described, with 50 elements.
You now want to get all contacts from that array that work in Frankfurt, Germany.
You now have to add methods to the company class to pass the criteria, enhance the property get of the contacts etc etc
With a collection class you just add an enum that contains the the fields that you want to filter, and a method that additionally passes the value like this:
set cColContacts = cCompany.getContacts(enPhone, "004960") ' enPhone is just a enum value, 004960 the number to reach Frankfurt from outside Germany.
IMHO this is a distinct advantage, but as I said, it's just a matter of taste ...
have a nice day
Patzer
_____________________________
Philo will never be forgotten
-
August 17th, 2005, 07:29 AM
#8
Re: Array inside a collection
...but one thing AFAIK is clear: as in VB you cannot return an array that is not of type variant from a function...
A common misconception. I do it all the time.
...you can not create methods in classes that return parts of the current array due to given criteria.
Actually, you can. Place the code below into a form, add a command button, and run it.
Code:
Option Explicit
Private Sub Command1_Click()
Dim S$(), I&
S = Test("C")
For I = 0 To UBound(S)
Debug.Print S(I)
Next
End Sub
Private Function Test(Var As String) As String()
Dim S$()
S = Split("A,B,C,Apple,Banana,Cranberry", ",")
Test = Filter(S, Var, True, vbTextCompare)
End Function
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
-
August 17th, 2005, 09:06 AM
#9
Re: Array inside a collection
Hi Wizbang,
that's impressive,
and a solution that I can use in another context for code optimizing for a task that I have currently (Resistor and capacitor values that I get from a database are used in a formula-class to get a frequency where the deviation from the desired frequency is as small as possible. I use collection classes and the result of the calculation (looping about 50.000 times) is soooo slow).
I guess one should check everything and believe nothing in VB :-)
Thx a lot for this tip.
have a nice day
Patzer
_____________________________
Philo will never be forgotten
-
August 17th, 2005, 03:25 PM
#10
Re: Array inside a collection
...Resistor and capacitor values that I get from a database are used in a formula-class to get a frequency where the deviation from the desired frequency is as small as possible...
Ah, electronics!! Now you're speaking my language!!
It would be interesting to poke around with some code of this kind. My first thought would be to start with the more popular values. After all, the standard values were chosen because of such requirements. An algorithm should be able to generate a virtually endless supply of standard values (not the 1% ones). Then the closest 1% values around a common value pair can be more easily selected (if you even want to use those). In fact, the direction of deviation would narrow the selection even further. Now, the rules for selecting the capacitor value might need other consideration. I guess I'd do a kind of "middle-of-the-road" deal, and then the ideal resistor can be calculated. The closest common values can be figured with an algo, then you can check each to find the closest pair. I don't see a long loop here, though I'm just more or less making it up as I type.
As an example, if the ideal resistor was 4.0k, the algo would spit out 3.9k, and maybe also 4.1k, though less common IMO. If the ideal cap was .0023µf, you'd select .0022 and maybe .0024, though I think less common. The more common values are cheaper, so it pays even if the resultant frequency is a tiny bit less precise. There's always a drift over time too, so if you wanted to really get picky, you could tack on something for that.
<EDIT>
Ooops...lets not hijack the thread!
Last edited by WizBang; August 17th, 2005 at 03:28 PM.
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|