Results 1 to 11 of 11
  1. #1
    Rawb is offline Expert
    Windows XP Access 2000
    Join Date
    Dec 2009
    Location
    Somewhere
    Posts
    875

    Modifying Read-only Properties in a User-Defined Class

    In short, is there a way to make it so that a Property can only be modified from within a specific Collection?



    For example, I have a User-Defined Class with a read-only property "LastUpdated". This property is updated internally whenever an instance of the class has its Index Property changed.

    Is there a way to make it so my Collection can modify this Property as well (for cloning/copying purposes) but still not let "outside" code modify it?

  2. #2
    Rod is offline Expert
    Windows 7 32bit Access 2007
    Join Date
    Jun 2011
    Location
    Metro Manila, Philippines
    Posts
    679
    Is there a way to make it so my Collection can modify this Property ...
    What exactly is your 'Collection?' The final answer will depend very much on the structure and inter-relationship of your classes.

  3. #3
    Rawb is offline Expert
    Windows XP Access 2000
    Join Date
    Dec 2009
    Location
    Somewhere
    Posts
    875
    Class: tSortItem
    Code:
    Option Compare Database
    Option Explicit
    
    Public Enum tSortType
      tSortAsc = 1
      tSortDesc = 2
      [_First] = 1
      [_Last] = 2
    End Enum
    
    Private tIndex As Long
    Private tField As String
    Private tLastUpdated As Date
    Private tTable As String
    Private tSort As tSortType
    
    ' Index is read/writeable
    Property Get Index() As Long
      Index = tIndex
    End Property
    
    Property Let Index(Value As Long)
      tIndex = Value
      tLastUpdated = Now()
    End Property
    
    
    ' Field is read/writeable
    Property Get Field() As String
      Field = tField
    End Property
    
    Property Let Field(Value As String)
      tField = Value
    End Property
    
    
    ' LastUpdated is read-only
    Property Get LastUpdated() As Date
      LastUpdated = tLastUpdated
    End Property
    
    
    ' Sort is read/writeable
    Property Get SortMethod() As tSortType
      SortMethod = tSort
    End Property
    
    Property Let SortMethod(Value As tSortType)
      tSort = Value
    End Property
    
    
    ' Table is read/writeable
    Property Get Table() As String
      Table = tTable
    End Property
    
    Property Let Table(Value As String)
      tTable = Value
    End Property
    Collection Class: tSortList
    Code:
    Option Compare Database
    Option Explicit
    
    Private tCount As Long
    
    Private tList As Collection
    
    Property Get Count() As Long
      Count = tCount
    End Property
    
    Public Property Get Item(Index As Long) As tSortItem
      Set Item = tList.Item(Index)
    End Property
    
    Public Sub Class_Initialize()
      Set tList = New Collection
    End Sub
    
    Public Function NewEnum() As IUnknown
      Set NewEnum = tList.[_NewEnum]
    End Function
    
    Public Sub Add(Table As String, Field As String, Optional SortMethod As tSortType = tSortAsc)
      Dim tItem As tSortItem
    
      Dim nbrSortMethod As tSortType
    
      Set tItem = New tSortItem
    
      If SortMethod = 0 Then
        nbrSortMethod = tSortAsc
      Else
        nbrSortMethod = SortMethod
      End If
    
      With tItem
        .Table = Table
        .Field = Field
        .SortMethod = nbrSortMethod
        .Index = Me.Count
      End With
    
      tList.Add tItem
    
      tCount = Me.Count + 1
    End Sub
    
    Public Sub Remove(Index As Long)
      Dim i As Long
    
      tList.Remove Index + 1 ' Because the indexing starts a one instead of zero??!?!
    
      i = Index + 1 ' Start at the item after Index
    
      Do While i < tList.Count + 1
        tList.Item(i).Index = tList.Item(i).Index - 1
        i = i + 1
      Loop
    
      tCount = Me.Count - 1
    End Sub
    Basically I'm trying to create a Clone() Functino for my Collection that accepts a single (Optional) Index as an argument. If the Index is provided, then a new Collection is created and ONLY that instance of my tSortItem Class is placed inside it. If no argument is passed, the entire Collection is copied.

  4. #4
    Rod is offline Expert
    Windows 7 32bit Access 2007
    Join Date
    Jun 2011
    Location
    Metro Manila, Philippines
    Posts
    679
    I’m attempting to approach this from first principles. All properties are public. So declaring a Property Let for LastUpdated immediately exposes it to all other objects. Yet without such a property (or a method) how may LastUpdated be available only to selected objects.

    The answer has to be that the object using the Property Let or method must declare itself. Since you have a Property Get LastUpdated, I suggest a method is more appropriate. You don’t want to include an otherwise unnecessary argument in the Property Get.

    So why not have something like:

    Public Sub SetLastUpdated(robj as Object, rdte as Date)
    If TypeOf robj is tSortLIst Then
    Do something
    Else
    Do nothing
    End If

    Not ideal, I agree.

    P.S. There might be another way using user events.
    Last edited by Rod; 12-20-2012 at 11:18 PM. Reason: Added P.S.

  5. #5
    Rawb is offline Expert
    Windows XP Access 2000
    Join Date
    Dec 2009
    Location
    Somewhere
    Posts
    875
    I agree, that's not an ideal solution...

    But, if it's the best I can do, then that's probably what I'mma do.

  6. #6
    Rod is offline Expert
    Windows 7 32bit Access 2007
    Join Date
    Jun 2011
    Location
    Metro Manila, Philippines
    Posts
    679
    I am wrong about properties always being public. But I don't think that gets us any further.

  7. #7
    Rod is offline Expert
    Windows 7 32bit Access 2007
    Join Date
    Jun 2011
    Location
    Metro Manila, Philippines
    Posts
    679
    I've been thinking some more about this.

    1. You could develop two projects: one containing your class structure and one for the application. Declaring LastUpdated as a friend means it is only available within the first project. This seems a sledgehammer solution for the proverbial nut.
    2. Almost as bad - depends how critical the requirement is - is to create and maintain a 'where used' dictionary/collection for sort items and move the last updated property to your tSortList collection (if the same date applies to all memebrs) or encode the last updated property in the dictionary/collection. You then need a procedure to determine the latest date updated for a sort item.

  8. #8
    Rawb is offline Expert
    Windows XP Access 2000
    Join Date
    Dec 2009
    Location
    Somewhere
    Posts
    875
    Yay! Back from vacation!

    OK, I've done a little looking into this whole "friend" thing you mentioned and it looks like it might be what I want. Unfortunately, I haven't yet been able to find any good resources on how to use it.

    I'll have to look into this further!

  9. #9
    stmoong is offline Competent Performer
    Windows XP Access 2007
    Join Date
    Sep 2011
    Location
    Singapore
    Posts
    108
    We can still update the Index like this:
    Code:
        .....
        sortItem.Index = sortItem.Index
        .....
    The value of Index is not changed, but the "LastUpdated" is updated. Is this the expected behaviour?

  10. #10
    Rawb is offline Expert
    Windows XP Access 2000
    Join Date
    Dec 2009
    Location
    Somewhere
    Posts
    875
    That's not really intended, but I'm not worried about it too much. What I'm looking for is a way to modify LastUpdated internally from the Collection while preventing anything outside from doing so (say, from a Form's code module).

    Also, according to others here (and my own experience) there does not seem to be a way to properly limit access to variables/properties/subs/etc. in a Class. So, I'll just code things openly and hope that anyone modifying my code in the future, follows "the rules."

  11. #11
    stmoong is offline Competent Performer
    Windows XP Access 2007
    Join Date
    Sep 2011
    Location
    Singapore
    Posts
    108
    Just comment your code

    Personally, I will also code openly and document the "proper" way to use the class if it's for internal development. For internal development, sometimes, keeping things less strict and flexible may be more productive. If the component is to be released for commercial distribution, then, probably a stricter implementation may be useful.

Please reply to this thread with any new information or opinions.

Similar Threads

  1. Replies: 1
    Last Post: 12-14-2012, 12:32 AM
  2. Replies: 4
    Last Post: 06-08-2012, 09:08 AM
  3. User defined keyboard shortcuts
    By prstoessel in forum Access
    Replies: 2
    Last Post: 09-26-2011, 12:45 PM
  4. User Defined Sorting in Form
    By sparlaman in forum Forms
    Replies: 6
    Last Post: 04-26-2011, 12:02 PM
  5. Error: "User-defined type not defined"
    By mastromb in forum Programming
    Replies: 10
    Last Post: 01-08-2010, 02:57 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums