あのブックのあのシートに、たしかデータを入れたはず、 顧客名や住所はすでに作成してある住所録から読み込んで入力したい、など、 すでに入力したデータを再利用したい場面は結構ありますよね。
そのために、ブックを開いて、データを表示させて、セルをコピーして、こっちのブックに戻ってセルに貼り付けて‥なんてやってられない。
ボタン一発でできないものか?
そんな悩みに答えるマクロを考えてみましょう。ボタン一発はムリですが、極力手入力をしないように、マウスクリックだけで、ならできます。
マクロプログラムの手順は以下のようにしました。
1.対象のワークブックを開く →[操作]: すでに開いているブックまたは開くブックを選択
2.[操作]:ブック内のシートを選択
3.[操作]:データを選択してマウスの右ボタンをクリック
4.選択範囲をコピー
5.元のブックのカレントセルに貼付け
6.ワークブックを閉じる
操作はマウスクリックだけ。
ポイントは、別のワークブックのイベントを取得して、データをコピーすることです。
ここではマクロが設定されているワークブックから、データコピー元のワークブックでのマウスの右クリックを検出して、選択範囲のコピー・貼付けを実行しています。
詳しくはソースコードをご覧ください。
*****標準モジュール*****
Option Explicit
Public wbkTrgt As Variant
Public whtTrgt As Variant
Public actWbk As Variant
Public actWht As Variant
Public actCell As Variant
Public Sub getData()
'*****他のワークブックからデータを読み込む*****
Dim res As Variant
Dim tmp As Variant
Dim idx As Long
Dim wbkPath As Variant
Dim wbk As Workbook
Dim wbkOpened As Variant
Dim wht As Worksheet
Dim whts As Variant
Dim usedcell As Range
wbkTrgt = ""
whtTrgt = ""
'カレントセルの情報を退避
actWbk = ThisWorkbook.Name
actWht = ThisWorkbook.ActiveSheet.Name
ThisWorkbook.Activate
ThisWorkbook.Worksheets(actWht).Select
actCell = ActiveCell.Address
'イベントを無効にする
Application.EnableEvents = False
'1.ワークブックを開く すでに開いているブック/ブックを選択
'すでに開いているワークブックを探す
ReDim wbkOpened(0 To 0)
idx = -1
For Each wbk In Workbooks
If wbk.Name <> ThisWorkbook.Name Then
idx = idx + 1
If idx > UBound(wbkOpened) Then
ReDim Preserve wbkOpened(0 To idx)
End If
wbkOpened(idx) = wbk.Name
End If
Next
If idx > -1 Then
'このブック以外に開いていたら、選択リストを表示する
tmp = ""
For idx = 0 To UBound(wbkOpened)
tmp = tmp & idx + 1 & ": " & wbkOpened(idx) & vbCrLf
Next idx
tmp = tmp & "番号で入力してください‥"
res = InputBox("すでに開いているワークブックから読み込みますか?" & vbCrLf _
& tmp, "ワークブック選択", "")
If res <> "" Then
'選択したワークブックをセット
wbkTrgt = Workbooks(wbkOpened(res - 1)).Name
End If
End If
If wbkTrgt = "" Then
'選択しなかったらファイルを探す
wbkPath = Application.GetOpenFilename( _
FileFilter:="Excelファイル (*.xls), *.xls,(*.xlsx),*.xlsx", _
Title:="開きたいファイルを選択してください", MultiSelect:=False)
If wbkPath <> False And wbkPath <> "" Then
'選択したfileをセット
Workbooks.Open Filename:=wbkPath, ReadOnly:=True
wbkTrgt = ActiveWorkbook.Name
End If
End If
If wbkTrgt <> "" Then
'2.ブック内のシートを選択
ReDim whts(0 To 0)
idx = -1
For Each wht In Workbooks(wbkTrgt).Worksheets
Set usedcell = wht.Cells.SpecialCells(xlCellTypeLastCell)
'シートの中で使用済の範囲の右下のセル
' → 使用後にデータを削除しても、初期化されないことがあるが、
' → シートの中にデータがあるかどうかのいちおうの目安として使用する
If Not (usedcell Is Nothing) Then
idx = idx + 1
If idx > UBound(whts) Then
ReDim Preserve whts(0 To idx)
End If
whts(idx) = wht.Name
End If
Next
Set usedcell = Nothing
If idx > -1 Then
tmp = ""
For idx = 0 To UBound(whts)
tmp = tmp & idx + 1 & ": " & whts(idx) & vbCrLf
Next idx
tmp = tmp & "番号で入力してください‥"
res = InputBox("シートを選択してください‥" & vbCrLf _
& tmp, "シート選択", "")
If res <> "" Then
whtTrgt = whts(res - 1)
Workbooks(wbkTrgt).Worksheets(whtTrgt).Activate
MsgBox "シート上でコピーしたいセルを選択して、" & vbCrLf _
& "マウスの右ボタンでクリックしてください。" & vbCrLf _
& "現在のシートのセルに貼付けできます。", vbOKOnly, "シート選択"
End If
Else
MsgBox "このブックは空のようです‥", vbOKOnly + vbInformation
End If
End If
'イベントを有効にする
Application.EnableEvents = True
End Sub
***** ThisWorkbook *****
Option Explicit
'すべてのブックのイベントを取得するオブジェクトを宣言
' → 宣言すると、myExcel の下記のイベントが使えるようになる
Private WithEvents myExcel As Application
Private Sub myExcel_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
'すべてのブックの、右クリックイベントプロシージャ
'3.データを選択 行全体/列全体/単独セル
'4.コピー
'5.貼付け カレントセル/セル選択
If Sh.Parent.Name = wbkTrgt And Sh.Name = whtTrgt Then
'選択範囲をカレントセルに貼り付ける 値のみ
If MsgBox("選択範囲をカレントセルに貼り付けます。" & vbCrLf _
& "元には戻せません。" & vbCrLf _
& "続けますか?", vbYesNo + vbQuestion, "貼付け確認") = vbYes Then
Selection.Copy
Workbooks(actWbk).Worksheets(actWht).Range(actCell).PasteSpecial _
Paste:=xlPasteValues
Application.CutCopyMode = False
'6.ワークブックを閉じる
If wbkTrgt <> "" Then
If MsgBox("コピーしました。" & vbCrLf _
& vbCrLf _
& "読み込んだワークブック:" & wbkTrgt & vbCrLf _
& "を閉じますか?", vbYesNo + vbQuestion) = vbYes Then
Workbooks(wbkTrgt).Close savechanges:=False
End If
End If
End If
'Excelの右クリックメニュをキャンセル
Cancel = True
End If
End Sub
Private Sub myExcel_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
'選択したシート名とセルアドレスを表示
Application.StatusBar = Sh.Name & " - " & Target.Address
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'ブックを閉じる前にオブジェクトを開放
Set myExcel = Nothing
End Sub
Private Sub Workbook_Open()
'ブックが開いたらオブジェクトを取得
Set myExcel = Application
End Sub
以上。