色の付いた文字部分を( )に変換する

このように部分的に色付けされたセル内の文字列を、右のようにカッコと空白に変換するプログラムです。テストの問題文を作る際に便利かと思います。
また、If文からSelect Case文への変換の仕方を見ていきたいと思います。
使い方
A1セルの内容をB1セルに変換して表示します。
A1セルを2回クリックして、編集モードにして( )にしたい部分をドラッグして文字色を変更してください。

文字色は標準の黒以外ならなんでもOKです。
また、数式バーからも変更できます。

プログラム解説
方針としては、Charactersというプロパティでセル内の文字列を1つずつ取り出せるので、その文字が色付きか判断して行きます。
さらに、カッコで括らなければいけないので、色付きに変化しかた否かをBoolean変数を用いて判断するようにしました。
Sub macro1()
Dim i As Long, bColor As Boolean, chrC As Long
Dim str As String
str = ""
bColor = False
Debug.Print Range("A1").Characters(1, 1).Font.Color
For i = 1 To Len(Range("A1"))
chrC = Range("A1").Characters(i, 1).Font.Color
If chrC <> 0 Then
If bColor Then
str = str & " "
Else
str = str & "("
bColor = True
End If
Else
If bColor Then
str = str & ")" & Range("A1").Characters(i, 1).Text
bColor = False
Else
str = str & Range("A1").Characters(i, 1).Text
End If
End If
Next i
If bColor Then
str = str & ")"
End If
Range("B1") = str
End Sub
For文の中で、色付き文字か?色付き文字が継続されているか?を判断しています。
最後にForループの後に閉じ括弧が必要か判断しています。
If文をまとめた書き方
さて、macro1 は If文が入れ子になっており、処理は異なるものの内部のIf文は2回目と同じに並んできます。
少々冗長なので、これをAndを使って、入れ子の無いIf文に変更してみます。
Sub macro2()
Dim i As Long, bColor As Boolean, chrC As Long
Dim str As String
str = ""
bColor = False
Debug.Print Range("A1").Characters(1, 1).Font.Color
For i = 1 To Len(Range("A1"))
chrC = Range("A1").Characters(i, 1).Font.Color
If chrC <> 0 And bColor Then
str = str & " "
ElseIf chrC <> 0 And bColor = False Then
str = str & "("
bColor = True
ElseIf chrC = 0 And bColor Then
str = str & ")" & Range("A1").Characters(i, 1).Text
bColor = False
ElseIf chrC = 0 And bColor = False Then
str = str & Range("A1").Characters(i, 1).Text
End If
Next i
If bColor Then
str = str & ")"
End If
Range("B1") = str
End Sub
この形ですと、分岐処理がどのような条件のときに処理されるのかがわかりやすくなります。
このままでも良いのですが、分岐要素が3つ4つと増えてきたときには、また冗長になっていく事が目に見えています。
そこで、Select Case文を使って分岐処理と分岐後の処理を2つに分けてみましょう。
Select Case文を使った書き方
今回はBoolean変数のようにTrue・Falseで分けられるような条件が複数ある場合を想定します。
この場合1・0で置き換えられるので、2進法を使って再現できます。
以下の図を見てください。

2つの条件の場合は2の2乗で0~3の値で表現できます。
条件が3つ4つと増えたら、3列、4列と増やし2の3乗、2の4乗と要素数が増えます。
やり方としては、最初の条件は、2の0乗で0か1を加え、次の条件では2の1乗で0か2を加えます。
実際のコードの方がわかりやすいと思いますので、以下をご覧ください。
Sub macro3()
Dim i As Long, bColor As Boolean, chrC As Long
Dim str As String
Dim n As Long
str = ""
bColor = False
Debug.Print Range("A1").Characters(1, 1).Font.Color
For i = 1 To Len(Range("A1"))
'/////////// 判定部分 ///////////
n = 0
'黒文字?
If Range("A1").Characters(i, 1).Font.Color = 0 Then
n = 1
End If
'色変化あり?
If bColor Then
n = n + 2
End If
'////////// 分岐部分 ///////////
Select Case n
Case 0 '黒以外 色変更なし
str = str & "("
bColor = True
Case 1 '黒 色変更なし
str = str & Range("A1").Characters(i, 1).Text
Case 2 '黒以外 色変更あり
str = str & " "
Case 3 '黒 色変更あり
str = str & ")" & Range("A1").Characters(i, 1).Text
bColor = False
End Select
Next i
If bColor Then
str = str & ")"
End If
Range("B1") = str
End Sub
ここでは n という整数の変数を用意して、最初の条件が True なら 1を加え、次の条件が True なら 2を加えています。
もし3つ目の条件があれば、その時は4を加えます。
一応3つの条件の時の値の分布をみておきましょう。

あとは、Select Case で条件にあう処理を書けばOKです。
まとめ
今回は If文から Select Case文に変換する方法として、2進法を用いた例を紹介しました。
条件に関しては、True・Falseで分けられるような場合でしか使えませんが、条件がたくさんあるような場合に、条件判断部分とそれぞれの処理部分を分けて記述できるので見通しの良いコードを書くことができると思います。
サンプルコードは、改造すればテスト問題の作成とかに役に立つかもしれませんので役立てて頂ければと思います。
macro1,2,3は動作は全く同じです。