G3509_And_note_トラブル発生
2025年2月6日
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;
入門事例としては、複雑になりすぎました