【问题标题】:Calling a function that returns an ArrayList调用返回 ArrayList 的函数
【发布时间】:2020-07-10 00:09:08
【问题描述】:

我对其他编程语言(如 java 和 C++)最有经验。 VBA 对我来说仍然很新,我几乎不知道我在做什么。我试图从函数返回一个数组列表,但我不断收到错误 5 - 无效的过程调用或参数。

Dim months As ArrayList
Dim temp As Integer

Set months = New ArrayList

'Copy and Paste State and Quarter Specific Data
Sheets("The Data (2)").Select
ActiveSheet.Range("$A:$T").AutoFilter Field:=6, Criteria1:=stateName
months = getMonths(Year, Quarter)
ActiveSheet.Range("$A:$T").AutoFilter Field:=17, Criteria1:=months.Item(0), Operator:=xlOr, Criteria2:=months.Item(1), Operator:=xlOr, Criteria3:=months.Item(2)
Range("$A$1:$$T$1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Windows("State Rate Planning Template.xlsm").Activate
Sheets(3).Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Range("A1").Select

我在“months = getMonths(Year, Quarter)”处收到错误消息。 Year 和 Quarter 是在我这里的代码上方声明的字符串。

这里是getMonths函数:

Function getMonths(Year As String, Quarter As String) As ArrayList

    Dim i As Integer
    Dim month As String
    Dim monthList As ArrayList
    
    Set monthList = New ArrayList
    
    If (StrComp(Quarter, "1", compare) = 0) Then
        For i = 1 To 3
            month = Year & "-0" & i
            monthList.Add month
        Next i
    
    ElseIf (StrComp(Quarter, "2", compare) = 0) Then
        For i = 4 To 6
            month = Year & "-0" & i
            monthList.Add month
        Next i
    
    ElseIf (StrComp(Quarter, "3", compare) = 0) Then
        For i = 7 To 9
            month = Year & "-0" & i
            monthList.Add month
        Next i
    
    ElseIf (StrComp(Quarter, "4", compare) = 0) Then
        For i = 10 To 12
            month = Year & "-" & i
            monthList.Add month
        Next i
    
    End If
    
    Set getMonths = monthList

End Function

对于 VBA 新手的任何帮助将不胜感激 :)

【问题讨论】:

  • ArrayList 不是 VBA 已知的数据类型。无需查看其余代码,请从 Dim months As Variant 开始。请注意,您不需要 Select 任何东西。 Range("$A$1:$$T$1").Select: Range(Selection, Selection.End(xlDown)).Select: Selection.Copy 的效果是Range("$A$1:$$T$1").Copy - 而$$T$1 是语法错误.
  • 我假设您添加了对 mscorlib.dll 的引用。即使这样,代码也无法编译。在每个模块/类的顶部添加 Option Explicit,然后是 Debug/Compile。更正您的代码并更新您的问题。

标签: excel vba function arraylist compiler-errors


【解决方案1】:

请试试这个代码。

Private Sub Test()
    ' 066
    
    Dim Months()    As String
    Dim Temp        As Integer
    
    Months = getMonths(2020, 4)
    For Temp = 1 To 3
        Debug.Print Months(Temp)
    Next Temp
End Sub

Function getMonths(ByVal Year As Integer, _
                   ByVal Quarter As Integer) As String()
    ' 066

    Dim Fun(1 To 3) As String               ' function return array
    Dim i           As Integer
    
    For i = 1 To 3
        Fun(i) = Format(((Quarter - 1) * 3) + i, CStr(Year) & "-00")
    Next i
    getMonths = Fun
End Function

【讨论】:

    【解决方案2】:

    将错误行改为

    Set months = getMonths(Year, Quarter)
    

    你不需要这条线

    Set months = New ArrayList
    

    months 持有对对象的引用(使用 c++ 和 java 术语),要设置该引用,您需要使用 VBA 的 Set 关键字。

    编辑:

    如果你使用@Variatus 的getMonths() 函数(它返回VBA 自己的Array,我很确定你可以像这样简化你的过滤器:

    ActiveSheet.Range("$A:$T").AutoFilter Field:=17, Criteria1:=months
    

    这没有经过测试,我需要更正,因为数组可能需要是一个乱码。不过试试也无妨。

    【讨论】:

      【解决方案3】:

      @Super Symmetry 的回答正是你需要继续下去的。

      可能偶然发现这个问题的其他人应该知道,为了能够直接使用 VBA 中的 ArrayList 类型(即在early binding 中),必须从工具/参考/浏览中添加对 mscorlib.dll 的引用,然后浏览到正确的 .NET Framework 文件夹(例如 C:\Windows\Microsoft.NET\Framework\v4.#.#####)并选择文件 mscorlib.tlb。后期绑定会让您的宏在具有不同版本 .NET 框架 (YMMV) 的计算机上运行,​​但会牺牲 Intellisense。

      您提到您是 VBA 新手,所以这里有一些附加信息。

      Option Explicit statement

      在所有模块和类模块的顶部使用 Option Explicit。您可以通过检查工具/选项/编辑器/需要变量声明来配置 VBA 编辑器自动为您执行此操作。然后您可以使用 Debug / Compile 快速查找问题。

      How to avoid using select in Excel VBA

      对于健壮和干净的代码,请避免使用 select 方法。如果您录制宏,则仅用于发现目的;使用这个流行答案中给出的技术清理它们。

      最后,我忍不住缩短了您的 getMonths 函数。这里有一个测试子:

      Option Explicit
      
      Function getMonths(iYear As Integer, iQuarter As Integer) As ArrayList
          Dim monthList As ArrayList
          Dim i As Byte
          Dim item As String
          
          Set monthList = New ArrayList
          
          'Assumption: iYear and iQuarter are both within valid ranges.
          For i = (iQuarter - 1) * 3 + 1 To (iQuarter - 1) * 3 + 3
              item = CStr(iYear) & "-" & Format(i, "00")
              monthList.Add item
          Next
          
          Set getMonths = monthList
      End Function
      
      Public Sub Test()
          Dim months As ArrayList
          Dim iYear As Integer
          Dim iQuarter As Integer
          Dim monthItem As Variant
          
          iYear = 2020
          For iQuarter = 1 To 4
              Set months = getMonths(iYear, iQuarter)
              For Each monthItem In months
                  Debug.Print monthItem
              Next
          Next
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-03
        • 2020-07-21
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 2015-03-09
        • 1970-01-01
        相关资源
        最近更新 更多