【问题标题】:change first 3 characters to bold format将前 3 个字符更改为粗体格式
【发布时间】:2021-08-13 08:39:35
【问题描述】:

如何将包含“T##-”的单元格的前 3 个字符和“CLEARANCE”字体更改为 BOLD 并将其循环到 STANDARD 和 NON-STANDARD 表格的最后一行

Sub Formatting()

    Dim StartCell As Range
    Set StartCell = Range("A15")
    Dim myList As Range

    Set myList = Range("A15:A" & Range("A" & Rows.Count).End(xlUp).Row)
    Dim x As Range

    For Each x In myList
        'myList.ClearFormats
        x.Font.Bold = False
        If InStr(1, x.Text, "CLEARANCE") > 0 Or InStr(1, x.Text, "clearance") > 0 Then
            x.Font.Bold = True
        Else
            x.Font.Bold = False
        End If
    Next
    
        For Each x In myList
        'myList.ClearFormats
        x.Font.Bold = False
        If InStr(1, x.Text, "T*") > 0 Then
            x.Font.Bold = True
        Else
            x.Font.Bold = False
        End If
    Next

End Sub

原点

格式化

【问题讨论】:

  • 要更改单元格的部分格式,请使用Characters 集合。
  • 也不需要循环;)最快的方法是过滤数据并使用它。 rng.AutoFilter Field:=1, Criteria1:="=T??-*", Operator:=xlAnd, Criteria2:="=*CLEARANCE*"
  • 还有另一种更快的方法(我相信比使用字符)。让我在发布答案之前做一些测试。
  • 示例:If Left(x, 1) = "T" Then x.Characters(, 3).Font.FontStyle = "Bold" 如果字符串以“T”开头,则将其前 3 个字符加粗。
  • 你能改变你的问题标题避免小写吗?还是你在对我们大喊大叫?

标签: excel vba loops fonts


【解决方案1】:

这是实现您想要的一种方法,我觉得它更快(我可能错了)。这种方式可以让 Excel 完成所有繁琐的工作:D。

假设我们的数据如下所示

逻辑:

  1. 确定您要使用的工作表。
  2. 删除A列中的所有自动过滤器和find last row
  3. 构建您的范围。
  4. 根据"=T??-*""=*CLEARANCE*" 过滤范围。
  5. 确定过滤范围。
  6. 检查是否有任何被过滤的内容,如果有,则执行Find and Replace
  7. 搜索“CLEARANCE”并将其周围替换为粗体标签,如代码所示。
  8. 循环过滤范围以创建 html 字符串,然后复制到剪贴板
  9. 最后将它们粘贴回去。

代码:

这是你正在尝试的吗?我已经对代码进行了注释,因此您理解它应该没有问题,但如果您这样做,只需询问:)

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim lRow As Long
    Dim rng As Range, rngFinal As Range, aCell As Range
    Dim htmlString As Variant
    
    '~~> Set this to the relevant Sheet
    Set ws = Sheet1
    
    With ws
        '~~> Remove any autofilter
        .AutoFilterMode = False
        
        '~~> Find last row in Col A
        lRow = .Range("A" & .Rows.Count).End(xlUp).Row
        
        '~~> Construct your range
        Set rng = .Range("A1:A" & lRow)
        
        '~~> Filter the range
        With rng
            .AutoFilter Field:=1, Criteria1:="=T??-*", _
                        Operator:=xlAnd, Criteria2:="=*CLEARANCE*"
                 
            '~~> Set the filtered range
            Set rngFinal = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
        End With
    End With
    
    '~~> Check if there was anything filtered
    If Not rngFinal Is Nothing Then
        rngFinal.Replace What:="CLEARANCE", Replacement:="<b>CLEARANCE</b>", _
        LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:= _
        False, ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
        
        '~~> Loop through the filtered range and add
        '~~> ending html tags and copy to clipboard and finally paste them
        For Each aCell In rng.SpecialCells(xlCellTypeVisible)
            If aCell Like "T??-*" Then
                htmlString = "<html><b>" & _
                             Left(aCell.Value2, 4) & "</b>" & _
                             Mid(aCell.Value2, 5) & "</html>"
                
                With CreateObject("htmlfile")
                    With .parentWindow.clipboardData
                        Select Case True
                            Case Len(htmlString): .setData "text", htmlString
                            Case Else: .GetData ("text")
                        End Select
                    End With
                End With
                
                DoEvents
                
                aCell.PasteSpecial xlPasteAll
            End If
        Next aCell
    End If
    
    '~~> Remove any filters
    ws.AutoFilterMode = False
End Sub

输出:

注意:如果您想在其中一个文本不存在时将其中一个文本加粗,则将上述代码中的Operator:=xlAnd 更改为Operator:=xlOr

【讨论】:

  • 我试过了,但它说编译错误:变量未定义在“FormulaVersion:=xlReplaceFormula2”
  • 我认为您使用的是旧版本的 excel。删除, FormulaVersion:=xlReplaceFormula2再试一次
  • 感谢它的魅力我刚刚删除了“FormulaVersion:=xlReplaceFormula2”
  • 我为你鼓掌!!我正在考虑一个带有子匹配的正则表达式解决方案,但仍在摸不着头脑....
  • @JvdV 很想看到它到位。 :) 如果你弄清楚了,请发布它!
【解决方案2】:

我想我会采用这个基于正则表达式的解决方案。我花了很长时间尝试使用 Submatches 属性,但由于它们没有 FirstIndex()Lenght() 属性,所以我别无选择,只能使用常规匹配对象和 Like() 运算符:

Sub Test()

Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim rng As Range, cl As Range, lr As Long

lr = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Set rng = ws.Range("A1:A" & lr)

With CreateObject("vbscript.regexp")
    .Global = True
    .Pattern = "\bCLEARANCE\b"
    For Each cl In rng
        If cl.Value Like "T[0-9][0-9]-*" Then
            cl.Characters(0, 3).Font.Bold = True
            If .Test(cl.Value) Then
                Set M = .Execute(cl.Value)
                cl.Characters(M(0).firstindex + 1, M(0).Length).Font.Bold = True
            End If
        End If
    Next
End With

End Sub

Like() 操作符只是用来验证单元格的值是否以大写“T”开头,后跟一个连字符的两位数。这种语法类似于正则表达式,但无需调用 regex-object 即可完成。

当满足起始条件时,我使用正则表达式匹配来测试单词边界之间的可选“CLEARANCE”,以断言子字符串不是较大子字符串的一部分。然后我使用FirstIndex()Lenght() 属性将相应的字符加粗。

【讨论】:

  • 这太美了! :) 为了使其更快地与 Autofilter 结合使用?
  • @SiddharthRout,谢谢,但不想从您的回答中得到任何雷声。我同意我们可以在这里加快速度。我注意到的一件事是,您忽略了缺少“CLEARANCE”的那一行。如果我可以问,你为什么这样做?
  • 我的印象是这两个条件都是必须的。可以通过将Operator:=xlAnd 更改为Operator:=xlOr 来轻松处理:)
  • @RonRosenfeld,感谢您的思考。这实际上是我在编辑之前在最初的帖子中写下的内容,但是当我使用 Like() 运算符来验证单元格值的开始时,我认为它是表达式中不必要的“或”运算符。
  • 旁注: Like 比较 "T[0-9][0-9]-*" 可以简化为 If cl.value Like "T##-*" Then(即# 替换 [0-9])@JvdV
【解决方案3】:

简短而简单,但不是快速灵活的方法。 “最低限度”
未指定工作表,因此使用活动工作表。将忽略“CLEARANCE”的多个实例,将循环所有内容(慢),忽略起始模式(只关心它是否以“T”开头),不会从不应为粗体的内容中删除任何粗体文本。

Sub FormattingLoop()
Dim x As Range
For Each x In Range("A15:A" & Cells(Rows.Count, "A").End(xlUp).Row)
    If Left(x, 1) = "T" Then x.Characters(, 3).Font.FontStyle = "Bold"
    If InStr(UCase(x), "CLEARANCE") > 0 Then x.Characters(InStr(UCase(x), "CLEARANCE"), 9).Font.FontStyle = "Bold"
Next x
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 2014-11-05
    • 2012-10-10
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多