• ベストアンサー

エクセル 日付比較のマクロ

以下の処理をエクセルで自動で行おうと思っています。 ___________A列__________________B列 1行目 2008/9-2009/7______終了 2行目 2009/3/12 ____________実施中 3行目 2008/10-2009/8_____終了 4行目 2008/9~2009/7_____終了 5行目 2008/10~2009/8 ___終了 6行目 2009/9/1 ______________実施中 B列が「実施中」でA列が処理日の「翌月以降」の行と B列が「終了」でA列が処理日の「前月以前」の行を 削除するマクロを作成したい。 例:2009/8/10に処理する場合、    A1が 2008/9-2009/7の行は削除対象    A4が 2008/9~2009/7の行は削除対象 A6が2009/9/1の行は削除対象 なお、年月日指定、年月の期間指定(ハイフンと~が混在) の2つの形式がある。 処理日との日付比較をどのように行えば良いでしょうか?

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

  • ベストアンサー
  • hotosys
  • ベストアンサー率67% (97/143)
回答No.3

こんなのではどうでしょうか? まず、B列が終了の場合だけA列が2つの日付(期間)になっている場合です。 まず考え方としては、前月以前と来月以降だけが問題になるので、各処理中の日付はその月の1日として処理します。 例えば2009/7は2009/7/1、2009/3/12は2009/3/1、処理日の2009/8/10は2009/8/1とすると、単純な大小比較で処理できると思います。 また、期間の~は半角マイナスに変換してから処理します。 2009/7などはdatevalue("2009/7")とすると自動的に2009/7/1に変換してくれますが、datevalue("09/7")などは2009/9/7になってしまいます。 datevalue("09/7/1")とすれば2009/07/01になるので、その処理も入れました。 Sub sample() Dim today As Date Dim lastRow As Long Dim r As Long Dim val As String Dim d() As String Dim v As String today = Date '処理日取得 today = DateSerial(Year(today), Month(today), 1) '処理日の月の1日に lastRow = Range("A" & Rows.Count).End(xlUp).Row For r = lastRow To 1 Step -1 val = Range("A" & r).Value val = Replace(val, "~", "-") '~を-" 'val = Replace(val, "-", "-") '必要なら全角マイナスを半角マイナスへ 'val = Replace(val, "ー", "-") '必要なら長音記号を半角マイナスへ d = Split(val, "-") '-で分割 Select Case Range("B" & r).Value Case "実施中" If InStr(InStr(d(0), "/") + 1, d(0), "/") = 0 Then d(0) = d(0) & "/1" '年/月の場合に年/月/1にする処理(たぶんなくてもいい) If DateSerial(Year(DateValue(d(0))), Month(DateValue(d(0))), 1) > today Then 'A列の日付の月の1日の日付が処理日の月の1日の日付より大きければ Rows(r).Delete '削除 End If Case "終了" If InStr(InStr(d(1), "/") + 1, d(1), "/") = 0 Then d(1) = d(1) & "/1" '年/月の場合に年/月/1にする処理(たぶんなくてもいい) If DateSerial(Year(DateValue(d(1))), Month(DateValue(d(1))), 1) < today Then 'A列の2番目の日付の月の1日の日付が処理日の月の1日の日付より大きければ Rows(r).Delete '削除 End If Case Else MsgBox "データ異常" Exit Sub End Select Next End Sub p.s. DateSerialは便利な関数で、DateSerial(2009,12+1,1)とすると自動的に2010/01/01にしてくれます。 DateSerial(2009,1-2,1)は2008/11/01にしてくれます。

dejiichi
質問者

お礼

ありがとうございます! ためしてみます!

その他の回答 (2)

回答No.2

日付の列を開始日と終了日で列を分けておけば入力も後の処理も簡単になるのに、どうしてわざわざ「 2008/9-2009/7」みたいな面倒な入力をさせているのでしょう、不思議です。いまからでも分けておかないと、また他の処理で困ることになるでしょう。 作業列を使えば、フィルタでなんとかなりそうですが、どうしてもマクロでないと駄目なんでしょうか?

dejiichi
質問者

お礼

実際にはもっと複雑な複数シートからなる表です。 以前からそのような日付で運用されていました。 どうしてもマクロでなくてもいいですが、効率化したいので、、

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

A列が内容的に日付的なデータで、B列が終了、実施中などのデータか。 ~は「-」(半角に置き換えてもよいか。触れないのか。 ーーーー ヒントは VBAであれば、プログラム内で Sub test01() x = Cells(1, "A") d1 = DateSerial(Year(x) - 1, Month(x) + 1, 1) d2 = DateSerial(Year(x), Month(x) - 1, 1) s1 = Year(d1) & "/" & Month(d1) s2 = Year(d2) & "/" & Month(d2) s3 = s1 & "-" & s2 MsgBox s1 MsgBox s2 MsgBox s3 End Sub のようにs1.S2を作る。 その際DateSerial(Year(x) - 1, Month(x) + 1, 1)のように日付シリアル値にするとき、月や年に+1やー1しないと、単純にMonth(x)+1すると、年末月などで13月になったりするので上記にした。 ーーーー また2008/9-2009/7のような行は Sub test02() x = Cells(2, "A") y = Split(x, "-") MsgBox y(0) MsgBox y(1) End Sub で2つに分離する。 そしてs1 とy(0),S2とy(1)を各々比較して範囲内月かチェックする。 またはそのままs3とTest02のx(セルの値文字列)と比較してもよいのかな。 ーー 該当した場合 行削除のコードは判っていますよね。マクロの記録をとれば判る。 ーー 以上は~を操作でーに置換出来てそのあとのこと。 置換してはダメの場合、プログラムの変数の中で~をーに置換した文字列を作り、あとの処理を始める。

dejiichi
質問者

お礼

ありがとうございます! ためしてみます!

関連するQ&A

専門家に質問してみよう