Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


359 / 13645 ツリー ←次へ | 前へ→

【80812】十字キーで色をつけたセルの移動の方法 SHUN 19/5/16(木) 18:40 質問[未読]
【80813】Re:十字キーで色をつけたセルの移動の方法 亀マスター 19/5/16(木) 19:35 回答[未読]
【80814】Re:十字キーで色をつけたセルの移動の方法 SHUN 19/5/16(木) 20:20 質問[未読]
【80824】Re:十字キーで色をつけたセルの移動の方法 亀マスター 19/5/17(金) 23:18 回答[未読]
【80830】Re:十字キーで色をつけたセルの移動の方法 SHUN 19/5/18(土) 12:37 お礼[未読]
【80815】Re:十字キーで色をつけたセルの移動の方法 hatena 19/5/16(木) 21:50 回答[未読]
【80831】Re:十字キーで色をつけたセルの移動の方法 SHUN 19/5/18(土) 12:38 お礼[未読]

【80812】十字キーで色をつけたセルの移動の方法
質問  SHUN  - 19/5/16(木) 18:40 -

引用なし
パスワード
   VBA初心者です。

初期位置に黄色で色をつけたセルを、十字キーで押すことにより
移動させるプログラムを組みたいです。(簡単なゲームの自機の操作みたいなイメージです)

以下自作ソースになります。

---

Sub 練習()

Dim i As Integer

Dim j As Integer


  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
  Select Case keycode
    Case vbKeyLeft
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    Case vbKeyUp
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    Case vbKeyRight
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j + 1
    Cells(i, j).Interior.ColorIndex = 6
    
    Case vbKeyDown
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i + 1
    Cells(i, j).Interior.ColorIndex = 6
    
  End Select


End Sub

---

初期場所(10,10)を黄色に塗って、例えば左を押したら(10,10)を無色にして
(9,10)に黄色をつけるイメージで作成しましたが、何の反応もありません。

ご教授よろしくお願いいたします。

【80813】Re:十字キーで色をつけたセルの移動の方法
回答  亀マスター  - 19/5/16(木) 19:35 -

引用なし
パスワード
   この手のプログラムを組むときは、次のようにループ処理で実現します。

Do

  '押しているキーを取得

  'キーコードに応じた動作

  'ループを抜けるための処理

Loop

現在提示されたコードで問題なのは、
1.ループしていないのでプログラム中で1回キーコードを判定したら終了する
2.そもそも入力状況が取得できていない(?)

入力状況の取得方法はいくつかありますが、Windows APIを使うのがわかりやすいと思います。
ht tps://excel-excel.com/tips/vba_305.html

なお、注意点として、ループ中にループを抜けるためのコードを入れておいてください。でないと、無限ループで終わらなくなります。
ループを抜ける方法は何でもいいですが、エスケープキーが押されたら抜けるというのがよく見られます。
If 【エスケープキーが押されている】 Then Exit Do
という感じにすればいいでしょう。

あと、VBEの設定で「変数の宣言を強制する」にチェックを入れておいた方がいいですよ。
これを入れておくと、コード中に「Option Explicit」が自動で入り、未定義の変数を使用するとエラーが発生してわかるようになりますが、変数を強制しない状態はバグの温床になります。
実際、
Select Case keycode
の「keycode」って、どこにも宣言してませんよね?

【80814】Re:十字キーで色をつけたセルの移動の方法
質問  SHUN  - 19/5/16(木) 20:20 -

引用なし
パスワード
   亀マスターさん
ご回答ありがとうございます。
初心者につき、変数の取得、というのがよくわかっていませんが、色々ググって以下のように修正してみました。
が、”ユーザー定義型が定義されていません”というエラーがでます。
なぜでしょうか?
---
Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As LongLong

Sub 練習()

Dim i As Integer

Dim j As Integer


  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
 Do
    If GetAsyncKeyState(37) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(38) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(39) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j + 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(40) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i + 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(13) <> 0 Then
    
    Exit Do
    
    End If
    
  Loop
  

End Sub

---

よろしくお願いいたします。

▼亀マスター さん:
>この手のプログラムを組むときは、次のようにループ処理で実現します。
>
>Do
>
>  '押しているキーを取得
>
>  'キーコードに応じた動作
>
>  'ループを抜けるための処理
>
>Loop
>
>現在提示されたコードで問題なのは、
>1.ループしていないのでプログラム中で1回キーコードを判定したら終了する
>2.そもそも入力状況が取得できていない(?)
>
>入力状況の取得方法はいくつかありますが、Windows APIを使うのがわかりやすいと思います。
>ht tps://excel-excel.com/tips/vba_305.html
>
>なお、注意点として、ループ中にループを抜けるためのコードを入れておいてください。でないと、無限ループで終わらなくなります。
>ループを抜ける方法は何でもいいですが、エスケープキーが押されたら抜けるというのがよく見られます。
>If 【エスケープキーが押されている】 Then Exit Do
>という感じにすればいいでしょう。
>
>あと、VBEの設定で「変数の宣言を強制する」にチェックを入れておいた方がいいですよ。
>これを入れておくと、コード中に「Option Explicit」が自動で入り、未定義の変数を使用するとエラーが発生してわかるようになりますが、変数を強制しない状態はバグの温床になります。
>実際、
>Select Case keycode
>の「keycode」って、どこにも宣言してませんよね?

【80815】Re:十字キーで色をつけたセルの移動の方法
回答  hatena  - 19/5/16(木) 21:50 -

引用なし
パスワード
   すでに回答で出てますが別案です。

ユーザーフォームを作成します。
名前は、UserForm1 とします。

ユーザーフォームのモジュールを下記のように記述します。

Option Explicit
Dim r As Range

Private Sub UserForm_Initialize()
  Me.StartUpPosition = 0
  Me.Left = 0 - Me.Width - 10
  Set r = Cells(10, 10)
  r.Interior.ColorIndex = 6
End Sub

Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  Dim r1 As Range
  Set r1 = r
  r1.Interior.ColorIndex = xlNone
  Select Case KeyCode
  Case vbKeyLeft
    If r.Column > 1 Then Set r1 = r.Offset(, -1)
  Case vbKeyUp
    If r.Row > 1 Then Set r1 = r.Offset(-1)
  Case vbKeyRight
    If r.Column < 20 Then Set r1 = r.Offset(, 1)
  Case vbKeyDown
    If r.Row < 20 Then Set r1 = r.Offset(1)
  Case vbKeyEscape
    Unload Me
    Exit Sub
  End Select
  r1.Interior.ColorIndex = 6
  Set r = r1
End Sub


シート上に、ユーザーフォームのボタンを配置して、
下記のマクロを登録します。

Sub ボタン1_Click()
  UserForm1.Show
End Sub

これで、ボタンをクリックすると、Cells(10, 10) が黄色になり、
矢印キーで黄色のセルが移動します。
ESCキーを押すと、終了します。


やっていることは、ユーザーフォームをウィンドウの外に移動させて見えないようにして、
キーボード入力はユーザーフォームで受け取るようにしてます。

【80824】Re:十字キーで色をつけたセルの移動の方法
回答  亀マスター  - 19/5/17(金) 23:18 -

引用なし
パスワード
   >”ユーザー定義型が定義されていません”というエラーがでます。

Declare Function から始まるAPIの宣言で、最後に As LongLong としているのが原因です。
LongLongは数値型ですが、これは64bti Officeの環境でしか使えません。
通常は32bitのOfficeを使っていると思われるので、LongLongではなくIntegerを使ってください。

−−−−−−−−−−−−−−−−

なお、それを修正したとしても、いくつか問題が発生することが予想されます。

1.始まるとキーボードの入力を受け付けなくなる
2.1回どれかのキーを押しただけで何十個分も先のセルの色が変わる
3.特定の条件で「アプリケーション定義またはオブジェクトのエラーです」が発生する。

一度実際にやってみて、どんな不具合なのか確認してみることをお勧めしますが、原因と対処法は次のようなものになります。

1.ループを回り続ける間、VBAがパソコンの処理全体を押さえてしまい、他のことができなくなる。
→DoEventsという処理があるので、使い方を調べてみてください。

2.ユーザーは1回だけキーを押したつもりでも、プログラムではループが一瞬で何十周もするので、押していた間にループした回数分だけそのキーが連続で押されたことになる。
→ループのたびに、直前のループでキーが押されていたかどうかをチェックし、押されていればそのループでは処理を行わないようにする。
具体的には、適当な変数(たとえばKeyOn)に、キーが押されたときの処理でTrueを代入し、どのキーも押されていなければFalseを代入する、という処理をとります。

3.変数i、jの値が0以下になった場合に発生します。このとき、Cells(i, j)で0行目や0列目のセルを指定することになるので、そんなものはないからとエラーになるのです。
iやjの値を変更するとき、変更後の結果が0以下になる場合は1にするといった対応が必要です。

以上、実際にやってみてわからないところがあれば、追加で質問してください。

【80830】Re:十字キーで色をつけたセルの移動の方法
お礼  SHUN  - 19/5/18(土) 12:37 -

引用なし
パスワード
   亀マスターさん

ありがとうございます。
以下のように組んでみたところ、上手くいきました。ありがとうございました。

  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
    
 Do
    '自機発生、操作
    
    If GetAsyncKeyState(37) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If j <= 3 Then
      j = 17
      Else
      j = j - 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(38) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If i <= 3 Then
      i = 17
      Else
      i = i - 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(39) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If j >= 17 Then
      j = 3
      Else
      j = j + 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(40) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If i >= 17 Then
      i = 3
      Else
      i = i + 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(13) <> 0 Then
    
    Exit Do
    
    End If
    
  DoEvents
  
  Sleep 90
  
  Loop
  

End Sub

【80831】Re:十字キーで色をつけたセルの移動の方法
お礼  SHUN  - 19/5/18(土) 12:38 -

引用なし
パスワード
   ありがとうございます。
初心者なのでユーザーフォームとは?となってしまいましたが、
別解も理解したほうが後々幅が広がると思うので、勉強しようと思います。
ありがとうございました。

359 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free