競馬成績表データベースを作る(ツール-Excel編)
1.概要
競馬成績表データベースを作るの第四弾です。これまで、作成したデータベースを活用するためには、検索表示などができないと
何の役にも立ちません。今回は、Excel VBAで作成します。当ブログ記事の「Excelでデータベース(SQLite3)を扱う」
で紹介しているテンプレートとなるソースコードを元にして、検索部分とデータ出力機能を追加しデータが抽出できるようにしたものです。
データベースをしっかり作成していれば、競馬以外の他の用途でも、いろいろと応用の効くものとすることができます。
2.ソースコード まずは、簡単に操作方法を説明します。Yahoo競馬レース成績表検索.xlsmを起動します。 検索条件のコンボボックスで「競馬場」、「距離」、「コース」の3つの条件を選択して、実行ボタンをクリックします。 抽出対象データがあれば、100件/1ページ単位にデータが表示されます。ページ制御をしていますので、「次ページ」、 「前ページ」、「先頭」、「最終」のボタンをクリックしてページを表示させます。 また、「出力」ボタンをクリックすると、CSV形式で抽出したデータを外部出力できます。「消去」ボタンは、 画面上のデータを強制的に消去するものです。新たな条件で「実行」ボタンをクリックすれば、前処理として 消去(画面クリア)させていますので、通常は操作不要です。尚、Yahoo競馬レース成績表検索.xlsmの実行には、 SQLiteのODBCとこのプログラムで利用するデータベース(pegasus.db)が必要ですので事前に準備しておいて下さい。 ThisWorkbookは、ブックを開いた時の初期設定処理をしています。検索条件設定用のコンボボックスに値をセットします。
参考として、データをExcelに取り込む場合は、メニューのデータから、リボンのデータの取得もしくは、テキストまたはCSVから実施して下さい。 Excelのバージョンによってリボンの名称や配置などが異なるかと思いますが、同じような機能があると思います。 筆者は、Windows10のMicrosoft365版のExcelを利用していますが、データの取り込みが従来のインポートがなくなっていて、Power Queryに なって少し操作に戸惑いました。標準では、従来のウィザードは利用できないと思っていましたが、ファイル→オプション→データ項目に レガシーデータインポートウィザードという項目があり、テキストから(レガシー)にチェックを入れると従来方式のウィザードが利用できました。 下記のいずれかの方法でCSVデータのインポートをして下さい。(参考)
下記のファイルをアーカイブにして提供します。データは、著作権に触れる恐れがあるため、配布することができません。 動作確認のテスト用のサンプルとして100件のみ入れてあります。実際に利用する場合は、各自で取得して新規に作成願います。 尚、データの取得やプログラム実行において損害等が生じた場合は、筆者は一切の責任も負いません。全て自己責任でお願いします。
ダウンロード
■関連記事
・Excelでデータベース(SQLite3)を扱う
・複数のファイルをマージする
・競馬成績表データベースを作る(事前準備編)
・競馬成績表データベースを作る(データ取得編)
・競馬成績表データベースを作る(データベース編)
・競馬成績表データベースを作る(ツール-HSP編)
2.ソースコード まずは、簡単に操作方法を説明します。Yahoo競馬レース成績表検索.xlsmを起動します。 検索条件のコンボボックスで「競馬場」、「距離」、「コース」の3つの条件を選択して、実行ボタンをクリックします。 抽出対象データがあれば、100件/1ページ単位にデータが表示されます。ページ制御をしていますので、「次ページ」、 「前ページ」、「先頭」、「最終」のボタンをクリックしてページを表示させます。 また、「出力」ボタンをクリックすると、CSV形式で抽出したデータを外部出力できます。「消去」ボタンは、 画面上のデータを強制的に消去するものです。新たな条件で「実行」ボタンをクリックすれば、前処理として 消去(画面クリア)させていますので、通常は操作不要です。尚、Yahoo競馬レース成績表検索.xlsmの実行には、 SQLiteのODBCとこのプログラムで利用するデータベース(pegasus.db)が必要ですので事前に準備しておいて下さい。 ThisWorkbookは、ブックを開いた時の初期設定処理をしています。検索条件設定用のコンボボックスに値をセットします。
'***** ブックを開いた時の初期設定処理 *****
Private Sub Workbook_Open()
Sheets("成績表").Select
Worksheets("成績表").Activate
'***** 検索条件用のコンボボックスを設定 *****
' 競馬場
Dim CBRaceKaisai(10)
CBRaceKaisai(0) = "東京"
CBRaceKaisai(1) = "中山"
CBRaceKaisai(2) = "京都"
CBRaceKaisai(3) = "阪神"
CBRaceKaisai(4) = "中京"
CBRaceKaisai(5) = "札幌"
CBRaceKaisai(6) = "函館"
CBRaceKaisai(7) = "福島"
CBRaceKaisai(8) = "新潟"
CBRaceKaisai(9) = "小倉"
' 距離
Dim CBKyori(20)
CBKyori(0) = "1000"
CBKyori(1) = "1150"
CBKyori(2) = "1200"
CBKyori(3) = "1300"
CBKyori(4) = "1400"
CBKyori(5) = "1500"
CBKyori(6) = "1600"
CBKyori(7) = "1700"
CBKyori(8) = "1800"
CBKyori(9) = "2000"
CBKyori(10) = "2100"
CBKyori(11) = "2200"
CBKyori(12) = "2300"
CBKyori(13) = "2400"
CBKyori(14) = "2500"
CBKyori(15) = "2600"
CBKyori(16) = "3000"
CBKyori(17) = "3200"
CBKyori(18) = "3400"
CBKyori(19) = "3600"
' コース
Dim CBCource(3)
CBCource(0) = "ダート"
CBCource(1) = "芝"
CBCource(2) = "障害"
' 各コンボボックスに設定値をセット
Worksheets("成績表").KaisaiComb.List = CBRaceKaisai
Worksheets("成績表").KyoriComb.List = CBKyori
Worksheets("成績表").CourceComb.List = CBCource
End Sub
Sheet1(成績表)は、シート上に配置した各ボタンのクリックイベントに対応した
ルーチンへジャンプするための処理を記述しています。
'***** データ削除 ***** Private Sub DataClr_Click() Call DataDelete End Sub '***** ファイル出力 ***** Private Sub FileOut_Click() Call CSVout End Sub '***** 実行開始 ***** Private Sub StartDB_Click() Call DataBase_Init Call SQLite(0) End Sub '***** 前ページ表示制御 ***** Private Sub BeforePage_Click() Call SQLite(0) End Sub '***** 次ページ表示制御 ***** Private Sub NextPage_Click() Call SQLite(1) End Sub '***** 先頭ページ表示制御 ***** Private Sub FirstPage_Click() Call StartDB_Click End Sub '***** 最終ページ表示制御 ***** Private Sub LastPage_Click() Call SQLite(3) End Sub '***** 各変数の初期化 ***** Private Sub DataBase_Init() StartPoint = 0 PageNo = 0 PageCount = 0 BackPoint = 0 ReadRec = 0 DispRec = 0 N_Page = 0 N_Num = 0 B_Page = 0 B_Num = 0 LastPage = 0 StartFLG = 0 KeepPage = 0 End Sub標準モジュール : seisekiはメインとなる処理を記述しています。 ソースコードは「Excelでデータベース(SQLite3)を扱う」 で紹介しているものがベースとなっています。処理の大部分は、ページ制御部分であり、実際にデータベースからのデータ抽出と表示部分は データベースの項目数(フィールド)の数だけ設定してループを回しているだけです。 処理の流れは、データベースオープン→テーブルセット→SQL文(クエリ)発行→ループでデータ表示といった流れになっています。 ルーチンの重複がありますが、外部データへの出力も同じで、抽出したデータをカンマ区切りとしてテキスト形式(CSV)で書き出しています。 尚、参考補足事項ですが、出力されたCSVファイルをダブルクリックしてExcelとの関連付け起動させないでください。Excelのセルの書式(属性) に自動で調整されて、日付形式などの意図しない形式で表示されてしまいます。データの確認は、メモ帳などのテキストエディタで確認して下さい。
参考として、データをExcelに取り込む場合は、メニューのデータから、リボンのデータの取得もしくは、テキストまたはCSVから実施して下さい。 Excelのバージョンによってリボンの名称や配置などが異なるかと思いますが、同じような機能があると思います。 筆者は、Windows10のMicrosoft365版のExcelを利用していますが、データの取り込みが従来のインポートがなくなっていて、Power Queryに なって少し操作に戸惑いました。標準では、従来のウィザードは利用できないと思っていましたが、ファイル→オプション→データ項目に レガシーデータインポートウィザードという項目があり、テキストから(レガシー)にチェックを入れると従来方式のウィザードが利用できました。 下記のいずれかの方法でCSVデータのインポートをして下さい。(参考)
'*********************************************************************************
'*
'* レース成績表データベース検索処理
'*
'*
'* ●Pegasus.db(SQLite3)利用によるレース成績表データベース検索
'*
'*
'*********************************************************************************
'***** グローバル変数 *****
Public My_Row As Long ' 行位置
Public My_Col As Long ' 列位置
Public StarPoint As Integer ' レコード開始位置
Public PageNo As Integer ' ページ番号
Public PageCount As Integer ' ページカウンタ
Public BackPoint As Integer ' 前ページ開始位置
Public B_Page As Integer ' 前ページ開始位置一時保存
Public B_Num As Integer ' 前ページ番号一時保存
Public N_Page As Integer ' 次ページ開始位置一時保存
Public N_Num As Integer ' 次ページ番号一時保存
Public StartFLG As Integer ' 前ページ、次ページ判定フラグ
Public KeepPage As Integer ' 最終ページ番号保存用
Public filename As String ' DataBase FileName
Public i As Long ' セルの表示開始位置制御カウンタ
Public DBName As String ' DataBace ODBC定義 (SQLite3)
Public Sql As String ' SQL
Public Db As Object ' DataBase
Public rs As Object ' Recordset
'***** データベース処理開始 (全件表示 : 100件単位) *****
Public Sub SQLite(ByVal StartFLG As Integer)
Dim S_PageCnt As Integer ' 開始ページカウンタ保存用
Dim S_PageNum As Integer ' 開始ページ番号保存用
Dim ReadRec As Integer ' 読み出しレコードカウンタ
Dim DispRec As Integer ' 表示件数制御カウンタ
Dim LastPage As Integer ' 最終ページ番号取得用
On Error Resume Next
'***** 前ページをセット *****
If StartFLG = 0 Then
S_PageCnt = B_Page
S_PageNum = B_Num
End If
'***** 次ページをセット *****
If StartFLG = 1 Then
S_PageCnt = N_Page
S_PageNum = N_Num
End If
'***** 最終ページをセット *****
If StartFLG = 3 Then
S_PageCnt = (KeepPage * PageCount) - PageCount + 1
S_PageNum = KeepPage
End If
'***** 画面クリア *****
Call DataDelete
'***** DB FileName設定 (※変更のこと) *****
If Dir(ThisWorkbook.Path & "¥pegasus.db") = "" Then
MsgBox "データベースファイルが存在しません。"
Exit Sub
End If
'***** データベースオープン *****
Call SQLiteDB_Open("pegasus.db")
'***** コンボボックスの各設定値をセット *****
Kaisai = Worksheets("成績表").KaisaiComb.Text
cource = Worksheets("成績表").CourceComb.Text
sKyori = Worksheets("成績表").KyoriComb.Text
'***** SQL文を発行 *****
Sql = "SELECT * FROM seisekidb WHERE KeiBabajyou COLLATE NOCASE LIKE '%" & Kaisai & "%'" _
& " AND Cource COLLATE NOCASE LIKE " & "'" & cource & "%'" _
& " AND Kyori COLLATE NOCASE LIKE " & "'%" & sKyori & "%'" _
& " ORDER BY ID ASC LIMIT 5000"
'***** テーブルセット *****
Call Table_Set
'***** 抽出レコード件数 *****
RecCount = rs.RecordCount
Range("B4") = RecCount
If RecCount = 0 Then
Call DB_Close
MsgBox "対象データがありませんでした。"
Exit Sub
End If
'***** 画面の表示更新停止開始 *****
Application.ScreenUpdating = False
'***** ページ制御カウンタ *****
StartPoint = S_PageCnt
PageNo = S_PageNum
PageCount = 100
BackPoint = StartPoint - PageCount
ReadRec = 0
DispRec = 0
'***** 初期値確認 (StartPoint) *****
If StartPoint = 0 Then
StartPoint = 1
PageNo = 1
Worksheets("成績表").BeforePage.Enabled = False
Worksheets("成績表").FirstPage.Enabled = False
End If
'***** 初期値確認 (PageNo) *****
If PageNo = 0 Then
PageNo = 1
Worksheets("成績表").BeforePage.Enabled = False
Worksheets("成績表").FirstPage.Enabled = False
End If
'***** ページ番号を表示 *****
Range("A4") = PageNo
'***** 最終ページ番号 *****
LastPage = (RecCount / PageCount) + 1
'***** 最終ページ保存 *****
If RecCount <= 100 Then LastPage = LastPage - 1
KeepPage = LastPage
Range("C4") = PageNo & " / " & KeepPage
If rs.EOF Then
StartPoint = 0
PageNo = 0
PageCount = 0
BackPoint = 0
ReadRec = 0
DispRec = 0
StartFLG = 0
'***** 全制御ボタンを不活性化 *****
Worksheets("成績表").BeforePage.Enabled = False
Worksheets("成績表").NextPage.Enabled = False
Worksheets("成績表").FirstPage.Enabled = False
Worksheets("成績表").LastPage.Enabled = False
Else
'▼▼▼▼ 結果をセルに書き込む (表示) ▼▼▼▼
i = 6 ' 表示開始位置 : 6行目~105行目
Do Until rs.EOF = True
' 読み込みレコードカウンタ
ReadRec = ReadRec + 1
' データ開始レコードまで読み飛ばし
If StartPoint <= ReadRec Then
' 設定(100件/頁)になったら表示を終了
If DispRec = PageCount Then
Worksheets("成績表").NextPage.Enabled = False
Exit Do
End If
' 表示レコードカウンタ
DispRec = DispRec + 1
'============= 結果の表示 ==========================================
Cells(i, 1).Value = ReadRec ' No. (ReadRec)
Cells(i, 2).Value = rs.Fields(1).Value ' 日付 (RaceDate)
Cells(i, 3).Value = rs.Fields(2).Value ' コード (BabaCode)
Cells(i, 4).Value = rs.Fields(3).Value ' R番号 (RaceNo)
Cells(i, 5).Value = rs.Fields(4).Value ' 競馬場 (KeiBabajyou)
Cells(i, 6).Value = rs.Fields(5).Value ' 開催 (Kaisai)
Cells(i, 7).Value = rs.Fields(6).Value ' 発走時間 (StartTime)
Cells(i, 8).Value = rs.Fields(7).Value ' 天気 (Tenki)
Cells(i, 9).Value = rs.Fields(8).Value ' 馬場 (Baba)
Cells(i, 10).Value = rs.Fields(9).Value ' レース名 (RaceName)
Cells(i, 11).Value = rs.Fields(10).Value ' コース (Cource)
Cells(i, 12).Value = rs.Fields(11).Value ' 距離 (Kyori)
Cells(i, 13).Value = rs.Fields(12).Value ' 単勝 (TanSyou)
Cells(i, 14).Value = rs.Fields(13).Value ' 枠連 (Wakulen)
Cells(i, 15).Value = rs.Fields(14).Value ' 馬連 (Umalen)
Cells(i, 16).Value = rs.Fields(15).Value ' 馬単 (UmaTan)
Cells(i, 17).Value = rs.Fields(16).Value ' 3連単 (SanlenTan)
Cells(i, 18).Value = rs.Fields(17).Value ' 1着 (OneUma)
Cells(i, 19).Value = rs.Fields(18).Value ' 2着 (TwoUma)
Cells(i, 20).Value = rs.Fields(19).Value ' 3着 (ThreeUma)
Cells(i, 21).Value = rs.Fields(20).Value ' 頭数 (Tousu)
' カウントアップ
i = i + 1
End If
rs.MoveNext
Loop
'***** 画面の表示更新停止解除 *****
Application.ScreenUpdating = True
'***** レコードの開始位置 *****
StartPoint = PageCount * PageNo + 1
'***** ページ制御 *****
'***** 前ページの場合 *****
If PageNo > 1 Then
Worksheets("成績表").BeforePage.Enabled = True
Worksheets("成績表").FirstPage.Enabled = True
StartFLG = 0
B_Page = BackPoint
B_Num = PageNo - 1
End If
'***** 次ページの場合 *****
If PageNo < LastPage Then
Worksheets("成績表").NextPage.Enabled = True
Worksheets("成績表").LastPage.Enabled = True
StartFLG = 1
N_Page = StartPoint
N_Num = PageNo + 1
End If
End If
'***** 前ページボタン不活性化 *****
If PageNo = 1 Then
Worksheets("成績表").BeforePage.Enabled = False
Worksheets("成績表").FirstPage.Enabled = False
End If
'***** 次ページボタン不活性化 *****
If PageNo >= LastPage Then
Worksheets("成績表").NextPage.Enabled = False
Worksheets("成績表").LastPage.Enabled = False
End If
'***** 画面更新の実行 *****
Application.ScreenUpdating = True
Range("B4").Select
'***** 接続を閉じる *****
Call DB_Close
Range("A1").Select
End Sub
'***** 抽出ファイル出力 *****
Sub CSVout()
Dim buf, StrTemp As String
Dim FNAME As String
'***** DB FileName設定 (※変更のこと) *****
If Dir(ThisWorkbook.Path & "¥pegasus.db") = "" Then
MsgBox "データベースファイルが存在しません。"
Exit Sub
End If
'***** データベースオープン *****
Call SQLiteDB_Open("pegasus.db")
'***** コンボボックスの各設定値をセット *****
Kaisai = Worksheets("成績表").KaisaiComb.Text
cource = Worksheets("成績表").CourceComb.Text
sKyori = Worksheets("成績表").KyoriComb.Text
'***** SQL文を発行 *****
Sql = "SELECT * FROM seisekidb WHERE KeiBabajyou COLLATE NOCASE LIKE '%" & Kaisai & "%'" _
& " AND Cource COLLATE NOCASE LIKE " & "'" & cource & "%'" _
& " AND Kyori COLLATE NOCASE LIKE " & "'%" & sKyori & "%'" _
& " ORDER BY ID ASC LIMIT 5000"
'***** テーブルセット *****
Call Table_Set
'***** 抽出レコード件数 *****
RecCount = rs.RecordCount
Range("B4") = RecCount
If RecCount = 0 Then
Call DB_Close
MsgBox "対象データがありませんでした。"
Exit Sub
End If
Do Until rs.EOF = True
'***** バッファにカンマ区切りのデータをセット *****
StrTemp = rs.Fields(1).Value & "," & _
rs.Fields(2).Value & "," & _
rs.Fields(3).Value & "," & _
rs.Fields(4).Value & "," & _
rs.Fields(5).Value & "," & _
rs.Fields(6).Value & "," & _
rs.Fields(7).Value & "," & _
rs.Fields(8).Value & "," & _
rs.Fields(9).Value & "," & _
rs.Fields(10).Value & "," & _
rs.Fields(11).Value & "," & _
rs.Fields(12).Value & "," & _
rs.Fields(13).Value & "," & _
rs.Fields(14).Value & "," & _
rs.Fields(15).Value & "," & _
rs.Fields(16).Value & "," & _
rs.Fields(17).Value & "," & _
rs.Fields(18).Value & "," & _
rs.Fields(19).Value & "," & _
rs.Fields(20).Value & vbCrLf
' レコードを加算
buf = buf + StrTemp
rs.MoveNext
Loop
'***** 抽出対象ファイルが無い場合 *****
If buf = "" Then
MsgBox "抽出対象ファイルがありません。"
Call DB_Close
Exit Sub
End If
'***** ファイル名を合成 (年月日時分秒) *****
FNAME = "Seiseki_" & Year(Date) & Right("0" & Month(Date), 2) & Right("0" & Day(Date), 2) & _
Right("0" & Hour(Time), 2) & Right("0" & Minute(Time), 2) & Right("0" & Second(Time), 2) & ".csv"
Open ThisWorkbook.Path & "¥" & FNAME For Output As #1
Print #1, buf
Close #1
MsgBox "ファイルに " & RecCount & "件 出力しました。"
'***** 接続を閉じる *****
Call DB_Close
End Sub
'***** データベースオープン *****
Sub SQLiteDB_Open(ByVal DBSetName As String)
filename = ThisWorkbook.Path & "¥pegasus.db"
DBName = "DRIVER=SQLite3 ODBC Driver;Database=" & filename & ";"
Set Db = CreateObject("ADODB.Connection")
Db.CursorLocation = 3
Db.Open DBName
End Sub
'***** テーブルセット *****
Sub Table_Set()
Set rs = CreateObject("ADODB.Recordset")
rs.Open Sql, Db, 3, 3
Set rs = Db.Execute(Sql)
End Sub
'***** データベースクローズ *****
Sub DB_Close()
rs.Close
Db.Close
Set rs = Nothing
Set Db = Nothing
End Sub
'***** データ消去 *****
Sub DataDelete()
Sheets("成績表").Select
Worksheets("成績表").Activate
If Range("A6") <> "" Then
Application.ScreenUpdating = False
Range("A6:U113").SpecialCells(xlCellTypeConstants, 23).ClearContents
Range("A4:C4").Value = ""
Application.ScreenUpdating = True
End If
End Sub
3.ダウンロード
提供するソースコードのライセンスは、CC0 (クレジット表示不要、改変可、商用可) とします。自由に利用して頂いてかまいません。
下記のファイルをアーカイブにして提供します。データは、著作権に触れる恐れがあるため、配布することができません。 動作確認のテスト用のサンプルとして100件のみ入れてあります。実際に利用する場合は、各自で取得して新規に作成願います。 尚、データの取得やプログラム実行において損害等が生じた場合は、筆者は一切の責任も負いません。全て自己責任でお願いします。
-
・import.bat
・pegasus.db
・raceseiseki.exe
・raceseiseki.hsp
・sqlite3.dll (raceseiseki.exeを実行するのに必要)
・Yahoo競馬結果リンク先取得.xlsm
・Yahoo競馬レース結果取得.xlsm
・Yahoo競馬レース成績表検索.xlsm
・ヘッダー名.txt
ダウンロード
■関連記事
・Excelでデータベース(SQLite3)を扱う
・複数のファイルをマージする
・競馬成績表データベースを作る(事前準備編)
・競馬成績表データベースを作る(データ取得編)
・競馬成績表データベースを作る(データベース編)
・競馬成績表データベースを作る(ツール-HSP編)




コメント
コメントを投稿