見出し画像

【競馬】Visual C++ で JRA-VAN DataLab. のデータを取得する

Visual C++ で JV-Link を操作することにより、JRA-VAN DataLab. が提供する競馬データを取得することができます。

今回は Visual C++ を使って簡単な競馬ソフトを作りたいと思います。

1. 動作環境

  • OS : Windows

どこまで古いバージョンで動作するかは分からないですが、Windows 10 以降であれば問題ないはずです。

私の使っている環境は

  • Windows 11 Home (64bit 版)

です。

2. JV-Link のインストール

こちらのページの [動作確認 (JV-Link)] のタブからインストーラーをダウンロードしてインストールおよび初期設定を行って下さい。
※ 使用するには JRA-VAN DataLab. の会員登録が必要です。

3. Visual Studio 2019 のインストール

Visual Studio Installer を使って Visual Studio Community 2019 をインストールします。
ワークロードには [デスクトップとモバイル] > [C++ によるデスクトップ開発] を選択し、オプション内の [v142 ビルドツール用 C++/CLI サポート (最新)] にチェックを入れます。
※ Visual Studio 2019 を使用して下さい。Visual Studio 2020 は IDE 自体が 64bit 化されたためか、この記事の手順ではうまくいきません。

4. 新規プロジェクトの作成

Visual Studio 2019 を起動し、[新しいプロジェクトの作成] をクリックします。

プロジェクト テンプレートから C++ 用の [CLR 空のプロジェクト (.NET Framework)] を選択し、[次へ] ボタンをクリックします。
※ [CLR 空のプロジェクト (.NET)] の方ではないので注意して下さい。

プロジェクト名、場所、ソリューション名を設定し、[作成] ボタンをクリックします。
プロジェクト名、ソリューション名はデフォルトの [Project1] としています。

新規のプロジェクトが作成されました。

[プロジェクト] > [新しい項目の追加] をクリックします。

新しい項目の追加画面が開きます。

[Visual C++] > [UI] > [Windows フォーム] を選択し、[追加] ボタンをクリックします。
名前はデフォルトの [MyForm.h] としています。

エラーが発生します。

[ファイル] > [ソリューションを閉じる] をクリックします。 

実行する操作を選択する画面が開いたら、直近で開いていたプロジェクトの名前をクリックします。

フォームが正常に表示されます。

[表示] > [ツールボックス] をクリックします。

ツールボックス パネルが表示されます。

5. JVLink Class の表示(初回のみ)

ツールボックス内の [全般] を右クリックし、[アイテムの選択] をクリックします。

ツールボックス アイテムの選択画面が開きます。

[COM コンポーネント] タブを開き、[JVLink Class] にチェックを入れ、[OK] ボタンをクリックします。

ツールボックス内に [JVLink Class] が表示されれば OK です。

※ JVLink Class の表示は一度行えば設定が保存されます。

6. プロジェクトの作成

ツールボックス内の [コモン コントロール] > [Button] をフォーム上に配置します。

IDE 画面右下のプロパティの Name はデフォルトの [button1] としています。

ツールボックス内の [全般] > [JVLink Class] をフォーム上に配置します。
※ JVLink Class は実行時に表示されないので、レイアウトを気にする必要はありません。

Name はデフォルトの [axJVLink1] としています。

デザインビューのフォームを選択し、プロパティをイベント タブに切り替え、[Load] の右側の空欄をダブルクリックします。

MyForm_Load 関数が追加された状態でコードエディタが開きます。

MyForm_Load 関数の中身を下記コードで上書きします。

	private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) {
		int returnCode;
		String^ sid = "UNKNOWN";

		// JVLink初期化
		returnCode = axJVLink1->JVInit(sid);

		// JVInitエラー処理
		if (returnCode != 0) {
			MessageBox::Show("JVInitエラー:" + returnCode.ToString());
			return;
		}
	}

デザインビューのフォーム上の button1 をダブルクリックします。

button1_Click 関数が追加されます。

button1_Click 関数の中身を下記コードで上書きします。

	private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
		int returnCode;
		int buffSize = 40000;
		String^ buff;
		String^ fileName;
		String^ raceName;
		String^ raceNames = "";
		int len;
		String^ lastChar;

		// 速報系データの0B12を呼び出し
		// 日付は直近の土日を指定して下さい
		returnCode = axJVLink1->JVRTOpen("0B12", "20230430");

		// JVRTOpenエラー処理
		if (returnCode != 0) {
			MessageBox::Show("JVRTOpenエラー:" + returnCode.ToString());
			return;
		}

		returnCode = 1;
		while (returnCode != 0) {
			returnCode = axJVLink1->JVRead(buff, buffSize, fileName);

			// JVReadエラー処理
			if (returnCode < -1) {
				MessageBox::Show("JVReadエラー:" + returnCode.ToString());
				break;
			}
			else if (returnCode == -1) {
				continue;
			}
			else if (returnCode == 0) {
				break;
			}

			if (buff->Substring(0, 2) == "RA") {
				// レース名を抽出
				raceName = buff->Substring(32, 30);
				len = raceName->Length;
				lastChar = raceName->Substring(len - 1, 1);
				// 末尾の全角スペースを除去
				while ((len > 0) && (lastChar == " ")) {
					raceName = raceName->Substring(0, len - 1);
					len = raceName->Length;
					if (len > 0) {
						lastChar = raceName->Substring(len - 1, 1);
					}
				}
				// レース名が空文字でなければレース名一覧に結合
				if (raceName != "") {
					raceNames += raceName + "\r\n";
				}
			}
		}

		// レース名一覧を表示
		MessageBox::Show(raceNames);

		// JVLink 終了処理
		returnCode = axJVLink1->JVClose();
	}

13 行目の

		returnCode = axJVLink1->JVRTOpen("0B12", "20230430");

の日付部分は直近の土日(中央競馬のレースが開催された日)を yyyymmdd 形式で指定して下さい。
※ このコードで取得している速報系データはレース後 1 週間程で配信されなくなるので、古い開催日を指定してもデータは取得できません。

[プロジェクト] > [新しい項目の追加] をクリックします。

新しい項目の追加画面が開いたら、[Visual C++] > [コード] > [C++ ファイル (.cpp)] を選択し、[追加] ボタンをクリックします。
名前はデフォルトの [ソース.cpp] としています。

コードエディタが開きます。

ソース.cpp 内に下記コードを入力します。

#include "MyForm.h" // Form名.h
#include <string>

using namespace System;
using namespace System::Windows::Forms;

[STAThreadAttribute]
int main(array<String^>^ args) {
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    // gcnew プロジェクト名::Form名()
    Application::Run(gcnew Project1::MyForm());
    return 0;
}

[プロジェクト] > [Project1 のプロパティ] をクリックします。

Project1 プロパティ ページ画面が開きます。

[構成プロパティ] > [リンカー] > [システム] を選択し、[サブシステム] のプルダウンから [Windows (/SUBSYSTEM:WINDOWS)] を選択します。

[構成プロパティ] > [リンカー] > [詳細設定] を選択し、[エントリポイント] の右の空欄に [main] と入力し、[OK] ボタンをクリックします。

[ローカル Windows デバッガー] ボタンをクリックします。

例外が発生します。

[デバッグの停止] ボタンをクリックします。

エクスプローラーで [プロジェクト フォルダ]\Project1\Interop フォルダを開き、AxInterop.JVDTLabLib.1.18.dll ファイルをコピーします。

[プロジェクト フォルダ]\Debug フォルダ内に AxInterop.JVDTLabLib.1.18.dll ファイルを貼り付けます。

7. 動作確認

[ローカル Windows デバッガー] ボタンをクリックします。

MyForm が表示されたら、button1 をクリックします。

メッセージボックスにレース名が表示されれば OK です。

レース開催が無い日や、古い開催日をコード内で指定している場合は下図のようなエラーが発生します。

※ Release 構成にして [ローカル Windows デバッガー] ボタンをクリックした場合も初回実行時は例外が発生するので、[プロジェクト フォルダ]\Release フォルダ内に AxInterop.JVDTLabLib.1.18.dll ファイルを配置して下さい。

この記事が気に入ったらサポートをしてみませんか?