以下の2つのマクロを実行してみてください。 どういう問題が生じているか、そして、 Format 関数を使うことによってその問題をどのように回避しているかが分かるかと思います。
Sub format_sample_hitoketa()
Dim dt As Date
Dim moji As String
dt = #4/28/2024#
moji = Format(dt, "yyyymm")
Range("A1").Value = moji
Range("B1").Value = Year(dt) & Month(dt)
End Sub
Sub format_sample_futaketa()
Dim dt As Date
Dim moji As String
dt = #11/28/2024#
moji = Format(dt, "yyyymm")
Range("A2").Value = moji
Range("B2").Value = Year(dt) & Month(dt)
End Sub
Sub month_evaluator()
Dim i As Long
Dim hiduke As Date
Dim first_day As Date '今月初日
Dim last_day As Date '今月最終日
Dim next_month_first_day As Date '翌月初日
Dim next_month_last_day As Date '翌月最終日
'今月初日を生成する(DateSerialは講座では扱ってませんが (^^; )
first_day = DateSerial(Year(Date), Month(Date), 1)
'翌月初日を求める
next_month_first_day = DateAdd("m", 1, first_day)
'翌月初日の1日前が今月最終日
last_day = DateAdd("d", -1, next_month_first_day)
'翌々月初日の1日前が翌月最終日(変数増やしたくないので関数入れ子にして1行で書きました (^^; )
next_month_last_day = DateAdd("d", -1, DateAdd("m", 1, next_month_first_day))
'テスト出力。きちんと所望の日付を生成できていることを確認
Debug.Print first_day '2024/04/01
Debug.Print last_day '2024/04/30
Debug.Print next_month_first_day '2024/05/01
Debug.Print next_month_last_day '2024/05/31
'サンプルデータをセルに書き込む
Range("E4").Value = #2/28/2024# '期待値: 前月以前
Range("E5").Value = #4/26/2024# '期待値: 当月
Range("E6").Value = #5/28/2024# '期待値: 翌月
Range("E7").Value = #7/28/2024# '期待値: 翌月+1
'個別データの処理例
For i = 4 To 7
hiduke = Range("E" & i).Value
Select Case hiduke
Case Is < first_day
'今月1日より前なら過去
Range("F" & i).Value = "前月以前"
Case first_day To last_day
'今月1日以降、今月最終日まで
Range("F" & i).Value = "当月"
Case next_month_first_day To next_month_last_day
'翌月1日以降、翌月最終日まで
Range("F" & i).Value = "翌月"
Case Else
'上記のいずれも満たさない場合
Range("F" & i).Value = "翌月+1"
End Select
Range("G" & i).Value = hiduke
Next
End Sub
Sub hidukecheck()
Dim gyo
For gyo = 2 To 6
Dim hiduke As Date
Dim nowd As Date
Dim hidukemoji As String
Dim nowdmoji As String
hiduke = Range("H" & gyo).Value
nowd = Now
hidukemoji = Format(hiduke, "yyyymm")
nowdmoji = Format(nowd, "yyyymm")
Select Case hidukemoji
Case Is = nowdmoji
Range("I" & gyo).Value = "当月"
Range("J" & gyo).Value = hidukemoji
Case Is < nowdmoji
Range("I" & gyo).Value = "前月以前"
Range("J" & gyo).Value = "前月以前"
Case Is = nowdmoji + 1
Range("I" & gyo).Value = "翌月"
Range("J" & gyo).Value = hidukemoji
Case Is > nowdmoji + 1
Range("I" & gyo).Value = "翌々月以降"
Range("J" & gyo).Value = hidukemoji
End Select
Next
End Sub
Sub input_sample_data()
' サンプルデータをセルに書き込む部分は本編に無関係なので別に準備しました
' また、より丁寧に検証できるようにサンプルデータを準備しました
'前々月
Range("D4").Value = "前々月末"
Range("E4").Value = #2/28/2024#
'前月
Range("D5").Value = "前月初日"
Range("E5").Value = #3/1/2024#
Range("D6").Value = "前月中日"
Range("E6").Value = #3/15/2024#
Range("D7").Value = "前月末日"
Range("E7").Value = #3/31/2024#
'当月
Range("D8").Value = "当月初日"
Range("E8").Value = #4/1/2024#
Range("D9").Value = "当月中日"
Range("E9").Value = #4/15/2024#
Range("D10").Value = "当月末日"
Range("E10").Value = #4/30/2024#
'翌月
Range("D11").Value = "翌月初日"
Range("E11").Value = #5/1/2024#
Range("D12").Value = "翌月中日"
Range("E12").Value = #5/15/2024#
Range("D13").Value = "翌月末日"
Range("E13").Value = #5/31/2024#
'翌々月
Range("D14").Value = "翌々月初日"
Range("E14").Value = #6/1/2024#
Range("D15").Value = "翌々月中日"
Range("E15").Value = #6/15/2024#
Range("D16").Value = "翌々月末日"
Range("E16").Value = #6/30/2024#
'さらに先の月
Range("D17").Value = "さらに先の月初日"
Range("E17").Value = #7/1/2024#
Range("D18").Value = "さらに先の月中日"
Range("E18").Value = #7/15/2024#
End Sub
Sub month_evaluator()
Dim i As Long
Dim hiduke As Date
Dim result As String '追加
' 韻を踏んだ変数名にしたいので以下のように変更した(変数名の長さも統一したい)
Dim month_1 As Date '当月初日
Dim month_2 As Date '翌月初日
Dim month_3 As Date '翌々月初日
month_1 = DateSerial(Year(Date), Month(Date), 1)
month_2 = DateAdd("m", 1, month_1)
month_3 = DateAdd("m", 2, month_1)
Debug.Print month_1, month_2, month_3 'こんな書き方もあります (^^
' 以下のように「Select Case 内では変数に値を入れるにとどめ、最終的にその値を書き込む」
' としたほうが見た目スッキリします
For i = 4 To 18
hiduke = Range("E" & i).Value
Select Case hiduke
Case Is < month_1
result = "前月以前"
Case Is < month_2
result = "当月"
Case Is < month_3
result = "翌月"
Case Else
result = "翌月+1"
End Select
Range("F" & i).Value = result
Range("G" & i).Value = hiduke
Next
End Sub
きういさんの投稿
(投稿ID: 5537) 添付ファイルのダウンロード権限がありません
素晴らしい講座を提供していただきありがとうございます!質問があります。
こちらで勉強したコードを早速仕事で使おうと思い、
Select Caseでによって列に表示される内容を変えるものを書きましたが、日付の認識?がおかしいものがあります。
GW前に職場でひっそりと撮ったスクリーンショットで恐縮です。(Tabで見やすくする癖を定着できておらず反省しています)
書いたコードの内容は、
指定のセルにある日付の年月によって、その隣の2列に条件に合った該当の内容を表示するものです。
指定のセルの日付が「前月以前」「当月」「翌月」「翌々月以降」であるかを表示する列と、
指定のセルの年月が「前月以前」とであれば「前月以前」と表示し、当月以降であればそのまま指定のセルの日付を表示する列です。
そこで本題の質問ですが、
「今年の10月、11月、12月」に限って、過去の日付と認識されてしまいます。
過去の日付、今年の9月まで、来年以降については問題なく動作します(月や年、確認するセルの位置を変えて確認)。
月が2桁であることが問題そうかなと思ったのですが、そこからどうしたらいいかわからず行き詰まっています。
お知恵を拝借できたら幸いです。どうかよろしくお願いします。
追伸
以前からネットで拾ってきたコードをなんとなく修正していくつもコードを書いていたのですが、自分で更から書くことはできませんでした。今回こちらで基礎の基礎から勉強させていただき、今までなんとなくやっていた点がつながってきています。毎回学びがあり、気付きがあり、何より楽しいです。本当にありがとうございます!
きういさんのコメント
(コメントID: 8340) 添付ファイルのダウンロード権限がありません
問題の部分で説明が不足しておりました。
「今年の10月、11月、12月」に限って、過去の日付と認識され、「前月以前」と両方の列に表示されてしまう、という意味です。
本来は、「翌々月以降」「セルの日付そのまま」が表示されるはずのものです。
小川 慶一さんのコメント
(コメントID: 8341)
おー、お役に立てているようでうれしく思います (^^*
日付の文字列化は Format 関数を使うのが良いかと思います。
以下の2つのマクロを実行してみてください。
どういう問題が生じているか、そして、 Format 関数を使うことによってその問題をどのように回避しているかが分かるかと思います。
小川 慶一さんのコメント
(コメントID: 8342)
小川 慶一さんのコメント
(コメントID: 8343)
以下でどうでしょうか。(月最終日を求めるのが面倒くさいのは仕方ないです)
きういさんのコメント
(コメントID: 8344)
早速ありがとうございます!!できました!!!何日も格闘していたので冗談抜きでうれしくて泣きそうです。本当にありがとうございます!!
日付は文字列に変換して桁数を合わせないといけないのですね。データ型の理解がよくできていなかったのだなと実感しました。小川先生にアドバイスいただいたように、以下のように日付を文字列にする段階を入れたことで解決しました!どこかの誰かの参考になるかもわかりませんので残しておきます。
GW明けに早速職場のデータを修正するのにわくわくしています。まだまだ講座の序盤ですが、もっと先に進んでいろいろできるようになるのが楽しみです!ありがとうございました!!
きういさんのコメント
(コメントID: 8345)
きういさんのコメント
(コメントID: 8346)
文字列にして解決して喜んでいたのですが、月初と最終日を求める方法はスマートですね!
自分の知識では到底思いつかない書き方なので、こういった方法があるのだなと感動しました。ご記載いただいたものをしっかりと自分で理解して書けるように勉強させていただきます!
小川 慶一さんのコメント
(コメントID: 8347)
その後、月末日を算出する必要もなく、もっとシンプルなコードを書けることに気づきました。
ということで、以下のコードを示します。これなら、マネしてみたいと思えるのではないでしょうか。
「"202404" とか "202310" とかいう文字列を作ってこれらの大小を比較する」ということでもいちおう動きますが...。
「文字列を作り、それを数値とみなして演算する(大小を比較する)」というのは、あまりスマートではないです。
その方法であっても解決できればまずは十分ですが、「日付のまま比較する」という選択肢も選べるように練習に取り組んでいただければとも思います (^^*
きういさんのコメント
(コメントID: 8349)
またもやありがとうございます!!目指しているものは同じなのに、そういった考え方をするのかととても勉強になりました。自分が最初に考えたものを実現させるというので留まってしまっておりましたが、そもそもこの道筋でいいのかと考えることの大切さを実感しました。もちろん最初にお返事をいただき、なんとかそれで動作するようにした過程で学んだこと(なぜ特定の年月についてだけうまく動作しなかったのか)も計り知れません。また、自分は今あるデータをどうするかといった「エクセルの関数でやるようなことをマクロ化したらどうなのか」的発想だったのですが、最初から変数に基準となる日付を入れるという方法を拝見して視界が開けたような気分です。また、Select Caseでは結果を表示するとこまではいれないといったところなど、細かいところまで学びが多くとてもうれしいです。感謝の念に堪えません・・・
これからも練習し、発想の引き出しを増やせるようにしていきたいです!
ありがとうございました!
小川 慶一さんのコメント
(コメントID: 8350)
お役に立てたようでよかったです (^^
> そもそもこの道筋でいいのかと
そこは、抽象的な理解が進むことと、具体的な実装と多く関わることで、次第にいろいろ見えてくるようになるかと思います。
>Select Caseでは結果を表示するとこまではいれないといったところなど、細かいところまで学びが多くとてもうれしいです。
講座でもいちおう扱ってはいます。
ですが、最初は見逃してしまいますよね。(復習大事です。初見のときには見落としていたこと、ピンとこなかったことなど、バシバシ入ってくるようになります)
ひきつづき、エクセルマクロでの成果をお楽しみください (^^*