「hmPy・IronPython」のその他の例題 CSVの読み込み
概要
IronPythonの例題のひとつとなります。
難解なCSVデータであっても正しく読み取るためのサンプルです。
マネージドdll(.NET用DLL)だけ公開されているような「配布ライブラリ」を、
hmPyを経由して、いかに手軽に秀丸マクロから利用するか、といったサンプルでもあります。

ダウンロード
説明
秀丸のマクロで「非常に難解なCSVデータであっても」、Excelと同程度相当の読み取り精度を誇る
CsvHelper.dllをマクロ内で利用するサンプルとなります。
上記zipファイルには一式が入っていますので、.mac内のファイル指定と、.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.mac, HmCsvHelper.pyのについて
パブリックドメインとします。(即ち利用は自由)
-
CsvHelper.dllについて
Josh Close著作物であり、MS-PL 及び、Apache ライセンス 2.0 のデュアルライセンスとなります。
詳細はCsvHelper Githubサイトを確認してください。
HmCsvHelper.zipのLICENSE.txt内に記載されています。