【问题标题】:How to CALL functions with their respective variable names using FOR?如何使用 FOR 调用具有各自变量名的函数?
【发布时间】:2017-12-16 22:16:10
【问题描述】:

我正在尝试通过使其可读性和简洁性来改进我的代码。在名为“ModTest”的模块和名为“ABC”的 Sheet1 中,我有以下内容:

Sub Questionnaire_1()  ' ModTest
  ' do something
End Sub

Sub Questionnaire_2()  ' ModTest
  ' do something
End Sub

Sub Questionnaire_3()  ' ModTest
  ' do something
End Sub

Sub Questionnaire_4()  ' ModTest
  ' do something
End Sub

Sub Math() ' ModTest

         Dim Question As Integer 

         Question = Sheets("ABC").Range("G5").Value

         If Question = 0 Then

             ' do something

         Else
                Select Case Question

                    Case Is = 1
                        Call Questionnaire_1

                    Case Is = 2
                        Call Questionnaire_1
                        Call Questionnaire_2

                    Case Is = 3
                        Call Questionnaire_1
                        Call Questionnaire_2
                        Call Questionnaire_3

                    Case Is = 4
                        Call Questionnaire_1
                        Call Questionnaire_2
                        Call Questionnaire_3
                        Call Questionnaire_4
                 End Select
          End if
End Sub

但是,我不只使用 4 个问卷,而是 100 个。我的意图是保留 [Sub Questionnaire_1 (...) Sub Questionnaire_100] 行,但是通过消除 Select Case 来改进 for 命令中名为“Variable”的 Call 函数:

Sub Math()

Dim i, Question As Integer 
Dim Variable as String

Question = Sheets("ABC").Range("G5").Value

       If Question = 0 Then

         ' do something

       Else
           For i = 1 to Question

             Variable = "Questionnaire_" & i

             Call Variable
           Next i
       End if
 End Sub

有人可以帮忙吗?我收到以下“VBA 编译错误:预期的子、函数或属性”。


再想一想,有可能通过另一种解决方案绕过 Select Case 和 Call 功能,该解决方案也有效并避免了使用 100 个潜艇!将以上代码全部替换为新改进的后续代码,如下:

Sub Questionnaire()  ' ModTest

Dim i, f, g, Question As Integer

Question = Sheets("ABC").Range("G5").Value

    If Question = 0 Then

         ' do something

    Else

        For i = 1 To Question

           f = 18 + 2 * i
           g = 19 + 2 * i

          With Worksheets("ABC")

             .Activate
             .Range("V2").Value = i
             .Range("X2").Value = "C"
             .Range("G2").Select
               Selection.Copy
             .Range("G" & f).Select
               Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
             .Range("G3").Select
               Selection.Copy
             .Range("H" & g).Select
               Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
             .Range("X2").Value = "I"
             .Range("L5").Select
               Selection.Copy
             .Range("L" & f).Select
               Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
             .Range("L6").Select
               Selection.Copy
             .Range("M" & g).Select
               Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

          End With

        Next i
   End If
End Sub

【问题讨论】:

  • Variable = "Questionnaire_" & i。您使用& 连接字符串,并使用And 作为布尔运算符。
  • 如果你的目标是提高可读性和简洁性,你不应该一开始就使用 100 个 Subs。假设它们几乎都做相同的事情(考虑到命名),您可能应该查看参数和/或类。
  • @LuizVaughan - 你需要使用Run 而不是Call - 请参阅@SiddharthRout 对重复问题的回答:stackoverflow.com/questions/15969796/…
  • @Chrowno 谢谢。 Classes 的使用确实很有前景,但在短期内它不是那么容易掌握的技术。在学习类/参数主题时,我偶然发现了一个有趣的网站 (excelmacromastery.com)。关于你的假设,你是对的。我更新了代码。实际上,当它从“Questionnarie_1 到 100”执行时,只有几件事发生了变化。如果您知道如何实现它,我将不胜感激。

标签: excel vba


【解决方案1】:

我怀疑此代码可能对您有用。请测试一下。

Option Explicit

Sub MathTest()
    ' 17 Dec 2017
    ' "Math" is a module of VBA. (For explanation, select and press F1)
    ' Its use as a procedure name may lead to unexpected results

    Dim Ws As Worksheet
    Dim i As Integer

    Set Ws = Worksheets("ABC")
    Application.ScreenUpdating = False
    ' this loop will not run if G5 < 1
    For i = 1 To Int(Val(Ws.Range("G5").Value))
        Questionnaire i, Ws
    Next i
    Application.ScreenUpdating = True
 End Sub

Private Sub Questionnaire(ByVal Q As Integer, _
                          Ws As Worksheet)
    ' 17 Dec 2017

    Const WhatsThis As Long = 18

    ' in the next line, all items are Variants except 'Question'
    ' Dim i, f, g, Question As Integer
    Dim RowG As Long
    Dim i As Long

    RowG = WhatsThis + (2 * Q)

    With Ws
        .Range("V2").Value = Q
        .Range("X2").Value = "C"

        For i = 0 To 1
            .Cells(RowG + i, "G").Value = .Cells(2 + i, "G").Value
        Next i
    End With
End Sub

【讨论】:

  • “Variatus”,感谢您抽出宝贵时间。哇,我们现在有三种可能的解决方案!我冒昧地更改了您的代码并对其进行了调整以适应我的需要。它已经过测试并提供了链接 (drive.google.com/open?id=1jRHLOD3ig1OVW27iABxxJnrr6wPOtdgP)。最良好的祝愿。
  • 我很高兴我没有离题太远,并且很高兴我的建议有所帮助。我在睡觉的时候看到你的编辑有一些骚动。版主认为您对我的代码的自定义并没有提高我的答案的价值,因此不允许您进行编辑。这只是为了让您知道我感谢您的努力。
  • 很高兴知道这一点。祝你圣诞快乐。
猜你喜欢
  • 2011-11-16
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2013-06-15
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多