過去の桐井戸端BBS (桐ver.9)
24693 別の項目のデータよりも大きい値を入力できないよう制約をかけたい katsuyoshi 2004/02/10-11:58
お世話になります。
日付による入力制約をかけたいと思いますが方法を教えて下さい。
OS Win XP  V9-2004
A.TBLに項目名[終了年月日]が入力されています。
B.TBLに項目名[年月日]を入力しようとしたときに
A.TBLの終了年月日よりも大きい日付を入力出来ないようにしたいのです。
お願いします。
24694 行制約になります 佐田 守弘 2004/02/10-12:15
記事番号24693へのコメント
katsuyoshiさん
[年月日]も[終了年月日]も日時型であるとの前提で話を進めます。
文字列型でも不可能ではありませんが書式が合っていないとうまく行きません。

●行制約で
他の項目との関係で制約を設定するには項目制約では行えないので、行制約式を使います。
この場合であれば
[年月日]の行制約式に
 [年月日]=<[終了年月日]
と設定して下さい。

●行制約の場合には
行制約の場合、項目制約と違って、1行の入力が終ってから制約式のチェックが行われます(1行のデータが揃わないと評価できないため)。
従って、入力時には制約条件を満たさない値でも入力が許されてしまいます。
制約条件に合わない[年月日]の値があると、その段階で訂正が求められる形になります。

●どうしてもその場で他の項目との関係での制約を行うなら
質問の主旨、つまり[年月日]を入力する段階で、[終了年月日]よりも前の日付であるかをチェックさせるとしたら、
フォームとイベントを使うしかないでしょう。
制約そのものに相当する判定は、入力後イベントで行います。
但し、[終了年月日]が入力されていない場合も想定しておかないと破たんします。
これをどこで行うかが課題でしょうね。このあたりを考えながらフォームの設計をして行かないと難しいかも知れません。

佐田守弘(KS-00119)
24697 Re:行制約になります katsuyoshi 2004/02/10-13:16
記事番号24694へのコメント
佐田さんありがとうございました。
イベント処理で行いたいと思いますのでもう少しご指導下さい。
A.wfm
 手続き定義開始t報告日::入力後(参照 文字列 &編集文字列,長整数 &モード,参照 長整数 &入力継続
  変数宣言 固有,日時{&終了月日}
表 "終了日.TBL" *B.wfmです。
代入 &終了月日=[終了月日}
if(>&終了月日<[報告日]) *ここでエラー(未定義の項目があります)

確認 "終了日以降の処理は契約集計処理で行って下さい。" &確認
    if(&確認=1)
&処理中止
    end
end
思いつきで記述していますので全く動きません。
報告日が終了月日より大きかったら処理を中止させたいのです。
お願いします。

24700 Re:行制約になります 佐田 守弘 2004/02/10-14:04
記事番号24697へのコメント
katsuyoshiさん

●入力後イベントの場合
入力後イベントでは、変数「&編集文字列」にキー入力した文字が、文字列として代入されています。
この値と[終了月日]を比較して、条件に合わなければ、&入力継続に1を代入してやれば、
日付の入力のやり直しが求められます。

●中止とは
 >報告日が終了月日より大きかったら処理を中止させたいのです。
との事ですが、終了月日よりも前の日付の入力を行うまで、前に進まなくなります。
中止の意味ですが、どの様に中止したいのでしょうか。
それによって処理の方法も様々です。

●疑問点
さて、[終了月日]は、年が入っていない様ですが、日時型とは違うのですか?
月日だけだと、日付の前後の判定がうまく行かないと思いますが。
例えば終了月日が1月10日で、報告日に12月20日を入力したら、エラーとして拒絶が行われる様になります。
それではまずいのでしょう。

また、終了日が記載されている表は別の表ですね。という事は、何かの項目でこの表を参照する事になるのですが、
その部分が解らないと入力後イベントの中に記述するコマンドが作れません。

佐田守弘(KS-00119)
24706 Re:行制約になります アックン(=^・^=) 2004/02/10-15:53
記事番号24697へのコメント
katsuyoshiさん、こんにちは。
> if(>&終了月日<[報告日]) *ここでエラー(未定義の項目があります)
先頭の > はいらないです。この書式エラーで、おかしなエラーメッセージが出ているんでしょう。

それと、入力後イベントのヘルプで例をじっくり読むことをおすすめします。
(わからない点はなんでもここで聞きましょう。誰かが答えますから。)
入力後イベントは、&編集文字列・&モード・&入力継続を使って記述する必要があります。
もし[報告日](項目)のデータ型が日時のときでも、&編集文字列(変数)のデータ型は文字列です。
式で使うときに注意してください。

それでは、あとは佐田さんにおまかせします。(^^;何しに出てきたんだか....
24712 Re:行制約になります katsuyoshi 2004/02/10-18:55
記事番号24706へのコメント
佐田さん、アックン(=^・^=)さんありがとうございました。
とりあえず、下記のように書いたら、意図する動きになりました。

手続き定義開始 t報告日::入力後(参照 文字列 &編集文字列,長整数 &モード,参照 長整数 &入力継続)
変数宣言 固有,日時{&終了月日,&入力月日}
 表 "終了日.TBL"
 代入 &終了月日=[終了月日]
 代入 &入力月日=#日時値( &編集文字列 )
 if(&終了月日<&入力月日)
  確認 "終了日以降の処理は契約集計処理で行って下さい。" &確認
  if(&確認=1)
   メソッド呼び出し @フォーム.更新モード設定( -1 )  *←ここでesc押下と同じ処理。
  else
   代入 &入力継続=1
  end
 end
手続き定義終了

ところで、確認でOKの時にescキー押下と同じメッセージを出して編集を無効にしたいのですが、
イベントでの記述を教えてください。

24736 メッセージボックスで 佐田 守弘 2004/02/11-02:47
記事番号24712へのコメント
katsuyoshiさん
>   メソッド呼び出し @フォーム.更新モード設定( -1 )
>ところで、確認でOKの時にescキー押下と同じメッセージを
>出して編集を無効にしたいのですが、

メッセージを出すなら、メッセージボックスコマンドを使ってみてはどうでしょうか。
入れる場所は、上記のメソッド呼び出しコマンドの前でよいと思います。
単に確認だけで、はい/いいえの選択もないので、押されたキーを変数に取る必要もなく、単に
メッセージボックス <タイトル>,<表示文字列>,アイコン =!,ボタン指定=1で良いのではないでしょうか。

佐田守弘(KS-00119)

24747 メッセージの後で編集を無効にしたい katsuyoshi 2004/02/11-12:25
記事番号24736へのコメント
佐田さんありがとうございました。
メッセージを出すことはできましたがOKボタンを押下した後
ESCボタンを押したときのように「レコードの編集を無効にします。
よろしいですか?」のメッセージを表示しレコード編集を無効にしたいのです。
説明がまずくてすみません。よろしくお願いします。
24760 Re:メッセージの後で編集を無効にしたい 悲しげ 2004/02/11-22:43
記事番号24747へのコメント
イベントの記述はともかくとして、結局はどのようにしたいのでしょう?

「終了日以降の処理は契約集計処理で行って下さい。」の確認で

1)Esc=キャンセルした時は、入力継続(報告日を再入力)とするのは判ります。

2)ではEnter=OKした時は「レコードの編集を無効にします。よろしいですか?」
のメッセージを出すとして、この時
2-1)Esc=キャンセルした時は、無効にしないで 終了月日<報告月日 のまま強行するのでしょうか?
それとも上記1)と同じく再入力させるのでしょうか?
2-2)Enter=OKした時は、値を破棄して表示モードにすることで、入力自体を断念すると云うことでしょうか?

この辺り、何だかとてもまわりくどいような気がすると云うか、2)のメッセージ挿入で、
処理をわざわざ複雑にしてしまうような印象を受けました。
私の誤読の可能性も高いですが、私ならこう書くかなと云う例を以下に挙げてみます。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
手続き定義開始 t報告日::入力後(・・・・・
 変数読み込み "終了月日.var"
 if(&終了月日<#日時値(&編集文字列))
  メッセージボックス "確 認"\
   ,"終了月日<報告月日となっています。\n"\
   +"終了日以降の処理は契約集計処理で行う必要があります。"\
   ,アイコン=!,ボタン指定=3,制御文字展開=する,&確認
   /*ボタン指定=3は「中止 再試行 無視」です*/
  if(&確認=3) /*中止牡丹*/
   確認 "しつこいですが、本当に中止しますよ?",&確認
   if(&確認=1)
    メソッド呼び出し @フォーム.更新モード設定(-1)
   else
    &入力継続=1
   end
   /*無確認で単に &入力継続=1 だけでいいような気もしますが(好み)*/
  else if(&確認=4) /*再試行牡丹*/
   &入力継続=1
  else if(&確認=5) /*無視牡丹*/
   確認 "無視して終了月日<報告月日のまま強行します!",&確認
   条件(&確認<>1) &入力継続=1
  end
手続き定義終了
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

どうやら"終了日.tbl"は、前回終了月日を管理する1行だけの表のようですね?
もしそうだとすれば、終了月日を取得するためだけにこの表を開くのは、
編集表管理が少し面倒となるので(処理後に編集表を元の表に戻す必要があるとか
"終了日.tbl"をどの時点で閉じるか、とか)、&終了月日は「変数読み込み」と
「変数書き出し」で管理することを想定してみました。

あ、挙動未検証ですが。(^^;)

24763 Re:メッセージの後で編集を無効にしたい katsuyoshi 2004/02/12-00:47
記事番号24760へのコメント
悲しげさんお世話様です。
どうも文章を書くことが苦手でご迷惑をおかけしています。
もう一度整理をさせて頂きます。
@ファイル構成
  ・予約.TBL 予約.WFM 契約.TBL 契約.WFM 終了日.TBL 終了日.WFM 

A>2-2)Enter=OKした時は、値を破棄して表示モードにすることで、入力自体を断念
 >すると云うことでしょうか?

 その通りです 

 終了日.TBLに入力された年月日以降は予約.TBLにレコードの追加を許可しないようにしたい。
  予約.TBLの項目[報告日](日時型)に終了日.TBLの項目[終了年月日](日時型)より大きい年月日が入力されたとき

   メッセージボックス "確認","予約期間終了日以降の入力処理は契約処理で行って下さい",アイコン=!,ボタン指定=1,制御文字展開=しない

  のメッセージ後OKボタンで入力を中止させたい。(入力継続はさせない)
  ESCボタンを押下してレコード編集を無効とするような動きをメッセージボックスのOKボタンでできないものかと考えました。

 終了日以降は予約.TBLの変更ができないようにしたい。どうしても変更する必要がある時は
終了日.TBLの年月日を変更してからの作業としたいと思っています。

B>どうやら"終了日.tbl"は、前回終了月日を管理する1行だけの表のようですね?
 >もしそうだとすれば、終了月日を取得するためだけにこの表を開くのは、編集
 >表管理が少し面倒となるので(処理後に編集表を元の表に戻す必要があるとか
 >"終了日.tbl"をどの時点で閉じるか、とか)、&終了月日は「変数読み込み」と
 >「変数書き出し」で管理することを想定してみました。

 悲しげさんのご指導にある変数書き出しと読み込みは使ったことが無いので
 どのタイミングでイベントに記述するのかもできれば教えて下さい。 

 振り出しに戻っての質問のようで恐縮ですがよろしくお願いします。


24767 Re:メッセージの後で編集を無効にしたい 悲しげ 2004/02/12-01:46
記事番号24763へのコメント
>のメッセージ後OKボタンで入力を中止させたい。(入力継続はさせない)
>ESCボタンを押下してレコード編集を無効とするような動きをメッセージボッ
>クスのOKボタンでできないものかと考えました。

う〜ん、どうも状況を想像できないのですが、こういうことでしょうか?

この処理は行追加(または行挿入)である。
チェックに引っかかった場合は、メッセージを出した後に、行追加(または行挿入)自体をやめたい。

私は既存行の訂正を想定していました。
で、改めて試してみましたら(実は私の先の投稿も間違っていたのですが)、
そもそも「入力後」イベントで「更新モード」設定メソドは使えない。
更新モードを変更できるイベントに「ソース値更新」イベントがあります。
これを使えば、チェックに引っかかった場合に行追加自体をキャンセルさせることができます。
なお、この時に「レコードの編集を無効にします。
よろしいですか?」的なメッセージをさらに出す必要は、私はないと思います。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
手続き定義開始 t報告日::ソース値更新()
 if(&終了月日<#日時値(&編集文字列))
  メッセージボックス "確 認"\
   ,"予約期間終了日以降の入力処理は契約処理で行って下さい"\
   ,アイコン=!,ボタン指定=1,制御文字展開=する
  method @フォーム.更新モード設定(-1)
  method @t報告日.フォーカス設定()
 end
手続き定義終了
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

変数読み込み・書き出しの件は、私のイメージでは変数読み込みは例えば
「フォーム開始」、変数書き出しは「フォーム終了」イベント辺りです。
それを考えるのが難しいのなら、表から取得することでかまいません。
が、紛らわしいので、すぐに閉じてしまった方がいいと思います。
終了日とやらは報告日を入力する度に変わる訳ではないだろうから、
一度取得すればよいので、例えば「フォーム開始」イベントで
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
 表 "終了日.tbl"
 ジャンプ 行番号=1 /*不要かも?*/
 &終了月日=[終了月日]
 終了 表 編集対象表 /*すぐに閉じる*/
 編集表 "某.tbl"  /*当該フォームの対象表、でも不要かも?*/
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

24783 Re:メッセージの後で編集を無効にしたい katsuyoshi 2004/02/12-14:07
記事番号24767へのコメント
悲しげさんありがとうございました。
>
この処理は行追加(または行挿入)である。
>チェックに引っかかった場合は、メッセージを出した後に、行追加(また
>は行挿入)自体をやめたい。

そのとおりです。
教えて頂いたことをもとに次のようにしたら意図する動きになりました。

手続き定義開始 t報告日::入力後(参照 文字列 &編集文字列,・・・・・)
変数宣言 固有,日時{&終了月日,&編集文字列}
表 "終了日.TBL"
&終了月日=[終了月日]
  終了 表 編集対象表 
手続き定義終了

手続き定義開始 t報告日::ソース値更新()
&編集文字列=[報告日]
 if(&終了月日<#日時値(&編集文字列))
  メッセージボックス "確 認"\
   ,"予約期間終了日以降の入力処理は契約処理で行って下さい"\
   ,アイコン=!,ボタン指定=1,制御文字展開=する
  method @フォーム.更新モード設定(-1)
  method @t報告日.フォーカス設定()
 end
手続き定義終了

変数は直接表を開いて取得することにしました。
難解な質問内容に適切なご指導頂きましたことに
感謝申し上げます。
 またの機会も宜しくお願いします。
24786 Re:メッセージの後で編集を無効にしたい 悲しげ 2004/02/12-15:48
記事番号24783へのコメント
当初の質問の文言からは「確認でOKの時にescキー押下と同じメッセージ」を出すことが
目的のようにしか読めませんでしたが、問題の所在は「入力後」イベントでは表示モードにできないの件だったのですね。(^^;)

さて、No24783を2〜3添削(^^;)します。

イベントハンドラで桐が自動的に宣言する変数と同名の変数を使うこと
は避けた方が無難です。うっかり間違う可能性大ありなので。

固有変数は、イベントハンドラ内ではなく、一般に冒頭「名札 メイン」
で宣言します。理由は・・・パス。

[報告日]項目もおそらく日時型だろうから、#日時値を使うのは蛇足では?

"終了日.tbl"は、どうやらその都度開いて値を取得したいみたいなので、
ならば「ソース値更新」イベントでやればいいと思います。
変数値代入のためだけに「入力後」イベントを発生させるのは無意味かと。

と云うわけで、独断と偏見で書き直してみると
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
名札 メイン
 *変数宣言 固有,日時{&終了月日,&報告月日} /*?*/
 変数宣言 固有,日時{&終了月日}



手続き定義開始 t報告日::ソース値更新()
 表 "終了日.TBL"
 &終了月日=[終了月日]
 終了 表 編集対象表 
 編集表 "なんとか.tbl" /*当該wfmの対象表*/
 if(&終了月日<[報告日]) /*註*/
  メッセージボックス "確 認"\
   ,"予約期間終了日以降の入力処理は契約処理で行って下さい"\
   ,アイコン=!,ボタン指定=1,制御文字展開=する
  method @フォーム.更新モード設定(-1)
  method @t報告日.フォーカス設定()
 end
手続き定義終了
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
(註)
 if(&終了月日<#日時値([報告日]))
とする必要はないような?
まして、&報告月日を別途変数宣言して
 &報告年月=[報告日]
 if(&終了月日<#日時値(&報告年月))
とする必要もないような?

&終了年月は、やっていることから推すに、他のフォームでも共用しそうに思えるのですが、
上記「ソース値更新」イベント内でしか使わないのであれば「メイン部」で宣言せずに、

手続き定義開始 t報告日::ソース値更新()
 表 "終了日.TBL"
 変数宣言 自動,日時{&終了月日=[終了月日]}
 終了 表 編集対象表 
 ・・・・・

とする方法もあります。(cf.自動変数のヘルプ)

24800 すっきりしました。ありがとうございました。 katsuyoshi 2004/02/12-22:51
記事番号24786へのコメント
悲しげさんありがとうございました。
なんか遠回りしてわざわざ難しくしていたようです。
ご指導のとおり記述を訂正しました。
ところで似たような質問がまたあります。
別スレッドで投稿しますのでよろしくお願いします。
24801 Re:すっきりしました。ありがとうございました。 佐田 守弘 2004/02/12-22:55
記事番号24800へのコメント
katsuyoshiさん
悲しげさんが後を次いで、目的を確認して下さいましたが、今までの書き込みで
まだ解らない部分が残っております。何と無く解り掛けた部分で言えば、
日付が誤っていたら、その行の入力を取り消してしまうという事の様です。
そうであれば、
 メソッド呼び出し @フォーム.更新モード設定(0)
 行削除
この2行でできるのではないかと思うのですが。
更新モード設定は-1として、その項目値の入力を取り消した方が良いかどうかは、
私には解りません。どちらにしても行削除してしまうので、同じ事と思います。

佐田守弘(KS-00119)
24809 Re:すっきりしました。ありがとうございました。 悲しげ 2004/02/13-00:17
記事番号24801へのコメント
どもっ、佐田さん、
え〜、かつよしさんに成り代わってご説明申し上げます。(^^;)
この件については、当初は私も既存行の訂正(あるいは、先ず行追加してしまった上での追加行の行訂正)だと見ていたのですが、
そうではなくて、行追加(または行挿入)途中の問題だったようです。
とすれば、レコードとしては未確定の時期であるからして

  メソッド呼び出し @フォーム.更新モード設定(0)
  行削除

とやると「処理対象行がない」旨のエラーメッセージに出会います。
どうも行追加などの場合は、更新モード設定(0)メソッドでも追加行は確定しない仕様のようです。
だからこの場合は、更新モード設定(-1)と同等に結果するようです。
よって、記述としては

  method @フォーム.更新モード設定(-1)  /*★*/
  method @t報告日.フォーカス設定()

だけに止めておく方がよいことになります。
ちなみに、この時★印部で 更新モード設定(0) としても同じ挙動となることが何だか腑に落ちない感じは否めませんが。(^^;)

かくのごとく、行追加等の場合と既存行の訂正の場合で挙動が異なるとすれば、
厳密には「更新モード取得」メソッドの返り値でもって、この辺りの対応をケース分けした方がよいかもしれません。
ただし本件の場合は、既存行の訂正でも、訂正のキャンセル程度に留め、行削除までは必要ないような気がしないでもありません。

24812 ありがとうございました。 katsuyoshi 2004/02/13-01:31
記事番号24801へのコメント
佐田さんありがとうございました。
>katsuyoshiさん
>悲しげさんが後を次いで、目的を確認して下さいましたが、今までの書き込みで
>まだ解らない部分が残っております。何と無く解り掛けた部分で言えば、
>日付が誤っていたら、その行の入力を取り消してしまうという事の様です。
>そうであれば、
> メソッド呼び出し @フォーム.更新モード設定(0)
> 行削除
>この2行でできるのではないかと思うのですが。
>更新モード設定は-1として、その項目値の入力を取り消した方が良いかどうか
>は、私には解りません。どちらにしても行削除してしまうので、同じ事と
>思います。

目的地までの行く道、行き方は何通りもあるものと感心しました。
できるだけ簡素化をしたほうが後で解りやすいのではと思ったところです。
ありがとうございました。勉強になりました。
また別スレッドもよろしくお願いします。

戻る