Wordのスタイルをタグ化するマクロです!
以前から、Wordの書式のタグ化には興味がありました。
下付き文字の書式情報をタグ化(テキスト情報)に変換するマクロ
関連して、水野麻子さんが非常に役に立つマクロを公開されています。
このマクロは、マクロ実行前に誤動作を防止する仕組もはいっておりまして、非常に完成度が高くてやさしいマクロです。
さて、これに関連して、先日おちょこちょいさんから文字書式を保存/復元するマクロ へのコメントをいただきました。
さらに、kinuasaさんがこれに対応して文字書式をマークアップする(Word VBA) の記事にてコード化をしていただいたおかげで、新しいマクロが生まれました。
kinuasaさんのコードを是非ご覧ください。
すごく美しいです。
「StyleToTag」のコードのCase で分類された書き方や、モジュール化の方法など、ヒントが満載です。
この解説だけで記事が何本か書けそうなくらいうれしいコードです。
公開をどうもありがとうございます。
また、私のコードで欠けていた改行記号の書式の処理を追記していただいております。
タグ化の肝は、改行記号にはいっている書式をどうやって処理するか?ですね。
なので、Rangeオブジェクト(以下のコード中の r )に改行記号がある場合とない場合とで処理を分けています。
ときおり、不可解な処理結果になることは知っておりましたが、細かく検証をしておりませんでした。
上記の改行記号の処理の追加で、処理が安定しました。ありがとうございました。
さらに、勝手ながらkinuasaさんのコードを少し改良して、私なりのマクロを作りました。
以下のコード中、部分的に変更しました。それ以外は、kinuasaさんのコードです。
<目次>
改良点①
文字書式が部分的に重なって登録されている文字列にたいしてタグ化できるように、「StyleToTag」のコードを変更いたしました。
kinuasaさんのコードでは、r.Textを持ちて置き換えをされていますが、r.Textの場合には、書式が落ちることもあるらしいため、別の方法でタグの追記をしました。
まだ、十分に試運転がされていないので、暫定的にこの処理としておきます。
改良点②
おちょこちょいさんのご要望のとおり、斜体と太字とのタグの順序を入れ替えました。
改良点③
先日kinuasaさんから教えていただいたカーソル位置の保存方法を用いました。
StyleToTagとTagToStyleの両方のコードで、myRangeというオブジェクトを定義しています。
ここにカーソル位置を保存しています。
Public Sub Sample_StyleToTag()
'ループでまとめて処理(タグ化)
Dim s(1 To 9) As String
Dim i As Long
s(1) = "i"
s(2) = "b"
s(3) = "u"
s(4) = "s"
s(5) = "ds"
s(6) = "sup"
s(7) = "sub"
s(8) = "h1"
s(9) = "p"
For i = LBound(s) To UBound(s)
StyleToTag s(i)
Next
End Sub
Public Sub Sample_TagToStyle()
'ループでまとめて処理(装飾化)
Dim s(1 To 9) As String
Dim i As Long
s(1) = "i"
s(2) = "b"
s(3) = "u"
s(4) = "s"
s(5) = "ds"
s(6) = "sup"
s(7) = "sub"
s(8) = "h1"
s(9) = "p"
For i = LBound(s) To UBound(s)
TagToStyle s(i)
Next
End Sub
Private Sub StyleToTag(ByVal sTag As String)
'装飾をタグ化
Dim r As word.Range
Dim myRange As word.Range
Set myRange = Selection.Range
Set r = ActiveDocument.Range(0, 0)
With r.Find
.ClearFormatting
.Format = True
.Forward = True
.MatchWildcards = False
.Text = vbNullString
'装飾検索(条件設定)
Select Case LCase$(sTag)
Case "b": .Font.Bold = True '太字
Case "i": .Font.Italic = True '斜体
Case "u": .Font.Underline = wdUnderlineSingle '下線
Case "s": .Font.StrikeThrough = True '取り消し線
Case "ds": .Font.DoubleStrikeThrough = True '二重取り消し線
Case "sup": .Font.Superscript = True '上付き文字
Case "sub": .Font.Subscript = True '下付き文字
Case "h1": .Style = ActiveDocument.Styles("見出し 1") '[見出し 1]
Case "p": .Style = ActiveDocument.Styles("本文") '[本文]
Case Else
MsgBox "対応していない形式です。" & vbCrLf & "処理を中止します。", vbCritical + vbSystemModal
Exit Sub
End Select
Do While .Execute
If InStr(r.Text, vbCr) Then
If vbCr <> r.Text Then
r.End = r.End - 1
r.InsertBefore "<" & sTag & ">"
r.InsertAfter "</" & sTag & ">"
Else
'r自体が改行記号の場合→何もしない
End If
Else
r.InsertBefore "<" & sTag & ">"
r.InsertAfter "</" & sTag & ">"
End If
'装飾解除
Select Case LCase$(sTag)
Case "b": r.Font.Bold = False
Case "i": r.Font.Italic = False
Case "u": r.Font.Underline = wdUnderlineNone
Case "s": r.Font.StrikeThrough = False
Case "ds": r.Font.DoubleStrikeThrough = False
Case "sup": r.Font.Superscript = False
Case "sub": r.Font.Subscript = False
Case "h1", "p": r.Select: Selection.ClearFormatting
End Select
r.Collapse wdCollapseEnd
Loop
.ClearFormatting
End With
myRange.Select
Set r = Nothing
Set myRange = Nothing
End Sub
Private Sub TagToStyle(ByVal sTag As String)
'タグを装飾化
Dim r As word.Range
Dim myRange As word.Range
Set myRange = Selection.Range
'対応チェック
Select Case LCase$(sTag)
Case "b", "i", "u", "s", "ds", "sup", "sub", "h1", "p":
Case Else
MsgBox "対応していない形式です。" & vbCrLf & "処理を中止します。", vbCritical + vbSystemModal
Exit Sub
End Select
Set r = ActiveDocument.Range(0, 0)
With r.Find
.ClearFormatting
.Format = False
.Forward = True
.MatchFuzzy = False
.MatchWildcards = True
.Text = "\<" & sTag & "\>*\</" & sTag & "\>"
Do While .Execute
'装飾実施
Select Case LCase$(sTag)
Case "b": r.Font.Bold = True
Case "i": r.Font.Italic = True
Case "u": r.Font.Underline = wdUnderlineSingle
Case "s": r.Font.StrikeThrough = True
Case "ds": r.Font.DoubleStrikeThrough = True
Case "sup": r.Font.Superscript = True
Case "sub": r.Font.Subscript = True
Case "h1": r.Style = ActiveDocument.Styles("見出し 1")
Case "p": r.Style = ActiveDocument.Styles("本文")
End Select
'タグ除去
Selection.SetRange r.End - Len(sTag) - 3, r.End
Selection.delete
Selection.SetRange r.Start, r.Start + Len(sTag) + 2
Selection.delete
r.Collapse wdCollapseEnd
Loop
.ClearFormatting
End With
myRange.Select
Set r = Nothing
Set myRange = Nothing
End Sub





