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)状态
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
现在我有其他要求
为了实现上述要求,我添加了以下代码
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;然后代码不能正确验证它。
任何人都可以在我错的地方帮助我吗? 以及我如何提高代码的性能...
答案 0 :(得分:0)
看看你的代码,看起来你真的很复杂,但实际上并非如此。
如果我正确收集此信息,用户将在您的excelworkbook中输入数据,并且您希望确保他们按照一些规则正确执行此操作。如果他们违反规则,你会将细胞染成红色。
更简单,更快捷的方法是使用内置的条件格式来实现excel。这也将允许您拆分代码,并且只检查实际已更改的数据:因此无需遍历所有单元格。
快速举例:
要添加此规则,请选择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
您可能会喜欢的其他提示: