ルビの割付を変更する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のルビ周りは、フィールドコードが絡むこともあって、なかなか気軽には手を出しにくい領域だったが、ワードの理解シリーズ様のおかげで、だいぶ理解が進んだと思う。
ここまで下準備ができていれば、ルビのフォントを変えたり、サイズを変えたりするぐらいなら楽勝です。
参考
コチラもどうぞ。