【问题标题】:Find text and change color查找文本并更改颜色
【发布时间】:2018-12-24 09:18:04
【问题描述】:

我想循环工作簿的所有工作表,以更改具有特定字符串的单元格的颜色。

我使用.Replace(我需要 MatchCase 和 lookat)。
它在不考虑大小写的情况下替换文本。 (例如,如果在数组中它是小写的并且找到的字符串是大写的,它将被更改为小写)。绕过此问题的唯一方法是使用MatchCase:= false 并列出所有选项,这可能效率非常低。

我可以使用.Find 或其他函数执行该操作吗?

Sub CellMarked()

Dim fndlist As Variant, x As Integer, sht as worksheet

fndlist = Array("Column1", "Column2")

For Each sht In ActiveWorkbook.Worksheets
    With sht
        For x = LBound(fndlist) To UBound(fndlist)
            .Cells.Replace What:=fndlist(x), Replacement:=fndlist(x), _
              lookat:=xlPart, SearchOrder:=xlByRows, MatchCase:=True, _
              SearchFormat:=False, ReplaceFormat:=True
            Application.ReplaceFormat.Font.Color = 255
        Next x
    End With
next sht
    
End Sub

【问题讨论】:

  • VBA 不是最好的解决方案。你真的应该考虑使用条件格式。
  • @K.Dᴀᴠɪs,我倾向于尽可能避免条件格式化,因为它会增加文件计算时间和文件大小。但这是我的感觉
  • @K.Dᴀᴠɪs,感谢您的建议,很遗憾我无法向工作簿添加任何条件格式,此宏应引用其他工作簿。

标签: excel vba


【解决方案1】:

您可以使用Find() 方法并构建一个辅助函数:

Function GetCellsWithValue(sht As Worksheet, val As Variant, foundCells As Range) As Boolean
    Dim found As Range
    Dim firstAddress As String
    With sht.UsedRange
        Set foundCells = .Resize(1, 1).Offset(.Rows.Count) ' fill foundCells with a "dummy" found one to avoid 'If Not foundCells Is Nothing' check before any 'Union()' method call

        Set found = .Find(what:=val, lookat:=xlPart, LookIn:=xlValues)
        If Not found Is Nothing Then
            firstAddress = found.Address
            Do
                Set foundCells = Union(foundCells, found)
                Set found = .FindNext(found)
            Loop While found.Address <> firstAddress
        End If

        Set foundCells = Intersect(.Cells, foundCells) ' get rid of the "dummy" found cell
    End With

    GetCellsWithValue = Not foundCells Is Nothing
End Function

你可以在你的“主要”子中使用如下:

Option Explicit

Sub CellMarked()

    Dim fndlist As Variant, val As Variant, sht As Worksheet
    Dim foundCells As Range

    fndlist = Array("Column1", "Column2")

    For Each sht In ActiveWorkbook.Worksheets
    With sht
        For Each val In fndlist
            If GetCellsWithValue(sht, val, foundCells) Then foundCells.Font.Color = 255
        Next
    End With
    Next sht

End Sub

【讨论】:

  • 嗨@DisplayName,它工作得很好。我将在我拥有的代码中实现(并调整)它!再次感谢您的大力支持!!!简单明了。
【解决方案2】:

查找文本应用填充

Sub CellMarked()

  Dim rngFind As Range, rngU As Range
  Dim fndlist As Variant
  Dim strFirst As String
  Dim i As Integer, x As Integer

  fndlist = Array("Column1", "Column2")

  For i = 1 To Worksheets.Count

    With Worksheets(i)

      For x = 0 To UBound(fndlist)
        ' Check if worksheet has no values.
        If Not .Cells.Find("*", .Cells(.Rows.Count, Columns.Count), -4163, 2, 1) _
            Is Nothing Then
          ' Find string.
          Set rngFind = .Cells.Find(fndlist(x), _
              .Cells(.Rows.Count, Columns.Count))
          If Not rngFind Is Nothing Then
            If Not rngU Is Nothing Then
              Set rngU = Union(rngU, rngFind) ' All other occurrences.
             Else
              Set rngU = rngFind ' First occurrence.
            End If
            strFirst = rngFind.Address
            ' Check for other occurrences.
            Do
              Set rngFind = .Cells.FindNext(rngFind)
              If rngFind.Address <> strFirst Then
                Set rngU = Union(rngU, rngFind)
               Else
                Exit Do
              End If
            Loop
          End If
        End If
      Next

      ' Apply formatting.
      If Not rngU Is Nothing Then
        rngU.Interior.Color = 255
        ' rngU.Font.Color = 255
        Set rngU = Nothing
      End If

    End With

  Next

End Sub

【讨论】:

  • 嗨@VBasic2008,搜索MatchCase := False ,我做了这个更改Set rngFind = .Cells.Find(what:=fndlist(x), lookat:=xlPart, SearchOrder:=xlByRows, MatchCase:=True, SearchFormat:=False)?,我希望它有意义。代码工作得很好!非常感谢我想知道您是否可以更好地解释这段代码.Cells(.Rows.Count, Columns.Count), -4163, 2, 1 提前谢谢
  • @M.Kuz:当输入不带参数的参数(-4163 或 xlValues)时(查找),它们必须按特定顺序排列:What、After、LookIn、LookAt、SearchOrder、SearchDirection、MatchCase、MatchByte , 搜索格式。前2个是自我解释。接下来的 3 个是 LookIn、LookAt 和 SearchOrder,它们每次都会保存,这就是为什么在后面的代码搜索中省略它们的原因。 SearchDirection 为 xlNext 且 MatchCase 默认为 False。 MatchCase True 表示 Aa 和 aa 不同。这些参数可以像我一样与值一起使用,也可以像你一样与常量一起使用。
  • @M.Kuz:当您省略第二个参数(After)时,搜索从最后评估的左上角单元格开始。当您编写 After:= .Cells(.Rows.Count, Columns.Count) 时,它从最后评估的右下角单元格开始,即首先评估左上角的第一个单元格。 -4613, 2, 1 表示 3 个(保存)参数 LookIn、LookAt 和 SearchOrder 的 xlValues、xlPart、xlByRows。要查看参数的相应值,只需在查找行之后停止代码并将鼠标悬停在参数上即可。我建议您仔细阅读 Find 方法的 VIsual Basic Help。
  • @M.Kuz:我认为 MatchCase 应该省略(假),因为如果你有 column1 而不是 Column1 它将找不到。也是搜索格式,在这种情况下它不会做任何事情。正如我所提到的,如果在“Set rngFind”行(即“If Not .Cells.Find”行之前使用了 3 个(保存)参数),则不必使用它们。我认为你应该保持原样。
  • 嗨,非常感谢您的澄清,它真的很详尽,对提高我的编码技能很有帮助。我完全同意你关于 MatchCase 应该设置为 false,我的错误。
【解决方案3】:

更改“strToFind”并尝试:

Option Explicit

Sub test()

    Dim strToFind As String
    Dim rng As Range, cell As Range
    Dim ws As Worksheet

    'String to Find is "Test"
    strToFind = "Test"

    With ThisWorkbook

        For Each ws In .Worksheets
            With ws
                Set rng = .UsedRange

                For Each cell In rng
                    If cell.Value = strToFind Then
                        cell.Interior.Color = RGB(255, 0, 0)
                    End If
                Next cell
            End With

        Next ws

    End With

End Sub

【讨论】:

  • 感谢您的建议,不幸的是这个宏不使用.find函数
猜你喜欢
  • 1970-01-01
  • 2020-02-24
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多