
ワードの文書中の文字列をマクロで書き換える。
準備:ワード文書(「文書1.docx」)にて
本文中に 「すずき」
表に 「すずき」
ヘッダー、フッターに 「すずき」
ふたつのTextBox中に 「すずき」
ワードのマクロ、エクセルでのマクロを、とにかく、試行錯誤で完成させました。
しかし、意味が分からない部分があります。
下記にて①、②、③、そして、安定の観点からのサジェスチョンを
お願いしたいと思います。
方法は、これだけではないと思います。多分、使うクラス、メンバーの違い
だと思います。何がしかのサジェスチョンをいただければ幸いです。
宜しくお願い致します。
尚、環境は Windows10(Windows8.1 32bitからup),Office2010です。
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Sub ワードでのマクロ()
Dim sec As Section
Dim hdr As HeaderFooter
Dim i as Integer
' 文章全体に対して、置換を実行する=====================
ActiveDocument.Range(0, 0).Select ’①必要性はない
Selection.WholeStory ’①仮に入れるなら、どんな場合?
strFind = "すずき"
strReplace = "鈴木"
With Selection.Find
.Text = strFind
.Replacement.Text = strReplace
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
' フッターに対して、置換を実行する=====================
For Each sec In ActiveDocument.Sections ’②For eachの必然性?
For Each hdr In sec.Footers ’②同様に
With hdr.Range.Find ’3回,回るが、フッタが3つあるわけではない!?
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next
Next
' ヘッダーに対して、置換を実行する=====================
For Each hdr In ActiveDocument.Sections.Item(1).Headers
’③Itemを使うことでも、OKであったが、やはりメンバーはitem(1)だけのようだ。
' このからくりはどうなっているのであろうか?
With hdr.Range.Find
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next
'Shapeオブジェクトに対して置換実行=================
For i = 1 To ActiveDocument.Shapes.Count
’For NextはTextBoxの数だけ。従って理解可。
ActiveDocument.Shapes(i).Select
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next i
End Sub
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Sub エクセルでのマクロ()
Dim WdApp As Word.Application
Dim WdDoc As Word.Document
'ワード 文章全体に対して、置換を実行する===================
Set WdDoc = GetObject("C:\文書1.docx") ’ワード文書をオープン
Set WdApp = WdDoc.Application
WdApp.Visible = True
WdDoc.Activate
strFind = "すずき"
strReplace = "鈴木"
With WdDoc.Content.Find
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
' フッターに対して、置換を実行する=====================
Dim sec As Word.Section
Dim hdr As Word.HeaderFooter
For Each sec In WdDoc.Sections
For Each hdr In sec.Footers
With hdr.Range.Find
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next
Next
' ヘッダーに対して、置換を実行する=====================
For Each hdr In WdDoc.Sections.Item(1).Headers
With hdr.Range.Find
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next
'Shapeオブジェクトに対して置換実行=================
Dim myShape As Word.Shape
For Each myShape In WdDoc.Shapes
myShape.TextFrame.TextRange.Find.ClearFormatting
myShape.TextFrame.TextRange.Find.Replacement.ClearFormatting
With myShape.TextFrame.TextRange.Find
.Text = strFind
.Replacement.Text = strReplace
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next
WdApp.Quit
End Sub
No.2ベストアンサー
- 回答日時:
No.1の回答者です。
お礼を読みました。VBAでステップインを使ってマクロの動作確認を
しているのですね。
私は、マクロについて少しずつ理解している最中であり、高度な処理を
するようなものは、理解もできていませんし書くこともできません。
ですから、いくつかの疑問に対しては、私なりに理解している範囲での
回答になりますので、違っている場合もあります。
お礼の1.について
> Selectionを入れることで、動きました
そうですか。私も理解しているわけではないのですが。
'ActiveDocument.Range(0, 0).Select
このコメントブロックを解除してもダメだったのでしょうか?
変数rngを本文領域でも使えるようにする方法もあります。
Set rng = ActiveDocument.Range(Start:=0, End:=0)
With rng.Find
.Text = strFind
.Replacement.Text = strReplace
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
私の環境では、これで動作します。
お礼の2.について
> ' セクションごとのヘッダー・フッターで指定
> For Each sec In ActiveDocument.Sections
繰り返しが必要なのは、SectionオブジェクトにはHeadersプロパティと
Footersプロパティがあり、HeadersFootersコレクションオブジェクト
を持つためです。ここには3つの定数があり、それぞれに対して指定を
する必要があるためです。
http://www.relief.jp/itnote/archives/word-vba-he …
さらに、セクション数が複数の場合に、セクション1と次のセクション
との関係で、前セクションとリンク(前と同じ)が切れている場合に、
指定した置換設定が続いているセクションでは実行されないためです。
このことから、セクションを指定する場合は、必要なので記入します。
お礼の3.について
お礼の2.と関連しますが、HeadersFootersコレクションオブジェクト
の3つの定数ごとに処理をしますので、3回の処理をします。
wdHeaderFooterEvenPages
wdHeaderFooterFirstPage
wdHeaderFooterPrimary
これをセクションごとのヘッダーとフッターで繰り返すためです。
お礼の4.について
テキストボックスのみのロックなどがあることすら知りません。
Wordだけで作成したテキストボックスなのでしょうか?
(Excelなら、個別にロックできるので)
Wordにも[編集の制限]がありますが、保護を開始して制限する範囲に、
テキストボックスのみがあるとは思えないのですが?
エラーになる部分のテキストボックスを直接確認してみてはいかが。
今回のエラーが、何が影響しているのか私にはわかりません。
On Errorステートメントでエラーを無視することはできそうですが、
これを使うのは原因がわかっている場合のほうが良いみたいです。
http://officetanaka.net/excel/vba/statement/OnEr …
ちなみに、Wordのバージョンなどの環境を書いたほうが、お互いの
違いによるトラブルを避けることができると思いますよ。
私の場合はWord2013なのですが、No.1の回答で提示したマクロは、
以前所持していたWord2002でも実行できたと思います。
No.1
- 回答日時:
前回と関連する質問ですか?
https://oshiete.goo.ne.jp/qa/9099249.html
WordのVBAにおける置換の対象は、[検索]ダイアログで[検索する場所]
として表示されるものすべてを指定する必要があります。
本文だけでなく、ヘッダー・フッター、脚注やテキストボックスなどのそれぞれに対して指定しないとならないので、それぞれを指定する必要があります。
今回の質問マクロでも、メイン文書(本文領域)とヘッダーとフッター、
テキストボックスそれぞれを指定していますよね。
この検索をする対象を探すときに、その領域の一番最初へとカーソルが来るようにすると、[ワイルドカード]を使った検索のときに検索対象が
外れる不具合を防ぐことができるおまじないみたいなものらしいです。
これが①を最初に書く理由です。
②については不要だと思います。理由としては、検索領域を選択状態に
する必要があるかどうかによります。
質問のマクロだと Selection.Find と Range.Find の両方を使いわけで
利用していますが、複数の領域がある場合は Range.Find だけで検索をしたほうがわかりやすくなると思います。
この場合はWholeStoryを使ってSelectionする必要がないと思います。
http://ameblo.jp/gidgeerock/entry-10555149798.html
http://ameblo.jp/gidgeerock/entry-10558772411.html
Selection.Find を使う場合は、検索条件をすべて書かないとエラーに
なる場合があるのに対して、Range.Find は必要な条件のみ書けば済む
利点もあります。
ですから
' 文章全体に対して、置換を実行する=====================
ActiveDocument.Range(0, 0).Select ' ワイルドカードでは必要
strFind = "すずき"
strReplace = "鈴木"
With Range.Find
.Text = strFind
.Replacement.Text = strReplace
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
で本文領域は問題なく検索し、置換が実行されるはずです。
ヘッダーやフッター、テキストボックスの場合は、それぞれの領域で
変数を用意し、その変数をRangeしてからRange.Findすることで対応
します。以下は、これらを組み込んで私なりに書いてみたものです。
Sub Wordで置換マクロ()
Dim strFind As String
Dim strReplace As String
Dim sp As Shape
Dim sec As Section
Dim hdr As HeaderFooter
Dim rng As Range
'ActiveDocument.Range(0, 0).Select ' ワイルドカードでは必要
strFind = "Word"
strReplace = "Excel"
With Range.Find
.Text = strFind
.Replacement.Text = strReplace
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
' セクションごとのヘッダー・フッターで指定
For Each sec In ActiveDocument.Sections
' フッターの場合
For Each hdr In sec.Footers
Set rng = hdr.Range
With rng.Find
.Text = strFind
.Replacement.Text = strReplace
.Execute Replace:=wdReplaceAll
End With
Next
' ヘッダーの場合
For Each hdr In sec.Headers
Set rng = hdr.Range
With rng.Find
.Text = strFind
.Replacement.Text = strReplace
.Execute Replace:=wdReplaceAll
End With
Next
Next
' テキストボックスの場合
For Each sp In ActiveDocument.Shapes
If sp.Type = msoTextBox Then
Set rng = sp.TextFrame.TextRange
With rng.Find
.Text = strFind
.Replacement.Text = strReplace
.Execute Replace:=wdReplaceAll
End With
End If
Next
End Sub
ExcelでWordを操作するマクロについては記載しません。
上記マクロを参考にして、Excelに移植してください。
質問にあるマクロは、いろいろなサイトのWord用のマクロを参考にした
ようでが、書き方を統一したほうがメンテナンスしやすいと思います。
ありがとうございます。
試してみました。
1.しかし、「オブジェクトがありません」と出てしまいました。
メイン本文の置換の頭です。
試行錯誤の結果
With Selection.Range.Find
.Text = strFind
.Replacement.Text = strReplace
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Selectionを入れることで、動きました。
ワードにおけるselectionが、まだ、きちんと理解できていませんが。
2. ' セクションごとのヘッダー・フッターで指定
での for eachは、1回でだけですが、やはり必要なようです。
1つのメンバーしか持たないcollectionにあっても、兎に角、
for eachでやるしかないのかと思います。
逆に、セクッションの定義は何でしょうか?
大きな文書ファイルにて、第1章、第2章でしょうか?
3.ヘッダーの中でのFor eachは3回、回っています(フッターも)
この3回は、何なのでしょうか? ヘッダー(フッター)を3つの領域に分けることができるということでしょうか?
4.テキストボックスに置いて、テキストロックが掛けられている場合、スキップするには、どうしたらよいでしょうか?
確かに、複数のテストボックスです。
a = ActiveDocument.Shapes.Count a=2とありました。
でも、何故か、2つめのテキストボックスでの
.Execute Replace:=wdReplaceAll
のところで、エラーとなってしまうのです。
テキストロックが掛けられているのだと思います(ロックの掛け方はまだ分かっていません)。先に進めるために、スキップしたいのです。
以上、よろしくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Excel VBA 教えてください。 VBA初心者です。 詳しい方がいましたら教えてください。 下記 3 2023/04/25 11:22
- Visual Basic(VBA) 実行時エラー´5854´ 文字列型パラメーターが長すぎます。 3 2023/06/08 21:17
- Excel(エクセル) 日付で矢印マクロ 4 2023/07/25 16:47
- Visual Basic(VBA) エクセルのマクロについて教えてください。 3 2023/02/22 08:53
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- Visual Basic(VBA) エクセルのマクロについて教えてください。 3 2023/02/17 11:59
- Visual Basic(VBA) 【VBAエラー】Nextに対するForがありません 対策について 5 2022/11/21 21:26
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) Excel VBAの解読について質問があります。 概要は、マクロでチェックボックスにチェックすると日 1 2023/02/10 07:50
- Visual Basic(VBA) 形式を選択して貼り付け 以下のコードで「元」シートと「先」シートのA列に同じ値があったら指定範囲をコ 5 2022/11/11 07:30
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Word文書、取り消し線部分の一...
-
エクセルで、コンマをピリオド...
-
箇条書きのアタマに一括で「・...
-
word文書内のピンク色の文字を...
-
excelマクロ ボタンを押して文...
-
ワードで赤字のみを削除する方法
-
MSワード、エクセルの文章にマ...
-
同じ文字
-
ワードで太字になっているとこ...
-
エクセル 住所録の中に登録して...
-
Word相互参照の文字を一括で変...
-
word ある文字色の部分のみ別の...
-
word 2003で、赤い文字(あるい...
-
ワードの置換で、文字列の前後...
-
エクセルでシートにある赤文字...
-
セルの中の不要な文字を削除し...
-
wordで長文中の赤字をすべて網...
-
Wordの置換でフォントが変わらない
-
Wordでカッコで括った文字を一...
-
ワードの表の中の値の表示形式...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Word文書、取り消し線部分の一...
-
箇条書きのアタマに一括で「・...
-
Wordでカッコで括った文字を一...
-
エクセルでシートにある赤文字...
-
Word相互参照の文字を一括で変...
-
word である文字をすべてイタリ...
-
ワードで赤字のみを削除する方法
-
Excelの表中,数字の「1」をす...
-
エクセルで、コンマをピリオド...
-
「WORD」での作業 日本語・英...
-
ワードの表の中の値の表示形式...
-
excelマクロ ボタンを押して文...
-
ワードで半角英数の文字だけ選...
-
word文書内のピンク色の文字を...
-
ワードで太字になっているとこ...
-
セルの中の不要な文字を削除し...
-
ワードである言葉を打つと自動...
-
MSワード、エクセルの文章にマ...
-
同じ文字
-
Word(2010)の差込印刷時に特定...
おすすめ情報