参考
競馬ソフト開発体験教室(https://jra-van.jp/dlb/sdv/trial.html)
Lesson.6 JV-Dataの内容を読み出す 応用編1(ADO.NETの利用) / Lesson.7 JV-Dataの内容を読み出す 応用編2(MDBの利用)
注:上記の参考サイトを元にVBからC#へ移植する進めていきます。
前回記事
JV-LinkをC#で使ってみる(WinForms版) ~5.コード変換を行う~
今回のソースコード
source – JV-LinkをC#で使ってみる(WinForms版) ~6.JV-Dataの内容を読み出す 応用編(1+2)~
開発環境
- Windows7 64ビット版
- Visual Studio Community 2017
- JV-Link Ver.4.5.1
ADOユーティリティクラス移植
ADO.NETでの用語について
以下に必要な用語を挙げておきます。
用語 | 説明 |
---|---|
データセット | メモリ上に作成された簡易的な「データベース」。 |
データソース | ファイルシステム上に作成された「データベース」。(MySQL、Access等) |
データプロバイダ | 「データセット」と「データソース」のデータを受け渡す為の、データ変換プログラム。 |
ADOユーティリティクラス移植
残念ながら、今回も参考サイトLesson.6/7で利用されている「ADOユーティリティクラス」のサンプルにはC#用が存在しませんので移植が必要になります。
まずソリューションエクスプローラーから「basADOUtility.cs」を新規作成します。
すると、basADOUtilityクラスの大枠が作成されます。ただし、basADOUtilityクラスは今回のテストプログラムとは無関係ですので、テストプログラムのnamespaceは外しておきます。
次に今回使うユーティリティに必要なusing節を追加いたします。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data; // データベースへの接続に必要
using System.Data.OleDb; // データベースへの接続に必要
using System.Diagnostics; // Debug クラス使用のために必要
using static JVData_Struct; // JVData_Struct クラス使用のために必要
class basADOUtility
{
}
と言うわけで、基本的には前回と同じ流れとなります。
ADOユーティリティクラスのサンプルの流れ
basADOUtilityクラスを使用したサンプルプログラムは次のような流れ(使い方)になっています。
※メインプログラム
- DataDataSetオブジェクトのインスタンスを作成します。 (DataDataSetクラスはVisual Studioが自動で作成してくれます。命名規則はデータベースのファイル名「Data.accdb」+「DataSet」です。)
- JV-Linkで読み込んだデータをDataDataSetへ書き込みます。
- DataDataSetへ書き込まれたデータを、データプロバイダを介して「Data.accdb」へ書き込みます。
- DataDataSetへ書き込んだデータから条件を指定してデータを読み出し、画面に表示します。
※basADOUtilityクラスの機能
- 「データセット」の「RACE」テーブルへの書き込み機能/読み出し機能
- 「データセット」の「UMA_RACE」テーブルへの書き込み機能/読み出し機能
- 「データセット」のテーブル削除機能
注:他のテーブルを扱う場合、ここに関数を追加する作りになっています。
注:ここで扱っているのは「データセット」であって「データベース(データソース)」ではありません。
basADOUtilityクラスの移植の解説
今回の移植はVBからあまり違いがないので簡単ですが、とてもコピペ作業が大変です。
以下はVBサンプルから移植した際の変更点です。
SetJVDataRaceDataSet()関数
引数にDataDataSetオブジェクトのインスタンスへを渡す必要がありますが、「DataDataSet」は名前が変更になる可能性がありますので、ここではdynamic型を使用しています。
SetJVDataRaceStructure()関数
ほぼそのまま移植しています。
SetJVDataUmaRaceDataSet()関数
ここもDataDataSetの受け渡しをdynamic型で行っています。
SetJVDataUmaRaceStructure()関数
ほぼそのまま移植しています。
deleteDBTable() 関数
引数を1つ追加しています。
元のVBサンプルでは「JVDataConnectionString」という接続文字列を直接使用していますが、文字列型としてメインプログラムから指定する形としています。
メインコードの修正
データソースの追加
プログラムへデータソースの追加を行いますが、VBサンプルとほぼ同じ手順で行えます。
まず、メニューの[表示(V)]→[その他のウィンドウ(E)]→[データソース(D)]を選択します。
[新しいデータソースの追加]を選択します。
データソースの種類を選択します。(データベースを扱うので[データベース]を選択します。)
データベースのモデルを選択しますが、選択できるのは[データセット]のみとなっています。
JRA-VANのサイトから JV-Data を保存するためのAccessファイル(Data.accdb)をダウンロードして、とりあえずデスクトップへ保存します。
データ接続の選択で「Data.accdb」ファイルを選択し、接続できることを確認します。
ファイルを選択すると、ファイルをプロジェクトフォルダーへコピーするか聞かれますので、必ず「はい」を選択します。
ここで「Data.accdb」がプロジェクトフォルダーへコピーされますが、実際にはプログラムの実行時にさらに実行フォルダーへコピーされ、実行フォルダー内のDBファイルへデータは書き込まれます。
接続文字列を指定しますが、デフォルトのままで問題ありません。
「データオブジェクトの選択」で今回利用する「RACE」「UMA_RACE」のテーブルを選択します。「データセット名」の変更は特に必要ありません。 (別に全部選択しても構いません。)
完了すると、データソースがプロジェクトへ追加されます。
メインプログラムの修正
とりあえず細々と修正点を以下に挙げていきます。全体像が無いと分かりずらいですので、全体のコードを参考にしてください。
DataDataSet オブジェクトのインスタンスを作成します。
注:定義は自動でコード化されているので、文字通り作成のみです。
// JV - Dataデータセット
DataDataSet jvdds = new DataDataSet();
DataDataSetオブジェクトの作成とRACEテーブル、UMA_RACEテーブルへのアダプターを作成します。
注:こちらも定義自体は自動でコード化されています。
// レース詳細のテーブルアダプタ
DataDataSetTableAdapters.RACETableAdapter raceTA = new DataDataSetTableAdapters.RACETableAdapter();
// 馬毎レース情報のテーブルアダプタ
DataDataSetTableAdapters.UMA_RACETableAdapter umaRaceTA = new DataDataSetTableAdapters.UMA_RACETableAdapter();
switch文内を「 JV-Link で読み込んだ JV-Data を各データセットへ格納する」ように書き換えます。
case int ret when ret > 0: // 正常読み込み
// レコード種別 ID の識別
if (strBuff.Substring(0, 2) == "RA")
{
// レース詳細構造体への展開
RaceInfo.SetDataB(ref strBuff);
// 読み込んだ情報をデータセットへ格納する
SetJVDataRaceDataSet(RaceInfo, jvdds);
}
else if (strBuff.Substring(0, 2) == "SE")
{
// 馬毎レース情報構造体への展開
RaceUmaInfo.SetDataB(ref strBuff);
// 読み込んだ情報をデータセットへ格納する
SetJVDataUmaRaceDataSet(RaceUmaInfo, jvdds);
}
else
{
// レース詳細、馬毎レース情報以外は読み飛ばす
AxJVLink1.JVSkip();
}
break;
データセットに取得した情報をデータソースへ書き出します。
// データセットの情報をDBへ反映
if (MessageBox.Show("取得したデータをMDBへ反映しますか?", "反映確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// レース詳細を反映
raceTA.Update(jvdds.RACE);
// 馬毎レース情報を反映
umaRaceTA.Update(jvdds.UMA_RACE);
}
先ほどいくつレース詳細を取得したかを確認します。
// レース詳細の件数を取得
raceIndex = jvdds.RACE.Count();
取得したレース詳細の中で「第10レース」のみを抜き出します。
(フィルタ基準の書式は 「フィールド名 比較演算子 値」です。詳細についてはマイクロソフトの MSDN ライブラリなどをご参照ください。)
と書かれていますのでそのうち調べようと思うのですが、多分SQL相当であろうかとは思います。
// レース詳細の第10レースを検索(複数行)
raceDRs = (DataDataSet.RACERow[])jvdds.RACE.Select("RaceNum = '10'");
抜き出した複数の「第10レース」の内、「配列の一番最初の物」を決め打ちで画面表示します。
// 取得結果の一件目を構造体にセット
SetJVDataRaceStructure(raceDRs[0], ref RaceInfo);
// 画面表示
rtbData.AppendText(
"年:" + RaceInfo.id.Year +
" 月日:" + RaceInfo.id.MonthDay +
" 場:" + objCodeConv.GetCodeName("2001", RaceInfo.id.JyoCD, 1) +
" 回次:" + RaceInfo.id.Kaiji +
" 日次:" + RaceInfo.id.Nichiji +
" R:" + RaceInfo.id.RaceNum +
" レース名:" + RaceInfo.RaceInfo.Ryakusyo10 +
"\n");
「配列の一番最初の第10レース」の出走馬を抜き出します。
// データセットからレース詳細のキーで馬毎レース情報の行(複数行)を検索
raceUmaDRs = (DataDataSet.UMA_RACERow[])jvdds.UMA_RACE.Select(
"Year = '" + RaceInfo.id.Year + "' AND " +
"MonthDay = '" + RaceInfo.id.MonthDay + "' AND " +
"JyoCD = '" + RaceInfo.id.JyoCD + "' AND " +
"Kaiji = '" + RaceInfo.id.Kaiji + "' AND " +
"Nichiji = '" + RaceInfo.id.Nichiji + "' AND " +
"RaceNum = '" + RaceInfo.id.RaceNum + "'");
抜き出した出走馬の配列を画面表示します。
// 一行ずつ取り出し、画面に表示
foreach (DataDataSet.UMA_RACERow raceUmaDR in raceUmaDRs)
{
// 行の情報を構造体にセット
SetJVDataUmaRaceStructure(raceUmaDR, ref RaceUmaInfo);
// 画面表示
rtbData.AppendText(
" 枠:" + RaceUmaInfo.Wakuban +
" 馬番:" + RaceUmaInfo.Umaban +
" 馬名:" + RaceUmaInfo.Bamei +
" 騎手:" + RaceUmaInfo.KisyuRyakusyo +
"\n");
}
コードの修正が完了したらプログラムを実行し、データ取得ボタンを選択して動作を確認します。
以上で、 JV-Data の内容のデータベース読み出しが完了となります。
ここまで出来ると、 JV-Link の役割はひとまず終了となり、後は JV-Link を離れてデータベースの操作となります。(速報系はまた別の話ですが。)