【问题标题】:Using string variables within a command in VBA在 VBA 的命令中使用字符串变量
【发布时间】:2017-07-06 21:51:07
【问题描述】:

我试图让一个字符串与一个代码一起工作,在该代码中,我自动执行多个选项卡以按相同的条件进行过滤,以获得从其他工作表中获取小计的工作表。
所以,我做了一些IfElses 来检查一些标准并尝试在此分析之后进行过滤,而不是必须执行多个AutoFilters 和多个Ifs。

所以,下面的部分工作得很好,它正在相应地制作字符串 (subStr)

If subBacia = "TODOS" Then
    subStr = """<>"""
Else
    subStr = """=" & subBacia & QUOTE & " , Operator:=xlOr, Criteria2:=" & QUOTE & "=TOTAIS" & QUOTE & ""
End If

但是,我避免为多个ifs 执行的这部分不起作用:

ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=4, Criteria1:=subStr

我的想法是,它最终会成为下面的构造,例如,具有多个标准:

ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=4, Criteria1:="=AN6b" _
    , Operator:=xlOr, Criteria2:="=TOTAIS"`

那么,我做错了什么,或者我应该做什么我不知道? 编辑:这里是完整的代码

Sub Filter()
    Dim subBacia, encarregado As String
    Dim bm As String
    Dim subStr, encStr, bmStr As String

    'Application.Calculation = xlCalculationManual
    'Application.ScreenUpdating = False

    Sheets("Resumo").Select
    encarregado = Range("T3")
    subBacia = Range("T5")
    bm = Range("T4")
    Const QUOTE = """"
    On Error Resume Next

    If encarregado = "TODOS" And bm = "TODOS" And subBacia = "TODOS" Then
        Sheets("Dem. Rede").Select
        ActiveSheet.ShowAllData
        Sheets("Dem. Interceptor").Select
        ActiveSheet.ShowAllData
        Sheets("Dem.Ramal").Select
        ActiveSheet.ShowAllData
    Else
        If encarregado = "TODOS" Then
            encStr = """<>"""
        Else
            encStr = """=" & encarregado & QUOTE & " , Operator:=xlOr, Criteria2:=" & QUOTE & "=TOTAIS" & QUOTE & ""
        End If
        If bm = "TODOS" Then
            bmStr = """<>"""
        Else
            bmStr = """=" & bm & QUOTE & " , Operator:=xlOr, Criteria2:=" & QUOTE & "=TOTAIS" & QUOTE & ""
        End If
        If subBacia = "TODOS" Then
            subStr = """<>"""
        Else
            subStr = """=" & subBacia & QUOTE & " , Operator:=xlOr, Criteria2:=" & QUOTE & "=TOTAIS" & QUOTE & ""
        End If
        Debug.Print encStr
        Debug.Print bmStr
        Debug.Print subStr
        Sheets("Dem. Rede").Select
            ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=2, Criteria1:=bmStr
            ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=3, Criteria1:=encStr
            ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=4, Criteria1:=subStr
        Sheets("Dem. Interceptor").Select
            ActiveSheet.Range("$A$12:$EM$137").AutoFilter Field:=2, Criteria1:=bmStr
            ActiveSheet.Range("$A$12:$EM$137").AutoFilter Field:=4, Criteria1:=encStr
            ActiveSheet.Range("$A$12:$EM$137").AutoFilter Field:=3, Criteria1:=subStr
        Sheets("Dem.Ramal").Select
            ActiveSheet.Range("$B$11:$Z$1214").AutoFilter Field:=3, Criteria1:=bmStr
            ActiveSheet.Range("$B$11:$Z$1214").AutoFilter Field:=2, Criteria1:=encStr
            ActiveSheet.Range("$B$11:$Z$1214").AutoFilter Field:=1, Criteria1:=subStr
        Sheets("Cadastro Ramal").Select
            ActiveSheet.Range("$A$9:$K$841").AutoFilter Field:=2, Criteria1:=bmStr
    End If

    'Application.Calculation = xlCalculationAutomatic
    'Application.ScreenUpdating = True    

End Sub   

编辑:顺便说一句,Debug.Print 正在返回,例如:"=9" , Operator:=xlOr, Criteria2:="=TOTAIS"
或者干脆"&lt;&gt;"
这正是它应该的方式,但是,我似乎无法按照我希望的方式连接代码中的字符串。

【问题讨论】:

  • 我可以看到您用于通话的代码吗? ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=4, Criteria1:=subStr ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=4, Criteria1:= & subStr
  • 嘿@JoshAnstead 我已经编辑并添加了完整的代码

标签: vba excel


【解决方案1】:

您不能即时构建 VBA 代码片段并使用它们来补充您硬编码的不完整语句。我认为这在任何地方都行不通。您可以dynamically create a complete sub 并执行它,但我不建议这样做。

但是,无论如何您都不需要动态代码生成。你想预先确定参数的值,所以要明确地这样做。诀窍是您需要明确使用 Missing 特殊值来传递给您不想要的参数:

Private Type CriteriaTuple
  Criteria1 As Variant
  Operator As Variant
  Criteria2 As Variant
End Type

Private Function MissingValue(Optional ByVal DoNotPassAnything As Variant) As Variant
  If Not IsMissing(DoNotPassAnything) Then Err.Raise 5, , "I said do not pass anything"
  MissingValue = DoNotPassAnything
End Function

Sub Filter()
  ....

  dim subStr as CriteriaTuple

  if ... then
    subStr.Criteria1 = """<>"""
    subStr.Operator = MissingValue
    subStr.Criteria2 = MissingValue
  else
    subStr.Criteria1 = """<>"""
    subStr.Operator = xlOr
    subStr.Criteria2 = """=TOTAIS"""
  end if

  ...

  ActiveSheet.Range("$A$12:$EX$2025").AutoFilter Field:=4, Criteria1:=subStr.Criteria1, Operator:=subStr.Operator, Criteria2:=subStr.Criteria2
End Sub

【讨论】:

    【解决方案2】:

    除非您可以另外显示,否则我认为您不能让 VBA 将您的字符串解释为参数列表。我不明白你想用这种方法保存什么。

    【讨论】:

    • 您可以在参数中使用 IIF 函数来避免重复代码,q.v. excelmacromastery.com/vba-if/#The_IIF_function
    • 我已经添加了完整的代码,这样你就可以看到我想要实现的目标,因为我会在多张工作表中自动过滤相同的标准,我试图保存。否则我想我将不得不做很多 if 和 elses
    猜你喜欢
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多