当数组为空时处理错误 9

发布于 2024-09-30 18:28:39 字数 531 浏览 3 评论 0原文

我正在编写一个脚本,它将循环遍历 Excel 电子表格并查找所选单元格是否有重复项。如果存在重复项,则该函数将返回一个数组,其中的行是重复的,并创建一条注释来告诉我这些行。

我已经能够处理错误 0,但现在当我使用 UBound 函数检查数组中是否有元素时,出现错误 9。

如何验证整数数组是否为空?

Function IsArrayEmpty(anArray As Variant) As Boolean
    Dim i As Integer

    On Error Resume Next
        i = UBound(anArray, 1)
    Select Case (Err.Number)
        Case 0
            IsArrayEmpty = True
        Case 9
            IsArrayEmpty = True
        Case Else
            IsArrayEmpty = False
    End Select
End Function

I am writing a script that will loop through an Excel spreadsheet and find if there are duplicates of selected cells. If there are duplicates then the function will return an array of which rows are duplicates and create a comment to tell me the rows.

I have been able to handle error 0 but now I am getting error 9 when I check if there are elements in the array using the UBound function.

How do I validate if the array of integers is empty?

Function IsArrayEmpty(anArray As Variant) As Boolean
    Dim i As Integer

    On Error Resume Next
        i = UBound(anArray, 1)
    Select Case (Err.Number)
        Case 0
            IsArrayEmpty = True
        Case 9
            IsArrayEmpty = True
        Case Else
            IsArrayEmpty = False
    End Select
End Function

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

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

发布评论

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

评论(9

儭儭莪哋寶赑 2024-10-07 18:28:39

尝试检查一个空数组:

Dim arr() As String

If (Not arr) = -1 Then
   Debug.Print "empty"
Else
   Debug.Print "UBound is " & UBound(X)
End If  

HTH!

Try this to check an empty array:

Dim arr() As String

If (Not arr) = -1 Then
   Debug.Print "empty"
Else
   Debug.Print "UBound is " & UBound(X)
End If  

HTH!

霞映澄塘 2024-10-07 18:28:39

您的函数失败,因为如果 UBound() 没有引发错误(即数组已确定尺寸),则 Err.Number 为 0 并且:

Case 0
  IsArrayEmpty = True

执行后返回不正确的结果。

最简单的方法是捕获错误:

Function IsArrayEmpty(anArray As Variant) As Boolean
On Error GoTo IS_EMPTY
If (UBound(anArray) >= 0) Then Exit Function
IS_EMPTY:
    IsArrayEmpty = True
End Function

Your function is failing because if there is no error raised by UBound() (i.e. the array is dimensioned) then Err.Number is 0 and:

Case 0
  IsArrayEmpty = True

is executed returning an incorrect result.

The simplest way is to just trap the error:

Function IsArrayEmpty(anArray As Variant) As Boolean
On Error GoTo IS_EMPTY
If (UBound(anArray) >= 0) Then Exit Function
IS_EMPTY:
    IsArrayEmpty = True
End Function
剑心龙吟 2024-10-07 18:28:39

你的数组变体是Empty还是Empty()?

'Empty' 是一个未初始化的变体:IsEmpty(myVar) 将返回 true...并且您可能会被愚弄,认为您有一个空数组(这是 'Empty()',而不是 'Empty' - 尝试跟上,那里将在此类之后进行一个简短的测试),因为 IsEmpty(myArray) 也返回 True。

Dim myVar as Variant      ' this is currently Empty, and Ubound returns an error
Dim myArray() as variant ' this is currently Empty(), and Ubound returns an error

Redim myVar(0 to 0) ' 这不再是空的,并且有一个有效的 Ubound
Redim myArray(0 to 0) ' 这不再是空的,并且有一个有效的 Ubound

检查 myVar 的可靠方法是 TypeName(myVar) - 如果它是数组,则名称包含括号:

  
If Instr(Typename(myVar), "(") > 0 then  

    ' we now know it is an array  
    If Not IsEmpty(myVar) Then  

       ' We can now check its dimensions  
        If Ubound(myVar) > 0  
             ' insert error-free code here  
        Endif  

    Endif  

Endif  

完整答案是 Excellerando

Is your array variant Empty or Empty()?

'Empty' is an uninitialised variant: IsEmpty(myVar) will return true... And you could be fooled into thinking you have an empty array (which is 'Empty()', not 'Empty' - try to keep up, there will be a short test after this class) because IsEmpty(myArray) returns True, too.

Dim myVar as Variant      ' this is currently Empty, and Ubound returns an error
Dim myArray() as variant ' this is currently Empty(), and Ubound returns an error

Redim myVar(0 to 0) ' this is no longer empty, and has a valid Ubound
Redim myArray(0 to 0) ' this is no longer empty, and has a valid Ubound

A reliable way to check myVar is TypeName(myVar) - if it's an array, the name contains brackets:

  
If Instr(Typename(myVar), "(") > 0 then  

    ' we now know it is an array  
    If Not IsEmpty(myVar) Then  

       ' We can now check its dimensions  
        If Ubound(myVar) > 0  
             ' insert error-free code here  
        Endif  

    Endif  

Endif  

The full answer is 'Detecting an array variant in Excel VBA' on Excellerando.

或十年 2024-10-07 18:28:39

Chip Pearson 几年前就给出了答案,现在仍然有效。这是我的图书馆已经使用了近四年的功能。

Public Function IsArrayEmpty(arr As Variant) As Boolean
    Dim lb As Long
    Dim ub As Long

    Err.Clear
    On Error Resume Next

    If IsArray(arr) = False Then
        ' we weren't passed an array, return True
        IsArrayEmpty = True
    End If

    ' Attempt to get the UBound of the array. If the array is
    ' unallocated, an error will occur.
    ub = UBound(arr, 1)
    If (Err.Number <> 0) Then
        IsArrayEmpty = True
    Else
        ''''''''''''''''''''''''''''''''''''''''''
        ' On rare occasion, under circumstances I
        ' cannot reliably replicate, Err.Number
        ' will be 0 for an unallocated, empty array.
        ' On these occasions, LBound is 0 and
        ' UBound is -1.
        ' To accommodate the weird behavior, test to
        ' see if LB > UB. If so, the array is not
        ' allocated.
        ''''''''''''''''''''''''''''''''''''''''''
        Err.Clear
        lb = LBound(arr)
        If lb > ub Then
            IsArrayEmpty = True
        Else
            IsArrayEmpty = False
        End If
    End If

    Err.Clear
End Function

基本上,它检查以确保您传递了一个数组,然后尝试查找上限(如果数组为空,则会抛出错误),最后将下限与上限进行比较以确保数组确实存在不为空。

Chip Pearson gave the answer years ago and it still works. Here's the function I've had in my library for almost four years.

Public Function IsArrayEmpty(arr As Variant) As Boolean
    Dim lb As Long
    Dim ub As Long

    Err.Clear
    On Error Resume Next

    If IsArray(arr) = False Then
        ' we weren't passed an array, return True
        IsArrayEmpty = True
    End If

    ' Attempt to get the UBound of the array. If the array is
    ' unallocated, an error will occur.
    ub = UBound(arr, 1)
    If (Err.Number <> 0) Then
        IsArrayEmpty = True
    Else
        ''''''''''''''''''''''''''''''''''''''''''
        ' On rare occasion, under circumstances I
        ' cannot reliably replicate, Err.Number
        ' will be 0 for an unallocated, empty array.
        ' On these occasions, LBound is 0 and
        ' UBound is -1.
        ' To accommodate the weird behavior, test to
        ' see if LB > UB. If so, the array is not
        ' allocated.
        ''''''''''''''''''''''''''''''''''''''''''
        Err.Clear
        lb = LBound(arr)
        If lb > ub Then
            IsArrayEmpty = True
        Else
            IsArrayEmpty = False
        End If
    End If

    Err.Clear
End Function

Basically, it checks to make sure you passed an array, then it attempts to find the upper bound (which will throw an error if the array is empty), and finally it compares the lower bound to the upper bound to make sure the array really isn't empty.

尸血腥色 2024-10-07 18:28:39

.. 我仍然收到错误 #9 脚本
越界

......这是否意味着您正在获取所需的信息(数组为空)?

.. I am still getting error #9 script
out of bounds

if you get error #9....doesn't that mean that you are geting the info that you need (array is empty)?

痕至 2024-10-07 18:28:39

您始终可以使用“isArray()”函数

Dim yourArray as variant
if not isArray(your_array) then
   msgbox("empty")
else
   msgbox("with data")
end if

You always can use "isArray()" function

Dim yourArray as variant
if not isArray(your_array) then
   msgbox("empty")
else
   msgbox("with data")
end if
夜唯美灬不弃 2024-10-07 18:28:39

您可以通过使用 JScript 的 VBArray() 对象(适用于变体类型、单维或多维的数组)检索总元素计数来检查数组是否为空:

Sub Test()

    Dim a() As Variant
    Dim b As Variant
    Dim c As Long

    ' Uninitialized array of variant
    ' MsgBox UBound(a) ' gives 'Subscript out of range' error
    MsgBox GetElementsCount(a) ' 0

    ' Variant containing an empty array
    b = Array()
    MsgBox GetElementsCount(b) ' 0

    ' Any other types, eg Long or not Variant type arrays
    MsgBox GetElementsCount(c) ' -1

End Sub

Function GetElementsCount(aSample) As Long

    Static oHtmlfile As Object ' instantiate once

    If oHtmlfile Is Nothing Then
        Set oHtmlfile = CreateObject("htmlfile")
        oHtmlfile.parentWindow.execScript ("function arrlength(arr) {try {return (new VBArray(arr)).toArray().length} catch(e) {return -1}}"), "jscript"
    End If
    GetElementsCount = oHtmlfile.parentWindow.arrlength(aSample)

End Function

对我来说,每个元素大约需要 0.3 mksec + 15毫秒初始化,因此10M元素的数组大约需要3秒。可以通过 ScriptControl ActiveX 实现相同的功能(它在 64 位 MS Office 版本中不可用,因此您可以使用 这个)。

You can check if the array is empty by retrieving total elements count using JScript's VBArray() object (works with arrays of variant type, single or multidimensional):

Sub Test()

    Dim a() As Variant
    Dim b As Variant
    Dim c As Long

    ' Uninitialized array of variant
    ' MsgBox UBound(a) ' gives 'Subscript out of range' error
    MsgBox GetElementsCount(a) ' 0

    ' Variant containing an empty array
    b = Array()
    MsgBox GetElementsCount(b) ' 0

    ' Any other types, eg Long or not Variant type arrays
    MsgBox GetElementsCount(c) ' -1

End Sub

Function GetElementsCount(aSample) As Long

    Static oHtmlfile As Object ' instantiate once

    If oHtmlfile Is Nothing Then
        Set oHtmlfile = CreateObject("htmlfile")
        oHtmlfile.parentWindow.execScript ("function arrlength(arr) {try {return (new VBArray(arr)).toArray().length} catch(e) {return -1}}"), "jscript"
    End If
    GetElementsCount = oHtmlfile.parentWindow.arrlength(aSample)

End Function

For me it takes about 0.3 mksec for each element + 15 msec initialization, so the array of 10M elements takes about 3 sec. The same functionality could be implemented via ScriptControl ActiveX (it is not available in 64-bit MS Office versions, so you can use workaround like this).

梦里南柯 2024-10-07 18:28:39

UBound 和 LBound 将返回给定数组的上下边界。因此,如果 Ubound(arr) 等于 LBound(arr),则它为空。

Dim arr() As String

If UBound(arr) = LBound(arr) Or UBound(arr) <= 0 Then
   Debug.Print "empty"
Else
   Debug.Print "not empty"
End If  

The UBound and LBound will return the upper and lower boundries of a given array. So, if Ubound(arr) is equal than LBound(arr) then it is empty.

Dim arr() As String

If UBound(arr) = LBound(arr) Or UBound(arr) <= 0 Then
   Debug.Print "empty"
Else
   Debug.Print "not empty"
End If  
樱娆 2024-10-07 18:28:39

在 MS Excel(Office 365 64 位)中编写 VBA 宏时,我遇到了这个“下标超出范围”问题...

UBound( 之前添加对 VarType() 的调用) 调用解决了这个奇怪的问题:

Dim arr() As String    ' Empty array - UBound() should return -1 but throws error 9 instead
Dim VT As VbVarType: VT = VarType(arr)
Dim upper_bound: upper_bound = UBound(arr)

While writing a VBA macro in MS Excel (Office 365 64-bit) I came across this "subscript out of range" issue...

Adding a call to VarType() before the UBound() call solves this weird problem:

Dim arr() As String    ' Empty array - UBound() should return -1 but throws error 9 instead
Dim VT As VbVarType: VT = VarType(arr)
Dim upper_bound: upper_bound = UBound(arr)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文