Delphi

基本-クラス型

クラス型

クラスって学校の組のようですね。

  • 「クラス」とは、特定のデータや処理をひとまとめにしたものです。英語では「class」と書き、「分類」「種類」「仲間」といった同種の集まりの意味があります。クラスから作られたものを「オブジェクト」(もの)といい、オブジェクト指向では、クラスやオブジェクトを組み合わせてプログラムを作ります。
  • オブジェクト指向のクラスは、オブジェクトの性質と振る舞いを決める設計図とも言えます。 「クラス」という設計図を基にしてオブジェクトの実体を作りますが、この実体をインスタンス(instance:実例)といいます。クラスに対して、具体的なデータを持つ個々のオブジェクトがインスタンスです。
  • クラス型は、レコード型のように複数の要素を保持できますが、データ型だけでなく、手続きや関数も要素とすることができます。この要素をメンバーと呼ぶこともあります。
  • スコープは、変数や手続きの有効範囲を示します。
    private プライベートメンバー(クラス内部でのみ利用)
    protected プロテクテッドメンバー(子クラスからは直接メンバーを使用できる)
    public  パブリックメンバー(クラスの外からも使用可能)
    published パブリッシュドメンバー(実行時型情報を生成)
  • 各メンバーには次の3種類があります。
    フィールド(変数)、メソッド(関数や手続き)、プロパティ(フィールドとメソッドの組み合わせ)

【書式】

Type
  識別子 = class
       フィールド;
       メソッド;
       プロパティ;
 end;

 

【定義方法】

  1. 新しいユニットファイルを作ります(ファイル→新規作成→ユニット)
  2. 空っぽのユニットファイルができますので、名前を付けて保存します。
    ren12
  3. interfaceの下にuses節を追加し、インポートする外部ユニットを記述します。
    ※unit1を参考にするとよいかも。
  4. implementaitionの下に具体的に手続きや関数を、「クラス名.メソッド名」という形で記入します。
    クラス名は、Typeを意味する「T」で始められることが多く、フィールド名は「F」で始められることが多いようです。

本の説明ではよくわからないので、こちら様(Seventh Delphi)のソースをお借りして試してみました。だいぶ前にアップロードされた記事のようですが、Delphi2006でも動きました。
TEditを使って新しく、TMyEditというクラスを生成しているのではないかと思います。

【実行結果】

ren13

【サンプルコード】 こちらは書籍を参考に自分で書いてみました。

unit Unit1;

interface

uses
  //外部ユニットを読み込む
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)      //クラスの宣言。親と同じ要素を継承
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);//自動でできた手続き宣言
  private
    { Private declarations }
  public                     //クラスを構成するメンバーの一部
    { Public declarations }
     Procedure SetMsg;      //手続きを宣言
  end;

var                         //var宣言部
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetMsg;                     //手続きの呼び出し
end;

procedure TForm1.SetMsg;      //手続き(クラス名が必要)
begin
  Edit1.Text := 'こんにちは'; //Edit1の前にクラス名は不要
end;
end.

【実行結果】

ren14

基本-集合型

集合型

初めて使います。
どんなものが出てくるのかな? わくわくドキドキ

【特徴】

  • 集合型は、順序型の集合を格納します
  • 数学での集合を取り扱える型です。
  • 同じ値を複数登録できません。
  • 順序型の値は0~255の範囲でなければなりません。

【宣言方法1】(書籍:やさしいDelphi より)

Type
識別子 = Set of   基底型;
...
識別子 =  [要素のリスト];

 

【宣言方法2】(書籍:やさしいDelphi より)

var
変数名 = Set of 基底型;
...
変数名 =  Set of 基底型;

 

月を入れる集合型を書いてみました。超シンプルですが、せいいっぱい(^^;
Ord関数は、0から順番に値を返してくれます。1月が0月になってしまったので、i の値を+1にしてみました。
こんなんで合っているのかなぁ・・・不安。
intToStr関数は、整数型を文字列型に変換してくれます。関数のお話はもう少し先で・・・

procedure TfrmMain.btnJikkouClick(Sender: TObject);

//集合型の宣言
Type TMonth = (January, February, March, April, May);

var
  i: Integer;
begin
  i := Ord(January) + 1;
  Memo1.Lines.Add(IntToStr(i)+ '月');
  i := Ord(February) + 1;
  Memo1.Lines.Add(IntToStr(i)+ '月');
  i := Ord(March) + 1;
  Memo1.Lines.Add(IntToStr(i)+ '月');
  i := Ord(April) + 1;
  Memo1.Lines.Add(IntToStr(i)+ '月');
  i := Ord(May) + 1;
  Memo1.Lines.Add(IntToStr(i)+ '月');
end;

【実行結果】

ren10

しかし、型を覚えるだけでも大変。しんどいわぁ
この値集合には「値が含まれているか」なんてこともできるらしいです。
in演算子 というのを使います。

いろいろなところ(本やWebサイト)を参考に、自分なりに書いてみました。
ソースコードに全部メモを入れているサイトがありましたので、素晴らしいと思いました。
最高の忘備録ですものね。マネしちゃお

procedure TfrmMain.btnJikkouClick(Sender: TObject);

Type TWeek = (Mon, Tue, Wed, Thu, Fri, Sat, Sun)  ; //集合型の宣言
     TWeekset = set of TWeek;

var
  WeekSet : TWeekset;                           //TWeekSet型の変数を宣言
  i       :integer;                             //集合型は数値で返ってくるので
begin
  i := Ord(Sun) + 1;                            //Sun番目の数値を格納

  Memo1.Clear;                                  //Memo1の文字をクリア
  WeekSet := [Mon, Tue, Wed, Thu, Fri, Sat]  ;  //変数にデータを格納 Sunを抜いた

  if Sun in WeekSet then                        //[Sun]が含まれているか?
     Memo1.Lines.Add( 'お仕事です')         //含まれている
  else
     Memo1.Lines.Add( 'お休みです')           //含まれていない
  end;

【実行結果】

ren11

 

基本-レコード型

レコード型

  • レコード型は、配列のように複数の要素を持つことができます。
  • 異なる型が格納できます。
  • 各要素に名前が付けられます。

【書式】

Type
<レコード型名> = record
<要素1>: <型1>;
<要素2>: <型2>;
・・・
end;

レコード型のサンプルを書いてみました。
Gender型をそのまま出そうとしたら、エラー攻撃に合いました。
文字列じゃないから、Memo1にそのまま入れちゃダメだったのね。
サンプルプログラムを見て作った、アンケートを参考に書き直しました。

procedure TfrmMain.btnJikkouClick(Sender: TObject);

Type
  Gender = (male, fmale);
  tMember = record
    Name  : String;
    Age   : Integer;
    Sex   : Gender;
  end;
var
    Member : tMember;

begin
 Memo1.Clear;
 with Member do
 begin
    Name := 'Jeanluc';
    Age  := 10;
    Sex  := male;
 end;

  Memo1.Lines.Add('名前= ' + Member.Name);
  Memo1.Lines.Add('年齢= ' + IntToStr(Member.Age));
  if (Member.Sex = male) then
      Memo1.Lines.Add('性別=男性')
   else
      Memo1.Lines.Add('性別=女性');
end;

【実行結果】

ren9

練習問題1 文字列の表示

練習問題1

  1. ボタンをクリックしたら、メッセージを表示する
  2. プログラムを実行する
  3. プロジェクトファイルとユニットファイルを保存する(名前を付ける)
  4. フォーム名とボタン名を変更する(キャプションも)
  5. フォームのタイトルとボタンのキャプションとアプリケーションのタイトルを表示する

一番最初って、こんなところから始めるのではないでしょうか。
いざ出発!

Delphiを起動し、「ツールパレット」の「Standard」から、「Tbutton」コンポーネントをフォームに貼り付けました。

kiso5

「Button1」をダブルクリックし、表れたコードエディタに、次のように入力しました。(beginとendの間)

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('初めてのプログラミングです');
end;

実行ボタンをクリックし「Button1」ボタンをクリックしました。
ここまで、2番までやっつけましたぞ。威張るほどのものでもないか(^^;
kiso6

名前を付けて保存するには、「ファイル」→「名前を付けて保存」をクリックします。
プロジェクトとユニット別々に名前を付けます。

ren1

キャプションと名前は、オブジェクトインスペクタのプロパティで設定します。

ren2

アプリケーションタイトルは「プロジェクト」-「オプション」で設定します。

ren4

ボタンのイベントプロシージャを次のように書き換えます。

procedure TfrmMain.btnJikkouClick(Sender: TObject);
begin
  ShowMessage(frmMain.Caption);
  ShowMessage(btnJikkou.Caption);
  ShowMessage(Application.Title);
end;

実行結果

「OK」をクリックすると、次のメッセージが表示されます。
この命令では1個ずつです。
簡単なプログラムでも、最初からきちんとやったほうがいいわね。
達成感があります。エラそうに(^^;

ren3

Delphi2006の初期画面

基礎をすっとばして、サンプルプログラミングを写して実行するところから始めました。
プログラミングの実行結果が先に見たかったのです。
ですからまだ何が何やら皆目わかっておりません。

我が家にある本は、一番新しいものでもDelphi5です。Delphi2なんていうのもあるんですよねぇ
ちょっと古すぎる気もしますが、こんなのも参考にしながら、分かる範囲で勉強過程を忘備録していこうと思います。

まず、Delphi2006を開いて、新しいプロジェクトを作成したときの画面をキャプチャーしてみました。
こんな感じです。赤丸をしてあるところは一番使いました。

kiso1

コードエディタです。ここにプログラムを書きます。
コ汚くなりましたがちょっとだけ青い色でメモをしときました。
上のほうはDelphiでほとんど入れてくれるようです。いまのところですが。
私が書いたのは、procedure(手続き)というところだけです。

kiso3

 

印刷テスト

print1

詳しい解説は、Mr.XRAY様のところにあるので省きますが、その通りにやったらプレビューできました。
やったネ!
最初は、Mr.XRAYさんのページにあるようにならなかったので、「は~ん、これは何か足りないんだな」と、過去の過ちからすぐに気づきました。足りなそうな分をパッケージに追加したら、バッチリです。

他の印刷にもチャレンジしてみようと思います。

 

データの印刷

「’plprev.dcu’ が見つかりません」1日私を苦しめた文字です。
「もうやめちゃおうかな」と、ふと思いました。
Delphi2006 って、そのままでは印刷できないんです。
印刷するためには、高い別売りのソフトが必要なようです。
MSAccessとかでDBやっている私には到底信じられません。

捨てる神あれば拾う神あり!
Mr.XRAYというお方が印刷用のコンポーネントをご自身のサイトで公開してくれています。
さっそく下記3つのファイルをダウンロードさせていただき解凍しました。
interbase-29

interbase-30

とりあえず、DBGrid印刷というのをインストールしてみようと、Mr.XRAYさんのコンポーネントの登録方法を読みながらチャレンジしてみました。順番としては次の通り。

  1. パスを通す
  2. 登録用パッケージのインストール

Dドライブのルートにフォルダを作ってパスを通し、そこに「plDBGridPrev.dcr」「plDBGridPrev.pas」を入れました。
しかしパッケージをインストールしようとすると、「’plprev.dcu’ が見つかりません」というメッセージで少しも先に進めません。
ググって調べると、ファイルが見つからないのはパスが通ってないからだというご意見が見つかりました。
でもって「きっとパスが通ってないんだわ」と、固く信じ込んでしまったのです。勝手に思い込み・・・

自分で作ったパスをやめて、最初からある「lib」というパスの通ったフォルダにも入れてみましたが、やっぱり同じエラーでした。
かれこれ丸1日、ああだこうだやってみて、あることに気づきました。
エラーはいつも、usesの「plPrev」いうところが赤くなります。
「パスがちゃんと通っているとしたら、plPrvが必要なのでは?」と思い、解凍した「plPrv」フォルダのファイルを、パスの通った(と思う)フォルダに入れました。
私は、Delphiに関してはほぼ無知です。こんな初歩のところにたどり着くのに1日かかりました。
あとで気づいたことですが、Mr.XRAYさんの「インストール方法」には、「プリンタ設定コンポーネントが必要です」とちゃんと書いてありました。
あまりにも情けないので、少しだけ恥の忘備録しておこうと思います(^^;

パスを通す

  1. Dのルートにフォルダ「XRAYp」を作り、解凍したファイル(pasとdcr)を全部入れました。
  2. Delphiを起動し(念のため管理者権限で)DBのあるプロジェクトファイルを開きました。
  3. 「ツール」-「オプション」をクリックし、「Delphiオプション」の「ライブラリ-Win32」を選択しました。
    ライブラリパスの右側の「・・・」をクリックすると、ライブラリパスの一覧ダイアログボックスが開きます。
    下のテキストボックス右側の「・・・」をクリックして、パスを入れ(フォルダの場所)、「追加」ボタンをクリックしました。
    interbase-31

パッケージのインストール

ここは、Mr.XRAYさんの「登録パッケージのインストール」を参考にさせていただきました。
環境は、Delphi2006です。

  1. 「ファイル」-「開く」をクリックし、下記フォルダから、「dclusr.dpk」を開きました。
    interbase-32
    interbase-33
  2. 画面右の「プロジェクトマネージャー」に、「dclusr.bpl」の名前で表示されました。
    この名前(パッケージ)の上で右クリックし「インストール」をクリックしました。
    interbase-35
    インストールがうまくいったときには、「~がインストールされました」のようにメッセージが出ます。
    苦労した後のこのメッセージには「やった!」と歓喜しましたよ~
    interbase-34
  3. パッケージで右クリックし、「上書き保存」をクリックしました。

コンポーネントを登録する

  1. パッケージで右クリックして「追加」を選択します。
    「参照」をクリックして、必要なファイルを選択します。
    interbase-36
  2. パッケージ名(dclusr.bpl)の上で右クリックし、メニューから「再構築」をクリックします。
    これでインストールが終わりです。

印刷

コンポーネントが追加されたので、いよいよ印刷テストしてみます。
フォームに、TplDBGridPrevコンポーネントを配置します。
interbase-37

ボタンを1つ配置し、このボタンのイベントプロシージャに次のコードを書きました。

procedure TMainForm.Button2Click(Sender: TObject);
begin
  plDBGridPrev1.Preview;
end;

実行結果

interbase-28

「印刷」をクリックしたら、プリンタに印刷できました。
たった1日でしたけれど、長く感じられた1日でした。
最後に、Mr.XRAYさま、ありがとうございました。と、ここで言っても伝わらないか(^^;

SQLを使って文字を検索

SQL・・・昨夜から挑戦していますが、まるで雲をつかむようです。 エラーばかりで全然できませんでしたが、今日なんとか1つだけ成功しました。 どうやら、コーテーションのところで躓いていたようです。 「東京花子」を検索したい場合、WHERE NAME = ‘東京花子’ というのが検索文字になります。 この「’」をDelphiで表すには、シングルコーテーションが2つ追加されます。つまり WHERE NAME = ’’’東京花子’’’ のようになるわけです。 これがわからなかった・・・・

下のコードでは、LIKEの後ろの「”’」は%以降の文字列をくくるシングルコーテーションというわけですね。
で、後ろに4つ並んでいるシングルコーテーションは、「’」を入れるためのもの。な~るへそ

procedure TfrmMain.btnSelectClick(Sender: TObject);
  var
    s : string;
begin

  //SQLを使って文字を選択 (NAME LIKE '%TARO%')
  s := '(NAME LIKE''' + '%' +  edtName.Text + '%' + '''' + ')';

  DataModule2.tblAddress.Active := False;
  DataModule2.tblAddress.DataSet.CommandText :=
   'SELECT * FROM MEIBO WHERE' + s ;

  DataModule2.tblAddress.Active := True;
end;

実行結果

「郎」という文字をテキストボックスに入力し、「選択」をクリックしました。名前に「郎」がつくレコードが選択されました。
複雑な検索をするには、フィルターだけでは無理みたいですね。「~を含む」というのはできなかったもの。
だけど、SQL難しそうです。

interbase-27

レコードの操作

InterBase7.5で作ったデータベースを、Delphiから表示させることができました。
やっと入り口に立てたところかな。

今度はレコードの操作をやってみます。
実は、便利なコンポーネントがあるんですよ。「TDBNavigator」コンポーネントです。
↓こんなボタンの集合体です。

interbase-24

しかし、ここでは勉強なので、ボタンを作って、ボタンをクリックしたときに作業するようにプログラムを書いてみようと思います。
こんな便利なのがあるんだから、実際はこれを使うほうが楽だと思いますが・・・
ボタンを5個配置しました。「TButton」コンポーネントです。

interbase-25

ボタンの上でダブルクリックをすると、イベントプロシジャーが開きますので、それぞれのイベントにコードを書きます。

プログラムのソース

//1つ前のレコードへ移動
procedure TfrmMain.btnAddClick(Sender: TObject);
begin
  //レコードを追加する
  DataModule2.tblAddress.Append;
end;

procedure TfrmMain.btnBackClick(Sender: TObject);
begin
  //1つ前のレコードへ移動
 DataModule2.tblAddress.Prior;
end;

procedure TfrmMain.btnDeleteClick(Sender: TObject);
begin
  if MessageDlg('削除してもいいですか?',mtConfirmation,
    [mbYes,mbNo],0) = mrYes then
    DataModule2.tblAddress.Delete;//レコードの削除
end;

//次のレコードへ移動
procedure TfrmMain.btnNextClick(Sender: TObject);
begin
  DataModule2.tblAddress.Next;
end;

procedure TfrmMain.btnSaveClick(Sender: TObject);
begin
  //データを保存する
  DataModule2.tblAddress.ApplyUpdates(-1);
end;

フィルターをかける

フィルターをかけるというのは、「指定したデータを探して取り出す」ということです。
一番簡単そうなヤツをやってみようと思います。

メインフォームの上のほうに、[TLabel]2つと[TEdit]を1つ[TButton]を2つ配置します。
「選択」「解除」のイベントプロシージャに次のコードを入力します。

  //フィルターを解除する
  DataModule2.tblAddress.Filtered := False;
  //名前でフィルター(選択)する
  DataModule2.tblAddress.Filter := 'NAME=''' + edtName.Text + '''';
  DataModule2.tblAddress.Filtered := True;

実行結果

interbase-26

DelphiからDBを表示する

InterBase7.5で作成したデータベースを、Delphi2006で表示してみます。
できればおなぐさみ~
※この方法は、ナッキー様のページを参考にさせていただきました。

コンポーネントの準備

Delphiを起動します。Form1のキャプションに「住所録」と入力し、Nameに「frmMain」としました。
フォームに直接コンポーネントを配置せずに、コンポーネントを一括で管理するために、データモジュールを使うことにします。
「ファイル」→「新規作成」→「その他」から「データモジュール」をクリックし、データモジュールを作成しました。これに「Data.pas」という名前を付けて保存しました。
interbase-19

このデータモジュールールを使うには、フォームから、「ファイル」→「ユニットを使う」をクリックし、目的のユニットを選択します。(ここではData.pas)

データモジュールに、コンポーネントを3つ配置します。
ツールパレットの「dbExpress」から「TSQLConnection」コンポーネントと「TSimpelDataSet」を、「Data Access」から「TDataSource」を配置します。

「SQLConnection1」を右クリックし「接続の設定」を選択します。
「dbExpress接続」ダイアログボックスが表示されるので、「+」をクリックし、新しい接続を設定します。
ドライバ名には、「Interbase」を選択し、接続名を入力し「OK」をクリックします。
ここでは「CUSTOMERDB」と入力しました。

interbase-21
接続名が表示されますので、赤く囲んだところを確認します。
データベースと文字コードです。

interbase-20

配置したコンポーネントにプロパティを設定します。

SQLConnection1の「LoginPrompt」(データベース)をFalseに、Connected(データベース)をTrueに設定します。

SimpleDataSet1の「Connection」(リンク)には「SQLConnection1」を、CommandType(リンク)に「ctTable 」を、CommandTextからテーブル名を入力(選択)します。ここでは「Meibo」を選択しています。ActiveプロパティをTrueにします。

DataSource1のDataSetには「SImpleDataSet1」を入力します。(選択)
Connectionには「SQLConnection1」を入力します。(選択)
Activeを「True」にします。

interbase-17

コンポーネントの準備ができたら、項目の準備です。
interbase-22SimpleDataSet1コンポーネントで右クリックし、「項目の設定」をクリックします。
空白のダイアログボックスが表示されるので、画面の白いところで右クリックをし、コンテキストメニューの「すべての項目の追加」をクリックします。

白いところが項目名で埋まりました。
この場面から新しい項目の作成などもできるようです。

 

 

 

 テーブルの内容を表示する

メインフォームに、「TDBGrid」を配置します。
データベースの「DataSource」プロパティに、「DataModule1.DataSource1」を選択(入力)します。
※DataModuleは1とは限らない。
Visibleを「True」に設定すると、テーブルの内容が表示されます。

実行すると次のように表示されました。
これで、InterBase7.5で作成したデータベースに、Delphiからアクセスすることができました。
やったね!
interbase-23