0

我必须编写一个函数来在 Excel 中对 VBA 中的给定范围进行排序。(冒泡排序)我做了以下事情:

Function MySort(M2 As Range)

    Dim r As Integer
    r = M2.Rows.Count

    Dim M1 as range
    M1 = M2

    Dim buffer

    For i = 0 To r
        For j = i To r

            If (M1.Item(i, 0) > M1.Item(j, 0)) Then

                buffer = M1.Item(i, 0)
                M1.Item(i, 0) = M1.Item(j, 0)
                M1.Item(j, 0) = buffer

            End If

        Next j
    Next i

    MySort = M1

End Function

问题 :

  • 它返回“#VALUE”
  • 我尝试将 Range 转换为数组
  • 如果我不将 M2 转换为 M1,则该函数将返回未排序的列表
  • 我尝试过基础 1 和基础 0

我想我确实已经确定了以下示例中突出显示的主要问题:

Function TestArray(M1 As Range)

    r = M1.Rows.Count

    Dim M2 As Range

    Dim M3()
    ReDim M3(r)

    M3 = M1
    M2 = M1

    TestArray = M3(0, 0) ' or M2.item(0, 0)

End Function

此函数将返回“#VALUE”。

为什么 M2.item(0, 0) 返回 "#VALUE" ?比较同一数组/范围的两个值的正确方法是什么?

4

2 回答 2

2

那么这一行:

Dim M1 as range

正在创建一个可以保存对范围变量的引用的空变量

M1 = M2

实际上是简写

Let M1.Value = M2.Value

但是由于 M1 是 Nothing(在其他语言中为 null),因此您不能很好地分配给它的一个属性。因此,您的 UDF 会在该行引发错误并退出。你不是在投射物体或任何东西。首先你不应该需要或使用 M1,你应该只需要 M2。

此外,这一行:

M1.Item(i, 0) = M1.Item(j, 0)

应该是这样的:

M1.Cells(i, 0) = M1.Cells(j, 0)

但是它永远不会在 UDF 中工作。您从 Excel 单元格中的公式调用的任何函数都不能更改其他单元格的内容。这是 Excel 中的一大禁忌。UDF 只能读取其他单元格,然后返回一个值。而已。如果要更改其他单元格,则必须将其称为宏,而不是 UDF。

编辑:供进一步阅读的参考资料

在此处阅读有关编写 UDF 及其限制的内容。
在此处阅读Let 和 Set 之间的区别
您可能还会发现在此处此处阅读范围对象很有帮助。

于 2013-09-30T17:54:50.110 回答
1
Function MySort(M2 As Range)

    Dim r As Integer
    r = M2.Rows.Count

    Dim ary()
    ReDim ary(r)

    ary = M2

    Dim buffer

    For i = 1 To r
        For j = i To r

            If (ary(i, 1) > ary(j, 1)) Then

                buffer = ary(i, 1)
                ary(i, 1) = ary(j, 1)
                ary(j, 1) = buffer

            End If

        Next j
    Next i

    MySort = ary

End Function

更改为我神奇地工作的数组。

于 2013-09-30T18:19:51.673 回答