C-3 名簿検索プログラム

「開く」ボタンを押すと
(氏名, 出身地, 電話番号の) データを読み込み、
また、「追加」ボタンの左の欄に新しいデータを入力して「追加」ボタンを押すと
そのデータが追加され、
「検索」ボタンの左の欄に検索したい言葉を入れて「検索」ボタンを押すと
「メンバー:」がついた行が右下に全て抽出されてから
該当するデータが全て順次表示され、
「保存」ボタンを押すと右上の生データがそのままファイルとして保存される、というプログラムを作りましょう。
なお、最初に「開く」ボタンを押さなくても、団体名の欄を埋めて「新規」ボタンを押すだけで
右上の生データに団体名が追加され、この後メンバーデータが追加できるよう準備する、というようにもしておきましょう。

【練習問題】

まずは、次のようにフォーム上にコンポーネントを配置してください。

コンポーネント Name プロパティ
「新規」ボタン ButtonNew
「開く」ボタン ButtonOpen
「保存」ボタン ButtonSave
オープンダイアログ OpenDialog1
セーブダイアログ SaveDialog1
「団体名」エディット EditOrgName
「追加」エディット EditAdd
「検索」エディット EditSearch
「追加」ボタン ButtonAdd
「検索」ボタン ButtonSearch
右上のメモ (生データが入る) MemoRawData
右下のメモ (「メンバー」データが入る) MemoMemberList

最初は、「開く」ボタンです。このボタンは、ファイルから MemoRawData (右上のメモ) へデータを読み込みます。

// 「開く」ボタン
procedure TForm1.ButtonOpenClick(Sender: TObject);
begin
  if (OpenDialog1.Execute = true)
    then
      begin
        MemoRawData.Lines.LoadFromFile(OpenDialog1.FileName); // ファイル読み込み
      end
  ;
end;

【基礎課題 C-5】

次は、「保存」ボタンです。このボタンは、MemoRawData (右上のメモ) の内容をファイルへ保存します。空欄部分を埋めて下さい。

// 「保存」ボタン
procedure TForm1.ButtonSaveClick(Sender: TObject);
begin
  if (________________________________)
    then
      begin
        ________________________________________________; // ファイル保存
      end
  ;
end;

【練習問題】

「新規」ボタンは、この後メンバーデータが追加できるよう準備します。このプログラムでは、生データのメモの内容を一応消去した後、団体名を生データに追加します。

// 「新規」ボタン
procedure TForm1.ButtonNewClick(Sender: TObject);
begin
  // 生データを保持する入れ物を作る
  MemoRawData.Lines.Clear;// 新たな入力に備えてメモの内容を消去
  MemoRawData.Lines.Add('団体名:' + EditOrgName.Text); // 団体名を設定
end;

「追加」ボタンでデータを追加します。また、連続してデータを追加するときに便利なように、データ入力エディットの内容を消去します。

// 「追加」ボタン
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
  MemoRawData.Lines.Add('メンバー:' + EditAdd.Text); // データ追加
  EditAdd.Text := ''; // 次の入力がやりやすいように欄の中身を消去
end;

※文字列’メンバー:’の中の「:」は半角文字です。

「検索」ボタンを押したときの処理は最も複雑です。この処理は、

という2つの処理から成り立っており、プログラムは次のようになります。

// 「検索」ボタン
procedure TForm1.ButtonSearchClick(Sender: TObject);
var
  temp: String; // 1行取り出し用変数
  i: Integer; // for 文用カウンタ
begin
  // 行頭が「メンバー:」である行を抽出、結果は複数行出てくる
  MemoMemberList.Lines.Clear;
  for i := 0 to MemoRawData.Lines.Count - 1 do
    begin
      if (AnsiPos('メンバー:', MemoRawData.Lines.Strings[i]) > 0)
        then // 行頭が「メンバー:」であれば
          begin
            // 作業しやすいように変数 temp へ写し
            temp := MemoRawData.Lines.Strings[i];
            // 「メンバー:」以降の文字列を取り出す
            MemoMemberList.Lines.Add(Copy(temp, 10, Length(temp) - 9));
          end
      ;
    end;

  // 検索結果表示
  if (MemoMemberList.Lines.Count <> 0)
    then // 「メンバー:」行が1行でもあれば
      begin
        for i := 0 to MemoMemberList.Lines.Count - 1 do // 1行ずつ
          begin
            temp := MemoMemberList.Lines.Strings[i]; // 取り出す
            if (AnsiPos(EditSearch.Text,temp) > 0) // キーワードが含まれていれば
              then
                begin
                  ShowMessage(temp); // 表示する
                end
            ;
          end;
      end
  ;
end;

これで目的のプログラムが出来ました。次の手順で動作を確認してみましょう。

(1) 団体名欄に「青空テニスクラブ」と書き込み、「新規」ボタンを押す。
(2) 次のメンバーデータを順に追加欄に書き込み「追加」ボタンを押す。
  • 佐藤一郎 石川県 090-1234-5678
  • 鈴木二郎 宮崎県 070-8765-4321
  • 宮崎三郎 福島県 024-681-3579
  • 石川花子 北海道 0123-45-6789
(3) 「保存」ボタンを押し、「data.txt」という名前で保存する。
(4) プログラムを一旦終了し、また起動する。
(5) 「開く」ボタンを押し、先ほどの「data.txt」というファイルを開く。
(6) 追加欄に「佐藤四郎 東京都 03-3333-3333」と書き込み、「追加」ボタンを押す。
(7) 検索欄に「佐藤」と書き込み、「佐藤」という名前がつく2人が順に表示されることを確認する。
(8) 再度「保存」ボタンを押し、「data.txt」という名前で保存し、終了する。

ここまでのプログラムをダウンロード(D)

【応用課題 C-1】

このプログラムでは、検索欄に「宮崎」や「石川」と入力すると、姓が「宮崎」「石川」である人と出身地が「宮崎県」「石川県」である人両方が表示されてしまいます。検索欄に「宮崎」と入力した場合には宮崎さんだけが表示されるようにする (宮崎県出身というだけで姓が「宮崎」ではない人は表示しないようにする) にはプログラムをどのように改良すると良いか、その方法を述べて下さい(実際にプログラミングしなくても結構です)。