過去の桐井戸端BBS (桐ver.9)
20287 文字列型から日時型への変換するときに日時データとして不正なデータがあれば未定義となるようにしたい R3 2003/05/10-07:57
どなたか教えてください。
投稿に失敗してしまいました。再掲します。
テーブルに項目(1)生年月日CD【文字列】,(2)生年月日【日時】があります。
このとき(2)には,項目計算式が設定してあります。

#計算(
#代入(&STR,#SSTR([生年月日CD],1,1)),
#条件選択(&STR="1",#代入(&STR,"M"),
&STR="2",#代入(&STR,"T"),
&STR="3",#代入(&STR,"S"),
&STR="4",#代入(&STR,"H"),
1,#代入(&STR,"X")),
#代入(&STR,&STR+#SSTR([生年月日CD],2,2)+"/"
+#SSTR([生年月日CD],4,2)+"/"
+#SSTR([生年月日CD],6,2)),
#日時値(&STR))

ここで,(1)生年月日CDのデータが,"4150201"の時は,
期待通りに(2)生年月日には日時データ"2003/02/01"が
入るのですが,日時データとして不正なデータ,
例えば"4159999"の時には"2003/01/01"となりますし,
"aaaaaaa"の時には"1989/01/01"となります。
関数#日時値の仕様を見てみますと
>変換後の値が、日時型の範囲外になる場合、
>年月日の範囲外の部分が 1 になり、
とあるので前述のような結果になると思うのですが,
日時データとして不正なデータの場合,項目(2)生年月日は,
未定義としたいのです。

長々と書いてしまいましたが,何かいい方法があれば
お教えください。

20291 Re:文字列型から日時型への変換について 宮城 2003/05/10-18:48
記事番号20288へのコメント
R3さん、こんにちは。

原始的手法ですが、条件選択関数で次のように組みます。

1桁目が1から4まで以外であれば不正
2、3桁目が1から64まで以外であれば不正
4、5桁目が1から12まで以外であれば不正
6、7桁目が1から31まで以外であれば不正

不正は未定義とし、このチェックをかいくぐったものだけ日時値を生成させる。

いきなり日時値生成かけると、不正値を含む場合「不正です」と桐におこられてにっちもさっちもいかなくなります。

もちろん、40231なんてのも上記チェックは通りますが、日時値生成でおこられてしまいます。

ところで、ですが、上記条件式だけでもこてこての記述になります。
私の趣味としては、生年月日CDを発生させる側で妙なデータが入り込まないようにさせ、
こちら側では値が入っていれば、さっさと日時値生成するというようにしたいところです。


20293 Re:文字列型から日時型への変換について 今村 誠 2003/05/11-10:57
記事番号20288へのコメント
R3さんこんにちは、検証していませんが以下の式でいかがでしょうか
#計算(#SET(STR,[生年月日CD]),
#SET(実行リターン,#num(#SSTR([生年月日CD],1,1))),
#SET(実行リターン,#cond(&実行リターン>0 .or &実行リターン<5,
#西暦年(#対応文字列("M,T,S,H",&実行リターン)+#SSTR(&STR,2,2)),1,0)),
#cond(&実行リターン<1,"",
#日(#日時値(#STR(&実行リターン)+"/"+#SSTR(&STR,4,2)+"/"+#SSTR(&STR,6,2)))
=#num(#SSTR(&STR,6,2))
.and #月(#日時値(#STR(&実行リターン)+"/"+#SSTR(&STR,4,2)+"/"+#SSTR
(&STR,6,2)))=#num(#SSTR(&STR,4,2)),
#日時値(#STR(&実行リターン)+"/"+#SSTR(&STR,4,2)+"/"+#SSTR
(&STR,6,2)),1,""))
20294 Re:演算子を間違えたので訂正 今村 誠 2003/05/11-11:28
記事番号20293へのコメント
#計算(
#SET(STR,[生年月日CD]),
#SET(実行リターン,#num(#sstr(&STR,1,1))),
#SET(実行リターン,#cond(&実行リターン>0 .and &実行リターン<5,
#西暦年(#対応文字列("M,T,S,H",&実行リターン)+#SSTR(&STR,2,2)),
1,0)),#cond(
&実行リターン<1,"",
#日(#日時値(#STR(&実行リターン)+"/"+#SSTR(&STR,4,2)+"/"+#SSTR(&STR,6,2)))
=#num(#SSTR(&STR,6,2)) .and
#月(#日時値(#STR(&実行リターン)+"/"+#SSTR(&STR,4,2)+"/"+#SSTR(&STR,6,2)))
=#num(#SSTR(&STR,4,2)),
#日時値(#STR(&実行リターン)+"/"+#SSTR(&STR,4,2)+"/"+#SSTR(&STR,6,2)),
1,""))
20296 Re:文字列型から日時型への変換について R3 2003/05/12-05:13
記事番号20288へのコメント
宮城さん,今村さんレス有り難うございます。
お礼,報告が遅れて申し訳ありません。
結果からいえば今村さんの計算式でこちらの意図するとおりの結果が出せました。
要は,変換前後の月,日を比較して合致すればOKということですね。
#IS日時(仮称)みたいな関数があって判定が出来ればいいんですけどね。>K3様
掲示板への質問は初めてでしたが,回答もらえて嬉しかったです。
お二人とも有り難うございました。


20297 Re:長整数型への変更も考慮してみては 今村 誠 2003/05/12-08:43
記事番号20296へのコメント
R3 さんこんにちは、計算式がお役に立てたようで
安心しました。
 今回の投稿の原因となった入力ミスですが、
2通りの考え方ができると思います。
1)入力者が意図的に間違ったデータを入力している
2)入力者が入力の規則を知らない。
1)の例としては、誕生日がその時点でわからないので
でたらめなデータを入力した。
2)の例としてはたとえば文字列項目なので
 s21.12.1や212612等として入力者は
昭和21年12月01日や大正12年6月12日のつもりでも
入力制約をかけることができないと思います。
この項目が生年月日を入力するためだけなのであれば、
この項目長整数にすると小数点も入力できないし、
数値なので1000000未満や9999999以上の場合は
エラーメッセージとして入力規則を表示したり
行制約式をかけることもできるのではないでしょうか。
20322 Re:長整数型への変更も考慮してみては R3 2003/05/13-05:00
記事番号20297へのコメント
今村さん,ご助言ありがとうございます。
実は,今回の件は日付データ入力のための
ものではありませんでした。
オラクルで作られたテーブルのデータを加工し,
印刷する必要があったのですが,そのデータが
文字列型で'4150131'のような形式だったというわけです。
'4150229'みたいな不正なデータがありました。
で,そのままCSV経由で桐のデータに落とし変換しようとして
はてどうしたものかとなった次第です。
オラクルなのに何で日付データが文字列型で定義してあるかはおいといて,
このような一時的な仕事の場合,桐のテーブルでの
データ操作,一覧表印刷は非常に強力で重宝しています。
データ入力を伴うシステムの場合,実はアクセスで組んでたりします。
(MSDE+ACCESS)。今回の件では,IsDate(para) が使えます。
でも,帳票が使いにくいです。(私が桐の帳票を知ってるからかも知れませんが)
桐もイベントが使えるようになったのでこっちの方も勉強しようと考えてますが,
どっちも中途半端になりそうな気が。
また,わからないことがあったらご指導お願いします。
ありがとうございました。

戻る