- ベストアンサー
KMmacro.exeをエクセルマクロでで自動操縦
現在、KMmacro.exeを常駐モードで、Ctrl + Shift + a ~ z までのHOTキー割り当てをし、JoyToKeyを使い操縦してます。それを、エクセルのマクロ機能で自動操縦する方法を教えてください。たとえば、G7のセルデーターがリアルタイムで変化しています。そのG7セルの値が55になったときに Ctrl + Shift + a という作業を手押しではなく、エクセルから自動で実行させる方法を教えてください。マクロは初心者です。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 (1) >グリーンで囲んである所の高値と安値を検知する方法はありますか? >図では、たまたま高値+40と安値+25が出ていますが、どの数値で出るかは決まっていません。 おそらくは、横軸は、時間ですよね。例えば、時間で取るとしたら、 基本的には、MAX と MIN を使いますが、その範囲の区切りを、時間で行います。(図参照) 最大値 C4 =MAX(INDEX(A:B,MATCH($C$2,A:A,1),2):INDEX(A:B,MATCH($D$2,A:A,1),2)) 最小値 D4 =MIN(INDEX(A:B,MATCH($C$2,A:A,1),2):INDEX(A:B,MATCH($D$2,A:A,1),2)) そうでない場合。 例えば、急激に上がった後に、値が下がったという範囲を監視する質問は、見たことはあるのですが、私には、手がけたことがありません。特別にアルゴリズムが必要のようです。 (2) OnTime メソッドを使用します。 '-------------------------------------- '別の標準モジュールにおいてください。 '実行は、フォームボタンを付けるとよいです。 Dim myTime As Date Dim flg As Boolean Sub Ontime_Set() 'トグルになっている If flg = False Then flg = True myTime = Now + TimeSerial(0, 0, 10) ElseIf flg = True Then flg = False Else Exit Sub End If If Range("A1").Value = "" Then Range("A1").Value = Format(Now, "hh:mm:ss") '時間記録(スタート) Range("A1").Offset(, 1).Value = Range("G7").Value 'G7 の値 End If Application.OnTime EarliestTime:=myTime, _ Procedure:="my_Procedure", Schedule:=flg If flg = False Then myTime = 0 End If End Sub Sub my_Procedure() With Range("A65536").End(xlUp).Offset(1) .Value = Format(Now, "hh:mm:ss") '時間記録 .Offset(, 1).Value = Range("G7").Value 'G7 の値 flg = False myTime = 0 End With Call Ontime_Set End Sub Sub Ontime_Reset() 'タイマーリセット On Error Resume Next Application.OnTime EarliestTime:=myTime, _ Procedure:="my_Procedure", Schedule:=False If Err.Number > 0 Then MsgBox "OnTime設定はされていません。", 64 Err.Clear flg = False Else MsgBox myTime & "の設定は解除されました。", 64 flg = False myTime = Empty End If End Sub
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 >MiniSpy というツールをインストールしましたが、 >何をするツールか良く分かりません。 #3 のコードとMiniSpy の使い方。 Private Sub Command1_Click() Dim strClassName As String Dim rtn As Long strClassName = "IEFrame" '*←インターネットの場合。 ' strClassName = "XLMAIN" '←Excelの場合。 rtn = FindWindow(strClassName, vbNullString) If rtn <> 0& Then MsgBox "既に起動しております。" Exit Sub End If End Sub strClassName = "IEFrame" '←インターネットの場合。 ' strClassName = "XLMAIN" '←Excelの場合。 MiniSpy で、"IEFrame" などのハンドルを取るために使います。ハンドルが取れないものもありますから、必ずしも完全ではありませんが、図にありますように、ソフトの□のところをドラッグして、別のソフトの一番上のところに持っていくと、名前が出てきます。 これを使えば、少なくとも、二重起動は避けられるのではないか、と思っています。
補足
Wendy02さん 丁寧にありがとうございます。 実際の数値の動きを図解しました。 追加で2つほど質問したいのですが、 質問(1) グリーンで囲んである所の高値と安値を検知する方法はありますか? 図では、たまたま高値+40と安値+25が出ていますが、どの数値で 出るかは決まっていません。 質問(2) リアルタイムで動いているG7の数値を1分刻みで自動記録する方法は ありますか? すみません!よろしくお願いします。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 添付の図をみてください。 値動きが図のようなら可能ですが、さて、値動きが、インクリメンタル・デクリメンタル(定量増加・定量減少)するなら、良いのですが、ランダムの数値では難しいです。#3 の説明は、後でつけます。やはり、#3のコードは万が一に使えたほうがよいと思います。 数値の上下に関して、作ってみました。マイナス値に関しては、詳しくは調べていません。 'Option Explicit Private Const sEXE = "C:\マウスabc\kmmacro\KMmacro.exe" Private Const sAF = "C:\マウスabc\kmmacro\aaa.MAC" Private Const sBF = "C:\マウスabc\kmmacro\bbb.MAC" Private Const sCF = "C:\マウスabc\kmmacro\ccc.MAC" Private Const sEF = "C:\マウスabc\kmmacro\eee.MAC" Private Const sFF = "C:\マウスabc\kmmacro\fff.MAC" Private Const sGF = "C:\マウスabc\kmmacro\ggg.MAC" Dim intFlg As Integer Dim flg1 As Boolean Dim flg2 As Boolean Private Sub Worksheet_Calculate() Dim num As Integer num = Range("G7").Value If num = 55 And num > 0 And flg1 = False Then flg1 = True ElseIf num < 0 Then flg1 = False End If If num = -55 And num > 0 And flg2 = False Then flg2 = True ElseIf num > 0 Then flg2 = False End If If num = 45 And flg1 Then Shell (sEXE & " /FILE=" & sAF) intFlg = 1 ElseIf num = 60 And flg1 And intFlg <= 1 Then Shell (sEXE & " /FILE=" & sBF) intFlg = 2 ElseIf num = 5 And flg1 And intFlg = 1 Then Shell (sEXE & " /FILE1=" & sCF) flg1 = False intFlg = 0 End If If num = -45 And flg2 Then Shell (sEXE & " /FILE=" & sEF) intFlg = 1 ElseIf num = -60 And flg2 And intFlg <= 1 Then Shell (sEXE & " /FILE=" & sFF) intFlg = 2 ElseIf num = -5 And flg2 Then Shell (sEXE & " /FILE=" & sGF) flg2 = False intFlg = 0 End If End Sub
補足
参考図を添付します。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 >終了の書き込みとか、終了のサインを出せませんか? 方法はいくつもありますが、やってみなくてはわからないものがあります。 ただ、不思議なことに、リアルタイムにデータが入ってくるとしても、一時、パラレロに動いているのですね。片方が動いているときは、リアルタイムにデータが入ってこなければよいのですが、そうでもないようです。 Sample を置いておきます。 'モジュールの最上段に置く Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Private Sub Command1_Click() Dim strClassName As String Dim rtn As Long strClassName = "IEFrame" '←インターネットの場合。 ' strClassName = "XLMAIN" '←Excelの場合。 rtn = FindWindow(strClassName, vbNullString) If rtn <> 0& Then MsgBox "既に起動しております。" Exit Sub End If End Sub http://www.vector.co.jp/soft/win95/prog/se291933.html MiniSpy というツールを使って、フレームのところを調べると、IEFrameやXLMAIN という名前が取れますので、それを、strClassName に入れてあげます。必ずしも取れるとは限りませんが、取れれば、起動状態は調べられます。上記のマクロが動かせれば、次の段階に進められます。
補足
Wendy02さん いろいろアドバイスありがとうございます。 MiniSpy というツールをインストールしましたが、 何をするツールか良く分かりません。 すみません。知識不足で・・・ ------------------------------------------------------------ flg = True '<---ここを加えればよいのですが……しかし問題あり ------------------------------------------------------------ 上記のプログラムを使うための別案ですが、 G7が5刻みで(+130 ~ -130)を往復しています。 たとえば、 数値が+の場合の処理 数値が上昇して+55を付け(+60に成らずに)+45まで戻ってきた時、A処理をさせる。 その後、+60を付けたらB処理をさせる。 そして、+5に成ったらC処理をさせる。 C処理が終わった時に一回きりの状態を元の状態に回復させる。 数値がプラスの場合の処理 数値が上昇して+55を付け(+60に成らずに)+45まで戻ってきた時、A処理をさせる。 その後、+60を付けたらB処理をさせる。 そして、+5に成ったらC処理をさせる。 C処理が終わった時に一回きりの状態を元の状態に回復させる。 数値がマイナスの場合の処理 数値が下降して-55を付け(-60に成らずに)-45まで戻ってきた時、E処理をさせる。 その後、-60を付けたらF処理をさせる。 そして、-5に成ったらG処理をさせる。 G処理が終わった時に一回きりの状態を元の状態に回復させる。 ということが出来ますか。 すみません。難題で・・・
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 画面のAppActivate が必要だと思っていたので、まさか、動くとは思わなかったです! >行ったり来たりしているのですが、G7が55になったとたん >何度も作業を実行してしまいます。 そうですね。今の設定ですと、繰り返してしまいます。 もともとも、二重起動しなうような設定は考えられていたのです。 If flg = True Then Exit Sub '←これがスイッチです。 このスイッチが、True の状態になっているときは、次の仕事をさせないわけですから、 '-------------------------------------------- Private Const sEXE = "C:\マウスabc\kmmacro\KMmacro.exe" Private Const sF = "C:\マウスabc\kmmacro\aaa.MAC" Dim flg As Boolean Private Sub Worksheet_Calculate() If flg = True Then Exit Sub '<---------ここで分岐 If Range("G7").Value = 55 Then flg = True '<------------------------ここを加えればよいのですが……しかし問題あり Shell (sEXE & " /FILE=" & sF) ''Shell "C:\マウスabc\kmmacro\KMacro.exe " & "C:\マウスabc\kmmacro\aaa.mac" End If End Sub '------------------------------------------------- flg =False に戻さない限りは、こうすると、一回きりになってしまいます。 >一度実行したら次の処理が終わるまでは Excelとは別に動いているということですよね。何か、終了の書き込みとか、終了のサインを出せませんか?何でもよいです。 例えば、 Range("A10").Value = True こういう新しいファイルが出来るとかでもよいです。 また、1分は二重起動させない、という方法でも可能ですが、確実性がありません。 他にも、二重起動させない専門的な方法もあるけれども、アプリケーションを別に動かしているとなると、そのアプリケーションのハンドルを取るとか、アプリケーションの名前が常駐しているかどうか、取る方法もありますが、私が持っていればよいのですが、手元にないと難しくなります。
補足
Wendy02さん ------------------------------------------------- 終了の書き込みとか、終了のサインを出せませんか? ------------------------------------------------- すみません 記入されていることをトライしてますが なかなか答えが出ません。 上記のサインをどのように出すか、考案中です。 めんどうをかけます。 よろしくお願いします。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 ここの掲示板は、フリーソフトのサポートではありませんが、 Excelの適当のセルに、=NOW() として、 Excel VBA側からは、シートモジュールで、以下のようなイベントで、 Private Const sEXE = "C:\PROGRA~1\kmmacro\KMmacro.exe" Private Const sF = "C:\PROGRA~1\kmmacro\test1.MAC" Dim flg As Boolean Private Sub Worksheet_Calculate() If flg = True Then Exit Sub If Range("G7").Value =55 Then Shell (sEXE & " /FILE=" & sF) ''Shell "[パス名]\KMacro.exe " & "[パス名]\マクロのファイル名.mac" End If End Sub とすればよいはずです。しかし、Excel内部からでは、Ctrl + Shift + a は、やってみないとなんともいえないと思います。理由は、アクティブになっているソフトウェアに対して、命令が送られるからです。だから、アクティブになっているソフトウェァを換えなくてはならないかもしれません。 また、Sendkey "^+a" で、キーコードそのものは送れるはずです。
お礼
Wendy02さん ありがとうございます。 --------------------------------------------------- Private Const sEXE = "C:\マウスabc\kmmacro\KMmacro.exe" Private Const sF = "C:\マウスabc\kmmacro\aaa.MAC" Dim flg As Boolean Private Sub Worksheet_Calculate() If flg = True Then Exit Sub If Range("G7").Value = 55 Then Shell (sEXE & " /FILE=" & sF) ''Shell "C:\マウスabc\kmmacro\KMacro.exe " & "C:\マウスabc\kmmacro\aaa.mac" End If End Sub ----------------------------------------------- 上記のようにしたら、うまくできました。 すばらしいです。最初は試行錯誤してなかなかうまく作動しなくて・・・自信をなくしていました。 しかし、出来たときは感激しました。ありがとうございます。 すみません!またお願いですが G7の値が+130~-130の間を 行ったり来たりしているのですが、G7が55になったとたん 何度も作業を実行してしまいます。 一度実行したら次の処理が終わるまではG7が55になっても 実行しない方法はありますか? Ctrl + Shift + a HOTキー割り当てはしなくて済みました。 作業命令はaaa.macに書き込むことでちゃんと動いています。 すみません!よろしくお願いします。
お礼
Wendy02さん 色々教えていただきほんとうにありがとうございます。 VBAは初心者なのでその記述がなかなか理解出来ないところが多々ありますが、ついていけるように、頑張ります。 ありがとうございます。
補足
Wendy02さん 二週間奮闘しているのですが、 === Excelとは別に動いているということですよね。何か、終了の書き込みとか、終了のサインを出せませんか?何でもよいです。=== 上記の答えが今でも出せない状況です。 もしかしたらと思い、 KMmacro.exeを使ってソフトを操作しているためそのソフトメーカーに 処理が終わったと言う信号が取れるように出来ますか?と問い合わせた所、対応出来ないと言われました。 MiniSpy で使用ソフトのHWND、Class、Caption,RECTが取れますがそれを使って処理が終わったと言う信号みたいなのが取れるのでしょうか? 前回の自動記録には非常に満足してます。ありがとうございます。 さらに記録拡張 V8,W8,X8,Y8,Z8,のデーターも記録したいのですがその方法を教えてくださいお願いします。 それから === 基本的には、MAX と MIN を使いますが、その範囲の区切りを、時間で行います。(図参照) === 最大値 C4 =MAX(INDEX(A:B,MATCH($C$2,A:A,1),2):INDEX(A:B,MATCH($D$2,A:A,1),2)) 最小値 D4 =MIN(INDEX(A:B,MATCH($C$2,A:A,1),2):INDEX(A:B,MATCH($D$2,A:A,1),2)) 上記の延長での質問ですが、下記のようにしたいのです。 (1)Am9:00から記録開始しAm11:00で記録終了 (2)Pm12:30から記録開始しPm15:10で記録終了 (3)記録方法は10分間隔で 始値、高値、安値、終値、を記録する 参考図を添付します。 よろしくお願いいたします。