ExcelVBAで、キーボード方向キーを押したら、その方向に塗りつぶしたセルを移動させたいです。
とりあえず、以下のようなマクロを組んだのですが、
方向キーを一度でも押すと、押した方向の彼方へ一瞬で飛んでいってしまいます。
Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long 'キー入力のAPI
'一番最初に塗りつぶすセル
set 塗りつぶし = Range("B2,C2")
do
塗りつぶし.Interior.ColorIndex = 3 '赤く塗りつぶし
'左入力したら塗りつぶしセルを左に移動
If GetAsyncKeyState(37) Then
塗りつぶし.Interior.ColorIndex = 0
Set 塗りつぶし = 塗りつぶし.Offset(0, -1)
End If
'右入力したら塗りつぶしセルを右に移動
If GetAsyncKeyState(39) <> 0 Then
塗りつぶし.Interior.ColorIndex = 0
Set 塗りつぶし = 塗りつぶし.Offset(0, 1)
End If
Loop
予想なんですが、一度でもキーを入力したら、
その方向へずっと入力しているようになっている
と思うのですが、どう直して良いか分かりません。
宜しくお願いします。
No.4ベストアンサー
- 回答日時:
> ExcelVBAで、キーボード方向キーを押したら、
> その方向に塗りつぶしたセルを移動させたい
何のためにこのマクロを作るのかによって答えは全然違ってきますが、
目的:マクロのお勉強で、背景色をセル移動してみたい
セルを移動: セルのデータではなく背景色だけ移動する
と勝手に仮定してアドバイスをします (^_^)
まず、この目的で GetAsyncKeyState API を使うのは不適切でしょう。
その理由は、いくつか試されたら簡単にわかります。
で、例えばこんな感じでもイケます
以下のコードを目的のシートのコードペイン(モジュールではなくて)
に貼り付けてください。
なお、この例では事前に目的のシートの "D6" を選択し、背景色をつけておいてから試します。
Option Explicit
Dim 初期化済み As Boolean
Dim 直前の色つきセル As Range
Dim 色番号 As Variant
Private Sub 初期設定()
Set 直前の色つきセル = Range("D6") ' ★★★ ここは適当にアレンジしてね
色番号 = 直前の色つきセル.Interior.ColorIndex
初期化済み = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim r0 As Long, c0 As Long, r1 As Long, c1 As Long
If Not 初期化済み Then 初期設定
r0 = Abs(Target.Row - 直前の色つきセル.Row)
c0 = Abs(Target.Column - 直前の色つきセル.Column)
If r0 > 1 Or c0 > 1 Then Exit Sub ' 方向キー以外で移動したときは処理しない
直前の色つきセル.Interior.ColorIndex = xlColorIndexNone
Target.Interior.ColorIndex = 色番号
Set 直前の色つきセル = Target
End Sub
以下、余談ですが
Excel上ではなく Visual Basic 2008ですとか、その他本格的なプログラム言語でつくる Window ならキー入力イベントがありますから、それで方向キー入力をイベントドリブンで処理できます。
しかしExcel上にはその機能がないので、方向キーなど、キー入力に応じて何かするというのは、難しいとおもいます。
なので、ご質問のようなことをなさるには本格的なプログラム言語をお使いになることを薦めます。
No.3
- 回答日時:
ご質問のコードは、イベントの一種で、プロ用のコードです。
失礼ですが、前回の質問内容から、そのコードを扱うような方には見えないのですが。Win32 API関数などには、PrivateやPablic などのステートメントを入れたほうが良いですし、意図的にしているなら別ですが、ColorIndex = 0 や2バイトの変数は関心しません。
私の記憶だけですが、GetAsyncKeyState(37) = 0 は、キーが押されていないという意味ですが、逆に[→]キー以外を押しているという意味にもなりますから、このキーを監視し続けても、解放されないはずです。もちろん、元のコードは、イベントの一種ですから、無限ループが発生させますが、それを利用するなら、RaiseEvent やWin32 API関数のタイマー処理で、イベントの監視が必要なはずです。ここの掲示板では、そのような内容は私にとっても敷居が高いです。RaiseEvent ならともかく、Do ~ Loop型のイベントは、、私はもう何年も作ったことがありません。
もう少しレベルを下げて作ってみました。なお、ActiveCell は、どこにあっても、関係がありません。
'//
'シートモジュール
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
Private Const VK_LEFT = &H25 '[←] 37
Private Const VK_UP = &H26 '[↑] 38
Private Const VK_RIGHT = &H27 '[→] 39
Private Const VK_DOWN = &H28 '[↓] 40
Private PArea As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const mCOLOR As Integer = 3
If PArea Is Nothing Then '初期化
Me.UsedRange.Interior.ColorIndex = xlColorIndexNone
Set PArea = Range("B2:C2")
End If
If GetAsyncKeyState(VK_LEFT) <> 0 Then
If PArea.Cells(1).Column = 1 Then Exit Sub
PArea.Interior.ColorIndex = xlColorIndexNone
Set PArea = PArea.Offset(0, -1)
APaint PArea, mCOLOR
ElseIf GetAsyncKeyState(VK_UP) <> 0 Then
If PArea.Cells(1).Row = 1 Then Exit Sub
PArea.Interior.ColorIndex = xlColorIndexNone
Set PArea = PArea.Offset(-1, 0)
APaint PArea, mCOLOR
ElseIf GetAsyncKeyState(VK_RIGHT) <> 0 Then
If PArea.Cells(PArea.Cells.Count).Column = Columns.Count Then Exit Sub
PArea.Interior.ColorIndex = xlColorIndexNone
Set PArea = PArea.Offset(0, 1)
APaint PArea, mCOLOR
ElseIf GetAsyncKeyState(VK_DOWN) <> 0 Then
If PArea.Cells(PArea.Cells.Count).Row = Rows.Count Then Exit Sub
PArea.Interior.ColorIndex = xlColorIndexNone
Set PArea = PArea.Offset(1, 0)
APaint PArea, mCOLOR
End If
End Sub
Private Sub APaint(rng As Range, clIdx As Integer)
With rng
.Interior.ColorIndex = xlColorIndexNone
.Interior.ColorIndex = clIdx
End With
End Sub
No.2
- 回答日時:
あなたのマクロは意図的に無限ループさせていますが,そのある時に←キーを押します。
あなたが←キーを押して「左入力したら塗りつぶしセルを左に移動」のIFが作動した後,そのキーから完全に指が離れるまで(つまりGetAsyncKeyState(37) が 0 になるまで)の間をそのDo Loopで回し続けて,「←キーが押されました・押されています」を消費し尽くさせます。これが「キーボードバッファをクリア」の意味です。
>例えば以下の書き方だとエラーが出てしまいます。
関数に値を入れようとしても,エラーになります。
1+1 = 2
と書いて「1+1に2を入れる」と書いても,ナンデスカ?となってしまいます。
1+1が2と等しいのか等しくないのか,IF 1+1 = 2 then のように判断式として使えば問題有りません。
No.1
- 回答日時:
1.端っこに辿り着いたら,それ以上先は無いのだから先に行かせないようにすること。
2.キーボードバッファをクリアすること
作成例:
Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long 'キー入力のAPI
sub macro1(_RIght)
'一番最初に塗りつぶすセル
set 塗りつぶし = Range("B2,C2")
do
塗りつぶし.Interior.ColorIndex = 3 '赤く塗りつぶし
'左入力したら塗りつぶしセルを左に移動
If GetAsyncKeyState(37) Then
塗りつぶし.Interior.ColorIndex = 0
if 塗りつぶし.column > 1
Set 塗りつぶし = 塗りつぶし.Offset(0, -1)
end if
End If
Do Until GetAsyncKeyState(37) = 0
Loop
この回答への補足
ありがとうございます。
問題なくできたのですが、
キーボードバッファの部分がイマイチ分かりません。
Do Until GetAsyncKeyState(37) = 0
Loop
例えば以下の書き方だとエラーが出てしまいます。
GetAsyncKeyState(37) = 0
バッファをクリアという意味も、もし宜しかったら教えて下さい。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【VBA】特定のワードが入っている行全体を塗りつぶしたい 4 2022/04/20 15:22
- Visual Basic(VBA) エクセルVBAのコードで質問です。 下のコードはJ16の文字列をB3を起点とする範囲から探して、見つ 5 2023/04/07 11:07
- Visual Basic(VBA) VBA初心者です。 VBAで行単位で条件付き書式の色をカウントしたいです。 大量のデータがあるExc 3 2022/06/08 10:02
- Visual Basic(VBA) VBA初心者です。 VBAで行単位で条件付き書式の色をカウントしたいです。 大量のデータがあるExc 3 2022/06/08 10:00
- Visual Basic(VBA) ExcelVBAのマクロについて。 9 2022/05/04 14:50
- Excel(エクセル) エクセルで教えて下さい。 2 2022/05/18 13:00
- Visual Basic(VBA) VBAについて教えてください。 Excelで セルのB6~BG24でダブルクリックすると ダブルクリ 1 2022/06/02 17:07
- その他(Microsoft Office) エクセル 表の移動 2 2023/04/05 20:29
- 仕事術・業務効率化 マークシートの番号を塗りつぶす時に、ミスって違う番号に塗りつぶしてしまうことがあるのですが、間違えず 3 2022/07/20 09:45
- Visual Basic(VBA) VBAで教えて頂きたいのですが? 1 2022/04/29 02:36
このQ&Aを見た人はこんなQ&Aも見ています
-
新NISA制度は今までと何が変わる?非課税枠の拡大や投資対象の変更などを解説!
少額から投資を行う人のための非課税制度であるNISAが、2024年に改正される。おすすめの銘柄や投資額の目安について教えてもらった。
-
矢印(左右)キーでイベントを発生させたい。
Visual Basic(VBA)
-
Excel vbaでキーの操作の入力
Excel(エクセル)
-
Enterキーでマクロを起動さす。
その他(ソフトウェア)
-
-
4
エクセルVBAで、MsgBox やInputBox は、画面の中央以外に表示させたい。
Excel(エクセル)
-
5
Excel VBA あるセルでENTERを押すと特定のセルへ移動したい
Excel(エクセル)
-
6
VBAでユーザーフォームの表示を確認
Visual Basic(VBA)
-
7
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
8
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【エクセル】IF関数 Aまたは...
-
エクセルで指定したセルのどれ...
-
対象セル内(複数)が埋まった...
-
貼り付けで複数セルに貼り付けたい
-
エクセル 足して割る
-
Excelで数式内の文字色を一部だ...
-
セルをクリック⇒そのセルに入力...
-
エクセルのセルの枠を超えて文...
-
エクセル オートフィルタで絞...
-
Excelでのコメント表示位置
-
excelのCOUNTIF関数で、『範囲=...
-
エクセルの一つのセルに複数の...
-
(Excel)数字記入セルの数値の後...
-
【Excel】 セルの色での判断は...
-
エクセルで第2、第4土曜日を抽...
-
EXCELで優先順位をつけて表示
-
枠に収まらない文字を非表示に...
-
エクセルvba (ByVal Targ...
-
EXCEL VBA セルに既に入...
-
エクセル 数字の前の「00」を...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで指定したセルのどれ...
-
【エクセル】IF関数 Aまたは...
-
対象セル内(複数)が埋まった...
-
エクセル 足して割る
-
Excelで数式内の文字色を一部だ...
-
貼り付けで複数セルに貼り付けたい
-
Excelでのコメント表示位置
-
セルをクリック⇒そのセルに入力...
-
EXCEL VBA セルに既に入...
-
excelのCOUNTIF関数で、『範囲=...
-
【Excel】 セルの色での判断は...
-
エクセル オートフィルタで絞...
-
エクセルのセルの枠を超えて文...
-
(Excel)数字記入セルの数値の後...
-
Excelで、「特定のセル」に入力...
-
エクセルの一つのセルに複数の...
-
複数のセルのいずれかに数字が...
-
excelの特定のセルの隣のセル指...
-
数式を残したまま、別のセルに...
-
ハイパーリンクの参照セルのズ...
おすすめ情報