[英]How do I refer to worksheets to loop through different worksheets and perform the same function on each of them?
[英]How do I reference charts with the same name, but on different worksheets?
我有兩個包含圖表的工作表,並使用宏來運行包含圖表的所有工作表並更新圖表中的值。
但是,在嘗試在第一個工作表之后引用工作表中的圖表時遇到問題 - 盡管工作表的引用發生了更改,但對圖表的引用卻沒有。
循環看起來像這樣:
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Name
Debug.Print ws.ChartObjects("Kortsone").Chart.Name
With ws.ChartObjects("Kortsone").Chart
...
End With
Next ws
我到達即時窗口的輸出如下:
Grafar ovn 3
Grafar ovn 3 Kortsone
Grafar ovn 4
Grafar ovn 3 Kortsone
正如您所看到的對工作表的引用更改,但圖表引用沒有。
有沒有辦法解決這個問題,還是我必須用獨特的名稱重命名我的所有圖表?
我正在使用Excel 2013
- 編輯 -我現在已根據評論中的建議進行了一些測試,看來打印到即時窗口的內容取決於當前活動工作表的內容。
嘗試使用for each chartobject
遇到了與之前相同的問題:
Sub test2()
Dim ws As Worksheet
Dim ch As ChartObject
For Each ws In ThisWorkbook.Worksheets
For Each ch In ws.ChartObjects
If ws.CodeName = "Graf4" Then
Debug.Print ws.Name
Debug.Print ch.Name
Debug.Print ch.Chart.Name
End If
Next ch
Next ws
End Sub
放棄:
Grafar ovn 4
Kortsone
Grafar ovn 3 Kortsone
Grafar ovn 4
Langsone
Grafar ovn 3 Langsone
...
正如您所發現的, Workheet.ChartObjects
方法將找到正確的ChartObject,但訪問Chartobject.Chart
屬性將返回ActiveSheet的圖表。 如果按名稱或索引號引用ChartObject,則無關緊要。
如果使用Worksheet.Shapes
方法查找ChartObject,則行為相同。
此行為與早期版本的Excel不同。 我確認代碼在Excel XP / 2002中有效,並且在2016年不起作用。我不確定行為何時發生變化。 它可能是2013年,或者它可能是2013年和2016年的補丁? Office for Mac 2016中的行為是相同的(即。不起作用)
在Microsoft提出修復之前,您必須在訪問Chart屬性之前激活工作表或激活ChartObject。
Sub test()
Dim ws As Worksheet
Dim co As ChartObject
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Name
Set co = ws.ChartObjects("Kortsone")
ws.Activate
'or
co.Activate
Debug.Print co.Chart.Name
With ws.ChartObjects("Kortsone").Chart
End With
Next ws
End Sub
我建議您暫時禁用ScreenUpdating,並在完成后重新激活原始活動表。
getChart
將圖表對象存儲在Static Collection
。 Static Collection
將保留在內存中,直到代碼中斷或工作簿關閉。
第一次調用getChart
所有圖表對象時,所有工作表都會被激活,每個工作表上的每個圖表都會添加到集合中。 之后,圖表只是在靜態集合中查找。
如果圖表(例如在調用函數后添加了圖表)不在集合中,則函數將自行重新加載。
Function getChart(ChartName As String, WorkSheetName As String, Optional Reload As Boolean) As Chart
Dim ws As Worksheet, ActiveWS As Worksheet
Dim co As ChartObject
Static ChartCollection As Collection
If ChartCollection Is Nothing Or Reload Then
Application.ScreenUpdating = False
Set ChartCollection = New Collection
Set ActiveWS = ActiveSheet
For Each ws In ThisWorkbook.Worksheets
ws.Activate
For Each co In ws.ChartObjects
ChartCollection.Add co.Chart, ws.Name & "!" & co.Name
Next
Next ws
ActiveWS.Activate
Application.ScreenUpdating = True
End If
On Error Resume Next
Set getChart = ChartCollection(WorkSheetName & "!" & ChartName)
If Err.Number <> 0 And Not Reload Then Set getChart = getChart(ChartName, WorkSheetName, True)
On Error GoTo 0
End Function
Sub Test()
Dim ws As Worksheet
Dim ch As Chart
Dim msg As String
Dim Start: Start = Timer
For Each ws In ThisWorkbook.Worksheets
Set ch = getChart("Kortsone", ws.Name)
If Not ch Is Nothing Then
msg = msg & ws.Name & "!" & ch.Name & " - Validated:" & (ws.Name = ch.Parent.Parent.Name) & vbCrLf
End If
Next ws
msg = msg & "Time in Seconds: " & Timer - Start
MsgBox msg
End Sub
Chart
和Worksheet.ChartObject.Chart
之間存在差異。
說清楚
ChartObject
以包含Chart
。 因此, Chart
是ChildObject
的子代,而ChildObject
又是Worksheet
的子代。 Chart
(或者您可以稱之為“圖表工作表”),等同於Worksheet
。 因此, Worksheet.ChartObject.Chart
與Chart
Worksheet.ChartObject.Chart
的不同之處如下:
Worksheet.ChartObject.Chart
中的Chart
包含Chart
所有屬性。 Chart
表包含Chart
所有屬性和工作表的某些屬性。 因此.Name
屬性應該用於Chart
表,但不適用於Worksheet.ChartObject.Chart
。
我說在調用ChartObject.Chart.Name
時附加顯示活動表名稱不是錯誤,而是調試錯誤。 ChartObject.Chart
首先不會也不應該有一個Name
。 您可以調用ChartObject.Chart.Name
因為Chart
對象模型的intellisense中存在重疊。 如果微軟不允許這樣做,就會有一個錯誤。
簡而言之,請記住圖表沒有名稱,它是ChartObject
或帶有名稱的Sheet
。 相比之下,圖表有ChartTitle
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.