String 为什么不';我不能从表单中获取返回值吗
用这个代码我称之为表单String 为什么不';我不能从表单中获取返回值吗,string,delphi,parameters,String,Delphi,Parameters,用这个代码我称之为表单 procedure TfrmMain.actDevTest_2Execute(Sender: TObject); var SelectedApp: string; begin if ApplicationSelect(Self, SelectedApp) then ShowMessage(SelectedApp); end; 表单如下所示 unit F_JsApplicationSelect; interface uses {$Include Uni
procedure TfrmMain.actDevTest_2Execute(Sender: TObject);
var
SelectedApp: string;
begin
if ApplicationSelect(Self, SelectedApp) then
ShowMessage(SelectedApp);
end;
表单如下所示
unit F_JsApplicationSelect;
interface
uses
{$Include UniDACCommon.inc}
Db, MemDS, DbAccess, Uni,
Classes, Controls, Forms,
U_Forms.Move,
Winapi.Messages, U_CustomMessages,
Dialogs, StdCtrls, Buttons, ComCtrls,
cxGroupBox, cxGraphics, cxControls, cxLookAndFeels,
cxLookAndFeelPainters, cxStyles, dxSkinsCore, dxSkinOffice2010Blue,
dxSkinscxPCPainter, cxCustomData, cxFilter, cxData, cxDataStorage, cxEdit,
cxNavigator, cxDBData, cxCheckBox, cxTextEdit, cxContainer, Vcl.Menus,
cxButtons, cxGridLevel, cxGridCustomTableView, cxGridTableView,
cxGridDBTableView, cxClasses, cxGridCustomView, cxGrid,
dxmdaset;
type
TfrmJsApplicationSelect = class(TForm)
grdApplicationsView1: TcxGridDBTableView;
grdApplicationsLevel1: TcxGridLevel;
grdApplications: TcxGrid;
colContact: TcxGridDBColumn;
colSection: TcxGridDBColumn;
colSelected: TcxGridDBColumn;
cxGroupBox1: TcxGroupBox;
btnOK: TcxButton;
srcApplications: TUniDataSource;
mdApplications: TdxMemData;
mdApplicationsfldselected: TBooleanField;
mdApplicationsfldcontact: TStringField;
mdApplicationsfldsection: TStringField;
mdApplicationsfldposition: TStringField;
mdApplicationsflddate: TDateField;
mdApplicationsfldguid: TStringField;
colPosition: TcxGridDBColumn;
colDdate: TcxGridDBColumn;
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure grdApplicationsView1CellDblClick(Sender: TcxCustomGridTableView;
ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
AShift: TShiftState; var AHandled: Boolean);
private
procedure SetupApplications;
procedure MessageClose(var aMessage: TMessage); message WM_FORMCLOSE;
public
constructor Create(aOwner: TComponent; var aApplication: string); reintroduce;
end;
function ApplicationSelect(aOwner: TComponent; var aApplication: string): boolean;
implementation
{$R *.dfm}
uses
System.SysUtils, Winapi.Windows,
F_UniConn,
U_Logfile,
U_AppDb, U_User;
var
lApplication : string;
function ApplicationSelect(aOwner: TComponent; var aApplication: string): boolean;
begin
with TfrmJsApplicationSelect.Create(aOwner, aApplication) do
try
Result := ShowModal = mrOK;
finally
Release;
end;
end;
procedure TfrmJsApplicationSelect.MessageClose(var aMessage: TMessage);
begin
Close;
end;
procedure TfrmJsApplicationSelect.SetupApplications;
var
Query: TUniQuery;
begin
Query := frmUniConn.CreateQuery;
try
Query.SQL.Clear;
Query.SQL.Add('SELECT fldapplication_guid');
Query.SQL.Add(' ,fldapplication_date');
Query.SQL.Add(' ,fldcontact_name');
Query.SQL.Add(' ,fldsection_desc');
Query.SQL.Add(' ,fldposition_desc');
Query.SQL.Add(' ,fldcreated_by');
Query.SQL.Add(' FROM ' + QueryJsApplications);
Query.SQL.Add(' WHERE (fldcreated_by = :fldcreated_by)');
Query.SQL.Add(' ORDER BY fldapplication_date DESC');
Query.ParamByName('fldcreated_by').AsString := User.ID;
try
Query.Execute;
if Query.RecordCount > 0 then
begin
while not Query.Eof do
begin
mdApplications.Open;
mdApplications.Append;
mdApplications.FieldByName('fldselected').AsBoolean := False;
mdApplications.FieldByName('fldguid').AsString := Query.FieldByName('fldapplication_guid').AsString;
mdApplications.FieldByName('flddate').AsDateTime := Query.FieldByName('fldapplication_date').AsDateTime;
mdApplications.FieldByName('fldcontact').AsString := Query.FieldByName('fldcontact_name').AsString;
mdApplications.FieldByName('fldsection').AsString := Query.FieldByName('fldsection_desc').AsString;
mdApplications.FieldByName('fldposition').AsString := Query.FieldByName('fldposition_desc').AsString;
mdApplications.FieldByName('fldguid').AsString := Query.FieldByName('fldapplication_guid').AsString;
mdApplications.Post;
Query.Next;
end;
mdApplications.First;
end;
except
on E:exception do
Logfile.Error('F_JsApplicationSelect.SetupApplications: ' + E.Message);
end;
finally
Query.Free;
end;
end;
constructor TfrmJsApplicationSelect.Create(aOwner: TComponent; var aApplication: string);
begin
inherited Create(aOwner);
lApplication := aApplication;
end;
procedure TfrmJsApplicationSelect.FormClose(Sender: TObject; var Action: TCloseAction);
begin
try
mdApplications.First;
while not mdApplications.Eof do
begin
if mdApplications.FieldByName('fldselected').AsBoolean = True then
begin
ShowMessage(mdApplications.FieldByName('fldguid').AsString);
lApplication := mdApplications.FieldByName('fldguid').AsString;
ShowMessage(lApplication);
end;
mdApplications.Next;
end;
except
on E: exception do
Logfile.Error('F_JsApplicationSelect.FormClose: ' + E.Message);
end;
end;
procedure TfrmJsApplicationSelect.FormKeyPress(Sender: TObject; var Key: Char);
begin
If Ord(Key) = 27 Then
ModalResult := mrAbort;
end;
procedure TfrmJsApplicationSelect.FormShow(Sender: TObject);
begin
SetupApplications;
ActiveControl := grdApplications;
if grdApplicationsView1.DataController.RecordCount > 0 then
begin
grdApplicationsView1.Controller.GoToFirst(False);
grdApplicationsView1.Controller.FocusedRecord.MakeVisible;
end;
end;
procedure TfrmJsApplicationSelect.grdApplicationsView1CellDblClick(
Sender: TcxCustomGridTableView; ACellViewInfo: TcxGridTableDataCellViewInfo;
AButton: TMouseButton; AShift: TShiftState; var AHandled: Boolean);
begin
try
mdApplications.Edit;
mdApplications.FieldByName('fldselected').AsBoolean := Not mdApplications.FieldByName('fldselected').AsBoolean;
mdApplications.UpdateRecord;
except
on E: exception do
Logfile.Error('F_JsApplicationSelect.grdApplicationsView1CellDblClick: ' + E.Message);
end;
end;
end.
但是为什么我在SelectedApp变量中得不到任何值呢?
我有另一个具有相同函数的表单,只是我发送给它的变量是一个TStringList,它工作正常。但是字符串根本不起作用。理解这一点所需的代码是:
function ApplicationSelect(aOwner: TComponent;
var aApplication: string): boolean;
begin
with TfrmJsApplicationSelect.Create(aOwner, aApplication) do
try
Result := ShowModal = mrOK;
finally
Release;
end;
end;
这反过来又叫
constructor TfrmJsApplicationSelect.Create(aOwner: TComponent;
var aApplication: string);
begin
inherited Create(aOwner);
lApplication := aApplication;
end;
因此,您会问,当对ApplicationSelect
的调用返回时,为什么ApplicationSelect
的调用方没有观察到对aaapplication
的任何修改
您不需要在ApplicationSelect
中修改var
参数aaapplication
。确实可以将其作为var参数传递给TfrmJsApplicationSelect.Create
,但同样TfrmJsApplicationSelect.Create
不会修改它。由于字符串
变量是一个值,因此调用者看不到对该变量的修改,因为它没有被修改
我对ApplicationSelect
的另一个评论是,您应该调用Free
,而不是Release
除此之外,我可以对您的代码发表更多的评论,但我将避免尝试全面的代码审查,而仅对您提出的直接问题发表评论
在评论中,您会问为什么将
aaapplication
更改为TStringList
会允许调用者观察修改。这是因为Delphi类变量是对对象的引用。当您将TStringList
变量作为参数传递时,您传递的是对对象的引用。当您在该对象上调用方法时,任何变化都会在实际对象上执行
那么,我将如何更改此代码以允许返回字符串值呢?首先,我将使
ApplicationSelect
成为一个返回字符串的函数。如果取消,我将中止
function SelectApplication(aOwner: TComponent): string;
var
Form: TfrmJsApplicationSelect;
begin
Form := TfrmJsApplicationSelect.Create(aOwner);
try
if Form.ShowModal <> mrOK then
Abort;
Result := Form.Application;
finally
Free;
end;
end;
并将其公开为公共财产:
property Application: string read FApplication;
然后表单只需要设置faapplication
,调用者就可以看到该值。因为您没有将任何内容返回到aaapplication
参数;以TfrmJsAttachmentsSelect.Create(aOwner、acoption、aaapplication、aList)开始执行尝试结果:=showmodel=mrOK;最终释放;终止终止与附件一起调用选择(Self,'Vælg bilag der skal vedhæftes mail',GuidZero,列表附件);调用后,我在ListAttachments中有一些内容。我的主要问题是,当我使用TStringList调用的表单以完全相同的方式调用时,为什么不能使用字符串作为参数。请分享您的评论-我不是Delphi专家,我想了解这一点,因为字符串列表是一个类,也是一个引用类型。字符串具有值语义。给我几分钟的时间来展开编辑。好的,我想我现在明白了。在调用Free之前,我会将函数ApplicationSelect更改为将cahnges设置为aaapplication。那应该够了,我think@OZ8HP我已经给了你一个如何解决这个问题的指南
property Application: string read FApplication;