Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 为什么不';我不能从表单中获取返回值吗_String_Delphi_Parameters - Fatal编程技术网

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;