VBA执行速度较慢时存在空白单元格。

huangapple go评论76阅读模式
英文:

VBA executes slowly if there are blank cells

问题

以下是您提供的Excel VBA宏的翻译部分:

我在Excel VBA中有以下的宏它按照我想要的方式工作。(比较Entry工作表的A列中的文本与Clauses工作表的A列中的文本并突出显示匹配的单元格但是如果Entry工作表的A列中有任何空单元格它运行得很慢似乎不重要的是Clauses工作表中是否有空单元格有没有办法让它在某人留空单元格时不要花那么长时间

Dim c As Range, fn As Range, adr As String
    With Sheets("sheet1")
        For Each c In .Range("A1", .Cells(Rows.Count, 1).End(xlUp))
            Set fn = Sheets("Clauses").Range("A:A").Find(c.Value, , xlValues, xlWhole)
                If Not fn Is Nothing Then
                    adr = fn.Address
                    c.Interior.Color = RGB(255, 100, 50)
                    Do
                        fn.Interior.Color = RGB(255, 100, 50)
                        Set fn = Sheets("Clauses").Range("A:A").FindNext(fn)
                    Loop While fn.Address <> adr
                End If
        Next
    End With

我已经尽量只返回翻译的部分,没有包含额外的内容。如果您有其他问题或需要进一步的帮助,请随时提出。

英文:

I have the following macro in Excel VBA, and it works as I want. (Compares text in Column A of the Entry sheet, with Column A of the Clauses sheet, and highlights matching cells) But if there are any blank cells in column A of the Entry sheet, it runs very slow. It doesn't seem to matter if there are empty cells in the Clauses sheet. Any ideas how to make it so it doesn't take so long if someone leaves a cell blank?

Dim c As Range, fn As Range, adr As String
    With Sheets(&quot;sheet1&quot;)
        For Each c In .Range(&quot;A1&quot;, .Cells(Rows.Count, 1).End(xlUp))
            Set fn = Sheets(&quot;Clauses&quot;).Range(&quot;A:A&quot;).Find(c.Value, , xlValues, xlWhole)
                If Not fn Is Nothing Then
                    adr = fn.Address
                    c.Interior.Color = RGB(255, 100, 50)
                    Do
                        fn.Interior.Color = RGB(255, 100, 50)
                        Set fn = Sheets(&quot;Clauses&quot;).Range(&quot;A:A&quot;).FindNext(fn)
                    Loop While fn.Address &lt;&gt; adr
                End If
        Next
    End With

I have tried using If Not c Is Nothing Then and &lt;&gt;&quot;&quot;. I'm just not sure if I am using them correctly?

答案1

得分: 1

以下是您要翻译的部分:

Highlight Matches in the Source and Destination

  • Never search for a value in a whole worksheet column.
  • You could use .End(xlUp) for both columns (adjust the first cells).

在源和目标中突出显示匹配项

  • 永远不要在整个工作表列中搜索值。
  • 您可以对两列使用 .End(xlUp)(调整第一个单元格)。

VBA执行速度较慢时存在空白单元格。

组合范围

<!-- language: lang-vb -->

Sub HighlightMatches()
    
    Dim wb As Workbook: Set wb = ThisWorkbook &#39; workbook containing this code
    
    &#39; The Find method or the End property will fail if the worksheet is filtered.
    
    Dim sws As Worksheet: Set sws = wb.Sheets(&quot;Sheet1&quot;)
    &#39;If sws.FilterMode Then sws.ShowAllData
    Dim srg As Range:
    Set srg = sws.Range(&quot;A2&quot;, sws.Cells(sws.Rows.Count, &quot;A&quot;).End(xlUp))
    
    Dim dws As Worksheet: Set dws = wb.Sheets(&quot;Clauses&quot;)
    &#39;If dws.FilterMode Then dws.ShowAllData
    Dim drg As Range:
    Set drg = dws.Range(&quot;A2&quot;, dws.Cells(dws.Rows.Count, &quot;A&quot;).End(xlUp))
    
    Dim surg As Range, sCell As Range, sValue
    Dim durg As Range, dCell As Range, dAddress As String
    
    For Each sCell In srg.Cells
        sValue = sCell.Value
        If Len(CStr(sValue)) &gt; 0 Then &#39; is not blank
            Set dCell = drg.Find(sValue, , xlValues, xlWhole)
            If Not dCell Is Nothing Then
                dAddress = dCell.Address
                Set surg = RefCombinedRange(surg, sCell)
                Do
                    Set durg = RefCombinedRange(durg, dCell)
                    Set dCell = drg.FindNext(dCell)
                Loop While dCell.Address &lt;&gt; dAddress
            End If
        End If
    Next sCell

    &#39; Clear and highlight in (almost) one go!

    If Not surg Is Nothing Then
        ClearAndHighlight srg, surg, RGB(255, 100, 50)
    End If
    
    If Not durg Is Nothing Then
        ClearAndHighlight drg, durg, RGB(255, 100, 50)
    End If

End Sub

组合范围

<!-- language: lang-vb -->

&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39
英文:

Highlight Matches in the Source and Destination

  • Never search for a value in a whole worksheet column.
  • You could use .End(xlUp) for both columns (adjust the first cells).

VBA执行速度较慢时存在空白单元格。

<!-- language: lang-vb -->

Sub HighlightMatches()
    
    Dim wb As Workbook: Set wb = ThisWorkbook &#39; workbook containing this code
    
    &#39; The Find method or the End property will fail if the worksheet is filtered.
    
    Dim sws As Worksheet: Set sws = wb.Sheets(&quot;Sheet1&quot;)
    &#39;If sws.FilterMode Then sws.ShowAllData
    Dim srg As Range:
    Set srg = sws.Range(&quot;A2&quot;, sws.Cells(sws.Rows.Count, &quot;A&quot;).End(xlUp))
    
    Dim dws As Worksheet: Set dws = wb.Sheets(&quot;Clauses&quot;)
    &#39;If dws.FilterMode Then dws.ShowAllData
    Dim drg As Range:
    Set drg = dws.Range(&quot;A2&quot;, dws.Cells(dws.Rows.Count, &quot;A&quot;).End(xlUp))
    
    Dim surg As Range, sCell As Range, sValue
    Dim durg As Range, dCell As Range, dAddress As String
    
    For Each sCell In srg.Cells
        sValue = sCell.Value
        If Len(CStr(sValue)) &gt; 0 Then &#39; is not blank
            Set dCell = drg.Find(sValue, , xlValues, xlWhole)
            If Not dCell Is Nothing Then
                dAddress = dCell.Address
                Set surg = RefCombinedRange(surg, sCell)
                Do
                    Set durg = RefCombinedRange(durg, dCell)
                    Set dCell = drg.FindNext(dCell)
                Loop While dCell.Address &lt;&gt; dAddress
            End If
        End If
    Next sCell

    &#39; Clear and highlight in (almost) one go!

    If Not surg Is Nothing Then
        ClearAndHighlight srg, surg, RGB(255, 100, 50)
    End If
    
    If Not durg Is Nothing Then
        ClearAndHighlight drg, durg, RGB(255, 100, 50)
    End If

End Sub

Combine Ranges

<!-- language: lang-vb -->

&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;
&#39; Purpose:      References a range combined from two ranges.
&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;
Function RefCombinedRange( _
    ByVal urg As Range, _
    ByVal arg As Range) _
As Range
    If urg Is Nothing Then Set urg = arg Else Set urg = Union(urg, arg)
    Set RefCombinedRange = urg
End Function

Clear and Highlight

<!-- language: lang-vb -->

&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;
&#39; Purpose:      Clears the fill color of a range, and applies
&#39;               a given fill color to another range.
&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;
Sub ClearAndHighlight( _
        ByVal ClearRange As Range, _
        ByVal HighlightRange As Range, _
        ByVal HighlightColor As Long)
     ClearRange.Interior.ColorIndex = xlNone
     HighlightRange.Interior.Color = HighlightColor
End Sub

答案2

得分: 0

因为在你的Clauses表中的所有空单元格(即在数据最后一个单元格下面的每个单元格)都在更改其颜色,所以花费的时间很长。有两种方法可以修复这个问题。将这一行代码:

If Not fn Is Nothing Then

更改为:

If Not fn Is Nothing And Not IsEmpty(c.Value) Then

另一种方法是限制你正在处理的范围,这是一个更清晰的选项。目前,你在Clauses表中使用了整个列,而在你的最后一行下面有一百多万个空单元格。你可以按照以下方式调整你的代码:

Dim c As Range, fn As Range, adr As String

'>>> 开始插入
Dim strLastRow As String   ' Clauses表的最后一行

strLastRow = Sheets("Clauses").Cells(Rows.Count, 1).End(xlUp).Address  ' 仅获取Clauses的最后一行
'<<< 结束插入

With Sheets("sheet1")
    For Each c In .Range("A1", .Cells(Rows.Count, 1).End(xlUp))
        '>>> 删除以下行
        'Set fn = Sheets("Clauses").Range("A:A").Find(c.Value, , xlValues, xlWhole)
        
        '<<< 插入以下行
        Set fn = Sheets("Clauses").Range("A1", strLastRow).Find(c.Value, , xlValues, xlWhole)
        
        If Not fn Is Nothing Then
            adr = fn.Address
            c.Interior.Color = RGB(255, 100, 50)
            Do
                fn.Interior.Color = RGB(255, 100, 50)
                '>>> 删除以下行
                'Set fn = Sheets("Clauses").Range("A:A").FindNext(fn)
                
                '<<< 插入以下行
                Set fn = Sheets("Clauses").Range("A1", strLastRow).FindNext(fn)
            Loop While fn.Address <> adr
        End If
    Next
End With
英文:

It is taking so long because all the empty cells in your clauses sheet (that is every cell below your last cell with data) are having their colour changed. There are two ways you can fix this. Change the line If Not fn Is Nothing Then to be If Not fn Is Nothing And Not IsEmpty(c.Value) Then.

The other way is to restrict the range that you are processing which is a much cleaner option. Currently you are using the entire column in the Clauses sheet and a million+ cells below your last row are empty. You can adjust your code as follows:

Dim c As Range, fn As Range, adr As String

&#39;&gt;&gt;&gt; Begin insert
Dim strLastRow As String   &#39; Last row for sheet &#39;Clauses&#39;

    strLastRow = Sheets(&quot;Clauses&quot;).Cells(Rows.Count, 1).End(xlUp).Address  &#39;Get the Clauses last row once only
&#39;&lt;&lt;&lt; End insert
    
    With Sheets(&quot;sheet1&quot;)
        For Each c In .Range(&quot;A1&quot;, .Cells(Rows.Count, 1).End(xlUp))
&#39;            Set fn = Sheets(&quot;Clauses&quot;).Range(&quot;A:A&quot;).Find(c.Value, , xlValues, xlWhole)              &#39;&lt;&lt;&lt; Delete
            Set fn = Sheets(&quot;Clauses&quot;).Range(&quot;A1&quot;, strLastRow).Find(c.Value, , xlValues, xlWhole)   &#39;&lt;&lt;&lt; Insert
                If Not fn Is Nothing Then
                    adr = fn.Address
                    c.Interior.Color = RGB(255, 100, 50)
                    Do
                        fn.Interior.Color = RGB(255, 100, 50)
&#39;                        Set fn = Sheets(&quot;Clauses&quot;).Range(&quot;A:A&quot;).FindNext(fn)             &#39;&lt;&lt;&lt; Delete
                        Set fn = Sheets(&quot;Clauses&quot;).Range(&quot;A1&quot;, strLastRow).FindNext(fn)   &#39;&lt;&lt;&lt; Insert
                    Loop While fn.Address &lt;&gt; adr
                End If
        Next
    End With

答案3

得分: 0

我已经通过以下公式作为条件格式的输入来实现相同的结果(用于“Clauses”工作表):

=IF(AND(NOT(ISBLANK(A2)),IFERROR(MATCH(A2,Sheet1!A:A,0),FALSE)),TRUE,FALSE)

它的外观如下:

VBA执行速度较慢时存在空白单元格。

由于整个过程基于Excel公式,因此着色是即时完成的。

英文:

I've achieved the same result, using the following formula as an input for conditional formatting (for the "Clauses" sheet):

=IF(AND(NOT(ISBLANK(A2)),IFERROR(MATCH(A2,Sheet1!A:A,0),FALSE)),TRUE,FALSE)

It looks as follows:

VBA执行速度较慢时存在空白单元格。

As the whole thing is Excel-formula based, the colouring is done instantaneously.

huangapple
  • 本文由 发表于 2023年7月7日 06:48:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632955.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定