セルの削除 – ExcelVBAの散策とruby

2016/03/21

参考サイト:  Excel VBA 入門講座 セルの削除


《目次》


1. 概要

 セルを削除するには 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番目の正方形の場合に該当します。

目次に戻る


2. マクロを登録するスクリプト

 「概要」で述べてきた事柄を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

目次に戻る


3. win32oleのスクリプト(定義済み定数の読み込み方法を含む)

 前述のマクロと同じ処理を行う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 のように行っています。

目次に戻る


4. exlapのスクリプト

 同じ処理を行う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のようにセル範囲を指定しなくてもいいというのが特徴です。書き込みのセル範囲は、データである配列の大きさから判断されます。


前のページ:行全体・列全体の指定

次のページ:セルのクリア

「ExcelVBAの散策とruby」トップページ