如何在 VBA(不是字典)中制作列表?

Posted

技术标签:

【中文标题】如何在 VBA(不是字典)中制作列表?【英文标题】:How to make a list in VBA (not a dictionary)? 【发布时间】:2017-03-08 20:48:13 【问题描述】:

虽然我熟悉编程,但我对 VB 或 VBA 不太熟悉。

我正在使用 Excel 2016 并尝试根据另一个工作表中的一列单元格填充组合框(位于用户表单上)。我需要删除空单元格、重复项、一些已知值,然后对最终得到的内容进行排序。

我有一些大部分工作的代码(除了排序我什么都有),但在覆盖它之前我没有保存它。它基于this answer。我不知道如何为其添加排序。它使用字典并用了 5 秒钟来弹出一个用户表单并填充组合框。列表中只有 1000 个单元格,所以在我看来,字典对于这个项目来说数据结构过于复杂。

我正在尝试从here 获取代码来工作,但我无法弄清楚它在做什么,因为变量名称非常模糊,而且我对 VB 不熟悉。

此时,我想我只需要自己进行搜索、替换和排序,而不是依赖 copypasta。我似乎找不到 VBA 是否有 List() 对象。每个人都在谈论数组和字典。如果存在,我想使用一种提供排序功能的数据结构。

对于这样的事情我应该使用什么数据结构?

我已经重构了最有效的代码。这是在用户窗体初始化上,如果不明显的话。

Private Sub UserForm_Initialize()

    '*Start with empty inputs
    InitialsTextBox.Value = ""

    MakeComboBox.Clear
    ModelComboBox.Clear

    '*Fill the Combo Boxes

    Dim oDictionary As Object
    Dim strCellContent As String
    Dim rngComboValues As Range
    Dim rngCell As Range

    Set rngComboValues = Sheets("BOM").Range("B:B")
    Set oDictionary = CreateObject("Scripting.Dictionary")

    For Each rngCell In rngComboValues
        strCellContent = rngCell.Value

        If Not oDictionary.exists(strCellContent) Then
            oDictionary.Add strCellContent, 0
        End If
    Next rngCell

    For Each itm In oDictionary.keys
        Me.MakeComboBox.AddItem itm
    Next itm

    Set oDictionary = Nothing
    End Sub

编辑/更新

下面的答案很好,但需要在运行 VBA 代码的机器上安装额外的库。虽然这可能适用于大多数情况(.NET 无论如何都很常见),但对于这个项目,我强烈希望没有依赖项和/或离开 VBA 语言。这将运行的环境可能不喜欢这样的事情。

【问题讨论】:

这是否能让你朝着正确的方向前进:***.com/questions/3587662/how-do-i-sort-a-collection 字典是集合吗?也许反过来?还是他们不相关? 字典是一种集合 也许这有助于将字典与集合进行比较:***.com/questions/32479842/… VBA 中不存在列表(您可能从 java 中知道它们)。但在将字典添加到 ComboBox 之前,您似乎只是错过了字典的“排序”部分:***.com/questions/14808104/… 我假设您的ComboBox 没有 16,384 个潜在值(如果有,那就是一些非常糟糕的用户体验)。没有理由测试 B:B 范围内的最后 15,000 个左右的空单元格,以查看您的 Dictionary 中是否已经有 Empty - 将您的数据范围限制为 data . 【参考方案1】:

如果存在,我想使用一种提供排序功能的数据结构。

是的,例如可以使用来自.Net 框架的SortedList。

SortedList 表示按键排序的键/值对集合,可通过键和索引访问。

VBA 代码示例:

添加对C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb的引用

Sub SortedListDemo()
    Dim sr As mscorlib.SortedList
    Set sr = New mscorlib.SortedList
    sr.Add "D", "D"
    sr.Add "B", "B"
    sr.Add "A", "A"
    sr.Add "C", "C"
    Dim i As Integer
    For i = 0 To sr.Count - 1
        Debug.Print "Key: " & sr.GetKey(i) & ", Value: " & sr.GetByIndex(i)
    Next i
    Set sr = Nothing
End Sub

输出

Key: A, Value: A
Key: B, Value: B
Key: C, Value: C
Key: D, Value: D

更多信息,例如 here。高温

【讨论】:

调用 .NET 是否需要额外的代码、库、权限或与 Windows 10、Citrix 或 Office 2013 的兼容性问题? .Net 框架必须安装在目标系统上,这样您才能使用它的类。我不明白你对附加代码的意思。您需要的代码显示在示例中。安装 .net 框架后,在VBA 代码中,您需要从 .net 框架(或者可能是实际安装的其他版本的 .net 框架)添加对上述类型库文件的引用,然后您可以创建实例这些类的。SortedList 标有ComVisibleAttribute,因此可以通过COM 在任何地方使用。但请在您的目标环境中自行尝试。

以上是关于如何在 VBA(不是字典)中制作列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VBA 中调用带有列表和另一个参数的函数?

如何从pandas DataFrame中制作字典列表?

VBA 如何批量将单元格复制到另一个工作表中

如何在Python中将json.loads作为列表而不是字典[重复]

如何在Excel VBA中使用字典Dictionary对象

如何在 Python 中使用字典比较两个列表