0
votes

I want to use a variable from my main form in another form, each form has its own unit.

I want to use iUser from Login_u in Result_u

I found an article where they said i should put the variable in public declaration and under implementation 'uses and then the unit that wants to access the variable'. Also in the unit that wants to access that variable under implementation uses and then the unit name from where it wants to get the variable

unit Login_u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, jpeg, ExtCtrls, StdCtrls;

type
TfrmLogin = class(TForm)
 btnLogin: TButton;
 cbxUser: TComboBox;
 procedure btnLoginClick(Sender: TObject);
private
 { Private declarations }
public
  iUser:Integer;
 { Public declarations }
end;

var
 frmLogin: TfrmLogin;
implementation
 uses Result_u;
{$R *.dfm}

procedure TfrmLogin.btnLoginClick(Sender: TObject);
 begin
   iUser:= cbxUser.ItemIndex;
   end;
end;
end. 

In my result unit i get the error undeclared identififier, I used the activate procedure and a show message just as a test

unit Result_u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, jpeg, ExtCtrls;

type
  TfrmResult = class(TForm)
  procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmResult: TfrmUitslae;

implementation
uses Login_u;
{$R *.dfm}

procedure TfrmUitslae.FormActivate(Sender: TObject);
begin
  ShowMessage(iUser);
end;

end.

I have read a few articles about this but I keep getting lost, I'm a highschool student so it doesnt need to be complex code.

2
Somewhere you need to create an instance of TFrmLogin. Then you can get the iUser through that instance: frmLoginInstance.iUser. Usually you should not use the global frmLogin variable (remove it) and declare it locally where you need it. Perhaps inside your TFrmResult declaration. And also remove the uses Result_u from Login_u. - LU RD
" they said i should put the variable in public declaration" - That's ok. - "and under implementation 'uses and then the unit that wants to access the variable'" - That's unnecessary, remove uses Result_u; from 'Login_u'. - "Also in the unit that wants to access that variable under implementation uses and then the unit name" - That's ok. --- What you're missing is to qualify the field -> ShowMessage(frmLogin.iUser); (of course it will fail since iUser is an integer). - Sertac Akyuz

2 Answers

2
votes

Usually you should not use global variables. The IDE adds global form variables when you create the forms and automatically creates them at startup.

Try to get in the habit to delete these variables and avoid creating them at startup. Normally only the main menu is sufficient at startup.

A login form should be a modal dialog. Assign the btnLogin button a ModalResult value of mrOk. This means that the login form will be closed with this result when the button is pressed. Note that the uses Result_u; declaration in unit TfrmLogin must be removed.

Here is a demonstration how to create the login form and how to obtain the iUser value through an instance of TFrmLogin:

unit Result_u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, jpeg, ExtCtrls;

type
  TfrmResult = class(TForm)
  procedure TestLogin;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

uses Login_u;

{$R *.dfm}

procedure TfrmResult.TestLogin;
var
  frmLogin: TFrmLogin;
begin
  frmLogin := TFrmLogin.Create(Nil);
  try
    if frmLogin.ShowModal = mrOk then
      ShowMessage('User login index is:'+IntToStr(frmLogin.iUser));
  finally
    frmLogin.Free;
  end;
end;

end.
0
votes

The easiest way to use that variable as you intend it is to just move its declaration out of the form class, so it will be global, always available (without needing to create and address an instance of the form).

unit Login_u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, jpeg, ExtCtrls, StdCtrls;

type
TfrmLogin = class(TForm)
 btnLogin: TButton;
 cbxUser: TComboBox;
 procedure btnLoginClick(Sender: TObject);
private
 { Private declarations }
public
 { Public declarations }
end;

var
 frmLogin: TfrmLogin;
 iUser:Integer;

implementation
 uses Result_u;
{$R *.dfm}

procedure TfrmLogin.btnLoginClick(Sender: TObject);
 begin
   iUser:= cbxUser.ItemIndex;
   end;
end;
end. 

Now you can use it inside Result_u as you have already tried.

Note: You declare a variable within the public section of a form class (as you did in your code) when that variable needs to hold different values at every instance of the form.