最終更新日 2024-09-25

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

概要

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

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

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

ダウンロード

更新日 2017/12/15
CsvHelper.zip v1.30

説明

秀丸のマクロで「非常に難解な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);
    

ライセンス