Word VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


15 / 306 ツリー ←次へ | 前へ→

【829】各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/2(金) 10:58 質問[未読]

【831】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/5(月) 9:30 質問[未読]
【832】Re:各ページ各行それぞれ違う文字列の挿入 亀マスター 18/2/5(月) 13:19 回答[未読]
【833】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/6(火) 11:14 質問[未読]
【835】Re:各ページ各行それぞれ違う文字列の挿入 亀マスター 18/2/6(火) 19:41 回答[未読]
【836】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/7(水) 14:03 質問[未読]
【837】Re:各ページ各行それぞれ違う文字列の挿入 亀マスター 18/2/7(水) 21:38 発言[未読]
【838】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/9(金) 12:47 質問[未読]
【839】Re:各ページ各行それぞれ違う文字列の挿入 亀マスター 18/2/10(土) 0:08 回答[未読]
【844】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/13(火) 12:48 質問[未読]
【848】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/14(水) 10:31 質問[未読]
【849】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/14(水) 11:05 お礼[未読]
【842】Re:各ページ各行それぞれ違う文字列の挿入 マナ 18/2/10(土) 15:00 発言[未読]
【845】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/13(火) 14:12 質問[未読]
【846】Re:各ページ各行それぞれ違う文字列の挿入 マナ 18/2/13(火) 19:54 発言[未読]
【847】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/14(水) 10:22 発言[未読]
【850】Re:各ページ各行それぞれ違う文字列の挿入 マナ 18/2/14(水) 19:51 発言[未読]
【851】Re:各ページ各行それぞれ違う文字列の挿入 あかよん 18/2/15(木) 14:03 お礼[未読]

【831】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/5(月) 9:30 -

引用なし
パスワード
   ご回答ありがとうございます。
とりあえず、*のところに1行目の前後に挿入する記述を書いて、テストをしてみました。*のところに記述したのは以下の通りです。それから、1ページ目だけに関しては、2行目以降はmytextの数字を変えただけでそのままコピペしてこの記述の繰り返しでできましたが、それでよいのでしょうか?


Selection.GoTo What:=wdGoToPage, Which:=wdGoToFirst, Count:=1
  myExcludes = Chr(9) & Chr(10) & Chr(11) & Chr(12) & Chr(13)

  Selection.EndKey Unit:=wdLine, Extend:=wdExtend
  Selection.MoveEndWhile Cset:=myExcludes, Count:=wdBackward
 
 Dim myDoc As Document
 Dim myRange As Range

 Const myText1 As String = "<item id=""" '前の文字列"
 Const myText2 As String = """>" '後の文字列

 Set myDoc = ActiveDocument

 With Selection
  .InsertBefore myText1
  .InsertAfter myText2
 End With

 With Selection
  Set myRange = myDoc.Range(.End - Len(myText2), .End)
 End With

 Selection.Collapse wdCollapseEnd

 Set myRange = Nothing
 Set myDoc = Nothing
   
 Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1

【832】Re:各ページ各行それぞれ違う文字列の挿入
回答  亀マスター  - 18/2/5(月) 13:19 -

引用なし
パスワード
   > Selection.GoTo What:=wdGoToPage, Which:=wdGoToFirst, Count:=1

無限ループしている直接の原因はこれでしょう。
これはカーソルを1ページ目へ移動する記述ですので、ループ処理の中でこれを使えば、いつも1ページ目しか処理されず、ループも終わらなくなりますね。

あと、その部分を削ったとしても今のままでは各ページの1行目だけに文字が挿入され、2行目以降が処理されなくなるように思えます。

文字を挿入する部分は、以下のように考えてみてください。
それぞれの処理の記述の仕方がわからなければ、再質問してください。

Do
  Selection.EndKey Unit:=wdLine, Extend:=wdExtend
  Selection.MoveEndWhile Cset:=myExcludes, Count:=wdBackward

  'ループの中でmyText1とmyText2の内容を変更できるように工夫が必要
  With Selection
    .InsertBefore myText1
    .InsertAfter myText2
  End With

  'もし10行目まで処理を終えていればループを抜ける
  If (10行目まで終わっている)
    (ループを抜ける)
  'まだ10行目になってなければカーソルを次の行に移動する
  Else
    (カーソルを次の行に移動)
  End If

Loop


ちなみに、

> Dim doc As Word.Document
> Set doc = Application.ActiveDocument

> Dim myDoc As Document
> Dim myRange As Range
> Set myDoc = ActiveDocument
> With Selection
>  Set myRange = myDoc.Range(.End - Len(myText2), .End)
> End With
> Set myRange = Nothing
> Set myDoc = Nothing

これらは完全に不要な記述ですね。実質的に何も処理していないので。
複数の処理について参考サイトからコピーしてきたのだと思われますが、あなたがやろうとしていることには必要ありませんよ。


> myExcludes

一見すると、変数の定義がされていないようです。
バグの元になるので、
Dim last_page As Long
などと並べて
Dim myExcludes As String
と記述しておいた方がいいですよ。


> Const myText1 As String = "<item id=""" '前の文字列"
> Const myText2 As String = """>" '後の文字列

間違いではないのですが、普通、変数や定数の宣言はコードの最初にしてしまいます。
Dim last_page As Long
などと並べて記述しておいた方がいいですよ。

> myExcludes = Chr(9) & Chr(10) & Chr(11) & Chr(12) & Chr(13)

ループ処理の中に記述すると、何度も同じ処理をすることになるので(今回の場合大した問題ではないですが)、ループに入る前に記述しましょう。

【833】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/6(火) 11:14 -

引用なし
パスワード
    数百ページあり必要に迫られていましたので、大変助かりました。基本的なことが理解できないままの質問に親切ご丁寧にお答えくださり、どうもありがとうございました。まだテストの段階ではありますが、教えていただいた通りに変更をして各ページ各行の前後の文字列の挿入はなんとかできました。

 もう一つ教えていただきたいことがあります。各ページの最後には参照する項目が追加されました。参照するものがない場合は何も記述されていませんが、参照する項目がある場合は、1件だったら1行、3件だったら3行記述されています。各ページの最終行の1行下に文字列を挿入したいのですが、ページの最終行というのはどのように判断するのでしょうか。

【835】Re:各ページ各行それぞれ違う文字列の挿入
回答  亀マスター  - 18/2/6(火) 19:41 -

引用なし
パスワード
   カーソル位置がページ最終行かどうかについては、それを直接判定する方法はないようです(私ではわからない&探しても見つけられなかった)

ですので、私ならどうするかですが、

1.現在のカーソル位置が何行目の何文字目かを記録
2.カーソルを次の行へ移動(最終ページの場合は動かない)
3.移動前と移動後の行番号を比較して、移動後の方が大きければ(同じページ内の次の行に移動している)最終行でない、同じか小さければ最終行と判定
4.元の位置にカーソルを戻す

という感じです。

何行目、何文字目というのは、
Selection.Information(wdFirstCharacterLineNumber)
Selection.Information(wdFirstCharacterColumnNumber)
で取得できます。

具体的なコードですが、こんなものでどうでしょう。

Dim tempLine As Long
Dim tempColumn As Long

tempLine = Selection.Information(wdFirstCharacterLineNumber)
tempColumn = Selection.Information(wdFirstCharacterColumnNumber)

Selection.Move wdLine, 1

Select Case Selection.Information(wdFirstCharacterLineNumber)
  Case Is < tempLine
    Selection.Move wdLine, -1
    Selection.Move wdCharacter, tempColumn - 1
    ※最終行だった場合の処理※
  Case tempLine
    Selection.HomeKey
    Selection.Move wdCharacter, tempColumn - 1
    ※最終行だった場合の処理※
  Case Else
    Selection.Move wdLine, -1
    Selection.Move wdCharacter, tempColumn - 1
    ※最終行でなかった場合の処理※
End Select

【836】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/7(水) 14:03 -

引用なし
パスワード
   ページの最終行を直接判定する方法はないのですね。
具体的に考え方やコードを教えてくださいまして、ありがとうございます。

 これは、データの空白行に改行記号がついていなくてもできますか?
データの空白行に改行記号がついていないので、ページの最終行にカーソルを置いて次の行へ移動すると次ページの1行目になります。(2番の「次の行へ移動」させた後にMsgBoxで行を表示させてみたら、やはり1でした。)試しに1ページ目の最終行にカーソルを置いてこのコードを実行させると、1ページ目の次ページの1行目に挿入されました。

 それから、最終行でなかった場合の処理というのは
1行下の列に移動して、また1番から繰り返すということでしょうか。(ページ毎のループに入れてよいのでしょうか?)

【837】Re:各ページ各行それぞれ違う文字列の挿入
発言  亀マスター  - 18/2/7(水) 21:38 -

引用なし
パスワード
   >データの空白行に改行記号がついていないので、ページの最終行にカーソルを置いて次の行へ移動すると次ページの1行目になります。(2番の「次の行へ移動」させた後にMsgBoxで行を表示させてみたら、やはり1でした。)

各ページは1〜10行目になんらかの文字列があり、続いて参照する項目があればそれが入る。その後、改行記号の連打ではなく空白(つまり改ページが入っている)ということでいいでしょうか。

> それから、最終行でなかった場合の処理というのは
>1行下の列に移動して、また1番から繰り返すということでしょうか。(ページ毎のループに入れてよいのでしょうか?)

私が示したコードは、今現在カーソルのある位置が最終行かどうかを判定するだけのものですので、現在の最終行の下に何か1行を加えるという目的であれば、少し手順を変えた方がいいかもですね。(基本的な考え方は同じです)

1.カーソルを次の行に移動
2.現在のカーソルが1行目かどうかを判定
3.1行目なら先ほどの行が最終行だったということなので、前の行に戻る
  1行目でなければ1行目になるまで1.〜2.を繰り返す
4.現在の行(最終行)の末尾にカーソルを移動
5.改行
6.挿入したい文章を加える

という感じですか。


>試しに1ページ目の最終行にカーソルを置いてこのコードを実行させると、1ページ目の次ページの1行目に挿入されました。

このコードというのがどういうものかわかりませんので、現在のコードの全体を示してもらえると助かります。

【838】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/9(金) 12:47 -

引用なし
パスワード
   >各ページは1〜10行目になんらかの文字列があり、続いて参照する項目があればそれが入る。その後、改行記号の連打ではなく空白(つまり改ページが入っている)ということでいいでしょうか。

はい。その通りです。
私はマクロの記録をちょっと手直しをしたことがあるくらいで、簡単なコードを理解するのも難しいレベルです。数百ページあり、必要に迫られてしまいまして、質問も拙いものばかりで大変お手数をおかけして申し訳ありません。

>1.カーソルを次の行に移動
>2.現在のカーソルが1行目かどうかを判定
>3.1行目なら先ほどの行が最終行だったということなので、前の行に戻る
>  1行目でなければ1行目になるまで1.〜2.を繰り返す
>4.現在の行(最終行)の末尾にカーソルを移動
>5.改行
>6.挿入したい文章を加える

 この3番目がどこにどのように繰り返しの記述を入れたらよいのか、どうしてもわかりません。よろしくお願いいたします。

Dim tempLine As Long
Dim tempColumn As Long

tempLine = Selection.Information(wdFirstCharacterLineNumber)
tempColumn = Selection.Information(wdFirstCharacterColumnNumber)

Selection.Move wdLine, 1     

Select Case Selection.Information(wdFirstCharacterLineNumber)
  Case 1 '1行目の時
    Selection.MoveUp Unit:=wdLine, Count:=1
    Selection.EndKey Unit:=wdLine
    Selection.TypeParagraph
    Selection.TypeText Text:="</item>"
  
  Case tempLine '最終ページの最終行の時
    Selection.EndKey Unit:=wdLine
    Selection.TypeParagraph
    Selection.TypeText Text:="</item>"
  
  Case Else
    
        ????  
    
End Select

【839】Re:各ページ各行それぞれ違う文字列の挿入
回答  亀マスター  - 18/2/10(土) 0:08 -

引用なし
パスワード
   >質問も拙いものばかりで大変お手数をおかけして申し訳ありません。
いえいえ、十分できていると思いますよ。
かくいう私も、偉そうなことを書いておきながらWord VBAはあまり得意ではないので、自分自身が勉強しながら回答しているという感じですので(^^ゞ

> この3番目がどこにどのように繰り返しの記述を入れたらよいのか、どうしてもわかりません。よろしくお願いいたします。

Do
  Selection.Move wdLine, 1
  Select Case Selection.Information(wdFirstCharacterLineNumber)
    Case 1 '1行目の時
      Selection.MoveUp Unit:=wdLine, Count:=1
      Selection.EndKey Unit:=wdLine
      Selection.TypeParagraph
      Selection.TypeText Text:="</item>"
    Case tempLine '最終ページの最終行の時
      Selection.EndKey Unit:=wdLine
      Selection.TypeParagraph
      Selection.TypeText Text:="</item>"
      Exit Sub '←ここを追加(ここでSubを抜ける。Doループの後に何かまだ処理をしたいならExit Do)
  End Select
Loop
※Selectionが最終行でなかった場合は何もせずに次のループに入るので、この場合はCase Else は不要。(中身のないCase Elseを書いても害はありませんが)

こんな感じでどうでしょう。

既に1〜10行目の処理を全てのページに対して済ませた後で最終行に参照項目を入れるなら、1ページ目の1行目にカーソルを戻し、そこからこのコードを実行すればいいでしょう。カーソル位置が最終行でなければそのまま次のループへ入ってSelection.Move wdLine, 1が繰り返され、最終行に行き着けば指定の文字列を追加した上で次のループに入り、最終ページの最終行になればそこでプログラムを終了します。

1〜10行目の処理→最終行に参照項目の設定→次のページの1〜10行目の処理・・・ということであれば、全てのページに1〜10行目の処理をするループの中で、10行目の処理を終えた後に上記のループを加えます(ループの中にループができる形)

自分では動作確認をしていませんので、不具合があるようでしたらまたおっしゃってください。

【842】Re:各ページ各行それぞれ違う文字列の挿入
発言  マナ  - 18/2/10(土) 15:00 -

引用なし
パスワード
   ▼あかよん さん:

お邪魔します。
わたしも勉強中で間違っているかもしれませんが

>各ページの最終行の1行下に文字列を挿入したいのですが、ページの最終行というのはどのように判断するのでしょうか。

必ず改ページがあるなら、置換が使えませんか。


Option Explicit

Sub test()
  Dim r As Range
  Const s As String = "</item>"
  
  Set r = ActiveDocument.Range
  
  With r.Find
    .Text = "^m"
    .Replacement.Text = "^p" & s & "^m"
    .Execute Replace:=wdReplaceAll
  End With
  
  r.InsertAfter vbCr & s

End Sub

【844】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/13(火) 12:48 -

引用なし
パスワード
   わかりやすく考え方を説明していただき、どうもありがとうございました。10行目までの挿入後のデータなので、以下の教えていただいたコード通りに実行してみましたところ、最初ページの最終行の最後の文字の後ろ、改行記号の前のところにカーソルがあり、止まったまま動かなくなり強制終了させないといけなくなります。
最終ページの最後の行の処理のところで、1行目を除いてみても、3行目だけの挿入するだけにしても、同じように最後の文字で止まって動かなくなります。
どうしたらよいでしょうか。


Dim tempLine As Long
Dim tempColumn As Long

tempLine = Selection.Infomation(wdFirstCharacterLineNumber)
tempColumn = Selection.Infomation(wdFirstColumnNumber)

Do
  Selection.Move wdLine, 1
   Select Case Selection.Information(wdFirstCharacterLineNumber)
    Case 1 '1行目の時
      Selection.MoveUp Unit:=wdLine, Count:=1
      Selection.EndKey Unit:=wdLine
      Selection.TypeParagraph
      Selection.TypeText Text:="</item>"
            Selection.Go To What:=wdGoToNext, Count:=1 

     Case tempLine '最終ページの最終行の時
      Selection.EndKey Unit:=wdLine
      Selection.TypeParagraph
      Selection.TypeText Text:="</item>"
      Exit Sub
  End Select
Loop

【845】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/13(火) 14:12 -

引用なし
パスワード
   マナ さんもご親切にありがとうございます。
改ページを文字挿入&改ページにすればよいとは思ったものの、改ページを検索する方法がわかりませんでした。このまま実行してみましたところ、検索に引っかかっていないみたいで、最終ページの最終行のみ挿入されます。置換では難しいということでしょうか?

【846】Re:各ページ各行それぞれ違う文字列の挿入
発言  マナ  - 18/2/13(火) 19:54 -

引用なし
パスワード
   ▼あかよん さん:

確かに置換でできるならわざわざマクロ使うことなかったです。

で、改ページですが

特殊文字の一覧にある
「任意指定のページ区切り」
が相当します。
直接、「^m」と入力してもよいです。

こちらを参考にしてください。
ht tp://www4.synapse.ne.jp/yone/word2013/word2013_kensaku_tokusyu.html

【847】Re:各ページ各行それぞれ違う文字列の挿入
発言  あかよん  - 18/2/14(水) 10:22 -

引用なし
パスワード
   ご親切に参考サイトを教えていただき、ありがとうございました。
>特殊文字の一覧にある
>「任意指定のページ区切り」
>が相当します。
>直接、「^m」と入力してもよいです。
>
^pは検索されるのですが、^mは直接入力して検索しても一致なしになります。
特殊文字の検索で改ページが検索できないので、教えていただいたコードを実行しても最後のページしか最終行に挿入されないのではないかと思います。置換でできたら楽なのですが。

【848】Re:各ページ各行それぞれ違う文字列の挿入
質問  あかよん  - 18/2/14(水) 10:31 -

引用なし
パスワード
   何日か職場のサーバーがダウンしていて、スマホで投稿していますので、肝心なところを書き間違えました。最初のページではなく、最後のページの最終行の最後の文字のところで、カーソルがチカチカとして、強制終了しないといけなくなります。よろしくお願いします。

【849】Re:各ページ各行それぞれ違う文字列の挿入
お礼  あかよん  - 18/2/14(水) 11:05 -

引用なし
パスワード
   比較する現在行が一番最初に取得した時のままになってしまっているんじゃないか?とループの中に☆の部分を入れて実行してみたら、できました。長々とご面倒をおかけして、申し訳ありませんでした。助けていただき、ありがとうございました。これから本番データで不安ですが、わかりやすく説明していただき、考え方は理解できましたので頑張ります。
>
>
>Dim tempLine As Long
>Dim tempColumn As Long
>
>tempLine = Selection.Infomation(wdFirstCharacterLineNumber)
>tempColumn = Selection.Infomation(wdFirstColumnNumber)
>
>Do

tempLine = Selection.Infomation(wdFirstCharacterLineNumber)  ←☆
tempColumn = Selection.Infomation(wdFirstColumnNumber)   ←☆


>  Selection.Move wdLine, 1
>   Select Case Selection.Information(wdFirstCharacterLineNumber)
>    Case 1 '1行目の時
>      Selection.MoveUp Unit:=wdLine, Count:=1
>      Selection.EndKey Unit:=wdLine
>      Selection.TypeParagraph
>      Selection.TypeText Text:="</item>"
>            Selection.Go To What:=wdGoToNext, Count:=1 
>
>      Case tempLine '最終ページの最終行の時
>      Selection.EndKey Unit:=wdLine
>      Selection.TypeParagraph
>      Selection.TypeText Text:="</item>"
>      Exit Sub
>  End Select
>Loop

【850】Re:各ページ各行それぞれ違う文字列の挿入
発言  マナ  - 18/2/14(水) 19:51 -

引用なし
パスワード
   ▼あかよん さん:

本当に、「改ページ」がありますか?
「セクション区切り」ということはありませんか。

【851】Re:各ページ各行それぞれ違う文字列の挿入
お礼  あかよん  - 18/2/15(木) 14:03 -

引用なし
パスワード
   ▼マナ さん:

1ページごとのデータと言われたので、ページと思いこんでいましたが、教えていただいた通りセクション区切りで検索したら検索できました。セクション区切りについてもよく知らずお恥ずかしいです。教えていただいたコードのmをbにしたら、できました。簡単にできるようになりました。どうもありがとうございました。

15 / 306 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
206458
(SS)C-BOARD v3.8 is Free