【问题标题】:VBA, Arrays, Ranges, SortingVBA、数组、范围、排序
【发布时间】:2013-09-30 17:44:48
【问题描述】:

我必须编写一个函数来在 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" ? 比较同一数组/范围的两个值的正确方法是什么?

【问题讨论】:

  • 这段代码有很多问题:你正在用整数遍历行(并且行可能会变得比整数所能承受的更高),你在不使用 Set 的情况下分配范围(强制),你是访问不存在的 .Item 属性,您只能通过让(理论)列为零(列从 1 开始)等来迭代行。我建议您(深入)查看 VBA 以及如何与之前的范围进行交互尝试任何事情(来这里......记住“最低限度的理解”要求)。
  • 认为它像数组,受“Option base”的影响msdn.microsoft.com/en-us/library/aa266179%28v=vs.60%29.aspx
  • 如前所述,您有很多不足之处,IMO 需要更多的帮助,而不仅仅是提供特定的解决方案(但是在提出具体问题之前,您需要进行一些研究和测试以适应格式)。范围不是数组,它们具有特定的功能,它们都从 1 开始。

标签: arrays vba sorting excel


【解决方案1】:

这一行:

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。

编辑:供进一步阅读的参考文献

阅读writing UDFs and their limitations here
阅读differences between Let and Set here
您可能还会发现阅读范围对象 herehere 很有帮助。

【讨论】:

  • 恐怕OP的代码有很多问题。实际上,如此之多,你能做的最好的事情就是完全从头开始。
  • @varocarbas 是的,但我们可以提供一些重大概念错误的提示,以将 OP 指向正确的方向,以便他们可以学习,而不是仅仅打“你不知道”的砖墙知道你在做什么走开。”
  • 这完全取决于你(我个人,依靠“最低限度的理解来问这里”的想法......但尊重任何人的意见)。虽然如果你想帮助 OP 而他写了这么错误的代码;也许唯一的方法就是给自己写一个合适的。
  • 关于“你不知道你在做什么走开。”,这是一个程序员的网站。如果您不是程序员(或者,至少不是特定语言),也许您不应该使用它;或者,至少,自己做一些工作(大量免费资源)。也许你应该看看这个网站的规则,看看事情是如何完成的;结束问题的原因之一是“没有表现出足够的理解”。另外,我不确定向不太了解的人提供工作代码是否真的对他有帮助。 “自己做一段时间”听起来对我更有帮助。
  • @varocarbas 我来回讨论这个问题。刚开始时很容易高估自己的知识和能力;初学者往往没有意识到他们不知道多少。因此,有时它有助于指出他们哪里出错了。而不是让他们尝试解决错误的问题或不存在的问题。
【解决方案2】:
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

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

【讨论】:

  • 而 M2 中的值被神奇地转移到了 ary ... 老实说,我不明白为什么没有必要知识的人会来到这里:这不是获取它的方法。
  • 无论如何...您会感激 AndASM 并打算从他的解释中获得一些知识,或者您更喜欢您的神奇解决方案,就是这样?因为下一次也许你应该从一开始就更清楚,这样整个过程会更快,没有任何人不必要地浪费时间。
猜你喜欢
  • 2018-03-29
  • 2020-09-28
  • 2015-06-03
  • 2015-08-02
  • 1970-01-01
  • 2014-02-22
  • 1970-01-01
  • 2014-10-11
  • 2017-08-29
相关资源
最近更新 更多