如何让ProjectBeforeAssignmentChange事件汇总成本至Task.Cost5字段
解决方法
核心问题是你未通过Assgn.Task获取分配对应的任务对象,且存在变量重名冲突,以下是修正后的实现代码和说明:
修正后的类模块代码(cm_Events)
Private Sub MyMSPApp_ProjectBeforeAssignmentChange(ByVal Assgn As Assignment, ByVal Field As PjAssignmentField, ByVal NewVal As Variant, Cancel As Boolean) Dim tsk As Task Dim totalLaborCost As Double Dim a As Assignment ' 避免和参数Assgn重名 ' 获取当前分配所属的任务对象 Set tsk = Assgn.Task ' 调试输出,确认资源分类与成本(可保留用于验证) If Assgn.Resource.Text2 = "Labor" Then Debug.Print Now, Assgn.ResourceName, Assgn.Resource.Text2, NewVal, "$" & Assgn.Cost, tsk.Name End If If EnableEvents Then EnableEvents = False ' 先清零Cost5,避免重复累加旧数据 tsk.Cost5 = 0 totalLaborCost = 0 ' 遍历任务下所有分配,汇总人工资源成本 For Each a In tsk.Assignments ' 按实际资源分类标记字段调整(此处用Text2匹配"Labor") If a.Resource.Text2 = "Labor" Then totalLaborCost = totalLaborCost + a.Cost End If Next a ' 将汇总结果写入任务的Cost5字段 tsk.Cost5 = totalLaborCost EnableEvents = True End If End Sub
关键修正点
- 获取任务对象:通过
Set tsk = Assgn.Task直接从触发事件的分配对象关联到所属任务,解决任务识别失败问题。 - 变量重名修复:循环时使用
a As Assignment替代与参数同名的Assgn,避免变量冲突导致的逻辑错误。 - 累加逻辑优化:每次汇总前清零
tsk.Cost5,确保计算结果为当前任务下人工成本的准确总和。 - 分类字段统一:代码中使用
Resource.Text2匹配人工分类,需根据你实际的资源标记字段(原代码中同时出现Text1/Text2)调整为一致字段。
注意事项
- 确保资源的对应文本字段(如Text2)已正确标记"Labor"(人工)或"Material"(材料)分类。
- 测试时打开VBA编辑器的立即窗口,查看调试输出确认资源分类和成本计算是否正确。
ProjectBeforeAssignmentChange事件在分配字段变更后、Project保存变更前触发,此时Assgn.Cost已更新为变更后的值,可直接用于汇总。
内容的提问来源于stack exchange,提问作者BP130
相关产品推荐
相关产品推荐

