もしあなたの会社で、10万行を超えるようなデータをExcelで扱っているならば、OracleとかSQLServerとかMySQLといったちゃんとしたリレーショナルベースを導入してもらうように提案すべきでしょう。まあ、少なくともAccessで処理するように業務のやり方を変えたほうが良いと私は思います。しかし、あなたにリレーショナルデータベースの知見がなかった場合、スキルの獲得に結構な時間がかかるでしょう。仮にスキルのある人材を獲得できたとしても、業務の高度化は常に属人化というリスクが伴います。ある人がいなくなった途端に会社が止まってしまうのです。余裕のある会社はともかく、金を生まないバックオフィスにどれだけの投資が期待できるのでしょう。管理者の立場からすると、仕事の継続性を担保するためには仕事を単純化しておきたいのです。かくかくしかじかの理由で、大量のデータ加工においても、Excel業務が現在も幅を利かしております。そして、それがゆえに「くそ仕事」が一向に消えていきません。
エクセルVBA高速化技術、オートフィルタの利用
経験則として、データが2、3万行を超えてくるあたりから、For文を用いた一行ごとの連続処理には限界のようなものを感じます。まあ、時間がかかるのです。画面更新の制御(Application.ScreenUpdating = False)や式の値(Value)化といった工夫を施してもなかなか厳しいものがあります。そこで、一つの回答となるのがオートフィルタを利用したマクロということになります。ここでは時間がかかる特定の行の削除処理について紹介いたします。
<例1 セルに値のないデータだけを残すVBA>
ここでは、例として「コード」列で、セルに値のないデータのみを残す方法として、高速化技術のオートフィルタを用いたマクロを示します。オートフィルタで、「コード」列に値のある行を選択(「コード」列に値のない行以外を選択)、この行(=可視化された行)を削除することで、「コード」列に値のない行のみを残すという手順を取っています。「コード」列はシートのA列にあると仮定します。
Sub 特定の列で値のないデータだけ抽出() 'オートフィルタの設定 Range("A1").CurrentRegion.AutoFilter Field:=1, Criteria1:="<>" Dim myRng As Range Dim lstRow As Long 'オートフィルタのRangeオブジェクト(フィルタの範囲)を取得 Set myRng = ActiveSheet.AutoFilter.Range 'オートフィルタのRangeオブジェクトをからフィルタ範囲の最終行を取得 lstRow = myRng.Rows.Count 'エラー(Criteria1で指定したものがない場合も処理を継続)処理 On Error Resume Next '列名の入った1行目を除き選択された抽出部分を削除 Rows("2:" & lstRow).SpecialCells(xlCellTypeVisible).Delete On Error GoTo 0 'オートフィルタの解除 Range("A1").AutoFilter 'オブジェクトの初期化 Set myRng = Nothing End Sub
<例2 セルに値のあるデータのみを残すVBA>
今度は逆に、「コード」列に何らかの値がある行のみを残すVBAのコードを示します。「コード」列に値のない行をオートフィルタで選択、この行(=可視化された行)を削除することで、「コード」列に値のある行のみを残すという手順を取っています。「コード」列はシートのA列にあると仮定します。
Sub 特定の列で値のあるデータだけ抽出() 'オートフィルタの設定 Range("A1").CurrentRegion.AutoFilter Field:=1, Criteria1:="=" Dim myRng As Range Dim lstRow As Long 'オートフィルタのRangeオブジェクト(フィルタの範囲)を取得 Set myRng = ActiveSheet.AutoFilter.Range 'オートフィルタのRangeオブジェクトをからフィルタ範囲の最終行を取得 lstRow = myRng.Rows.Count 'エラー(Criteria1で指定したものがない場合も処理を継続)処理 On Error Resume Next '列名の入った1行目を除き選択された抽出部分を削除 Rows("2:" & lstRow).SpecialCells(xlCellTypeVisible).Delete On Error GoTo 0 'オートフィルタの解除 Range("A1").AutoFilter 'オブジェクトの初期化 Set myRng = Nothing End Sub
Criteria1の引数の使用の仕方
違いは、Criteria1の引数だけです。例1では、「”<>”」”が使われ、例2では「”=”」が使用されています。「”<>”」は、空白行以外、「”=”」の意味になっています。通常の使用例も含めて、まとめておきましょう。
引数 | 選択されるもの |
"文字列" | 「文字列」と一致するセルの行を選択 |
"=" | 空白のセルの行を選択 |
"<>" | 空白以外のセルの行を選択 |
”9*” | 「9」で始まる文字列セルの行を選択 |