Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Andrzejek on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

cannot compile if using a public function in another unit 1

Status
Not open for further replies.

Steveinalab

Programmer
Jul 8, 2022
3
US
I have a Delphi program that has a simple function (mysum) defined in the public area
of the form. I drop a button on the form, and on its click event I call my simple function
and get the result;

I later create a new project, and decide I want to use the mysum function, so I
add the first program (containing the mysum function) to the uses clause after
the implementation line.

I can right click on the unit name and select find declaration and it shows the unit I
want with the function, but it won't compile if I try to use the function, giving the error
"undeclared identifier mysum". I tried using the unit name dot the function name like
x := mydemou1.mysym(3,2) but I get the same error.

My solution is to create a new function in the same unit, named mysum2, but not make it part of the
form's class definition, instead it is right after the end line that ends the class definition.
so it is right before "var Form2 : Tform2".

It compiles and works fine, but it cannot refer to any components on the form.
My question is can you call a function that is defined in the form's Public Area from another
program that uses it? Or is it impossible for a calling program to call any functions
defined in the form's public area?
 
I got my program to work after reading the similar problem on tek-tips posted by Mikrom.

After reading the thread several times, I simply named the form in the subprogram to "myform2" and the class name was changed to TMyform2.

I was still getting the same compile error, but on a wild guess I added the form name to the function call in the form of <module name.form name.function name>, see next line
x := mydemou2.myform2.mysum(17,8);

and it compiles and runs fine just by adding the form name between the unit name and the function name.
I no longer needed to call the global "mysum2" function.

But a new problem has appeared. I added a variable named abcde of type integer in the public area of tmyform2, immediately after the mysum function.
It compiles but when I tried assigning a value to abcde I get access exceptions. But if I do nothing in the calling program regarding variable abcde, but I assign a value to it within the unit that has the mysum function, I still get access errors whether I code it like this:
function tmyform2.mysum(a,b:integer) : integer;
begin
result := a+b + myform2.abcde;
end;

or like this, not qualifying the variable with the form name:
function tmyform2.mysum(a,b:integer) : integer;
begin
result := a+b + abcde;
end;

If I take abcde out of the class definition public area, and simply add it as a variable right after myform2 : tmyform2
it runs fine. So my understanding of using the public area is still lacking.

This has all been a learning exercise for me, so there is no need for anyone to spend any time on this.

 
Sounds like a lot of what you're struggling with is more knowing what the proper contexts are of things within Delphi. Specifically, you seem to be confusing a lot of OOP concepts. To that end, there's no "understanding of using the public area" per se. It's understanding how everything works together. Unfortunately, this would require almost a classroom unit, and I'm not sure what to suggest as I had other books to figure out how OOP works. Even then, I still had to play with a lot of it.

An easier "for instance" to play with:

Code:
unit testunit;
interface
type
  { class definitions }
  TMyClass1 = class
    // the outer world knows about these things.
    public
       a, b: integer;

       function myadd1: integer;
    // the class itself only knows about these things.
    private
       c, d: integer;
  end;

  TMyClass2 = class(TMyClass1)
    // the outer world knows about these things.
    public
       e: integer;

       function myadd2: integer;
    // the class itself only knows about these things.
    private
       f: integer;
  end;

implementation
// this is a class function definition.
function TMyClass1.myadd1: Integer;
begin
  c := a;
  d := b;
  Result := c + d;
end;

function TMyClass2.myadd2: Integer;
begin
  c := a;
  d := b;
  f := e;
  Result := c + d + e;
end;

end.
Main:
Code:
{$APPTYPE CONSOLE}
program test_context; uses testunit;

{ these are global variables & definitions related to the unit }

function myadd1(a, b: Integer): Integer;
// these are local variables to myadd1
var
  c, d: integer;
begin
  c := a;
  d := b;
  Result := c + d;
end;

var
  a, b: integer;
  c: Integer;
  myclass1: TMyClass1;
  myclass2: TMyClass2;
begin
  a := 2; b := 3;
  c := a + b;
  writeln('Main Program: ', c);
// can't do anything with the class without doing this.  Try to access that
// part and you will get access violations:
  myclass1 := TMyClass1.Create;
  try
    myclass1.a := 2;
    myclass1.b := 4;
// This is an example of what the "sections" do.  Compiler will come back with
// "Undeclared identifier: 'c'" if the following line is uncommented.
//  myclass1.c := 2;
    c := myclass1.myadd1;
    writeln('First Class: ', c);
  finally
    myclass1.Free;
  end;
// descendant class
  myclass2 := TMyClass2.Create;
  try
    myclass2.a := 2;
    myclass2.b := 3;
    myclass2.e := 10;
    c := MyClass2.myadd2;
    writeln('Sub Class: ', c);
  finally
    myclass2.Free;
  end;
  readln;
end.

There isn't a lot there in that program (and pretty much just a demo), but it helps explain a lot of how OOP in Delphi works. A lot of the problem (and blessing) is in that it hides a lot of things that are happening in the background. But basically, the idea is to know the scopes behind where things belong. But I will have to say it does take a lot of practice to figure out how things work well enough to design things well using Delphi and OOP.

 
Thanks for posting the 2 units.
I do not see an option to close this thread or mark it as "solved", but ok with me if someone wants to close it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top