【VBAリファレンス】VBAサンプル集Excel将棋:棋譜ファイルから対局一覧作成による業務効率化の極意

スポンサーリンク

概要

Excel VBAを活用した将棋の棋譜管理は、単なる趣味の領域を超え、大量の対局データを効率的に処理する高度なデータエンジニアリングの学習教材となります。本稿では、指定フォルダ内の複数の棋譜ファイル(CSA形式やKIF形式など)を読み込み、対局日、先手・後手の名前、勝敗結果、戦型などの情報を自動的に抽出して、Excelのリスト形式へ一括出力する仕組みを解説します。この技術は、将棋データの整理のみならず、社内の日報集計やログファイルの解析といった実務に応用可能な汎用性の高いテクニックです。

詳細解説

棋譜ファイルからのデータ抽出には、VBAの「FileSystemObject(FSO)」によるファイル操作と、「TextStream」によるテキスト読み込み処理が不可欠です。棋譜ファイルは一般的にテキスト形式で保存されており、各行には特定のキーワード(例:「先手:」「後手:」「対局日:」)が含まれています。これらをVBAで一行ずつ読み込み、正規表現(RegExp)を用いて必要な情報を切り出すのが最も堅牢な手法です。

処理の流れは以下の通りです。
1. 特定のフォルダパスを指定し、FSOを使用してフォルダ内の全ファイルを取得する。
2. ファイルが棋譜ファイルであることを確認し、読み取り専用モードで開く。
3. 行単位でループ処理を行い、文字列比較(InStr関数)や正規表現を用いて対局メタデータを抽出する。
4. 抽出したデータを配列やコレクションに格納し、最後にExcelシートの指定範囲へ一括転記する。

特に重要なのは「例外処理」です。棋譜ファイルは作成者やソフトによってフォーマットが微妙に異なる場合があるため、エラーが発生しても処理を止めず、次のファイルへ移行する「On Error Resume Next」とエラーハンドリングの設計が重要となります。

サンプルコード

以下に、指定フォルダ内のテキスト形式の棋譜から対局情報を抽出する標準的なVBAコードを提示します。


Option Explicit

' 参照設定:Microsoft Scripting Runtime を有効にしてください
Sub ExtractKifuData()
    Dim fso As FileSystemObject
    Dim folder As folder
    Dim file As file
    Dim ts As TextStream
    Dim filePath As String
    Dim lineData As String
    Dim ws As Worksheet
    Dim rowIdx As Long
    
    Set fso = New FileSystemObject
    Set ws = ThisWorkbook.Sheets("対局一覧")
    rowIdx = 2
    
    ' フォルダパスを指定
    Set folder = fso.GetFolder("C:\ShogiData\Kifu")
    
    Application.ScreenUpdating = False
    
    For Each file In folder.Files
        If LCase(fso.GetExtensionName(file.Name)) = "kif" Or _
           LCase(fso.GetExtensionName(file.Name)) = "csa" Then
            
            Set ts = fso.OpenTextFile(file.Path, ForReading)
            
            ' 初期化
            Dim sente As String, gote As String, dateVal As String
            
            Do Until ts.AtEndOfStream
                lineData = ts.ReadLine
                ' キーワード検索によるデータ抽出
                If InStr(lineData, "先手:") > 0 Then sente = Split(lineData, ":")(1)
                If InStr(lineData, "後手:") > 0 Then gote = Split(lineData, ":")(1)
                If InStr(lineData, "対局日:") > 0 Then dateVal = Split(lineData, ":")(1)
            Loop
            
            ' シートへの書き込み
            ws.Cells(rowIdx, 1).Value = file.Name
            ws.Cells(rowIdx, 2).Value = dateVal
            ws.Cells(rowIdx, 3).Value = sente
            ws.Cells(rowIdx, 4).Value = gote
            
            rowIdx = rowIdx + 1
            ts.Close
        End If
    Next file
    
    Application.ScreenUpdating = True
    MsgBox "棋譜一覧の作成が完了しました。", vbInformation
End Sub

実務アドバイス

実務レベルでこのコードを運用する場合、以下の3点に注意してください。

第一に「文字コードの判定」です。棋譜ファイルはShift-JISで保存されている場合とUTF-8で保存されている場合があります。VBA標準のTextStreamはShift-JISに強いため、UTF-8ファイルを読み込むと文字化けが発生します。その場合は「ADODB.Stream」オブジェクトを使用して、文字コードを指定して読み込む設計にアップグレードする必要があります。

第二に「パフォーマンスの最適化」です。ファイル数が数千件を超える場合、一行ずつセルに書き込む処理は非常に低速になります。一度、Variant型の2次元配列に全データを格納し、最後に「ws.Range(“A2”).Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr」のように一括転記することで、処理速度を劇的に向上させることができます。

第三に「正規表現の活用」です。単純なInStr関数では、表記揺れ(例:「先手」「先手:」「先手:」)に対応できません。正規表現(VBScript.RegExp)を導入し、パターンマッチングを行うことで、より柔軟かつ正確なデータ抽出が可能になります。

まとめ

Excel VBAを用いた棋譜データの一括管理は、単に「データを整理する」だけでなく、大量の非構造化データを構造化データへ変換する「ETL(Extract/Transform/Load)プロセス」の基礎を学ぶ絶好の機会です。今回紹介したコードは、あくまでスタート地点です。ここから、勝敗判定の自動化、戦型解析の自動化、さらには抽出したデータを別のシートでグラフ化するなどの機能を追加していくことで、あなただけの強力な棋譜管理システムへと成長させることができます。

プロフェッショナルなVBA開発者を目指すのであれば、まずはこの仕組みを理解し、自身の環境に合わせてカスタマイズすることから始めてください。コードの読み書きを繰り返すことで、変数のスコープ管理やオブジェクトモデルへの理解が深まり、将棋データの処理だけでなく、あらゆるExcel業務の自動化において大きな武器となるはずです。VBAの可能性は無限大です。ぜひ、このサンプルをベースに、さらに洗練されたツールへと昇華させてください。

タイトルとURLをコピーしました