在VBA中声明长度为0的字符串数组-不可能吗?

科姆·班德尔

真的不可能在VBA中声明0长度的数组吗?如果我尝试这样做:

Dim lStringArr(-1) As String

我收到一个编译错误,说范围没有值。如果我试图欺骗编译器并在运行时像这样重做:

ReDim lStringArr(-1)

我收到下标超出范围的错误。

我已经稍微改变了上面的内容,但是没有运气,例如

Dim lStringArr(0 To -1) As String

用例

我想将变量数组转换为字符串数组。变体数组可能是空的,因为它来自字典的Keys属性。keys属性会返回一组变体。我希望在代码中使用字符串数组,因为我有一些函数可以处理要使用的字符串数组。这是我正在使用的转换函数。由于lMaxIndex = -1,这将导致下标超出范围错误:

Public Function mVariantArrayToStringArray(pVariants() As Variant) As String()
    Dim lStringArr() As String
    Dim lMaxIndex As Long, lMinIndex As Long
    lMaxIndex = UBound(pVariants)
    lMinIndex = LBound(pVariants)
    ReDim lStringArr(lMaxIndex)
    Dim lVal As Variant
    Dim lIndex As Long
    For lIndex = lMinIndex To lMaxIndex
        lStringArr(lIndex) = pVariants(lIndex)
    Next
    mVariantArrayToStringArray = lStringArr
End Function

哈克

返回包含空字符串的单例数组。注意-这不是我们想要的。我们想要一个空数组-这样遍历它就像什么都不做。但是包含一个空字符串的单例数组通常可以工作,例如,如果我们以后想将所有字符串连接到字符串数组中。

Public Function mVariantArrayToStringArray(pVariants() As Variant) As String()
    Dim lStringArr() As String
    Dim lMaxIndex As Long, lMinIndex As Long
    lMaxIndex = UBound(pVariants)
    lMinIndex = LBound(pVariants)
    If lMaxIndex < 0 Then
        ReDim lStringArr(1)
        lStringArr(1) = ""
    Else
        ReDim lStringArr(lMaxIndex)
    End If
    Dim lVal As Variant
    Dim lIndex As Long
    For lIndex = lMinIndex To lMaxIndex
        lStringArr(lIndex) = pVariants(lIndex)
    Next
    mVariantArrayToStringArray = lStringArr
End Function

自回答以来更新

这是我用来将变量数组转换为字符串数组的函数。Comintern的解决方案似乎更高级,更通用,如果我仍然坚持使用VBA进行编码,那么我可能会切换到这一天:

Public Function mVariantArrayToStringArray(pVariants() As Variant) As String()
    Dim lStringArr() As String
    Dim lMaxIndex As Long, lMinIndex As Long
    lMaxIndex = UBound(pVariants)
    lMinIndex = LBound(pVariants)
    If lMaxIndex < 0 Then
        mVariantArrayToStringArray = Split(vbNullString)
    Else
        ReDim lStringArr(lMaxIndex)
    End If
    Dim lVal As Variant
    Dim lIndex As Long
    For lIndex = lMinIndex To lMaxIndex
        lStringArr(lIndex) = pVariants(lIndex)
    Next
    mVariantArrayToStringArray = lStringArr
End Function

笔记

  • 我使用Option Explicit。这不会改变,因为它可以保护模块中的其余代码。
共产国际

如评论中所述,您可以通过调用Split“本地”执行此操作vbNullString,如此处所述

表达式-必填。包含子字符串和定界符的字符串表达式。如果expression是零长度的string(“”),则Split返回一个空数组,即没有元素和数据的数组。

如果您需要更通用的解决方案(例如,其他数据类型),则可以SafeArrayRedim直接在oleaut32.dll中调用该函数,并请求将传递的数组重新定义为0个元素。您必须跳过几个步骤才能获得数组的基地址(这是由于该VarPtr函数的古怪)。

在模块声明部分:

'Headers
Private Type SafeBound
    cElements As Long
    lLbound As Long
End Type

Private Const VT_BY_REF = &H4000&
Private Const PVDATA_OFFSET = 8

Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias _
    "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, _
    ByVal length As Long)

Private Declare Sub SafeArrayRedim Lib "oleaut32" (ByVal psa As LongPtr, _
    ByRef rgsabound As SafeBound)

过程-向其传递一个初始化的数组(任何类型),它将删除其中的所有元素:

Private Sub EmptyArray(ByRef vbArray As Variant)
    Dim vtype As Integer
    CopyMemory vtype, vbArray, LenB(vtype)
    Dim lp As LongPtr
    CopyMemory lp, ByVal VarPtr(vbArray) + PVDATA_OFFSET, LenB(lp)
    If Not (vtype And VT_BY_REF) Then
        CopyMemory lp, ByVal lp, LenB(lp)
        Dim bound As SafeBound
        SafeArrayRedim lp, bound
    End If
End Sub

用法示例:

Private Sub Testing()
    Dim test() As Long
    ReDim test(0)
    EmptyArray test
    Debug.Print LBound(test)    '0
    Debug.Print UBound(test)    '-1
End Sub

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

DS中的Ember设置数组->不可能吗?

从JVM的角度来看,从原始数组继承是不可能的吗?

分配取消引用的字符指针真的不可能吗?

Node.js中的无限循环是不可能的吗?

在C#泛型中这是不可能的吗?

在React Native中运行mount()不可能吗?

减少Python中的循环是不可能的吗?

在导轨中组装多个模型的关系-不可能吗?

具有依赖类型的字符串文字-不可能吗?

使用EF Core 3.1为SQL Server序列获取“ NEXT VALUE FOR”-不可能吗?

Go中函数参数中的后增运算符,不可能吗?

真的不可能在Windows 10中禁用更新吗?

MySQL 8:UPDATE查询中的RANK函数不可能吗?

我可以得出结论,在cntk中不可能实现“深梦”吗?

在Windows 10中使用通配符搜索文件-不可能吗?

反应状态数组索引不可能

AMPL中不可能的推论上限

C链表中不可能的结果

不可能访问字符串变量上的属性

字符串资源新行/ n不可能?

大量的字符串应该是不可能的

不可能有一个带有泛型的基于数组的Queue吗?

垂直SSRS矩阵分组以将标题保留在同一列中?不可能吗

在Cabal安装过程中,“不可能的事情发生了”,我应该继续尝试吗?

在Racket中从端口获取任意子字符串似乎是不可能的

不可能对声明的输入强制使用整数

变量不可能设置为“未定义”

向属性添加匿名数组。不可能?

在Python中删除数据中不可能的值