Progress .p question

As always I seemed to have completely missed a thought when I typed that.... But I got the answer I wanted and a bit more to chew on. Thanks!

TO clearify this is what I have and what I wanted.

This line is run in an On Leave statement for a configurator:
run //SERVERIPADDRESS/Epicor905/LOOKUPS/GO-PED/PED-ACC-PRICE.p(ChrSuffix,Substring(ChrPartNbr,1,1) + ChrCab + ChrDrawer,output DecAccPrice).

This is what the beginning of my .p File looks like:
/* Inputs DEFINED */
DEF INPUT PARAM ChrSuffix AS CHAR NO-UNDO.
DEF INPUT PARAM ChrPart AS CHAR NO-UNDO.

/* outputs DEFINED */
DEF OUTPUT PARAM DecAccPrice AS DECIMAL NO-UNDO

What I wanted was to how to add extra inputs and outputs to be optional...

But these lines give me what I think will work for what I was thinking of doing for inputs anyways Will give it a test:
> DEFINE INPUT PARAMETER p1 AS INT NO-UNDO.
> DEFINE INPUT PARAMETER p2 AS INT NO-UNDO.
> DEFINE OUTPUT PARAM pSum AS INT NO-UNDO.
>
> IF p1 = ? or p2 = ? THEN RETURN ERROR "Operands cannot be NULL".




--- In vantage@yahoogroups.com, "Mike Anstey" <manstey@...> wrote:
>
> You can update the dataset directly via a .p if you pass in the dataset
> shown at the top of the screen when you select run ABL program.
>
> (This example is for the Customer BO).
>
> Here is what you would put in the method (usually in the before slot)
>
>
>
> For you action you select "Execute ABL Code", when that screen comes up
> your will see the name of the dataset being used at the top.
>
>
>
> Make sure you click "Execute code below" and put in something like this:
>
>
>
>
>
> RUN ud/Bpm/yourprogram.p({&input-output_dataset_CustomerDataSet}).
> (replace the dataset with what you see at the top of the screen, BUT it
> should allways start with "&input-output_dataset_"
>
> And you then just replace the "CustomerDataSet" with the correct one.
>
>
>
> This will allow you to pass the dataset into your .p program and
> manipulate it any way you want.
>
>
>
> (the path I show is for unix and has to be accessible via your propath)
> windows has the slashes the other way I think.
>
>
>
> In your server side program you need to start with the following:
>
>
>
> {Bpm/Bpm.i &OBJECT_NAME=Customer &BPM_BO_SOURCE_BO=1}
>
> {core/CallContext/CallContext.i}
>
>
>
> {&define_input-output_parameter_dataset_for_CustomerDataSet} ( This
> is that same dataset you passed in on the method side, but note that
> this has &define_ in front of it)
>
>
>
>
>
> Finally you need to select the changed record and do whatever you want
> to the tt record:
>
>
>
> FIND FIRST ttCustomer WHERE ttCustomer.RowMod = "U" OR
> ttCustomer.RowMod = "A" NO-ERROR.
>
> IF AVAIL ttCustomer THEN
>
> DO:
>
> MESSAGE "ttCustomer.CustNum " ttCustomer.CustNum.
>
> ..... do stuff
>
> END.
>
>
>
> You can change or update ANY field on the file you are working with and
> it will get passed back to your screen and update the record when you
> save.
>
>
>
> And the best part? You NEVER have to open that method directive again.
> Just make your changes to the .p program and next time someone runs it,
> the changes will take effect.
>
>
>
>
>
> From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com] On Behalf
> Of reptcon
> Sent: Friday, May 11, 2012 1:12 PM
> To: vantage@yahoogroups.com
> Subject: [Vantage] Re: Progress .p question
>
>
>
>
>
> /* put program sum.p on appserver */
>
> DEFINE INPUT PARAMETER p1 AS INT NO-UNDO.
> DEFINE INPUT PARAMETER p2 AS INT NO-UNDO.
> DEFINE OUTPUT PARAM pSum AS INT NO-UNDO.
>
> IF p1 = ? or p2 = ? THEN RETURN ERROR "Operands cannot be NULL".
>
> ASSIGN pSum = p1 + p2 NO-ERROR.
>
> IF ERROR-STATUS:ERROR THEN RETURN ERROR ERROR-STATUS:GET-MESSAGE(1).
>
> MESSAGE ("-- Sum.p of " + string(p1) + " + " + string(p2) + " = " +
> string(pSum)).
>
> RETURN "". /* The caller should check for RETURN-VALUE > "" to signify
> error or message for the user */
>
> /* ----------------------------------------------------------
> Then in a directive - to call sum.p from Progress ABL
>
> Not being so careful to CAP keywords below ...
> Progress ABL, unlike C#, is case-insensitive unless you
> go out of your way to make it so.
> And you can freely abbrevieate keywords so long as you type
> enough to make them unique, e.g. def var for DEFINE VARIABLE.
> ---------------------------------------------------------- */
>
> def var viTemp as int no-undo.
> def var op1 as int no-undo.
> def var op2 as int no-undo.
>
> def var i as int no-undo.
>
> repeat i = 1 to 10: /* time returns seconds since midnight */
>
> op1 = random(1,time).
> op2 = random(time,100000).
>
> if i = 10 then op2 = ?. /* NULL to force error condition */
>
> RUN cahTest.p (INPUT op1, INPUT op2, OUTPUT viTemp) no-error.
>
> /* INPUT is assumed and keyword is optional in parameters but OUTPUT or
> INPUT-OUTPUT is required when used. */
>
> /* Check to see if "RETURN ERROR" was passed back
> There are ways of making these messages appear to the user
> rather than in the appserver log as written below */
>
> if return-value > "" then message "RetVal:" + return-value.
> if error-status:error then do:
> message "Error:" + error-status:get-message(1).
> end.
> else message "Loop: " + string(i) + " Sum of " + string(op1) " + "
> string(op2) + " = " + string(viTemp).
>
> end. /* i loop */
>
> return.
>
> /* -----------------------------------------------------
> to call this from C# passing parameters
> is a bit more complicated,
> but I just wrote this in a customiztion of ud40
> with 3 epiText boxes and a button to trigger it.
> grr wish I could copy/paste the screen,
> will send via email if you want to see: cheins@...
> <mailto:cheins%40pny.com>
>
> note that these assemby references were required:
>
> - Epicor.Mfg.Core.BLConnectionPool
> - Epocir.Mfg.Core.Session
> - Progress.o4glrt
>
> they have to exists in your epicor client folder.
>
> plus this libarary reference at the top of the program:
>
> using Progress.Open4GL.DynamicAPI;
>
> ------------------------------------------------------ */
>
> private void epiButtonC1_Click(object sender, System.EventArgs args)
> {
> // ** Place Event Handling Code Here **
> int viSum = getSumABL(Convert.ToInt32(epiTextBoxC1.Text),
> Convert.ToInt32(epiTextBoxC2.Text));
> epiTextBoxC3.Text = viSum.ToString();
> }
>
> private int getSum(int p1,int p2)
> {
> return p1 + p2;
> }
>
> private int getSumABL(int p1, int p2)
> {
> private int getSumABL(int p1, int p2)
> {
> string sysReturn = "";
> int viSum = 0;
>
> Epicor.Mfg.Core.Session epiSession =
> ((Epicor.Mfg.Core.Session)oTrans.Session);
> Session ablSession = default(Progress.Open4GL.DynamicAPI.Session);
>
> try
> {
> ablSession = epiSession.ConnectionPool.Get();
> ParameterSet parms = new ParameterSet(3);
> parms.setIntegerParameter(1, p1, ParameterSet.INPUT);
> parms.setIntegerParameter(2, p2, ParameterSet.INPUT);
> parms.setIntegerParameter(3, null, ParameterSet.OUTPUT);
> ablSession.runProcedure("cahTest.p", parms);
> sysReturn = (String)parms.ProcedureReturnValue;
> if (sysReturn == String.Empty) viSum = (int)parms.getOutputParameter(3);
>
> }
>
> catch (Exception err)
> {
> MessageBox.Show(err.ToString());
> }
> finally
> {
> if ((ablSession != null))
> {
> epiSession.ConnectionPool.Release(ablSession);
> }
> }
> if (sysReturn != "") MessageBox.Show(sysReturn);
> return viSum;
>
> }
>
> --- In vantage@yahoogroups.com <mailto:vantage%40yahoogroups.com> ,
> "Gibby" <guyguy50@> wrote:
> >
> > I've on advice of some helpful people here have started using a lot of
> .p programs for many of my onleave queries and calculation as it allows
> so much more freedom for data manipulating and such. But coming from a
> C++ / PERL /PHP world to progress has got me asking where is this?
> >
> > So my curious question of today is can I write a progress program,
> with using a run statement from my OnLeave statement and have optional
> inputs and outputs? I can't seem to find anything in the three main
> progress reference books that discuss this. Maybe I'm missing it, but it
> seems like it should be something that a 4th generation language should
> have. Then maybe it doesn't,so asking if anyones attempted this?
> >
>
>
>
>
>
> [Non-text portions of this message have been removed]
>
I've on advice of some helpful people here have started using a lot of .p programs for many of my onleave queries and calculation as it allows so much more freedom for data manipulating and such. But coming from a C++ / PERL /PHP world to progress has got me asking where is this?

So my curious question of today is can I write a progress program, with using a run statement from my OnLeave statement and have optional inputs and outputs? I can't seem to find anything in the three main progress reference books that discuss this. Maybe I'm missing it, but it seems like it should be something that a 4th generation language should have. Then maybe it doesn't,so asking if anyones attempted this?
/* put program sum.p on appserver */

DEFINE INPUT PARAMETER p1 AS INT NO-UNDO.
DEFINE INPUT PARAMETER p2 AS INT NO-UNDO.
DEFINE OUTPUT PARAM pSum AS INT NO-UNDO.

IF p1 = ? or p2 = ? THEN RETURN ERROR "Operands cannot be NULL".

ASSIGN pSum = p1 + p2 NO-ERROR.

IF ERROR-STATUS:ERROR THEN RETURN ERROR ERROR-STATUS:GET-MESSAGE(1).

MESSAGE ("-- Sum.p of " + string(p1) + " + " + string(p2) + " = " + string(pSum)).

RETURN "". /* The caller should check for RETURN-VALUE > "" to signify error or message for the user */

/* ---------------------------------------------------------------
Then in a directive - to call sum.p from Progress ABL

Not being so careful to CAP keywords below ...
Progress ABL, unlike C#, is case-insensitive unless you
go out of your way to make it so.
And you can freely abbrevieate keywords so long as you type
enough to make them unique, e.g. def var for DEFINE VARIABLE.
--------------------------------------------------------------- */

def var viTemp as int no-undo.
def var op1 as int no-undo.
def var op2 as int no-undo.

def var i as int no-undo.

repeat i = 1 to 10: /* time returns seconds since midnight */

op1 = random(1,time).
op2 = random(time,100000).

if i = 10 then op2 = ?. /* NULL to force error condition */

RUN cahTest.p (INPUT op1, INPUT op2, OUTPUT viTemp) no-error.

/* INPUT is assumed and keyword is optional in parameters but OUTPUT or INPUT-OUTPUT is required when used. */

/* Check to see if "RETURN ERROR" was passed back
There are ways of making these messages appear to the user
rather than in the appserver log as written below */

if return-value > "" then message "RetVal:" + return-value.
if error-status:error then do:
message "Error:" + error-status:get-message(1).
end.
else message "Loop: " + string(i) + " Sum of " + string(op1) " + " string(op2) + " = " + string(viTemp).

end. /* i loop */

return.


/* -----------------------------------------------------
to call this from C# passing parameters
is a bit more complicated,
but I just wrote this in a customiztion of ud40
with 3 epiText boxes and a button to trigger it.
grr wish I could copy/paste the screen,
will send via email if you want to see: cheins@...

note that these assemby references were required:

- Epicor.Mfg.Core.BLConnectionPool
- Epocir.Mfg.Core.Session
- Progress.o4glrt

they have to exists in your epicor client folder.

plus this libarary reference at the top of the program:

using Progress.Open4GL.DynamicAPI;

------------------------------------------------------ */

private void epiButtonC1_Click(object sender, System.EventArgs args)
{
// ** Place Event Handling Code Here **
int viSum = getSumABL(Convert.ToInt32(epiTextBoxC1.Text), Convert.ToInt32(epiTextBoxC2.Text));
epiTextBoxC3.Text = viSum.ToString();
}

private int getSum(int p1,int p2)
{
return p1 + p2;
}

private int getSumABL(int p1, int p2)
{
private int getSumABL(int p1, int p2)
{
string sysReturn = "";
int viSum = 0;

Epicor.Mfg.Core.Session epiSession = ((Epicor.Mfg.Core.Session)oTrans.Session);
Session ablSession = default(Progress.Open4GL.DynamicAPI.Session);

try
{
ablSession = epiSession.ConnectionPool.Get();
ParameterSet parms = new ParameterSet(3);
parms.setIntegerParameter(1, p1, ParameterSet.INPUT);
parms.setIntegerParameter(2, p2, ParameterSet.INPUT);
parms.setIntegerParameter(3, null, ParameterSet.OUTPUT);
ablSession.runProcedure("cahTest.p", parms);
sysReturn = (String)parms.ProcedureReturnValue;
if (sysReturn == String.Empty) viSum = (int)parms.getOutputParameter(3);
}

catch (Exception err)
{
MessageBox.Show(err.ToString());
}
finally
{
if ((ablSession != null))
{
epiSession.ConnectionPool.Release(ablSession);
}
}
if (sysReturn != "") MessageBox.Show(sysReturn);
return viSum;

}

--- In vantage@yahoogroups.com, "Gibby" <guyguy50@...> wrote:
>
> I've on advice of some helpful people here have started using a lot of .p programs for many of my onleave queries and calculation as it allows so much more freedom for data manipulating and such. But coming from a C++ / PERL /PHP world to progress has got me asking where is this?
>
> So my curious question of today is can I write a progress program, with using a run statement from my OnLeave statement and have optional inputs and outputs? I can't seem to find anything in the three main progress reference books that discuss this. Maybe I'm missing it, but it seems like it should be something that a 4th generation language should have. Then maybe it doesn't,so asking if anyones attempted this?
>
You can update the dataset directly via a .p if you pass in the dataset
shown at the top of the screen when you select run ABL program.

(This example is for the Customer BO).

Here is what you would put in the method (usually in the before slot)



For you action you select "Execute ABL Code", when that screen comes up
your will see the name of the dataset being used at the top.



Make sure you click "Execute code below" and put in something like this:





RUN ud/Bpm/yourprogram.p({&input-output_dataset_CustomerDataSet}).
(replace the dataset with what you see at the top of the screen, BUT it
should allways start with "&input-output_dataset_"

And you then just replace the "CustomerDataSet" with the correct one.



This will allow you to pass the dataset into your .p program and
manipulate it any way you want.



(the path I show is for unix and has to be accessible via your propath)
windows has the slashes the other way I think.



In your server side program you need to start with the following:



{Bpm/Bpm.i &OBJECT_NAME=Customer &BPM_BO_SOURCE_BO=1}

{core/CallContext/CallContext.i}



{&define_input-output_parameter_dataset_for_CustomerDataSet} ( This
is that same dataset you passed in on the method side, but note that
this has &define_ in front of it)





Finally you need to select the changed record and do whatever you want
to the tt record:



FIND FIRST ttCustomer WHERE ttCustomer.RowMod = "U" OR
ttCustomer.RowMod = "A" NO-ERROR.

IF AVAIL ttCustomer THEN

DO:

MESSAGE "ttCustomer.CustNum " ttCustomer.CustNum.

..... do stuff

END.



You can change or update ANY field on the file you are working with and
it will get passed back to your screen and update the record when you
save.



And the best part? You NEVER have to open that method directive again.
Just make your changes to the .p program and next time someone runs it,
the changes will take effect.





From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com] On Behalf
Of reptcon
Sent: Friday, May 11, 2012 1:12 PM
To: vantage@yahoogroups.com
Subject: [Vantage] Re: Progress .p question





/* put program sum.p on appserver */

DEFINE INPUT PARAMETER p1 AS INT NO-UNDO.
DEFINE INPUT PARAMETER p2 AS INT NO-UNDO.
DEFINE OUTPUT PARAM pSum AS INT NO-UNDO.

IF p1 = ? or p2 = ? THEN RETURN ERROR "Operands cannot be NULL".

ASSIGN pSum = p1 + p2 NO-ERROR.

IF ERROR-STATUS:ERROR THEN RETURN ERROR ERROR-STATUS:GET-MESSAGE(1).

MESSAGE ("-- Sum.p of " + string(p1) + " + " + string(p2) + " = " +
string(pSum)).

RETURN "". /* The caller should check for RETURN-VALUE > "" to signify
error or message for the user */

/* ----------------------------------------------------------
Then in a directive - to call sum.p from Progress ABL

Not being so careful to CAP keywords below ...
Progress ABL, unlike C#, is case-insensitive unless you
go out of your way to make it so.
And you can freely abbrevieate keywords so long as you type
enough to make them unique, e.g. def var for DEFINE VARIABLE.
---------------------------------------------------------- */

def var viTemp as int no-undo.
def var op1 as int no-undo.
def var op2 as int no-undo.

def var i as int no-undo.

repeat i = 1 to 10: /* time returns seconds since midnight */

op1 = random(1,time).
op2 = random(time,100000).

if i = 10 then op2 = ?. /* NULL to force error condition */

RUN cahTest.p (INPUT op1, INPUT op2, OUTPUT viTemp) no-error.

/* INPUT is assumed and keyword is optional in parameters but OUTPUT or
INPUT-OUTPUT is required when used. */

/* Check to see if "RETURN ERROR" was passed back
There are ways of making these messages appear to the user
rather than in the appserver log as written below */

if return-value > "" then message "RetVal:" + return-value.
if error-status:error then do:
message "Error:" + error-status:get-message(1).
end.
else message "Loop: " + string(i) + " Sum of " + string(op1) " + "
string(op2) + " = " + string(viTemp).

end. /* i loop */

return.

/* -----------------------------------------------------
to call this from C# passing parameters
is a bit more complicated,
but I just wrote this in a customiztion of ud40
with 3 epiText boxes and a button to trigger it.
grr wish I could copy/paste the screen,
will send via email if you want to see: cheins@...
<mailto:cheins%40pny.com>

note that these assemby references were required:

- Epicor.Mfg.Core.BLConnectionPool
- Epocir.Mfg.Core.Session
- Progress.o4glrt

they have to exists in your epicor client folder.

plus this libarary reference at the top of the program:

using Progress.Open4GL.DynamicAPI;

------------------------------------------------------ */

private void epiButtonC1_Click(object sender, System.EventArgs args)
{
// ** Place Event Handling Code Here **
int viSum = getSumABL(Convert.ToInt32(epiTextBoxC1.Text),
Convert.ToInt32(epiTextBoxC2.Text));
epiTextBoxC3.Text = viSum.ToString();
}

private int getSum(int p1,int p2)
{
return p1 + p2;
}

private int getSumABL(int p1, int p2)
{
private int getSumABL(int p1, int p2)
{
string sysReturn = "";
int viSum = 0;

Epicor.Mfg.Core.Session epiSession =
((Epicor.Mfg.Core.Session)oTrans.Session);
Session ablSession = default(Progress.Open4GL.DynamicAPI.Session);

try
{
ablSession = epiSession.ConnectionPool.Get();
ParameterSet parms = new ParameterSet(3);
parms.setIntegerParameter(1, p1, ParameterSet.INPUT);
parms.setIntegerParameter(2, p2, ParameterSet.INPUT);
parms.setIntegerParameter(3, null, ParameterSet.OUTPUT);
ablSession.runProcedure("cahTest.p", parms);
sysReturn = (String)parms.ProcedureReturnValue;
if (sysReturn == String.Empty) viSum = (int)parms.getOutputParameter(3);

}

catch (Exception err)
{
MessageBox.Show(err.ToString());
}
finally
{
if ((ablSession != null))
{
epiSession.ConnectionPool.Release(ablSession);
}
}
if (sysReturn != "") MessageBox.Show(sysReturn);
return viSum;

}

--- In vantage@yahoogroups.com <mailto:vantage%40yahoogroups.com> ,
"Gibby" <guyguy50@...> wrote:
>
> I've on advice of some helpful people here have started using a lot of
.p programs for many of my onleave queries and calculation as it allows
so much more freedom for data manipulating and such. But coming from a
C++ / PERL /PHP world to progress has got me asking where is this?
>
> So my curious question of today is can I write a progress program,
with using a run statement from my OnLeave statement and have optional
inputs and outputs? I can't seem to find anything in the three main
progress reference books that discuss this. Maybe I'm missing it, but it
seems like it should be something that a 4th generation language should
have. Then maybe it doesn't,so asking if anyones attempted this?
>





[Non-text portions of this message have been removed]