CsvDataReader のバグ? - umemura - 04-01-2013
CsvDataReader では、行末がカンマのみの場合、無視されているように思います。
たとえば、「,,,」というCSVを読み込むと、
列数は、3 となります。
(read-record で読み込んで確認すると、"","","" というデータとして保持されている)。
これは、望ましくないです。
null もしくは空文字の4列のデータになるべきかと思います。
これは、バグでしょうか。
また、回避する方法はありますでしょうか。
RE: CsvDataReader のバグ? - umemura - 09-08-2014
CsvDataReader のクラスを継承して回避できました。
Code: {curl 8.0 applet}
{curl-file-attributes character-encoding = "utf8"}
{applet manifest = "manifest.mcurl",
{compiler-directives careful? = true}
}
{define-class public open CustomCsvDataReader {inherits CsvDataReader}
{constructor public {default ...}
{construct-super {splice ...}}
}
{method protected open {split-record out:StringArray}:StringArray
def recs = {super.split-record out}
||行の最後が "," の場合に、空の列として認識されないため
||返却される文字配列に追加してやる
def line-str = {self.current-line.trim-clone}
{if line-str[line-str.size - 1] == ',' then
{out.append ""}
}
{return recs}
}
}
||CSVの行数をカウントする
{define-proc public {count-column-size
url:Url
,header-line-count:int = 0
,columns:#{Array-of RecordGridColumn} = null
,character-encoding:CharEncoding = {get-character-encoding-by-name "shift-jis"}
}:void
||カラム数チェックのための、実際のCSVのカラム数
let csv-col-size:int = 0
||継承したクラスを利用するかどうか
let csv-reader:CsvDataReader =
{CustomCsvDataReader
header-line-count = header-line-count,
url, character-encoding = character-encoding
}
def default = {{Array-of int}}
||各業の列数を取得
{while csv-reader.done? == false do
{if-non-null tmp-col = {csv-reader.read-record} then
{default.append tmp-col.size}
}
}
set csv-reader =
{CsvDataReader
header-line-count = header-line-count,
url, character-encoding = character-encoding
}
def custom = {{Array-of int}}
||各業の列数を取得
{while csv-reader.done? == false do
{if-non-null tmp-col = {csv-reader.read-record} then
{custom.append tmp-col.size}
}
}
def tbl = {Table columns = 3, "行数","列個数(CsvDataReader)", "列個数(CustomCsvDataReader)"}
{for i:int = 0 below custom.size do
{tbl.add i + 1}
{tbl.add default[i]}
{tbl.add custom[i]}
}
{popup-message tbl}
}
{def ta =
{TextArea
width = 4in , height = 2in,
value =
"1,2,3\n" &
"1,\n" &
"1\n" &
",\n" &
"\"\",\"\"\n" &
" , "
}
}
{VBox
ta,
{CommandButton
label = "CSVの列をカウント",
{on Action do
{count-column-size {string-url ta.value }}
}
}
}
下記に公開されている実装コードを参考にしました。
(オープンコントロール以外でも、公開されているファイルがあったんですね)
Program Files\Curl Corporation\Surge\9\ide\data-access\base\impl\csv-recordset.scurl
RE: CsvDataReader のバグ? - rom - 09-11-2014
(04-01-2013, 06:14 PM)umemura Wrote: CsvDataReader では、行末がカンマのみの場合、無視されているように思います。
たとえば、「,,,」というCSVを読み込むと、
列数は、3 となります。
(read-record で読み込んで確認すると、"","","" というデータとして保持されている)。
これは、望ましくないです。
null もしくは空文字の4列のデータになるべきかと思います。
これは、バグでしょうか。
また、回避する方法はありますでしょうか。 umemuraさん
お久しぶりです。
僕もCsvDataReaderを使う際に気になっていました!
>CsvDataReader のクラスを継承して回避できました。
クラスを継承して回避すればよかったのですね。。。
僕は「CsvDataReader.from-stream」でストリームを読み込んだ時に
この現象が発生して悩んでいましたが、解決策?その場しのぎ?として
ストリームの行末にカンマを足して、無理やり読ませていました!
キチンとした解決策が分かってよかったです!
|