ITを駆使する猫エンジニア

 こんばんは、童爺です。

 

 今回ユーザ詳細画面を作ったので、公開します。

 

 まず、挙動から。

 

 アプリを立ち上げて、IDとパスワードを入力します。

 

 で、Enterキー押下又はログインボタンクリックで以下の画面へ遷移します。

 

 県を北海道から秋田に変えます。

 

 登録ボタンをクリックして再度最初の画面からログインし直します。

 

 県が秋田に代わっています。

 

 この状態で、キャンセル又は登録ボタンクリックで、元の画面へ戻ります。

 

 上記を見てもらえれば解ると思いますが、前のログイン情報が残ったままです。

 

 これはデバックで便利なのでこのままにしていますが、完成したら以前のログイン情報は消すつもりです。

 

 セキュリティ上、その方が良いので。

 

 で、設計画面です。

 

 コードです。

unit UserDetail;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMX.Layouts, FireDAC.Stan.Intf,
  FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf,
  FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys,
  FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs,
  FireDAC.FMXUI.Wait, Data.DB, FireDAC.Comp.Client, FMX.ListBox,
  FMX.DateTimeCtrls, FMX.Edit, FireDAC.Stan.Param, FireDAC.DatS,
  FireDAC.DApt.Intf, FireDAC.DApt, System.Rtti, System.Bindings.Outputs,
  Fmx.Bind.Editors, Data.Bind.EngExt, Fmx.Bind.DBEngExt, Data.Bind.Components,
  Data.Bind.DBScope, FireDAC.Comp.DataSet;

type
  TForm_UserDetail = class(TForm)
    Layout_Header: TLayout;
    Label_Cation: TLabel;
    Layout_Footer: TLayout;
    Layout_BtnFooter: TLayout;
    Button_Resist: TButton;
    Button_Cancel: TButton;
    Layout_ID: TLayout;
    Label_ID: TLabel;
    Edit_ID: TEdit;
    Layout_UserName: TLayout;
    Label_UserName: TLabel;
    Edit_UserName: TEdit;
    Layout_LastName: TLayout;
    Label_LastName: TLabel;
    Edit_LastName: TEdit;
    Layout_FirstName: TLayout;
    Label_FirstName: TLabel;
    Edit_FirstName: TEdit;
    Layout_Password: TLayout;
    Label_Password: TLabel;
    Layout_Birthday: TLayout;
    Label_Birthday: TLabel;
    DateEdit_Birthday: TDateEdit;
    FDConnection_UserDetail: TFDConnection;
    FDQuery_UserDetail: TFDQuery;
    Layout_RePassword: TLayout;
    Label_RePassword: TLabel;
    Edit_RePassword: TEdit;
    Edit_Password: TEdit;
    FDQuery_UserDetailUpdate: TFDQuery;
    Layout_Ken: TLayout;
    Label_Ken: TLabel;
    ComboBox_Ken: TComboBox;
    BindSourceken: TBindSourceDB;
    FDTableken: TFDTable;
    BindingsList_Ken: TBindingsList;
    LinkFillControlToField1: TLinkFillControlToField;
    procedure Button_CancelClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button_ResistClick(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
    constructor Create(AOwner: TComponent; const id: Integer; const UserName: String; const Password: String); reintroduce;
  end;

var
  Form_UserDetail: TForm_UserDetail;

implementation

{$R *.fmx}

uses
  System.Hash,
  MMS_CommonDialog;

procedure TForm_UserDetail.Button_ResistClick(Sender: TObject);
var
  MsgDlg: TForm_MsgDlg;
  MD5: THashMD5;
begin
  if Edit_UserName.Text = '' then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, 'ユーザ名を入力してください。');
    MsgDlg.ShowModal;
    exit;
  end;
  if Edit_LastName.Text = '' then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, '苗字を入力してください。');
    MsgDlg.ShowModal;
    exit;
  end;
  if Edit_FirstName.Text = '' then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, '名を入力してください。');
    MsgDlg.ShowModal;
    exit;
  end;
  if Edit_Password.Text = '' then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, 'パスワードを入力してください。');
    MsgDlg.ShowModal;
    exit;
  end;
  if Edit_RePassword.Text = '' then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, 'パスワード再入力を入力してください。');
    MsgDlg.ShowModal;
    exit;
  end;
  if Edit_Password.Text <> Edit_RePAssword.Text then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, 'パスワードが一致しません。');
    MsgDlg.ShowModal;
    exit;
  end;
  if ComboBox_Ken.ItemIndex = -1 then
  begin
    MsgDlg := TForm_MsgDlg.Create(self, '県名を選択してください。');
    MsgDlg.ShowModal;
    exit;
  end;
  try
    try
      FDQuery_UserDetailUpdate.Params.ParamByName('Input_id').AsInteger := StrToInt(Edit_ID.Text);
      FDQuery_UserDetailUpdate.Params.ParamByName('Input_username').AsString := Edit_UserName.Text;

      MD5 := THashMD5.Create;
      MD5.Update(Edit_Password.Text);
      FDQuery_UserDetailUpdate.Params.ParamByName('Input_password').AsString := MD5.HashAsString;

      FDQuery_UserDetailUpdate.Params.ParamByName('Input_last_name').AsString := Edit_LastName.Text;
      FDQuery_UserDetailUpdate.Params.ParamByName('Input_first_name').AsString := Edit_FirstName.Text;
      FDQuery_UserDetailUpdate.Params.ParamByName('Input_birthday').AsString := DateEdit_Birthday.Text;
      FDQuery_UserDetailUpdate.Params.ParamByName('Input_ken').AsInteger := ComboBox_Ken.ItemIndex + 1;
      FDQuery_UserDetailUpdate.ExecSQL;
    except
      on e: Exception do
      begin
        FDQuery_UserDetailUpdate.Close;
        MsgDlg := TForm_MsgDlg.Create(self, 'Error:' + e.Message);
        MsgDlg.ShowModal;
        raise;
      end;
    end;
  finally
    FDQuery_UserDetailUpdate.Close;
  end;
  Close;
end;

constructor TForm_UserDetail.Create(AOwner: TComponent; const id: Integer; const UserName: String; const Password: String);
var
  MsgDlg: TForm_MsgDlg;
begin
  inherited Create(AOwner);

  try
    try
      FDConnection_UserDetail.Open;
      FDTableken.Open();
      FDQuery_UserDetail.Params.ParamByName('Input_id').AsInteger := id;
      FDQuery_UserDetail.Params.ParamByName('Input_username').AsString := UserName;
      FDQuery_UserDetail.Open();

      Edit_ID.Text := IntToStr(id);
      Edit_UserName.Text := UserName;
      Edit_LastName.Text := FDQuery_UserDetail.FieldByName('last_name').AsString;
      Edit_FirstName.Text := FDQuery_UserDetail.FieldByName('First_name').AsString;
      Edit_Password.Text := Password;
      Edit_RePAssword.Text := Password;
      DateEdit_Birthday.Text := FDQuery_UserDetail.FieldByName('birthday').AsString;
      ComboBox_Ken.ItemIndex := FDQuery_UserDetail.FieldByName('ken').AsInteger - 1;
    except
      on e: Exception do
      begin
        MsgDlg := TForm_MsgDlg.Create(self, 'Error:' + e.Message);
        MsgDlg.ShowModal;
        Close;
      end;
    end;
  finally
    FDQuery_UserDetail.Close;
  end;
end;

procedure TForm_UserDetail.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FDTableken.Close;
  FDConnection_UserDetail.Close;
end;

procedure TForm_UserDetail.Button_CancelClick(Sender: TObject);
begin
  Close;
end;

end.

 

 メインフォームも変更しているのですが、未だ工事中の箇所があるので、全て完成してから再度、公開します。

 

 今回の反省点ですが、新規作成画面とフォームのデザインが同じで且つ、登録ボタンをクリックした際の入力チェックが同じです。

 

 なので親フォームを作って入力チェック等を実装してから、継承して子フォームを作ればよかったなと、出来上がってから思いました。

 

 画面のデザインを漠然と考えていただけなので、失敗しました。

 

 次回からは本番じゃないからとか思わずに勉強でも、しっかりとデザインを考えてから設計に入りたいと考えています。

 

 あ、継承せずにコンストラクタのCreateを呼ぶ際、パラメータで挙動を変更するでもよかったかな?

 

 どっちがスマートだろう。

 

 やっぱオブジェクト指向言語を使用しているのだから継承かな。

 

 まあ、そんな感じです。

 


 

 それではまた。

 

 でわでわ。