16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"レコード型を動的配列で管理するクラス"
この発言に対し以下のコメントが寄せられています
#01394 HATENA さん レコード型リスト ユニット(interface)
#01395 HATENA さん レコード型リストユニット(implementation)
【タイトル】固定長レコード型データを動的配列で管理するクラス
【概略】
固定長のレコードを管理するとき、D4以降で導入された動的配列を使うか、TList
を使うか一長一短で迷うところです。TListだと、メソッドで削除、挿入、追加、ソ
ートが簡単にできます。しかし、インスタンスを自前で作成したり、解放したりしな
ければなりません。動的配列だと、インスタンスを管理する必要はありませんが、便
利なメソッドはありません。また、追加を繰り返す場合など、そのたびにメモリの再
割り当てが発生するので遅くなります。
そこで、動的配列をフィールドに持つクラスで、TList & TStrigList とほぼ互換
のメソッドを持たせたクラスを作ってみました。
メモリ管理も、TList のように count, capacity プロパティを持っていて、メモ
リの再割り当ての発生を抑制しています。
また nifty:FDELPHI/MES/16/1383 のTListでの管理と比較して、ファイルへの入出力
が高速です。
デメリットとしては、可変長のレコードには対応していないこと。レコードサイズが
大きい場合は、ソートや挿入などは、TList に比べてオーバーヘッドが大きくなるこ
と。
【サンプルプロジェクト】
簡単なスケジュール管理データを例にしました。
フォームにリストボックスとボタンを4個置きます。
unit Unit1;
interface
uses
Windows, SysUtils, Classes, Controls, Forms,
ExtCtrls, StdCtrls, Unit2;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton; //AddData
Button2: TButton; //Delete
Button3: TButton; //Save
Button4: TButton; //Load
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private 宣言 }
RecList: TRecList;
procedure ShowData;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//比較関数 Date と StartTime で昇順にソート
function MyCompare(Item1, Item2: TMyRec): Integer;
begin
Result := Item1.Date - Item2.Date;
if Result = 0 then
Result := Item1.StartTime - Item2.StartTime;
end;
//リストボックスにデータをセット
procedure TForm1.ShowData;
var
i: Integer;
begin
ListBox1.Items.BeginUpdate;
try
ListBox1.Items.Clear;
for i := 0 to RecList.Count - 1 do
ListBox1.Items.Add(Format('%s %s 〜 %s %s',
[ DateToStr(RecList[i].Date),
TimeToStr(RecList[i].StartTime / CTime),
TimeToStr(RecList[i].EndTime / CTime),
RecList[i].Title ]));
finally
ListBox1.Items.EndUpdate;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RecList := TRecList.Create;
RecList.SortCompare := MyCompare; //比較関数をプロパティにセット
RecList.Sorted := True; //上記の比較関数を基に
//常にソートされた状態にする
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RecList.Free;
end;
//AddData 適当なデータを作成して追加
procedure TForm1.Button1Click(Sender: TObject);
var
MyRec: TmyRec;
i: integer;
begin
Randomize;
for i := 0 to 99 do
begin
MyRec.Date := Trunc(Date) - Random(365);
MyRec.StartTime := CTime - Random(CTime);
MyRec.EndTime := MyRec.StartTime + 30;
MyRec.Title := IntToStr(GetTickCount);
RecList.Add(MyRec);
end;
ShowData;
end;
//Delete リストボックスで選択されているデータを削除
procedure TForm1.Button2Click(Sender: TObject);
begin
if ListBox1.ItemIndex = -1 then Exit;
RecList.Delete(ListBox1.ItemIndex, 1);
ShowData;
end;
//Save
procedure TForm1.Button3Click(Sender: TObject);
begin
RecList.SaveToFile('Test.Dat');
end;
//Load
procedure TForm1.Button4Click(Sender: TObject);
begin
RecList.LoadFromFile('Test.Dat');
ShowData;
end;
end.
01/10/09(火) 10:42 HATENA(GFC03235)
Original document by HATENA 氏 ID:(GFC03235)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|