作者別: chie

基本-変数と定数

変数

  • 変数宣言は、「var」で始まるブロックで記述します。
  • 変数名の後ろにコロン(:)を記述し、その後ろに型を記述します。
  • 同じ型であれば、カンマで区切って複数の宣言をすることができます。
    var
      intNum: Integer;
      strName1,strName2,strName3:String;
  • レコード型とクラス型を使用するときには、「<変数名>.<要素名>」として各要素を設定することができます。
  • with文を使って変数名を省略することができます。
     
    with Member do
     begin
        Name := 'Jeanluc';
        Age  := 10;
        Sex  := male;
     end;
  • ローカル変数は、変数を宣言した手続きや関数、メソッド内だけで有効です。
  • ユニット変数は、変数を宣言したユニット内であれば、どのイベントハンドラからでも利用できます。
    ただそ、外のユニットからは利用できません。
  • グローバル変数は、プロジェクト全体から利用できます。
    unit1のpublicで宣言した変数は、他のユニットからも参照できます。(uses節にユニットを追加する)

変数名の制約

  • 変数には、大文字小文字の区別はありません。
  • 変数の1文字目にはアルファベットかアンダーバー(_)を使います。
  • ピリオドは使えません。
  • 型名や予約語と同じ名前は使えません。
  • 適用範囲内で同じ変数名をつけることはできません。

変数名(番外編)

※下記記事はAccessのVBAで勉強したものです。Delphiとは違っている部分もあるかと。

  • 変数とは、データを格納するメモリ上の場所のことです。変数には任意の名前が付けられます。
  • 分かりやすい変数名をつけるための工夫が必要です。
    パブリック変数かローカル変数が分かる
    データ型がわかる
    長い変数はアンダーバーや大文字などを使って区切る
    ループの制御変数を決めておく、など。下記は、Accessでお世話になったぜんこうさんからの引用です。
    VBAですが、Delphiでも共通する部分があると思います。
    ああ、コレとても勉強になるわ。ボタン名のつけ方などもわかるようにしたほうがいいですよね。
変数名は先頭にデータ型を小文字で明示して Dim を見なくても変数の型が
 わかるようにします。その後で頭を大文字にして、変数名をわかりやすい
 ように、必要なら省略しながら命名します。
Integer → intAge
 Long → lngRecCnt (RecordCountの略)
String → strAddress
 Boolean → blnExistFile
みたいな感じ。 
定数は型は書かずに、全部大文字にしてます。
MAX_LINE_COUNT
 INIT_FILENAME
みたいな感じ。

プロシージャ名は、単語の先頭を大文字で後は小文字、述語を最初に
書いてます。
GetFileName
 SetJobsComboBox
みたいな感じ。

また、フォームのテキストボックスなども変数と同様にコントロールの
種類がわかるようにしてます。
TextBox → txtAddress
 ComboBox → cmbJobs
 ListBox → lstCompany
 CommandButton → cmdOk または btnOk
みたいな感じ。

定数

  • 定数は、値を格納しておく領域ですが、値の変更はできません。
  • プログラム中で、決まった値(変化しない)を使うときに利用します。
  • 定数宣言は、「const」で始まるブロックに記述します。
  • 定数名の後ろにイコール(=)を記述し、その後ろに値を記述します。

【書式】

const
   AGE   = 10;
   NAME  = 'Jean';

基本-クラス型

クラス型

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

  • 「クラス」とは、特定のデータや処理をひとまとめにしたものです。英語では「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