CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jan 2005
    Posts
    77

    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

  2. #2
    Join Date
    Dec 2001
    Posts
    6,332

    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?

  3. #3
    Join Date
    Aug 2000
    Location
    Essex, Uk
    Posts
    1,214

    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

  4. #4
    Join Date
    Jan 2005
    Posts
    77

    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

  5. #5
    Join Date
    May 2001
    Posts
    91

    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

  6. #6
    Join Date
    Dec 2001
    Posts
    6,332

    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?

  7. #7
    Join Date
    May 2001
    Posts
    91

    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

  8. #8
    Join Date
    Dec 2001
    Posts
    6,332

    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?

  9. #9
    Join Date
    May 2001
    Posts
    91

    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

  10. #10
    Join Date
    Dec 2001
    Posts
    6,332

    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
  •  





Click Here to Expand Forum to Full Width

Featured