- ベストアンサー
改ページコントロールを使ってマウスホイールでフォーム内のページを変える方法
- 改ページコントロールを使ってマウスホイールを動かした時にフォーム内でページが変わる方法について調べました。
- VBを使用して、マウスホイールの動きに応じてフォーム内のページを切り替える方法を見つけました。
- VBに詳しくないため、具体的な実装方法が分からず困っています。どなたか教えていただけませんか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
後追い失礼致します。 (私事・些事で時間が取れなかったもので・・・) SendKeysを使用しているため、安定動作に若干不安要素がありますが(汗)、 以下の処理ではいかがでしょうか。 (フォームビューで、キーボードのPageUp/PageDownキーを押したときと同じ 動作をさせています) Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long) If Count > 0 Then SendKeys "{PGDN}" Else SendKeys "{PGUP}" End If End Sub なお、本当であれば、1つのフォームに表示するコントロールはもっと減らして、 減らしたコントロールは必要に応じてポップアップフォームなどで別途表示、 とすることが薦められていますので、併せて参考まで。 (例えば、社員情報を登録・表示する際に、ベースとなるフォームでは 社員本人の情報のみとして、家族については配偶者の有無や人数のみを 表示し、いる場合はコマンドボタンでその情報を表示するポップアップフォーム を展開、といった感じです) ※1つのテーブルにそれらの情報すべてが含められている場合は、テーブルの 分割(正規化)も必要になります。 ・・・改修となると非常に労力を要しますので、今後の参考までに、という ことで・・・(汗)
その他の回答 (4)
- DexMachina
- ベストアンサー率73% (1287/1744)
No.3です。 > う・・・エラーが出ます(T_T) すみません、今度は「非連結コントロール設置時の動作確認」が抜けていました(汗) (Dirtyプロパティを更新するには、アクティブコントロールが連結コントロールである必要 があります) 前回画像としてつけたサイトを、参考までにもう一度ここにリンクしておきます: http://www.f3.dion.ne.jp/~element/msaccess/AcTipsFrmMouseWheelEvent.html ・・・とはいえ、「現在のページ内にある連結コントロール」の取得というのは、正直 かなり無理をしないといけないので、『SendKeysで簡単に』は無理がありますね(汗) ということで、No.2・3は取り下げます。 お目汚し&お時間を取らせてしまったこと、お詫び致します。 > レコードが動いても全然困らないんで大丈夫ですよ^^; そのAccessファイルは、9treeさん以外の方も使われるんですよね? だとすると、その動作は「なんだこれは?」と思われてしまうと思いますので、 nicotinismさんの回答を使用されることを 【強く】 お勧めします(汗) 大変失礼致しました。
お礼
レスに気が付きました(土日は全く見てませんでした)。。。 色々とご尽力ありがとうございました。 でもBAはNo.2にしたいと思います。 改ページを入れたらわりと動作が安定しましたので・・・ また何かあればよろしくお願いします。
- nicotinism
- ベストアンサー率70% (1019/1452)
あのう・・改ページコントロールを挿入していないのでは? 添付図の左側の下から2番目です。 コントロールボックスを出して上記をクリックし フォームの好きな所でクリックすると点々(改ページ)が挿入されます。 最初に紹介したリンク先でも、『・・・・・』が左側にありますよ。 自分の意見をゴリ押しするつもりは有りませんが、 フォームヘッダーにもう隙間はないのでしょうかね。 ご参考まで。
お礼
ありがとうございます 今月いっぱいでacceesも作らないといけないのでまた質問させて頂くかもしれませんがよろしくお願いします。
補足
改ページコントロールを入れたら動きました(初めて改ページの存在に気が付きました^^;) 自分がネットで調べたやつも改ページを入れたら動きました^^; なるほど~って感じです ボタンを入れるスペースは会社のデザインの関係もあってギリギリで作っているのでちょっと無理なんですよね。。。 ヘッダーフッター以外の途中の隙間にはあるんですけどね^^; ボタンを押すためにマウスを移動させるなら、バーを移動させる為にマウスを移動させる手間と同じだなと思いました
- DexMachina
- ベストアンサー率73% (1287/1744)
No.2です。 > ただどこに入れたらいいのかわからないので触れませんでしたが^^;^^; 余計なことを言って、混乱させてしまったかもしれません(汗) 一応、説明を追加しておくと、『改ページ』コントロール(フォームのデザインビュー 用のツールバーで、『タブ コントロール』の隣のボタンで追加できます)を、フォーム の1画面分の半分の高さの位置に設置すると、PageUp/PageDownキーによる 移動が、画面単位ではなくそのコントロールの位置になる(=微調整が可能)、 ということです。 (・・・この説明もわかりにくすぎですが・・・(汗)) ご提示のURLの情報を元に、既に追加済みでしたら、ここは聞き流して下さい(汗) > ちなみに合わせてレコードも動きますがこれは仕方なしですね^^; あ・・・すみません、非連結フォームで動作確認していました(汗) とりあえず、コードを以下のようにすることで、PageUp/PageDownキーと同様の 動作にすることはできました。 (PageDownキーでは、1番下のページに行くと、次からはレコード移動になります: そのレコードの先頭ページに移動するには、PageUpを数回押すか、Homeキー を1回押します) なお、意図した動作をさせるために試行錯誤した結果、「マウスホイール時」 イベントと同時に、フォームの「更新前処理」と「タイマ時」イベントも使用する 形となりました。 <以下、コード> '以下の変数は、複数のイベント間で使用するため、先頭(クラスモジュール 'レベル)での宣言が必要 Private myDirec As Boolean, myCancel As Boolean, myDirty As Boolean '【マウスホイール時イベント】 Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long) If Me.NewRecord Then '新規レコードは「Dirty=True」にすると問題なので対象外としました。 Exit Sub ElseIf (Count > 0) Then 'ホイールの回転方向を変数に記録(下方向) myDirec = True ElseIf Me.CurrentRecord = 1 Then '「先頭レコード&上方向」は処理不要 Exit Sub Else 'ホイールの回転方向を変数に記録(上方向) myDirec = False End If 'タイマを使用し、レコード移動の取り消しが行われるのを見計らいます。 '(意図した動作にならない場合は、「10」を「100」などに変更してみて ' 下さい:但し、数値を大きくすると、スクロール速度が低下します) Me.TimerInterval = 10 'Dirtyプロパティの現在値を記録した上で、「更新前処理」のCancelに 'よってレコード移動を制限するため、同プロパティを「True」に設定。 myDirty = Me.Dirty Me.Dirty = True '「更新前処理」の取り消しを行うためのフラグを立てる。 myCancel = True End Sub '【更新前処理イベント】 Private Sub Form_BeforeUpdate(Cancel As Integer) 'マウスホイールによるレコード移動を取り消し If myCancel Then Cancel = True End Sub '【タイマ時イベント】 Private Sub Form_Timer() Dim nRec As Long, sKey As String '本イベントの反復を避ける Me.TimerInterval = 0 'フラグを初期化 myCancel = False 'PageUp/PageDown前のレコード位置を確認 nRec = Me.CurrentRecord 'SendKeysでページを移動 '(末尾ページだった場合はレコード移動になります) If myDirec Then SendKeys "{PgDn}" Else SendKeys "{PgUp}" End If 'Dirtyプロパティの値を元に戻す。 Me.Dirty = myDirty End Sub ・・・以上です。
補足
う・・・エラーが出ます(T_T) 「このフォームを使ってデータ変更するには、編集可能な連結フィールドにフォーカスがある必要があります」と出ます。 デバッグを開くとホイールイベントのところの Me.Dirty = Trueが反転します 一応改ページなんかも入れてみましたが関係ないみたいですね それからなんだか催促してしまったようで申し訳ないです レコードが動いても全然困らないんで大丈夫ですよ^^; この質問もBAをするのを忘れておりましたら書き込みがあったんで^^; それはそれで納得いかーんとも思われるかと思うので もうしばらくそのままにしておきますが、ホント暇つぶし程度でよいので。。。
- nicotinism
- ベストアンサー率70% (1019/1452)
レスが無いので・・考えてみましたがヤヤコシクなるかもです。 本番フォームではなく、適当なフォームを作成して動作確認してください。 フォームは単票フォーム、 改ページコントロールは等間隔で2cm ごと 詳細セクションの高さは上記間隔の倍数であること Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long) Const pageHeight As Integer = 2 '←改ページコントロールの間隔指定 Dim currentPageNo As Integer Dim maxPage As Integer If Me.ActiveControl.Section <> acDetail Then 'アクティブなコントロールが詳細セクションに無ければ抜ける Exit Sub End If maxPage = Me.Section(acDetail).Height \ pageHeight * 567 '1cm は 567 twip '何ページに分かれるかを詳細セクションの高さとpageHeightから割り出す currentPageNo = Screen.ActiveControl.Properties("top") \ pageHeight * 567 + 1 '現在何ページ目にいるのかをアクティブなコントロールの配置位置から割り出す If Count > 0 And currentPageNo <> maxPage Then 'ホイールが手前回転で最終ページではない場合 Me.GoToPage currentPageNo + 1 ElseIf Count < 0 And currentPageNo <> 1 Then 'ホイールが向こう回転で1ページ目ではない場合 Me.GoToPage currentPageNo - 1 End If End Sub コメント以外の解説 フォームで表示されているページが何ページ目かを知る直接的な関数はありません。 なのでフォーム上でアクティブなコントロールから割り出す必要があると考えました。 上記コードは単純にテキストボックスやコマンドボタンの場合だけを考えていますので サブフォームが配置してあって、それがアクティブな場合などは機能しません。 また、フォームのサイズをドラッグしてページあたりのサイズ(pageHeight)よりも 高さを広げた場合にも動作がおかしくなります。 その他にも制約が色々ありそうです。 単純にページ数だけのコマンドボタンを設けて、それぞれで Me.GotoPage 1 とか Me.GotoPage 3 とかにしておいた方が無難だと思います。。。 http://www.tsware.jp/tips/tips_026.htm も参考に。私からは以上です。
補足
毎回ありがとうございます 早速テストフォーム(高さは20cm)を作ってやってみましたがアクティブコントロールがなんたらっと出たので 上部と下部にそれぞれテキストボックスとボタンを作ってみましたが、やはり動きませんでした。。。 ページ番号がこのフォームに無いとでます。 リンク先のがページ場合を設定をするというような内容だったので試してみたのですがこれも動きません。 う~んなんか複雑みたいですね・・・・ ちなみにご提案いただいた >単純にページ数だけのコマンドボタンを設けて、それぞれで >Me.GotoPage 1 とか Me.GotoPage 3 とかにしておいた方が無難だと思います。 は、スペースの関係でできそうに無いです^^;
補足
回答ありがとうございます 出来ました!! 補足のもありがとうございます ただどこに入れたらいいのかわからないので触れませんでしたが^^;^^; ちなみに合わせてレコードも動きますがこれは仕方なしですね^^; ありがとうございました