「Wordの「検索と置換」について」の版間の差分
Notion-MW タグ: 差し戻し済み |
Notion-MW タグ: 手動差し戻し |
||
(同じ利用者による、間の1版が非表示) | |||
18行目: | 18行目: | ||
文書全体の置換のためには、簡潔にいえば、①文書内の必要なRangeを全て取得する②取得した全てのRangeごとに検索や置換を実行する、という2ステップが必要である。このうち難しいのは①のほうで、②は割と簡単である。とりあえず②を担当する関数の名前を<code>My_Find_and_Replace()</code>としておこう。そうすると、①の部分については、前述の英語サイトを参考に結論からいえば、以下のように書けばいいということになる。 | 文書全体の置換のためには、簡潔にいえば、①文書内の必要なRangeを全て取得する②取得した全てのRangeごとに検索や置換を実行する、という2ステップが必要である。このうち難しいのは①のほうで、②は割と簡単である。とりあえず②を担当する関数の名前を<code>My_Find_and_Replace()</code>としておこう。そうすると、①の部分については、前述の英語サイトを参考に結論からいえば、以下のように書けばいいということになる。 | ||
< | <syntaxhighlight lang="vb.net">Sub Macro0() | ||
Set objUndo = Application.UndoRecord | Set objUndo = Application.UndoRecord | ||
objUndo.StartCustomRecord ( | 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行目: | 32行目: | ||
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 | 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行目: | 48行目: | ||
Next | Next | ||
objUndo.EndCustomRecord | objUndo.EndCustomRecord | ||
End Sub</ | 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行目: | 55行目: | ||
②の部分である<code>My_Find_and_Replace</code>の例は以下のようなものになるだろう。 | ②の部分である<code>My_Find_and_Replace</code>の例は以下のようなものになるだろう。 | ||
< | <syntaxhighlight lang="vb.net">Sub My_Find_and_Replace(r As Range) | ||
With r.Find | With r.Find | ||
.ClearFormatting | .ClearFormatting | ||
.Replacement.ClearFormatting | .Replacement.ClearFormatting | ||
.text = | .text = "前" | ||
.Replacement.text = | .Replacement.text = "後" | ||
.Font.Name = | .Font.Name = "MS 明朝" | ||
.Replacement.Font.Name = | .Replacement.Font.Name = "MS ゴシック" | ||
.Wrap = wdFindContinue | .Wrap = wdFindContinue | ||
.Execute Replace:=wdReplaceAll | .Execute Replace:=wdReplaceAll | ||
End With | End With | ||
End Sub</ | End Sub</syntaxhighlight> | ||
この例ではMS明朝で書かれた「前」という文字をMSゴシックの「後」という文字に全て置換する。「MS」は全角である。wdFindContinueは文書の先頭に戻って置換を続けるオプションであるが、今回のようにSelectionではなくRangeに対してFindする場合はおそらく不要。その他色々とオプションがあるので調べてみるとよい。 | この例ではMS明朝で書かれた「前」という文字をMSゴシックの「後」という文字に全て置換する。「MS」は全角である。wdFindContinueは文書の先頭に戻って置換を続けるオプションであるが、今回のようにSelectionではなくRangeに対してFindする場合はおそらく不要。その他色々とオプションがあるので調べてみるとよい。 | ||
90行目: | 90行目: | ||
例えば有名な「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の上に合字用アルファベットが乗ったもの」を全て消したりフォントを変えたりしたければ、以下のように合字用の文字をあわせてワイルドカード指定することになる(合字用の文字を入れているので奇妙な見た目になっているが問題なく動作する)。 | ||
< | <syntaxhighlight lang="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行目: | 187行目: | ||
例えば筆者が公開している[https://github.com/ge9/NazonoMincho 謎乃明朝](文字数が多いため「謎乃明朝」「謎乃明朝+」の2フォントに分かれている)がサポートしている全ての文字で使われるように置換する場合は以下のようになる。与えられたRangeに対して置換するという前述の②の部分だけ載せるので適宜①の部分と組み合わせること。 | 例えば筆者が公開している[https://github.com/ge9/NazonoMincho 謎乃明朝](文字数が多いため「謎乃明朝」「謎乃明朝+」の2フォントに分かれている)がサポートしている全ての文字で使われるように置換する場合は以下のようになる。与えられたRangeに対して置換するという前述の②の部分だけ載せるので適宜①の部分と組み合わせること。 | ||
< | <syntaxhighlight lang="vb.net">Sub SearchAndReplaceInStory(myStoryRange As Range) | ||
Dim CJK As String | Dim CJK As String | ||
Dim CJKComp As String | Dim CJKComp As String | ||
198行目: | 198行目: | ||
Dim KRadi As String | Dim KRadi As String | ||
Dim RadiSup As String | Dim RadiSup As String | ||
CJK = | CJK = "[" & ChrW(&H4E00) & "-" & ChrW(&H9FFF) & "]" | ||
CJKComp = | CJKComp = "[" & ChrW(&HF900) & "-" & ChrW(&HFAFF) & "]" | ||
CJKA = | CJKA = "[" & ChrW(&H3400) & "-" & ChrW(&H4DBF) & "]" | ||
KRadi = | KRadi = "[" & ChrW(&H2F00) & "-" & ChrW(&H2FDF) & "]" | ||
RadiSup = | RadiSup = "[" & ChrW(&H2E80) & "-" & ChrW(&H2EFF) & "]" | ||
IVS = ChrW(& | IVS = ChrW(&HDB40) & "[" & ChrW(&HDD00) & "-" & ChrW(&HDDEF) & "]" | ||
SVS = | SVS = "[" & ChrW(&HFE00) & "-" & ChrW(&HFE0F) & "]" | ||
CJKBtoF = | CJKBtoF = "[" & ChrW(&HD840) & "-" & ChrW(&HD87D) & "][" & ChrW(&HDC00) & "-" & ChrW(&HDFFF) & "]" | ||
CJKCompS = ChrW(& | CJKCompS = ChrW(&HD87E) & "[" & ChrW(&HDC00) & "-" & ChrW(&HDFFF) & "]" | ||
TIP = | TIP = "[" & ChrW(&HD880) & "-" & ChrW(&HD8BF) & "][" & ChrW(&HDC00) & "-" & ChrW(&HDFFF) & "]" | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJK | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKComp | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKA | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", KRadi | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", RadiSup | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKCompS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJK & IVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKA & IVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKBtoF & IVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", TIP & IVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJK & SVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKA & SVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", CJKBtoF & SVS | ||
' replaceFont myStoryRange, | ' replaceFont myStoryRange, "謎乃明朝 Regular", TIP & SVS | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝+ Regular", CJKBtoF | ||
replaceFont myStoryRange, | replaceFont myStoryRange, "謎乃明朝 Regular", TIP | ||
End Sub | End Sub | ||
232行目: | 232行目: | ||
With myStoryRange.Find | With myStoryRange.Find | ||
.text = text | .text = text | ||
.Replacement.text = | .Replacement.text = "" | ||
.Wrap = wdFindContinue | .Wrap = wdFindContinue | ||
.Format = True | .Format = True | ||
242行目: | 242行目: | ||
.Execute Replace:=wdReplaceAll | .Execute Replace:=wdReplaceAll | ||
End With | End With | ||
End Sub</ | End Sub</syntaxhighlight> | ||
康煕部首なども置換するため長ったらしくなってしまったが、サロゲート文字をChrWで指定するというところさえ理解してしまえば、やっていることは単純である。ChrW(&H4E00)などは普通に漢字で「一」と書いてももちろん構わない。 | 康煕部首なども置換するため長ったらしくなってしまったが、サロゲート文字をChrWで指定するというところさえ理解してしまえば、やっていることは単純である。ChrW(&H4E00)などは普通に漢字で「一」と書いてももちろん構わない。 | ||