• ベストアンサー

EXCELでVBAを使用してセル移動のコントロールをしています。

EXCELでVBAを使用してセル移動のコントロールをしています。 主にENTERキー、SHIHT+TAB キーでのセル移動の制御を行っていますが、 EXCELの機能で矢印キー↑↓←→のキー操作が邪魔で、 思うような位置にセルが移動しなく、 たぶんEXCEL側の制御の動きをしているのではないかと思うのです。 VBAでセル移動の制御をしているせいか、 EXCEL制御で動く矢印キーが思うように制御しません。 そこで、このEXCEL制御の矢印キーの動きをしないようにと考えてます。 どのようにしたら、矢印キー制御を阻止できるでしょうか? 教えて頂けませんか?

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

  • ベストアンサー
noname#144013
noname#144013
回答No.1

こんにちは。 以下、的外れでしたらすみません。 今ひとつ、やりたい事の『目的』と『状況』が解らないのですが、 > セル移動のコントロール とは、具体的にどのような事をなさりたいのでしょうか? 例えば、下記の過去質問のようなことをやりたいと言う事でしょうか? ■過去質問 Do Loop Until 条件停止後のセル位置について http://qanda.rakuten.ne.jp/qa5320531.html だとした場合ですが、 1)キーの動作を設定する   ApplicationオブジェクトのOnKeyメソッドで、キー動作の設定or無効化などの   設定が可能です。  <例>     Application.OnKey "{UP}", ""   '[↑]キーを無効化     Application.OnKey "{UP}"     '[↑]キーを標準動作に戻す 2)入力されたキーの状態を得る(キースキャン)   WindowsAPI関数の"GetAsyncKeyState"などを使用すれば、入力キーの状態   を取得できます。  <例>   グローバルで、     Public Const VK_UP = &H26   '[↑]キーの仮想キーコードの定義     'WinAPI "GetAsyncKeyState"の参照定義     Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vkey As Long) As Long   と宣言しておいて、     Dim iUp As Integer    '[↑]キー検出用     iUp = GetAsyncKeyState(VK_UP) And &H8000   で、[↑]キーの押下状態を取得できます。   ※&H8000は、現在そのキーが押されているか否かを判定するための    ビットマスク値として使用しています。 以上のような方法が利用できるかもしれません。 ■参考サイト VBAマクロ応用講座 API関数 マウス キー イベント GetAsyncKeyState OnKey http://home.att.ne.jp/zeta/gen/excel/c04p07.htm MSDN GetAsyncKeyState 関数 http://msdn.microsoft.com/ja-jp/library/cc364583.aspx 参考までに、上記にあげた過去質問のようなキー制御を行うサンプルマクロを 掲載してみました。 マクロを実行すると、ワークシート上のアクティブなセルが「緑」色の表示になり、 以後、カーソル移動キー(↑、↓、←、→、Enter、Tab、Shift+Enter、Shift+Tab) の操作で、「緑」色のセルが上下左右に移動します。 ※[Esc]キーを押すとマクロが終了します。 注)下記マクロは、Excel2000で作成しましたが、他のバージョンのExcelの場合、   上手く動作するかどうかは判りません。 ■キー制御のサンプルマクロ 注1)このマクロは、「標準モジュール」のコードとして実装して下さい。 注2)インデント等のため、全角スペースを入れています。 /////↓ここから/////////////////////////////////// Option Explicit '仮想キーコードの定義 Public Const VK_SHIFT = &H10  '[Shift]キー Public Const VK_CONTROL = &H11 '[Ctrl]キー Public Const VK_ESCAPE = &H1B '[Esc]キー Public Const VK_TAB = &H9   '[Tab]キー Public Const VK_UP = &H26   '[↑]キー Public Const VK_DOWN = &H28  '[↓]キー Public Const VK_LEFT = &H25  '[←]キー Public Const VK_RIGHT = &H27  '[→]キー Public Const VK_RETURN = &HD  '[Enter]キー Public Const VK_HOME = &H24  '[Home]キー Public Const VK_END = &H23   '[End]キー Public Const VK_PRIOR = &H21  '[PageUp]キー Public Const VK_NEXT = &H22  '[PageDown]キー 'WinAPIの参照定義 Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vkey As Long) As Long Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) ' 'キー操作テスト ' Sub KeyScan()   Dim iKey As Integer   '入力キーの識別コード   Dim iUp As Integer   '[↑]キー検出用   Dim iDown As Integer  '[↓]キー検出用   Dim iLeft As Integer  '[←]キー検出用   Dim iRight As Integer  '[→]キー検出用   Dim iShift As Integer  '[Shift]キー検出用   Dim iEsc As Integer   '[Esc]キー検出用   Dim iTab As Integer   '[Tab]キー検出用   Dim iEnter As Integer  '[Enter]キー検出用   Dim cyMin As Long    'セル位置の最小行   Dim cxMin As Long    'セル位置の最小カラム   Dim cyMax As Long    'セル位置の最大行   Dim cxMax As Long    'セル位置の最大カラム   Dim cy1 As Long     '今回のセル位置(行位置)   Dim cx1 As Long     '今回のセル位置(カラム位置)   Dim cy2 As Long     '前回のセル位置(行位置)   Dim cx2 As Long     '前回のセル位置(カラム位置)   'セル位置の範囲を設定   cyMin = 1        'セル位置の最小行   cyMin = 1        'セル位置の最小カラム   cyMax = Rows.Count   'セル位置の最大行   cxMax = Columns.Count  'セル位置の最大カラム   'アクティブセルの位置を取得   cy1 = ActiveCell.Row   cx1 = ActiveCell.Column   cy2 = cy1   cx2 = cx1   '全セルをクリアする   Range(Cells(1, 1), Cells(Rows.Count, Columns.Count)).Clear   'タイトルバーに処理中メッセージ表示   Application.ActiveWindow.Caption = "【カーソル制御中】- ※[Esc]キーで停止"   '開始セルの選択&カラー設定   Cells(cy1, cx1).Select   Cells(cy1, cx1).Interior.ColorIndex = 4   'カーソル移動関連のキー無効化   Application.OnKey "{PGUP}", ""   '[PageUp]   Application.OnKey "{PGDN}", ""   '[PageDown]   Application.OnKey "{HOME}", ""   '[Home]   Application.OnKey "{END}", ""    '[End]   Application.OnKey "^{HOME}", ""   '[Ctrl]+[Home]   Application.OnKey "^{END}", ""   '[Ctrl]+[End]   Application.OnKey "^{UP}", ""    '[Ctrl]+[↑]   Application.OnKey "^{DOWN}", ""   '[Ctrl]+[↓]   Application.OnKey "^{LEFT}", ""   '[Ctrl]+[←]   Application.OnKey "^{RIGHT}", ""  '[Ctrl]+[→]   Application.OnKey "+{PGUP}", ""   '[Shift]+[PageUp]   Application.OnKey "+{PGDN}", ""   '[Shift]+[PageDown]   Application.OnKey "+{HOME}", ""   '[Shift]+[Home]   Application.OnKey "+{END}", ""   '[Shift]+[End]   Application.OnKey "+{UP}", ""    '[Shift]+[↑]   Application.OnKey "+{DOWN}", ""   '[Shift]+[↓]   Application.OnKey "+{LEFT}", ""   '[Shift]+[←]   Application.OnKey "+{RIGHT}", ""  '[Shift]+[→]   Application.OnKey "+^{HOME}", ""  '[Shift]+[Ctrl]+[Home]   Application.OnKey "+^{END}", ""   '[Shift]+[Ctrl]+[End]   Application.OnKey "+^{UP}", ""   '[Shift]+[Ctrl]+[↑]   Application.OnKey "+^{DOWN}", ""  '[Shift]+[Ctrl]+[↓]   Application.OnKey "+^{LEFT}", ""  '[Shift]+[Ctrl]+[←]   Application.OnKey "+^{RIGHT}", ""  '[Shift]+[Ctrl]+[→]   Application.OnKey "%{PGUP}", ""   '[Alt]+[PageUp]   Application.OnKey "%{PGDN}", ""   '[Alt]+[PageDown]   'エラー処理の設定(エラー発生時の停止回避)   On Error Resume Next   'ループ処理1:全体処理([Esc]キーが押されるまでループ)   Do While (1)     'ループ処理2:キー入力監視(指定のキーが押されるまでループ)     iKey = 0  '入力キーの識別コードをリセット     Do       '入力キー検出       iEsc = GetAsyncKeyState(VK_ESCAPE) And &H8000       iUp = GetAsyncKeyState(VK_UP) And &H8000       iDown = GetAsyncKeyState(VK_DOWN) And &H8000       iLeft = GetAsyncKeyState(VK_LEFT) And &H8000       iRight = GetAsyncKeyState(VK_RIGHT) And &H8000       iEnter = GetAsyncKeyState(VK_RETURN) And &H8000       iTab = GetAsyncKeyState(VK_TAB) And &H8000       iShift = GetAsyncKeyState(VK_SHIFT) And &H8000       '入力キーの識別コードセット       If iEsc Then         iKey = 99  '[Esc]       ElseIf iUp Then         iKey = 1  '[↑]       ElseIf iDown Then         iKey = 2  '[↓]       ElseIf iLeft Then         iKey = 3  '[←]       ElseIf iRight Then         iKey = 4  '[→]       ElseIf iEnter And Not iShift Then         iKey = 5  '[Enter]       ElseIf iEnter And iShift Then         iKey = 6  '[Shift]+[Enter]       ElseIf iTab And Not iShift Then         iKey = 7  '[Tab]       ElseIf iTab And iShift Then         iKey = 8  '[Shift]+[Tab]       End If       'システムに制御を渡す(※溜まっているメッセージの処理)       DoEvents     Loop While iKey = 0  '指定キーの入力が無ければループ '@@:DBG     'デバッグ表示:イミディエイトウィンドウにキー識別コードを表示     Debug.Print "iKey=" & iKey '@@:DBG     '[Esc]キーが押されたらループを抜ける     If iKey = 99 Then Exit Do     '今回のセル位置取得     cy1 = ActiveCell.Row     cx1 = ActiveCell.Column     'セル位置が変わったら表示更新     If cy1 <> cy2 Or cx1 <> cx2 Then       '前回セル位置のカラーをクリアして、今回セル位置のカラーをセット       Cells(cy2, cx2).Interior.ColorIndex = xlNone       Cells(cy1, cx1).Interior.ColorIndex = 4       'セル位置のセーブ(前回値へ)       cy2 = cy1       cx2 = cx1     End If   Loop   'エラー処理の解除   On Error GoTo 0   '前回セル位置のカラーをクリア   Cells(cy2, cx2).Interior.ColorIndex = xlNone   'タイトルバーの表示を戻す   Application.ActiveWindow.Caption = ThisWorkbook.Name   'キー無効化の解除   Application.OnKey "{PGUP}"   '[PageUp]   Application.OnKey "{PGDN}"   '[PageDown]   Application.OnKey "{HOME}"   '[Home]   Application.OnKey "{END}"    '[End]   Application.OnKey "^{HOME}"   '[Ctrl]+[Home]   Application.OnKey "^{END}"   '[Ctrl]+[End]   Application.OnKey "^{UP}"    '[Ctrl]+[↑]   Application.OnKey "^{DOWN}"   '[Ctrl]+[↓]   Application.OnKey "^{LEFT}"   '[Ctrl]+[←]   Application.OnKey "^{RIGHT}"  '[Ctrl]+[→]   Application.OnKey "+{PGUP}"   '[Shift]+[PageUp]   Application.OnKey "+{PGDN}"   '[Shift]+[PageDown]   Application.OnKey "+{HOME}"   '[Shift]+[Home]   Application.OnKey "+{END}"   '[Shift]+[End]   Application.OnKey "+{UP}"    '[Shift]+[↑]   Application.OnKey "+{DOWN}"   '[Shift]+[↓]   Application.OnKey "+{LEFT}"   '[Shift]+[←]   Application.OnKey "+{RIGHT}"  '[Shift]+[→]   Application.OnKey "+^{HOME}"  '[Shift]+[Ctrl]+[Home]   Application.OnKey "+^{END}"   '[Shift]+[Ctrl]+[End]   Application.OnKey "+^{UP}"   '[Shift]+[Ctrl]+[↑]   Application.OnKey "+^{DOWN}"  '[Shift]+[Ctrl]+[↓]   Application.OnKey "+^{LEFT}"  '[Shift]+[Ctrl]+[←]   Application.OnKey "+^{RIGHT}"  '[Shift]+[Ctrl]+[→]   Application.OnKey "%{PGUP}"   '[Alt]+[PageUp]   Application.OnKey "%{PGDN}"   '[Alt]+[PageDown] End Sub /////↑ここまで/////////////////////////////////// ※添付画像は、上記マクロ実行中のExcelブックのキャプチャ画像です。 以上です。参考になれば幸いです。

okWaveMebi
質問者

お礼

ありがとうございます。 上記のようなメソッド、APIを使って行っていました。 そして、VBAでセル移動をコントロールしていた(ENTER,SHIFT+TAB)手前、 矢印キーの動きがどうもおかしい現象が発生し、 矢印キーの制御をVBAでなく EXCELの本来の制御で行うようにしました。 よって、VBA内のWorkSheet_SelectionChange()から 矢印キーを検知したら このイベントから抜けてEXCEL側に制御させるようにしました。