如果语句VBA

我在Excel VBA中使用IfElseIf语句为数据库search写脚本。 search是通过一个UserForm进行的,该UserForm有两个字段,标记为CountryCategory并在脚本中定义如下:

 Dim country As String Dim Category As String country = Sheets("Results").Range("D5").Value Category = Sheets("Results").Range("D6").Value 

信息在search国家方面被search和呈现,因此search运行所需的最小值是用户提供的国家在数据库中的国家。

根据用户input的标准,search将在名为“ Database的工作表中运行一个数据表,并将结果粘贴到另一个名为“ Results表中。 根据search条件,脚本将运行If语句指定的几个选项。

scheme1 – 用户提供了一个国家和一个类别,并且:

  • country存在于数据库中,但是;
  • Category不存在于特定的国家。

在这种情况下, MsgBox会popup,说用户提供的国家和类别的特定组合不存在于数据库中。 该消息将询问用户是否希望针对所提供的国家的所有条目进行search,在这种情况下。 我已经写了相应的代码如下:

 finalrow = Sheets("Database").Range("A200000").End(xlUp).Row For i = 2 To finalrow If Sheets("Database").Cells(i, 1) = country And _ (Category <> "" Or Sheets("Database").Cells(i, 3) <> Category) Then Dim question As Integer question = MsgBox("Unfortunately, the Database has no sources regarding " & Category & " in " & country & ". Would you perhaps want to broaden your search and see all sources regarding " & country & "?", vbYesNo + vbQuestion, "Empty Sheet") If question = vbYes Then Sheets("Results").Range("D6").ClearContents Category = Sheets("Results").Range("D6").Value boolRestart = True Else Sheets("Results").Range("D5").ClearContents Sheets("Results").Range("D6").ClearContents Me.Hide WelcomeForm.Show Exit Sub End If 

scheme2 – 用户提供了一个country和:

  • country存在于数据库中;
  • 用户还提供了针对特定国家的数据库中存在的Category ;
  • 用户已将Category字段留空。

在这种情况下,search将运行。 这是写在脚本如下:

 ElseIf Sheets("Database").Cells(i, 1) = country And _ (Sheets("Database").Cells(i, 3) = Category Or Category = "") Then 'Copy the headers of the "Database" sheet With Sheets("Database") .Range("A1:I1").Copy End With Sheets("Results").Range("B10:J10").PasteSpecial 'Copy the rows of the table that match the search query With Sheets("Database") .Range(.Cells(i, 1), .Cells(i, 9)).Copy End With Sheets("Results").Range("B20000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats End If 

我试图以几种不同的方式编写脚本,但search引擎不能按我的意愿工作。 现在发生的事情是,当我input一个我知道在数据库中的国家时,无论是否input一个CategoryOPTION 1总是被触发。 我已经尝试完全删除OPTION 1 ,只运行一个带有OPTION 2If语句,并且search运行正常,并填写了CountryCategory ,但是,只要OPTION 1在代码中,无论用户input什么内容,这总是运行的选项。

完整的代码在这里,供您参考:

 Dim country As String 'Search query country, user-inputted Dim Category As String 'Search query category user-inputted Dim finalrow As Integer Dim i As Integer 'row counter Dim ws As Worksheet Set ws = Sheets("Database") country = Sheets("Results").Range("D5").Value Category = Sheets("Results").Range("D6").Value finalrow = Sheets("Database").Range("A200000").End(xlUp).Row For i = 2 To finalrow If Sheets("Database").Cells(i, 1) = country And _ (Category <> "" Or Sheets("Database").Cells(i, 3) <> Category) Then Dim question As Integer question = MsgBox("Unfortunately, the Database has no sources regarding " & Category & " in " & country & ". Would you perhaps want to broaden your search and see all sources regarding " & country & "?", vbYesNo + vbQuestion, "Empty Sheet") If question = vbYes Then Sheets("Results").Range("D6").ClearContents Category = Sheets("Results").Range("D6").Value boolRestart = True Else Sheets("Results").Range("D5").ClearContents Sheets("Results").Range("D6").ClearContents Me.Hide WelcomeForm.Show Exit Sub End If ElseIf Sheets("Database").Cells(i, 1) = country And _ (Sheets("Database").Cells(i, 3) = Category Or Category = "") Then 'Copy the headers of the "Database" sheet With Sheets("Database") .Range("A1:I1").Copy End With Sheets("Results").Range("B10:J10").PasteSpecial 'Copy the rows of the table that match the search query With Sheets("Database") .Range(.Cells(i, 1), .Cells(i, 9)).Copy End With Sheets("Results").Range("B20000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats End If Next I 

非常感谢您的帮助。

问题是如果任何一行不符合标准,你的代码将进入选项1,而如果每一行都不符合标准,我们只希望它失败。 因此,我们需要对数据进行两次扫描,首先检查是否有任何传递行(如果不是那么我们提供清除类别),然后再复制相关数据。

尝试这个:

 Option Explicit Private Sub CommandButton1_Click() Dim country As String 'Search query country, user-inputted Dim Category As String 'Search query category user-inputted Dim finalrow As Integer Dim i As Integer 'row counter Dim ws As Worksheet Dim foundMatch As Boolean foundMatch = False Set ws = Sheets("Database") country = Sheets("Results").Range("D5").Value Category = Sheets("Results").Range("D6").Value finalrow = Sheets("Database").Range("A200000").End(xlUp).Row For i = 2 To finalrow If Sheets("Database").Cells(i, 1) = country And _ (Sheets("Database").Cells(i, 3) = Category Or Category = "") Then foundMatch = True End If Next i If Not foundMatch Then Dim question As Integer question = MsgBox("Unfortunately, the Database has no sources regarding " & Category & " in " & country & ". Would you perhaps want to broaden your search and see all sources regarding " & country & "?", vbYesNo + vbQuestion, "Empty Sheet") If question = vbYes Then Sheets("Results").Range("D6").ClearContents Category = Sheets("Results").Range("D6").Value Else Sheets("Results").Range("D5").ClearContents Sheets("Results").Range("D6").ClearContents Me.Hide WelcomeForm.Show Exit Sub End If End If For i = 2 To finalrow If Sheets("Database").Cells(i, 1) = country And _ (Sheets("Database").Cells(i, 3) = Category Or Category = "") Then 'Copy the headers of the "Database" sheet With Sheets("Database") .Range("A1:I1").Copy End With Sheets("Results").Range("B10:J10").PasteSpecial 'Copy the rows of the table that match the search query With Sheets("Database") .Range(.Cells(i, 1), .Cells(i, 9)).Copy End With Sheets("Results").Range("B20000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats End If Next i End Sub 

我认为你应该把你的代码分成三个独立的子程序: – 第一个将在用户触发search时运行,然后它必须检查country是否有一个有效的值(如果没有给出错误消息),然后检查Category是否有值,如果它有值,则转到第二个子程序,如果它是空的,则转到第三个子程序; – 第二个子程序必须得到countryCategoryvariables的值,并返回预期的结果; – 第三个子程序只能得到countryvariables并返回预期的结果。

你可以把这两个variables放在模块的开头(在任何Sub之前,使用Private而不是Dim ),以使它们可以被该模块中的任何子程序访问,或者你可以创build带有参数的子程序,在这里你可以传递值到另一个Sub而不使它们该模块中的所有Sub都可以访问。 我更喜欢第二种select。 如果你不知道如何将parameter passing给另一个模块,那就是一个例子:

 Sub QueryCountryAndCategory (QCountry as String, QCategory as String) 

在这个SubQCountryQCategory是只能在该模块中访问的variables,它将接收调用者子例程传递的值,如下所示(使用variables):

 QueryCountryAndCategory(country, Category) 

或者像这样:

 QueryCountryAndCategory(QCountry:=country, QCategory:=Category) 

请记住,长码难以维护,难以testing。 当你的代码变长的时候,总是考虑把它分成几个Sub或者Function (它会返回一个值)。 testing也比较容易,因为你可以单独运行每个Sub来查看它是否正常工作。

On (Category <> "" Or Sheets("Database").Cells(i, 3) <> Category) ThenORreplace为AND

该检查必须考虑两者

  1. category不是空的AND
  2. category未find

中频工作的方式是,如果其中任何一个都会触发

  1. category不是空的(所以,如果你在categoryinput任何东西,它将在这里匹配)
  2. category不匹配(如果该category是空的,但它实际上有什么在列表上)