Microsoft Access 掲示板

カレンダーをキー移動した際の症状について

4 コメント
views
4 フォロー

知恵袋から、FC2に。そこからここまでやってきました。移動したという情報を見る前に、FC2の方へもうコメントをしてしまいました、申し訳ありません。

FC2で配布されていた VBACalendarDlg.accdb の F_Calender を利用させていただきながら
ACCESS2016で入力フォームを作っています。
年配の作業者も多いので、本当に助かっています。ありがとうございます。
しかしながら1つ問題が発生しました。もし以前に解決為されていたら申し訳ありません。

フォームのボタンから F_calendar を表示し、キー移動で日付選択をする場合です。
開く際の日付が 1900年1月 である場合に、キー移動を行うと、移動後の日も、日付選択の水色が解除されず、今自分がどこに居るか分からなくなってしまっています(翌月移動なども同様)。キー移動で1900年2月以降にまで進むと、その水色が消えない症状は出てこなくなりました。しかし、1899年12月に移動した場合は水色キープ症状は出たままです。
また、1900年1月以前で開いた際も同様の不具合が起きます。

自分で作ったフォームだけでなく、ダウンロードさせていただいたテンプレフォームから行っても同様でした。(使用環境の都合、WinAPI宣言部分に PtrSafe は追加しています。)
まだまだ初心者なので具体的にどこをいじればいいのかがわからず、やや困惑しております。お力添えをいただけますでしょうか?

ゲッキョク駐車場
作成: 2020/05/27 (水) 14:21:01
通報 ...
1

フォームのボタンから F_calendar を表示し、キー移動で日付選択をする場合です。
開く際の日付が 1900年1月 である場合に、キー移動を行うと、移動後の日も、日付選択の水色が解除されず、今自分がどこに居るか分からなくなってしまっています(翌月移動なども同様)。キー移動で1900年2月以降にまで進むと、その水色が消えない症状は出てこなくなりました。しかし、1899年12月に移動した場合は水色キープ症状は出たままです。

そのような昔の日付が入力されることは想定外でした。F_calendarフォームのモジュールで、
先頭の宣言部を下記のように修正してください。

Option Compare Database
Option Explicit

Dim ctl As Control
'FirstDay As Date この行を削除して、下記の1行を追加
Dim FirstDay As Variant 
Dim vDate As Date

さらに、SetCalendar関数の先頭部分を下記のように修正してください。

'カレンダー 日にち設定関数
Private Function SetCalendar(aDate As Date)
Dim i As Integer, D As Date, m As Integer, n As Integer

'   If FirstDay > 0 Then  この行を削除して、下記の1行を追加
    If Not IsEmpty(FirstDay) Then
        Me("D" & vDate - FirstDay).BackStyle = 0 '透明
    End If

'以下略

異常で問題なく動作するようになります。

2
ゲッキョク駐車場 2020/05/27 (水) 16:46:50 cb55f@f6500

ありがとうございます!解決しました!

後学のためにお聞きしたいのですが、今回の事象の理由は以下の通りであってますでしょうか?

●変更前
・DATEデータ型の場合、1900/01/01が「0」、それ以前が負の数 で設定される。
・If FirstDay > 0 Then 部分で、1900/01/01以前の日がはじかれ、IF節内に入れなかった。
・1900/01/15などの日も、同カレンダー内に「0」が存在してしまっている為(?)に同様の事象。
●変更後
・型をVariantに変更し、IF条件をFirstDayが初期化されてたら(空っぽだったら?)ので、IF内の透明化処理(?)が行われた。

3

まず、FirstDay変数には、カレンダーの先頭の日付の一つ前の日付か格納されます。
1900年1月のカレンダーだと、1/1は月曜なので、その前日の日曜は、1899/12/31 になりこれが先頭になります。
FirstDayには、1899/12/30 が格納されます。

修正前の

   If FirstDay > 0 Then
        Me("D" & vDate - FirstDay).BackStyle = 0 '透明
    End If

のコードの意味は、FirstDay に日付が代入されているかどうかをチェックしています。
つまり、カレンダーフォーム起動直後で、まだ、FirstDayに何も代入されていない場合はなにもせずに、
日付が代入されていたら選択日付のラベルの背景色を透明に戻す、
という処理をしています。

VBAの Date型の初期値(宣言してから何も代入されていないときの値)は #1899/12/30# でこれは内部的には 0 です。FirstDay > 0 でなければ、FirstDayは初期値のままでフォーム起動直後と判断していました。

ところが、1900年1月のカレンダーだと FirstDay には、1899/12/30 が代入されてしまいます。つまり、初期値と同じ値になります。このため、カレンダーの先頭日付か代入されているのに、初期値のままと判断してなにもしないことになり、後の処理で矛盾が発生してしまい動作がおかしくなりました。

修正後は、
FirstDay は Variant型で宣言しました。Variant型は初期値(代入前)は Empty値という特殊な値になります。また、どのようなデータ型でも代入できます。もちろんDate型の値も代入できます。IsEmpty関数でEmpty値かどうか判定できます。IsEmpty(FirstDay) が True なら確実に、初期値のまま(代入されていない)という判定ができます。

4
ゲッキョク駐車場 2020/05/28 (木) 08:55:15 cb55f@f6500 >> 3

丁寧な解説ありがとうございます!
Date型や、variant型を特によく理解せずに使ってたので、すごく助かりました!😆
また、躓きましたら、助けを求めるかもしれません。
その時はよろしくお願いいたします!