我有一个Master-Project,在里面我有几个子项目。
我想根据字段Text5
的值格式化行的颜色。
当前问题:如何使用VBA代码引用第二个子项目中的行。
当我运行代码并修改任务ID 5中的Text5
值(在子项目2中)时,它会修改任务ID 5的颜色,但是修改子项目1的颜色。
如何使用SelectRow
并将参考添加到所需的子项目?
我的代码 (相关部分)
Sub FormatChangedTasks()
Dim SubPrj As Subproject
Dim Tsk As Task
Dim i As Long
For Each SubPrj In ActiveProject.Subprojects
' compare the name of Sub-Project with the one saved in the "Stack" srray
If SubPrj.SourceProject.Name = ModifiedPrjName Then
For Each Tsk In SubPrj.SourceProject.Tasks
If Not Tsk Is Nothing Then
i = Tsk.ID
' check if Tsk.Text5 value has changed from value in "StatusStackArr" array
If StatusStackArr(i - 1).StatusOldVal <> Tsk.Text5 Then
' **** at the line below it selects the Row from the top
' (not the desired Sub-Project) ******
SelectRow Row:=i, RowRelative:=False
' --format entire row --
Select Case Tsk.Text5 ' Get the Field's used field, not name
Case "R", "Y", "G"
FontEx CellColor:=7, Color:=0
FontEx Italic:=False ' Font regular
Case "Complete"
FontEx Italic:=True ' Font Italic
FontEx CellColor:=15, Color:=14 ' Background Silver ; font Gray
End Select
' rest of code (un-relevant)
答案 0 :(得分:1)
要格式化表格中的文字,请使用FontEx方法。此方法格式化活动(选定)单元格。要选择要格式化的行,请使用SelectRow方法。要使用此方法,您需要知道:
对于过滤器或折叠摘要隐藏的选项1和2任务,都必须相应地调整SelectRow
方法的行参数。很难知道哪些任务可能被隐藏。使用此方法的最佳方法是首先确保所有任务都可见(请参阅代码)。
此外,在使用子项目时,计算绝对行位置是一项挑战,因为首先需要将日程表中的子项目的任务计数加到主项目本身的任何本机任务中(尽管这是非典型的) )。
所有这些都导致使用Find
方法选项3作为在主项目中选择任务的最佳方式。要准确选择正确的任务,必须将Find方法与唯一字段一起使用。唯一ID字段是唯一保证唯一的字段。
将任务添加到项目时,将分配增量唯一ID,从1开始。当项目在主项目中合并时,通过添加种子值来更改唯一ID,以便主服务器中不存在重复项项目
种子价值基于内部子项目&#34;索引&#34;。第一个子项目的任务的种子值为4194304,第二个子项目的任务的种子值为8388608(4194304 * 2),依此类推。
如果从主程序中删除子项目,它的索引&#34;没有重复使用。同样,如果子项目在主服务器中重新排列,则&#34;索引&#34;价值观不会改变。因此,您不能使用子项目对象的Index
属性来获取内部&#34;索引&#34;用于创建种子的值,因为该属性仅指示子项目的顺序。
(注意,有一种方法可以获得这个内部值,但这超出了这个问题的范围。仅供参考,它还需要选择所有任务。)
要在用户界面中选择任务,您需要知道主计划中的唯一ID。如果您通过SourceProject.Tasks
方法访问任务,您将访问其本机子项目中的任务,并且唯一ID将不包含种子值。例如,唯一ID将是2,它在主项目中不是唯一的,因此不足以使用Find方法选择任务。
由于您已经遍历了计划中的所有任务,因此确定主唯一ID的最简单方法是在主项目中本地循环执行任务。为此,选择所有任务并循环选择。
Sub FormatChangedTasks()
' show all tasks
FilterClear
SelectAll
SummaryTasksShow (0)
OutlineShowAllTasks
Dim AllTasks As Tasks
Set AllTasks = ActiveSelection.Tasks
Dim Tsk As Task
For Each Tsk In AllTasks
If Not Tsk Is Nothing Then
' compare the name of Sub-Project with the one saved in the "Stack" srray
If Tsk.Project = ModifiedPrjName Then
' check if Tsk.Text5 value has changed from prior value
' NOTE: use a dictionary here instead of an array
If StatusStackArr(i - 1).StatusOldVal <> Tsk.Text5 Then
Find "Unique ID", "equals", Tsk.UniqueID
SelectRow
' --format entire row --
Select Case Tsk.Text5 ' Get the Field's used field, not name
Case "R", "Y", "G"
FontEx CellColor:=7, Color:=0
FontEx Italic:=False ' Font regular
Case "Complete"
FontEx Italic:=True ' Font Italic
FontEx CellColor:=15, Color:=14 ' Background Silver ; font Gray
End Select
' rest of code (un-relevant)
End If
End If
Next Tsk
End Sub
注意:
答案 1 :(得分:0)
插入子项目任务的(显示的)任务唯一ID来自以下公式:
(4194304 * ([PROJECT_UID]+1)) + [TASK_UID]
其中[PROJECT_UID]
是插入项目的唯一ID(不是索引)。 (插入的子项目的项目摘要被视为主项目中的任务,并且会收到其自己的唯一ID。)
选择一个任务后,您可以从类似以下内容中获得插入子项目的唯一ID:
ActiveProject.Subprojects(ActiveSelection.Tasks(1).Project).InsertedProjectSummary.UniqueID
或者如果您已经拥有TASK_UID(一个长值),则可以使用:
ActiveProject.Subprojects(ActiveProject.Tasks.UnqiueID([TASK_UID]).Project).InsertedProjectSummary.UniqueID
最后,如果您本身具有Task对象:
ActiveProject.Subprojects(Task.Project).InsertedProjectSummary.UniqueID
您可以在此处使用Find "Unique ID","equals",[TASK_UID]
选择要格式化的任务。
HT到Rachel,获取“种子”提示和值4194304。
编辑:有时Task.Project
属性返回子项目名称(例如[MyProject]
),有时返回完整路径(例如c:\users\[userName]\[MyProject].mpp
),以便仅获取项目名称使用类似的东西:
If Instr(Task.Project,".mpp") > 0 Then
strProject = Replace(Dir(Task.Project),".mpp","")
Else
strProject = Task.Project
End If