如何对集合进行排序?
有谁知道如何在VBA中对集合进行排序?
Does anyone know how to sort a collection in VBA?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
有谁知道如何在VBA中对集合进行排序?
Does anyone know how to sort a collection in VBA?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(12)
游戏迟到了...这里是 VBA 中针对数组和集合的 MergeSort 算法 的实现。我使用随机生成的字符串在接受的答案中针对 BubbleSort 实现测试了此实现的性能。下图总结了结果,即您不应使用 BubbleSort 对 VBA 集合进行排序。
您可以从我的 GitHub 存储库 下载源代码,或者直接复制/粘贴下面的源代码放入相应的模块中。
对于集合
col
,只需调用Collections.sort col
。集合模块
数组模块
IVariantComparator 类
如果没有向
sort
方法提供IVariantComparator
,然后假设自然排序。但是,如果您需要定义不同的排序顺序(例如反向)或者想要对自定义对象进行排序,则可以实现IVariantComparator
接口。例如,要按相反顺序排序,只需创建一个名为CReverseComparator
的类,代码如下:CReverseComparator class
然后调用排序函数,如下所示:
Collections.sort col,新 CReverseComparator
奖励材料: 有关不同排序算法性能的直观比较,请查看 https://www.toptal.com/developers/sorting-algorithms/
Late to the game... here's an implementation of the MergeSort algorithm in VBA for both Arrays and Collections. I tested the performance of this implementation against the BubbleSort implementation in the accepted answer using randomly generated strings. The chart below summarizes the results, i.e. that you should not use BubbleSort to sort a VBA collection.
You can download the source code from my GitHub Repository or just copy/paste the source code below into the appropriate modules.
For a collection
col
, just callCollections.sort col
.Collections module
Arrays module
IVariantComparator class
If no
IVariantComparator
is provided to thesort
methods, then the natural ordering is assumed. However, if you need to define a different sort order (e.g. reverse) or if you want to sort custom objects, you can implement theIVariantComparator
interface. For example, to sort in reverse order, just create a class calledCReverseComparator
with the following code:CReverseComparator class
Then call the sort function as follows:
Collections.sort col, New CReverseComparator
Bonus Material: For a visual comparison of the performance of different sorting algorithms check out https://www.toptal.com/developers/sorting-algorithms/
这篇文章中的以下代码使用了冒泡排序
The code below from this post uses a bubble sort
您可以使用
ListView
。虽然它是一个 UI 对象,但您可以使用它的功能。它支持排序。您可以将数据存储在Listview.ListItems
中,然后像这样排序:You could use a
ListView
. Although it is a UI object, you can use its functionality. It supports sorting. You can store data inListview.ListItems
and then sort like this:Collection 是一个相当错误的排序对象。
集合的关键是提供对由键标识的特定元素的快速访问。项目如何在内部存储应该是无关紧要的。
如果您确实需要排序,您可能需要考虑使用数组而不是集合。
除此之外,是的,您可以对集合中的项目进行排序。
您需要采用互联网上可用的任何排序算法(您可以在基本上任何语言中搜索实现)并在发生交换的地方进行微小的更改(其他更改是不必要的,因为可以通过索引访问 vba 集合,如数组)。要交换集合中的两个项目,您需要将它们从集合中删除,然后将它们插入到正确的位置(使用
Add
方法的第三个或第四个参数)。Collection is a rather wrong object for sorting.
The very point of a collection is to provide very fast access to a certain element identified by a key. How the items are stored internally should be irrelevant.
You might want to consider using arrays instead of collections if you actually need sorting.
Other than that, yes, you can sort items in a collection.
You need to take any sorting algorithm available on the Internet (you can google inplementations in basically any language) and make a minor change where a swap occurs (other changes are unnecessary as vba collections, like arrays, can be accessed with indices). To swap two items in a collection, you need to remove them both from the collection and insert them back at the right positions (using the third or the forth parameter of the
Add
method).VBA 中的
Collection
没有本机排序,但由于您可以通过索引访问集合中的项目,因此您可以实现排序算法来遍历集合并排序到新集合中。这是 VBA/ 的 HeapSort 算法实现 VB 6。
这似乎是冒泡排序算法实现 适用于 VBA/VB6。
There is no native sort for the
Collection
in VBA, but since you can access items in the collection via index, you can implement a sorting algorithm to go through the collection and sort into a new collection.Here's a HeapSort algorithm implementation for VBA/VB 6.
Here's what appears to be a BubbleSort algorithm implementation for VBA/VB6.
如果您的集合不包含对象并且您只需要升序排序,您可能会发现这更容易理解:
我在几分钟内完成了它,所以这可能不是最好的冒泡排序,但它应该很容易理解,并且因此很容易根据您自己的目的进行修改。
If your collection doesn't contain objects and you only need to sort ascending, you might find this easier to understand:
I hacked this up in minutes, so this may not be the best bubble sort, but it should be easy to understand, and hence easy to modify for your own purposes.
这是我的 BubbleSort 的实现:
它通过引用获取集合,因此可以轻松返回它作为一个函数,它有一个可选参数用于升序和降序排序。
排序会在立即窗口中返回此内容:
This is my implementation of BubbleSort:
It takes the collection by reference, thus it can easily return it as a function and it has an optional parameter for Ascending and Descending sorting.
The sorting returns this in the immediate window:
这段代码运行良好,但它是用java编写的。
要翻译它,你可以这样做:
SeriesManager 只是一个存储两个值之间差异的类。它实际上可以是您想要排序的任何数值。默认情况下按升序排序。
如果不创建自定义类,我很难在 vba 中对集合进行排序。
This code snippet works well, but it is in java.
To translate it you could do it like this:
SeriesManager is just a class that stores the difference between two values. It can really be any number value you want to sort on. This by default sorts in ascending order.
I had difficulty sorting a collection in vba without making a custom class.
这是 QuickSort 算法的 VBA 实现,通常是 MergeSort 的更好替代方案:
存储在集合中的对象必须实现
ISortableObject
接口,该接口必须在您的 VBA 项目中定义。为此,请使用以下代码添加一个名为 ISortableObject 的类模块:This is a VBA implementation of the QuickSort algorithm, which is often a better alternative to MergeSort:
The objects stored in the collection must implement the
ISortableObject
interface, which must be defined in your VBA project. To do that, add a class module called ISortableObject with the following code:我想进一步使用 igorsp7 QuickSort
如果您不想使用特殊接口,只是为了方便排序时,您可以使用 CallByName 函数:
此外,我已将 colSortable 更改为 Object,因为我使用了很多 自定义类型集合。
I want to go a little bit further with igorsp7 QuickSort
If you dont wan't to use special Interface, just for the sake of sorting you can use CallByName function:
Also i've changed colSortable to be Object, as I'm using a lot of custom typed collections.
如前所述,集合没有内置排序功能。我使用 VBA Collection 的内置
After
属性想出了一个更简单的实现。此方法循环遍历集合中的每个现有项目,一旦新项目 (
NewItem
) 比当前循环值 (Col.Item(i)
) 晚 < a href="https://www.tek-tips.com/viewthread.cfm?qid=1764000" rel="nofollow noreferrer">ASCII 比较,它退出循环并添加NewItem 进入该位置。
As mentioned, Collections do not have a built in sort feature. I came up with a simpler implementation using VBA Collection's built in
After
property.This method loops through each existing item in the Collection, and once the new item (
NewItem
) comes later than the current loop value (Col.Item(i)
) by ASCII comparison, it exits the loop and addsNewItem
into that spot.在上面的答案中添加了缺少的功能(copyOf(),length(),swap())(@Austin)。
Added missing features( copyOf(), length(), swap() ) to the answer above(@Austin).