2016/10/28 追記:
改良版のマクロを書きました。
前回の記事では、Wordのルビダイアログの操作に挑んで見事につまづいたわけですが、対処は簡単です。
配置やオフセット、フォントといったオプションの設定で上手くいかないのであれば、ダイアログでそれらの設定を行わなければ良いわけです。
'ThisDocument Option Explicit Private d As Object Public Sub Sample() If Selection.Start <> Selection.End Then Set d = CreateObject("htmlfile") Set d.parentWindow.onhelp = Me d.parentWindow.SetTimeout "onhelp.SetPhoneticDialog()", 100, "VBScript" 'setTimeoutで時間差実行 Application.Dialogs(wdDialogPhoneticGuide).Show End If End Sub Public Sub SetPhoneticDialog(Optional ByVal dummy As Long = 0) '[ルビ]ダイアログ操作 '※UIAutomationClient(UIAutomationCore.dll)要参照 Dim uiAuto As CUIAutomation Dim elmRoot As IUIAutomationElement Dim elmPhoneticDialog As IUIAutomationElement 'ルビダイアログ Dim elmOkButton As IUIAutomationElement 'OK Dim elmRubyEdit As IUIAutomationElement 'ルビ Dim iptn As IUIAutomationInvokePattern Set uiAuto = New CUIAutomation Set elmRoot = uiAuto.GetRootElement '[ルビ]ダイアログ取得 While elmPhoneticDialog Is Nothing Set elmPhoneticDialog = GetElement(uiAuto, elmRoot, UIA_NamePropertyId, "ルビ", UIA_WindowControlTypeId) DoEvents Wend '[OK]ボタン取得 Set elmOkButton = GetElement(uiAuto, elmPhoneticDialog, UIA_NamePropertyId, "OK", UIA_ButtonControlTypeId) '[ルビ]エディットボックス取得 Set elmRubyEdit = GetElement(uiAuto, elmPhoneticDialog, UIA_AutomationIdPropertyId, "19") If Len(Trim(elmRubyEdit.GetCurrentPropertyValue(UIA_ValueValuePropertyId))) < 1 Then elmRubyEdit.SetFocus Else '[OK]ボタンクリック Set iptn = elmOkButton.GetCurrentPattern(UIA_InvokePatternId) iptn.Invoke End If End Sub Private Function GetElement(ByVal uiAuto As CUIAutomation, _ ByVal elmParent As IUIAutomationElement, _ ByVal propertyId As Long, _ ByVal propertyValue As Variant, _ Optional ByVal ctrlType As Long = 0) Dim cndFirst As IUIAutomationCondition Dim cndSecond As IUIAutomationCondition Set cndFirst = uiAuto.CreatePropertyCondition(propertyId, propertyValue) If ctrlType <> 0 Then Set cndSecond = uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, ctrlType) Set cndFirst = uiAuto.CreateAndCondition(cndFirst, cndSecond) End If Set GetElement = elmParent.FindFirst(TreeScope_Subtree, cndFirst) End Function
上記の通り、“OKボタンを押す操作だけ”行うようにした結果、前回の記事のコードに比べて大分シンプルになりました。
前回つまづいたWord 2016での動作も問題ありません。
これでようやくルビダイアログが操作できるようになったので、あとは一括ふりがな設定をするべく、マクロを連続で実行するだけです。
選択範囲にある漢字にルビを一括設定するWordマクロ
連続で実行と言っても、処理手順は「ルビ(ふりがな)を一括設定するWordマクロ」で書いている通り、“単語単位で列挙していき、単語が漢字である場合にルビを設定、漏れ防止に文字単位で列挙していき、文字が漢字である場合にルビを設定”していけば良いだけです。
'ThisDocument Option Explicit Private d As Object Public Sub Sample2() Dim sel As Word.Range Dim r As Word.Range Set d = CreateObject("htmlfile") Set d.parentWindow.onhelp = Me Set sel = Selection.Range '単語単位で処理 For Each r In sel.Words If ChkKanjiRange(r) = True Then r.Select d.parentWindow.SetTimeout "onhelp.SetPhoneticDialog()", 100, "VBScript" 'setTimeoutで時間差実行 Application.Dialogs(wdDialogPhoneticGuide).Show End If Next '文字単位で処理 For Each r In sel.Characters If IsKanji(r.Text) = True Then r.Select d.parentWindow.SetTimeout "onhelp.SetPhoneticDialog()", 100, "VBScript" 'setTimeoutで時間差実行 Application.Dialogs(wdDialogPhoneticGuide).Show End If Next MsgBox "処理が終了しました。", vbInformation + vbSystemModal End Sub Public Sub SetPhoneticDialog(Optional ByVal dummy As Long = 0) '[ルビ]ダイアログ操作 '※UIAutomationClient(UIAutomationCore.dll)要参照 Dim uiAuto As CUIAutomation Dim elmRoot As IUIAutomationElement Dim elmPhoneticDialog As IUIAutomationElement 'ルビダイアログ Dim elmOkButton As IUIAutomationElement 'OK Dim elmRubyEdit As IUIAutomationElement 'ルビ Dim iptn As IUIAutomationInvokePattern Set uiAuto = New CUIAutomation Set elmRoot = uiAuto.GetRootElement '[ルビ]ダイアログ取得 While elmPhoneticDialog Is Nothing Set elmPhoneticDialog = GetElement(uiAuto, elmRoot, UIA_NamePropertyId, "ルビ", UIA_WindowControlTypeId) DoEvents Wend '[OK]ボタン取得 Set elmOkButton = GetElement(uiAuto, elmPhoneticDialog, UIA_NamePropertyId, "OK", UIA_ButtonControlTypeId) '[ルビ]エディットボックス取得 Set elmRubyEdit = GetElement(uiAuto, elmPhoneticDialog, UIA_AutomationIdPropertyId, "19") If Len(Trim(elmRubyEdit.GetCurrentPropertyValue(UIA_ValueValuePropertyId))) < 1 Then elmRubyEdit.SetFocus Else '[OK]ボタンクリック Set iptn = elmOkButton.GetCurrentPattern(UIA_InvokePatternId) iptn.Invoke End If End Sub Private Function GetElement(ByVal uiAuto As CUIAutomation, _ ByVal elmParent As IUIAutomationElement, _ ByVal propertyId As Long, _ ByVal propertyValue As Variant, _ Optional ByVal ctrlType As Long = 0) Dim cndFirst As IUIAutomationCondition Dim cndSecond As IUIAutomationCondition Set cndFirst = uiAuto.CreatePropertyCondition(propertyId, propertyValue) If ctrlType <> 0 Then Set cndSecond = uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, ctrlType) Set cndFirst = uiAuto.CreateAndCondition(cndFirst, cndSecond) End If Set GetElement = elmParent.FindFirst(TreeScope_Subtree, cndFirst) End Function Private Function ChkKanjiRange(ByVal rng As Word.Range) As Boolean '指定したRangeが漢字のみかチェック Dim ret As Boolean Dim i As Long ret = True For i = 1 To Len(rng.Text) If IsKanji(Mid(rng.Text, i, 1)) = False Then ret = False Exit For End If Next ChkKanjiRange = ret End Function Private Function IsKanji(ByVal char As String) As Boolean '漢字判別 Dim cc As Variant Dim ret As Boolean ret = True '初期化 cc = Val("&H" & Hex(AscW(char)) & "&") Select Case cc Case 19968 To 40959 'CJK統合漢字(U+4E00-U+9FFF) Case 13312 To 19903 'CJK統合漢字拡張A(U+3400-U+4DBF) Case 131072 To 173791 'CJK統合漢字拡張B(U+20000-U+2A6DF) Case 173824 To 177983 'CJK統合漢字拡張C(U+2A700-U+2B73F) Case 177984 To 178207 'CJK統合漢字拡張D(U+2B740-U+2B81F) Case 63744 To 64255 'CJK互換漢字(U+F900-U+FAFF) Case 194560 To 195103 'CJK互換漢字補助(U+2F800-U+2FA1F) Case Else ret = False End Select IsKanji = ret End Function
仕組みとしては上記コードで問題なく処理できるはずです。
・・・が、いざ実行してみると、
上図のようにふりがなが表示されない文字列が出てくるのです。
(手動でダイアログを表示した場合は、問題なくふりがな表示されるので原因は不明)
Word 2016では問題なく実行できるので(下図参照)、恐らくはIME等の実行環境に原因があるのだと思いますが、これ以上はさすがに調べるのが面倒なので、このあたりで妥協しておきます。
そんなわけで、結局ExcelのGetPhoneticメソッドを使う方法とどちらがマシなのか分からないくらい中途半端なコードになってしまいましたが、一応ルビダイアログの操作はできた、ということで、今回は終わりにしたいと思います。
この記事へのコメントはありません。