G3509_And_note_トラブル発生

202526

7:30

G3509_andoroid_and_note_data_trouble

 

トラブル発生

 

 

 

 

 

まずこのようなイレギュラーデータを読み込みで無視する処理を追加します

 

 

 

if (rec_form_chk(cut_tbl) == false) continue;

 

記憶をたどると、削除処理でも読み込みがあるので同じ処理を追加します

 

 

 

 

 

 

レコード書式検査関数を作ります

 

 

 

前回作成しているレコード配置処理関数を修正します

 

 

 

 

外部変数を追加します

 

 

public static int Note_rec_fld_max = 11 + 1;        // レコード領域最大件数

 

レコード書式検査関数のコードを作成します

 

注意 このコードはトラブルにより変更になりました

 

 

int fld_max = prm_tbl.Length;

int yy_all, mm, dd, th, tm, ts;

 

msg2("fld_max=", fld_max.ToString(), "");

 

// 要素個数の判定

if (Note_rec_fld_max <= fld_max) return false;

 

// 2025.02.06 THU (07:03) goma0099 -12577505-

// この検査はイコールでチェックしたいところですが、前段でカンマ区切りする時

// 配列を固定で30件確保しているので fld_max はおそらく 30 固定です

// 可変フィールドの使い方が未経験なので、固定配列はこのままです

// そうすると、フィールド件数チェックは余り意味はないように思われます

 

// 今回のトラブルを回避するための書式検査はカレンダーがメインになると思われます

yy_all = int.Parse(prm_tbl[0]);

mm = int.Parse(prm_tbl[1]);

dd = int.Parse(prm_tbl[2]);

th = int.Parse(prm_tbl[3]);

tm = int.Parse(prm_tbl[4]);

ts = int.Parse(prm_tbl[5]);

 

if (cal_data_chk(yy_all,mm,dd,th,tm,ts) == false) return false;

 

th = int.Parse(prm_tbl[8]);

tm = int.Parse(prm_tbl[9]);

ts = int.Parse(prm_tbl[10]);

 

if (cal_data_chk(0,0,0, th, tm, ts) == false) return false;

 

return true;

 

 

カレンダー検査関数を作成します

 

注意 このコードはトラブルにより変更になりました

 

 

 

// カレンダー書式検査

private bool cal_data_chk(

int prm_yy_all,

int prm_mm,

int prm_dd,

int prm_th,

int prm_tm,

int prm_ts

)

{

if(0 < prm_yy_all)

{

if (prm_yy_all < 1980 || 2199 < prm_yy_all) return false;

}

 

if(12 < prm_mm) return false;

if (31 < prm_dd) return false;

 

if (59 < prm_th) return false;

if (59 < prm_tm) return false;

if (59 < prm_ts) return false;

 

return true;

}

 

ここで、クリーン、配置し確認します

 

 

 

失敗です 変わらずアプリは起動しません

 

 

 

注意 このコードはトラブルにより変更になりました

 

 

// レコード書式検査

private bool rec_form_chk(string[] prm_tbl)

{

int fld_max = prm_tbl.Length;

 

msg2("fld_max=", fld_max.ToString(), "");

 

// 要素個数の判定

if (Note_rec_fld_max <= fld_max) return false;

 

// 2025.02.06 THU (07:03) goma0099 -12577505-

// この検査はイコールでチェックしたいところですが、前段でカンマ区切りする時

// 配列を固定で30件確保しているので fld_max はおそらく 30 固定です

// 可変フィールドの使い方が未経験なので、固定配列はこのままです

// そうすると、フィールド件数チェックは余り意味はないように思われます

 

// 今回のトラブルを回避するための書式検査はカレンダーがメインになると思われます

 

if (cal_data_chk(prm_tbl[0], prm_tbl[1], prm_tbl[2], prm_tbl[3], prm_tbl[4], prm_tbl[5]) == false) return false;

 

if (cal_data_chk("","","", prm_tbl[8], prm_tbl[9], prm_tbl[10]) == false) return false;

 

return true;

}

 

 

カレンダー書式検査も修正します

 

注意 このコードはトラブルにより変更になりました

 

 

// カレンダー書式検査

private bool cal_data_chk(

string prm_yy_all,

string prm_mm,

string prm_dd,

string prm_th,

string prm_tm,

string prm_ts

)

{

string[] cst_tbl = new string[6 + 1];

int yy_all, mm, dd, th, tm, ts;

 

if (prm_yy_all != null)

{

if (int.TryParse(prm_yy_all, out yy_all) == false) return false;

if (yy_all < 1980 || 2199 < yy_all) return false;

}

 

if (prm_mm != null)

{

if (int.TryParse(prm_mm, out mm) == false) return false;

if (12 < mm) return false;

}

 

if (prm_dd != null)

{

if (int.TryParse(prm_dd, out dd) == false) return false;

if (31 < dd) return false;

}

 

if (prm_th != null)

{

if (int.TryParse(prm_th, out th) == false) return false;

if (59 < th) return false;

}

 

if (prm_tm != null)

{

if (int.TryParse(prm_tm, out tm) == false) return false;

if (59 < tm) return false;

}

 

if (prm_ts != null)

{

if (int.TryParse(prm_ts, out ts) == false) return false;

if (59 < ts) return false;

}

return true;

}

 

今回新しい機能を知りました、早見表に記録しました

 

 

 

文字列で渡された年度の書式を検査し数値に変換します

 

// 数値変換のテスト

// 文字列で渡される年度検査

string yy_all_cst = "_1980_";

int yy_all;

if(int.TryParse(yy_all_cst,out yy_all) == false) msg("書式エラーです");

else msg(yy_all.ToString());

 

 

// 数値変換のテスト

// 文字列で渡される年度検査

string yy_all_cst = "1980";

int yy_all;

if (int.TryParse(yy_all_cst, out yy_all) == false) msg("書式エラーです");

else msg(yy_all.ToString());

 

 

 

// 数値変換のテスト

// 文字列で渡される年度検査

string yy_all_cst = "";

int yy_all;

if (int.TryParse(yy_all_cst, out yy_all) == false) msg("書式エラーです");

else msg(yy_all.ToString());

 

 

 

失敗です、アプリは起動しません

 

 

レコードモニタを追加して、レコード要素数のモニタも入れました

 

 

推測とは異なり、少ない領域も検査できることがわかりました

 

 

しかしながら、カレンダー検査もうまく働いていないので調査をします

 

 

 

 

 

if文の組み方を変更してみます

 

 

年月日検査だけに分離すると、アプリが起動しました

 

 

 

エラーログ ④ ⑤ が通っているので、正常です

 

 

パラメータ件数が多すぎてオーバーフロー?

 

時分秒検査を作るとエラーになるのだろうか?

 

解決 

 

 

処理がすっきりしたので、分割した関数はそのままにします

 

注意 このコードはトラブルにより変更になりました

 

 

 

// レコード書式検査

private bool rec_form_chk(string[] prm_tbl)

{

int fld_max = prm_tbl.Length;

 

// 要素個数の判定

if (Note_rec_fld_max <= fld_max) return false;

 

// 2025.02.06 THU (07:03) goma0099 -12577505-

// この検査はイコールでチェックしたいところですが、前段でカンマ区切りする時

// 配列を固定で30件確保しているので fld_max はおそらく 30 固定です

// 可変フィールドの使い方が未経験なので、固定配列はこのままです

// そうすると、フィールド件数チェックは余り意味はないように思われます

 

// 今回のトラブルを回避するための書式検査はカレンダーがメインになると思われます

 

if (Cal_ymd_chk(prm_tbl[0], prm_tbl[1], prm_tbl[2]) == false) return (false);        //登録年月日

if (Cal_hms_chk(prm_tbl[3], prm_tbl[4], prm_tbl[5]) == false) return (false);        //登録時分秒

if (Cal_hms_chk(prm_tbl[8], prm_tbl[9], prm_tbl[10]) == false) return (false);        //フラグ時分秒

 

return true;

}

 

cal_data_chk() 関数を削除し、Cal_ymd_chk() Cal_hms_chk() に分割します

 

注意 このコードは、ログ記録の追加のため変更されています

 

// 年月日書式検査

private bool Cal_ymd_chk(

string prm_yy_all,

string prm_mm,

string prm_dd

)

{

int yy_all, mm, dd;

 

if (prm_yy_all != null)

{

if (int.TryParse(prm_yy_all, out yy_all) == false) return false;

if (yy_all < 1980 || 2199 < yy_all) return false;

}

 

if (prm_mm != null)

{

if (int.TryParse(prm_mm, out mm) == false) return false;

if (12 < mm) return false;

}

 

if (prm_dd != null)

{

if (int.TryParse(prm_dd, out dd) == false) return false;

if (31 < dd) return false;

}

 

return true;

}

 

// 時分秒書式検査

private bool Cal_hms_chk(

string prm_th,

string prm_tm,

string prm_ts

)

{

int th, tm, ts;

 

if (prm_th != null)

{

if (int.TryParse(prm_th, out th) == false) return false;

if (59 < th) return false;

}

 

if (prm_tm != null)

{

if (int.TryParse(prm_tm, out tm) == false) return false;

if (59 < tm) return false;

}

 

if (prm_ts != null)

{

if (int.TryParse(prm_ts, out ts) == false) return false;

if (59 < ts) return false;

}

 

return true;

}

 

関数の先頭は、大文字で始めなければならないらしく、大文字にします

 

 

本来のレコード領域数が少ない場合のパスを作ります

 

 

 

 

 

ログモニタの取り忘れがありました

 

 

 

テータが全く表示されません

 

 

 

 

フラグ時分秒がパス出来ていないようです

 

null  ->  ""  に変更します

 

注意 このコードは、ログ記録の追加のため変更されています

 

// 年月日書式検査

private bool Cal_ymd_chk(

string prm_yy_all,

string prm_mm,

string prm_dd

)

{

int yy_all, mm, dd;

 

if (prm_yy_all != "")

{

if (int.TryParse(prm_yy_all, out yy_all) == false) return false;

if (yy_all < 1980 || 2199 < yy_all) return false;

}

 

if (prm_mm != "")

{

if (int.TryParse(prm_mm, out mm) == false) return false;

if (12 < mm) return false;

}

 

if (prm_dd != "")

{

if (int.TryParse(prm_dd, out dd) == false) return false;

if (31 < dd) return false;

}

 

return true;

}

 

// 時分秒書式検査

private bool Cal_hms_chk(

string prm_th,

string prm_tm,

string prm_ts

)

{

int th, tm, ts;

 

if (prm_th != "")

{

if (int.TryParse(prm_th, out th) == false) return false;

if (59 < th) return false;

}

 

if (prm_tm != "")

{

if (int.TryParse(prm_tm, out tm) == false) return false;

if (59 < tm) return false;

}

 

if (prm_ts != "")

{

if (int.TryParse(prm_ts, out ts) == false) return false;

if (59 < ts) return false;

}

 

return true;

}

 

フラグ時分秒のパスに成功しました

 

 

 

 

 

これで完成かと思ったのですが、削除コマンドを実行するとデータが消えました

 

 

 

ログモニタが消されてなかったので、削除します

 

 

間違いなくレコードフォーム判定が原因です

 

 

 

 

 

書式検査のエラーログを恒久的に残します

 

 

 

// 年月日書式検査

private bool Cal_ymd_chk(

string prm_yy_all,

string prm_mm,

string prm_dd)

{

int yy_all, mm, dd;

 

if (prm_yy_all != "")

{

if (int.TryParse(prm_yy_all, out yy_all) == false)

{

msg2("年に文字が含まれています", prm_yy_all, "");

return false;

}

if (yy_all < 1980 || 2199 < yy_all)

{

msg2("年数値オーバーフロー", yy_all.ToString(),"");

return false;

}

}

 

if (prm_mm != "")

{

if (int.TryParse(prm_mm, out mm) == false)

{

msg2("月に文字が含まれています", prm_mm, "");

return false;

}

if (12 < mm)

{

msg2("月数値オーバーフロー", mm.ToString(), "");

return false;

}

}

 

if (prm_dd != "")

{

if (int.TryParse(prm_dd, out dd) == false)

{

msg2("日に文字が含まれています", prm_dd, "");

return false;

}

if (31 < dd)

{

msg2("日数値オーバーフロー", dd.ToString(), "");

return false;

}

}

 

return true;

}

 

// 時分秒書式検査

private bool Cal_hms_chk(

string prm_th,

string prm_tm,

string prm_ts

)

{

int th, tm, ts;

 

if (prm_th != "")

{

if (int.TryParse(prm_th, out th) == false)

{

msg2("時に文字が含まれています", prm_th, "");

return false;

}

if (59 < th)

{

msg2("時数値オーバーフロー", th.ToString(), "");

return false;

}

}

 

if (prm_tm != "")

{

if (int.TryParse(prm_tm, out tm) == false)

{

msg2("分に文字が含まれています", prm_tm, "");

return false;

}

if (59 < tm)

{

msg2("分値オーバーフロー", tm.ToString(), "");

return false;

}

}

 

if (prm_ts != "")

{

if (int.TryParse(prm_ts, out ts) == false)

{

msg2("秒に文字が含まれています", prm_ts, "");

return false;

}

if (59 < ts)

{

msg2("秒数値オーバーフロー", ts.ToString(), "");

return false;

}

}

 

return true;

}

 

レコード要素数の不一致でした

 

 

 

 

 

ここでは書式検査に先立って、要素の分解が出来ていません

 

 

 

if (rec_form_chk(txt_buf) == false) continue;

 

 

 

// レコード書式検査

private bool rec_form_chk(string prm_txt_buf)

{

string[] fld_tbl = new string[30];

int fld_max;

 

fld_tbl = prm_txt_buf.Split(',');

fld_max = fld_tbl.Length;   // 要素個数が正しく判定されます

// 配列のサイズではありません

 

 

// 要素個数の判定

if (fld_max != Note_rec_fld_max)

{

msg2("レコード要素数が不一致です", fld_max.ToString(), Note_rec_fld_max.ToString());

return false;

}

 

// 2025.02.06 THU (07:03) goma0099 -12577505-

// 関数外の処理では、30件確保した配列に、Split で代入しています

// カンマ区切りを分割代入していますが、分割した要素個数が正しく取得出来ます

// 配列の大きさではありません

// なので要素数が少ないものはもちろんですが、多いものもゴミデータとして扱います

 

if (Cal_ymd_chk(fld_tbl[0], fld_tbl[1], fld_tbl[2]) == false) return (false);        //登録年月日

if (Cal_hms_chk(fld_tbl[3], fld_tbl[4], fld_tbl[5]) == false) return (false);   //登録時分秒

if (Cal_hms_chk(fld_tbl[8], fld_tbl[9], fld_tbl[10]) == false) return (false);  //フラグ時分秒

 

return true;

}

 

本日表示の処理も変更します

 

 

 

if (rec_form_chk(lin_cst) == false) continue;

 

入門事例としては、複雑になりすぎました