• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Accessでのマウスホイールの無効化)

Accessでのマウスホイールの無効化

このQ&Aのポイント
  • Accessを使用して特定のフォームでマウスのホイールの動作を無効化する方法について教えてください。
  • VBE上でコードを貼り付けてもうまく動作しない原因について教えてください。
  • コードの貼り付ける位置が間違っている場合、正しい位置にコードを貼り付ける方法について教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.4

> 1.フォームには貼り付ける際、前回は末尾に貼り付けたが今回は冒頭に >  貼り付けた あ。。これですね。原因は。 Private WithEvents ~ はモジュールの先頭でなければなりません。 先頭というのは、1行目という意味ではなく、他プロシージャよりも 必ず前の部分に書くという意味です。 Sub aaa()   '処理 End Sub Private WithEvents ~ はダメなのですが、 Private hoge As Long Private WithEvents ~ Sub aaa()   '処理 End Sub のようならば OK。他 Sub プロシージャよりも前のブロックに書か ないといけない決まりになってます。 > サブクラス化の危険性を考慮した、より安全な手法による、 > 参考ソースの方はいかがでしょうか? 表現の仕方が悪かったようです。Access でマウスホイールの挙動を 制御するには、  1. サブクラス化を行う  2. ActiveX 等を使う 以外の方法はありません。 2. は別途で Dll または OCX 等のファイルをインストールする必要 があります。未確認ですが、Vector 等で探せば VBA 用のものが 見つかるかもしれません。なければ自作するしかないんですが・・・ ただし、社内で配布するものとして追加インストールが必要な手法 というのは難点になりますよね...?  # システム管理者や社内のOA運用方針との兼ね合いで 一方、1. のサブクラス化では、追加インストールは不要ですが、 先述のようなリスクもあるわけです。これは、ユーザー側という よりも、システム設計・開発しているあなたの側に細心の注意を 払う必要があるということを意味しています。 つまり、バグの無いものを作る必要があるということです。 そして、十分にテストする必要もあります。 #2 を回答した時点では、参考にされたソースを詳しく検証して ませんでしたから、ソースに不備があるのかも? ならば、手元に ある以前開発したものを参考ソースとして提示・・といった発言を してしまったのですが、特に参考にされたソースには問題がありま せんでした。  # 元々は MSDN (Microsoft の技術サポート情報サイト)に  # 公開されていたもののようです 似たようなソースをアップしても有益な情報とはならないでしょう。 従いまして参考ソースのアップは控えさせて頂きました。 私の回答の結論としては、繰り返しになりますが、  ・サブクラス化の手法を使う(参考にされたソースを活用する)  ・エラーが発生しないように、十分にテストを繰り返し、バグの   無いモノをリリースする いうことになります。 誤解を与えてしまったようで、申し訳ありません。

Spacewatch
質問者

お礼

 丁寧な解説をいただき有り難うございます。  よくわかりました。  1. サブクラス化を行う  2. ActiveX 等を使う のふたつの方法があり、2はユーザに負担をかける(あるいはそのサポート の為の管理者側の負担もあるかも?)、一方、1についてはもしバグがあると システム全体に影響を及ぼすので、管理者側がしっかり検証したものである 必要があるが、今回のソースのように検証されたものであれば問題はない、 ということですね。  なお、ほかに一点だけ気になることがあり、補足質問の方に書かせて いただきます。  もし、なにか見識があればコメントいただければ幸いです。  今回はどうも有り難うございました。大変助かりました。 以上  

Spacewatch
質問者

補足

 一点だけ気になっていることがあるのですが、それは、先の補足に 書かせていただきました『VBEによるコード修正後、Accessを閉じる際の 操作の違いによって、VBAのセーブがうまく行ったり行かなかったりという ことがあるのか・・・?』 という点です。  実は、昨日、うまくいきましたとの状況報告をアップした後に、再びうまく いかないことがありました(・・・・・・該当フォームを開くと、「計算しています」 の状態が延々と続きフリーズしてしまう現象)。  このときは、一旦タスクマネージャで強制終了した後、データベース ウィンドウを開き、モジュールオブジェクトがウィンドウ右側に表示されている 状態で、データベースウィンドウの右上の×をクリックして閉じる、という ことを行い、再度アプリ起動すると、今度はうまくいきました。  その後はいまのところ問題ありません。  Accessは、他のOfficeソフトと異なり、ウィンドウを閉じる行為が、セーブ されるデフォルトになっていて、少し感覚が違うのですが、上記についても このあたりの関係で、VBAを使う際に何か留意しておくべき事項がある ということなのでしょうか?  また、念のため確認ですが、上記のような状況は、サブクラス化による 不安定現象ではないと考えてよろしいのですよね?  これらについて、なにか見識がありましたら最後にコメントいただけません でしょうか?  よろしくお願い致します。

その他の回答 (3)

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.3

再度 URL 先のソースを試しましたが、特に問題なさそうです。  # 今度はうまく動きました 標準モジュール、クラスモジュール、フォームと3つのモジュールに ソースを間違いなく貼り付けてますか? 改造した部分はありませんか? それから、各モジュールはちゃんと Save してから実行してますか? 動作確認が取れてますから、念のため、今一度説明を良く読んで、 再度貼り付け作業からやってみて下さい。

Spacewatch
質問者

補足

 有り難うございました。  もう一度全てクリアして、最初からやり直してみたらうまくいきました。  前回どこがまずかったのか不明ですが、可能性としては以下の辺り かと・・・・ 1.フォームには貼り付ける際、前回は末尾に貼り付けたが今回は冒頭に  貼り付けた 2.前回もちゃんとセーブしたつもりでしたが、以下の手順8~10を厳格に  実行した    8.VBE画面を閉じ、データベースウインドウからモジュールを選択します。    9.Accessを一旦閉じます。    10.再度Accessを開き該当フォームを開きます。   なお、手順8の後半の意味がよくわからなかったのですが、データベース  ウィンドウにてオブジェクトのうちからモジュールを選択し、種々の モジュールオブジェクトがウィンドウ右側に表示されている状態で、 データベースウィンドウの右上の×をクリックして閉じる、ということを 厳格に行いました。   前回の手順の詳しいところは、よく記憶していませんが、もしかすると モジュールオブジェクトを選択していなかったかもしれませんし、Accessを 閉じる方法もデータベースウィンドウの×をクリックではなく、いきなり Accessのウィンドウの×をクリックで閉じていたかもしれません。   ともあれ、このあたりの操作の違いによって、セーブがうまく行ったり 行かなかったりということはあるのでしょうか?  それと、あと1点確認させていただきたいのですが、2回目の回答で触れて いただいていたサブクラス化の危険性を考慮した、より安全な手法による、 参考ソースの方はいかがでしょうか?    よろしくお願い致します。

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

そうですか。。。 一応、参照された URL のソースを試してみたらマウスホイールを 禁止できましたが、そのままフリーズしてしまいました。 やっていることは、サブクラス化といって、本来 Windows (OS) が行っていること(この場合、マウスホイールの挙動に関する OS が発信した Access への制御メッセージ)を無理やり横取りし、 自前の処理に置き換えているわけです。 したがって、ヘタをするとアプリ、最悪 OS ごとダウンするリスキー な手法でもあり、ある程度アプリや OS に精通している方以外には お勧めできない手法なんですよね。。。 時間がなくて細かく検証してませんが、夜中か数日中にはその結果、 または参考ソースをアップしときます。 よろしければ締め切らず気長にお待ち下さい。

Spacewatch
質問者

補足

 早速のレス有り難うございます。    サブクラス化・・・・?、全くわかりません。。。。 (^^;)  当方Accessに出会って1年にはなりますが、もとよりソフト開発者ではなく、 限りなくエンドユーザに近い立場であり、ましてやOSに精通など、ほど遠い 状況です。    1週間ほど前にリリースさせ、すでに社内で稼働しているアプリなのですが、 ユーザに対しては、誤ってホイールに触れないように、注意喚起して使って もらっています。これを、近々回避することができ、しかもシステム的に安定・ 安全な方法を教えていただけるのであれば、非常に助かります。  締め切らずにお待ちいたしますので、よろしくお願い致します。 以上

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.1

レス番号 8910 にある      > Class1モジュールの名前をCMouseWheelに変更します をやってないとみた。 単に Access ではなく、Access2003 などバージョンまで明記して下さい。 ご参考になった URL のソースは、AddressOf 演算子が使われてますから、 Access2000 以降のバージョンである必要があります。

Spacewatch
質問者

補足

KenKen_SPさん  回答有り難うございます。  連絡が漏れておりましたが、バージョンはAccess2003 SP3となっています。  2000以降のバージョンである必要があるとのことですので、まずは対応して いるということにはなるでしょうか。    さて、 >レス番号 8910 にある   >  > Class1モジュールの名前をCMouseWheelに変更します >をやってないとみた。 とのことですが、一応やったつもりではあります。  現状は、VBAの左下にあるプロパティのペインで、オブジェクト名欄に CMouseWheel と記述してありますし、その上のプロジェクトのペインで、クラスモジュール の下にツリーでぶら下がっているモジュールのイメージの脇にも CMouseWheelと表示されています。  これでよろしいのですよね?  ちなみに、CMouseWheelをダブルクリックして開く、VBAコードの表示 エリア上部左側には(General)と表示され、右側には(Declarations)と 表示されており、コード部分には以下を貼り付けています。  それでもダメです。よろしくお願いします。 (以下、CMouseWheelのコード) -------------------------------- Option Compare Database Private frm As Object Private intCancel As Integer Public Event MouseWheel(Cancel As Integer) Public Property Set Form(frmIn As Object) Set frm = frmIn End Property Public Property Get MouseWheelCancel() As Integer MouseWheelCancel = intCancel End Property Public Sub SubClassHookForm() lpPrevWndProc = SetWindowLong(frm.hwnd, GWL_WNDPROC, AddressOf WindowProc) Set CMouse = Me End Sub Public Sub SubClassUnHookForm() Call SetWindowLong(frm.hwnd, GWL_WNDPROC, lpPrevWndProc) End Sub Public Sub FireMouseWheel() RaiseEvent MouseWheel(intCancel) End Sub

関連するQ&A