https://www.moug.net/faq/viewtopic.php?t=78705
2020年問題
投稿日時: 19/10/15 17:21:10
投稿者: rag
日付の下五桁を使ってロット名を作り昇順で並べていました。
例:2019/10/15なら、91015となります。
このため、2020年以降0で始まるロットになると、昇順が崩れてしまいます。
幸いなことに、ロットは文字列型にしており字数制限もしていませんでしたので、ロット番号を生成するときにAを頭につけるなどして昇順を維持することは出来ます。
しかし、実際の製品のロットにはAがついているわけではなく、もちろん見栄えもよろしくありません。
また、データベースのフィールドは増やしたくありません。
このような状況で、改善策はあるでしょうか。
回答
投稿日時: 19/10/15 19:25:54
投稿者: よろずや
SELECT Q.ロット FROM (
SELECT IIF(LEFT(ロット,1)>RIGHT(FORMAT(DATE,"YYYY"),1),"1","2") AS D, ロット
FROM テーブル) AS Q
ORDER BY Q.D, Q.ロット;
ってな感じかな。
投稿日時: 19/10/18 16:32:05
投稿者: rag
回答ありがとうございました。
申し訳ありません。
当方の情報不足、あるいは実力不足で、説明がいきたら無かったため、すこし違った結果がえられるソースを作っていただいたようです。
ご解答を吟味して勉強しなおして、また質問させていただくかもしれません。
ともあれ、ありがとうございました。
すべてにおいて謎が多い
1.日付の五桁2019/10/21なら91021で名前を付けることがあり得ない
いったいなぜ日付の下五桁という発想が出てくるのか。
日付の下五桁を使うくらいならシリアル値を使えばよいわけで、なぜこんな発想に至るのかがまるでわからない。
2.このため、2020年以降0で始まるロットになると、昇順が崩れてしまいます。
これも全く理解しがたい。9の次が0になることを知らない。知っていてこういうのを組むのは知らないのと同じなので、知らないんだよ。
自分がまずとんでもない無知だということに気づかないといけない。
さらに、もしあとから製品を日付順に追加しているなら、ID列さえあれば解決する。しかし「フィールドを追加したくない」と言っているので、その解決方法を使いたくないのだろう。
3.ロットは文字列型にしており字数制限もしていませんでしたので、ロット番号を生成するときにAを頭につけるなどして昇順を維持することは出来ます。
幸いも何も文字列型以外とれない。 2020/1/1 は101になってしまう。固定長の文字列型ならわかるのだが。。。
謎は多いが結論としては
その五桁を今のうちにシリアル値にする。2010年が存在しない前提なら次のような関数が使える。
Function FiveDegitdate(str5 As String)
Dim reg As New RegExp
Dim DT As Date
reg.Global = True
reg.IgnoreCase = False
reg.Multiline = False
reg.Pattern = "[0-4]"
If reg.test(Left(str5, 1)) = True Then str5 = CStr("202" & str5) Else str5 = CStr("201" & str5)
DT = CDate(Format(str5, "0000\/00\/00"))
FiveDegitdate = CLng(DateSerial(Year(DT), Month(DT), Day(DT)))
End Function
これをどう使うかとか、金をいくらもらってもこれ以上教える気にならない。仮にこのAccessのデータベースが本当に存在するなら、高い確率でまだ地雷が埋まっているとしか思えないからだ。
そもそもロットが下五桁、それで製品名になるのは、単品か小品数で1日に作る量が限られており、在庫があまりない、という場面だ。おそらく2018年から2020年のスパン程度だろう。という前提で作成された関数である。
また、VBScript regexpに参照設定が必要。