2016/04/02
参考サイト:
あるセル範囲を別の箇所に複写したいことがあります。その方法を取り上げます。
「複写する」という場合、元のセル範囲をそのまま残すケース、元のセル範囲を消してしまうケースの二通りが考えられます。
「残す」のがコピー&貼り付け、「消してしまう」のが切り取り&貼り付けです。
VBAのメソッドでは、コピー&貼り付けをCopyで行い、切り取り&貼り付けをCutで行います。使い方は同じで、複写先の開始番地を指定します。
Range("A1:B2").Copy Destination:=Range("A5")
とすれば、A1:B2の2×2の4個のセルをA5以下に貼り付けます。A5:B6のセル範囲に貼り付けられることになります。
ここで注意していただきたいのは、複写先のA5:B6に何か書き込まれてあった場合です。それらは失われます。つまり、上書きされてしまいます。
上書きでなく挿入したいのなら、Copyを行う前に A5:B6に対してInsertをあらかじめ実行しておく必要があります。
なお、Destination:= という記述は省略してかまいません。
Range("A1:B2").Copy Range("A5")
と書いても正しく実行されます。
次に切り取り&貼り付けですが、
Range("A1:B2").Cut Destination:=Range("A5")
とすれば、A1:B2の4個のセルがA5以下に複写されます。
このとき、A1:B2のセルは、4個とも空白セルになります。この点がコピー&貼り付けと異なる点です。
空白セルになるというのは、セルがクリア(Clear)されることを意味します。削除(Delete)されるのとは違います。したがって、切り取られるセル範囲の周辺において、下の行が繰り上がったり、右側の列が左にシフトしたりはしません。
Copy, Cut の両法とも、セル範囲を別のワークシートに複写することができます。たとえば下のような記述が可能です。
Worksheets(1).Range("A1:B2").Copy Destination:=Worksheets(2).Range("A1")
上のようにすれば、第1ワークシートのA1:B2の4個が第2ワークシートのA1:B2に複写されます。
「概要」で述べてきた事柄をVBAマクロとして登録するためのスクリプトを掲げます。
これまでと同様に、マクロには Control + j
というショートカットキーを割り当てます。
第1ワークシートのA1:B2の2×2=4個にデータを書き込み、それをコピー&貼り付けしたあと、切り取り&貼り付けを行います。第2ワークシートへのコピー&貼り付けも行います。
1# encoding: Windows-31J 2require "./exlap" 3 4macro_str = <<'EOS' 5Sub Macro1() 6 Worksheets(1).Activate 7 Call WriteData() 8 Range("A1:B2").Copy Range("A5") 9 Range("B5").Cut range("B8") 10 Range("A6").Cut range("A9") 11 Worksheets(1).Range("A1:B2").Copy Worksheets(2).Range("A1") 12End Sub 13 14Sub WriteData() 15 ActiveSheet.UsedRange.Clear 16 Range("A1:B1").Value = Array("ice", "water") 17 Range("A2:B2").Value = Array("rain", "snow") 18End Sub 19EOS 20 21macro_name = "Macro1" 22File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 23Exlap.new("Book1.xls") do |wb| 24 wb.macro_add(macro_str) 25 wb.Application.MacroOptions("Macro"=>macro_name, "ShortcutKey"=>"j") 26 wb.save 27end
前述のマクロと同じ処理を行うwin32oleのスクリプトは下のようになります。
1# encoding: Windows-31J 2require "win32ole" 3 4def fullpath(filename) 5 fso = WIN32OLE.new("Scripting.FileSystemObject") 6 return fso.GetAbsolutePathName(filename) 7end 8 9File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 10app = WIN32OLE.new("Excel.Application") 11wb = app.Workbooks.Add() 12ws = wb.Worksheets(1) 13ws.Activate 14ws.UsedRange.Clear 15ws.Range("A1:B2").Value = [%w(ice water), %w(rain snow)] 16ws.Range("A1:B2").Copy ws.Range("A5") 17ws.Range("B5").Cut ws.range("B8") 18ws.Range("A6").Cut ws.range("A9") 19wb.Worksheets(1).Range("A1:B2").Copy wb.Worksheets(2).Range("A1") 20wb.SaveAs(fullpath("Book1"), -4143) 21app.Quit
ほとんどはVBAマクロと共通です。特別に工夫している点はありません。
同じ処理を行うexlapのスクリプトを掲げます。
中核部分は win32のスクリプトと同じです。
1# encoding: Windows-31J 2require "./exlap" 3 4File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 5Exlap.new("Book1.xls") do |wb| 6 ws = wb.ss(1) 7 ws.Activate 8 ws.UsedRange.Clear 9 ws.Range("A1:B2").Value = [%w(ice water), %w(rain snow)] 10 ws.Range("A1:B2").Copy ws.Range("A5") 11 ws.Range("B5").Cut ws.range("B8") 12 ws.Range("A6").Cut ws.range("A9") 13 wb.ss(1).Range("A1:B2").Copy wb.ss(2).Range("A1") 14 wb.save 15end
Copy, Cut のメソッドで、複写先(Destination)を指定しないと、セル範囲がクリップボードにコピーされます。下のように書いた場合です。
Range("A1:B2").Copy
Range("A1:B2").Cut
クリップボードにコピーされたデータを目的の箇所に貼り付ける時は Paste を用います。
その場合、Range("A5").Paste
のようには書けないので注意してください。次のように2行で書きます。
Range("A5").Select
ActiveSheet.Paste
クリップボード経由の複写だと、マクロ記述の行数が増えてしまうので素直に複写先(Destination)を指定する方がいいと思いますが、ワードなどの別のアプリケーションに貼り付けたい時はクリップボード経由ということになるでしょうか。