• ベストアンサー

VBAエクセル、Now()より以前のデータ削除

お世話になります。 range("B")列に日付がありその行にはRange(”C”)以下データがあります。 Range("B3")からRange("B30")までDELETEしたくない日付があり Range("B31")からの日付はNow以前はDeleteしたいのですがどなたか構文を教えてください。 宜しくお願いします

質問者が選んだベストアンサー

  • ベストアンサー
  • kagakusuki
  • ベストアンサー率51% (2610/5101)
回答No.1

 「TODAY()以前」や「Date以前」ではなく >Now以前 と仰っておられるという事は、B列に入力されているデータとは「2016/01/22」などの様な「日付」データではなく、「2016/01/22 20:44:56」などの様な時刻も含んだ「日時」のデータであり、Now関数が返す値が例えば「2016/01/22 20:44:56」である場合には、「2016/01/22 20:44:55」や「2016/01/22 20:44:56」などの様な「2016/01/22 20:44:56」以前の日時が入力されている行は削除し、「2016/01/22 20:44:57」の様な「2016/01/22 20:44:56」以前の日時が入力されている行は残すという事で宜しいのでしょうか?  それでしたら以下の様なVBAとなります。 Sub QNo9115488_VBAエクセルNowより以前のデータ削除() Const DateColumn = "B" '日付が入力されている列 Const FirstRow = 31 '削除の対象となる可能性がある最初の行 Dim LastRow With ActiveSheet LastRow = .Range(DateColumn & Rows.Count).End(xlUp).row If LastRow <= FirstRow Then MsgBox "処理すべきデータがありません。" _ & vbCrLf & "マクロを終了します。" _ , vbExclamation, "データ無し" Exit Sub End If With Application .ScreenUpdating = False .Calculation = xlManual End With .Range(DateColumn & FirstRow - 1 & ":" & DateColumn & LastRow) _ .AutoFilter Field:=1, Criteria1:="<=" & Now, _ Field:=1, Criteria2:="", Operator:=xlOr .Range(DateColumn & FirstRow & ":" & DateColumn & LastRow) _ .SpecialCells(xlCellTypeVisible).EntireRow.Delete .Cells.AutoFilter End With With Application .CutCopyMode = False .Calculation = xlAutomatic .ScreenUpdating = True End With End Sub

nebikitorikai
質問者

お礼

そのものずばりで大満足です、これから組み込んでいきます有難うございました。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.3

#2です。下記は#1のご回答と似てしまいましたが、「エクセルのフィルタ機能で条件該当分をつかみ」(という処理方式で)、Deleteする方式でやってみました。 Sub test04() Dim buf As Date x = Range("A10000").End(xlUp).Row ’MsgBox x Range("A30:c" & x).Select buf = "2016/1/23 9:30:00" ’Now()の替わり テスト用 MsgBox Format(buf, "yyyy/mm/mm/dd hh:mm:ss") '確認用 条件の境目の時刻 Selection.AutoFilter Field:=2, Criteria1:="<=" & buf ’例で30分丁度は削除対象は Selection.Delete End Sub 30行目は見出しとみなされるのか、フィルタサインが出てしまう。しかし31行目以下行を対象として、条件に該当するかを見てくれるようだ。 Selection.Delete をコメント化しておいて、全レコード復帰は Sub test03() ActiveSheet.Cells.AutoFilter End Sub 実行でできる。 べつ必ず、別シートにシートコピーしておいて、そちらでテスト実行してください。 ーー なお http://officetanaka.net/excel/vba/tips/tips151.htm 田中先生の記事を参考に 慎重にやったつもりですが、こちら側では、テストデータを充分には作りにくいので、質問者の方で、十分確認して、その後 Selection.Delete のコメントを外して実行してください。 Selection.Delete をコメント化しておいて実行すると、削除対象行を範囲指定した状態で終わるので、確認できます。 なおDateTime型のデータ型はエクセルVBAにはなく、Dateに時刻部分も混めることができる。#2で述べた日付と時刻を結合した数で表せる、エクセルの特色からくるもの。

nebikitorikai
質問者

お礼

有難うございました、imogasi様の記述も私なりに作成し試して出来上がりました。感謝です。

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.2

(1)エクセルシートのセルの、日付・時刻の値の仕組み 日付が整数(1900年以来の経過日数)で、時刻は0時からのその時刻までの経過時間を、24時間を1とする整数で、両者の和(小数点以下月の普通の数)の数が使われる。 Now関数の返す数も同じ性格の数のはず。 だから2つの日・時刻の日+時刻の前後関係は、2つの小数点付き数の大小関係で判別できる。 すなわちIF関数両者の値を比べて判定したらしまい。 (2)やり方(ロジック)は、2・3考えられると思うが、行ごと繰り返し法が素直で良いだろう。その際 (3)行削除はFor Nextを使う場合は、最下の行から上行に、上がって行く処理をするのが定石。 http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_row_del.html  それには For !00 to 31 Step -1 Next のような構文が使えて、造作もない。 (A)Stepの値にマイナス指定。 (B)Forのあとの範囲を大から To 小に記述 。 ーー (4)Range("B3")からRange("B30")までDELETEしたくない日付があり これも(3)の31がそれを担うので、簡単。 (5)上記で100行と例えている、データのある最稼行を捉えるのは、定石で http://www.niji.or.jp/home/toru/notes/8.html Range("A65536").End(xlUp).Row A65536はエクセル2003時代までのもの。必要なもっと大きい数を指定してみて。 (6)行削除は http://excel-ubara.com/excelvba1/EXCELVBA329.html など参照 ーー これら(1)や(3)などを、VBAのとい自作使用経験が少なくて、知らなかったのではないか。(1)はエクセルそのもののを使う必要知識。 ーー 普通は、個人の利用ではDateは使っても、時刻までは問題にしないはず。 株式の売買などに関した処理の質問か。こういうのは損得に関連するものなので、VBAを使うなら、VBAの勉強をある程度してからのことだと思うのだが。  (行繰り返し法以外の他の方法は、むつかしい点があるので、テストできれば上げてみます。)

nebikitorikai
質問者

お礼

有難うございました。勉強に励みます。

関連するQ&A