エクセルVBA100本ノック。13本目:文字列の部分フォント

この記事から得るもの

指定した文字に色を付け、太文字にする。
InStr関数をループして処理する方法が分かる。

1 今回のお題

選択セル(Selection:複数範囲あり)の文字列に「注意」という文字があった場合は、その「注意」の文字だけを"赤の太字"に設定してください。
セル以外(図形等)が選択されている場合は何もせずに正常終了するようにしてください。

f:id:bimori466:20201108151708p:plain

excel-ubara.com

2 今回のお題の意図

個人情報の取り扱いがうるさくなった昨今の社会的な背景があるように感じました。注意が入っているデータはメールしないなど。
注意、社外秘などのワードがあれば強調するというときに使えます。

3 回答

最初は全く処理が思いつきませんでした。とりあえずわかるのはInstr()関数で、特定の文字が含まれているか調べることでした。

私の最初の回答

Sub ノック13本目_1()

i = InStr(Selection, "注意")
Selection.Characters(Start:=i, Length:=2).Font.Color = -16776961

End Sub

選択したセルに”注意”が入っていれば、発見した文字位置から2文字を赤色に塗るという簡単なもの。
しかし、これでは1セルに対して1回しか処理を実行できません。
例えば、「ハチに注意、蛇に注意」と”注意”が2回ある場合は、2文字目の注意は赤色にできません。
その点をふまえて改良したのが次のコード。

2回目の回答

Sub ノック13本目_4()

Dim myrng As Range
Dim StratLen As Long
Dim SeachedLen As Variant


For Each myrng In Selection
    
    StratLen = 1
    
    Do
        SeachedLen = InStr(StratLen, myrng.Value, "注意")
        
        If SeachedLen = 0 Then: Exit Do
        
        myrng.Characters(Start:=SeachedLen, Length:=2).Font.Color = vbRed
        myrng.Characters(Start:=SeachedLen, Length:=2).Font.Bold = True
        
        StratLen = SeachedLen + 2
    Loop
Next

変数StratLenに、Instr関数で処理する文字位置を指定します(初期値は1)。
Instr関数の戻り値が0(注意の文字がない)になるまで繰り返します。
こうして、Do Loopで繰り返し処理することにより、1つのセルに複数の注意という文字が入っていても、文字を赤色にすることができます。

しかし、お題の中に、「セル以外(図形等)が選択されている場合は何もせずに正常終了するようにしてください」という条件を忘れていました。
選択されているものが、セルなのか、図形なのかを調べるには、TypeName関数を使います。

選択されているものが、セルの場合のみ処理するコードを追記

Sub ノック13本目_5()

Dim myrng As Range
Dim StratLen As Long
Dim SeachedLen As Variant


If TypeName(Selection) <> "Range" Then
        Exit Sub
End If

For Each myrng In Selection
    
    StratLen = 1
    
    Do
        SeachedLen = InStr(StratLen, myrng.Value, "注意")
        
        If SeachedLen = 0 Then: Exit Do
        
        myrng.Characters(Start:=SeachedLen, Length:=2).Font.Color = vbRed
        myrng.Characters(Start:=SeachedLen, Length:=2).Font.Bold = True
        
        StratLen = SeachedLen + 2
    Loop
Next

End Sub

これで、セルが選択されている場合のみのコードが完成です。

4 一言

今回のお題は、かなり実用的なものだと感じました。唐突にこういうの作れ!という光景が思い浮かぶようでした。
InStr関数をループ処理する。勉強になりました。