ルビの割付を変更するFunction(Word)
ルビの割付を変更するFunction
正確に言えば、ルビの割付位置を変更した後のField
オブジェクトのCode.Text
プロパティの値を変更するFunctionです。
ルビの割付の変更
たとえば、
この「月面宙返」にルビを振る。
「ルビ」ダイアログボックスにこのように設定して、[OK]をクリックすると、
このように、ルビが振られる。
で、日本語入力をオフにして、[Alt] + [F9]を押すと、
このように、フィールドコードが表示される。
ちなみに、この場合のフィールドコードは、
EQ \* jc2 \* "Font:MS 明朝" \* hps10 \o\ad(\s\up 10(ムーンサルト),月面宙返)
となっている。
フィールドコードの解読については、
コチラのサイトが非常に詳しく説明してくださっている。
ルビの割付に関わっているのは、
\* jc2
の部分(①)と、
\ad
の部分(②)。
フィールドコードの文字列は、Field
オブジェクトのCode.Text
プロパティを参照すれば取得できるので、取得した文字列のうち、①と②を書き換えて、再設定してやればよい。
ルビの割付を変更するFunctionのコード
まず、列挙体を作っておく。
リスト1 標準モジュール宣言セクション
'Enums' Private Enum AlignCode acAlignCenter = 0 '中央揃え' acAlignDistribution1 '均等割付1' acAlignDistribution2 '均等割付2' acAlignLeft '左揃え' acAlignRight '右揃え' End Enum
このように設定しておき、Functionの引数をAlignCode
型にしておけば、引数の指定が楽かつわかりやすくなる。
次は、フィールドコード文字列点検用のFunction。
実は、均等割付絡みのフィールドコードのうち、②の方、すなわち
\ad
は、手動で「中央揃え」にすると、本来「\ac
」となるはずが、省略されてしまうのである!!!!!!!!
こんなふうに手動で「中央揃え」に変更してみる。
すると、フィールドコードは、
ほらね。
こいつと比べると一目瞭然。
「\o
」の後がいきなり「(s\up\
」になっている。
これでは非常に困る。
従って、省略を補うFunctionを作った。
リスト2 標準モジュール
Private Function getRepairedFieldCodeText( _ ByVal targetFieldCodeText) As String Dim ret As String ret = targetFieldCodeText Dim ar As Variant ar = Split(ret, "\") '" 'インデックスの最大値が「7」だったら、省略されていない。' If UBound(ar) = 7 Then GoTo Finalizer '省略を補う処理' ReDim Preserve ar(7) ar(7) = ar(6) ar(6) = ar(5) ar(5) = "ac(" '手動で「中央揃え」にした後は、 ar(4) の値が"o("になる。' ar(4) = "o" ret = getAssembledFieldCodeText(ar) Finalizer: getRepairedFieldCodeText = ret End Function Private Function getAssembledFieldCodeText( _ ByRef splitFieldCode As Variant) As String Dim i As Long Dim ret As String For i = LBound(splitFieldCode) To UBound(splitFieldCode) ret = ret & splitFieldCode(i) & "\" '" Next ret = Left(ret, Len(ret) - 1) getAssembledFieldCodeText = ret End Function
一旦、フィールドコード文字列を「\」をデリミタとしてSplit
関数でバラしておき、必要な箇所を修正して再度組み立て直す、という処理にした。
ここまでで準備はおしまい。
あとは、メインのFunction。
リスト3 標準モジュール
Private Function getConvertedAlignmentRubyFieldCodeText( _ ByVal targetFieldCodeText As String, _ ByVal targetAlignCode As AlignCode) As String Dim ret As String ret = targetFieldCodeText If targetAlignCode < 0 Or _ targetAlignCode > 4 Then GoTo Finalizer '……(1)' ret = getRepairedFieldCodeText(ret) Dim alignSetting1 As String Dim alignSetting2 As String Select Case targetAlignCode '……(2)' Case acAlignCenter alignSetting1 = "* jc0 ": alignSetting2 = "ac(" Case acAlignDistribution1 alignSetting1 = "* jc1 ": alignSetting2 = "ad(" Case acAlignDistribution2 alignSetting1 = "* jc2 ": alignSetting2 = "ad(" Case acAlignLeft alignSetting1 = "* jc3 ": alignSetting2 = "al(" Case acAlignRight alignSetting1 = "* jc4 ": alignSetting2 = "ar(" End Select Dim ar As Variant '……(3)' ar = Split(ret, "\") '" ar(1) = alignSetting1 ar(5) = alignSetting2 ret = getAssembledFieldCodeText(ar) '……(4)' Finalizer: getConvertedAlignmentRubyFieldCodeText = ret End Function
(1)の
If targetAlignCode < 0 Or _ targetAlignCode > 4 Then GoTo Finalizer
はガード節。第2引数は列挙体にしたけれど、別に整数なら「5
」でも「-3
」でも渡せてしまうので、そういう予期せぬ値が渡されていたらここでシャットアウト。第1引数で渡された文字列をそのまま返すことにする。
(2)からの11行
Select Case targetAlignCode Case acAlignCenter alignSetting1 = "* jc0 ": alignSetting2 = "ac(" Case acAlignDistribution1 alignSetting1 = "* jc1 ": alignSetting2 = "ad(" Case acAlignDistribution2 alignSetting1 = "* jc2 ": alignSetting2 = "ad(" Case acAlignLeft alignSetting1 = "* jc3 ": alignSetting2 = "al(" Case acAlignRight alignSetting1 = "* jc4 ": alignSetting2 = "ar(" End Select
では、第2引数に応じて、均等割付の種類に応じた2箇所の文字列を変数にぶち込んでいる。
(3)からの4行
Dim ar As Variant ar = Split(ret, "\") '" ar(1) = alignSetting1 ar(5) = alignSetting2
では、Split
関数で一旦フィールドコード文字列をバラし、インデックス「1
」と「5
」の要素を書き換える。
あとは(4)の
ret = getAssembledFieldCodeText(ar)
で、リスト2のgetAssembledFieldCodeText
メソッドを用いて、再びフィールドコード文字列を組み立て直しておしまい。
使ってみる
次のコードで実験。
リスト4 標準モジュール
Public Sub test01() Dim targetField As Field For Each targetField In Selection.Fields With targetField If .Type = wdFieldFormula And _ (InStr(1, .Code.Text, "\s\up") > 0 Or _ InStr(1, .Code.Text, "\s\do") > 0) Then '……(5)' .Code.Text = getConvertedAlignmentRubyFieldCodeText( _ .Code.Text, acAlignLeft) '……(*)' End If End With Next End Sub
選択範囲のField
オブジェクトを総当たりにする方式。
したがって、(5)の
If .Type = wdFieldFormula And _ (InStr(1, .Code.Text, "\s\up") > 0 Or _ InStr(1, .Code.Text, "\s\do") > 0) Then
で、ルビのためのフィールドなのかどうかを判定する。
ルビ用のフィールドコードの特徴は、「\s\up
」(上付き)か(手動で設定できないからめったに見かけないけど)「\s\do
」(下付き)のどちらかが含まれていることなので、このような条件式にした。
実行結果
(*)のところでgetConvertedAlignmentRubyFieldCodeText
メソッドに渡した第2引数がacAlignLeft
なので、
当然こうなる。
(*)を
.Code.Text = getConvertedAlignmentRubyFieldCodeText( _ .Code.Text, acAlignRight)
に変えると、
こうなって、
.Code.Text = getConvertedAlignmentRubyFieldCodeText( _ .Code.Text, acAlignCenter)
こうすると、
こうなる。
おわりに
Wordのルビ周りは、フィールドコードが絡むこともあって、なかなか気軽には手を出しにくい領域だったが、ワードの理解シリーズ様のおかげで、だいぶ理解が進んだと思う。
ここまで下準備ができていれば、ルビのフォントを変えたり、サイズを変えたりするぐらいなら楽勝です。
参考
コチラもどうぞ。