VBAの勉強を始めてみた

色々試しています。

Word 開いている全文書の同じ行にクリップボードのデータを貼り付ける

今回は Word で開いているすべての文書の同じ行(厳密にいうと段落※)にクリップボードのデータを貼り付けさせてみたいと思います。

 

イメージとしてはこんな感じ。

f:id:kouten0430:20181014143415j:plain

 

マクロ実行時にアクティブな文書(最前面にある文書)のカーソル位置を読み取り、すべての文書の同じ行にデータを貼り付けします。

貼り付けされる順番は、アクティブな文書から・・・・・・ではなく、どの文書がアクティブであろうとも文書を開いた順番と逆(最後に開いた文書 → 最初に開いた文書)になるので注意して下さい。

 

コードはこちら。

Sub 現在開いている全文書の同じ行にクリップボードのデータを貼り付ける()
    '現在アクティブになっている文書のカーソル位置と同じ行(厳密には段落)にデータが貼り付けされます
    'データが貼り付けされる順番は文書を開いた順番と逆(最後に開いた文書 → 最初に開いた文書)になります
    Dim myLib As Object
    Set myLib = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")  '参照設定なしでDataObjectのインスタンスを生成する
    Dim 全文字列 As String
    Dim 分割文字列 As Variant
    Dim i As Integer
    Dim 段落番号 As Integer
    Dim 文書 As Document
    
    myLib.GetFromClipboard
    
    On Error Resume Next
    
    全文字列 = myLib.GetText
    
    On Error GoTo 0
    
    If 全文字列 <> "" Then
        分割文字列 = Split(全文字列, vbCrLf)  '全文字列を改行で分割し配列に格納する
        i = 0
    
        段落番号 = ActiveDocument.Range(0, Selection.End + 1).Paragraphs.Count  'カーソル位置の段落番号を取得する
    
        For Each 文書 In Documents  '処理の順番は文書を開いた順番と逆になることに注意!
            If i <= UBound(分割文字列) Then
                文書.Paragraphs(段落番号).Range.InsertBefore 分割文字列(i)
                i = i + 1
            Else
                Exit For
            End If

        Next
        
    Else
        MsgBox "クリップボードにデータがありません!"

    End If
    
End Sub

 

※コードの大まかな流れ

  • まず、クリップボードの全文字列を変数に格納します。
  • 次に、Split関数を使って全文字列を改行(CrLf)で分割し配列に格納します。
  • アクティブな文書のカーソル位置の段落番号(つまり、カーソルがあるのは先頭から数えて何個目の段落か)を Paragraphs.Count でカウントして変数に格納します。※段落の先頭にカーソルがある場合、一つ前の段落までしかカウントされないため、先頭からカーソル位置+1文字の範囲内にある段落をカウントさせています。
  • For Each ~Next で、現在開いているすべての文書に対してループ処理を行います。
  • ループ内の処理:文書の該当の段落に配列の文字列を挿入します(次のループで、配列は次の要素に進みます)。ループの途中で配列の要素が尽きたら、ループを抜けて終了します。

 

※段落とは?

  • 改行の次の文字から次の改行までを指します。次の改行までが長くなると右端で折り返されて複数行に渡る場合もあります。

 

※コードの使用方法

  • SubからEnd Subまでをコピーし、標準モジュール等に貼り付けて使用して下さい。なお、マクロで実行した処理は「元に戻す」ことができません。実行前に一旦保存し、やり直しのできる状態にしておいて下さい。Wordで標準モジュールにコードを貼り付けてマクロを使用する方法はこちら