Ms access VBA:反转数组?

Ms access VBA:反转数组?,ms-access,vba,Ms Access,Vba,如何反转充满整数的数组,例如: [1;5;8;45;54] 致: 有没有我可以使用的内置函数 我尝试使用以下方法: 我从工具>引用中添加了Mscorlib.dll,但它显示了错误:语法错误。在Array.Reverse(arr)位置。Array.Reverse听起来像VB.Net,而不是VBA Chip Pearson的功能几乎可以满足您对阵列(和其他结构)的任何需求 -->reversearlayinplace 有关部分是: Ndx2 = UBound(InputArray) ' loop

如何反转充满整数的数组,例如:

[1;5;8;45;54]
致:

有没有我可以使用的内置函数

我尝试使用以下方法:


我从工具>引用中添加了Mscorlib.dll,但它显示了错误:语法错误。在Array.Reverse(arr)位置。

Array.Reverse
听起来像VB.Net,而不是VBA

Chip Pearson的功能几乎可以满足您对阵列(和其他结构)的任何需求

-->
reversearlayinplace

有关部分是:

Ndx2 = UBound(InputArray)
' loop from the LBound of InputArray to the midpoint of InputArray
For Ndx = LBound(InputArray) To ((UBound(InputArray) - LBound(InputArray) + 1) \ 2)
    'swap the elements
    Temp = InputArray(Ndx)
    InputArray(Ndx) = InputArray(Ndx2)
    InputArray(Ndx2) = Temp
    ' decrement the upper index
    Ndx2 = Ndx2 - 1
Next Ndx

您可以使用
ArrayList
类并包装其
Reverse
方法:

Function ReverseArray(arr As Variant) As Variant
    Dim val As Variant

    With CreateObject("System.Collections.ArrayList") '<-- create a "temporary" array list with late binding 
        For Each val In arr '<--| fill arraylist
            .Add val
        Next val
        .Reverse '<--| reverse it
        ReverseArray = .Toarray '<--| write it into an array
    End With
End Function
功能反转array(arr作为变量)作为变量
Dim-val作为变体

对于CreateObject(“System.Collections.ArrayList”)”Andre关于Chip Pearson函数的回答,我认为for循环中的+1是错误的,在LBound和UBound不都是偶数或都是奇数的情况下,会导致中点反转被恢复。i、 e.LBound和UBound之间的差异为奇数

考虑0=LBound和9=UBound

9+1=10/2=5

因此,循环将适用于Ndx=0到5。这是6次迭代。一次迭代太多了

导致以下掉期交易。
Ndx=0,Ndx2=9:09
Ndx=1,Ndx2=8:18
Ndx=2,Ndx2=7:27
Ndx=3,Ndx2=6:36
Ndx=4,Ndx2=5:45
Ndx=5,Ndx2=4:54

因此,中点元素4和5交换,然后再交换回来。
结果是:9,8,7,6,4,5,3,2,1,0

此外,LBound应添加到UBound中,而不是减去。如果减去,那么它只适用于零的LBound。考虑50=L界限,100=UWOND。这将导致Ndx=50到25。注意,这应该是从计算到计算,而不是迭代计数计算

以下是我的一维和二维数组反转函数。
它们还可以选择性地保留指定数量的标题行

' Reverse array (one dimensional), optionally retain header rows.
Private Sub Reverse_Array_1d(ByRef Ary As Variant, Optional Header_Rows As Integer = 0)

 Dim Dimension_Y As Integer     ' Rows (height)
 Dim Y_first As Long
 Dim Y_last As Long
 Dim Y_last_plus_Y_first As Long
 Dim Y_next As Long

 Dimension_Y = 1
 Y_first = LBound(Ary, Dimension_Y) + Header_Rows
 Y_last = UBound(Ary, Dimension_Y)
 Y_last_plus_Y_first = Y_last + Y_first

 Dim tmp As Variant

 For Y = Y_first To Y_last_plus_Y_first / 2
    Y_next = Y_last_plus_Y_first - Y
    tmp = Ary(Y_next)
    Ary(Y_next) = Ary(Y)
    Ary(Y) = tmp
 Next

End Sub

ReDim Ary(0 To 9) As Variant
Header_Rows = 1
Call Reverse_1d_Array(Ary, CInt(Header_Rows))

(1) :如果您的数据由单个字符或回文组成,则这是一个简单但有限的解决方案。假设您的数组名为vTmp,您可以选择一个不出现在数据中的分隔符——我将使用“|”。那么,单线方法是:

vTmp = VBA.Split(VBA.StrReverse(VBA.Join(vTmp, "|")), "|")
它是有限的,因为每个值也将被反转。可以通过使用引用另一个数组中的值的索引替换这些值来解决这个问题,但这并不比其他解决方案简单

(2) :完整的解决方案,作为完整的Excel VBA函数:

Public Function rxReverse(uInput) As Variant
  '' Simply reverses the order of items in input array.
  '' If Input is singular, then it reverses the content.
  ''
  '' v1 Rich Sulin 05-08-2019
  Dim vTmp As Variant
  Dim a1 As Long, a2 As Long, a3 As Long
  Dim i As Long, j As Long
    ''
    rxReverse = vbNullString
    ''
    '' uInput is a Range object?
    If TypeOf uInput Is Range Then
        a1 = 1
        If uInput.Columns.Count > 1 Then
            a2 = uInput.Columns.Count
            ReDim vTmp(a1 To a2) As Variant
            a3 = 1 + (a2 - a1) / 2
            For i = a1 To a3
                j = a2 - i + 1
                vTmp(j) = uInput(1, i).Value
                vTmp(i) = uInput(1, j).Value
            Next i
        ElseIf uInput.Rows.Count > 1 Then
            a2 = uInput.Rows.Count
            ReDim vTmp(a1 To a2) As Variant
            a3 = 1 + (a2 - a1) / 2
            For i = a1 To a3
                j = a2 - i + 1
                vTmp(j) = uInput(1, i).Value
                vTmp(i) = uInput(1, j).Value
            Next i
        Else
            vTmp = VBA.StrReverse(VBA.CStr(uInput.Value))
        End If
    ''
    '' uInput is an Array?
    Else
        Select Case VBA.VarType(uInput)
            Case Is >= vbArray
                a1 = LBound(uInput)
                a2 = UBound(uInput)
                ReDim vTmp(a1 To a2) As Variant
                a3 = 1 + (a2 - a1) / 2
                For i = a1 To a3
                    j = a2 - i + 1
                    vTmp(j) = uInput(i)
                    vTmp(i) = uInput(j)
                Next i
    ''
    '' uInput is an irrelevant type?
            Case vbNull, vbEmpty, vbError
                Exit Function
    ''
    '' uInput is a singular data; reverse it.
            Case Else
                vTmp = VBA.StrReverse(VBA.CStr(uInput))
        End Select
    End If
    ''
    rxReverse = vTmp
    ''
    '' If called from a Worksheet, vertically, then orient output array "vertically"
    If VBA.IsObject(Application.Caller) Then
        If Application.Caller.Rows.Count > 1 Then
            rxReverse = Application.WorksheetFunction.Transpose(vTmp)
        End If
    End If
End Function

应该有帮助。(使用
Array.Reverse
)。我以前试过,但没用。你说的“没用”是什么意思?发生了什么事?它将数组反转到位,因此您不想在文本上使用它<代码>变暗
一个变量,并将其反转。
' Reverse array (one dimensional), optionally retain header rows.
Private Sub Reverse_Array_1d(ByRef Ary As Variant, Optional Header_Rows As Integer = 0)

 Dim Dimension_Y As Integer     ' Rows (height)
 Dim Y_first As Long
 Dim Y_last As Long
 Dim Y_last_plus_Y_first As Long
 Dim Y_next As Long

 Dimension_Y = 1
 Y_first = LBound(Ary, Dimension_Y) + Header_Rows
 Y_last = UBound(Ary, Dimension_Y)
 Y_last_plus_Y_first = Y_last + Y_first

 Dim tmp As Variant

 For Y = Y_first To Y_last_plus_Y_first / 2
    Y_next = Y_last_plus_Y_first - Y
    tmp = Ary(Y_next)
    Ary(Y_next) = Ary(Y)
    Ary(Y) = tmp
 Next

End Sub

ReDim Ary(0 To 9) As Variant
Header_Rows = 1
Call Reverse_1d_Array(Ary, CInt(Header_Rows))
' Reverse array (two dimensional), optionally retain header rows.
Private Sub Reverse_Array_2d(ByRef Ary As Variant, Optional Header_Rows As Integer = 0)

 Dim Dimension_Y As Integer     ' Rows (height)
 Dim Y_first As Long
 Dim Y_last As Long
 Dim Y_last_plus_Y_first As Long
 Dim Y_next As Long

 Dimension_Y = 1
 Y_first = LBound(Ary, Dimension_Y) + Header_Rows
 Y_last = UBound(Ary, Dimension_Y)
 Y_last_plus_Y_first = Y_last + Y_first

 Dim Dimension_X As Integer      ' Columns (width)
 Dim X_first As Long
 Dim X_last As Long

 Dimension_X = 2
 X_first = LBound(Ary, Dimension_X)
 X_last = UBound(Ary, Dimension_X)

 ReDim tmp(X_first To X_last) As Variant

 For Y = Y_first To Y_last_plus_Y_first / 2
    Y_next = Y_last_plus_Y_first - Y
    For X = X_first To X_last
        tmp(X) = Ary(Y_next, X)
        Ary(Y_next, X) = Ary(Y, X)
        Ary(Y, X) = tmp(X)
    Next
 Next

End Sub

ReDim Ary(0 To 9, 0 To 3) As Variant
Header_Rows = 1
Call Reverse_2d_Array(Ary, CInt(Header_Rows))
vTmp = VBA.Split(VBA.StrReverse(VBA.Join(vTmp, "|")), "|")
Public Function rxReverse(uInput) As Variant
  '' Simply reverses the order of items in input array.
  '' If Input is singular, then it reverses the content.
  ''
  '' v1 Rich Sulin 05-08-2019
  Dim vTmp As Variant
  Dim a1 As Long, a2 As Long, a3 As Long
  Dim i As Long, j As Long
    ''
    rxReverse = vbNullString
    ''
    '' uInput is a Range object?
    If TypeOf uInput Is Range Then
        a1 = 1
        If uInput.Columns.Count > 1 Then
            a2 = uInput.Columns.Count
            ReDim vTmp(a1 To a2) As Variant
            a3 = 1 + (a2 - a1) / 2
            For i = a1 To a3
                j = a2 - i + 1
                vTmp(j) = uInput(1, i).Value
                vTmp(i) = uInput(1, j).Value
            Next i
        ElseIf uInput.Rows.Count > 1 Then
            a2 = uInput.Rows.Count
            ReDim vTmp(a1 To a2) As Variant
            a3 = 1 + (a2 - a1) / 2
            For i = a1 To a3
                j = a2 - i + 1
                vTmp(j) = uInput(1, i).Value
                vTmp(i) = uInput(1, j).Value
            Next i
        Else
            vTmp = VBA.StrReverse(VBA.CStr(uInput.Value))
        End If
    ''
    '' uInput is an Array?
    Else
        Select Case VBA.VarType(uInput)
            Case Is >= vbArray
                a1 = LBound(uInput)
                a2 = UBound(uInput)
                ReDim vTmp(a1 To a2) As Variant
                a3 = 1 + (a2 - a1) / 2
                For i = a1 To a3
                    j = a2 - i + 1
                    vTmp(j) = uInput(i)
                    vTmp(i) = uInput(j)
                Next i
    ''
    '' uInput is an irrelevant type?
            Case vbNull, vbEmpty, vbError
                Exit Function
    ''
    '' uInput is a singular data; reverse it.
            Case Else
                vTmp = VBA.StrReverse(VBA.CStr(uInput))
        End Select
    End If
    ''
    rxReverse = vTmp
    ''
    '' If called from a Worksheet, vertically, then orient output array "vertically"
    If VBA.IsObject(Application.Caller) Then
        If Application.Caller.Rows.Count > 1 Then
            rxReverse = Application.WorksheetFunction.Transpose(vTmp)
        End If
    End If
End Function