当范围只包含一个值时,函数不会返回数组

tee*_*pee 3 excel vba excel-vba

我有一个函数用于返回一个由单列数据列表创建的数组.我一直使用这个函数的返回值作为一个伪全局变量(LINENAMES_ARRAY),我传递给许多函数.这些函数比检查它If Len(Join(LINENAMES_ARRAY)) = 0 Then或者通过带有For Each语句的项目进行检查.这是代码:

  Function LINENAMES_ARRAY() As Variant
  'returns an array of all items in the main sheet linenames column
      LINENAMES_ARRAY = Application.Transpose(MAIN.Range( _
      MAIN.Cells(MAIN_HEAD_COUNT + 1, MAIN_LINENAMES_COLUMN), _
      MAIN.Cells(LINENAMES_COUNT + 1, MAIN_LINENAMES_COLUMN)))
  End Function
Run Code Online (Sandbox Code Playgroud)

我最近偶然发现了其中一个你看不到它直到你看到它的问题,同时将这个工作簿用于一个新项目,如果数组恰好只有1个元素,那么一切都会失败.显然在这种情况下,这会返回一个值,因此Join()也会失败For Each __ in LINENAMES_ARRAY.为什么不将它视为1x1数组而不是自由值?我已经开始通过重写调用它的函数来缓解这个问题,检查它是否是一个数组,然后再做一些其他的过程.像:

For j = 1 To LINENAMES_COUNT
    LINES_BOX.AddItem lineNames(j)
Next j
Run Code Online (Sandbox Code Playgroud)

改为:

If Not IsArray(LINENAMES_ARRAY) Then
     myListBox.AddItem CStr(LINENAMES_ARRAY)
Else
    For j = 1 To LINENAMES_COUNT
       LINES_BOX.AddItem LINENAMES_ARRAY(j)
    Next j
End If
Run Code Online (Sandbox Code Playgroud)

然而,这变得混乱,并且在我的代码中添加了许多额外的检查,我希望在LINENAMES_ARRAY函数中处理.有没有办法返回1x1阵列?还是其他任何解决方法?

小智 6

如果将数组创建为单个元素数组并以数组方式填充,则该数组可以包含单个元素.

Option Explicit

Dim MAIN_HEAD_COUNT As Long
Dim LINENAMES_COUNT As Long
Dim MAIN_LINENAMES_COLUMN As Long
Dim MAIN As Worksheet

Sub stuff()
    Dim arr As Variant
    Set MAIN = Worksheets("Sheet1")
    MAIN_LINENAMES_COLUMN = 2
    MAIN_HEAD_COUNT = 2
    LINENAMES_COUNT = 2

    arr = LINENAMES_ARRAY()
    Debug.Print IsArray(arr)
    Debug.Print LBound(arr) & ":" & UBound(arr)
End Sub

Function LINENAMES_ARRAY() As Variant
    Dim a As Long, tmp() As Variant
    ReDim tmp(0 To LINENAMES_COUNT - MAIN_HEAD_COUNT)
    For a = 0 To LINENAMES_COUNT - MAIN_HEAD_COUNT
        tmp(a) = MAIN.Range(MAIN.Cells(MAIN_HEAD_COUNT + 1, MAIN_LINENAMES_COLUMN), _
                            MAIN.Cells(LINENAMES_COUNT + 1, MAIN_LINENAMES_COLUMN)).Cells(a).Value2
    Next a
    'returns an array of all items in the main sheet linenames column
    LINENAMES_ARRAY = tmp
End Function
Run Code Online (Sandbox Code Playgroud)

VBE 立即窗口的结果:

True
0:0
Run Code Online (Sandbox Code Playgroud)

  • Jeeped钉了它.您只是创建一个Variant,然后让VBA决定数据类型到底是什么(因此是Variant).VBA决定只有一个元素的值不是数组,并且很可能将其作为String转换.如果你专门创建一个数组,然后将函数返回值设置为该数组,即使它只有一个元素,它也是一个数组. (2认同)