Excel Vba递归Sub不更改Variant ByRef参数

时间:2017-05-26 17:32:49

标签: excel-vba function recursion parameter-passing variant

我有以下Sub将一列数字放入Variant数组,而不是调用其上的Bubble排序函数来对仍在Loo变量中的数字进行排序。我希望改变Loo,即在排序函数接收到Byref并完成其工作后,它中的数字按排序顺序出现。有趣的是,排序发生了,正如Watch在排序功能中显示Inarray。但是Loo - 尽管将ByRef赋予函数 - 却永远不会改变。

变量数组是否不适合ByRef参数传递?我在分拣机功能上做错了吗?递归是什么“杀死”Inarray才能写回Loo?

Option Explicit
Option Base 1

Public Loo As Variant

Public Destfile As Workbook

Private i As Integer

Sub sorter()
Set Destfile = Workbooks("SomeWB")

With Destfile.Worksheets("Somesheet").ListObjects("sometable").ListColumns("Numbers")
    Loo = Application.Transpose(.DataBodyRange)
End With

BubbleSortArray (Loo)


End Sub

冒泡排序功能如下:

Option Explicit
Option Base 1
Private NumberOfChanges, p As Integer
Private Store As Variant

Public Sub BubbleSortArray(ByRef Inarray As Variant)

    NumberOfChanges = 0
        For p = 1 To UBound(Inarray, 1) - 1
        If Inarray(p) > Inarray(p + 1) Then

            Store = Inarray(p + 1)
            Inarray(p + 1) = Inarray(p)
            Inarray(p) = Store

            NumberOfChanges = NumberOfChanges + 1

        End If
    Next p

    If NumberOfChanges <> 0 Then BubbleSortArray (Inarray)

End Sub

2 个答案:

答案 0 :(得分:2)

您遇到的问题是由您呼叫中的Loo周围的括号引起的。 VBA与其他语言的不同之处在于,如果对例程的调用没有赋值,则不需要括号,实际上会导致不同的行为。所以:

BubbleSortArray (Loo)

或多或少告诉VBA在将Loo传递给排序例程之前对其进行评估。

如果你这样称呼它,一切都会好的:

BubbleSortArray Loo

例如参见这个小小的演示:

Sub foo()
    Dim x As Integer
    x = 1
    bar (x)
    MsgBox x
    bar x
    MsgBox x
End Sub

Sub bar(ByRef x As Integer)
x = 10
End Sub

答案 1 :(得分:0)

我相信你需要明确地制作Loo和Inarray数组而不是变体(你可以使它们成为变种数组......或者Long,String,等等)。拥有全局或模块级变量也不是一个好主意。 这样的事情会起作用:

Option Explicit
Option Base 1

Sub sorter()
    Dim Loo() As Variant
    Dim Destfile As Workbook

    Set Destfile = ThisWorkbook

    With Destfile.Worksheets("QueryResult").ListObjects("Table1").ListColumns("COLUMN_NAME")
        Loo = Application.Transpose(.DataBodyRange)
    End With

    Call BubbleSortArray(Inarray:=Loo)

    Stop
End Sub


Public Sub BubbleSortArray(ByRef Inarray() As Variant)
    Dim NumberOfChanges As Integer
    Dim p As Integer
    Dim Store As Variant

    NumberOfChanges = 0
        For p = 1 To UBound(Inarray, 1) - 1
        If Inarray(p) > Inarray(p + 1) Then

            Store = Inarray(p + 1)
            Inarray(p + 1) = Inarray(p)
            Inarray(p) = Store

            NumberOfChanges = NumberOfChanges + 1

        End If
    Next p

    If NumberOfChanges <> 0 Then BubbleSortArray Inarray:=Inarray

End Sub