How to use a Procedure

his_airness

New Member
I have a file, named CreateVersion.p.
The content is as followed:
PROCEDURE CreateVersion:
......
END PROCEDURE.


My question is: How can I call this procedure from another file?
 
IF the .p file is in your propath then simply:Run fileName.p IN THIS-PROCEDURE.ELSE RUN c:\path\FileName.p IN THIS-PROCEDURE.
 

tamhas

ProgressTalk.com Sponsor
If the procedure is the entire file, then the PROCEDURE keyword is unnecessary and you can just run CreateVersion.p. Use of the keyword suggests that you want to run the .p persistent and then run the internal procedure name IN handle.
 

TomBascom

Curmudgeon
I have a file, named CreateVersion.p.
The content is as followed:
PROCEDURE CreateVersion:
......
END PROCEDURE.


My question is: How can I call this procedure from another file?

CreateVersion is an Internal Procedure (often abbreviated as "IP" by Progress programmers) within CreateVersion.p.

Running it from another procedure within or the main body of CreateVersion.p is easy, just say "run CreateVersion.". Or, if you like redundant typing, "run CreateVersion in this-procedure.".

There are several ways that you can run it from other procedures. But you need to run CreateVersion.p first. Something along these lines will instantiate CreateVersion.p as a Persistent Procedure (known as a "PP"):

Code:
define variable p_handle as handle no-undo.

run CreateVersion.p persistent set p_handle.

run CreateVersion in p_handle.

This makes CreateVersion.p available to any program in the session that knows the value of p_handle. Of course that results in a chicken and egg problem about how to disburse the value of the handle. That can be solved in many ways. One method is to modify CreateVersion.p slightly to install itself as a Session Super Procedure ("SSP") like so:

Code:
PROCEDURE CreateVersion:
......
END PROCEDURE.

session:add-super-procedure( this-procedure ).

This then allows you to call CreateVersion without knowing its handle. Thus changing the sample code to:

Code:
run CreateVersion.p persistent.

run CreateVersion.

Many times you might launch a library of generally useful persistent procedures (sometimes known as a Persistent Procedure Library or "PPL") in this fashion in your startup routine making them available to your whole application.

There are other methods as well (publish & subscribe for instance) and you can have many adventures with super procedure stacks, procedure managers and app servers but these simple examples ought to get you started.
 
For readability define a handle, helps error trappin. Remember somebody else will have to read & debug the code. Supplin a handle will help, even if the handle is simply THIS-PROCEDURE. The debugger will know instantly where to look. If the block is in a persistantly ran object ala ADM(1) / ADM 2 it helps Progress / OpenEdge. Just like using remarks /* comments */ whenever possible, even if it seems obvious.
 

his_airness

New Member
These things don't resolve the problem. I will explain it:

I have a file test.p. This creates a tree of xml-elements.

DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hOrderRequest AS HANDLE NO-UNDO.
CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hOrderRequest.
hDoc:CREATE-NODE(hOrderRequest, "OrderRequest","ELEMENT").
hDoc:APPEND-CHILD(hOrderRequest).

So now i have 1 xml element.

I want to call this procedure in the file CreateVersion.p(in this file, there's nothing else than this procedure):

PROCEDURE CreateVersion:
/* <Version1.0 */
DEFINE INPUT PARAMETER doc AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER parentnode AS HANDLE NO-UNDO.

DEFINE VARIABLE hNode AS HANDLE NO-UNDO.
CREATE X-NODEREF hNode.

doc:CREATE-NODE(hNode,"Version1.0","ELEMENT").
parentNode:APPEND-CHILD(hNode).
END PROCEDURE.

So i have to give 2 parameters... Can someone give an easy solution to this?
 

FrancoisL

Member
At the start of your program (only need to do it once)
Code:
define variable p_handle as handle no-undo.

run CreateVersion.p persistent set p_handle.


The each time you need to call it :

Code:
run CreateVersion in p_handle (hDoc , hOrderRequest ).
 

schaapie

Member
Am I missing something or...
If this is the only thing in the file:
Code:
procedure ...
...
end procedure.

The easiest way to use it then would be to treat is as an include.
Insert this line in your code:
Code:
{(pro)path_to_file/createversion.p}

After that you can use the procedure in your code as an internal procedure:
Code:
run CreateVersion(hDoc , hOrderRequest ).
No need for "set handle" or "run in handle".

Normally include-files are named *.i but it's not necessary.
This would make al youre compiled programms bigger since the code is really included in all files.
Maintenance remains the same, only one file.
 

TomBascom

Curmudgeon
I don't think that promoting the use of include files for this sort of thing is such a good idea. The whole point of creating internal procedures is to get away from that sort of thing ;)
 

RKR

Member
Am I missing something or...
If this is the only thing in the file:
Code:
procedure ...
...
end procedure.
The easiest way to use it then would be to treat is as an include.
Insert this line in your code:
Code:
{(pro)path_to_file/createversion.p}
After that you can use the procedure in your code as an internal procedure:
Code:
run CreateVersion(hDoc , hOrderRequest ).
No need for "set handle" or "run in handle".

Normally include-files are named *.i but it's not necessary.
This would make al youre compiled programms bigger since the code is really included in all files.
Maintenance remains the same, only one file.

:confused: As usual u are missing something :awink:
You just mentioned yourself one of the disadvantages of including this file. Increase in .r size, which can eventually become a problem. Another disadvantage is re-usability. If in the future some other procedures will be included in this file then all these procedures will again be included in .r,even when these procedures are not needed.

always think about the future and remember, the quickest way is usual the dirtiest way ;p
 

schaapie

Member
:confused: As usual u are missing something :awink:
...
always think about the future and remember, the quickest way is usual the dirtiest way

:awink: How do you know I am usually missing something? Since I didn't miss the thing you mention
 

RKR

Member
:awink: How do you know I am usually missing something? Since I didn't miss the thing you mention

You missed :D

If you use a .p file as an include you will have to recompile all other sources where the file is included. This means extra documentation to keep track of where this file is used, or simply recompiling the complete application.

Increase of .r size means a decrease in performance. When you have your code on a shared network drive it means an increase in network traffic and a further decrease in performance. This is one of the reasons why we use persistent and super procedures so you can instantiate a procedure once and use the internals whenever and whereever you need and in most cases when a change is required only the recompilation of 1 procedure is necessary. Includes with procedural code are so 1845 :awink:
 

jakea

New Member
Erm...

Why is the code in the original file in a Procedure? If you just remove the "Procedure..." and "End procedure" lines, you can just call the program, can't you?

Or if you insist it is a procedure, add a line at the top of the file:

RUN CreateVersion...

and then have RUN {directory}{file}.p.

Or is this too easy?

Jake.
 

his_airness

New Member
And if I have a file FormatNumber.p:
Function FormatNumber

FUNCTION FormatNumberToIngrammicro RETURNS CHARACTER
(INPUT DateOrig AS DATE):
DEFINE VARIABLE DateTechData AS CHARACTER.
....
RETURN DateTechData.
END FUNCTION.

how can I call it in another function:
ASSIGN.....
 

tamhas

ProgressTalk.com Sponsor
Either there is some problem in communication here or you are going about your development in an odd way. Are these your own examples or are you getting them from some other source? Certainly, there are plentiful sources of bad examples out there!

If you want and it is appropriate to wrap a small bit of code as a separate executable, you need neither PROCEDURE or FUNCTION keywords inside the .p. Just define some parameters, put the code in there, and call it. For any block of code which tends to be one time usage, this is the right thing to do.

If you have one or more procedures and functions which you need repeatedly for a certain section of code, then package them together in reasonable collections and run them persistently, as you have been shown above.

If you make the persistent procedure a SUPER, then you don't need the in handle stuff to run the internal procedures and functions.

If the scope of use extends beyond a simple block, then consider making it a SESSION SUPER. This is appropriate for procedures and functions that are generally useful in a session such as context information like what is the current fiscal period.
 
Top