2016/03/21
参考サイト: Excel VBA 入門講座 セルの削除
セルを削除するには Deleteメソッドを使います。
Range("A2").EntireRow.Delete
とすれば第2行目全体を削除します。
Range("C1").EntireColumn.Delete
とすれば第3列目全体の削除です。
では、A1セル1個だけを削除した時はどうなるでしょうか。これは少々ややこしいです。
3×3の9個のセルを考えます。セル番地でいうと A1:C3 です。各セルには「1番」 「2番」などを書き込んでおきます。電話機のプッシュフォンの数時ボタンと同じ並びです。
1番 | 2番 | 3番 |
4番 | 5番 | 6番 |
7番 | 8番 | 9番 |
今、「1番」を削除したとします。その時の挙動がどうなるかですが、2通り考えられます。
○ 下に位置する「4番」と「7番」が上に繰り上がるパターン
4番 | 2番 | 3番 |
7番 | 5番 | 6番 |
8番 | 9番 |
○ 右側にある「2番」と「3番」が左にずれるパターン
2番 | 3番 | |
4番 | 5番 | 6番 |
7番 | 8番 | 9番 |
Range("A1").Delete
とすると、4番・7番が上に繰り上がります。
Range("A1").Delete xlShiftUp
としても同じように4番・7番が繰り上がります。
Range("A1").Delete xlShiftToLeft
とすれば、2番・3番が左にずれてきます。
Deleteメソッドのパラメータに指定されている xlShiftToLeft(整数値 -4159), xlShiftUp(整数値 -4162)は、あらかじめ整数の値がセットされている定数です。
このどちらかを指定することにより、削除後のずれ方を明確に指示することができます。
しかし、わざわざ長い定数名を書くのは面倒です。そこで、定数を指定しない場合の挙動をもう少し見てみましょう。
定数の指定を省略した時の挙動には次のルールがあります。仮に、各々のセルが正方形であるとイメージしてお読み下さい。
1番目と2番目のルールは、直感に合致するのではないかと思います。
3番目のルールは覚えておくしかないでしょうか。
削除するセルが1個だけのケースは、3番目の正方形の場合に該当します。
「概要」で述べてきた事柄をVBAマクロとして登録するためのスクリプトを掲げます。
これまでと同様に、マクロには Control + j
というショートカットキーを割り当てます。
3×3のデータを書き込んでから、セルの削除を行うというパターンを4通り実行します。
最初は A1:C3、次が A5:C7、それから A9:C11、そして A13:C15の領域に3×3のデータを書き込みます。
WriteData() というマクロは3×3のデータをセルに書き込むものです。パラメータで渡された数値を行番号とみなして、その行以降に3×3のデータを書き込みます。
Macro1というマクロの中で、まずはWriteDataを呼び出すてデータを書き込み、それからセルの削除を行っています。
1# encoding: Windows-31J 2require "./exlap" 3 4macro_str = <<'EOS' 5Sub Macro1() 6 Call WriteData(1) 7 Range("A1").Delete ' 1個だけ削除:上に繰り上がり 8 Call WriteData(5) 9 Range("A5").Delete xlShiftToLeft ' 1個だけ削除:左シフトを指示 10 Call WriteData(9) 11 Range("A9:A10").Delete ' 縦長を削除:左にシフト 12 Call WriteData(13) 13 Range("A13:B13").Delete ' 横長を削除:上に繰り上がり 14End Sub 15 16Sub WriteData(Ri As Integer) 17 Range(Cells(Ri,1), Cells(Ri,3)).Value = Array("1番", "2番", "3番") 18 Range(Cells(Ri+1,1), Cells(Ri+1,3)).Value = Array("4番", "5番", "6番") 19 Range(Cells(Ri+2,1), Cells(Ri+2,3)).Value = Array("7番", "8番", "9番") 20End Sub 21EOS 22 23macro_name = "Macro1" 24File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 25Exlap.new("Book1.xls") do |wb| 26 wb.macro_add(macro_str) 27 wb.Application.MacroOptions("Macro"=>macro_name, "ShortcutKey"=>"j") 28 wb.save 29end
前述のマクロと同じ処理を行うwin32oleのスクリプトを掲げます。
セルを削除するための Deleteメソッドに与えるパラメータ xlShiftToLeft は、予め定義されている定数ですが、これを使えるようにするには一定の手順が必要です。VBAの場合のように、いきなり使い始めることはできません。
空のモジュール XlConstant を設けておいて、WIN32OLE.const_load() を呼び出します。すると、定義済みの定数を使えるようになります。
XlConstant というモジュールの名前は任意です。好きな名前を使ってかまいません。
ともあれスクリプトを記します。
1# encoding: Windows-31J 2require "win32ole" 3 4def fullpath(filename) 5 fso = WIN32OLE.new("Scripting.FileSystemObject") 6 return fso.GetAbsolutePathName(filename) 7end 8 9module XlConstant 10end 11include XlConstant 12 13ary = [%W(1番 2番 3番), %w(4番 5番 6番), %w(7番 8番 9番)] 14File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 15app = WIN32OLE.new("Excel.Application") 16WIN32OLE.const_load(app, XlConstant) 17wb = app.Workbooks.Add() 18ws = wb.Worksheets("Sheet1") 19ws.Range("A1:C3").Value = ary 20ws.Range("A1").Delete # 1個だけ削除:上に繰り上がり 21ws.Range("A5:C7").Value = ary 22ws.Range("A5").Delete(XlShiftToLeft) # 1個だけ削除:左シフトを指示 23ws.Range("A9:C11").Value = ary 24ws.Range("A9:A10").Delete # 縦長を削除:左にシフト 25ws.Range("A13:C15").Value = ary 26ws.Range("A13:B13").Delete # 横長を削除:上に繰り上がり 27wb.SaveAs(fullpath("Book1"), XlWorkbookNormal) 28app.Quit
定義済みの定数を使えるようにする手順だけを抜き出すと下のとおり。
module XlConstant
end
include XlConstant
app = WIN32OLE.new("Excel.Application")
WIN32OLE.const_load(app, XlConstant)
include XlConstant
は必須ではありませんが、これがないと、rubyスクリプト内で定義済み定数を記述するとき、XlConstant::XlShiftToLeft
と書かなければなりません。単に XlShiftToLeft と書いただけではエラーになります。
なお、VBAでは xlShiftToLeft と先頭文字が小文字の ‘x’ ですが、rubyでは大文字の ‘X’ にします。rubyでは、定数が大文字のアルファベットで始まるというルールがあるためです。
3×3のデータは、配列の形で変数aryに代入しています。2次元配列です。
そのセルへの書き込みは、ws.Range("A1:C3").Value = ary
のように行っています。
同じ処理を行うexlapのスクリプトを掲げます。
exlapでは Exlap.new
が実行されると、定義済みの定数を使えるようになります。WIN32OLE.const_load() を呼び出さなくても大丈夫です。
1# encoding: Windows-31J 2require "./exlap" 3 4ary = [%W(1番 2番 3番), %w(4番 5番 6番), %w(7番 8番 9番)] 5File.delete("Book1.xls") if test(?e, "Book1.xls") # 既存のBook1.xlsを削除 6Exlap.new("Book1.xls") do |wb| 7 ws = wb.ss("Sheet1") 8 ws.from_a("A1", ary) 9 ws.Range("A1").Delete # 1個だけ削除:上に繰り上がり 10 ws.from_a("A5", ary) 11 ws.Range("A5").Delete(XlShiftToLeft) # 1個だけ削除:左シフトを指示 12 ws.from_a("A9", ary) 13 ws.Range("A9:A10").Delete # 縦長を削除:左にシフト 14 ws.from_a("A13", ary) 15 ws.Range("A13:B13").Delete # 横長を削除:上に繰り上がり 16 wb.save 17end
3×3のデータは、2次元配列の形で変数aryに代入していますが、それをセルに書き込む時に ws.from_a("A1", ary)
のように from_a() を用いています。
from_aは、exlapで独自に定義されているメソッドです。第1引数は書き込みの開始番地(セルの番地)、第2引数は書き込むデータ(配列)です。
開始番地を指定すればよく、A1:C3のようにセル範囲を指定しなくてもいいというのが特徴です。書き込みのセル範囲は、データである配列の大きさから判断されます。