删除VBA数组的第一个元素

时间:2015-12-11 20:09:28

标签: arrays excel vba excel-vba

有没有办法在VBA中删除数组的第一个元素?

像javascript shift()方法?

Option Explicit

Sub Macro1()
Dim matriz() As Variant
Dim x As Variant
matriz = Array(0)

ReDim Preserve matriz(1)
matriz(1) = 5
ReDim Preserve matriz(2)
matriz(2) = 10
ReDim Preserve matriz(3)
matriz(3) = 4

ReDim Preserve matriz(1 To UBound(matriz))

For Each x In matriz
    Debug.Print x
Next x
End Sub

这是在回避错误:Subscript out of range

6 个答案:

答案 0 :(得分:11)

VBA中没有直接的方法,但您可以像这样轻松删除第一个元素:

'Your existing code
'...
'Remove "ReDim Preserve matriz(1 To UBound(matriz))"
For i = 1 To UBound(matriz)
  matriz(i - 1) = matriz(i)
Next i
ReDim Preserve matriz(UBound(matriz) - 1)

答案 1 :(得分:5)

遗憾的是没有。你必须写一个方法来做到这一点。一个很好的例子是http://www.vbforums.com/showthread.php?562928-Remove-Item-from-an-array

'~~> Remove an item from an array, then resize the array

    Public Sub DeleteArrayItem(ItemArray As Variant, ByVal ItemElement As Long)
    Dim i As Long

    If Not IsArray(ItemArray) Then
      Err.Raise 13, , "Type Mismatch"
      Exit Sub
    End If

    If ItemElement < LBound(ItemArray) Or ItemElement > UBound(ItemArray) Then
      Err.Raise 9, , "Subscript out of Range"
      Exit Sub
    End If

    For i = ItemElement To lTop - 1
      ItemArray(i) = ItemArray(i + 1)
    Next
    On Error GoTo ErrorHandler:
    ReDim Preserve ItemArray(LBound(ItemArray) To UBound(ItemArray) - 1)
    Exit Sub
    ErrorHandler:
    '~~> An error will occur if array is fixed
    Err.Raise Err.Number, , _
    "Array not resizable."

    End Sub

答案 2 :(得分:2)

不是答案,而是对阵列寻址的研究。

此代码:     ReDim Preserve matriz(1)     matriz(1)= 5

创建一个包含两个元素的数组:0和1 UBound()返回1

以下是一些可能有助于探讨此问题的代码:

Option Explicit

Sub Macro1()
   Dim matriz() As Variant
   Dim x As Variant
   Dim i As Integer
   matriz = Array(0)

   ReDim Preserve matriz(1)
   matriz(1) = 5
   ReDim Preserve matriz(2)
   matriz(2) = 10
   ReDim Preserve matriz(3)
   matriz(3) = 4

   Debug.Print "Initial For Each"
   For Each x In matriz
       Debug.Print ":" & x
   Next x
   Debug.Print "Initial For i = 0"
   For i = 0 To UBound(matriz)
       Debug.Print ":" & matriz(i)
   Next i
   Debug.Print "Initial For i = 1"
   For i = 1 To UBound(matriz)
       Debug.Print ":" & matriz(i)
   Next i
   Debug.Print "remove one"

   For i = 1 To UBound(matriz)
     matriz(i - 1) = matriz(i)
   Next i
   ReDim Preserve matriz(UBound(matriz) - 1)

   For Each x In matriz
       Debug.Print ":" & x
   Next x

   Debug.Print "remove one more"
   For i = 1 To UBound(matriz)
     matriz(i - 1) = matriz(i)
   Next i
   ReDim Preserve matriz(UBound(matriz) - 1)

   For Each x In matriz
       Debug.Print ":" & x
   Next x
End Sub

输出:

Initial For Each
:0
:5
:10
:4
Initial For i = 0
:0
:5
:10
:4
Initial For i = 1
:5
:10
:4
remove one
:5
:10
:4
remove one more
:10
:4

答案 3 :(得分:1)

如果您有字符串数组,则可以再次连接,偏移和拆分。

Public Sub test()

    Dim vaSplit As Variant
    Dim sTemp As String

    Const sDEL As String = "||"

    vaSplit = Split("1 2 3 4", Space(1))
    sTemp = Join(vaSplit, sDEL)

    vaSplit = Split(Mid$(sTemp, InStr(1, sTemp, sDEL) + Len(sDEL), Len(sTemp)), sDEL)

    Debug.Print Join(vaSplit, vbNewLine)

End Sub

返回

2
3
4

答案 4 :(得分:1)

没有直接方法,但是可以解决一些问题:-)

此方法使用中间目标范围

  • [1]接收数组数据(例如从单元格Word2Vec开始)和
  • ....将它们作为调整后的2-dim数据字段(从单元格A10开始计数,因此省略了第一个元素)返回
  • [2]将其转置回平面一维数组

示例代码

A11

VBE即时窗口(Option Explicit Sub Macro1() 'Method: use temporary target range to restructure array Dim matriz() As Variant Dim rng As Range '[0.1] Assign same data set to array as in original post matriz = Array(0, 5, 10, 4) Debug.Print "a) original matriz(" & LBound(matriz) & " To " & UBound(matriz) & ")", Join(matriz, ", ") 'instead of: ' ReDim Preserve matriz(0 To 3) ' matriz(0) = 0: matriz(1) = 5: matriz(2) = 10: matriz(3) = 4 '[0.2] Set temporary range to memory Set rng = ThisWorkbook.Worksheets("Tabelle1").Range("A10").Resize(UBound(matriz) + 1, 1) '[1] Write array data to range and reassign to matriz cutting first row rng = Application.Transpose(matriz) ' fill in array data (transposed to column) matriz = rng.Offset(1, 0).Resize(UBound(matriz), 1) ' assign data to (2-dim) array omitting first row '[2] Transpose back to flat 1-dim array matriz = Application.Transpose(Application.Index(matriz, 0, 1)) Debug.Print "b) ~~> new matriz(" & LBound(matriz) & " To " & UBound(matriz) & ")", Join(matriz, ", "), End Sub )中的示例输出

Debug.Print

相关链接

Can I return a 0-based array from ws.UsedRange?

答案 5 :(得分:0)

下面是函数“ Shift”,其行为类似于JS中的shift方法,并举例说明了“ Shift”的用法

Sub tryShift()

Dim aRy As Variant, sT As Variant

aRy = Array("one", "two", "three", "four")

Debug.Print "Original array:"
For Each sT In aRy
Debug.Print sT
Next

aRy = Shift(aRy)

Debug.Print vbCrLf & "Array having been " & Chr(34) & "shifted" & Chr(34) & ":"
For Each sT In aRy
Debug.Print sT
Next

End Sub

Function Shift(aRy As Variant)

Dim iCt As Integer, iUbd As Integer

iCt = 0
iUbd = UBound(aRy)

Do While iCt < iUbd
    aRy(iCt) = aRy(iCt + 1)
    iCt = iCt + 1
Loop

ReDim Preserve aRy(UBound(aRy) - 1)

Shift = aRy

End Function

输出:

Original array:
one
two
three
four

Array having been "shifted":
two
three
four