vb6 数组,上限为 -1

发布于 2024-11-30 00:54:15 字数 430 浏览 0 评论 0原文

如果数组没有项,某些函数(例如 Split())将返回一个数组,其中 -1 为上限,0 为下限,如果数组没有项,例如:

Dim s() As String
s = Split("", ",")
Debug.Print UBound(s)
Debug.Pring LBound(s)

在这种情况下 UBound(s) 将等于 - 1 和 LBound(s) 将等于 0。我有相当多的代码检查上限是否为 -1,以查看数组是否有值。这很好用。

问题是我现在想将数组数据类型从字符串更改为长整型。我似乎无法创建一个上限为 -1 、下限为 0 的 long 数组,并且 Split()Join() 函数只能在字符串数组。

我希望能够返回一个上限为-1 的长数组。这可能吗?

Some functions such as Split() will return an array with -1 for the upper bound and zero for the lower bound if the array has no items, eg:

Dim s() As String
s = Split("", ",")
Debug.Print UBound(s)
Debug.Pring LBound(s)

In this case UBound(s) will equal -1 and LBound(s) will equal 0. I have a fair amount of code checking for -1 on the upper bound to see if the array has values or not. This works great.

The problem is that I now want to change the array data type from string to long. I cannot seem to create an array of longs with an upper bound of -1 and a lower bound of 0, and the Split() and Join() functions only operate on string arrays.

I would like to be able to return a long array with an upper bound of -1. Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半寸时光 2024-12-07 00:54:15

我不认为你可以在 VB6 中自己完成它。但是,如果您愿意使用 Windows API 函数SafeArrayCreateVector,您可以做到:

Private Declare Function LongSplitEmulator Lib "OLEAUT32.DLL" Alias "SafeArrayCreateVector" _
    (Optional ByVal vt As VbVarType = vbLong, _
     Optional ByVal low As Long = 0, _
     Optional ByVal count As Long = 0) As Long()

Dim a() As Long
a = LongSplitEmulator()
MsgBox UBound(a)

如果您需要对其他数据类型执行此操作,您可以更改 vt 参数。

请注意,我想我最初是从 Vi2 对此的回答中发现这一点的 讨论

I don't think you can do it in VB6 it self. However, if you're willing to use the Windows API function SafeArrayCreateVector you can do it:

Private Declare Function LongSplitEmulator Lib "OLEAUT32.DLL" Alias "SafeArrayCreateVector" _
    (Optional ByVal vt As VbVarType = vbLong, _
     Optional ByVal low As Long = 0, _
     Optional ByVal count As Long = 0) As Long()

Dim a() As Long
a = LongSplitEmulator()
MsgBox UBound(a)

If you need to do it for other datatypes you can change the vt parameter.

Please note, I think I originally found out about this from Vi2's answer to this discussion.

沉睡月亮 2024-12-07 00:54:15

您可以编写自己的 split 函数来执行此操作:

Private Sub SplitLongs(ByVal strData As String, ByRef lng() As Long)
    Dim i As Integer
    Dim s() As String
    s = Split(strData, ",")
    If UBound(s) = -1 Then
        ReDim lng(-1 To -1)
    Else
        ReDim lng(LBound(s) To UBound(s))
        For i = LBound(s) To UBound(s)
            If IsNumeric(s(i)) Then lng(i) = s(i)
        Next
    End If
End Sub

You could write your own split function to do this:

Private Sub SplitLongs(ByVal strData As String, ByRef lng() As Long)
    Dim i As Integer
    Dim s() As String
    s = Split(strData, ",")
    If UBound(s) = -1 Then
        ReDim lng(-1 To -1)
    Else
        ReDim lng(LBound(s) To UBound(s))
        For i = LBound(s) To UBound(s)
            If IsNumeric(s(i)) Then lng(i) = s(i)
        Next
    End If
End Sub
雪花飘飘的天空 2024-12-07 00:54:15

VB6 的一个问题是无法可靠地创建或检测空(或未初始化)数组。有时,可以通过检查上限是否大于下限来检测未初始化的数组;然而,这既不优雅也没有记录。正确完成此类操作的最佳方法是将数组包含在 Variant 中,并将 Variant 设置为 Empty 以取消初始化数组。然后,您可以使用诸如 If VarType(v) = vbEmpty ... 之类的检查

One problem with VB6 is there is no way to reliably create or detect an empty (or uninitialized) array. Sometimes, it is possible to detect an uninitialized array by checking whether the upper-bound is greater than the lower-bound; however, this is neither elegant nor documented. The best way to accomplish such a thing properly is to enclose the array in a Variant, and set the Variant to Empty to deinitialize the array. You may then use a check such as If VarType(v) = vbEmpty ...

分开我的手 2024-12-07 00:54:15

另一种方法是强类型的“工厂”函数:

Private Declare Function SafeArrayRedim Lib "oleaut32.dll" (ByVal ArrayPtr As Long, ByRef DataPtr As tagSAFEARRAYBOUND) As Long

Private Type tagSAFEARRAYBOUND
  cElements As Long
  lLbound As Long
End Type

Public Type Feed
  ID As String
  Name As String
  Active As Boolean
  BasePath As String
End Type

Public Sub EmptyFeedArray(ByRef Arr() As Feed)
Dim Data As tagSAFEARRAYBOUND
Dim lngErr As Long

  'Redim to one item
  ReDim Arr(0 To 0)
  'Reset the safe array to empty
  lngErr = SafeArrayRedim(Not Not Arr, Data)
  'Raise any errors
  If lngErr <> 0 Then Err.Raise lngErr
End Sub

我认为这也适用于整数类型。

Another way is a strongly typed "factory" function:

Private Declare Function SafeArrayRedim Lib "oleaut32.dll" (ByVal ArrayPtr As Long, ByRef DataPtr As tagSAFEARRAYBOUND) As Long

Private Type tagSAFEARRAYBOUND
  cElements As Long
  lLbound As Long
End Type

Public Type Feed
  ID As String
  Name As String
  Active As Boolean
  BasePath As String
End Type

Public Sub EmptyFeedArray(ByRef Arr() As Feed)
Dim Data As tagSAFEARRAYBOUND
Dim lngErr As Long

  'Redim to one item
  ReDim Arr(0 To 0)
  'Reset the safe array to empty
  lngErr = SafeArrayRedim(Not Not Arr, Data)
  'Raise any errors
  If lngErr <> 0 Then Err.Raise lngErr
End Sub

I think this also works with integral types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文