2

我想我一定很密集,我是 Delphi 的新手,正在尝试将 sql 结果读入一个类以轻松访问它。我创建了一个虚拟类来进行这样的测试:

type
test_class = class
 id:integer;
 job_number:string;
 cust_name :string ;
 procedure get_record_data;
end;

然后我这样调用程序:

procedure test_class.get_record_data;
begin
 test_class.Create;
 test_class.id := tform3.adoQuery1.FieldByName('id').AsInteger;
 test_class.job_number := tform3.adoQuery1.FieldByName('job number').AsString;
 test_class.cust_name := tform3.adoQuery1.FieldByName('customer name').AsString;
end;

然后我像这样测试我的结果:

procedure TForm3.Button1Click(Sender: TObject);
begin
 showmessage('Id number is ' + inttostr(test_class.id));
end;

showmessage 行引发编译器错误,提示 Method Identifier Expected。

以 test_class.id:=、test_class.job_number:= 和 test_class.cust_name:= 开头的行都给了我相同的 Method Identifier Expected 以及缺少运算符或分号错误。

我究竟做错了什么?有没有更简单的方法来解决这个问题?完成此操作后,空值会出现问题吗?

4

3 回答 3

8

您不能将类用作实例。您必须保留对创建实例的引用,根据您的示例,它可能看起来像这样......

type
Ttest_class=class
 id:integer;
 job_number:string;
 cust_name :string ;
 Class Function get_record_data(ADS:TCustomAdodataset):Ttest_class;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  TC:Ttest_class;
begin
   TC := Ttest_class.get_record_data(AdoQuery1);
   try
   showmessage('Id number is ' + inttostr(TC.id));
   finally
     TC.Free
   end;
end;


class function Ttest_class.get_record_data(ADS: TCustomAdodataset): Ttest_class;
begin
 Result := Ttest_class.Create;
 Result.id:=ADS.FieldByName('id').AsInteger;
 Result.job_number:= ADS.FieldByName('job number').AsString;
 Result.cust_name:= ADS.FieldByName('customer name').AsString;
end;

正如@MarjanVenema 所建议并通过评论要求提供一个更可取的版本:

type
  Ttest_class = class
    id: integer;
    job_number: string;
    cust_name: string;
    Constructor Create(ADS: TCustomAdodataset);
  end;

Constructor Ttest_class.Create(ADS: TCustomAdodataset);
begin
  id := ADS.FieldByName('id').AsInteger;
  job_number := ADS.FieldByName('job number').AsString;
  cust_name := ADS.FieldByName('customer name').AsString;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  TC: Ttest_class;
begin
  TC := Ttest_class.Create(ADOQuery1);
  try
    showmessage('Id number is ' + inttostr(TC.id));
  finally
    TC.Free
  end;
end;
于 2013-08-28T23:29:44.530 回答
6

test_class是一个类型而不是一个实例变量。要访问一个类型的对象,test_class您需要声明一个该类型的变量,创建一个实例,然后使用它的字段、方法的属性。最后,您需要释放该对象的内存。

例如(为了不让你感到困惑,我不会使用 a try...finally):

procedure TForm3.Button1Click(Sender: TObject);
var tc: test_class;  //instance variable declaration
begin
  tc := test.class.Create; //creation of the object
  tc.get_record_data; //call a method to fill the class fields
  ShowMessage('Id number is ' + inttostr(tc.id)); //use of the object
  tc.Free; //freeing the memory object
end;

顺便说一句,按照惯例,Delphi 中的用户定义类型以T不带下划线的驼峰式大小写开头和后面,如TTestClass代替test_class.

我猜你不知道类、对象和实例变量的概念。谷歌他们的定义,有很多关于它的信息,例如本教程


如果你get_record_data method想填充它们所属实例的变量,事情会像这样:

procedure test_class.get_record_data ;
begin
  id         := tform3.adoQuery1.FieldByName('id').AsInteger;
  job_number := tform3.adoQuery1.FieldByName('job number').AsString;
  cust_name  := tform3.adoQuery1.FieldByName('customer name').AsString;
end;
于 2013-08-28T23:22:26.137 回答
1

Test_Class需要知道它是从什么填充数据的。您试图引用Form3.ADOQuery1,但 TForm3 几乎肯定是类,而不是对象。

如果您使用的是 Delphi 自动生成的代码,那么应该有一行说类似

var Form3: TForm3

在您单位的顶部。如果是这种情况,那么您可以通过在该过程中将所有 TForm3 替换为 Form3 来更正您的代码。

更好的解决方案是为您的get_record_data过程提供要填写的查询:

procedure test_class.get_record_data (const aQuery: TADOQuery);
begin
  id         := aQuery.FieldByName('id').AsInteger;
  job_number := aQuery.FieldByName('job number').AsString;
  cust_name  := aQuery.FieldByName('customer name').AsString;
end;

对于这么小的对象,更好的是直接传入 3 个变量:

procedure test_class.set_object_data(const aID: integer; const aJob_Number, aCust_Name: string

于 2013-08-29T14:28:49.580 回答