gpt4 book ai didi

vba - 如何在子项目中选择任务的行(在主项目中)

转载 作者:行者123 更新时间:2023-12-05 06:39:22 26 4
gpt4 key购买 nike

我有一个主项目,里面有几个子项目。

我想根据字段 Text5 的值格式化行的颜色。

当前问题:如何使用VBA代码引用第二个子项目中的行。当我运行代码并修改任务 ID 5(在子项目 2 中)中的 Text5 值时,它修改了任务 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)

最佳答案

挑战——在主项目中格式化一行

要格式化表格中的文本,请使用 FontEx方法。此方法格式化事件(选定)单元格。要选择要格式化的行,请使用 SelectRow方法。要使用此方法,您需要了解:

  1. 它相对于事件选择的位置,或者
  2. 它在可见任务中的绝对位置,或者
  3. 根据唯一标识符查找任务

对于被过滤器或折叠摘要隐藏的选项 1 和 2 任务意味着必须相应地调整 SelectRow 方法的行参数。很难知道哪些任务可能被隐藏。使用此方法的最佳方式是首先确保所有任务都是可见的(参见代码)。

此外,在处理子项目时,计算绝对行位置是一项挑战,因为首先您需要获得时间表中较高位置的子项目的任务数以及主项目本身中的任何 native 任务(尽管这是非典型的).

所有这些导致使用Find 方法,选项 3,作为在主项目中选择任务的最佳方式。要准确选择正确的任务,必须将 Find 方法与唯一字段一起使用。唯一 ID 字段是唯一保证唯一的字段。

主项目中的唯一 ID

将任务添加到项目时,会分配一个递增的唯一 ID,从 1 开始。当项目在主项目中组合时,通过添加种子值更改唯一 ID,以便主项目中没有重复项项目。

种子值基于内部子项目“索引”。第一个子项目的任务的种子值为 4194304,第二个子项目的任务的种子值为 8388608 (4194304 * 2),依此类推。

如果从主项目中删除子项目,则不会重新使用它的“索引”。同样,如果子项目在母版中重新排列,“索引”值也不会改变。因此,您不能使用子项目对象的 Index 属性来获取用于创建种子的内部“索引”值,因为该属性仅指示子项目的顺序。(注意,有一种方法可以获得这个内部值,但这超出了这个问题的范围。仅供引用,它还需要选择所有任务。)

解决方案

要在用户界面中选择任务,您需要知道它在主计划中的唯一 ID。如果您通过 SourceProject.Tasks 方法访问任务,您将访问其 native 子项目中的任务,并且唯一 ID 将不包含种子值。例如,唯一 ID 将为 2,这在主项目中不是唯一的,因此不足以使用 Find 方法选择任务。

由于您已经循环遍历了计划中的所有任务,因此确定主唯一 ID 的最简单方法是循环遍历主项目中的 native 任务。为此,请选择所有任务并循环选择。

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 或 2。选择所有任务将花费 10-15 个子项目的时间,但其余代码将以接近相同的速度运行。
  • 如果任务已分组或未按任务 ID 排序,则选项 1 或 2 的所有选项均无效。
  • 将以前的值存储在由任务 ID 索引的数组中不适用于主项目。相反,将以前的值存储在以主唯一 ID 作为键的集合或字典中。 See this SO post about using dictionaries in VBA.

关于vba - 如何在子项目中选择任务的行(在主项目中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44655957/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com