热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

VBA:嵌套字典是一个很好的解决方案吗?-VBA:Isnesteddictionaryagoodsolutionforthis?

IhaveanExcelspreadsheetwithcoloredcells.IwastryingtobuildaVBAscriptthatcanreturnt

I have an Excel spreadsheet with colored cells. I was trying to build a VBA script that can return the row number(s) that match the pre-selected cell colors. However the color is "column-specific", which means it should only match the color in the same column as the selected cells.

我有一个带有彩色单元格的Excel电子表格。我正在尝试构建一个VBA脚本,该脚本可以返回与预先选择的单元格颜色匹配的行号。但是,颜色是“特定于列”,这意味着它应该只匹配与所选单元格在同一列中的颜色。

For example, in the screenshot attached, pre-selected cells are A3(blue) and B4(red).

例如,在附带的屏幕截图中,预先选择的单元格是A3(蓝色)和B4(红色)。

Example

The desired return is: 1, 3, 4, 5. It should not return 2 because even though B2 is in blue color, but there's no blue color cell selected in column B.

期望的回报是:1,3,4,5。它不应该返回2,因为即使B2是蓝色,但是在B列中没有选择蓝色单元格。

What is the best data structure to solve this problem?

解决此问题的最佳数据结构是什么?

Here are my thoughts:

以下是我的想法:

1) In a single column, multiple cells may be selected. Duplicated colors may exist. I was thinking of using a Colors dictionary to store the pre-selected color in the column.

1)在单个列中,可以选择多个单元。可能存在重复的颜色。我正在考虑使用Colors字典将预先选定的颜色存储在列中。

2) Since colors are "column-specific", I was thinking of using a Columns dictionary to track the columns that has pre-selected cells. Use column number as key, and Colors(dictionary) as value.

2)由于颜色是“特定于列”,我正在考虑使用Columns字典来跟踪具有预选单元格的列。使用列号作为键,使用Colors(字典)作为值。

3) My code is as below:

3)我的代码如下:

Dim objSelection As Range
Dim objSelectionArea As Range
Dim objCell As Range
Dim c, r As Long
Dim Columns As New Scripting.Dictionary
Dim Colors As New Scripting.Dictionary

' Get the current selection
Set objSelection = Application.Selection

' Walk through the areas
For Each objSelectionArea In objSelection.Areas

    ' Walk through the cells in an area
    For Each objCell In objSelectionArea
        c = objCell.Column
        r = objCell.Row
        cellColor = objCell.Interior.Color

        ' If this is a new column add it to dictionary. Also add color.
        If Not Columns.Exists(c) Then
            ' Put cell color into color dictionary as key
            Colors.Add cellColor, r
            ' Put color dictionary into column dictionary
            Columns.Add c, Colors
        ' if colomn already in dictionary, just do the color part
        ElseIf Not Columns(c).Exists(cellColor) Then
            Columns(c).Add cellColor, r
        End If
    Next

Next

' Walk through each columns that has selected cells
For Each c in Columns.Keys
    ' Walk through each cells in this column
    For r = 1 to MaxRow' Assuming MaxRow is the last row number of the table

        ' If the cell color in the the column-specific RefColor dictionary
        If Columns(c).Exists(Cells(r, c).Interior.Color) Then
        ' Do something here to indicate row r is one of the matches
        End If

    Next

Next

The problem of this nested dictionary is - the Colors dictionary is not "column-specific"(even though I nested it in a 'Columns' dictionary. When I store colors into Colors, it's like adding colors into a global/single dictionary. So the outcome does not meet business requirement.

这个嵌套字典的问题是 - Colors字典不是“特定于列”(即使我将它嵌套在'Columns'字典中。当我将颜色存储到Colors中时,就像在全局/单个字典中添加颜色一样。所以结果不符合业务要求。

Is nested dictionary the best data structure for this problem? Or shall I use a different data structure? Thank you!

嵌套字典是这个问题的最佳数据结构吗?或者我应该使用不同的数据结构?谢谢!

3 个解决方案

#1


0  

I think the nested dictionaries could work; although you would have to make a few changes to make the colors dictionary truly column specific.

我认为嵌套的词典可以工作;虽然您必须进行一些更改才能使颜色字典真正特定于列。

Note my changes in your code below:

请注意我在以下代码中的更改:

  • Did not explicitly declare a single Colors dictionary. Declaring specific colors dictionary meant:

    没有明确声明单个Colors字典。声明特定颜色字典意味着:

    • Sub/Function level variable (apparent Global dictionary behavior)
    • 子/函数级变量(明显的全局字典行为)

    • Adding to Columns dictionary, simply added additional references to existing Colors Dictionary
    • 添加到列字典,只需添加对现有颜色字典的其他引用

    • Can reference Colors dictionary by variable name
    • 可以通过变量名称引用Colors词典

  • Instead, when the cell is in a new column, add a new dictionary into the Columns dictionary. This means:

    相反,当单元格位于新列中时,将新字典添加到“列”字典中。意即:

    • Each dictionary "added" to the columns dictionary is unique.
    • 每个字典“添加”到列字典中是唯一的。

    • Column-level variable; instead of global
    • 列级变量;而不是全球

    • Can not refer to dictionary by name; only by reference to item/key connection from the Columns dictionary
    • 不能按名称参考字典;仅通过引用Columns字典中的item / key连接

    • Code to add color to color dictionary(s) becomes identical between if column exists or if it does not (thus, the slight change in the logic block)
    • 在列存在或不存在的情况下,为颜色字典添加颜色的代码变得相同(因此,逻辑块中的轻微更改)

  • Dim c As Variant: This is what your code was doing implicitly. For VBA variables, each variable needs to be declared separately, or it defaults to Variant

    Dim c As Variant:这是您的代码隐式执行的操作。对于VBA变量,每个变量需要单独声明,或者默认为Variant

    • If c is declared as long, a different Variant variable will need to be declared for looping through the dictionary keys.
    • 如果c声明为long,则需要声明一个不同的Variant变量来循环遍历字典键。

Note: The line Columns(c).Add cellColor, r adds the cell color as a key in the dictionary and the row as the item. This means that if that color already exists in that dictionary, the item will be overwritten with the new row value. Looking at your code, that shouldn't be an issue (selecting r as row value from looping through row numbers), but I thought I should mention this just in case you were planning on preserving the row values of the originally selected cells.

注意:行Columns(c).Add cellColor,r将单元格颜色添加为字典中的键,将行添加为项目。这意味着如果该字典中已存在该颜色,则该项将被新行值覆盖。看看你的代码,这不应该是一个问题(从循环遍历行号选择r作为行值),但我想我应该提到这一点,以防你计划保留最初选择的单元格的行值。


Dim objSelection As Range
Dim objSelectionArea As Range
Dim objCell As Range
Dim c As Variant 'Made implied declaration explicit. Needs to be variant or the "for each c" loop fails
Dim r As Long
Dim Columns As New Scripting.Dictionary

' Get the current selection
Set objSelection = Application.Selection

' Walk through the areas
For Each objSelectionArea In objSelection.Areas

    ' Walk through the cells in an area
    For Each objCell In objSelectionArea
        c = objCell.Column
        r = objCell.Row
        cellColor = objCell.Interior.Color

        ' If this is a new column add it to dictionary. Also add color.
        ' Simplified If-End If....
        If Not Columns.Exists(c) Then
            ' Put color dictionary into column dictionary
            Columns.Add c, New Scripting.Dictionary ' Creates new dictionary for each column
        End If

        ' Put cell color into color dictionary as key
        Columns(c).Add cellColor, r
    Next

Next

#2


0  

I think it's an efficient data structure

我认为这是一种有效的数据结构

This uses nested dictionaries of colors, based on columns

这使用基于列的嵌套颜色词典


Option Explicit

Public Sub GetColColorsBasedOnSelectedRows()
    Dim ur As Range, c As Long, r As Long, rCnt As Long, cCnt As Long, sel As Range
    Dim d As Dictionary, dColors As Dictionary, cc As Long, res As String, sCell As Range

    Set ur = Sheet1.UsedRange
    rCnt = ur.Rows.Count
    cCnt = ur.Columns.Count
    Set d = New Scripting.Dictionary
    For c = 1 To cCnt   'Get all colors in all used range, by columns
        Set dColors = New Scripting.Dictionary
        For r = 1 To rCnt
            cc = ur(r, c).Interior.Color
            If InStr(1, dColors(cc), r & ", ") = 0 Then
                dColors(cc) = dColors(cc) & r & ", "
            End If
        Next
        Set d(c) = dColors
    Next
    Dim msg As String, shown As Dictionary
    Set shown = New Scripting.Dictionary
    For Each sel In Application.Selection.Areas
        For Each sCell In sel.Cells
            If Not shown.Exists(sCell.Column & "-" & sCell.Interior.Color) Then
                msg = msg & sCell.Address(0, 0) & ", "
                res = res & d(sCell.Column)(sCell.Interior.Color)
                shown(sCell.Column & "-" & sCell.Interior.Color) = 0
            End If
        Next
    Next
    Debug.Print "Selected cells: " & Left(msg, Len(msg) - 2)
    Debug.Print "Row colors:     " & Left(res, Len(res) - 2) & vbCrLf
    ShowAllItems d
End Sub

Private Sub ShowAllItems(ByRef d As Dictionary)

    Dim x As Variant, y As Variant, i As Long, m As String

    For Each x In d
        i = i + 1
        For Each y In d(x)
          m = d(x)(y)
          Debug.Print "Column: " & i & ", Color: " & y & ", Rows: " & Left(m, Len(m) - 2)
        Next
    Next
End Sub

Result

Selected cells: A3, B4, C2, D1, D7
Row colors:     1, 3, 4, 5, 2, 1, 6, 3, 5, 7

Column: 1, Color: 16772300,   Rows: 1, 3
Column: 1, Color: 6684672,    Rows: 2
Column: 1, Color: 16777215,   Rows: 4, 5, 6
Column: 1, Color: 192,        Rows: 7
Column: 2, Color: 16777215,   Rows: 1, 3, 6
Column: 2, Color: 16772300,   Rows: 2
Column: 2, Color: 192,        Rows: 4, 5
Column: 2, Color: 6684672,    Rows: 7
Column: 3, Color: 16777215,   Rows: 1, 3, 4, 7
Column: 3, Color: 6684672,    Rows: 2
Column: 3, Color: 16772300,   Rows: 5
Column: 3, Color: 192,        Rows: 6
Column: 4, Color: 192,        Rows: 1, 6
Column: 4, Color: 16777215,   Rows: 2
Column: 4, Color: 6684672,    Rows: 3, 5, 7
Column: 4, Color: 16772300,   Rows: 4

Sheet1

Sheet1

#3


0  

I found the answer here: Excel VBA: nested dictionary issue

我在这里找到答案:Excel VBA:嵌套字典问题

I'm a newbie to VBA so I made a mistake in the original code.

我是VBA的新手,所以我在原始代码中犯了一个错误。

I should create a new inner dictionary whenever adding a new key to the outer dictionary.

每当向外部字典添加新密钥时,我都应该创建一个新的内部字典。

So instead of:

所以代替:

Dim Colors As New Scripting.Dictionary

I should have done:

我应该做的:

Dim Colors As Scripting.Dictionary

Then, whenever adding a new key to the outer dictionary, I should do:

然后,每当向外部字典添加新密钥时,我应该这样做:

Set Colors = New Scripting.Dictionary

推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
author-avatar
碧后珍重
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有