Curl Global Community
CsvDataReader のバグ? - Printable Version

+- Curl Global Community (https://communities.curl.com)
+-- Forum: Discussions (https://communities.curl.com/forumdisplay.php?fid=1)
+--- Forum: General Curl questions (https://communities.curl.com/forumdisplay.php?fid=2)
+--- Thread: CsvDataReader のバグ? (/showthread.php?tid=879)



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」でストリームを読み込んだ時に
この現象が発生して悩んでいましたが、解決策?その場しのぎ?として
ストリームの行末にカンマを足して、無理やり読ませていました!

キチンとした解決策が分かってよかったです!