3月4日(月)Excelのマクロ 空白行削除
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
ただいまコメントを受けつけておりません。
3月4日(月)Excelのマクロ 空白行削除
こんな風なデータがあり、これが約1週間に1度届く。
届くたびに、各枠のタイトルと空白行を削除して、フィルタを使い条件で絞り込んだモノを使用している。がっ、毎回同じ作業なのでこれを自動処理化(マクロ)できないものかなぁ~と。
というわけで、初めてのマクロ化に挑戦
まずは、空白行と各テーブルの1行目にあるタイトルを削除することに挑む。
LstRow という最後尾の行の値を入れる変数をつくり、End(xlDown).Row というのを使い末尾の行の値を取得することにした。名前の列(C)には必ず入力があることが基本となっているので、C列の2行目から下で末尾を求めることにした。
'データ行末尾
Dim LstRow As Long
LstRow = ActiveSheet.Range("c2").End(xlDown).Row
'メッセージ:末尾の値
MsgBox "最終行:" & LstRow
が、メッセージで出力された値は、”8” だった・・・
なので、今度は少し加え再度取得してみることに。
'データ行末尾
Dim LstRow As Long
LstRow = ActiveSheet.Range("c2").End(xlDown).Row
'取得した値の2行下が空白でなければ、再度末尾取得
Do Until Range("c" & LstRow + 2) = ""
LstRow = ActiveSheet.Range("c" & LstRow + 2).End(xlDown).Row
Loop
'メッセージ:末尾の値
MsgBox "最終行:" & LstRow
取得した値は、”32” になった。
バッチリ
追加したのは、Do Until ~ Loop っていうループ処理。
C列には、テーブルの間に空白行が1行入るような形なので、最初に値を取得した2行下のCに値が入っていれば、再度末尾取得をやりなおし、値を取得した行の2行下のCが空っぽのところまで繰り返せ!というもの。
次にやることは、その取得した行範囲のタイトルと空白行を削除させること。
但し、2行目のタイトルは残しておく。
上のような条件から、3行目からさっき取得した行末尾までの範囲内で、列Cが空っぽの行とその次の行を削除するような式を考えれば良いのかな。
※ここで重要なのが、処理は先頭行から末尾行に向かってではなく、末尾行から先頭行に向かって処理するようにした方がスムーズに処理できるらしいとのこと。
なるほどねぇー。
そんなわけで、出来たのは下記のようなコード。
'空白行削除
For i = LstRow To 2 Step -1
If Range("C" & i) = "" Then
Rows(i + 1).Delete
Rows(i).Delete
End If
Next
最後に、会社>仕様歴 の優先順位で昇順ソートをかける。
出来あがったコードは下記。
'ソート 条件:会社・仕様歴順番で昇順
'行末尾
LstRow = ActiveSheet.Range("c2").End(xlDown).Row
'列末尾
lstCol = ActiveSheet.Range("b2").End(xlToRight).Column
※式が長くなる場合は、「_ 」(アンダースコア)を使って式を複数行に分ける事が可能
以上、これで出来あがりなので、実際に動作実行
最初のデータがこんな風に変換された。
当初の予定通り動作するモノができた。
枠線がちょっと気にはなるけど、今回はスルー。
というわけで、初めてのマクロ化に挑戦
まずは、空白行と各テーブルの1行目にあるタイトルを削除することに挑む。
LstRow という最後尾の行の値を入れる変数をつくり、End(xlDown).Row というのを使い末尾の行の値を取得することにした。名前の列(C)には必ず入力があることが基本となっているので、C列の2行目から下で末尾を求めることにした。
'データ行末尾
Dim LstRow As Long
LstRow = ActiveSheet.Range("c2").End(xlDown).Row
'メッセージ:末尾の値
MsgBox "最終行:" & LstRow
が、メッセージで出力された値は、”8” だった・・・
むむっ
9行目(C9)が空白なので、その前の行である8が取得されたようだ・・・。なので、今度は少し加え再度取得してみることに。
'データ行末尾
Dim LstRow As Long
LstRow = ActiveSheet.Range("c2").End(xlDown).Row
'取得した値の2行下が空白でなければ、再度末尾取得
Do Until Range("c" & LstRow + 2) = ""
LstRow = ActiveSheet.Range("c" & LstRow + 2).End(xlDown).Row
Loop
'メッセージ:末尾の値
MsgBox "最終行:" & LstRow
取得した値は、”32” になった。
追加したのは、Do Until ~ Loop っていうループ処理。
C列には、テーブルの間に空白行が1行入るような形なので、最初に値を取得した2行下のCに値が入っていれば、再度末尾取得をやりなおし、値を取得した行の2行下のCが空っぽのところまで繰り返せ!というもの。
次にやることは、その取得した行範囲のタイトルと空白行を削除させること。
但し、2行目のタイトルは残しておく。
上のような条件から、3行目からさっき取得した行末尾までの範囲内で、列Cが空っぽの行とその次の行を削除するような式を考えれば良いのかな。
※ここで重要なのが、処理は先頭行から末尾行に向かってではなく、末尾行から先頭行に向かって処理するようにした方がスムーズに処理できるらしいとのこと。
上から処理していくと削除した行より以下の行が、こんな風に上にくりあがってくるので、処理によってはおかしなことになっちゃうようだ
'空白行削除
For i = LstRow To 2 Step -1
If Range("C" & i) = "" Then
Rows(i + 1).Delete
Rows(i).Delete
End If
Next
最後に、会社>仕様歴 の優先順位で昇順ソートをかける。
出来あがったコードは下記。
'ソート 条件:会社・仕様歴順番で昇順
'行末尾
LstRow = ActiveSheet.Range("c2").End(xlDown).Row
'列末尾
lstCol = ActiveSheet.Range("b2").End(xlToRight).Column
'ソート範囲:B3(タイトル行を除く)から行列末のセル
Range(Cells(3, 2), Cells(LstRow, lstCol)).Sort _
Key1:=Columns("F"), Order1:=xlAscending, _
Key2:=Columns("D"), Order2:=xlAscending
※式が長くなる場合は、「_ 」(アンダースコア)を使って式を複数行に分ける事が可能
以上、これで出来あがりなので、実際に動作実行
最初のデータがこんな風に変換された。
枠線がちょっと気にはなるけど、今回はスルー。
PR