テーブルのレコードから、CSVファイルを生成する方法をご紹介します。
はじめに
テーブルのレコードから、CSVファイルを作成する方法をご紹介します。
今回の方法は、「SQL.Export.Mgr.cls」を利用して、CSVを出力します。
全件出力するので、出力条件を定義する事が出来ませんが、レコードを簡易に出力できるので利便性は高いです。
また、テーブル毎の出力関数を作成する必要がないのもメリットです。
CSVファイルの取り込みに関しては、下記記事を参照してください。
CSVファイルをエクスポートする
前述した通り、CSVファイルを出力するには「SQL.Export.Mgr.cls」を使用します。
サンプルは下記になります。
関数の解説は後程行います。
ClassMethod export(fileName As %String, clsNm As %String, rowName As %String, rowType As %String = "", dlm As %String = ",", charSet As %String = "UTF8")
{
s (makeRflg,openFlg, total,rows) = 0
try {
s mgr = ##class(%SQL.Export.Mgr).%New()
s sNm = $tr($ClassMethod(clsNm, "%PackageName"),".","_")
, tNm = $ClassMethod(clsNm, "%ClassName")
s mobj = ##class(%SQL.Manager.API).%New()
$$$ThrowOnError(mobj.CheckIdentifier(.sNm))
$$$ThrowOnError(mobj.CheckIdentifier(.tNm))
s mgr.FileName = fileName
s mgr.TableName = sNm_"."_tNm
s mgr.IQN = $$$BuildIQN(sNm,tNm)
// CSVファイルの設定
s mgr.Delimiter = dlm
//s mgr.StringQuote = ""
s mgr.Charset = charSet
s mgr.HasHeaders = 1 // 1:ヘッダを出力
// 日時フォーマット
s mgr.DateFormat = 3
s mgr.TimeFormat = 1
// CSVカラムと型を設定
f pos=1:1:$l(rowName,",") d mgr.ColumnNames.Insert($p(rowName,",",pos))
i (rowType'="") f pos=1:1:$l(rowType,",") d mgr.ColumnTypes.Insert($p(rowType,",",pos))
$$$ThrowOnError(mgr.GenerateExportRoutine()) s makeRflg = 1
$$$ThrowOnError(mgr.OpenExport()) s openFlg = 1
d {
$$$ThrowOnError( mgr.ExportRows(.rows, .done))
s total = total + rows
} while('done)
$$$ThrowOnError( mgr.CloseExport() ) s openFlg = 0
$$$ThrowOnError( mgr.DeleteExportRoutine() )
}catch e {
w !,$System.Status.DisplayError(e.AsStatus())
d:(openFlg) mgr.CloseExport() // ファイルを閉じる
d:(makeRflg) mgr.DeleteExportRoutine() // ルーチン削除
}
w !!,$$$FormatText("総数:%1 at %2", total, $zdt($h,3,1))
}
解説
関数の引数を解説
引数名 | 説明 |
---|---|
fileName | CSVファイルの出力先(ファイル名含む) |
clsNm | 出力対象テーブルの名称 |
rowName | CSVファイルの列名を指定する ※データクラスのプロパティ名と一致させる必要があり |
rowType | CSVファイルの列の型を指定する ・D – Date ・TS – TimeStamp // あまり役に立っていない「S」でもいい ・N – Numeric ・S – String ・STREAM – Stream ・T – Time |
dlm | デリミタ(初期値=”,”) |
charSet | ファイルの文字コード(初期値=”UTF8″) |
出力するプロパティが全てString型であれば、rowTypeの指定は不要です。
もし、プロパティの型に「%Date」や「%Time」等を出力する場合は、型指定を行わないと$horolog型のまま出力します。
出力処理の解説
先ずは、クラス「%SQL.Export.Mgr.cls」をインスタンス化する事から始まります。
s mgr = ##class(%SQL.Export.Mgr).%New()
「FileName」「TableName」「IQN」は必須の設定になります。
s mgr.FileName = fileName // 出力先のファイル名とパス
s mgr.TableName = sNm_"."_tNm // SQLで使用するテーブル名称
s mgr.IQN = $$$BuildIQN(sNm,tNm) // 内部用
「Delimiter」は、ファイルの区切り文字を指定します。
TSVファイル時は「$c(9)」を設定します。
出力値を特定の文字で括りたい場合は、「StringQuote」を指定します。
ただし、全ての値が括られるわけではありません。
String型、Stream型であり、区切り文字・括り文字が含まれる, 値の前後に半角スペースが含まれている等々の条件が必要になります。
ファイルの文字コードを「Charset」に指定します。
ヘッダを出力する場合は「HasHeaders」に「1」を指定します。
s mgr.Delimiter = dlm
s mgr.StringQuote = """"
s mgr.Charset = charSet
s mgr.HasHeaders = 1 // 1:ヘッダを出力
「DateFormat」「TimeFormat」も、各$zDate(val, format), $zTime(val, format)のformat部を指定します。
s mgr.DateFormat = 3
s mgr.TimeFormat = 1
カラム(列)の名称と型を設定します。
プロパティ名とカラム名は完全一致である必要があります。
f pos=1:1:$l(rowName,",") d mgr.ColumnNames.Insert($p(rowName,",",pos))
i (rowType'="") f pos=1:1:$l(rowType,",") d mgr.ColumnTypes.Insert($p(rowType,",",pos))
出力部分のメイン処理になります。
d {
$$$ThrowOnError( mgr.ExportRows(.rows, .done))
s total = total + rows
} while('done)
引数「rows」を足していくと、読み込んだ総レコード数となります。
引数「done=1」で、最終行の読み込み完了となります。
出力部のミソ
下記は「%SQL.Export.Mgr.mac」で、レコードを取得する処理(SQL文)を生成する処理になります。
Set text=" &SQL(DECLARE Z CURSOR FOR SELECT"
; SELECT list
Set colno=1
For i=1:1:cols Do
. Set name=..ColumnNames.GetAt(i),type=..ColumnTypes.GetAt(i)
. Set:name'="" text=text_$S(colno=1:" ",1:", ")_$s(type'="STREAM":name,1:"%OBJECT("_name_")"),colno=colno+1
Set text=text_" INTO"
; INTO list
Set colno=1
For i=1:1:cols Do
. Set name=..ColumnNames.GetAt(i)
. Set:name'="" text=text_$S(colno=1:" ",1:", ")_"%d("_colno_")",colno=colno+1
Set text=text_" FROM "_..TableName_")"
Do rtn.WriteLine(text)
「%SQL.Export.Mgr」を利用してのCSVファイル出力は、下記のような特性があります。
また、生成されたルーチンを確認してみます。
Write %d(1),",",%d(2),",",%d(3),",",$$QUOTE(%d(4)),",",$$QUOTE(%d(5)),",",$$QUOTE(%d(6)),",",$$QUOTE(%d(7)),",",$$QUOTE(%d(8)),",",$$QUOTE(%d(9)),",",$$QUOTE(%d(10)),",",$$QUOTE(%d(11)),",",$S(%d(12)="":"",1:$ZDT(%d(12),3)),",",%d(13),",",$$QUOTE(%d(14)),",",$S(%d(15)="":"",1:$ZDT(%d(15),3)),",",$$QUOTE(%d(16)),",",$$QUOTE(%d(17)),",",%d(18),!
QUOTE(s) { If s'["",s'[",",$l($zstrip(s,"<>W"))=$l(s),s'[$c(10) Quit s
For i=$l(s,""):-1:2 Set $piece(s,"",i)=""_$piece(s,"",i)
Quit ""_s_"" }
おわりに
今回はCSVファイルの出力をご紹介致しました。
「%SQL.Export.Mgr」を利用すれば、「出力PGを別途作成する必要がない」為、非常に使い勝手の良い方法だと思います。
ただし、対象レコードを絞り込む事が出来ない、%DateTimeや特殊な型に対応出来ない等、全ての値にたいし特定文字で括れない等、若干機能制限があります。
それでも、ターミナル等で設定すれば簡単にCSVファイルが出力できるので、活用するタイミングはあると思います。