|
◆グローバル変数
ファイルの開く、保存を行う事は出来るようになりましたが、ファイル名の欄が常に何も無し状態となっており、先ほど指定した内容が入っていて欲しい、つまり、ファイル名を保持して欲しい、と思われる事でしょう。ファイル名を変数に入れるようにしても、イベントハンドラ内で下記のようにローカル変数として変数宣言をしても、このイベントハンドラを終了した段階で変数内容はクリアされてしまいますので意味がありません。ローカル変数の場合、同じ変数名でも他のイベントハンドラ内のローカル変数とは別物として扱われ、他のイベントハンドラへ変数内容を受け渡す事も出来ません。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
var
fname : string ;
begin
OpenDialog1.FileName := fname ; (?)
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
Memo1.Lines.LoadFromFile(fname);
end;
end; |
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
var
fname : string ;
begin
SaveDialog1.FileName := fname ; (?)
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
Memo1.Lines.SaveToFile(fname);
end;
end; |
このようにイベントハンドラ mnuFileOpenClick、mnuFileSaveAsClick の双方で同じ変数を扱いたい、という場合には、グローバル変数として変数宣言をする事が出来ます。グローバル変数として宣言するには、その変数を利用するイベントハンドラ・関数・手続きよりも先に、それらの外で変数宣言を行う事で可能です。
変数宣言を行う場所としては、
@すぐ直前
var
fname : string ;
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
Memo1.Lines.LoadFromFile(fname);
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
Memo1.Lines.SaveToFile(fname);
end;
end; |
A implementation節の直後
〜
var
Form1: TForm1;
implementation
var
fname : string ;
{$R *.dfm}
// メニュー
// →ファイル→新規作成
procedure TForm1.mnuFileNewClick(Sender: TObject);
〜 |
B implementation節の直前
〜
var
Form1: TForm1;
fname : string ;
implementation
{$R *.dfm}
// メニュー
// →ファイル→新規作成
procedure TForm1.mnuFileNewClick(Sender: TObject);
〜 |
というようなパターンがあります。いずれでも構いませんが、@だと、どこで変数を宣言したのかが分かりにくくなりますので@は避けた方が良いでしょう。
◆Private宣言、Public宣言
しかし、Delphi(Object Pascal)におけるグローバル変数の多用は余り美しくない、という事でお薦め出来る手法ではありません。この変数 fname は、TForm1 内で使用する変数で、オブジェクト指向的には、自分の中で使うものは自分の中で宣言してカプセル化(モジュール化;パッケージ化)してしまう、という考えの元でいくと、オブジェクト(クラス)内でのみ使用する変数はそのクラス内で宣言しましょう、という事で、変数 fname も TForm1 クラス定義内で宣言する事になります。
TForm1クラス定義は
type
TForm1 = class(TForm)
Memo1: TMemo;
StatusBar1: TStatusBar;
MainMenu1: TMainMenu;
mnuFile: TMenuItem;
mnuFileNew: TMenuItem;
N1: TMenuItem;
mnuFileExit: TMenuItem;
mnuFileOpen: TMenuItem;
mnuFileSaveAs: TMenuItem;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure mnuFileNewClick(Sender: TObject);
procedure mnuFileExitClick(Sender: TObject);
procedure mnuFileOpenClick(Sender: TObject);
procedure mnuFileSaveAsClick(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end; |
となっています。
ここには、これまで追加したコンポーネントのオブジェクトやイベントハンドラが記述されています。TForm1では、こういうオブジェクトやイベントハンドラが使用されていますよという事が一目瞭然です。このうち「Memo1: TMemo;」〜「procedure mnuFileSaveAsClick(Sender: TObject);」までは Delphiが自動的に記述を行う部分なのでそのまま置いておき、我々が記述するのは、Private宣言、Public宣言の部分だけにします。
Private宣言部分は、この TForm1内でのみ使用し、外からは見せません・アクセス出来ません、という部分です。Public宣言部分は、この TForm1内で使用するのですが、外から見たりアクセスする事が出来ます。フォームを複数利用する場合に有効となってきます。ここでは、変数 fname は、TForm1内でのみ使用し外からアクセスする必要もありませんので、Private宣言部分で変数宣言を行います。
type
TForm1 = class(TForm)
Memo1: TMemo;
StatusBar1: TStatusBar;
MainMenu1: TMainMenu;
mnuFile: TMenuItem;
mnuFileNew: TMenuItem;
N1: TMenuItem;
mnuFileExit: TMenuItem;
mnuFileOpen: TMenuItem;
mnuFileSaveAs: TMenuItem;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure mnuFileNewClick(Sender: TObject);
procedure mnuFileExitClick(Sender: TObject);
procedure mnuFileOpenClick(Sender: TObject);
procedure mnuFileSaveAsClick(Sender: TObject);
private
{ Private 宣言 }
fname : string ;
public
{ Public 宣言 }
end; |
変数だけでなく、自作の関数や手続きも、Private/Public宣言部分に記述する事が出来ます。変数宣言のあとに記述します。
type
TForm1 = class(TForm)
〜
private
{ Private 宣言 }
fname : string ;
function ABCDE(V1,V2:integer) : Integer ;
procedure FGHIJK(V1,V2:string) ;
public
{ Public 宣言 }
end; |
この場合、関数、手続きの記述は
function TForm1.ABCDE(V1,V2:integer) : Integer ;
begin
・・・
end;
procedure TForm1.FGHIJK(V1,V2:string) ;
begin
・・・
end; |
のように、関数名・手続き名の前に、「TForm1.」を付ける必要があります。つまり、「TForm1のABCDE関数」「TForm1のFGHIJK手続き」のような感じとなります。
こうする事によって、オブジェクトインスペクタでは見えませんが、変数は TForm1オブジェクトのプロパティのように、関数や手続きは、メソッドのように、扱う事が出来るようになります。
こうして、グローバル変数・自作の関数・手続きの所在ははっきりと明確にしておくと、後でプログラムを見た場合に分かり易かったり、他人が使う場合や、他のプログラムで再利用する場合などに都合が良くなります。
※プログラムが複雑化し、フォームなどを複数利用したりして、いろんなフォームで利用する共通関数群などは、ユニットを新規作成し、ユニット内で宣言、実装を行って、それを利用する各フォームでは uses節にそのユニット名を記述する、という手法もあります。
変数 fname は TForm1の Private内で宣言するとして、本ソフトを起動した時と、新規作成を行った時に初期化処理(内容を空にする)を行うようにします。
オブジェクトインスペクタ画面でForm1 オブジェクトの OnShow イベント欄を選択し、ダブルクリックします。「FormShow」と表示され、コードエディタ画面にそのプログラムコードが追加されます。 | |
procedure TForm1.FormShow(Sender: TObject);
begin
end; |
これを下記のように記述します。
// 起動時
procedure TForm1.FormShow(Sender: TObject);
begin
fname := '' ;
end; |
次に、「新規作成」を行った時の初期化処理を行います。
オブジェクトインスペクタ画面で mnuFileNew オブジェクトの OnClick イベント欄「mnuFileNewClick」の箇所をダブルクリックするか、又は、コードエディタ画面をスクロール表示させて、「procedure TForm1.mnuFileNewClick(Sender: TObject);」の箇所へ移動して下さい。
// メニュー
// →ファイル→新規作成
procedure TForm1.mnuFileNewClick(Sender: TObject);
begin
if MessageDlg('新規作成します。', mtConfirmation,
[mbYes, mbNo], 0) = mrYes then begin
Memo1.Lines.Clear ;
end;
end; |
これを下記のように記述します。
// メニュー
// →ファイル→新規作成
procedure TForm1.mnuFileNewClick(Sender: TObject);
begin
if MessageDlg('新規作成します。', mtConfirmation,
[mbYes, mbNo], 0) = mrYes then begin
Memo1.Lines.Clear ;
fname := '' ;
end;
end; |
既に記述しましたが、「開く」「名前を付けて保存」を行った時の処理も忘れずに変更して下さい。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
Memo1.Lines.LoadFromFile(fname);
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
Memo1.Lines.SaveToFile(fname);
end;
end; |
「OpenDialog1.FileName := fname ;」は、「ファイルを開く」ダイアログ画面のファイル名欄にファイル名を表示させるため指定しています。フルパス・ファイル名を受け渡すと Delphi6 では、ファイルの場所もそのディスクドライブ・フォルダへ移動してくれるようです(※旧バージョンのDelphiでは、InitialDirプロパティに切り分けて代入する必要がありました)。
Executeメソッドを行った後、「fname := OpenDialog1.FileName ;」で変数 fname に指定したファイルのフルパス・ファイル名が代入されます。
◆OpenDialog、SaveDialog
「ファイルを開く」ダイアログ画面を表示するための OpenDialog コンポーネント、「ファイル名を付けて保存」ダイアログ画面を表示するための SaveDialog コンポーネント、についてもう少し詳しく記述します。
オブジェクトインスペクタ画面でOpenDialog1 オブジェクトの DefaultExt プロパティ欄を選択し、「txt」と入力します。
このプロパティは、ファイル名を入力する際、拡張子(ファイルの種類)を省略した際に自動的に付加する内容を指定します。「.」は入力しません。
例えばファイル名に「abc」と入力すると、「abc.txt」と入力した事になります。 | |
|
|
オブジェクトインスペクタ画面で OpenDialog1 オブジェクトの Filter プロパティ欄を選択すると右横に[…]ボタンが表示されますのでこのボタンをクリックします。 | |
|
|
「フィルタの設定」画面が表示されます。初期状態は何も表示されていません。 | |
|
|
フィルタ名・フィルタを
「Text Files(*.txt)」「*.txt」
「All Files(*.*)」「*.*」
と入力します。
フィルタの指定は、ダイアログ画面の「ファイルの種類」の選択欄に反映されます。 | |
|
|
オブジェクトインスペクタ画面で OpenDialog1 オブジェクトの Title プロパティ欄を選択するとダイアログ画面のタイトルバーに表示される文字内容を指定する事が出来ます。何も指定していない場合は「ファイルを開く」と表示されます。 | |
|
|
オブジェクトインスペクタ画面で OpenDialog1 オブジェクトの Options プロパティの左横にある[+]をクリックして下さい。 | |
|
|
Options プロパティでは、表示されるダイアログ画面での様々な表示・動作状態を指定する事が出来ます。
基本的には標準状態のままでも構いませんが、必要な設定はここで必ず行うようにしておきます。 | |
|
|
Options プロパティ内の
「ofPathMustExist」を「True」にします。これは、存在しないパス名を指定する事が出来なくなります。 | |
|
|
Options プロパティ内の
「ofFileMustExist」を「True」にします。これは、存在しないファイル名を指定する事が出来なくなります。
存在しないファイルを「開く」ことは出来ない為です。 | |
次に、SaveDialog コンポーネントについて見ていきます。OpenDialog コンポーネントと良く似ているのが分かります。
オブジェクトインスペクタ画面でSaveDialog1 オブジェクトの DefaultExt プロパティ欄を選択し、「txt」と入力します。
OpenDialog1 オブジェクトと同じ意味です。
Filter プロパティ欄を選択すると右横に[…]ボタンが表示されますのでこのボタンをクリックします。 | |
|
|
「フィルタの設定」画面が表示されます。初期状態は何も表示されていません。 | |
|
|
フィルタ名・フィルタを
「Text Files(*.txt)」「*.txt」
「All Files(*.*)」「*.*」
と入力します。
フィルタの指定は、ダイアログ画面の「ファイルの種類」の選択欄に反映されます。 | |
|
|
面倒であれば、OpenDialog1 オブジェクトの Filter プロパティ内容をコピー&ペーストする事も可能です。文字列として「Text File(*.txt)|*.txt|All Files(*.*)|*.*」と表現されています。 |
|
|
|
オブジェクトインスペクタ画面で SaveDialog1 オブジェクトの Title プロパティ欄を選択するとダイアログ画面のタイトルバーに表示される文字内容を指定する事が出来ます。何も指定していない場合は「ファイル名を付けて保存」と表示されます。 | |
|
|
オブジェクトインスペクタ画面で SaveDialog1 オブジェクトの Options プロパティの左横にある[+]をクリックして下さい。 | |
|
|
Options プロパティでは、表示されるダイアログ画面での様々な表示・動作状態を指定する事が出来ます。
基本的には標準状態のままでも構いませんが、必要な設定はここで必ず行うようにしておきます。 | |
|
|
Options プロパティ内の
「ofOverwritePrompt」を「True」にします。これは、既に存在するファイルを指定した場合、上書き保存をしても良いかどうかを尋ねる画面を表示させる事が出来るようになります。
※プログラム上で MessageDlg等を使って問い合わせをするのであれば「False」のままにします。 | |
メニュー「ファイル」→「すべて保存」をクリックしてプログラムの保存を行い、メニュー「プロジェクト」→「MemoCyo を再構築」をクリックしてプログラムのコンパイル(再構築)を行い、正常終了したら、メニュー「実行」→「実行」をクリックして下さい。
「ファイル」メニュー内の「開く」を行って下さい。 | |
|
|
以前、試しに作成したテキストファイル「test.txt」を開いてみます。 | |
|
|
ファイル「test.txt」を開きました。 | |
|
|
仮に、存在しないファイル名「1234556」と入力したとします。
(拡張子を指定していないので自動的に「1234556.txt」と解釈されます) | |
|
|
指定したファイルが存在しない場合には、「ファイルが見つかりません」というエラーメッセージ画面が表示されます。 | |
|
|
「ファイル」メニュー内の「名前を付けて保存」を行って下さい。 | |
|
|
ファイル名に「abcde」と入力して[保存]ボタンをクリックして下さい。
拡張子を省略した場合は自動的に「abcde.txt」と解釈されます。 | |
|
|
テキストファイルが保存されます。
再度、「ファイル」メニュー内の「名前を付けて保存」を行って下さい。 | |
|
|
先ほど保存を行った「abcde.txt」を指定してみて下さい。 | |
|
|
「〜\abcde.txtは既に存在します。上書きしますか?」という確認メッセージ画面が表示されます。 | |
◆例外処理
ファイルの読み書きを行う際には、必ず、例外処理を行うようにします。ディスクを途中で抜いたり、ファイルが壊れていたり、ディスクが壊れていたり、保存時にはプロテクトが掛かっていたり、ディスク空き容量が足らなくなったり、という場合に、例外(エラー)が発生します。
コードエディタ画面をスクロール表示させて「開く」「名前を付けて保存」のイベントハンドラの箇所へ移動して下さい。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
Memo1.Lines.LoadFromFile(fname);
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
Memo1.Lines.SaveToFile(fname);
end;
end; |
これを下記のように記述します。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
try
Memo1.Lines.LoadFromFile(fname);
except
;
end;
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
try
Memo1.Lines.SaveToFile(fname);
except
if (FileExists(fname)) then
DeleteFile(fname);
end;
end;
end; |
「開く」に失敗した場合は特別何もしていませんが、内容をクリアしたい場合には、「except」の次行で「Memo1.Lines.Clear ;」のように記述します。
「保存」に失敗した場合、途中で内容が欠落したファイルが作成されている場合があります。そういった中途半端なファイルにはほとんど意味がありませんので削除しておきます。FileExists 関数は、指定したファイルが存在する場合には True を、存在しない場合には False を返します。もし存在する場合には、DeleteFile 関数で指定したファイルを削除します。
◆タイトルバー
ファイルを開いたり保存したりするソフトウェアでは、よく、タイトルバーにそのファイル名を表示させる場合があります。タイトルバーは、Form1 の Caption プロパティに表示させたい内容を入れます。
まずは最初の起動時です。
// 起動時
procedure TForm1.FormShow(Sender: TObject);
begin
fname := '' ;
end; |
これを下記のように記述します。
// 起動時
procedure TForm1.FormShow(Sender: TObject);
begin
fname := '' ;
Form1.Caption := 'めも帳';
end; |
Form1内で記述しているのですから、「Form1.」を省いて「Caption := 'めも帳';」でも構わないのですが、それだと逆に分かりにくくなる場合もありますので敢えて「Form1.」を付けています。
次に、「新規作成」を行った時です。
// メニュー
// →ファイル→新規作成
procedure TForm1.mnuFileNewClick(Sender: TObject);
begin
if MessageDlg('新規作成します。', mtConfirmation,
[mbYes, mbNo], 0) = mrYes then begin
Memo1.Lines.Clear ;
fname := '' ;
end;
end; |
これを下記のように記述します。
// メニュー
// →ファイル→新規作成
procedure TForm1.mnuFileNewClick(Sender: TObject);
begin
if MessageDlg('新規作成します。', mtConfirmation,
[mbYes, mbNo], 0) = mrYes then begin
Memo1.Lines.Clear ;
fname := '' ;
Form1.Caption := 'めも帳';
end;
end; |
次に、「開く」「名前を付けて保存」を行った時です。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
try
Memo1.Lines.LoadFromFile(fname);
except
;
end;
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
try
Memo1.Lines.SaveToFile(fname);
except
if (FileExists(fname)) then
DeleteFile(fname);
end;
end;
end; |
これを下記のように記述します。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
try
Memo1.Lines.LoadFromFile(fname);
Form1.Caption := 'めも帳−' + fname ;
except
;
end;
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
try
Memo1.Lines.SaveToFile(fname);
Form1.Caption := 'めも帳−' + fname ;
except
if (FileExists(fname)) then
DeleteFile(fname);
end;
end;
end; |
メニュー「ファイル」→「すべて保存」をクリックしてプログラムの保存を行い、メニュー「プロジェクト」→「MemoCyo を再構築」をクリックしてプログラムのコンパイル(再構築)を行い、正常終了したら、メニュー「実行」→「実行」をクリックして下さい。 | |
|
|
「ファイル」→「開く」にて、以前作成したテスト用テキストファイル「test.txt」を開きました。
タイトルバーにファイル名がフルパスで表示されているのが分かります。 | |
フルパス・ファイル名で表示すると長くなってしまって分かりにくい、という場合には、ExtractFileName 関数を利用して、パス(ディスクドライブ、フォルダ)の部分を除去してファイル名だけにして表示させるようにします。
※変数 fname にパスを除去した内容を入れてしまうと、開く/保存時のファイルの場所が分からなくなってしまいますので、変数に代入しないよう御注意下さい。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
try
Memo1.Lines.LoadFromFile(fname);
Form1.Caption := 'めも帳−' + fname ;
except
;
end;
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
try
Memo1.Lines.SaveToFile(fname);
Form1.Caption := 'めも帳−' + fname ;
except
if (FileExists(fname)) then
DeleteFile(fname);
end;
end;
end; |
これを下記のように記述します。
// メニュー
// →ファイル→開く
procedure TForm1.mnuFileOpenClick(Sender: TObject);
begin
OpenDialog1.FileName := fname ;
if (OpenDialog1.Execute) then begin
fname := OpenDialog1.FileName ;
try
Memo1.Lines.LoadFromFile(fname);
Form1.Caption := 'めも帳−' + ExtractFileName(fname) ;
except
;
end;
end;
end;
// メニュー
// →ファイル→名前を付けて保存
procedure TForm1.mnuFileSaveAsClick(Sender: TObject);
begin
SaveDialog1.FileName := fname ;
if (SaveDialog1.Execute) then begin
fname := SaveDialog1.FileName ;
try
Memo1.Lines.SaveToFile(fname);
Form1.Caption := 'めも帳−' + ExtractFileName(fname) ;
except
if (FileExists(fname)) then
DeleteFile(fname);
end;
end;
end; |
メニュー「ファイル」→「すべて保存」をクリックしてプログラムの保存を行い、メニュー「プロジェクト」→「MemoCyo を再構築」をクリックしてプログラムのコンパイル(再構築)を行い、正常終了したら、メニュー「実行」→「実行」をクリックして下さい。 | |
|
|
「ファイル」→「開く」にて、以前作成したテスト用テキストファイル「test.txt」を開きました。
タイトルバーにファイル名がパス無しで表示されているのが分かります。 | |
|
|
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 16
17 18 19 20
シェアウェア
Script!World
データベース
|