Learning
Learning

Reputation: 127

Calling a new procedure error Undeclared Identifier

Hello I am writing a new application and have made a little procedure (UpdateTotals). The application compiles and works well until I call this new procedure. Then I get the Undeclared Tdentifier error. I have written procedures and functions before but have never had this error except when I forget to put the form identifier in front of the procedure. My code is

unit ng1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, 

  ...

  DateUtils, StrUtils;

type
  TForm1 = class(TForm)
    InText : TEdit;
    qsum : TQuery;
    
    ...
    
    procedure UpdateTotals;
    procedure InTextKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormActivate(Sender: TObject);
    procedure NewshbtnClick(Sender: TObject);
    procedure qbtnClick(Sender: TObject);
    procedure numedExit(Sender: TObject);
    procedure mc1DropDown(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  pcname : string;
  wsum, hsum, totsum, ssum, stotsum:Real;
  wcnt, hcnt, totcnt, sscnt, stotcnt, pcnum :Integer;
implementation

{$R *.dfm}

procedure TForm1.UpdateTotals;
begin
  qsum.Close;
  qsum.SQL.Text:='select sum(amount) from dest1';
  qsum.Open;
  wsum:=qsum.Fields[0].AsFloat;
  wcnt:=qsum.RecordCount;
  qsum.Close;
  qsum.SQL.Text:='select sum(amount) from desty';
  qsum.Open;
  hsum:=qsum.Fields[0].AsFloat;
  hcnt:=qsum.RecordCount;
  totsum:=wsum+hsum;
  totcnt:=wcnt+hcnt;
   case AnsiIndexStr(pcname, ['SHOP','EILEEN-PC','DAVID'] )   of
      0: pcnum := 1;
      1: pcnum := 2;
      2: pcnum := 3;
   end;
  qsum.Close;
  qum.SQL.Text:='select sum(amount) from session';
  qsum.Open;
  ssum:=qsum.Fields[0].AsFloat;
  sscnt:=qsum.RecordCount;
  stotsum:=stotsum+ssum;
  stotcnt:=stotcnt+sscnt;
  zg1.Cells[1,2]:=IntToStr(wcnt);

...

end;
...

end.

I call the procedure

UpdateTotals;

Can anyone help please?

I am sorry the error code I get is

[Error] ng1.pas(185): Undeclared identifier: 'UpdateTotals'
[Fatal Error] ngift.dpr(5): Could not compile used unit 'ng1.pas'

when I call the procedure from another procedure (below) which is called on form activate

procedure fillhead(zgg:TZColorStringGrid);
var
  Rct: TRect;
  res: integer;
begin
  res := zgg.MergeCells.AddRectXY(1, 0, 3, 0);
  res := zgg.MergeCells.AddRectXY(4, 0, 6, 0);
  res := zgg.MergeCells.AddRectXY(7, 0, 9, 0);
  zgg.Cells[1,0]:='Warminster Road';
  zgg.Cells[4,0]:='High Street';
  zgg.Cells[7,0]:='Totals';
  zgg.Cells[1,1]:='Entries:';
  zgg.Cells[4,1]:='Entries:';
  zgg.Cells[7,1]:='Entries:';
  zgg.Cells[2,1]:='Amount:';
  zgg.Cells[5,1]:='Amount:';
  zgg.Cells[8,1]:='Amount:';
  zgg.Cells[3,1]:='Claim:';
  zgg.Cells[6,1]:='Claim:';
  zgg.Cells[9,1]:='Claim:';
  zgg.Cells[0,2]:='Quarter Totals';
  zgg.Cells[0,3]:='This Session';
  UpdateTotals;// The compile time error occurs here
end;

Upvotes: 1

Views: 607

Answers (1)

Ken White
Ken White

Reputation: 125757

Your fillhead procedure is not a method of an object, while your declaration of UpdateTotals is a member of TForm1. You're calling UpdateTotals inside fillhead, which means you need to preface it with the name of the class instance (Form1) which contains UpdateTotals.

procedure fillhead(zgg:TZColorStringGrid);
var
  Rct: TRect;
  res: integer;
begin
  res := zgg.MergeCells.AddRectXY(1, 0, 3, 0);
  res := zgg.MergeCells.AddRectXY(4, 0, 6, 0);
  res := zgg.MergeCells.AddRectXY(7, 0, 9, 0);
  zgg.Cells[1,0]:='Warminster Road';
  zgg.Cells[4,0]:='High Street';
  zgg.Cells[7,0]:='Totals';
  zgg.Cells[1,1]:='Entries:';
  zgg.Cells[4,1]:='Entries:';
  zgg.Cells[7,1]:='Entries:';
  zgg.Cells[2,1]:='Amount:';
  zgg.Cells[5,1]:='Amount:';
  zgg.Cells[8,1]:='Amount:';
  zgg.Cells[3,1]:='Claim:';
  zgg.Cells[6,1]:='Claim:';
  zgg.Cells[9,1]:='Claim:';
  zgg.Cells[0,2]:='Quarter Totals';
  zgg.Cells[0,3]:='This Session';
  Form1.UpdateTotals; 
end;

Note that this would hard-code it being called only for Form1, so it would be inaccessible from another form with a different name. You should either make fillhead a member of TForm1, where you don't need to decide which form is calling it, or change fillhead to accept another parameter that represents the form instance.

procedure fillhead(AForm: TForm1; zgg:TZColorStringGrid);
var
  Rct: TRect;
  res: integer;
begin
  res := zgg.MergeCells.AddRectXY(1, 0, 3, 0);
  res := zgg.MergeCells.AddRectXY(4, 0, 6, 0);
  res := zgg.MergeCells.AddRectXY(7, 0, 9, 0);
  zgg.Cells[1,0]:='Warminster Road';
  zgg.Cells[4,0]:='High Street';
  zgg.Cells[7,0]:='Totals';
  zgg.Cells[1,1]:='Entries:';
  zgg.Cells[4,1]:='Entries:';
  zgg.Cells[7,1]:='Entries:';
  zgg.Cells[2,1]:='Amount:';
  zgg.Cells[5,1]:='Amount:';
  zgg.Cells[8,1]:='Amount:';
  zgg.Cells[3,1]:='Claim:';
  zgg.Cells[6,1]:='Claim:';
  zgg.Cells[9,1]:='Claim:';
  zgg.Cells[0,2]:='Quarter Totals';
  zgg.Cells[0,3]:='This Session';
  AForm.UpdateTotals;
end;

My preference would be to make fillhead a member of the TForm1 class itself, and remove the need to pass the stringgrid in at all. This means that you can use the code without worrying in any use of TForm1, allowing you to create multiple instances of that form at the same time.

Upvotes: 2

Related Questions