自作のバイナリデータにTTableにあるFieldByNameの
ようなクラスとメソッドを自作しアクセスしたいのですが、
作り方がよくわかりません。
TMyTbl = class
private
var
fName : array[0..255] of string;//'CUSTID','CUSTNAME','CUSTTEL'等が入る
dataS : array[0.255,0..999] of string;//fName毎のデータ。0-999の最大1000行
FDatabaseName : string;
FTableName : string;
protected
public
property DatabaseName : string Read FDatabaseName Write FDatabaseName;
property TableName : string Read FTableName Write FTableName;
function Open;
function Close;
function FieldByName(fieldName:string):???;
end;
DatabaseName,tableNameにそれぞれバイナリデータベースのパス、名前設定後
Openで、配列fName,dataSに読み込み、FiledByNameで、引数のfieldNameで
渡した項目名で変数:fNameを調べ、該当するdataSのデータを返してたいのですが。
TTableではAsStringで値を取得(設定)できますが、これはどのようにコーディング
すればよいのですか?
var
myTbl:TMyTbl;
begin
myTbl:=TMyTbl.Create;
Memo1.Lines.Add(myTbl.FieldByName('CUSTNAME').AsString);
Memo1.Lines.Add(myTbl.FieldByName('CUSTNAME').AsString);
myTbl.Close;
お願い致します。
VCLのソースを見た方がイイと思うけど。
TBinaryField.GetAsString
TBinaryField.SetAsString
Memo1.Lines.Add(MyTabel.FieldByName('CUSTOM'));
のように単純に関数で返すのならば
Fname を StringList にして
function First;
begin
Index := 0;
end;
function Next;
begin
Inc(Index);
end;
function FieldByName(FieldName:String):String;
begin
FieldIndex := StringList.IndexOf(FieldName);
if FiledIndex <> -1 then
begin
Result := DataS[FiledIndex,Index];
end
else
begin
//Fieldが存在しない
end;
end;
.AsString で返すのならば TMyField だけでは無理です
TBinaryFieldみたいのを作成して下さい
それはさん、KHE00221さん、早速ありがとうございます。
TBinaryFieldみたいにしようとVCLソースを見ましたが
よく分かりませんでした。
function FieldByNameAsString(FieldName:String):String;
function FieldByNameAsInteger(FieldName:String):Integer;
のように、.As〜のやめて、関数名にいれます。
あきらめちゃいましたか・・・
FieldByName は オブジェクト FieldByName2 はレコードを使用した場合です
unit MyTable;
interface
uses
SysUtils, Classes;
type
TMyField = class(TComponent)
private
FAsString : String;
published
property asString :String read fAsString;
end;
TMyField2 = record
asString : String;
end;
TMyTable = class(TComponent)
private
FMyField : TMyField;
FMyField2 : TMyField2;
FIndex : Integer;
FName : array[0..255] of string;
FData : array[0..255,0..999] of string;
protected
procedure SetNames(Index:Integer;Value:String);
function GetNames(Index:Integer):String;
procedure SetDatas(Index1,Index2:Integer;Value:String);
function GetDatas(Index1,Index2:Integer):String;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function FieldByName(AName:String):TMyField;
function FieldByName2(AName:String):TMyField2;
property Names [Index:Integer] : String read GetNames write SetNames;
property Datas [Index1,Index2:Integer] : String read GetDatas write SetDatas;
procedure First;
procedure Next;
published
property Index : Integer read FIndex write FIndex;
end;
procedure Register;
implementation
procedure TMyTable.SetNames(Index: Integer; Value: string);
begin
FName[Index] := Value;
end;
function TMyTable.GetNames(Index: Integer):String;
begin
Result := FName[Index];
end;
procedure TMyTable.SetDatas(Index1,Index2: Integer; Value: string);
begin
FData[Index1,Index2] := Value;
end;
function TMyTable.GetDatas(Index1,Index2: Integer):String;
begin
Result := FData[Index1,Index2];
end;
procedure TMyTable.First;
begin
FIndex := 0;
end;
procedure TMyTable.Next;
begin
Inc(FIndex);
end;
function TMyTable.FieldByName(AName:String):TMyField;
var
I,J : Integer;
begin
//ANameに一致するFNameを探す
J := -1;
for I:=0 to High(FName) -1 do
begin
if FName[I] = AName then J := I;
end;
if J <> -1 then
begin
//見付かったら
FMyField.FAsString := Datas[J,Index];
end
else
begin
//見付からなければ
FMyField.FAsString := '';
end;
Result := FMyField;
end;
function TMyTable.FieldByName2(AName:String):TMyField2;
var
I,J : Integer;
begin
//ANameに一致するFNameを探す
J := -1;
for I:=0 to High(FName) -1 do
begin
if FName[I] = AName then J := I;
end;
if J <> -1 then
begin
//見付かったら
FMyField2.AsString := Datas[J,Index];
end
else
begin
//見付からなければ
FMyField2.AsString := '';
end;
Result := FMyField2;
end;
constructor TMyTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FMyField := TMyField.Create(Self);
end;
destructor TMyTable.Destroy;
begin
FMyField.Free;
inherited Destroy;
end;
procedure Register;
begin
RegisterComponents('KHE00221', [TMyTable]);
end;
end.
-------------------------------------------------------------------
MyTable を使用した例
------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
I,J : Integer;
begin
//データ初期化
for I:=0 to 10 do
begin
for J:=0 to 99 do
begin
MyTable1.Names[I] := 'Name'+IntToStr(I);
MyTable1.Datas[I,J] := 'Data'+IntToStr(I)+'/'+IntToStr(J);
end;
end;
//表示
Memo1.Lines.Add(MyTable1.FieldByName('Name1').asString);
Memo1.Lines.Add(MyTable1.FieldByName('Name20').asString);
MyTable1.Next;
Memo1.Lines.Add(MyTable1.FieldByName2('Name2').asString);
Memo1.Lines.Add(MyTable1.FieldByName2('Name30').asString);
end;
KHE00221さん、
大変貴重なソースをありがとうございます。
あきらめて、お恥ずかしい次第です。
これで、自作DBアクセスクラス作成してみます。
VCLも理解できるようになるかもわかりません。
大変ありがとうございました。
何度もすみません。
FieldByName内で、read時(現状)は、
FMyField.FAsString := Datas[J,Index];
でよいのですが、write時は逆に、
Datas[J,Index]:=FMyField.FAsString;
と思うのです、readなのか、writeなのか
FieldByName内でどのように判断すればよいのでしょうか?
書き込みは一切考慮してませんでしたので書き込みできるように修正しました
unit MyTable;
interface
uses
SysUtils, Classes;
type
TMyTable = class;
TMyField = class(TComponent)
private
FMyTable : TMyTable;
FAsString : String;
FIndex : Integer;
protected
procedure SetAsString(Value:String);
public
constructor Create(AOwner:TComponent);
destructor Destroy; override;
published
property asString :String read fAsString write SetAsString;
property Index : Integer read FIndex write FIndex;
end;
TMyTable = class(TComponent)
private
FMyField : TMyField;
FIndex : Integer;
FName : array[0..255] of string;
FData : array[0..255,0..999] of string;
protected
procedure SetNames(Index:Integer;Value:String);
function GetNames(Index:Integer):String;
procedure SetDatas(Index1,Index2:Integer;Value:String);
function GetDatas(Index1,Index2:Integer):String;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function FieldByName(AName:String):TMyField;
property Names [Index:Integer] : String read GetNames write SetNames;
property Datas [Index1,Index2:Integer] : String read GetDatas write SetDatas;
procedure First;
procedure Next;
published
property Index : Integer read FIndex write FIndex;
end;
procedure Register;
implementation
constructor TMyField.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FMyTable := TMyTable(AOwner);
end;
destructor TMyField.Destroy;
begin
inherited Destroy;
end;
procedure TMyField.SetAsString(Value: string);
begin
FMyTable.Datas[FIndex,FMyTable.Index] := Value;
end;
procedure TMyTable.SetNames(Index: Integer; Value: string);
begin
FName[Index] := Value;
end;
function TMyTable.GetNames(Index: Integer):String;
begin
Result := FName[Index];
end;
procedure TMyTable.SetDatas(Index1,Index2: Integer; Value: string);
begin
FData[Index1,Index2] := Value;
end;
function TMyTable.GetDatas(Index1,Index2: Integer):String;
begin
Result := FData[Index1,Index2];
end;
procedure TMyTable.First;
begin
FIndex := 0;
end;
procedure TMyTable.Next;
begin
Inc(FIndex);
end;
function TMyTable.FieldByName(AName:String):TMyField;
var
I,J : Integer;
begin
//ANameに一致するFNameを探す
J := -1;
for I:=0 to High(FName) -1 do
begin
if FName[I] = AName then J := I;
end;
if J <> -1 then
begin
//見付かったら
FMyField.FAsString := Datas[J,Index];
end
else
begin
//見付からなければ
FMyField.FAsString := '';
end;
FMyField.Index := J;
Result := FMyField;
end;
constructor TMyTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FMyField := TMyField.Create(Self);
end;
destructor TMyTable.Destroy;
begin
FMyField.Free;
inherited Destroy;
end;
procedure Register;
begin
RegisterComponents('KHE00221', [TMyTable]);
end;
end.
--------------------
使い方
--------------------
MyTable1.First;
MyTable1.FieldByName('Name1').asString := '1111';
MyTable1.Next;
MyTable1.FieldByName('Name1').asString := '2222';
MyTable1.First;
Memo1.Lines.Add(MyTable1.FieldByName('Name1').asString);
MyTable1.Next;
Memo1.Lines.Add(MyTable1.FieldByName('Name1').asString);
MyTable1.Next;
Memo1.Lines.Add(MyTable1.FieldByName('Name1').asString);
KHE00221さん、早速ありがとうございます。
実行させましたところ、Memo1に値が表示されました。
ありがとうございました。
ソースを見て勉強させていただきます。
(FieldByNameの戻り値のTMyFieldのプロパティasStringのSetAsStringが
FieldByNameの最後で呼び出されるのですね。
FieldByNameの中で判定するものと思い込んでいたので、
想像もつきませんでした。)
ツイート | ![]() |