2017-05-26 103 views
1

我有以下Sub获取一列数字到一个Variant数组,而不是调用它上面的Bubble排序函数来排序仍在Loo变量中的数字。我希望Loo被改变,即在排序函数收到Byref并完成其工作之后,其中的数字以排序顺序出现。有趣的是,排序功能会在Watch上显示Inarray时进行排序。但是Loo - 尽管给了ByRef函数 - 从未改变过。Excel Vba递归子不改变Variant 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 

回答

0

我相信你会需要明确地使卢和Inarray阵列,而不是变体(你可以让他们变的阵列...或长,字符串,不管)。拥有全局或模块级变量也不是一个好主意。 像这样将工作:

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 
+0

的主要原因是在你的代码失败,然而,你递归调用BubbleSortArray(带圆括号) - 它试图评估Inarray,因此不通过引用传递。请参阅http://www.cpearson.com/excel/byrefbyval.aspx和http://www.tushar-mehta.com/publish_train/xl_vba_cases/1004%20ByVal%20ByRef.shtml – Hauffa

+0

@jkpieterse - 我认为你的电话参考是好的,因为他们使用“呼叫”,但BubbleSortArrary内的呼叫本身是问题(抱歉,由于我没有足够的声望,所以不能评论你的答案)。 – Hauffa

+0

事实上,任何带括号的电话都不好! BubbleSort的递归和调用也是如此。感谢您解释问题的链接! – Fiordiligi

2

你所面临的问题是由呼叫周围噜括号引起的。 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 
+0

非常感谢!正如你所说:删除括号后一切都很好。 :-) – Fiordiligi