「hmPy・IronPython」のその他の例題 CSVの読み込み

  • 概要

    IronPythonの例題のひとつとなります。

    難解なCSVデータであっても正しく読み取るためのサンプルです。

    マネージドdll(.NET用DLL)だけ公開されているような「配布ライブラリ」を、
    hmPyを経由して、いかに手軽に秀丸マクロから利用するか、といったサンプルでもあります。

  • ダウンロード

    DOWNLOAD ⇒ CsvHelper.zip v1.30ファイル。
    └更新日 2017/04/08

    説明

    秀丸のマクロで「非常に難解なCSVデータであっても」、Excelと同程度相当の読み取り精度を誇る
    CsvHelper.dllをマクロ内で利用するサンプルとなります。

    上記zipファイルには一式が入っていますので、.mac内のファイル指定と、.csvのパスの位置は合わせるようにしてください。

    難解なCSVデータが含まれている例

    (※残念ながら「秀丸本体」はこのCSVを正しく解釈できません)

    IronPythonの部分

    IronPythonの部分で.NET FrameworkのライブラリとなるCsvHelperを読み込み、秀丸マクロから取り扱えるインターフェイスにしましょう。
    今回は、単純に2次元データとして読み込んでいますが、CsvHelperの本領は、
    クラスデータ構造と直接紐づけ可能なことにありますのでIronPythonであれば、どちらにでもテキスト記述で対応できます。

    また、今回のサンプルでは触れていませんが、CsvHelperは読み込みだけではなく、書き込みにも利用することが可能です。
    詳細はCsvHelper Githubサイトを確認してください。

    # coding: cp932
    
    # このcsvhelper.pyはただのサンプルコードです。ご自由にお使いください。
    
    # 途中エラーでもクリアしておかねばならない
    CsvAllData = []
    RowCount = 0
    
    
    import clr
    import sys
    sys.path.append(hm.Macro.Var["currentmacrodirectory"])
    clr.AddReferenceByPartialName( "CsvHelper")
    clr.AddReferenceByPartialName( "System.Windows.Forms" )
    
    import System.IO
    import System.Text
    import System.Collections.Generic
    
    from CsvHelper import *
    
    # デバッグ用途
    __PYDEBUG__ = 0
    if __PYDEBUG__:
    	class HM:
    	    def debuginfo(self, str):
    	        print(str+"\n")
    
    	hm = HM()
    	target_csv_filename = r"C:\usr\hidemaru\csvhelper\a.csv"
    
    
    try:
        target_csv_filename = target_csv_filename
    except:
        System.Windows.Forms.MessageBox.Show("ファイル名が指定されていません。", "エラー", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error)
        raise IOError
    
    
    try:
        target_csv_encoding = target_csv_encoding
    except:
        target_csv_encoding = "shift_jis"
        hm.debuginfo("エンコーディングの指定が無いため、csvはCP932(SJIS)の文字コードとみなします")
    
    
    try:
        encoding = System.Text.Encoding.GetEncoding(target_csv_encoding)
    except:
        hm.debuginfo("存在しないエンコーディング名の指定。CP932(SJIS)の文字コードとみなします")
        target_csv_encoding = "shift_jis"
        encoding = System.Text.Encoding.GetEncoding(target_csv_encoding)
    
    
    try:
        print(target_csv_filename)
        file_stream = System.IO.StreamReader(target_csv_filename, encoding)
        parser = CsvParser(file_stream);
    except Exception:
        System.Windows.Forms.MessageBox.Show("CSVファイルの読み取りエラー", "エラー", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error)
        System.Console.WriteLine(Exception)
        if file_stream:
            file_stream.Close()
        raise IOError
    
    
    
    RowCount = 0
    while (True):
        try:
            row_data = parser.Read();
            if row_data == None:
                break;
    
            # 全体のデータに1行足す
            CsvAllData.append(row_data[:])
            print(row_data)
            RowCount = RowCount + 1
        except:
            break;
    
    
    file_stream.Close();
    
    # データ全体の行数
    def GetRowCount():
        return RowCount
    
    # 対象の1行内のデータ数を得る
    def GetColCount(row_ix):
        try:
            global CsvAllData
            row_data = CsvAllData[row_ix]
            return row_data.Count
        except:
            hm.debuginfo("データの範囲外です")
            raise IndexError
    
    
    # 指定のセルデータを得る
    def GetCellItem(row_ix, col_ix):
        try:
            return CsvAllData[row_ix][col_ix]
        except:
            hm.debuginfo("データの範囲外です")
            return ""
    
    
  • マクロ側の処理

    マクロ側では「読み込むファイル」や「対象ファイルの文字コード」を指定することとなるでしょう。
    指定可能なエンコーディング文字については、「http://dobon.net/vb/dotnet/string/getencodingobject.html」などを参照してください。

    // このcsvhelper.macはサンプルコードです自由にご利用ください。
    
    #PY = loaddll( hidemarudir + @"\hmPy.dll" );
    
    if (!#PY) {
        message("hmPyが未導入のようです");
        endmacro;
    }
    
    // 前準備
    // サンプルにあるようなcsvファイルのフルパスを指定してください。
    #_ = dllfuncw(#PY, "DoString", R"IPY(
    
    target_csv_filename = "C:\\work\\test.csv"; 
    target_csv_encoding = "shift_jis";
    
    )IPY"
    );
    
    // csvhelper.pyを実行
    #IS = dllfuncw(#PY, "DoFile", currentmacrodirectory + @"\csvhelper.py" );
    
    // 実際のデータを得る
    #_ = dllfuncw(#PY, "DoString", R"IPY(
    
    data_row_count = GetRowCount()
    hm.debuginfo("全部で何行:" + str(data_row_count))
    
    data_item = GetCellItem(1, 2)
    hm.debuginfo("Cell(1,2)のデータ:" + data_item);
    
    
    )IPY"
    );
    
    freedll(#PY);
        
  • ライセンス

      HmCsvHelper.zipのLICENSE.txt内に記載されています。

    • HmCsvHelper.mac, HmCsvHelper.pyのについて

      パブリックドメインとします。(即ち利用は自由)

    • CsvHelper.dllについて

      Josh Close著作物であり、MS-PL 及び、Apache ライセンス 2.0 のデュアルライセンスとなります。
      詳細はCsvHelper Githubサイトを確認してください。