首次出现后突出显示所有重复项

时间:2014-05-10 15:16:47

标签: excel-vba vba excel

我已附上excel表格以供参考。如“After”表中所示,我需要使用某种颜色突出显示重复关键字的第2到第n个实例。

有人可以帮我解决这个问题。Excel File

1 个答案:

答案 0 :(得分:2)

此站点的存在是为了让程序员能够帮助其他程序员发展他们的技能。有时在答案中提供了重要的代码片段,但这不是免费的编码站点。你一口气要求太多,并没有努力解决你自己的问题。这是本网站的两个主要禁忌。

你知道Excel VBA吗?如果不是,您不太可能理解任何包含代码的答案。搜索" VB Excel教程"。有很多可供选择。尝试一些并完成符合您学习风格的一个。我更喜欢书。我访问了一个大型图书馆并查看了所有Excel VBA引物。然后我买了我喜欢的那个。

一旦你掌握了一些VBA,请尝试自己编写宏。当我不确定如何创建宏时,我将整个问题分成几步。然后我写了一个宏,它将解决第1步并证明它已经成功解决了第1步。然后我更新宏以解决第2步并证明它已经成功解决了第1步和第2步。这种技术的优点是:

  • 我隔离了每个问题和
  • 我知道我正在取得进步。

如果你编写一个大的宏并且它不起作用,你不知道从哪里开始调试。这项技术的一个优点是,如果你不能得到第4步,比如说,工作,你可以隔离相关的代码,说它做了什么,并在这里寻求帮助,使它做你想要的。这是最快回答的问题类型。

下面有很多细节。通过它慢慢查找我提到的陈述和功能。如果有必要,请回答问题,但是,你可以为自己解决的越多,你发展技能的速度就越快。

我应该警告你,下面的代码已直接输入答案,但尚未检查过。我不相信有任何错误,但你应该为这种可能性做好准备。我还故意省略了一些陈述的部分内容,强迫你查阅它们,我相信这些陈述会帮助你发展。我希望这可以让你在没有真正给你答案的情况下开始。

这些是我为此问题建议的步骤:


您将需要一个for循环来检查从2到RowLast的每一行。你如何找到RowLast的价值?我搜索了[excel-vba] find last row并找到了各种问题以及解释如何执行此操作的答案。设置RowLast后,您可以通过以下方式将其输出到立即窗口来证明您具有正确的值:

Debug.Print RowLast

对循环进行编码以获取所需工作表中每行的单元格A.为了证明你正在访问每一行的每个单元格A,我建议如下:

Debug.Print RowCrnt & " " & .Cells(RowCrnt, "A").Value

您需要将每个单元格拆分为单独的单词或短语。在您的示例中,分隔符始终为comma space。您可以依赖它comma space,还是可以选择comma spacespace commaspace comma space等等?您需要使用Split。仔细看看。我建议您在comma上拆分,然后使用函数Trim删除任何空格。如果您拆分为阵列CellPart,我建议您获得初始证据,证明您已正确拆分单元格:

Debug.Print Trim(CellPart(0)) & "|" Trim(CellPart(1))

要正确拆分单元格,您需要另一个For循环来访问CellPart的每个元素。查找UBound以了解如何获取数组的最后一个元素的数量。我建议如下。查找Debug.Print以查找&#34 ;;"的重要性在第2行的末尾。

For InxCP = 0 to ....
  Debug.Print Trim(CellPart(InxCP)) & "|";
Next
Debug.Print

现在变得有点复杂了。您将必须构建所有单词或短语的数组。对于CellPart的每个元素,您需要检查它是否已存在于数组中。如果已经存在,则需要为其着色。如果它不存在,则需要将其添加到数组中。您事先并不知道阵列必须保留多少条目。语句Redim调整数组大小,而Redim Preserve调整数组大小而不丢弃当前内容。

如果您需要构建一个大型数组,Redim Preserve可能是一个缓慢的语句。解释器必须找到足够大的内存来容纳新的更大的数组,将现有数组复制到这个新空间,并将旧数组的空间传递给垃圾收集器。我更喜欢在大块中增加数组的大小以减少使用Redim Preserve的次数。还有其他技术可能更好,但我相信这种技术最容易理解(比其他技术更容易):

Dim InxTokenCrntMax As Long     ' Last used entry in Token
Dim Token() As String

' Initialise Token with room for 1000 entries
ReDim Token(1 To 1000)
InxTokenCrntMax = 0

...

' Add new word/phrase to Token
InxTokenCrntMax = InxTokenCrntMax + 1
If InxTokenCrntMax > UBound(Token) Then
  ' Token is full.  Add another 1000 entries.
  ReDim Preserve Token( 1 To 1000 + UBound(Token))
EndIf
Token(InxTokenCrntMax) = NewWordOrPhrase

之前我讨论过你需要的两个外部For循环。外部循环用于工作表中的每一行,中间循环用于行的单元格A中的每个单词/短语。对于每个单词/短语,您需要修剪任何前导或尾随空格,然后使用内部循环将其与数组令牌的当前内容进行匹配。如果匹配,请突出显示单元格中的单词/短语,然后退出内循环的当前重复。如果没有匹配,请将单词/短语添加到Token,如上所示。我会使用类似的东西:

Dim Found As Boolean
Dim InxTokenCrnt As Long
Dim InxTokenCrntMax As Long     ' Last used entry in Token
Dim RowCrnt As Long
Dim RowLast As Long
Dim Token() As String

...

For RowCrnt = 2 ....
  CellPart = Split( ...
  For InxCP = 0 ...     
    TokenCrnt = Trim(CellPart(InxCP))
    Found = False
    For InxTokenCrnt = 1 To InxTokenCrntMax
      If Token(InxTokenCrnt) = TokenCrnt Then
        ' Highlight TokenCrnt within Cell
        ....
        Found = True
        Exit For
      End If
    Next
    If Not Found Then
      ' Add TokenCrnt to Token
      ...
    End If
  Next
Next

...

' Prove all the words/phrases have been collected into Token
For InxTokenCrnt = 1 To InxTokenCrntMax
  Debug.Print Token(InxTokenCrnt)
Next

最后一步是高亮显示重复的单词/短语。

  • 开启Macro Recorder。
  • 突出显示单元格中的单词/短语。
  • 关闭宏录制器。

录制的宏将显示突出显示单元格部分的语句的语法。但是,这段代码:

  • 将对选定的单元格进行操作。
  • 将使用数字作为起始位置。
  • 将使用长度数字。

您需要调整此代码以对指定的单元格进行操作,并将变量用于突出显示的部分的位置和长度。


祝你好运。