見出し画像

VB.NETでJVLinkからデータ取得 9 コーディング 6

前回までで取得したい値を望みの形で表示する所までできました。

前回記事

この後は目的に合わせて加工なりしていけば良いのですが、今回のこのテストプロジェクトでは、取得した人気オッズデータをテーブルとして扱えるように、単純にExcelに落とす事をゴールとしているので、TextBoxに表示したデータをExcelに流し込むイメージでやっていきましょう。

空のExcelブックにJVLink_test.xlsxと名前を付け、一番最初にデスクトップ上に作ったJVLink-TESTフォルダーに保存します。


このまま空白のExcelシートに対して項目名を追加して流し込むのもいいんですが、簡単の為にここは予め項目名入りのシートを用意してしまいましょう。

A列は文字列型、B列C列は数値型(整数)、D列は数値型で小数点以下第一位までの表示にします。
列名の部分を右クリック→セルの書式設定で変更可能です。

これで受け皿はできました。
続いてコードの変更ですが、最初にやらなくてはいけないことがあります。
それは、Visual Studio2019でExcelファイルを扱うための準備です。

VBA時代にはそもそもOffice製品を扱う為の言語だったので、今からやるようなことは必要なかったのですが、VB.NETではいちいちExcelを扱えるように設定してやらないといけません。
今回使っていくライブラリはEPPlusで、非商用利用なら無料で使えます。

いつものようにVisual Studio2019を管理者権限で開き、JVLink-TESTのプロジェクトを開き、右側のソリューションエクスプローラーの中のJVLink-TESTを右クリックします。

右クリックするとNuGetパッケージの管理というのが出てくるので選択します。
出てきたNuGetパッケージマネージャーでEPPlusと参照で入力すると出てくるEPPlusをインストールします。

インストールが終わったら、readme.txtを読み、NuGet: JVLink-TESTと共にタブは消してOKです。

続いてコードを書き換えますが、前回までは単勝オッズの整形を表示前にやっていましたが、経験的に予め整形してもExcelの書き込み時にどうせ再度整形する事になるので、表示部分では整形しないようにします。
エラーが出ると凹むのでわかっているエラーはなるべく避けましょう。

' Excel操作用の名前空間の追加
Imports OfficeOpenXml
Imports System.IO

Public Class Form1
    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
        ' 取得したいレースIDを指定
        Dim raceNum As String = "2024031707010403"
        ' JVLinkからの戻り値を格納する変数を定義
        Dim retval As Long
        ' 定数としてretvalのバッファサイズを指定
        Const buffSize As Long = 1000

        ' JVLink初期化を実施
        Me.AxJVLink1.JVInit("UNKNOWN")
        ' 0B31からレースIDを引数にして人気オッズを読み込みを開始
        retval = Me.AxJVLink1.JVRTOpen("0B31", raceNum)


        ' retvalが負の値だと何かしらのエラーが発生しているので処理を中断
        If retval < 0 Then
            MsgBox("JVRTOpenエラー。RC=" & retval)
            Exit Sub
        End If


        ' JVRTOpenが成功した事をTextBoxにを表示
        TextBox1.AppendText("JVRTOpen成功。RC=" & retval & Environment.NewLine)

        ' Excelファイルへの書き込み準備
        Dim excelFilePath As String = "C:\Users\ユーザー名\Desktop\JVLink-TEST\JVLink_test.xlsx"
        Dim fileInfo As New FileInfo(excelFilePath)
        Using package As New ExcelPackage(fileInfo)
            Dim worksheet As ExcelWorksheet = package.Workbook.Worksheets.FirstOrDefault(Function(x) x.Name = "Sheet1")
            If worksheet Is Nothing Then
                worksheet = package.Workbook.Worksheets.Add("Sheet1")
            End If
            Dim startRow As Integer = 2

            ' データ読み込みのためのループを開始
            Do
                ' データを格納するためのバッファを準備
                Dim strBuff As String = New String(vbNullChar, buffSize)
                ' JVLinkからデータを読み込む
                retval = AxJVLink1.JVRead(strBuff, buffSize, Nothing)

                If retval = -1 Then ' データの終端に達したらループを終了
                    Exit Do
                ElseIf retval < 0 Then ' JVReadエラー処理
                    ' エラー内容表示
                    MessageBox.Show("JVReadエラー。RC=" & retval)
                    Exit Do
                ElseIf retval > 0 Then ' データが正常に読み込まれた場合、解析を行う
                    Dim dataStartIndex As Integer = strBuff.IndexOf("O"c) + 1
                    If dataStartIndex > 0 Then
                        Dim validData As String = strBuff.Substring(dataStartIndex).Trim()
                        Dim endIndex As Integer = validData.IndexOf(" "c)
                        If endIndex > 0 Then
                            validData = validData.Substring(0, endIndex)
                        End If

                        ' データの成形と表示
                        Dim i As Integer = 0
                        While (42 + i * 8 + 6) <= validData.Length ' 馬番の位置と単勝人気の位置を考慮
                            Dim horseNumber = validData.Substring(42 + i * 8, 2) ' 馬番の頭の0を保持
                            Dim winOdds = validData.Substring(44 + i * 8, 4) ' 単勝オッズ
                            Dim winOrder = validData.Substring(48 + i * 8, 2)

                            ' R_IDの正確な生成
                            Dim raceDate As String = validData.Substring(10, 8) ' 日付
                            Dim venueCode As String = validData.Substring(18, 2) ' 競馬場コード
                            Dim holdingNumber As String = validData.Substring(20, 2) ' 開催回
                            Dim dayNumber As String = validData.Substring(22, 2) ' 開催日数
                            Dim raceNumber As String = validData.Substring(24, 2) ' レース番号
                            Dim R_ID As String = raceDate & venueCode & holdingNumber & dayNumber & raceNumber & horseNumber ' 最終的なレースID

                            ' 単勝オッズの整形は行わず、そのまま表示
                            Dim displayText = $"{R_ID}," & $"{horseNumber}," & $"{winOdds}," & $"{winOrder}"
                            TextBox1.AppendText(displayText & Environment.NewLine)

                            ' Excelにデータを書き込む処理
                            worksheet.Cells(startRow + i, 1).Value = R_ID ' レースIDを書き込む
                            worksheet.Cells(startRow + i, 2).Value = Integer.Parse(horseNumber.TrimStart(New Char() {"0"c})) ' 馬番を整数として書き込む(先頭のゼロを除去)

                            ' 単勝人気はそのまま整数として書き込む
                            worksheet.Cells(startRow + i, 3).Value = Integer.Parse(winOrder)

                            ' 単勝オッズをDecimal型に変換し、10で割ってExcelに書き込む(ここで整形)
                            Dim winOddsDecimal As Decimal = Decimal.Parse(winOdds) / 10D
                            worksheet.Cells(startRow + i, 4).Value = winOddsDecimal


                            i += 1 ' 次のデータ項目のために行を進める
                        End While
                    End If
                End If
            Loop While retval <> 0

            ' JVCloseを呼び出してセッションを終了
            Me.AxJVLink1.JVClose()

            ' Excelファイルの変更を保存
            package.Save()
        End Using
    End Sub
End Class

ファイルパスの"ユーザー名"という部分は皆さんの環境に置き換えてください。


実行します

お疲れさまでした。
今回はこれでGOALになります。

次は除外取り消しの馬がいた時の処理をやって〆ようかと思います。

シリーズ最後の記事


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