You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 14:02:08