2017-08-02 71 views
1

我有一個excel宏,用於在基於另一個SO問題here的「Worksheet_Change」函數中的Excel中管理按鈕可見性。Worksheet_Change設置目標範圍很慢

問題是,雖然宏工作,它使更新Excel工作表相當滯後。我已成功地緩慢牽制,一條線路:

Set rUpdated = Range(Target.Dependents.Address) 

這將通過後面的腳本進行迭代更新爲變量的單元格區域。如果我用這一行調用一個腳本,我發現這是所有延遲的地方。這似乎是一條相當簡單的路線,但有沒有更好的方法來做到這一點?

披露:

Private Sub Worksheet_Change(ByVal Target As Range) 
    Dim rUpdated As Range 
    Dim shp As Shape 
    Dim rCell As Range 
    Set rUpdated = Range(Target.Dependents.Address) 
    If Not rUpdated Is Nothing Then 
     For Each rCell In rUpdated 
      If rCell.Column = 1 Then 
       'Look at each shape in the sheet and cross-reference with rCell. 
       For Each shp In Target.Parent.Shapes 
        If shp.TopLeftCell.Row = rCell.Row Then 
         shp.Visible = (rCell.Value <> "") 
         Exit For 'Exit the loop - the correct button has been found. 
        End If 
       Next shp 
      End If 
     Next rCell 
    End If 
End Sub 
+0

你引用的單元格是否總是在同一行?如果是這樣的話,編寫一個自定義函數可能會更快,該函數將更改單元格的地址並檢查當前行中的公式 – Zac

+0

否,引用的單元格可能是電子表格的整個高度。不過,我只關心一行。我只需要一個比調用'Target.Dependents'更好的方法。 – fileinster

回答

0

我替換下面一行(和同伴線)配置:

On Error Resume Next 
ActiveSheet.Shapes("buttonRow" & Target.Row).Visible = (ActiveSheet.Cells(Target.Row, 1).Value <> "") 

然而,爲了得到這個工作,我首先需要重命名我的形狀。我使用這個功能來做到這一點:

Function renamebuttons() 
    For Each shp In ActiveSheet.Shapes 
     shp.name = "buttonRow" & shp.TopLeftCell.Row 
    Next shp 
End Function 

我運行該功能一次,並刪除它。一旦完成,我的形狀現在可以通過名稱來引用,並且不再導致在每個形狀和每個目標相關的循環中延遲。工作表中經歷的延遲現在是最小的。

0

所以,如果我理解正確的話,你想使一個按鈕可見,如果該行作爲細胞被改變。我唯一能想到的就是減慢速度,那就是檢查很多rCellShapes。我不知道你的文檔的結構是什麼。所以我的想法是:我不會每次都瀏覽所有的形狀,我會以一種模式命名它們,你可以用它們所在的行來標識它們,所以你使用名稱來解決它們(即Row2爲行2中的按鈕)。

Private Sub Worksheet_Change(ByVal Target As Range) 
    Dim rUpdated As Range 
    Dim shp As Shape 
    Dim rCell As Range 
    Dim obj As OLEObject 

    Set rUpdated = Range(Target.Dependents.Address) 
    If Not rUpdated Is Nothing Then 
     For Each rCell In rUpdated 
      If rCell.Column = 1 Then 
       On Error Resume Next 
       Set obj = ActiveSheet.OLEObjects("Row" & rCell.Row) 
       If Err.Number = 0 Then 
        obj.Visible = (rCell.Value <> "") 
       End If 
      End If 
     Next rCell 
    End If 
End Sub 
+0

通過所有rCells或Shapes不會導致緩慢。如果我將sub限制在單行「Set rUpdated = Range(Target.Dependents.Address)」中,那就是我得到所有緩慢的地方。我測試了你的代碼,它運行的時間差不多。 – fileinster

+0

當它的這一行,你應該在一個乾淨的'Workbook'中測試它只有幾個參考,看看性能是否糟糕。還有什麼東西在後面跑? – UGP

+0

在只有單元格公式複製的乾淨工作簿中進行測試。只有VBA代碼是worksheet_change宏中的這一行。無可否認,可能會有很多依賴項,因爲公式中有很多對其他單元格的引用,但是我無法更改它,因爲它會破壞工作表的功能和用途。例如,一個公式引用了8個單元,並且在單個單元更新中總共可以更新總共16個單元。沒有VBA的性能問題。 – fileinster