adrian07
adrian07

Reputation: 31

Error: "Undeclared identifier" using a form from another Unit - Delphi 2010

I'm trying to use a Form from another Unit, but the code isn't recognizing the other Unit.

Example:

     unit uImpressao;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics,
      Controls, Forms, Dialogs, uniGUITypes, uniGUIAbstractClasses,
      uniGUIClasses, uniGUIForm, uniGUIBaseClasses, uniPanel, uniURLFrame;

    type
      TfImpressao = class(TUniForm)
        ufRelatorio: TUniURLFrame;
        UniImage1: TUniImage;
        procedure UniImage1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    implementation

    {$R *.dfm}

    uses
      MainModule, Main, uBancoHoras;

procedure TfImpressao.UniImage1Click(Sender: TObject);
begin
  fBh.iTeste.Visible := false;
end;

end.

    unit uBancoHoras;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, uniGUITypes, uniGUIAbstractClasses,
  uniGUIClasses, uniGUIForm, uniLabel, pngimage, uniImage, uniGUIBaseClasses,
  uniPanel, uniPageControl, uniButton, uniBitBtn, uniSpeedButton, uniCanvas,
  uniDateTimePicker, uniMemo, uniMultiItem, uniComboBox, uniEdit, uniBasicGrid,
  uniDBGrid, uniDBMemo, uniRadioButton, uniDBText, uniRadioGroup, frxClass,
  frxDBSet;

type
  TfBH = class(TUniForm)
    iTeste : TUniImage;
  private
    { Private declarations }
  public
    { Public declarations }

  end;

var
  url: string;

function fBH: TfBH;

implementation

{$R *.dfm}

uses
  MainModule, Main, uImpressao;

function fBH: TfBH;
begin
  Result := TfBH(MM.GetFormInstance(TfBH));
end;

procedure TfBH.iTesteClick(Sender: TObject);
begin
    fImpressao.ShowModal;
end;

When I try using the uImpressao unit in uBancohoras unit, returns the error "Undeclared identifier 'fImpressao'". Using uBancoHoras unit in the uImpressao unit, works fine.

I don't understand why this error is happening with one unit, but not with the other.

I hope you can help me!

Upvotes: 2

Views: 2403

Answers (2)

Ken White
Ken White

Reputation: 125757

Note: Please note that this answer was based on the original code posted in the question, which was subsequently replaced in its entirety with new and vastly different code.

fBH is not declared in unit A,so fBH.iTeste.Visible := True; can't possibly work; there is no such variable. You deleted the global variable fBH that the IDE creates for you (although, interestingly you left the var statement above it right above the implementation keyword).

Either add back in the declaration (by adding var fBH: TfBH; between the end of the class declaration and the implementation keyword), or create an instance of the form in unit B when you need to use it and access it through the local variable from there.

(Whichever direction you go, you never address a form using the variable from within that form's methods; use Self instead. Don't use fBH.ShowModal; use either Self.ShowModal or ShowModal instead.)

Upvotes: 2

J...
J...

Reputation: 31463

In uBancoHoras you have defined

function fBH: TfBH;

...
implementation
...

function fBH: TfBH;
begin
  Result := TfBH(MM.GetFormInstance(TfBH));
end;

So you have defined a global function called fBH that returns an instance of the TfBH form class, seemingly through some sort of factory method (probably defined in MainModule?).

There is no corresponding method or variable in uImpressao with the name fImpressao, however - the the compiler error that fImpressao is an undeclared identifier.

Assuming that MM.GetFormInstance is suited to the task, and also assuming you wish to keep this design pattern, you would have to define (in uImpressao)something like :

function fImpressao: TfImpressao;

...
implementation
...

function fImpressao : TfImpressao;
begin
  Result := TfImpressao(MM.GetFormInstance(TfImpressao));
end;

We can't see the implementation details of MM.GetFormInstance, however, so there is no guarantee that this will work - it only follows the pattern that fBH has set. Agreed with Ken that you should perhaps consider a better way to manage your forms. Resorting to global variables or global methods that reach across units to dig up a class instance feels like a headache waiting to happen...

Upvotes: 1

Related Questions