成績データの入力

DialogBox から成績データを入力して、簡単なエラーチェックを行います。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの仕様

ビジネスアプリケーションでは入力データのエラーチェックは非常に重大な問題です。
人間の作業にエラーはつきもので、細心の注意を払ってもエラーがまぎれ込むのを防げません。
オーダーメードのプログラムの利点は、そのシステムに最も適したプログラムを作成できることです。
エラーを少しでも食い止めるために「考えられるあらゆるチェック」をプログラムに組み込んで下さい。
今回のデータは単純で大したチェックはできませんが、次のエラーチェックをしてみましょう。
  1. 追加登録で学籍番号の重複は許さない。
    学籍番号の更新はできません。
    更新したいときは、レコードを削除してから追加します。
  2. 学籍番号は数字3桁で「001番~990番」までとします。
    入力時には先頭の空白を省略することができ、「23」と「023」は同じ番号とする。
  3. 成績は「0点~100点」までとします。
  4. 名前は最大15文字で、先頭を空白(全角・半角)で初めてはならない。
    性と名の間には「全角の空白」または「半角で2バイトの空白(既存のデータ形式と同じ)」をタイプする。
    「半角1バイト」で区切られているときは「半角2バイト」に編集して表示する。
  5. 学籍番号と成績は「数字に先行する空白と数字」以外の入力を禁止する。
    下の表は、.(空白),\0('\0') を意味します。
          ...15\0           //正しい
          78\0              //正しい
          3A\0              //誤り(英字が混ざっている)
          ...1.5\0          //誤り(数字の中間に空白がある)
          23.\0             //誤り(数字の後に空白がある)
          \0                //誤り(数字がタイプされていない)
          ..\0              //誤り(数字がタイプされていない)
  6. エラーを発見した時、ブザーを鳴らしてエラーメッセージを表示し、エラーを起こした Box にフォーカスを設定して注意を促します。
  7. ブザーを鳴らす関数です。
    周波数と鳴動タイムをパラメータとして渡します。
    一部のOS(マシン)では周波数を変えても決まった音しか鳴らない場合があります。
    Beep(440,100);
  8. フォーカスを IDC_EDIT1 の EditBox に設定するコードです。
    SetFocus(GetDlgItem(hDlg, IDC_EDIT1));
  9. レコードを削除するときは、削除確認をして下さい。
  10. レコードの追加は、学籍番号をキーにして挿入することにします。
    レコードの挿入は難しくは無いはずです。
  11. レコードの更新とレコードの追加でエラーをチェックして下さい。
    点数の範囲チェックや番号の重複チェックは簡単でしょう。
  12. プログラムを終了する前に全レコードをファイルに保存して下さい。


ビジネスアプリケーションでは入力データのエラーチェックは非常に重要な問題です。
プログラマに取っては面倒なことかも知れませんが「考えられるあらゆるチェック」を行うのです。
  1. 日付の妥当性のチェック(年月日の関係)
  2. コードの照合チェック
  3. 数字や英字のチェック
  4. 数値やコードの範囲チェック
  5. チェックデジットによるチェック
  6. 桁によるチェック(一桁目は1と2に限るなど)
  7. 組み合わせによるチェック
  8. マスターファイルとの照合チェック
他にもコンピュータでチェックが出来るあらゆる項目が入力チェックの対象になります。

DialogBox のメニュー

DialogBox にはメニューバーが無いので、代わりに右クリックメニューを使います。
右クリックメニューの詳細は 右クリックメニューを設定する を参照して下さい。
メニューでは「データ入力,データ保存,ソート,終了」の機能をサポートします。
    case IDCANCEL:
         データの保存を確認して終了
         break;
    case IDM_GET:
         現データの保存を確認して、新しいファイルを入力する
         break;
    case IDM_PUT:
         現在処理中のデータをファイルに保存
         break;
    case IDM_SORT:
         番号や成績でソートする
         break;

DialogBox では WM_RBUTTONDOWN は検出されないので WM_CONTEXTMENU でメニューを表示します。
//    case WM_RBUTTONDOWN:
    case WM_CONTEXTMENU:
        pt.x= LOWORD(lp);
        pt.y= HIWORD(lp);
        hMenu= LoadMenu(g_inst,"MYMENU");
        if (hMenu==NULL)
        {   MessageBox(hDlg,"MYMENU のロードに失敗","確認",MB_OK);
            break;
        }
        hSubmenu= GetSubMenu(hMenu,0);
        ClientToScreen(hDlg,&pt);
        TrackPopupMenu(hSubmenu,TPM_LEFTALIGN,pt.x,pt.y,0,hDlg,NULL);
        DestroyMenu(hMenu);
        break;


メニュー操作と注意事項
メッセージで確認したときの応答と対処です。
オプション機能

プログラムアドバイス

    struct  D_DEF
    {   char    num[4];
        char    name[16];
        char    ten1[4];
        char    ten2[4];
        char    ten3[4];
        char    crlf[2];
    }   DATA[100];
  1. 同じ形式の構造体同士は直接代入できる。
    DATA[i]= DATA[k];
  2. 改行コード(0x0D, 0x0A)を設定する。
    DATA[i].crlf[0]= '\r';
    DATA[i].crlf[1]= '\n';
  3. 構造体 DATA[i] をゼロクリアする。
    ZeroMemory(&DATA[i],sizeof(D_DEF));
  4. 全角空白(0x81, 0x40)の比較。(半角の空白は 0x20)
    if (strncmp(DATA[i].name," ",2)==0) 全角空白の処理;
  5. char タイプを 0x81 と比較すると負の値として比較され、思った結果にならないことがある。
    このような場合、unsigned char(または BYTE) を使う方が間違いが少ない。
    if (DATA[i].name[0]==0x81)
  6. Edit Box 中の文字数を取得する。
    len= SendMessage(GetDlgItem(hDlg,IDC_EDIT1),EM_LINELENGTH,0,0);

Edit Box のプロパティから「Number」を設定すると「数字以外の入力が出来なくなる」のでこの機能を使うことも有力です。
説明の画像

超初心者のプログラム入門(Win32API C++)