「Wordの「検索と置換」について」の版間の差分

Notion-MW
タグ: 差し戻し済み
Notion-MW
タグ: 差し戻し済み
18行目: 18行目:
文書全体の置換のためには、簡潔にいえば、①文書内の必要なRangeを全て取得する②取得した全てのRangeごとに検索や置換を実行する、という2ステップが必要である。このうち難しいのは①のほうで、②は割と簡単である。とりあえず②を担当する関数の名前を<code>My_Find_and_Replace()</code>としておこう。そうすると、①の部分については、前述の英語サイトを参考に結論からいえば、以下のように書けばいいということになる。
文書全体の置換のためには、簡潔にいえば、①文書内の必要なRangeを全て取得する②取得した全てのRangeごとに検索や置換を実行する、という2ステップが必要である。このうち難しいのは①のほうで、②は割と簡単である。とりあえず②を担当する関数の名前を<code>My_Find_and_Replace()</code>としておこう。そうすると、①の部分については、前述の英語サイトを参考に結論からいえば、以下のように書けばいいということになる。


<pre class="visual">Sub Macro0()
<syntaxhighlight lang="python">
 
vb.net
Sub Macro0()
   Set objUndo = Application.UndoRecord
   Set objUndo = Application.UndoRecord
   objUndo.StartCustomRecord (&quot;Replace All With VBA&quot;)
   objUndo.StartCustomRecord ("Replace All With VBA")
   'Fix the skipped blank Header/Footer problem.
   'Fix the skipped blank Header/Footer problem.
   lngValidate = ActiveDocument.Sections(1).Headers(1).Range.StoryType
   lngValidate = ActiveDocument.Sections(1).Headers(1).Range.StoryType
32行目: 35行目:
       Select Case rngStory.StoryType
       Select Case rngStory.StoryType
         Case 6, 7, 8, 9, 10, 11
         Case 6, 7, 8, 9, 10, 11
           If rngStory.ShapeRange.Count &gt; 0 Then
           If rngStory.ShapeRange.Count > 0 Then
             For Each oShp In rngStory.ShapeRange
             For Each oShp In rngStory.ShapeRange
               If oShp.TextFrame.HasText Then
               If oShp.TextFrame.HasText Then
48行目: 51行目:
   Next
   Next
   objUndo.EndCustomRecord
   objUndo.EndCustomRecord
End Sub</pre>
End Sub</syntaxhighlight>
<code>My_Find_and_Replace</code>が二か所あることに注意。また、<code>objUndo</code>に関する部分は、これを設定しておくことでこのマクロによる置換操作全体が「ひとまとめの操作」と認識され、Ctrl+Zだけで全て戻せるようになる(これがないと何度か必要になる)。不要ならこの3行は削ってよい。
<code>My_Find_and_Replace</code>が二か所あることに注意。また、<code>objUndo</code>に関する部分は、これを設定しておくことでこのマクロによる置換操作全体が「ひとまとめの操作」と認識され、Ctrl+Zだけで全て戻せるようになる(これがないと何度か必要になる)。不要ならこの3行は削ってよい。


55行目: 58行目:
②の部分である<code>My_Find_and_Replace</code>の例は以下のようなものになるだろう。
②の部分である<code>My_Find_and_Replace</code>の例は以下のようなものになるだろう。


<pre class="visual">Sub My_Find_and_Replace(r As Range)
<syntaxhighlight lang="python">
 
vb.net
Sub My_Find_and_Replace(r As Range)
     With r.Find
     With r.Find
         .ClearFormatting
         .ClearFormatting
         .Replacement.ClearFormatting
         .Replacement.ClearFormatting
         .text = &quot;&quot;
         .text = ""
         .Replacement.text = &quot;&quot;
         .Replacement.text = ""
         .Font.Name = &quot;MS 明朝&quot;
         .Font.Name = "MS 明朝"
         .Replacement.Font.Name = &quot;MS ゴシック&quot;
         .Replacement.Font.Name = "MS ゴシック"
         .Wrap = wdFindContinue
         .Wrap = wdFindContinue
         .Execute Replace:=wdReplaceAll
         .Execute Replace:=wdReplaceAll
     End With
     End With
End Sub</pre>
End Sub</syntaxhighlight>
この例ではMS明朝で書かれた「前」という文字をMSゴシックの「後」という文字に全て置換する。「MS」は全角である。wdFindContinueは文書の先頭に戻って置換を続けるオプションであるが、今回のようにSelectionではなくRangeに対してFindする場合はおそらく不要。その他色々とオプションがあるので調べてみるとよい。
この例ではMS明朝で書かれた「前」という文字をMSゴシックの「後」という文字に全て置換する。「MS」は全角である。wdFindContinueは文書の先頭に戻って置換を続けるオプションであるが、今回のようにSelectionではなくRangeに対してFindする場合はおそらく不要。その他色々とオプションがあるので調べてみるとよい。


90行目: 96行目:
例えば有名な「pͪoͣnͬpͣoͥnͭpͣa͡inͥ」の最初の「pͪ」は、内部的には普通のローマ字のpと合字用の上付きアルファベットのhという2文字で表現されているが、カーソルを移動させる限りではまとめて1文字のように扱われる(メモ帳などにコピペすれば確認できる)。従って、「pͪoͣnͬpͣoͥnͭpͣa͡inͥ」の「p」を全て削除しようと思ってWordの置換でpを””に置換しても、<strong>書記素クラスタとしては「p」に一致するものがない</strong>ので何も起こらない。「pͪ」と書記素クラスタごと入れれば正しく置換される。「pの上に合字用アルファベットが乗ったもの」を全て消したりフォントを変えたりしたければ、以下のように合字用の文字をあわせてワイルドカード指定することになる(合字用の文字を入れているので奇妙な見た目になっているが問題なく動作する)。
例えば有名な「pͪoͣnͬpͣoͥnͭpͣa͡inͥ」の最初の「pͪ」は、内部的には普通のローマ字のpと合字用の上付きアルファベットのhという2文字で表現されているが、カーソルを移動させる限りではまとめて1文字のように扱われる(メモ帳などにコピペすれば確認できる)。従って、「pͪoͣnͬpͣoͥnͭpͣa͡inͥ」の「p」を全て削除しようと思ってWordの置換でpを””に置換しても、<strong>書記素クラスタとしては「p」に一致するものがない</strong>ので何も起こらない。「pͪ」と書記素クラスタごと入れれば正しく置換される。「pの上に合字用アルファベットが乗ったもの」を全て消したりフォントを変えたりしたければ、以下のように合字用の文字をあわせてワイルドカード指定することになる(合字用の文字を入れているので奇妙な見た目になっているが問題なく動作する)。


<pre class="visual">p[ͣ-ͯ]</pre>
<syntaxhighlight lang="python">
 
vb.net
p[ͣ-ͯ]</syntaxhighlight>
Wordの置換では正規表現のグループは使えないので「上付きアルファベットはそのままでpだけをbに変えてbͪoͣnͬbͣoͥnͭbͣa͡inͥにする」などはおそらく単一の「検索と置換」の実行では不可能である。もちろんマクロで場合分けしてやればできるはず。
Wordの置換では正規表現のグループは使えないので「上付きアルファベットはそのままでpだけをbに変えてbͪoͣnͬbͣoͥnͭbͣa͡inͥにする」などはおそらく単一の「検索と置換」の実行では不可能である。もちろんマクロで場合分けしてやればできるはず。


187行目: 196行目:
例えば筆者が公開している[https://github.com/ge9/NazonoMincho 謎乃明朝](文字数が多いため「謎乃明朝」「謎乃明朝+」の2フォントに分かれている)がサポートしている全ての文字で使われるように置換する場合は以下のようになる。与えられたRangeに対して置換するという前述の②の部分だけ載せるので適宜①の部分と組み合わせること。
例えば筆者が公開している[https://github.com/ge9/NazonoMincho 謎乃明朝](文字数が多いため「謎乃明朝」「謎乃明朝+」の2フォントに分かれている)がサポートしている全ての文字で使われるように置換する場合は以下のようになる。与えられたRangeに対して置換するという前述の②の部分だけ載せるので適宜①の部分と組み合わせること。


<pre class="visual">Sub SearchAndReplaceInStory(myStoryRange As Range)
<syntaxhighlight lang="python">
 
vb.net
Sub SearchAndReplaceInStory(myStoryRange As Range)
     Dim CJK As String
     Dim CJK As String
     Dim CJKComp As String
     Dim CJKComp As String
198行目: 210行目:
     Dim KRadi As String
     Dim KRadi As String
     Dim RadiSup As String
     Dim RadiSup As String
     CJK = &quot;[&quot; &amp; ChrW(&amp;H4E00) &amp; &quot;-&quot; &amp; ChrW(&amp;H9FFF) &amp; &quot;]&quot;
     CJK = "[" & ChrW(&H4E00) & "-" & ChrW(&H9FFF) & "]"
     CJKComp = &quot;[&quot; &amp; ChrW(&amp;HF900) &amp; &quot;-&quot; &amp; ChrW(&amp;HFAFF) &amp; &quot;]&quot;
     CJKComp = "[" & ChrW(&HF900) & "-" & ChrW(&HFAFF) & "]"
     CJKA = &quot;[&quot; &amp; ChrW(&amp;H3400) &amp; &quot;-&quot; &amp; ChrW(&amp;H4DBF) &amp; &quot;]&quot;
     CJKA = "[" & ChrW(&H3400) & "-" & ChrW(&H4DBF) & "]"
     KRadi = &quot;[&quot; &amp; ChrW(&amp;H2F00) &amp; &quot;-&quot; &amp; ChrW(&amp;H2FDF) &amp; &quot;]&quot;
     KRadi = "[" & ChrW(&H2F00) & "-" & ChrW(&H2FDF) & "]"
     RadiSup = &quot;[&quot; &amp; ChrW(&amp;H2E80) &amp; &quot;-&quot; &amp; ChrW(&amp;H2EFF) &amp; &quot;]&quot;
     RadiSup = "[" & ChrW(&H2E80) & "-" & ChrW(&H2EFF) & "]"
     IVS = ChrW(&amp;HDB40) &amp; &quot;[&quot; &amp; ChrW(&amp;HDD00) &amp; &quot;-&quot; &amp; ChrW(&amp;HDDEF) &amp; &quot;]&quot;
     IVS = ChrW(&HDB40) & "[" & ChrW(&HDD00) & "-" & ChrW(&HDDEF) & "]"
     SVS = &quot;[&quot; &amp; ChrW(&amp;HFE00) &amp; &quot;-&quot; &amp; ChrW(&amp;HFE0F) &amp; &quot;]&quot;
     SVS = "[" & ChrW(&HFE00) & "-" & ChrW(&HFE0F) & "]"
     CJKBtoF = &quot;[&quot; &amp; ChrW(&amp;HD840) &amp; &quot;-&quot; &amp; ChrW(&amp;HD87D) &amp; &quot;][&quot; &amp; ChrW(&amp;HDC00) &amp; &quot;-&quot; &amp; ChrW(&amp;HDFFF) &amp; &quot;]&quot;
     CJKBtoF = "[" & ChrW(&HD840) & "-" & ChrW(&HD87D) & "][" & ChrW(&HDC00) & "-" & ChrW(&HDFFF) & "]"
     CJKCompS = ChrW(&amp;HD87E) &amp; &quot;[&quot; &amp; ChrW(&amp;HDC00) &amp; &quot;-&quot; &amp; ChrW(&amp;HDFFF) &amp; &quot;]&quot;
     CJKCompS = ChrW(&HD87E) & "[" & ChrW(&HDC00) & "-" & ChrW(&HDFFF) & "]"
     TIP = &quot;[&quot; &amp; ChrW(&amp;HD880) &amp; &quot;-&quot; &amp; ChrW(&amp;HD8BF) &amp; &quot;][&quot; &amp; ChrW(&amp;HDC00) &amp; &quot;-&quot; &amp; ChrW(&amp;HDFFF) &amp; &quot;]&quot;
     TIP = "[" & ChrW(&HD880) & "-" & ChrW(&HD8BF) & "][" & ChrW(&HDC00) & "-" & ChrW(&HDFFF) & "]"
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJK
     replaceFont myStoryRange, "謎乃明朝 Regular", CJK
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKComp
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKComp
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKA
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKA
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, KRadi
     replaceFont myStoryRange, "謎乃明朝 Regular", KRadi
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, RadiSup
     replaceFont myStoryRange, "謎乃明朝 Regular", RadiSup
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKCompS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKCompS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJK &amp; IVS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJK & IVS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKA &amp; IVS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKA & IVS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKBtoF &amp; IVS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKBtoF & IVS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, TIP &amp; IVS
     replaceFont myStoryRange, "謎乃明朝 Regular", TIP & IVS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJK &amp; SVS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJK & SVS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKA &amp; SVS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKA & SVS
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, CJKBtoF &amp; SVS
     replaceFont myStoryRange, "謎乃明朝 Regular", CJKBtoF & SVS
'    replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, TIP &amp; SVS
'    replaceFont myStoryRange, "謎乃明朝 Regular", TIP & SVS
     replaceFont myStoryRange, &quot;謎乃明朝+ Regular&quot;, CJKBtoF
     replaceFont myStoryRange, "謎乃明朝+ Regular", CJKBtoF
     replaceFont myStoryRange, &quot;謎乃明朝 Regular&quot;, TIP
     replaceFont myStoryRange, "謎乃明朝 Regular", TIP
End Sub
End Sub


232行目: 244行目:
     With myStoryRange.Find
     With myStoryRange.Find
         .text = text
         .text = text
         .Replacement.text = &quot;&quot;
         .Replacement.text = ""
         .Wrap = wdFindContinue
         .Wrap = wdFindContinue
         .Format = True
         .Format = True
242行目: 254行目:
         .Execute Replace:=wdReplaceAll
         .Execute Replace:=wdReplaceAll
     End With
     End With
End Sub</pre>
End Sub</syntaxhighlight>
康煕部首なども置換するため長ったらしくなってしまったが、サロゲート文字をChrWで指定するというところさえ理解してしまえば、やっていることは単純である。ChrW(&amp;H4E00)などは普通に漢字で「一」と書いてももちろん構わない。
康煕部首なども置換するため長ったらしくなってしまったが、サロゲート文字をChrWで指定するというところさえ理解してしまえば、やっていることは単純である。ChrW(&amp;H4E00)などは普通に漢字で「一」と書いてももちろん構わない。