IronPythonの例題のひとつとなります。
難解なCSVデータであっても正しく読み取るためのサンプルです。
マネージドdll(.NET用DLL)だけ公開されているような「配布ライブラリ」を、
hmPyを経由して、いかに手軽に秀丸マクロから利用するか、といったサンプルでもあります。
秀丸のマクロで「非常に難解なCSVデータであっても」、Excelと同程度相当の読み取り精度を誇る
CsvHelper.dllをマクロ内で利用するサンプルとなります。
上記zipファイルには一式が入っていますので、.mac内のファイル指定と、.csvのパスの位置は合わせるようにしてください。
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内に記載されています。
パブリックドメインとします。(即ち利用は自由)
Josh Close著作物であり、MS-PL 及び、Apache ライセンス 2.0 のデュアルライセンスとなります。
詳細はCsvHelper Githubサイトを確認してください。