使用' For Each'时出错循环和'如果' excel vba中的声明

时间:2015-01-27 10:45:25

标签: excel-vba vba excel

Excel VBA - 使用' For Each'时出错循环和'如果'言。

我有一本excel工作簿;有两张纸:

第一张表是:' Jurisdictions'其中有三列:

国家(B栏),州(C栏)和城市(D栏)

此表格为每个城市提供单一条目。

但是,由于每个城市都列在不同的行上,州和国家的名称(城市所属的名称)可以在多行上重复。

对于Ex:

Col B   |  Col C   |   Col D   |
--------------------------------
U.S.    | New York |  Buffalo  |
U.S.    | New York | Manhattan |

(这是我的两行)

我有另一张纸:Sheet1;

这里我也有三个相同的栏目; (还有20个其他专栏)

这三栏我将在“管辖区”的三栏中进行验证。片。 (Sheet1中只列出了少数“司法管辖区”;这些可以是任何顺序,可以是任何国家/地区)

验证规则是:

1)对于国家

  • 国家/地区名称只能是单个值。
  • 应与'国家'下的姓名匹配管辖权表中的一栏。
  • 应忽略案例(大写/小写)

2)状态

  • 可以将一个或多个值仅用分号分隔(要用分号分隔这些值,我已编写了不同的代码并且工作正常)
  • 此单元格中的条目甚至可以是' All'
  • 所有州名称应与州'州'下列出的州相匹配。管辖表栏目。 (如果列出了多个条目;应首先根据分隔符分隔 - 分号然后进行比较)
  • 应忽略案件(大写/小写);应修剪州名前后的额外空格。

3)城市

  • 可以使用分号分隔一个或多个值。
  • 此单元格中的条目可以是'全部'也
  • 所有城市名称应与“城市”中列出的城市相匹配。管辖表栏目。 (如果列出了多个条目;应首先根据分隔符分隔 - 分号然后进行比较)
  • 应忽略案件(大写/小写);应修剪州名前后的额外空格。

我有以下代码正确验证国家,州和城市。 (语言 - 拼写。)

即。

Col B   |  Col C   |       Col D        |
-----------------------------------------
U.S.    | New York | Buffalo            |
U.S.    | New York | Manhattan; Buffalo |
India   | Karnataka| Bangalore          |

它还可以正确验证层次结构。

Dim nLastRow As Long
Dim nLastRowSheet2 As Long
Dim rngFnder As Range
Dim strFndAddress As String

Dim stString As String
Dim stArray() As String

'Get the last row
'Dim lastRow As Integer
nLastRow = Sheets("Sheet1").Cells(Rows.Count, 2).End(xlUp).Row
nLastRowSheet2 = Sheets("Jurisdictions").Cells(Rows.Count, 2).End(xlUp).Row

Dim c As Range
Dim d As Range
Dim e As Variant

'Turn screen updating off to speed up macro code.
'User won't be able to see what the macro is doing, but it will run faster.
Application.ScreenUpdating = False

For Each c In Worksheets("Sheet1").Range("D2:D" & nLastRow)
stString = c
stArray() = Split(stString, ";")
For Each e In stArray()
    e = Trim(e)

    strFndAddress = ""
    On Error Resume Next

        Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).Find(e)

        If rngFnder Is Nothing And c <> "All" Then
            c.Interior.Color = vbRed

        Else
            strFndAddress = rngFnder.Address
            Do
                If c.Offset(, -1) = rngFnder.Offset(, -1) And c.Offset(, -2) = rngFnder.Offset(, -2) Then
                    strFndAddress = ""
                    Exit Do
                Else

                    Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).FindNext(rngFnder)

                End If
            Loop While Not rngFnder Is Nothing And rngFnder.Address <> strFndAddress
        End If

        If rngFnder.Address = strFndAddress Then
            c.Interior.Color = vbRed
        End If
    On Error GoTo 0
    Set c = Nothing
    strFndAddress = ""
Next
Next

现在我有其他要求

  • &#39;州&#39;中可列出多个州。细胞只用分号分开。
  • 如果州内列出多个州;那么城市的相邻单元应该(强制性地)具有价值&#34; All&#34;只要。 (好像列出了多个状态,然后上面的代码无法正确验证层次结构)
  • 状态单元格可能具有&#34;全部&#34; (即所有州;没有单独列出的州)
  • 如果州小区有价值&#34;全部&#34;然后相邻的城市小区应该(强制性地)具有价值&#34;所有&#34;仅
  • 可能会出现在State下列出单个州值的情况,但仍然相邻的城市单元格可以有值&#34;所有&#34;

为了实现上述要求,我添加了以下代码

For Each c In Worksheets("Sheet1").Range("D2:D" & nLastRow)
        If c.Offset(, -1) = "All" And c = "All" Then
            c.Interior.Color = vbWhite
        End If
Next

和...

For Each c In Worksheets("Sheet1").Range("D2:D" & nLastRow)
    If c = "All" Then
    stString = c.Offset(, -1)
    stArray() = Split(stString, ";")
    End If
        For Each e In stArray()
        e = Trim(e)
        strFndAddress = ""

        On Error Resume Next

        Set rngFnder = Sheets("Jurisdictions").Range("C2:C" & nLastRowSheet2).Find(e)

        If rngFnder Is Nothing And e <> "All" Then
            'c.Interior.Color = c.Interior.Color (Do Nothing)
        Else
            strFndAddress = rngFnder.Address
            Do
            If c.Offset(, -2) = rngFnder.Offset(, -2) Then
                    strFndAddress = ""
                    c.Interior.Color = vbWhite
                    Exit Do
            Else
                    Set rngFnder = Sheets("Jurisdictions").Range("C2:C" & nLastRowSheet2).FindNext(rngFnder)

            End If
            Loop While Not rngFnder Is Nothing And rngFnder.Address <> strFndAddress
        End If

        If rngFnder.Address = strFndAddress Then
        'c.Interior.Color = c.Interior.Color (Do Nothing)
        End If
        On Error GoTo 0
        Set c = Nothing
        strFndAddress = ""

    Next
 Next

最后一个代码有点错误。

如果&#39;状态&#39;细胞有一个单一的状态和相邻的城市&#39;细胞有价值&#34;所有&#34; :它正确验证了它。

可是;如果&#39; State&#39;细胞有多个状态用分号隔开;和邻近的城市&#39;细胞有价值&#34;所有&#34;然后代码不能正确验证它。

任何人都可以在我错的地方帮助我吗? 以及我如何提高代码的性能...

2 个答案:

答案 0 :(得分:0)

看看你的代码,看起来你真的很复杂,但实际上并非如此。

如果我正确收集此信息,用户将在您的excelworkbook中输入数据,并且您希望确保他们按照一些规则正确执行此操作。如果他们违反规则,你会将细胞染成红色。

更简单,更快捷的方法是使用内置的条件格式来实现excel。这也将允许您拆分代码,并且只检查实际已更改的数据:因此无需遍历所有单元格。

快速举例:

  • 如果州内列出多个州;那么城市的相邻单元应该(强制性地)具有价值&#34; All&#34;只要。 (好像列出了多个状态,然后上面的代码无法正确验证层次结构) 您声明多个状态将以冒号分隔。因此,您需要一条规则来说明:如果我在B列下的单元格包含&#34 ;;&#34;然后我的B栏下的单元格必须包含&#34; All&#34;。如果不是这样,我想在C列红色下为单元格着色。

要添加此规则,请选择C列的第一个单元格,然后选择&#34;条件格式&#34;从Excel的“主页”选项卡; s功能区。然后,您创建一个新规则,并选择使用公式来确定要格式化的单元格。 你需要的公式是 &#34; = NOT(ISERROR(FIND(&#34 ;;&#34 ;; B1)))&#34; 然后将格式设置为红色填充并保存规则。

此规则现在适用于第一行,为了使其适用于整个列,您可以去管理规则并调整&#34;适用于&#34;字段为$ C:$ C或您可以将格式复制到要使用的单元格。

您可以为工作簿上的每个规则创建条件格式设置规则。您还可以编写特定规则的函数,这些规则在Excel的本机功能中无法轻松表达。

这将使您的检查变得简单易用,但它也会使您的用户反馈即时:只要他们输入值,就会应用规则。

答案 1 :(得分:0)

首先,请允许我说明我之前回答中的方法可以轻松应用于包含数据的工作簿,并且是最好的前进方式。

但是当你要求输入你的代码时,也许你应该看看你的第二部分。如果State有多个州,并且州可以在司法管辖区标签上找到,那么您的代码将转到以下其他块:

strFndAddress = rngFnder.Address
Do
    If c.Offset(, -2) = rngFnder.Offset(, -2) Then
        strFndAddress = ""
        c.Interior.Color = vbWhite
        Exit Do
    Else
        Set rngFnder = Sheets("Jurisdictions").Range("C2:C" & nLastRowSheet2).FindNext(rngFnder)
    End If
Loop While Not rngFnder Is Nothing And rngFnder.Address <> strFndAddress

这个区块对&#34; All&#34;值。

此外,这条线让我感到困惑(不止一次):

c.Interior.Color = c.Interior.Color

您可能会喜欢的其他提示:

  • 重命名您的变量,以便您可以真正阅读它们所代表的内容:&#34; cityName&#34;而不是&#34; e&#34;和cityCell而不是&#34; c&#34;有很大的不同。
  • 使用工作表的UsedRange确定最后一行和列。它比使用End函数更快,更稳定。
  • 请勿使用On Error Resume Next。这将压制任何错误并使之成为现实 很难找到发生的任何错误。