VBA:子对象属性变更时如何更新父类对应属性值
树形任务列表的属性同步问题与优化方案探讨
我正在构建树形结构的任务列表,包含Task_List和Task两个类。Task_List可嵌套其他Task_List或Task,其多项属性为所含子项对应属性的汇总值(如Duration属性为所有子项Duration之和)。
已实现大部分功能(包括子对象访问父类),但难以找到优雅的方式在子对象属性变更时更新Task_List的对应汇总属性。目前尝试的三种方案均存在缺陷:
- 方案1:子对象的X属性变更时,触发父类的公共函数,重置父类X值后遍历所有子项重新求和赋值
- 问题:实现繁琐,每次变更都需遍历所有子项,数据量大时性能损耗严重
- 方案2:为
Task_List添加X属性的Let方法,子对象调用该方法先减去旧值,再加上新值- 问题:比方案1高效,但父类属性可被非子对象修改,无法限制调用方
- 方案3:与方案2类似,但传递整个子对象,父类验证该对象是否为自身子项
- 问题:无法实现,怀疑VBA不支持该方式
寻求相关指导与帮助,可补充更多信息。
简化示例代码
Task类模块
Private Type Task Name As String Value As Long Parent as Task_List End Type Private self As Task Public Sub Initialize(Parent as Task_List) Set self.Parent = Parent End Sub Public Property Get Parent() as Task_List Set Parent = Self.Parent End Property Property Let Name(ByVal Name As String) self.Name = Name End Property Property Get Name() As String Name = self.Name End Property ' 这里同时写了方案2和3的调用,实际只会用其中一种 Property Let Value(ByVal Value As Long) Call self.Parent.Option_2(-self.Value) Call self.Parent.Option_3(self,-1) self.Value = Value Call self.Parent.Option_3(self,1) Call self.Parent.Option_2(self.Value) End Property Property Get Value() As Long Value = self.Value End Property
Task列表类
Private Type Task_List Name As String SubTasks As New Collection Value As Long End Type Private self As Task_List Public Property Get SubTasks() As Collection Set SubTasks = self.SubTasks End Property Public Property Let SubTasks(SubTask_Coll As Collection) Set self.SubTasks = SubTask_Coll End Property Property Let Name(ByVal Name As String) self.Name = Name End Property Property Get Name() As String Name = self.Name End Property Property Get Value() As Long Value = self.Value End Property Public Sub Option_2(ByVal Update_Value as long, _ Optional ByVal Multiplier as Long = 1) self.Value = self.Value + (Multiplier * Update_Value) End Sub Public Sub Option_3(ByVal Child_Task as Variant, _ Optional ByVal Multiplier as Long = 1) On Error Resume Next If Child_Task.Parent = self Then self.Value = self.Value + (Multiplier * Child_Task.Value) End If On Error GoTo 0 End Sub Public Sub Option_1() Dim Cur_Sum As Long, Cur_Task as Variant For Each Cur_Task In self.SubTasks Cur_Sum = Cur_Sum + Cur_Task.Value Next Cur_Task self.Value = Cur_Sum End Sub
使用示例
Sub Example() Dim Main_List As New Task_List Main_List.Name = "Bake Bread" Dim T1 As New Task T1.Initialize Main_List Main_List.Subtasks.Add T1 T1.Name = "Buy Ingredients" T1.Value = 250 Dim T2 As New Task T2.Initialize Main_List Main_List.Subtasks.Add T2 T2.Name = "Do Baking" T2.Value = 400 Debug.Print Main_List.SubTasks(1).Name Debug.Print Main_List.SubTasks(2).Name Debug.Print Main_List.Value End Sub
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

