2
votes

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!

2
The code you've posted would also generate E2029 Identifier expected but 'IMPLEMENTATION' found since you've defined a global var section in the interface with no defined variables. This would be the case for both unit A and unit B - that you claim unit B works means that you have posted code that is different from what you are actually compiling and using. Asking us to help debug code that you have deliberately modified from the actual code you are testing can make debugging very difficult and confusing for everyone. You should always try to post the exact code you are using. - J...
Got it, J. Should I edit my question, then, with the codes? I tried to reduce the entire code, but actually I drop some important parts. I'll post the entirely part of that section of the code then, right? Thanks for the comment. - adrian07
No, in fact I think the approach of trying to make a minimal example is the best idea - this reduces the problem to the smallest amount of code needed to demonstrate the problem and makes things easier for everyone. If you are making a minimal example, however, you should always make sure that you test it first to be sure that you have included the correct, minimal amount of code needed to demonstrate your problem. The other benefit of doing this is that you will often solve your own problem during this process! stackoverflow.com/help/mcve - J...
Okay than, I'm testing it. Thanks again. - adrian07
Post the smallest code you can make that illustrates the issue. Posting fake code doesn't help anyone. That still seems to be an issue since FB appears nowhere in the code. - David Heffernan

2 Answers

1
votes

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...

2
votes

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.)