//──────────────────────────────────────── /// <summary> /// テーブル読取。 /// </summary> /// <param name="forTable_request"></param> /// <param name="forTable_format"></param> /// <param name="log_Reports"></param> /// <returns></returns> private Table_Humaninput ReadTable( Request_ReadsTable forSubTable_Request_TblReads, Format_Table_Humaninput o_TableFormat_ForSubTable_Puts, Log_Reports log_Reports ) { Table_Humaninput o_Tbl; if (log_Reports.Successful) { // 正常時 // // テーブル読取り CsvTo_Table_HumaninputImpl reader = new CsvTo_Table_HumaninputImpl(); // テーブル o_Tbl = reader.Read( forSubTable_Request_TblReads, o_TableFormat_ForSubTable_Puts, true, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 goto gt_EndMethod; } if (log_Reports.Successful) { // 正常時 // NOフィールドの値を 0からの連番に振りなおします。 o_Tbl.RenumberingNoField(); } } else { o_Tbl = null; } // // // // gt_EndMethod: return(o_Tbl); }
//──────────────────────────────────────── private Table_Humaninput Read_AaFilesCsv(Log_Reports log_Reports) { //「Aa_Files.csv」を読み取る要求を作成します。 Request_ReadsTable forAafilescsv_Request = this.CreateReadRequest_AaFilesCsv(log_Reports); Format_Table_Humaninput forAafilescsv_Format = this.ReadIndexFormat(); // // 「Aa_Files.csv」読取り CsvTo_Table_HumaninputImpl reader = new CsvTo_Table_HumaninputImpl(); Table_Humaninput xenonTable_Aafilescsv; if (log_Reports.Successful) { // 正常時 xenonTable_Aafilescsv = reader.Read( forAafilescsv_Request, forAafilescsv_Format, true, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 goto gt_EndMethod; } } else { xenonTable_Aafilescsv = null; } // // // // gt_EndMethod: return(xenonTable_Aafilescsv); }
//──────────────────────────────────────── /// <summary> /// パーサーのハブ。 /// /// </summary> /// <param name="request_ReadsTable">テーブルに付けたい名前や、ファイルパスの要求。</param> /// <param name="xenonTableFormat_puts">テーブルの行列が逆になっているなどの、設定。</param> /// <param name="isRequired">テーブルが無かった場合、エラーとするなら真。</param> /// <param name="out_sErrorMsg"></param> /// <returns></returns> public Table_Humaninput Read( Request_ReadsTable request_ReadsTable, Format_Table_Humaninput xenonTableFormat_puts, bool isRequired, Log_Reports log_Reports ) { Log_Method log_Method = new Log_MethodImpl(); log_Method.BeginMethod(Info_Table.Name_Library, this, "Read",log_Reports); Table_Humaninput xenonTable_Result; string filepathabsolute_Csv = request_ReadsTable.Expression_Filepath.Execute4_OnExpressionString( EnumHitcount.Unconstraint, log_Reports); if (!log_Reports.Successful) { // 既エラー。 xenonTable_Result = null; goto gt_EndMethod; } string string_Csv; // CSVテキスト Exception error_Excp; if (CsvTo_Table_HumaninputImpl.S_WRITE_ONLY!=request_ReadsTable.Use) { // 書き出し専用でなければ。 // ファイル読取を実行します。 try { if (!System.IO.File.Exists(filepathabsolute_Csv)) { // ファイルが存在しない場合。 xenonTable_Result = null; goto gt_Error_NotExistsFile; } // TODO:IOException 別スレッドで開いているときなど。 string_Csv = System.IO.File.ReadAllText(filepathabsolute_Csv, Global.ENCODING_CSV); //log_Method.WriteDebug_ToConsole(string_Csv); } catch (System.IO.IOException e) { // エラー処理。 xenonTable_Result = null; string_Csv = ""; error_Excp = e; goto gt_Error_FileOpen; } catch (Exception e) { // エラー処理。 xenonTable_Result = null; string_Csv = ""; error_Excp = e; goto gt_Error_Exception; } } else { string_Csv = ""; } xenonTable_Result = this.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 goto gt_EndMethod; } // NOフィールドの値を 0からの連番に振りなおします。 xenonTable_Result.RenumberingNoField(); if (isRequired && null == xenonTable_Result) { goto gt_Error_NullTable; } goto gt_EndMethod; // // #region 異常系 //──────────────────────────────────────── gt_Error_FileOpen: if (log_Reports.CanCreateReport) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("Er:201;", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("ファイルの読取りに失敗しました。"); s.Newline(); s.Newline(); s.Append(" ファイル=["); s.Append(filepathabsolute_Csv); s.Append("]"); s.Newline(); s.Newline(); s.Append("もしかして?"); s.Newline(); s.Append(" ・ファイルの有無、ファイル名、ファイル パスを確認してください。"); s.Newline(); s.Append(" ・別アプリケーションで ファイルを開いていれば、閉じてください。"); s.Newline(); s.Newline(); // // ヒント request_ReadsTable.Expression_Filepath.Cur_Configuration.ToText_Locationbreadcrumbs(s); s.Append(error_Excp.Message); r.Message = s.ToString(); log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── gt_Error_NotExistsFile: if(log_Reports.CanCreateReport) { if ("" == request_ReadsTable.Expression_Filepath.Directory_Base) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("Er:202;", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("指定されたファイルはありませんでした。CSVファイルを読み込もうとしたとき。"); s.Newline(); s.Newline(); s.AppendI(1, "指定されたファイルパス=["); s.Append(filepathabsolute_Csv); s.Append("]"); s.Newline(); { s.AppendI(1, "ベース・ディレクトリは指定されていません。"); s.Newline(); s.AppendI(2, "もし相対パスが指定されていた場合、実行した.exeファイルからの相対パスとします。"); s.Newline(); s.Newline(); } s.Append(" ヒント:ファイルの有無、ファイル名、ファイル パスを確認してください。"); s.Newline(); // ヒント s.Append(r.Message_Configuration( request_ReadsTable.Expression_Filepath.Cur_Configuration)); r.Message = s.ToString(); } else { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("▲エラー235!", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("指定されたファイルはありませんでした。CSVファイルを読み込もうとしたとき。"); s.Newline(); s.Newline(); s.AppendI(1, "指定されたファイルパス=["); s.Append(filepathabsolute_Csv); s.Append("]"); s.Newline(); { s.AppendI(1, "指定されたベース・ディレクトリ=["); s.Append(request_ReadsTable.Expression_Filepath.Directory_Base); s.Append("]"); s.Newline(); s.Newline(); } s.Append(" ヒント:ファイルの有無、ファイル名、ファイル パスを確認してください。"); s.Newline(); // ヒント s.Append(r.Message_Configuration( request_ReadsTable.Expression_Filepath.Cur_Configuration)); r.Message = s.ToString(); } log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── gt_Error_Exception: if (log_Reports.CanCreateReport) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("▲エラー104!", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("▲エラー4030!(" + Info_Table.Name_Library + ")"); s.Newline(); s.Append("CSV読み取り中にエラーが発生しました。"); s.Append(Environment.NewLine); s.Append(Environment.NewLine); s.Append("指定CSVファイル=["); s.Append(filepathabsolute_Csv); s.Append("]"); s.Append(Environment.NewLine); s.Append(Environment.NewLine); // // ヒント request_ReadsTable.Expression_Filepath.Cur_Configuration.ToText_Locationbreadcrumbs(s); s.Append("エラーの種類:"); s.Append(error_Excp.GetType().Name); s.Append(Environment.NewLine); s.Append(Environment.NewLine); s.Append("エラーメッセージ:"); s.Append(error_Excp.Message); r.Message = s.ToString(); log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── gt_Error_NullTable: if (log_Reports.CanCreateReport) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("▲エラー105!", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("▲エラー131!"); s.Newline(); s.Append("["); s.Append(request_ReadsTable.Name_PutToTable); s.Append("]テーブルがありませんでした。"); s.Append(Environment.NewLine); s.Append(Environment.NewLine); r.Message = s.ToString(); log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── #endregion // // gt_EndMethod: log_Method.EndMethod(log_Reports); return xenonTable_Result; }
//──────────────────────────────────────── /// <summary> /// /// </summary> /// <param name="string_Csv"></param> /// <param name="request_ReadsTable"></param> /// <param name="xenonTableFormat_puts"></param> /// <param name="out_SErrorMsg"></param> /// <returns></returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable request_ReadsTable, Format_Table_Humaninput xenonTableFormat_puts, Log_Reports log_Reports ) { Table_Humaninput result; if (xenonTableFormat_puts.IsRowcolumnreverse) { // // 縦、横がひっくりかえっているCSVテーブルを読み込みます。 // if (xenonTableFormat_puts.IsAllintfieldsActivated) { // // 型定義のレコードがなく、全てのフィールドがint型のCSVテーブルを読み込みます。 // CsvTo_Table_Humaninput_ReverseAllIntsImpl csvTo = new CsvTo_Table_Humaninput_ReverseAllIntsImpl(); csvTo.CharSeparator = this.CharSeparator; Table_Humaninput xenonTable = csvTo.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 result = null; goto gt_EndMethod; } result = xenonTable; } else { CsvTo_Table_Humaninput_ReverseImpl csvTo = new CsvTo_Table_Humaninput_ReverseImpl(); csvTo.CharSeparator = this.CharSeparator; Table_Humaninput xenonTable = csvTo.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 result = null; goto gt_EndMethod; } result = xenonTable; } } else { // // 縦、横そのままのCSVテーブルを読み込みます。 // CsvTo_Table_Humaninput_RegularImpl csvTo = new CsvTo_Table_Humaninput_RegularImpl(); csvTo.CharSeparator = this.CharSeparator; Table_Humaninput xenonTable = csvTo.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 result = null; goto gt_EndMethod; } result = xenonTable; } goto gt_EndMethod; // // // // gt_EndMethod: return result; }
//──────────────────────────────────────── /// <summary> /// TODO:「,」「"」に対応したい。 /// /// /// 縦と横が逆のテーブル。 /// /// 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="csvText"></param> /// <returns>列名情報も含むテーブル。列の型は文字列型とします。</returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable forTable_Request, Format_Table_Humaninput forTable_Format, Log_Reports log_Reports ) { Log_Method log_Method = new Log_MethodImpl(); log_Method.BeginMethod(Info_Table.Name_Library, this, "Read",log_Reports); // // // // CsvLineParserImpl csvParser = new CsvLineParserImpl(); Table_Humaninput xenonTable = new Table_HumaninputImpl( forTable_Request.Name_PutToTable, forTable_Request.Expression_Filepath, forTable_Request.Expression_Filepath.Cur_Configuration ); xenonTable.Tableunit = forTable_Request.Tableunit; xenonTable.Typedata = forTable_Request.Typedata; xenonTable.IsDatebackupActivated = forTable_Request.IsDatebackupActivated; xenonTable.Format_Table_Humaninput = forTable_Format; // // 一旦、テーブルを全て読み込みます。 // List<List<string>> lines = new List<List<string>>(); { // CSVテキストを読み込み、型とデータのバッファーを作成します。 System.IO.StringReader reader = new System.IO.StringReader(string_Csv); while (-1 < reader.Peek()) { string sLine = reader.ReadLine(); List<string> tokens = new List<string>(); string[] sFields; sFields = csvParser.UnescapeLineToFieldList(sLine, this.charSeparator).ToArray(); int nColumnIndex = 0; foreach (string sToken in sFields) { if (nColumnIndex == 0 && ToCsv_Table_Humaninput_RowColRegularImpl.S_END == sToken.Trim().ToUpper()) { // 1列目にENDがある場合、その手前までの列が有効データです。 // END以降の行は無視します。 goto row_end; } tokens.Add(sToken); nColumnIndex++; } lines.Add(tokens); } row_end: // ストリームを閉じます。 reader.Close(); } // // 型定義部 // // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル) // RecordFielddefinition recordFielddefinition = new RecordFielddefinitionImpl(); // // データ・テーブル部 // List<List<string>> rows = new List<List<string>>(); // // まず、0列目、1列目、2列目のデータを読み取ります。 // int nRowIndex=0; foreach (List<string> tokens in lines) { Fielddefinition fieldDefinition = null; int nColumnIndex = 0; foreach(string sToken in tokens) { if(0==nColumnIndex) { // // 0列目は、フィールド名です。 // string sFieldName = sToken;//.Trim().ToUpper(); // テーブルのフィールドを追加します。型の既定値は文字列型とします。 fieldDefinition = new FielddefinitionImpl(sFieldName, EnumTypeFielddefinition.String); recordFielddefinition.Add(fieldDefinition); } else if(1==nColumnIndex) { // // 1列目は、フィールドの型名です。 // nColumnIndex = 1; string sFieldTypeNameLower = sToken.Trim().ToLower(); // テーブルのフィールドを追加します。型の既定値は文字列型とします。 // TODO int型とboolean型にも対応したい。 if (FielddefinitionImpl.S_STRING.Equals(sFieldTypeNameLower)) { fieldDefinition.Type_Field = EnumTypeFielddefinition.String; } else if (FielddefinitionImpl.S_INT.Equals(sFieldTypeNameLower)) { fieldDefinition.Type_Field = EnumTypeFielddefinition.Int; } else if (FielddefinitionImpl.S_BOOL.Equals(sFieldTypeNameLower)) { fieldDefinition.Type_Field = EnumTypeFielddefinition.Bool; } else { // 型が未定義の列は、文字列型として読み取ります。 // TODO: 警告。(エラーではない) Log_TextIndented t = new Log_TextIndentedImpl(); t.Append("▲エラー45!(" + Info_Table.Name_Library + ")"); t.Newline(); t.Append("型の名前を記入してください。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("※縦と横がひっくり返っているテーブルと指定されています。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("1列目(先頭を0とする)に、型の名前は必須です。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("["); t.Append(fieldDefinition.Name_Humaninput); t.Append("]フィールド (["); t.Append(nRowIndex); t.Append("]行目)に、"); t.Append(Environment.NewLine); t.Append("型名が["); t.Append(sFieldTypeNameLower); t.Append("]と入っています。この名前には、未対応です。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("文字列型として続行します。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("テーブル名=["); t.Append(forTable_Request.Name_PutToTable); t.Append("]"); t.Append(Environment.NewLine); t.Append("ファイル・パス=["); t.Append(forTable_Request.Expression_Filepath.Humaninput); t.Append("]"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); string sWarning = t.ToString(); MessageBox.Show(sWarning, "▲警告!(L02)"); fieldDefinition.Type_Field = EnumTypeFielddefinition.String; } } else if(2==nColumnIndex) { // // 2列目は、フィールドのコメントとします。 // nColumnIndex = 2; { fieldDefinition.Comment = sToken; } } else { // // 3列目から右側は、データ・テーブル部。 // if(0==nRowIndex) { // // 先頭行 // // // 「EOF」というトークンが出てくるまで。 // if(ToCsv_Table_Humaninput_RowColRegularImpl.S_EOF==sToken.Trim().ToUpper()) { goto column_end; } List<string> record = new List<string>(); // 1番目のフィールド_データを追加。 record.Add( sToken); rows.Add(record); } else { // // 2番目以降のフィールド_データを追加。 // // // 先頭の3つのレコード分、切り詰めます。 // int nDataIndex = nColumnIndex - 3; if (nDataIndex < rows.Count) { List<string> record = rows[nDataIndex]; record.Add(sToken); } else { // 無視 } } } nColumnIndex ++; }//c column_end: nRowIndex++; } //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ"); // テーブル作成。テーブルのフィールド型定義と、データ本体をセットします。 xenonTable.CreateTable(recordFielddefinition, log_Reports); if (log_Reports.Successful) { xenonTable.AddRecordList(rows, recordFielddefinition, log_Reports); //essageBox.Show("CSV読取後のテーブル作成終わり", "TableCsvLibデバッグ"); } goto gt_EndMethod; // // gt_EndMethod: log_Method.EndMethod(log_Reports); return xenonTable; }
//──────────────────────────────────────── #endregion #region アクション //──────────────────────────────────────── /// <summary> /// TODO:「,」「"」に対応したい。 /// /// /// 縦、横がひっくり返っていて、 /// 型定義レコードがないCSVテーブルの読取。 /// </summary> /// <param name="csvText"></param> /// <returns>列名情報も含むテーブル。</returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable forTable_Request, Format_Table_Humaninput forTable_Format, Log_Reports log_Reports ) { Log_Method log_Method = new Log_MethodImpl(); log_Method.BeginMethod(Info_Table.Name_Library, this, "Read", log_Reports); // // // // CsvLineParserImpl csvParser = new CsvLineParserImpl(); Table_Humaninput xenonTable = new Table_HumaninputImpl( forTable_Request.Name_PutToTable, forTable_Request.Expression_Filepath, forTable_Request.Expression_Filepath.Cur_Configuration); xenonTable.Tableunit = forTable_Request.Tableunit; xenonTable.Typedata = forTable_Request.Typedata; xenonTable.IsDatebackupActivated = forTable_Request.IsDatebackupActivated; xenonTable.Format_Table_Humaninput = forTable_Format; // // 一旦、テーブルを全て読み込みます。 // List <List <string> > lines = new List <List <string> >(); { // CSVテキストを読み込み、型とデータのバッファーを作成します。 System.IO.StringReader reader = new System.IO.StringReader(string_Csv); string[] sFields; while (-1 < reader.Peek()) { string sLine = reader.ReadLine(); List <string> tokens = new List <string>(); sFields = csvParser.UnescapeLineToFieldList(sLine, this.charSeparator).ToArray(); int nColumnIndex = 0; foreach (string sToken in sFields) { if (nColumnIndex == 0 && ToCsv_Table_Humaninput_RowColRegularImpl.S_END == sToken.Trim().ToUpper()) { // 1列目にENDがある場合、その手前までの列が有効データです。 // END以降の行は無視します。 goto row_end; } tokens.Add(sToken); nColumnIndex++; } lines.Add(tokens); } row_end: // ストリームを閉じます。 reader.Close(); } // // 型定義部 // // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル) // RecordFielddefinition recordFielddefinition = new RecordFielddefinitionImpl(); // // データ・テーブル部 // List <List <string> > rows = new List <List <string> >(); // // まず、0列目、1列目のデータを読み取ります。 // int nRowIndex = 0; foreach (List <string> tokens in lines) { Fielddefinition fieldDefinition = null; int nColumnIndex = 0; foreach (string sToken in tokens) { if (0 == nColumnIndex) { // // 0列目は、フィールド名です。 // string sFieldName = sToken;//.Trim().ToUpper(); // テーブルのフィールドを追加します。フィールドの型は、intに固定です。 fieldDefinition = new FielddefinitionImpl(sFieldName, EnumTypeFielddefinition.Int); recordFielddefinition.Add(fieldDefinition); } else if (1 == nColumnIndex) { // // 1列目は、フィールドのコメントとします。 // nColumnIndex = 1; { fieldDefinition.Comment = sToken; } } else { // // 2列目から右側は、データ・テーブル部。 // if (0 == nRowIndex) { // // 先頭行 // // // 「EOF」というトークンが出てくるまで。 // if (ToCsv_Table_Humaninput_RowColRegularImpl.S_EOF == sToken.Trim().ToUpper()) { goto column_end; } List <string> record = new List <string>(); // 1番目のフィールド_データを追加。 record.Add(sToken); rows.Add(record); } else { // // 2番目以降のフィールド_データを追加。 // // // 先頭の2つのレコード分、切り詰めます。 // int nDataIndex = nColumnIndex - 2; if (nDataIndex < rows.Count) { List <string> record = rows[nDataIndex]; record.Add(sToken); } else { // 無視 } } } nColumnIndex++; }//c column_end: nRowIndex++; } //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ"); // テーブル作成。テーブルのフィールド型定義と、データ本体をセットします。 xenonTable.CreateTable(recordFielddefinition, log_Reports); if (log_Reports.Successful) { xenonTable.AddRecordList(rows, recordFielddefinition, log_Reports); //essageBox.Show("CSV読取後のテーブル作成終わり", "TableCsvLibデバッグ"); } goto gt_EndMethod; // // gt_EndMethod: log_Method.EndMethod(log_Reports); return(xenonTable); }
//──────────────────────────────────────── #endregion #region アクション //──────────────────────────────────────── /// <summary> /// TODO:「,」「"」に対応したい。 /// /// /// 縦と横が逆のテーブル。 /// /// 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="csvText"></param> /// <returns>列名情報も含むテーブル。列の型は文字列型とします。</returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable forTable_Request, Format_Table forTable_Format, Log_Reports log_Reports ) { Log_Method log_Method = new Log_MethodImpl(); log_Method.BeginMethod(Info_Table.Name_Library, this, "Read", log_Reports); // // // // CsvLineParserImpl csvParser = new CsvLineParserImpl(); Table_Humaninput xenonTable = new Table_HumaninputImpl( forTable_Request.Name_PutToTable, forTable_Request.Expression_Filepath, forTable_Request.Expression_Filepath.Conf); xenonTable.Tableunit = forTable_Request.Tableunit; xenonTable.Typedata = forTable_Request.Typedata; xenonTable.IsDatebackupActivated = forTable_Request.IsDatebackupActivated; xenonTable.Format_Table_Humaninput = forTable_Format; // // 一旦、テーブルを全て読み込みます。 // List <List <string> > lines = new List <List <string> >(); { // CSVテキストを読み込み、型とデータのバッファーを作成します。 System.IO.StringReader reader = new System.IO.StringReader(string_Csv); while (-1 < reader.Peek()) { string sLine = reader.ReadLine(); List <string> tokens = new List <string>(); string[] sFields; sFields = csvParser.UnescapeLineToFieldList(sLine, this.charSeparator).ToArray(); int nColumnIndex = 0; foreach (string sToken in sFields) { if (nColumnIndex == 0 && ( ToCsv_Table_RowColRegularImpl_.S_EOL == sToken.Trim().ToUpper() || ToCsv_Table_RowColRegularImpl_.S_END == sToken.Trim().ToUpper() ) ) { // 1列目にENDがある場合、その手前までの列が有効データです。 // END以降の行は無視します。 goto row_end; } tokens.Add(sToken); nColumnIndex++; } lines.Add(tokens); } row_end: // ストリームを閉じます。 reader.Close(); } // // 型定義部 // // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル) // RecordFielddef recordFielddef = new RecordFielddefImpl(); // // データ・テーブル部 // List <List <string> > rows = new List <List <string> >(); // // まず、0列目、1列目、2列目のデータを読み取ります。 // int nRowIndex = 0; foreach (List <string> tokens in lines) { Fielddef fieldDefinition = null; int nColumnIndex = 0; foreach (string sToken in tokens) { if (0 == nColumnIndex) { // // 0列目は、フィールド名です。 // string sFieldName = sToken;//.Trim().ToUpper(); // テーブルのフィールドを追加します。型の既定値は文字列型とします。 fieldDefinition = new FielddefImpl(sFieldName, EnumTypeFielddef.String); recordFielddef.Add(fieldDefinition); } else if (1 == nColumnIndex) { // // 1列目は、フィールドの型名です。 // nColumnIndex = 1; string sFieldTypeNameLower = sToken.Trim().ToLower(); // テーブルのフィールドを追加します。型の既定値は文字列型とします。 // TODO int型とboolean型にも対応したい。 if (FielddefImpl.S_STRING.Equals(sFieldTypeNameLower)) { fieldDefinition.Type_Field = EnumTypeFielddef.String; } else if (FielddefImpl.S_INT.Equals(sFieldTypeNameLower)) { fieldDefinition.Type_Field = EnumTypeFielddef.Int; } else if (FielddefImpl.S_BOOL.Equals(sFieldTypeNameLower)) { fieldDefinition.Type_Field = EnumTypeFielddef.Bool; } else { // 型が未定義の列は、文字列型として読み取ります。 // TODO: 警告。(エラーではない) Log_TextIndented t = new Log_TextIndentedImpl(); t.Append("▲エラー45!(" + Info_Table.Name_Library + ")"); t.Newline(); t.Append("型の名前を記入してください。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("※縦と横がひっくり返っているテーブルと指定されています。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("1列目(先頭を0とする)に、型の名前は必須です。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("["); t.Append(fieldDefinition.Name_Humaninput); t.Append("]フィールド (["); t.Append(nRowIndex); t.Append("]行目)に、"); t.Append(Environment.NewLine); t.Append("型名が["); t.Append(sFieldTypeNameLower); t.Append("]と入っています。この名前には、未対応です。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("文字列型として続行します。"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); t.Append("テーブル名=["); t.Append(forTable_Request.Name_PutToTable); t.Append("]"); t.Append(Environment.NewLine); t.Append("ファイル・パス=["); t.Append(forTable_Request.Expression_Filepath.Humaninput); t.Append("]"); t.Append(Environment.NewLine); t.Append(Environment.NewLine); string sWarning = t.ToString(); MessageBox.Show(sWarning, "▲警告!(L02)"); fieldDefinition.Type_Field = EnumTypeFielddef.String; } } else if (2 == nColumnIndex) { // // 2列目は、フィールドのコメントとします。 // nColumnIndex = 2; { fieldDefinition.Comment = sToken; } } else { // // 3列目から右側は、データ・テーブル部。 // if (0 == nRowIndex) { // // 先頭行 // // // 「EOF」というトークンが出てくるまで。 // if (ToCsv_Table_RowColRegularImpl_.S_EOF == sToken.Trim().ToUpper()) { goto column_end; } List <string> record = new List <string>(); // 1番目のフィールド_データを追加。 record.Add(sToken); rows.Add(record); } else { // // 2番目以降のフィールド_データを追加。 // // // 先頭の3つのレコード分、切り詰めます。 // int nDataIndex = nColumnIndex - 3; if (nDataIndex < rows.Count) { List <string> record = rows[nDataIndex]; record.Add(sToken); } else { // 無視 } } } nColumnIndex++; }//c column_end: nRowIndex++; } //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ"); // テーブル作成。テーブルのフィールド型定義と、データ本体をセットします。 xenonTable.CreateTable(recordFielddef, log_Reports); if (log_Reports.Successful) { xenonTable.AddRecordList(rows, recordFielddef, log_Reports); //essageBox.Show("CSV読取後のテーブル作成終わり", "TableCsvLibデバッグ"); } goto gt_EndMethod; // // gt_EndMethod: log_Method.EndMethod(log_Reports); return(xenonTable); }
//──────────────────────────────────────── /// <summary> /// 「Aa_Files.csv」に書かれている「テーブル」と「スクリプト」を読取り、登録します。 /// </summary> private void ReadAndRegisterFiles( Table_Humaninput xenonTable_Aafilescsv, Log_Reports log_Reports ) { // // // //()メソッド開始 // // // Log_Method log_Method = new Log_MethodImpl(0, Log_ReportsImpl.BDebugmode_Static); log_Method.BeginMethod(Info_Functions.Name_Library, this, "ReadAndRegisterFiles", log_Reports); string err_STypedata; // // // // 「Aa_Files.csv」自身の絶対ファイルパス // // // string sFpatha_Aafilescsv; if (log_Reports.Successful) { sFpatha_Aafilescsv = xenonTable_Aafilescsv.Expression_Filepath_ConfigStack.Execute4_OnExpressionString( EnumHitcount.Unconstraint, log_Reports); if (!log_Reports.Successful) { // 既エラー。 goto gt_EndMethod; } } else { sFpatha_Aafilescsv = null; } // // // //「TYPE_DATA」というフィールドは必須です。 // // // bool isExists_FieldTypedata; if (log_Reports.Successful) { if (xenonTable_Aafilescsv.DataTable.Columns.Contains(NamesFld.S_TYPE_DATA)) { isExists_FieldTypedata = true; } else { isExists_FieldTypedata = false; } } else { isExists_FieldTypedata = false; } int err_NRow = 1;//行番号 if (log_Reports.Successful) { // // テーブルを全て(読み込まないもの除く)読み取ります。 // foreach (DataRow datarow in xenonTable_Aafilescsv.DataTable.Rows) { Request_ReadsTable requestRead = this.CreateReadRequest( datarow, xenonTable_Aafilescsv, log_Reports); if (!log_Reports.Successful) { //既エラー時、ループ抜け。 break; } // // テーブルを読み取るのか、XMLを読み取るのかの区別。 // if ( ValuesTypeData.TestTable(requestRead.Typedata) || !isExists_FieldTypedata //TYPE_DATAフィールドそのものが無ければ、エラーとはせず、テーブルとして読み込みます。 ) { // // テーブルなら。 // Format_Table_Humaninput forTable_format = this.Read_RequestPart_Table( datarow, sFpatha_Aafilescsv, log_Reports); Table_Humaninput oTable; // テーブル読取の実行。(書き出し専用の場合は、登録だけする) oTable = this.ReadTable( requestRead, forTable_format, log_Reports ); // テーブルは読み込まなくても、登録はする。 if (log_Reports.Successful) { // アプリケーション・モデルに、テーブルを登録 this.Owner_MemoryApplication.MemoryTables.AddTable_Humaninput( oTable, log_Reports ); } // } else if ( ValuesTypeData.TestCode(requestRead.Typedata) ) { // // XMLなら。 // MemoryCodefileinfo moScriptfileInfo = this.Read_RequestPart_Script( datarow, sFpatha_Aafilescsv, xenonTable_Aafilescsv, log_Reports ); // 登録 if (log_Reports.Successful) { this.Owner_MemoryApplication.MemoryCodefiles.Add( moScriptfileInfo, log_Reports ); } //requestRead. log_Method.WriteDebug_ToConsole("sTypeData=[" + requestRead.Typedata + "]"); } else { //エラー。 err_STypedata = requestRead.Typedata; goto gt_Error_TypeData; } //エラー報告用の行カウンター。 err_NRow++; } } goto gt_EndMethod; // // #region 異常系 //──────────────────────────────────────── gt_Error_TypeData: { Builder_TexttemplateP1p tmpl = new Builder_TexttemplateP1pImpl(); tmpl.SetParameter(1, NamesFld.S_TYPE_DATA, log_Reports); //フィールド名TYPE_DATA tmpl.SetParameter(2, err_STypedata, log_Reports); //TYPE_DATAフィールドの値 tmpl.SetParameter(3, ValuesTypeData.Message_Allitems(), log_Reports); //TYPE_DATAフィールドに設定できる値のリスト Configurationtree_Node cf = new Configurationtree_NodeImpl("データ部" + err_NRow + "行", xenonTable_Aafilescsv.Parent); tmpl.SetParameter(4, Log_RecordReportsImpl.ToText_Configuration(cf), log_Reports);//設定位置パンくずリスト this.Owner_MemoryApplication.CreateErrorReport("Er:110011;", tmpl, log_Reports); } goto gt_EndMethod; //──────────────────────────────────────── #endregion // // gt_EndMethod: log_Method.EndMethod(log_Reports); }
//──────────────────────────────────────── /// <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="csvText"></param> /// <returns>列名情報も含むテーブル。列の型は文字列型とします。</returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable forTable_request, Format_Table_Humaninput forTable_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 xenonTable = new Table_HumaninputImpl( forTable_request.Name_PutToTable, forTable_request.Expression_Filepath, forTable_request.Expression_Filepath.Cur_Configuration ); xenonTable.Tableunit = forTable_request.Tableunit; xenonTable.Typedata = forTable_request.Typedata; xenonTable.IsDatebackupActivated = forTable_request.IsDatebackupActivated; xenonTable.Format_Table_Humaninput = forTable_puts; Exception err_Excp; int error_Count_Index; string[] error_Fields_Cur; // // 型定義部 // // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル) // RecordFielddefinition recordFielddefinition = new RecordFielddefinitionImpl(); // // データ・テーブル部 // List<List<string>> dataTableRows = new List<List<string>>(); // CSVテキストを読み込み、型とデータのバッファーを作成します。 System.IO.StringReader reader = new System.IO.StringReader(string_Csv); CsvLineParserImpl csvParser = new CsvLineParserImpl(); // CSVを解析して、テーブル形式で格納。 { // データとして認識する列の総数です。 int nDataColumnsCount = 0; int nRowIndex = 0; string[] fields_Cur; while (-1 < reader.Peek()) { string line = reader.ReadLine(); fields_Cur = csvParser.UnescapeLineToFieldList(line, this.charSeparator).ToArray(); if (0 == nRowIndex) { // 0行目 // 列名の行とします。 for (int nColumnIx = 0; nColumnIx < fields_Cur.Length; nColumnIx++) { string sColumnName = fields_Cur[nColumnIx]; // 列名を読み込みました。 // トリム&大文字 string sCellValueTU = sColumnName.Trim().ToUpper(); if (ToCsv_Table_Humaninput_RowColRegularImpl.S_END == sCellValueTU) { // 列名に ”END” がある場合、その手前までの列が有効データです。 // ”END” 以降の列は無視します。 goto field_name_reading_end; } // テーブルのフィールドを追加します。型の既定値は文字列型とします。 FielddefinitionImpl fieldDef = new FielddefinitionImpl(sColumnName, EnumTypeFielddefinition.String); recordFielddefinition.Add(fieldDef); nDataColumnsCount++; } // 0行目は、テーブルのデータとしては持ちません。 } else if (1 == nRowIndex) { // 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 (FielddefinitionImpl.S_STRING.Equals(name_FieldType_Lower)) { recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.String; } else if (FielddefinitionImpl.S_INT.Equals(name_FieldType_Lower)) { recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.Int; } else if (FielddefinitionImpl.S_BOOL.Equals(name_FieldType_Lower)) { // 2009-11-11修正:SRS仕様では「bool」が正しい。「boolean」は間違い。 recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.Bool; } else { // 型が未定義の列は、文字列型として読み取ります。 // TODO:警告を出すか? recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.String; } } // 1行目は、テーブルのデータとしては持ちません。 } else if (2 == nRowIndex) { // 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:境界線エラーをキャッチしてない。 recordFielddefinition.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_Humaninput_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 (recordFielddefinition.Count <= nColumnIx) { // 0行目で数えた列数より多い場合。 // テーブルのフィールドを追加します。型は文字列型とします。名前は空文字列です。 recordFielddefinition.Add(new FielddefinitionImpl("", EnumTypeFielddefinition.String)); } sList_Column.Add(sValue); } dataTableRows.Add(sList_Column); end_recordAdd: ; } field_name_reading_end: //essageBox.Show("ttbwIndex=[" + ttbwIndex + "]行目ループ終わり", "TableCsvLibデバッグ"); nRowIndex++; } } reading_end: // ストリームを閉じます。 reader.Close(); //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ"); // テーブルのフィールド定義。 xenonTable.CreateTable(recordFielddefinition,log_Reports); if(log_Reports.Successful) { // データ本体のセット。 xenonTable.AddRecordList(dataTableRows, recordFielddefinition, 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("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("──────────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 ここまで"); s.Append(Environment.NewLine); // // ヒント s.Append(Log_RecordReportsImpl.ToText_Configuration(xenonTable)); 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 = forTable_request.Expression_Filepath.Execute4_OnExpressionString( 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 xenonTable; }
//──────────────────────────────────────── #endregion #region アクション //──────────────────────────────────────── /// <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="csvText"></param> /// <returns>列名情報も含むテーブル。列の型は文字列型とします。</returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable forTable_request, Format_Table_Humaninput forTable_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 xenonTable = new Table_HumaninputImpl( forTable_request.Name_PutToTable, forTable_request.Expression_Filepath, forTable_request.Expression_Filepath.Cur_Configuration); xenonTable.Tableunit = forTable_request.Tableunit; xenonTable.Typedata = forTable_request.Typedata; xenonTable.IsDatebackupActivated = forTable_request.IsDatebackupActivated; xenonTable.Format_Table_Humaninput = forTable_puts; Exception err_Excp; int error_Count_Index; string[] error_Fields_Cur; // // 型定義部 // // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル) // RecordFielddefinition recordFielddefinition = new RecordFielddefinitionImpl(); // // データ・テーブル部 // List <List <string> > dataTableRows = new List <List <string> >(); // CSVテキストを読み込み、型とデータのバッファーを作成します。 System.IO.StringReader reader = new System.IO.StringReader(string_Csv); CsvLineParserImpl csvParser = new CsvLineParserImpl(); // CSVを解析して、テーブル形式で格納。 { // データとして認識する列の総数です。 int nDataColumnsCount = 0; int nRowIndex = 0; string[] fields_Cur; while (-1 < reader.Peek()) { string line = reader.ReadLine(); fields_Cur = csvParser.UnescapeLineToFieldList(line, this.charSeparator).ToArray(); if (0 == nRowIndex) { // 0行目 // 列名の行とします。 for (int nColumnIx = 0; nColumnIx < fields_Cur.Length; nColumnIx++) { string sColumnName = fields_Cur[nColumnIx]; // 列名を読み込みました。 // トリム&大文字 string sCellValueTU = sColumnName.Trim().ToUpper(); if (ToCsv_Table_Humaninput_RowColRegularImpl.S_END == sCellValueTU) { // 列名に ”END” がある場合、その手前までの列が有効データです。 // ”END” 以降の列は無視します。 goto field_name_reading_end; } // テーブルのフィールドを追加します。型の既定値は文字列型とします。 FielddefinitionImpl fieldDef = new FielddefinitionImpl(sColumnName, EnumTypeFielddefinition.String); recordFielddefinition.Add(fieldDef); nDataColumnsCount++; } // 0行目は、テーブルのデータとしては持ちません。 } else if (1 == nRowIndex) { // 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 (FielddefinitionImpl.S_STRING.Equals(name_FieldType_Lower)) { recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.String; } else if (FielddefinitionImpl.S_INT.Equals(name_FieldType_Lower)) { recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.Int; } else if (FielddefinitionImpl.S_BOOL.Equals(name_FieldType_Lower)) { // 2009-11-11修正:SRS仕様では「bool」が正しい。「boolean」は間違い。 recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.Bool; } else { // 型が未定義の列は、文字列型として読み取ります。 // TODO:警告を出すか? recordFielddefinition.ValueAt(nColumnIx).Type_Field = EnumTypeFielddefinition.String; } } // 1行目は、テーブルのデータとしては持ちません。 } else if (2 == nRowIndex) { // 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:境界線エラーをキャッチしてない。 recordFielddefinition.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_Humaninput_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 (recordFielddefinition.Count <= nColumnIx) { // 0行目で数えた列数より多い場合。 // テーブルのフィールドを追加します。型は文字列型とします。名前は空文字列です。 recordFielddefinition.Add(new FielddefinitionImpl("", EnumTypeFielddefinition.String)); } sList_Column.Add(sValue); } dataTableRows.Add(sList_Column); end_recordAdd: ; } field_name_reading_end: //essageBox.Show("ttbwIndex=[" + ttbwIndex + "]行目ループ終わり", "TableCsvLibデバッグ"); nRowIndex++; } } reading_end: // ストリームを閉じます。 reader.Close(); //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ"); // テーブルのフィールド定義。 xenonTable.CreateTable(recordFielddefinition, log_Reports); if (log_Reports.Successful) { // データ本体のセット。 xenonTable.AddRecordList(dataTableRows, recordFielddefinition, 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("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("──────────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 ここまで"); s.Append(Environment.NewLine); // // ヒント s.Append(Log_RecordReportsImpl.ToText_Configuration(xenonTable)); 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 = forTable_request.Expression_Filepath.Execute4_OnExpressionString( 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(xenonTable); }
//──────────────────────────────────────── /// <summary> /// テーブル読取。 /// </summary> /// <param name="forTable_request"></param> /// <param name="forTable_format"></param> /// <param name="log_Reports"></param> /// <returns></returns> private Table_Humaninput ReadTable( Request_ReadsTable forSubTable_Request_TblReads, Format_Table_Humaninput o_TableFormat_ForSubTable_Puts, Log_Reports log_Reports ) { Table_Humaninput o_Tbl; if (log_Reports.Successful) { // 正常時 // // テーブル読取り CsvTo_Table_HumaninputImpl reader = new CsvTo_Table_HumaninputImpl(); // テーブル o_Tbl = reader.Read( forSubTable_Request_TblReads, o_TableFormat_ForSubTable_Puts, true, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 goto gt_EndMethod; } if (log_Reports.Successful) { // 正常時 // NOフィールドの値を 0からの連番に振りなおします。 o_Tbl.RenumberingNoField(); } } else { o_Tbl = null; } // // // // gt_EndMethod: return o_Tbl; }
//──────────────────────────────────────── #endregion #region アクション //──────────────────────────────────────── /// <summary> /// パーサーのハブ。 /// /// </summary> /// <param name="request_ReadsTable">テーブルに付けたい名前や、ファイルパスの要求。</param> /// <param name="tableFormat_puts">テーブルの行列が逆になっているなどの、設定。</param> /// <param name="isRequired">テーブルが無かった場合、エラーとするなら真。</param> /// <param name="out_sErrorMsg"></param> /// <returns></returns> public Table_Humaninput Read( Request_ReadsTable request_ReadsTable, Format_Table tableFormat_puts, bool isRequired, Encoding encodingCsv, Log_Reports log_Reports ) { Log_Method log_Method = new Log_MethodImpl(); log_Method.BeginMethod(Info_Table.Name_Library, this, "Read", log_Reports); // 読み取ったテーブル Table_Humaninput xTable; //絶対ファイルパス string csvAbs = request_ReadsTable.Expression_Filepath.Lv4Execute_OnImplement( EnumHitcount.Unconstraint, log_Reports); if (!log_Reports.Successful) { // 既エラー。 xTable = null; goto gt_EndMethod; } // CSVテキスト string contents; Exception error_Excp; if (CsvTo_TableImpl.S_WRITE_ONLY != request_ReadsTable.Use) { // 書き出し専用でなければ。 // ファイル読取を実行します。 try { if (!System.IO.File.Exists(csvAbs)) { // ファイルが存在しない場合。 xTable = null; goto gt_Error_NotExistsFile; } // TODO:IOException 別スレッドで開いているときなど。 contents = System.IO.File.ReadAllText(csvAbs, encodingCsv); //log_Method.WriteDebug_ToConsole(string_Csv); } catch (System.IO.IOException e) { // エラー処理。 xTable = null; contents = ""; error_Excp = e; goto gt_Error_FileOpen; } catch (Exception e) { // エラー処理。 xTable = null; contents = ""; error_Excp = e; goto gt_Error_Exception; } } else { contents = ""; } xTable = this.Read( contents, request_ReadsTable, tableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 goto gt_EndMethod; } // NOフィールドの値を 0からの連番に振りなおします。 xTable.RenumberingNoField(); if (isRequired && null == xTable) { goto gt_Error_NullTable; } goto gt_EndMethod; // // #region 異常系 //──────────────────────────────────────── gt_Error_FileOpen: if (log_Reports.CanCreateReport) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("Er:201;", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("ファイルの読取りに失敗しました。"); s.Newline(); s.Newline(); s.Append(" ファイル=["); s.Append(csvAbs); s.Append("]"); s.Newline(); s.Newline(); s.Append("もしかして?"); s.Newline(); s.Append(" ・ファイルの有無、ファイル名、ファイル パスを確認してください。"); s.Newline(); s.Append(" ・別アプリケーションで ファイルを開いていれば、閉じてください。"); s.Newline(); s.Newline(); // // ヒント request_ReadsTable.Expression_Filepath.Conf.ToText_Locationbreadcrumbs(s); s.Append(error_Excp.Message); r.Message = s.ToString(); log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── gt_Error_NotExistsFile: if (log_Reports.CanCreateReport) { if ("" == request_ReadsTable.Expression_Filepath.Directory_Base) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("Er:202;", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("指定されたファイルはありませんでした。CSVファイルを読み込もうとしたとき。"); s.Newline(); s.Newline(); s.AppendI(1, "指定されたファイルパス=["); s.Append(csvAbs); s.Append("]"); s.Newline(); { s.AppendI(1, "ベース・ディレクトリは指定されていません。"); s.Newline(); s.AppendI(2, "もし相対パスが指定されていた場合、実行した.exeファイルからの相対パスとします。"); s.Newline(); s.Newline(); } s.Append(" ヒント:ファイルの有無、ファイル名、ファイル パスを確認してください。"); s.Newline(); // ヒント s.Append(r.Message_Conf( request_ReadsTable.Expression_Filepath.Conf)); r.Message = s.ToString(); } else { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("▲エラー235!", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("指定されたファイルはありませんでした。CSVファイルを読み込もうとしたとき。"); s.Newline(); s.Newline(); s.AppendI(1, "指定されたファイルパス=["); s.Append(csvAbs); s.Append("]"); s.Newline(); { s.AppendI(1, "指定されたベース・ディレクトリ=["); s.Append(request_ReadsTable.Expression_Filepath.Directory_Base); s.Append("]"); s.Newline(); s.Newline(); } s.Append(" ヒント:ファイルの有無、ファイル名、ファイル パスを確認してください。"); s.Newline(); // ヒント s.Append(r.Message_Conf( request_ReadsTable.Expression_Filepath.Conf)); r.Message = s.ToString(); } log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── gt_Error_Exception: if (log_Reports.CanCreateReport) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("▲エラー104!", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("▲エラー4030!(" + Info_Table.Name_Library + ")"); s.Newline(); s.Append("CSV読み取り中にエラーが発生しました。"); s.Append(Environment.NewLine); s.Append(Environment.NewLine); s.Append("指定CSVファイル=["); s.Append(csvAbs); s.Append("]"); s.Append(Environment.NewLine); s.Append(Environment.NewLine); // // ヒント request_ReadsTable.Expression_Filepath.Conf.ToText_Locationbreadcrumbs(s); s.Append("エラーの種類:"); s.Append(error_Excp.GetType().Name); s.Append(Environment.NewLine); s.Append(Environment.NewLine); s.Append("エラーメッセージ:"); s.Append(error_Excp.Message); r.Message = s.ToString(); log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── gt_Error_NullTable: if (log_Reports.CanCreateReport) { Log_RecordReports r = log_Reports.BeginCreateReport(EnumReport.Error); r.SetTitle("▲エラー105!", log_Method); Log_TextIndented s = new Log_TextIndentedImpl(); s.Append("▲エラー131!"); s.Newline(); s.Append("["); s.Append(request_ReadsTable.Name_PutToTable); s.Append("]テーブルがありませんでした。"); s.Append(Environment.NewLine); s.Append(Environment.NewLine); r.Message = s.ToString(); log_Reports.EndCreateReport(); } goto gt_EndMethod; //──────────────────────────────────────── #endregion // // gt_EndMethod: log_Method.EndMethod(log_Reports); return(xTable); }
//──────────────────────────────────────── /// <summary> /// /// </summary> /// <param name="contents">CSVテキスト</param> /// <param name="request">テーブル読取り時の要求。</param> /// <param name="formatPuts">設定するフォーマット。</param> /// <param name="out_SErrorMsg"></param> /// <returns></returns> public Table_Humaninput Read( string contents, Request_ReadsTable request, Format_Table formatPuts, Log_Reports log_Reports ) { // 読み取ったテーブル Table_Humaninput resultTable; if (formatPuts.IsRowcolumnreverse) { // // 縦、横がひっくりかえっているCSVテーブルを読み込みます。 // if (formatPuts.IsAllintfieldsActivated) { // // 型定義のレコードがなく、全てのフィールドがint型のCSVテーブルを読み込みます。 // CsvTo_Table_ReverseAllIntsImpl_ csvTo = new CsvTo_Table_ReverseAllIntsImpl_(); csvTo.CharSeparator = this.CharSeparator; resultTable = csvTo.Read( contents, request, formatPuts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 resultTable = null; goto gt_EndMethod; } } else { CsvTo_Table_ReverseImpl_ csvTo = new CsvTo_Table_ReverseImpl_(); csvTo.CharSeparator = this.CharSeparator; resultTable = csvTo.Read( contents, request, formatPuts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 resultTable = null; goto gt_EndMethod; } } } else { // // 縦、横そのままのCSVテーブルを読み込みます。 // CsvTo_Table_RegularImpl_ csvTo = new CsvTo_Table_RegularImpl_(); csvTo.CharSeparator = this.CharSeparator; resultTable = csvTo.Read( contents, request, formatPuts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 resultTable = null; goto gt_EndMethod; } } goto gt_EndMethod; // // // // gt_EndMethod: return(resultTable); }
//──────────────────────────────────────── /// <summary> /// TODO:「,」「"」に対応したい。 /// /// /// 縦、横がひっくり返っていて、 /// 型定義レコードがないCSVテーブルの読取。 /// </summary> /// <param name="csvText"></param> /// <returns>列名情報も含むテーブル。</returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable forTable_Request, Format_Table_Humaninput forTable_Format, Log_Reports log_Reports ) { Log_Method log_Method = new Log_MethodImpl(); log_Method.BeginMethod(Info_Table.Name_Library, this, "Read",log_Reports); // // // // CsvLineParserImpl csvParser = new CsvLineParserImpl(); Table_Humaninput xenonTable = new Table_HumaninputImpl( forTable_Request.Name_PutToTable, forTable_Request.Expression_Filepath, forTable_Request.Expression_Filepath.Cur_Configuration); xenonTable.Tableunit = forTable_Request.Tableunit; xenonTable.Typedata = forTable_Request.Typedata; xenonTable.IsDatebackupActivated = forTable_Request.IsDatebackupActivated; xenonTable.Format_Table_Humaninput = forTable_Format; // // 一旦、テーブルを全て読み込みます。 // List<List<string>> lines = new List<List<string>>(); { // CSVテキストを読み込み、型とデータのバッファーを作成します。 System.IO.StringReader reader = new System.IO.StringReader(string_Csv); string[] sFields; while (-1 < reader.Peek()) { string sLine = reader.ReadLine(); List<string> tokens = new List<string>(); sFields = csvParser.UnescapeLineToFieldList(sLine, this.charSeparator).ToArray(); int nColumnIndex = 0; foreach (string sToken in sFields) { if (nColumnIndex == 0 && ToCsv_Table_Humaninput_RowColRegularImpl.S_END == sToken.Trim().ToUpper()) { // 1列目にENDがある場合、その手前までの列が有効データです。 // END以降の行は無視します。 goto row_end; } tokens.Add(sToken); nColumnIndex++; } lines.Add(tokens); } row_end: // ストリームを閉じます。 reader.Close(); } // // 型定義部 // // (※NO,ID,EXPL,NAME など、フィールドの定義を持つテーブル) // RecordFielddefinition recordFielddefinition = new RecordFielddefinitionImpl(); // // データ・テーブル部 // List<List<string>> rows = new List<List<string>>(); // // まず、0列目、1列目のデータを読み取ります。 // int nRowIndex=0; foreach (List<string> tokens in lines) { Fielddefinition fieldDefinition = null; int nColumnIndex = 0; foreach(string sToken in tokens) { if(0==nColumnIndex) { // // 0列目は、フィールド名です。 // string sFieldName = sToken;//.Trim().ToUpper(); // テーブルのフィールドを追加します。フィールドの型は、intに固定です。 fieldDefinition = new FielddefinitionImpl(sFieldName, EnumTypeFielddefinition.Int); recordFielddefinition.Add(fieldDefinition); } else if(1==nColumnIndex) { // // 1列目は、フィールドのコメントとします。 // nColumnIndex = 1; { fieldDefinition.Comment = sToken; } } else { // // 2列目から右側は、データ・テーブル部。 // if(0==nRowIndex) { // // 先頭行 // // // 「EOF」というトークンが出てくるまで。 // if(ToCsv_Table_Humaninput_RowColRegularImpl.S_EOF==sToken.Trim().ToUpper()) { goto column_end; } List<string> record = new List<string>(); // 1番目のフィールド_データを追加。 record.Add( sToken); rows.Add(record); } else { // // 2番目以降のフィールド_データを追加。 // // // 先頭の2つのレコード分、切り詰めます。 // int nDataIndex = nColumnIndex - 2; if (nDataIndex < rows.Count) { List<string> record = rows[nDataIndex]; record.Add(sToken); } else { // 無視 } } } nColumnIndex ++; }//c column_end: nRowIndex++; } //essageBox.Show("CSV読取終わり1 rows.Count=[" + rows.Count + "]", "TableCsvLibデバッグ"); // テーブル作成。テーブルのフィールド型定義と、データ本体をセットします。 xenonTable.CreateTable(recordFielddefinition,log_Reports); if( log_Reports.Successful) { xenonTable.AddRecordList(rows, recordFielddefinition, log_Reports); //essageBox.Show("CSV読取後のテーブル作成終わり", "TableCsvLibデバッグ"); } goto gt_EndMethod; // // gt_EndMethod: log_Method.EndMethod(log_Reports); return xenonTable; }
//──────────────────────────────────────── /// <summary> /// /// </summary> /// <param name="string_Csv"></param> /// <param name="request_ReadsTable"></param> /// <param name="xenonTableFormat_puts"></param> /// <param name="out_SErrorMsg"></param> /// <returns></returns> public Table_Humaninput Read( string string_Csv, Request_ReadsTable request_ReadsTable, Format_Table_Humaninput xenonTableFormat_puts, Log_Reports log_Reports ) { Table_Humaninput result; if (xenonTableFormat_puts.IsRowcolumnreverse) { // // 縦、横がひっくりかえっているCSVテーブルを読み込みます。 // if (xenonTableFormat_puts.IsAllintfieldsActivated) { // // 型定義のレコードがなく、全てのフィールドがint型のCSVテーブルを読み込みます。 // CsvTo_Table_Humaninput_ReverseAllIntsImpl csvTo = new CsvTo_Table_Humaninput_ReverseAllIntsImpl(); csvTo.CharSeparator = this.CharSeparator; Table_Humaninput xenonTable = csvTo.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 result = null; goto gt_EndMethod; } result = xenonTable; } else { CsvTo_Table_Humaninput_ReverseImpl csvTo = new CsvTo_Table_Humaninput_ReverseImpl(); csvTo.CharSeparator = this.CharSeparator; Table_Humaninput xenonTable = csvTo.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 result = null; goto gt_EndMethod; } result = xenonTable; } } else { // // 縦、横そのままのCSVテーブルを読み込みます。 // CsvTo_Table_Humaninput_RegularImpl csvTo = new CsvTo_Table_Humaninput_RegularImpl(); csvTo.CharSeparator = this.CharSeparator; Table_Humaninput xenonTable = csvTo.Read( string_Csv, request_ReadsTable, xenonTableFormat_puts, log_Reports ); if (!log_Reports.Successful) { // 既エラー。 result = null; goto gt_EndMethod; } result = xenonTable; } goto gt_EndMethod; // // // // gt_EndMethod: return(result); }