Excel VBAで「SPAT4自動投票システム」を作ってみました。
最初に書いておきます。
・このプログラムで何か問題が起きても、管理人は責任を負いません。
馬券購入についても当然ですが各個人の問題です。文句言わないでください。
・ある程度の知識がある方を前提にしています。
プログラムの内容についての質問等にはあまり答える気はありません。
わからないことがあれば、各個人でググって調べてください。
・自由に改変とかしてください。これで商売されるのも勝手にやってください。
ただ何の責任もとりません。
ブログなどで紹介するなら『「The Sunday Breeze」のやつを参考にした』程度でも
ひとこと書いてもらえると嬉しいです。強制ではないです。
-----
さて。
JRAのインターネット投票システム「iPAT」には
自動で投票済ませてくれるプログラムがあるんですが
地方競馬用の投票システム(SPAT4、オッズパーク、楽天競馬)には
ネットを探す限り、自動で投票してくれるシステムはないようです。
ということで、今回簡単ではありますが
管理人が長く使っている「SPAT4」で自動投票してくれるプログラムを組みました。
---
基本的な動作と前提条件
・管理人はVBで作っていますが、単独exeで動くかOfficeベースで動くかの違いなので
ExcelのVBAでも動作すると思います。Excelのバージョンによっては使えません。
もしかしたらVB.netでも使えるのかな?(未確認)
・InternetExplorerを使います。Windows10ではオプションでインストールできます。
・当たり前ですが、予想はしません。
予想(買い目)をフォーマットに従ってテキストファイルに書いておくことが前提です。
・公開するソースは「3連複」「3連単」「ワイド」の「フォーメーション」のみを対応としていますが
ほかの券種や買い方も簡単に追加できると思います。
必要な方はご自由に直してください。
・事前にSPAT4への入金はしておいてください(残高不足で投票できないだけですが)
---
こういう予想ファイルを作りましょう。
コース名、レース番号、券種、馬1(ハイフンでつなげる)、馬2、馬3、1点当たりの金額(100円単位)をカンマ区切りで。
同じ形式で複数行記入できます。違う競馬場でも違うレースでも違う券種でも、いっぺんに投票できます。
この場合、1行目は
高知12レースの3連複で
馬1(1列目)が5、馬2(2列目)が3,6,9、馬3(3列目)が1,2,3,7,9,10,11,12で
各100円ずつの購入。
2行目は帯広9レースのワイドの場合
馬1(1列目)に5、馬2(2列目)に3,6,9
馬3がないので、値を入れずにカンマが続くように書きます。
この場合は各200円ずつ(計600円ですかね)
---
最初にInternetExplorerをVBAの中で使える設定をしましょう。
メニューの[ツール]から[参照設定]を開いて
・Microsoft HTML Object Library
・Microsoft Internet Controls
を探してチェックを入れましょう。
それと、ソースの一番最初に次のように書いておきましょう。
Windowsで提供されている標準の関数を使う準備です。
---
ではプログラムをぶつ切りで書いていきます。
最終的につなげれば、動くはずです。
まずは予想ファイルを読み込みます。
「c:\temp」に「votedata_なんとか.csv」という名前で保存している例です。
複数ファイルがあってもいいように、ループさせます。
InternetExplorerを開きます。
ページが完全に表示されるまで待機。
ここで、HTMLのソースを見ればわかりますが
ログインフォーム全体が「LOGIN」
加入者番号は「MEMBERNUMR」、利用者IDは「MEMBERIDR」と名前がついています。
それぞれ値を入れて、ログインボタンを押しましょう。
ページが完全に表示されるまで待機。
ボタンが並んでいる中から、「投票入力」と書かれているボタンを選んでクリックします。
ページが完全に表示されるまで待機。
このページはフレーム構成になっていて
上の黄色が0、赤が左から1,2,3、下の黄色が4
使うのは1,2,3ですかね。
フレームを分割します。
最後の金額入力の準備だけしたら
予想ファイルから1行ずつ見ていきますかね。
フレーム1(左の赤)を見ていきます。
それぞれこういう名前がついています(HTMLにこう書かれています)
まずは「PLACE」というセレクトボックス(コンボボックス)を探して
予想ファイルの1項目目(0)と一致する場名を選択します。
選択したら、JavaScriptのonChangeイベントを実行。
onChangeを実行しないと、レース番号が出てきません。
同じ要領で、次はレース番号。予想ファイルの2項目目(1)
続いて式別。予想ファイルの3項目目(2)
投票方式はフォーメーション固定にしてます。
流しとか追加するなら、同じ要領でできますね。
金額は予想ファイルの7項目目(6)
「KINGAKU」という名前のテキストボックスに値をぶち込むだけです。
ここまでいくと、フレーム2(真ん中の赤)に頭数分のチェックボックスが出てきます。
ここでは
列は馬1「C1」、馬2「C2」、馬3「C3」
んで
行は馬番マイナス1の番号が名前になっています。
馬1の5番なら「C1の4」
馬2の3番と6番と9番なら「C2の2、C2の5、C2の8」
にそれぞれチェックを入れるだけです。
予想ファイルの4項目目(3)をハイフンで分割して、C1の馬番マイナス1にチェック
馬2も同じ。予想ファイルの5項目目(4)をC2列へ。
馬3も同じ。ただ馬連馬単ワイドの場合は、この処理を飛ばすように書いたほうがいいです。
ここまで来たら、
チェックボックスをクリックしたときに動くJavaScriptを呼びます。
馬1の馬番1をクリックしたテイで。(実際にチェックはしません)
このonClickを動かさないと、組数(AMOUNT)が計算されないのです。
これで組数が表示されるので、その数字×金額(合計金額)を控えておきましょう。
んで、フレーム1(左)の「入力決定」ボタンを探して押します。
んで次の行の処理へ。ループ2(ファイルの行があるだけループ)を繰り返します。
すべての行の入力を終えたら、
フレーム3(右)の「投票内容確認へ」のボタンを探して押します。
ただ、このボタンを押すとき
普通に押すと制御が利かなくなりますので(このあとダイアログが出てくるので)
非同期で押すようにしましょう。
非同期でボタンを押したら、ちょっと時間を空けて(2秒)
ダイアログ(「Web ページからのメッセージ」)のウインドウを探してOKボタンを押してあげます。
ページが完全に表示されるまで待機。
これまでと同じやり方ですね。
暗証番号は「MEMBERPASSR」、投票金額は「TOTALMONEYR」という名前になっていますので
それぞれ入れて、「投票する」ボタンを探して押します。
この時も先ほど同様、非同期でボタンを押して、ダイアログのOKボタンまで押しましょう。
ページが完全に表示されるまで待機。
これで投票完了です。
InternetExplorerを閉じて、次のファイルを開く準備をして
ループ1(ファイルがあるだけループ)を繰り返します。
これで終了です。
---
今回作ったのは予想ファイルを使って読み込んで投票する仕組みですが
Excelのセルを読み込んで投票する仕組みも簡単にできると思います。
適当に直して使ってください。
どっちにしても大事なのは
「予想するロジック」(今回でいう「予想ファイルの作り方」)だと思いますので。
・このプログラムで何か問題が起きても、管理人は責任を負いません。
馬券購入についても当然ですが各個人の問題です。文句言わないでください。
・ある程度の知識がある方を前提にしています。
プログラムの内容についての質問等にはあまり答える気はありません。
わからないことがあれば、各個人でググって調べてください。
・自由に改変とかしてください。これで商売されるのも勝手にやってください。
ただ何の責任もとりません。
ブログなどで紹介するなら『「The Sunday Breeze」のやつを参考にした』程度でも
ひとこと書いてもらえると嬉しいです。強制ではないです。
-----
さて。
JRAのインターネット投票システム「iPAT」には
自動で投票済ませてくれるプログラムがあるんですが
地方競馬用の投票システム(SPAT4、オッズパーク、楽天競馬)には
ネットを探す限り、自動で投票してくれるシステムはないようです。
ということで、今回簡単ではありますが
管理人が長く使っている「SPAT4」で自動投票してくれるプログラムを組みました。
---
基本的な動作と前提条件
・管理人はVBで作っていますが、単独exeで動くかOfficeベースで動くかの違いなので
ExcelのVBAでも動作すると思います。Excelのバージョンによっては使えません。
もしかしたらVB.netでも使えるのかな?(未確認)
・InternetExplorerを使います。Windows10ではオプションでインストールできます。
・当たり前ですが、予想はしません。
予想(買い目)をフォーマットに従ってテキストファイルに書いておくことが前提です。
・公開するソースは「3連複」「3連単」「ワイド」の「フォーメーション」のみを対応としていますが
ほかの券種や買い方も簡単に追加できると思います。
必要な方はご自由に直してください。
・事前にSPAT4への入金はしておいてください(残高不足で投票できないだけですが)
---
こういう予想ファイルを作りましょう。
コース名、レース番号、券種、馬1(ハイフンでつなげる)、馬2、馬3、1点当たりの金額(100円単位)をカンマ区切りで。
同じ形式で複数行記入できます。違う競馬場でも違うレースでも違う券種でも、いっぺんに投票できます。
高知,12,三連複,05,03-06-09,01-02-03-07-09-10-11-12,1
帯広,9,ワイド,05,03-06-09,,2
帯広,9,ワイド,05,03-06-09,,2
この場合、1行目は
高知12レースの3連複で
馬1(1列目)が5、馬2(2列目)が3,6,9、馬3(3列目)が1,2,3,7,9,10,11,12で
各100円ずつの購入。
2行目は帯広9レースのワイドの場合
馬1(1列目)に5、馬2(2列目)に3,6,9
馬3がないので、値を入れずにカンマが続くように書きます。
この場合は各200円ずつ(計600円ですかね)
---
最初にInternetExplorerをVBAの中で使える設定をしましょう。
メニューの[ツール]から[参照設定]を開いて
・Microsoft HTML Object Library
・Microsoft Internet Controls
を探してチェックを入れましょう。
それと、ソースの一番最初に次のように書いておきましょう。
Windowsで提供されている標準の関数を使う準備です。
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const WM_COMMAND As Long = &H111&
Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const WM_COMMAND As Long = &H111&
---
ではプログラムをぶつ切りで書いていきます。
最終的につなげれば、動くはずです。
まずは予想ファイルを読み込みます。
「c:\temp」に「votedata_なんとか.csv」という名前で保存している例です。
複数ファイルがあってもいいように、ループさせます。
strPath = "c:\temp\"
strFile = Dir$(strPath & "votedata_*.csv")
Do While strFile <> "" ’ ここからループ1(ファイルがあるだけループ)
fileNo = FreeFile
Open strPath & strFile For Input As #fileNo
strFile = Dir$(strPath & "votedata_*.csv")
Do While strFile <> "" ’ ここからループ1(ファイルがあるだけループ)
fileNo = FreeFile
Open strPath & strFile For Input As #fileNo
InternetExplorerを開きます。
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.navigate "https://www.spat4.jp/keiba/pc"
objIE.Visible = True
objIE.navigate "https://www.spat4.jp/keiba/pc"
ページが完全に表示されるまで待機。
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
DoEvents
Loop
ここで、HTMLのソースを見ればわかりますが
ログインフォーム全体が「LOGIN」
加入者番号は「MEMBERNUMR」、利用者IDは「MEMBERIDR」と名前がついています。
それぞれ値を入れて、ログインボタンを押しましょう。
objIE.document.LOGIN.MEMBERNUMR.Value = "01234567"
objIE.document.LOGIN.MEMBERIDR.Value = "12345678"
objIE.document.LOGIN.submit
objIE.document.LOGIN.MEMBERIDR.Value = "12345678"
objIE.document.LOGIN.submit
ページが完全に表示されるまで待機。
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
ボタンが並んでいる中から、「投票入力」と書かれているボタンを選んでクリックします。
For Each objTag In objIE.document.getElementsByTagName("input")
If InStr(objTag.outerHTML, "投票入力") > 0 Then
objTag.Click
Exit For
End If
Next
If InStr(objTag.outerHTML, "投票入力") > 0 Then
objTag.Click
Exit For
End If
Next
ページが完全に表示されるまで待機。
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
このページはフレーム構成になっていて
上の黄色が0、赤が左から1,2,3、下の黄色が4
使うのは1,2,3ですかね。
フレームを分割します。
Set objFrame = objIE.document.frames
最後の金額入力の準備だけしたら
予想ファイルから1行ずつ見ていきますかね。
Dim Kingaku As Integer
Kingaku = 0
Do While Not EOF(fileNo) ’ ここからループ2(ファイルの行があるだけループ)
Line Input #fileNo, buf
strFileData = Split(buf, ",")
Kingaku = 0
Do While Not EOF(fileNo) ’ ここからループ2(ファイルの行があるだけループ)
Line Input #fileNo, buf
strFileData = Split(buf, ",")
フレーム1(左の赤)を見ていきます。
それぞれこういう名前がついています(HTMLにこう書かれています)
まずは「PLACE」というセレクトボックス(コンボボックス)を探して
予想ファイルの1項目目(0)と一致する場名を選択します。
選択したら、JavaScriptのonChangeイベントを実行。
onChangeを実行しないと、レース番号が出てきません。
For Each slt In objFrame(1).document.getElementsByTagName("select")
If slt.Name = "PLACE" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = strFileData(0) Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
If slt.Name = "PLACE" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = strFileData(0) Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
同じ要領で、次はレース番号。予想ファイルの2項目目(1)
For Each slt In objFrame(1).document.getElementsByTagName("select")
If slt.Name = "RACE" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = strFileData(1) Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
If slt.Name = "RACE" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = strFileData(1) Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
続いて式別。予想ファイルの3項目目(2)
For Each slt In objFrame(1).document.getElementsByTagName("select")
If slt.Name = "SHIKI" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = strFileData(2) Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
If slt.Name = "SHIKI" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = strFileData(2) Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
投票方式はフォーメーション固定にしてます。
流しとか追加するなら、同じ要領でできますね。
For Each slt In objFrame(1).document.getElementsByTagName("select")
If slt.Name = "HOUSHIKI" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = "フォーメーション" Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
If slt.Name = "HOUSHIKI" Then
For Each opt In slt.getElementsByTagName("option")
If opt.Text = "フォーメーション" Then
opt.Selected = True
slt.onchange
Exit For
End If
Next
End If
Next
金額は予想ファイルの7項目目(6)
「KINGAKU」という名前のテキストボックスに値をぶち込むだけです。
txtKin = objFrame(1).document.getElementsByName("KINGAKU")
txtKin.Value = strFileData(6)
sleep 1000 ’ 1秒待機
txtKin.Value = strFileData(6)
sleep 1000 ’ 1秒待機
ここまでいくと、フレーム2(真ん中の赤)に頭数分のチェックボックスが出てきます。
ここでは
列は馬1「C1」、馬2「C2」、馬3「C3」
んで
行は馬番マイナス1の番号が名前になっています。
馬1の5番なら「C1の4」
馬2の3番と6番と9番なら「C2の2、C2の5、C2の8」
にそれぞれチェックを入れるだけです。
予想ファイルの4項目目(3)をハイフンで分割して、C1の馬番マイナス1にチェック
splittedResult = Split(strFileData(3), "-")
For Each output In splittedResult
objFrame(2).document.getElementsByName("C1")(output - 1).Checked = True
Next
For Each output In splittedResult
objFrame(2).document.getElementsByName("C1")(output - 1).Checked = True
Next
馬2も同じ。予想ファイルの5項目目(4)をC2列へ。
splittedResult = Split(strFileData(4), "-")
For Each output In splittedResult
objFrame(2).document.getElementsByName("C2")(output - 1).Checked = True
Next
For Each output In splittedResult
objFrame(2).document.getElementsByName("C2")(output - 1).Checked = True
Next
馬3も同じ。ただ馬連馬単ワイドの場合は、この処理を飛ばすように書いたほうがいいです。
splittedResult = Split(strFileData(5), "-")
For Each output In splittedResult
objFrame(2).document.getElementsByName("C3")(output - 1).Checked = True
Next
For Each output In splittedResult
objFrame(2).document.getElementsByName("C3")(output - 1).Checked = True
Next
ここまで来たら、
チェックボックスをクリックしたときに動くJavaScriptを呼びます。
馬1の馬番1をクリックしたテイで。(実際にチェックはしません)
このonClickを動かさないと、組数(AMOUNT)が計算されないのです。
objFrame(2).document.getElementsByName("C1")(0).onclick
これで組数が表示されるので、その数字×金額(合計金額)を控えておきましょう。
txtAmount = objFrame(2).document.getElementsByName("AMOUNT")
Kingaku = Kingaku + txtAmount.Value * strFileData(6)
Kingaku = Kingaku + txtAmount.Value * strFileData(6)
んで、フレーム1(左)の「入力決定」ボタンを探して押します。
For Each objTag In objFrame(1).document.getElementsByTagName("input")
If InStr(objTag.outerHTML, "入力決定") > 0 Then
objTag.Click
Exit For
End If
Next
If InStr(objTag.outerHTML, "入力決定") > 0 Then
objTag.Click
Exit For
End If
Next
んで次の行の処理へ。ループ2(ファイルの行があるだけループ)を繰り返します。
Sleep 2000 ’ 念のため2秒待機
Loop ’ ループ2の戻り
Loop ’ ループ2の戻り
すべての行の入力を終えたら、
フレーム3(右)の「投票内容確認へ」のボタンを探して押します。
ただ、このボタンを押すとき
普通に押すと制御が利かなくなりますので(このあとダイアログが出てくるので)
非同期で押すようにしましょう。
非同期でボタンを押したら、ちょっと時間を空けて(2秒)
ダイアログ(「Web ページからのメッセージ」)のウインドウを探してOKボタンを押してあげます。
btnIdx = 0
For Each objTag In objFrame(3).document.getElementsByTagName("input")
If InStr(objTag.outerHTML, "投票内容確認へ") > 0 Then
objFrame(3).document.Script.setTimeout "javascript:document.getElementsByTagName(""input"")(" & CStr(btnIdx) & ").click()", 10
Sleep 2000
hwindow = FindWindow("#32770", "Web ページからのメッセージ")
PostMessage hwindow, WM_COMMAND, vbOK, 0&
Exit For
End If
btnIdx = btnIdx + 1
Next
For Each objTag In objFrame(3).document.getElementsByTagName("input")
If InStr(objTag.outerHTML, "投票内容確認へ") > 0 Then
objFrame(3).document.Script.setTimeout "javascript:document.getElementsByTagName(""input"")(" & CStr(btnIdx) & ").click()", 10
Sleep 2000
hwindow = FindWindow("#32770", "Web ページからのメッセージ")
PostMessage hwindow, WM_COMMAND, vbOK, 0&
Exit For
End If
btnIdx = btnIdx + 1
Next
ページが完全に表示されるまで待機。
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
これまでと同じやり方ですね。
暗証番号は「MEMBERPASSR」、投票金額は「TOTALMONEYR」という名前になっていますので
それぞれ入れて、「投票する」ボタンを探して押します。
この時も先ほど同様、非同期でボタンを押して、ダイアログのOKボタンまで押しましょう。
objIE.document.BET_CHECK.MEMBERPASSR.Value = "0000"
objIE.document.BET_CHECK.TOTALMONEYR.Value = CStr(Kingaku * 100)
btnIdx = 0
For Each objTag In objIE.document.getElementsByTagName("input")
If InStr(objTag.outerHTML, "投票する") > 0 Then
objIE.document.Script.setTimeout "javascript:document.getElementsByTagName(""input"")(" & CStr(btnIdx) & ").click()", 10
Sleep 2000
hwindow = FindWindow("#32770", "Web ページからのメッセージ")
PostMessage hwindow, WM_COMMAND, vbOK, 0&
Exit For
End If
btnIdx = btnIdx + 1
Next
objIE.document.BET_CHECK.TOTALMONEYR.Value = CStr(Kingaku * 100)
btnIdx = 0
For Each objTag In objIE.document.getElementsByTagName("input")
If InStr(objTag.outerHTML, "投票する") > 0 Then
objIE.document.Script.setTimeout "javascript:document.getElementsByTagName(""input"")(" & CStr(btnIdx) & ").click()", 10
Sleep 2000
hwindow = FindWindow("#32770", "Web ページからのメッセージ")
PostMessage hwindow, WM_COMMAND, vbOK, 0&
Exit For
End If
btnIdx = btnIdx + 1
Next
ページが完全に表示されるまで待機。
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
DoEvents
Loop
sleep 2000 ’ 念のため2秒待機
これで投票完了です。
InternetExplorerを閉じて、次のファイルを開く準備をして
ループ1(ファイルがあるだけループ)を繰り返します。
objIE.Quit
Set objIE = Nothing
strFile = Dir$
Loop ’ ループ1の戻り
Set objIE = Nothing
strFile = Dir$
Loop ’ ループ1の戻り
これで終了です。
---
今回作ったのは予想ファイルを使って読み込んで投票する仕組みですが
Excelのセルを読み込んで投票する仕組みも簡単にできると思います。
適当に直して使ってください。
どっちにしても大事なのは
「予想するロジック」(今回でいう「予想ファイルの作り方」)だと思いますので。
このネタへのコメント:
コメントはありません。