コード例 #1
0
        //────────────────────────────────────────
        #endregion



        #region アクション
        //────────────────────────────────────────

        /// <summary>
        /// <summary>
        /// CSVを読取り、テーブルにして返します。
        ///
        ///
        /// SRS仕様の実装状況
        /// ここでは、先頭行を[0]行目と数えるものとします。
        /// (1)CSVの[0]行目は列名です。
        /// (2)CSVの[1]行目は型名です。
        /// (3)CSVの[2]行目はコメントです。
        ///
        /// (4)データ・テーブル部で、0列目に「EOF」と入っていれば終了。大文字・小文字は区別せず。
        ///    それ以降に、コメントのようなデータが入力されていることがあるが、フィールドの型に一致しないことがあるので無視。
        ///    TODO: EOF以降の行も、コメントとして残したい。
        ///
        /// (5)列名に ”END”(半角) がある場合、その手前までの列が有効データです。
        ///    ”END”以降の列は無視します。
        ///    TODO: ”END”以降の行も、コメントとして残したい。
        ///
        /// (6)int型として指定されているフィールドのデータ・テーブル部に空欄があった場合、DBNull(データベース用のヌル)とします。
        /// </summary>
        /// <param name="contents">CSVテキスト</param>
        /// <param name="request">要求</param>
        /// <param name="format_puts">設定するフォーマット</param>
        /// <param name="log_Reports"></param>
        /// <returns>列名情報も含むテーブル。列の型は文字列型とします。</returns>
        public Table_Humaninput Read(
            string contents,
            Request_ReadsTable request,
            Format_Table format_puts,
            Log_Reports log_Reports
            )
        {
            Log_Method log_Method = new Log_MethodImpl();

            log_Method.BeginMethod(Info_Table.Name_Library, this, "Read(1)", log_Reports);

            Table_Humaninput xTable = new Table_HumaninputImpl(
                request.Name_PutToTable, request.Expression_Filepath, request.Expression_Filepath.Conf);

            xTable.Tableunit               = request.Tableunit;
            xTable.Typedata                = request.Typedata;
            xTable.IsDatebackupActivated   = request.IsDatebackupActivated;
            xTable.Format_Table_Humaninput = format_puts;


            Exception err_Excp;
            int       error_Count_Index;

            string[] error_Fields_Cur;


            //
            // 型定義部
            //
            // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル)
            //
            RecordFielddef rFielddef = new RecordFielddefImpl();

            //
            // データ・テーブル部
            //
            List <List <string> > dataTableRows = new List <List <string> >();

            // CSVテキストを読み込み、型とデータのバッファーを作成します。
            System.IO.StringReader reader    = new System.IO.StringReader(contents);
            CsvLineParserImpl      csvParser = new CsvLineParserImpl();

            // CSVを解析して、テーブル形式で格納。
            {
                // データとして認識する列の総数です。
                int nDataColumnsCount = 0;

                // 行番地(0開始)
                int      nRow = 0;
                string[] fields_Cur;
                while (-1 < reader.Peek())
                {
                    string line = reader.ReadLine();

                    fields_Cur = csvParser.UnescapeLineToFieldList(line, this.charSeparator).ToArray();


                    if (0 == nRow)
                    {
                        // 0行目

                        // 列名の行とします。

                        for (int nColumnIx = 0; nColumnIx < fields_Cur.Length; nColumnIx++)
                        {
                            string sColumnName = fields_Cur[nColumnIx];

                            // 列名を読み込みました。

                            // トリム&大文字
                            string sCellValueTU = sColumnName.Trim().ToUpper();
                            if (
                                ToCsv_Table_RowColRegularImpl_.S_EOL == sCellValueTU ||
                                ToCsv_Table_RowColRegularImpl_.S_END == sCellValueTU
                                )
                            {
                                // 列名に ”END” がある場合、その手前までの列が有効データです。
                                // ”END” 以降の列は無視します。
                                goto field_name_reading_end;
                            }

                            // テーブルのフィールドを追加します。型の既定値は文字列型とします。
                            FielddefImpl fieldDef = new FielddefImpl(sColumnName, EnumTypeFielddef.String);
                            rFielddef.Add(fieldDef);
                            nDataColumnsCount++;
                        }


                        // 0行目は、テーブルのデータとしては持ちません。
                    }
                    else if (1 == nRow)
                    {
                        // 1行目

                        // フィールド型名の行。

                        for (int nColumnIx = 0; nColumnIx < nDataColumnsCount; nColumnIx++)
                        {
                            string name_FieldType_Lower;
                            try
                            {
                                name_FieldType_Lower = fields_Cur[nColumnIx].ToLower();
                            }
                            catch (IndexOutOfRangeException e)
                            {
                                err_Excp = e;
                                goto gt_Error_FdIndexOutOfRangeException;
                            }

                            // 列の型名を読み込みました。

                            // テーブルのフィールドを追加します。型の既定値は文字列型とします。
                            // TODO int型とboolean型にも対応したい。
                            if (FielddefImpl.S_STRING.Equals(name_FieldType_Lower))
                            {
                                rFielddef.ValueAt(nColumnIx).Type_Field = EnumTypeFielddef.String;
                            }
                            else if (FielddefImpl.S_INT.Equals(name_FieldType_Lower))
                            {
                                rFielddef.ValueAt(nColumnIx).Type_Field = EnumTypeFielddef.Int;
                            }
                            else if (FielddefImpl.S_BOOL.Equals(name_FieldType_Lower))
                            {
                                // 2009-11-11修正:SRS仕様では「bool」が正しい。「boolean」は間違い。
                                rFielddef.ValueAt(nColumnIx).Type_Field = EnumTypeFielddef.Bool;
                            }
                            else
                            {
                                // 型が未定義の列は、文字列型として読み取ります。

                                // TODO:警告を出すか?

                                rFielddef.ValueAt(nColumnIx).Type_Field = EnumTypeFielddef.String;
                            }
                        }

                        // 1行目は、テーブルのデータとしては持ちません。
                    }
                    else if (2 == nRow)
                    {
                        // 2行目

                        // フィールドのコメントの行。
                        // TODO: フィールドのコメントの行は省略されることがある。

                        for (int column = 0; column < nDataColumnsCount; column++)
                        {
                            if (fields_Cur.Length <= column)
                            {
                                error_Fields_Cur = fields_Cur;
                                //error_Count_Columns = fields_Cur.Length;
                                error_Count_Index = column;
                                goto gt_Error_CommentFieldCount;
                            }

                            string comment_Field = fields_Cur[column];//todo:bug:境界線エラーをキャッチしてない。

                            rFielddef.ValueAt(column).Comment = comment_Field;
                        }

                        // 2行目は、テーブルのデータとしては持ちません。
                    }
                    else
                    {
                        // 3行目以降のループ。
                        List <string> sList_Column = new List <string>();

                        // データ・テーブル部で、0列目に「EOF」と入っていれば終了。大文字・小文字は区別せず。

                        if (fields_Cur.Length < 1)
                        {
                            // 空行は無視。
                            goto end_recordAdd;
                        }
                        //ystem.Console.WriteLine(InfxenonTable.LibraryName + ":" + this.GetType().Name + "#UnescapeToList: sFields[0]=[" + sFields[0] + "] sLine=[" + sLine + "]");

                        string sCellValueTrimUpper = fields_Cur[0].Trim().ToUpper();
                        if (ToCsv_Table_RowColRegularImpl_.S_EOF == sCellValueTrimUpper)
                        {
                            goto reading_end;
                        }

                        int nColumnCount;
                        if (fields_Cur.Length < nDataColumnsCount)
                        {
                            // 「実際にデータとして存在する列数」
                            nColumnCount = fields_Cur.Length;
                        }
                        else
                        {
                            // 「データとして存在する筈の列数」(これ以降の列は無視)
                            nColumnCount = nDataColumnsCount;
                        }


                        for (int nColumnIx = 0; nColumnIx < nColumnCount; nColumnIx++)
                        {
                            string sValue;

                            sValue = fields_Cur[nColumnIx];

                            if (rFielddef.Count <= nColumnIx)
                            {
                                // 0行目で数えた列数より多い場合。

                                // テーブルのフィールドを追加します。型は文字列型とします。名前は空文字列です。
                                rFielddef.Add(new FielddefImpl("", EnumTypeFielddef.String));
                            }

                            sList_Column.Add(sValue);
                        }

                        dataTableRows.Add(sList_Column);
end_recordAdd:
                        ;
                    }
field_name_reading_end:

                    //essageBox.Show("ttbwIndex=[" + ttbwIndex + "]行目ループ終わり", "TableCsvLibデバッグ");
                    nRow++;
                }
            }
reading_end:

            // ストリームを閉じます。
            reader.Close();

            //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ");


            // テーブルのフィールド定義。
            xTable.CreateTable(rFielddef, log_Reports);
            if (log_Reports.Successful)
            {
                // データ本体のセット。
                xTable.AddRecordList(dataTableRows, rFielddef, log_Reports);
            }

            goto gt_EndMethod;
            //
            //
            #region 異常系
            //────────────────────────────────────────
gt_Error_CommentFieldCount:
            if (log_Reports.CanCreateReport)
            {
                Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error);
                r.SetTitle("▲エラー1356!", log_Method);

                Log_TextIndented s = new Log_TextIndentedImpl();

                s.Append("「フィールド・コメント」行のフィールド数が合いませんでした。");
                s.Append(Environment.NewLine);
                s.Append(Environment.NewLine);
                s.Append("もしかして?");
                s.Append(Environment.NewLine);
                s.Append("  ・1行目の最後のフィールドには「EOL」を入れてください。");
                s.Append(Environment.NewLine);
                s.Append(Environment.NewLine);

                s.Append("index=[");
                s.Append(error_Count_Index);
                s.Append("]");
                s.Append(Environment.NewLine);

                s.Append("列数=[");
                s.Append(error_Fields_Cur.Length);
                s.Append("]");
                s.Append(Environment.NewLine);
                s.Append(Environment.NewLine);

                //
                // ヒント
                s.Append(Log_RecordReportsImpl.ToText_Conf(xTable));
                s.Append(Environment.NewLine);

                s.Append(Environment.NewLine);
                s.Append(Environment.NewLine);
                s.Append("──────────fields ここから");
                s.Append(Environment.NewLine);
                foreach (string field in error_Fields_Cur)
                {
                    s.Append("field=[");
                    s.Append(field);
                    s.Append("]");
                    s.Append(Environment.NewLine);
                }
                s.Append("──────────fields ここまで");

                r.Message = s.ToString();
                log_Reports.EndCreateReport();
            }
            goto gt_EndMethod;
            //────────────────────────────────────────
gt_Error_FdIndexOutOfRangeException:
            if (log_Reports.CanCreateReport)
            {
                Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error);
                r.SetTitle("▲エラー132!", log_Method);

                Log_TextIndented s = new Log_TextIndentedImpl();
                s.Newline();

                s.Append("フィールド定義の数が合いませんでした。");
                s.Append(Environment.NewLine);
                s.Append(Environment.NewLine);

                string sFpatha = request.Expression_Filepath.Lv4Execute_OnImplement(
                    EnumHitcount.Unconstraint, log_Reports);
                s.Append("ファイルパス=[");
                s.Append(sFpatha);
                s.Append("]");
                s.Append(Environment.NewLine);
                s.Append(Environment.NewLine);

                //
                // ヒント
                s.Append(err_Excp.Message);

                r.Message = s.ToString();
                log_Reports.EndCreateReport();
            }
            goto gt_EndMethod;
            //────────────────────────────────────────
            #endregion
            //
            //
gt_EndMethod:
            log_Method.EndMethod(log_Reports);
            return(xTable);
        }