每當需要查找時,我都會使用Dictionary
對象。在我的解決方案中,我使用嵌套字典返回頂層和活動的組合。 (注:我試着儘可能地瞭解你的業務需求,但我確信我沒有認識到它,我還假設了一些關於初學者水平的VBA知識,如果你有問題,請問我們會盡力幫助)。
首先,創建一個新的模塊來容納全球可用的Dictionary
。這不能是Worksheet
模塊。 (在VBE中,轉到插入 - >模塊)。在模塊的最頂端,創造一個子程序之前就宣佈一個公開的Dictionary
Public oDictWbs As Object
我們只希望這本字典的一個實例,所以我喜歡用Singleton
狀的圖案,如果已經創建了返回Dictionary
如果沒有,則創建並返回一個新的。 (注意:我將計算出的例程返回到RefreshWBS
,以便它可以用於根據您的業務規則創建新字典。例如,在默認工作表OnChange
事件中,您可以調用RefreshWBS
[code重用總是很有趣])。
Private Function GetWBS() As Object
If Not oDictWbs Is Nothing Then
Set GetWBS = oDictWbs
Exit Function
End If
Set GetWBS = RefreshWBS()
End Function
Private Function RefreshWBS()
Dim sDefault As Worksheet
Dim rTopLevels As Range
Dim rActivities As Range
Dim rIterator As Range
Dim rInnerIter As Range
Set oDictWbs = Nothing
'Both variables below establish the range that stores the fixed info (the default worksheet)
'Instead of hard coding in the range, create your own logic based on your needs and rules
Set sDefault = Sheets("Default")
Set rTopLevels = sDefault.Range("B1:C1")
Set rActivities = sDefault.Range("A3:A4")
Set oDictWbs = CreateObject("Scripting.Dictionary")
For Each rIterator In rTopLevels
If Not oDictWbs.exists(rIterator.Value) Then
Set oDictWbs(rIterator.Value) = CreateObject("Scripting.Dictionary")
End If
For Each rInnerIter In rActivities
If Not oDictWbs(rIterator.Value).exists(rInnerIter.Value) Then
oDictWbs(rIterator.Value)(rInnerIter.Value) = sDefault.Cells(rInnerIter.Row, rIterator.Column)
End If
Next rInnerIter
Next rIterator
Set RefreshWBS = oDictWbs
End Function
最後,我們創建一個可以從工作表本身進行訪問,使用戶能夠在WBS字典訪問信息的功能。您可以輸入Excel單元格中的一個函數,如=GetWbsActivityTime(B1, A4)
,假定單元格B1包含頂級描述符,A4描述該活動。只要該值在字典中,它就會返回與其相關的值。
Function GetWbsActivityTime(sTopLevel As String, sActivity As String) As Variant
Dim oDict As Object
Set oDict = GetWBS()
If Not oDict.exists(sTopLevel) Then
GetWbsActivityTime = CVErr(xlErrRef)
Exit Function
End If
If Not oDict(sTopLevel).exists(sActivity) Then
GetWbsActivityTime = CVErr(xlErrRef)
Exit Function
End If
GetWbsActivityTime = oDict(sTopLevel)(sActivity)
End Function
我知道這是一個很大的吸收,所以審查,並讓我知道的任何問題或與怪癖,我可以提供幫助。另外,如果我完全錯過了練習的要點,請告訴我,我會看看我們是否可以挽救部分解決方案。
'我只是不知道如何使數組持久化 - - 通過在模塊級別聲明它而不是過程級別。再次,你可能應該修復醜陋的查找,因爲我不知道它絕對是醜陋的。 – GSerg
謝謝@GSerg。醜陋的查找的一個大問題是,我必須執行角色默認查找,加上基於其他標準的其他計算,這需要活動#。我的最終目標是將Worksheet_Change函數更改爲僅折回頂部活動行,並重用角色默認數組來填充角色,而不是活動周下的每個單元格的當前INDEX/MATCH。 –