スキップしてメイン コンテンツに移動

対処例:Accessフォームでチェックボックスが思うように設定できない

開発プラットフォームとしてAcccessという事は多い。
そして何気に不思議な動作をする事が多いのも事実。

今回であったのは、フォームに置いたチェックボックスが、フォームを開いた際に思ったように振舞ってくれない、というもの。

このチェックボックスは規定値=FALSEで設定してあって、人の操作以外でこのチェックボックスの値は操作していない。

そしてこのチェックボックスを置いたフォームを開くと…

問題のチェックボックス、チェックがついた状態で描画される!!!

こまったチャンである。
時折は意図したとおりにOFFの状態で開く場合もあるものの、まれ。
ここはしっかりユーザーの操作(チェックボックスをONにする)に基づき、関連の項目を入力してもらう、という動作をさせたいし、また他へのI/F項目でもあって、しっかりさせたい。ちなみに、TripleState プロパティは Falseに設定してある。

簡単にググッてみたものの、ちょっと同様の事例や対処は見つからず。いくつか試したが、うまく行かない。

で、結論から書くと、こういう対処をした。

Form_OPENイベントの際に、問題のチェックボックスに以下の操作を実行

・問題のチェックボックスにフォーカス設定
・問題のチェックボックスに対して、SendKeys でスペース(" ")一文字投げつけ
・問題のチェックボックスの Value 値を確認。True の場合、もう一回SendKey でスペース(" ")一文字投げつけ

発想としては、チェックボックスがカレントな状態のとき、スペースキーで値が操作できる事を思い出し、ぶつけてみた。
でも、実は最初はうまく行かず。

はて?

で、SendKeys のリファレンスを改めて眺めて、Wait オプションがある事を思い出した。
解説するまでもないが、これが True の場合、そのキーが処理されるまでVBAは次の実行をまつ。デフォルトでは False で実行される。なので、Accessが、なげつけられた?(いや、自分で自分に投げているわけだから…)スペースキーを受け取る前にVBAが進んでるか?と思い、以下に書き換えてやってみた。

SendKeys " ", True

そしたら、なんと、なんとか、安定した。

よくプログラムは理屈だ、と教えられた。確かにそのとおり。でも現実こういう不可解な事象には出くわすわけで、それに何とか形をつけるのも仕事の内。

はっきりいって結果オーライな対処。もっとスマートな方法もあったかも知れぬが。
ま、一つの事例として。

2018/03/14 追記
この問題について、もう一度やってみた。
実は似た状況で別のチェックボックスに同じようにやるのだが、やはり思ったようには振舞ってくれないケースが出た。

で、改めてチェックボックスが持つ値を確認してみたのだけれど、これが Integer型なんだと判った。
-1 が On(チェックボックスにチェックが入った状態)
0  が Off(チェックボックスにチェックが入っていない状態)

これまで人間系が操作したチェックボックスの値の評価を Boolean型で処理していたのね。それで評価も出来ていたからそれでいいんだ、と思っていたんだけど。
思い込みとは怖い。

で、端的に言えば、上記の Integer型で値をセットしてやると、すんなりと行くんだわ、これが。

これが正解みたいです。

2018/03/15 追記
チェックボックスが、って話。結論からいくと自分の設定がうまくなかった、という事のよう。
問題のチェックボックス、規定値が ”On" って表現なのね。これがいけない。
素直に規定値= "-1" って与えればしっかり動作した。
ここの設定がおかしくて、フォームを開きなおした際の値の入り方がおかしかった訳だ。

思い込みはいかんね。

コメント

このブログの人気の投稿

VBS で引数を受け取るサンプル

WScript.Arguments に引数要素が配列で格納されているので、これを取り出す。 =========================================== '############################# 'パラメータ=オーダーIDの取り出しとセット '############################# Dim oParam 'パラメータオブジェクト Dim strPrm0  'パラメータ要素格納 Set oParam = WScript.Arguments strPrm0 = oParam(0) Wscript.echo strPrm0 =========================================== これを引数あり、引数なしでそれぞれ実行してみる。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >cscript.exe test.vbs a a >cscript.exe test.vbs test.vbs(9, 1) Microsoft VBScript 実行時エラー: インデックスが有効範囲にありません。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ strPrm0 = oParam(0) の場所で怒られている。 引数なしで起動した場合には相応の対応をしたい。 そこで、上記を書き換える。 WScript.Arguments のCount ポロパティの値をチェックして動作を切り分ける方法。 =========================================== '############################# 'パラメータ=オーダーIDの取り出しとセット '############################# Dim oParam 'パラメータオブジェクト Dim strPrm0  'パラメータ要素格納 Set oParam = WScript.Arguments ...

Accessで環境変数を使う

今回のお題は、ディレクトリの特定の仕方について。 Accessで処理するファイルを、ある場所、具体的にはユーザープロファイルの”ダウンロード”フォルダからアプリのディレクトリに移動したい。 ただ、”ダウンロード”フォルダはログインしているユーザーによって絶対パスが変わってくる。それをどうするか? 今回の場合、ユーザーのリテラシーがそれほど高くなく、ネットからダウンロードされたファイルを、ユーザー自身がファイル選択ダイアログから選んで指示するのは避ける、という判断となった。 一応、ネットからダウンロードされるファイルの保存先はユーザー別の”ダウンロード”フォルダ、という事は保障される前提。 ダウンロードされるファイル名は名前付けルールにそって、識別子のお尻にタイムスタンプが付く。 ただ、Access側での処理のタイミングの問題で、同時に複数のダウンロードファイルを処理するケースも想定された。 個人的には、バッチファイルを同期でアクセスから実行して…、で良いんじゃない?と思った。 それなら環境変数でユーザープロファイルのパスが取れるから。 でも他からの判断でアクセス内で完結させる方法をとる事となった。 で、結局はWSHの ExpandEnvironmentStrings メソッドを使う事にした。 このメソッドは環境変数(%XXXX%)文字列をあたえるとそれの展開結果を返してくれる。 なんで、ExpandEnvironmentStrings("%userprofile%")とすると、ログインユーザーのユーザープロファイルパスが帰ってくる。 なお、これをAccessで使うには参照設定として「Windows Script Host Object Model」 を追加しないといけない。 また、オブジェクトを使うにはアーリーバインディングで書く必要がある事に注意。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...