• ベストアンサー

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/17068)
回答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/17068)
回答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

  • Excelマクロ、特定行の削除

    A列に日付か文字のどちらかが入力してある表があります。  A列(日付文字) B列(時刻) C列以下(その他データ ) 日付は全て同じ日付(11月11日なら全部これ)で、文字も全て同じ文字です。 日付またはB列が時刻(さまざまな数値)の行を削除して、A列が文字の行だけ残したいのです。 Range("2:2").Select Selection.Delete Shift:=xlUp これを表範囲で繰り返すのはわかります。 "2:2"の所に変数を用いると思いますが、変数に日付の行を指定したりするコードが分かりません。 A列が文字の行を検索し、それ以外の行を削除でもよいのですよね。 よろしくお願いします。

  • VBAエクセル、項目検索からデータ抽出

    お世話になります。早速ですがsheets("データ元").Range("A2")にNo.、Range("B2")に日付、Range("C2")に曜日、Range("D2")に項目、Range("E2")に詳細、Range("F2")に金額があり A3~F3以下LastRowまでデータが入っています。 Range("D3")以下LastLowの中から1会社名を検索するとその会社名すべてのデータが新規ブックSheet1に書き出され、そのシートのRange("G3")に合計額を出す構文をどなたかご教示ください宜しくお願いします。エクセル2003と2013を各パソコンで使用しています。

  • 【VBA】 通し番号の入力について

    こんばんは。 こちらの識者の方々にはいつもお世話になっています。 VBAの件で質問があります。 B列の最終行までA列に001から文字列で連番を振りたい場合、どのような構文になりますでしょうか。 Range("A1:A" & Range("B" & Cells.Rows.Count).End(xlUp).Row).Value = Format(row, "000") は通らなかったのですが、なにかいい構文はありますでしょうか。 データは必ず1000行以下ですので、番号は3桁で大丈夫です。 よろしくお願いいたしますm(_ _)m

  • エクセル VBA

    最近マクロの勉強を始めたばかりの初心者で、どうしても Loop 処理の構文が理解出来ません。 S列 T列 U列  0  0  0 10  5  8  0  4  0   ・  ・   ・   ・  ・   ・ 上記のようにS列(3行目)からU列(最終行変動)に0~20000位の値が入っていて、データの並び替えでS列(昇順)で並べ替えをした後、S列の値が0の場合のみS~T列をDelete Shift:=xlUP したいです。 もしくはS列が0の場合のみT列まで選択 Range("S3:U...") とし、S列が0の行をまとめて Delete Shift:=xlUp したいです。 並べ替えまでマクロすぐ出来たのですが、Loop For Next など構文が理解できません。 どなたかお知恵をお貸し下さい。

  • Excel VBA データのクリアについて

    Excelファイルで、C列に、2行目から下に全て、条件付き書式を入れています。 そしてA2:E20000セルまでデータが入っており、マクロでこのデータの2行目以下をクリアしたい(1行目はタイトル行)と思います。このとき endR=cells(rows.count,1).end(xlup).row Range(cells(2,1),cells(endR,1)).entireRow.clearContents このコードでは、データのクリア自体は出来るのですが、Excelがデータの終端を2万行目と認識したままになってしまい、ファイルサイズが重くなってしまいます。といってclearContentsの部分をDeleteにしてしまうと、C列に入れた条件付き書式が全て消えてしまいます。データの終端を2行目と認識させ、かつ条件付き書式も削除されないようにする確実な方法はないでしょうか?なおデータは2万行ぴったりとは限りませんし、何度も読み込んだりクリアしたりします。

  • Excel VBA データ削除の高速化

     今晩は,質問させていただきます.どうぞよろしくお願いいたします.  Win7 + Excel2007でございます。  B~D列の、1~300,000行程にデータが入っており、グラフ化する際に重いです。 そこでこれを周期的に間引く為に (例えば、10行消して1行残す→また10行消して・・・の繰り返し)、 .Range(.Cells(行1, 2), .Cells(行2, 4)).Delete Shift:=xlUp を繰り返すコードを作成いたしました。 が、非常に動作が遅く、数千行実行するのにも暫く時間がかかるほどでございます。。。  原因を解明すべく検索いたしておりますと、VBAの中でもデータ削除が原因で マクロ動作が遅くなるケースは珍しく無いようでございます。 他のコーディング方法で何か、上記より早い方法というのは あるのでございますでしょうか?  もしお詳しい方がいらっしゃいましたら,是非アドバイスいただけないでしょうか。 どうぞよろしくお願いいたします。

  • エクセルVBAで重複データの削除

    A列、B列、C列・・・とデータが入っていて、B~D列の5行目から10行目が関連の有るデータのかたまりとします。 C~D列の全てのデータが重複している場合に、最初のほうのデータ(行番号が小さいほう)を残すものとして、重複データを削除したいのです。 削除するときは、 B~Dの範囲で削除する。A列等は削除しない。 削除したらデータは上に詰める。 データはソートしない。 ということをやりたいのですが、簡単に出来ますでしょうか? 良く覚えていないのですが、ネット上で色々探してみても、必ずソートしている気がしたので、ソートしない方法が知りたいのですが。

  • エクセルVBA実行エラーの対処方法

    以前教えていただいた構文ですが、NOWより過ぎてない日付がFirstRow 31より有り、過ぎた日付がない場合に実行するとエラーが出ます。これを回避するのを教えてください。 宜しくお願いします。 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

  • エクセルVBAの書き方で教えてください。

    エクセルで、 「A列にデータを入力した日付をB列に自動で入れる」 (A列のデータを消したときは、B列のデータも消える)ということをするのに、 他の質問を参考にして、 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 1 Then   '対象の列が1列目(A列)なら If Target.Value <> "" Then   '入力された値がブランクでなければ Target.Offset(0, 1).Value = Date   '0行ずれた(同じ行)の1列右隣に日付を入れる Else       'そうでなければ(Deleteキーで消されたら) Target.Offset(0, 1).Value = ""   '同行右隣をブランクすなわち""として消す End If      '入力された値の処理終り End If      '1列目(A列)の処理終り、従ってB列以降はチェックしない End Sub と、入力して、うまく動きました。 ところが、「A列に入力」→「B列に自動で日付」だけでなく、 「D列に入力」→「E列に自動で日付」 「H列に入力」→「I列に自動で日付」と、1つのエクセルシートの中で いくつかの同じ条件のことを繰り返そうと思うとうまくいきません。 この場合、どのようにVBAを記入したら良いのか、教えてください。 よろしくお願いします。

  • エクセルVBA シートにある日付1週間分転記

    お世話になります、Sheet1,Range(”A3")からFirstRow、Range(”A")にナンバーSheet1Range(”B")に日付Range(”C")に曜日Range(”D3")に会社名Range(”E")に行先名があります。 Sheet1Range(”B")にある日付1週間分をsheet2~sheet8に転記。sheet2には今日の日付をsheet3には翌日の日付を~sheet8までそれぞれ1週間分転記し、これを1日ごとクリアーかデリートしてから更新する構文をどなたかご教示お願いします。