BPM double jeopardy?! ...2 methods down and 179 left to try!?

Thanks, Jim, and others. I do have one way working now, so i'm pretty thankful for all the help.

--- In vantage@yahoogroups.com, "jckinneman" <jckinneman@...> wrote:
>
> Typically I run a trace log on the transactions that I want to modify via a BPM. Looking through the trace long will list the methods that are called during the transaction. Not an exact science and doesn't always provide the complete picture. BPMs isn't always the solution, using embedded is sometimes the way to go.
>
> Based on the systems I have worked on Epicor isn't the best nor the worst when it comes to documentation. From a positive standpoint they are working on it, something you can't say for all companies. Things are much improved from 5+ years ago when I started working on Epicor. As with most systems it takes time to get the feel of a product sort of like the time it takes to learn the culture of the company you are working at. Once you get an overall feel for Epicor the behavior is fairly consistent, again not perfect but usually.
>
> Jim Kinneman
>
>
> --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> >
> >
> >
> > ttOrderHed problem encountered in these methods where I've tried it:
> >
> > SalesOrder.Update (pre-processing)
> > SalesOrder.MasterUpdate (preprocessing)
> >
> > Is one of these other methods known as best for weight calcs?:
> >
> > SalesOrder.ChangeSellingQtyMaster
> > SalesOrder.ChangeSellingQuantity
> > SalesOrder.ChangeSellingReqQty
> > SalesOrder.CheckSellingQuantityChange
> > SalesOrder.GetCalcQtyPref
> > SalesOrder.GetRows
> > SalesOrder.OnChangeOfFixedAmount
> > SalesOrder.SetCalcQtysPref
> > SalesOrder.UpdateExt
> >
> > SalesOrder has 181 methods to choose from; ones above ones seem the most relevent. Argh.
> >
> > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > >
> > > You probably mentioned it but which method is the code running against? Depending on the method it may only have data under certain conditions, other times it may be empty at the time the method is called. It is not uncommon to need the same or very similar BPM on more than one method to cover all conditions and methods that may be called.
> > >
> > > Jim Kinneman
> > > Encompass Solutions, Inc
> > >
> > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > >
> > > > Maybe all fields actually are there in the ttTables - I may have misspelled a field I was looking for, but still...
> > > >
> > > > The ttTables in pre-processing seem "spotty" as to what they happen to provide access to, as opposed to post-processing where the ordinary tables contain committed & comprehensive data (as would be expected).
> > > >
> > > > As evidence of what appears "spotty", here's full code to a simple pre-processing BPM example:
> > > >
> > > > OUTPUT TO "c:\temp\dang.txt".
> > > > MESSAGE "code area #1".
> > > > FOR EACH ttorderhed:
> > > > MESSAGE "code area #2... " + STRING(ttorderhed.ordernum).
> > > > END.
> > > > MESSAGE "code area #3".
> > > > OUTPUT CLOSE.
> > > >
> > > > CASE A: When this pre-processing BPM fires on a new order, it has no problem tapping the ttOrderHed temp table to get ordernum (which happens to be 0 at this early stage). The contents of the log file in this situation are as expected:
> > > >
> > > > code area #1
> > > > code area #2... ttorderhed.ordernum = 0
> > > > code area #3
> > > >
> > > > CASE B: But when it fires on an existing order that user is editing, then the log file reports only this!:
> > > >
> > > > code area #1
> > > > code area #3
> > > >
> > > > What the heck?! Where's "code area #2"?! It seems here in CASE B that pre-processing does not have a handle on ttOrderHed, whereas in CASE A it does.
> > > >
> > > > My guess is that I need to modify the code to somehow explicitly address ttOrderHed to make it accessible - a way that will work for any state of order creation or editing.
> > > >
> > > > Anybody know what code I might add to make it always able to get to "code area #2"...?
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > > > >
> > > > > Which fields from the order are not available? It is OK to look-up values from the part table since you are not updating it.
> > > > >
> > > > > DEFINE VAR relWeight AS DECIMAL.
> > > > > DEFINE VAR linWeight AS DECIMAL.
> > > > > DEFINE VAR hedWeight AS DECIMAL.
> > > > >
> > > > > FOR EACH ttorderhed:
> > > > > /* find, calc & store release weight */
> > > > > FOR EACH ttorderrel:
> > > > > FIND FIRST part WHERE ttorderrel.company = part.company AND
> > > > > ttorderrel.PartNum = part.PartNum no-lock no-error.
> > > > > IF AVAIL part THEN DO:
> > > > > relWeight = part.NetWeight * ttorderrel.OurReqQty.
> > > > > ttorderrel.number01 = relWeight.
> > > > > hedWeight = hedWeight + relWeight.
> > > > > END.
> > > > > ttorderhed.number01 = hedWeight.
> > > > > END.
> > > > >
> > > > > Jim Kinneman
> > > > > Encompass Solutions, Inc
> > > > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > > > >
> > > > > >
> > > > > >
> > > > > > The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?
> > > > > >
> > > > > > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > > > > > >
> > > > > > > If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
> > > > > > >
> > > > > > > Jim Kinneman
> > > > > > > Encompass Solutions, Inc
> > > > > > >
> > > > > > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> > > > > > > >
> > > > > > > > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> > > > > > > >
> > > > > > > > Here's the tweaked wizard code that does the refresh:
> > > > > > > >
> > > > > > > >
> > > > > > > > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > > > > > > > {
> > > > > > > > // ** Argument Properties and Uses **
> > > > > > > > // ** args.MethodName **
> > > > > > > > // ** Add Event Handler Code **
> > > > > > > >
> > > > > > > > // ** Use MessageBox to find adapter method name
> > > > > > > > // EpiMessageBox.Show(args.MethodName)
> > > > > > > > switch (args.MethodName)
> > > > > > > > {
> > > > > > > > case "Update":
> > > > > > > > oTrans.Refresh();
> > > > > > > > // --above line is added tweak --
> > > > > > > > break;
> > > > > > > > }
> > > > > > > >
> > > > > > > > }
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
I have a post-processing BPM that upon "Save" calculates weight for orderhed,
orderdtl, and orderrel (derrived from code found on forum) and it runs correctly
when the users clicks "Save"... the first time.

Trouble happens if user changes release qty again and then clicks "Save" again.
This causes an error stating "Row has been modified by another user and couldn't
be updated. Please press the Refresh button and re-enter your changes."

Trouble is averted just as the error message says, if user clicks "Refersh"
before that last "Save".

This makes me think the tt... buffers are thinking "dirty" though the "Save"
ought to have made them clean. Is that the trouble? Is there a way to force the
buffers to be ready (i.e. "clean") within my BPM so that users don't have to
click "Refresh" intermittently?

-------Below is my BPM code-------------------------
DEFINE VAR relWeight AS DECIMAL.
DEFINE VAR linWeight AS DECIMAL.
DEFINE VAR hedWeight AS DECIMAL.

FOR EACH ttorderhed:
FIND FIRST orderhed WHERE ttorderhed.company = orderhed.company AND ttorderhed.ordernum = orderhed.OrderNum.
IF AVAIL orderhed THEN DO:

/* find, calc & store release weight */
FOR EACH ttorderrel:
FOR EACH orderrel WHERE ttorderrel.company = orderrel.Company AND ttorderrel.OrderNum = orderrel.OrderNum AND ttorderrel.OrderLine = orderrel.OrderLine AND ttorderrel.OrderRelNum = orderrel.OrderRelNum:
FIND FIRST part WHERE ttorderrel.company = part.company AND ttorderrel.PartNum = part.PartNum.
IF AVAIL part THEN DO:
relWeight = part.NetWeight * ttorderrel.OurReqQty.
ttorderrel.number01 = relWeight.
RUN lib\UpdateTableBuffer.p(input BUFFER OrderRel:HANDLE, 'Number01', relWeight).
END.
END.
END.

/* roll up release weights into header */
FOR EACH orderrel WHERE ttorderhed.company = orderrel.company AND ttorderhed.ordernum = orderrel.OrderNum:
relWeight = orderrel.number01.
hedWeight = hedWeight + relWeight.
END.
ttorderhed.number01 = hedWeight.
RUN lib\UpdateTableBuffer.p(input BUFFER OrderHed:HANDLE, 'Number01', hedWeight).

END.
END.

FOR EACH ttorderdtl:
FIND FIRST orderdtl WHERE ttorderdtl.company = orderdtl.company AND ttorderdtl.ordernum = orderdtl.OrderNum AND ttorderdtl.orderline = orderdtl.Orderline.
IF AVAIL orderdtl THEN DO:

FOR EACH ttorderrel:
FOR EACH orderrel WHERE ttorderrel.company = orderrel.Company AND ttorderrel.OrderNum = orderrel.OrderNum AND ttorderrel.OrderLine = orderrel.OrderLine AND ttorderrel.OrderRelNum = orderrel.OrderRelNum:
FIND FIRST part WHERE ttorderrel.company = part.company AND ttorderrel.PartNum = part.PartNum.
IF AVAIL part THEN DO:
relWeight = part.NetWeight * ttorderrel.OurReqQty.
ttorderrel.number01 = relWeight.
/* can i really skip this?... RUN lib\UpdateTableBuffer.p(input BUFFER OrderRel:HANDLE, 'Number01', relWeight).*/
END.
END.
END.

/* roll up release weights into line */
linWeight = 0.
FOR EACH orderrel WHERE ttorderdtl.company = orderrel.company AND ttorderdtl.ordernum = orderrel.OrderNum AND ttorderdtl.orderline = orderrel.orderline:
relWeight = orderrel.number01.
linWeight = linWeight + relWeight.
END.
ttorderdtl.number01 = linWeight.
RUN lib\UpdateTableBuffer.p(input BUFFER OrderDtl:HANDLE, 'Number01', linWeight).

END.
END.
The problem is that the post processing runs after the records are
written to the database.

If you change any values after the record has been saves, it will be
seen as though someone else changed the record.

To get around this, you can either move your code to a preprocessing
directive or to a data directive.





From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com] On Behalf
Of itwepicor
Sent: Thursday, June 21, 2012 6:37 PM
To: vantage@yahoogroups.com
Subject: [Vantage] BPM double jeopardy?!





I have a post-processing BPM that upon "Save" calculates weight for
orderhed,
orderdtl, and orderrel (derrived from code found on forum) and it runs
correctly
when the users clicks "Save"... the first time.

Trouble happens if user changes release qty again and then clicks "Save"
again.
This causes an error stating "Row has been modified by another user and
couldn't
be updated. Please press the Refresh button and re-enter your changes."

Trouble is averted just as the error message says, if user clicks
"Refersh"
before that last "Save".

This makes me think the tt... buffers are thinking "dirty" though the
"Save"
ought to have made them clean. Is that the trouble? Is there a way to
force the
buffers to be ready (i.e. "clean") within my BPM so that users don't
have to
click "Refresh" intermittently?

-------Below is my BPM code-------------------------
DEFINE VAR relWeight AS DECIMAL.
DEFINE VAR linWeight AS DECIMAL.
DEFINE VAR hedWeight AS DECIMAL.

FOR EACH ttorderhed:
FIND FIRST orderhed WHERE ttorderhed.company = orderhed.company AND
ttorderhed.ordernum = orderhed.OrderNum.
IF AVAIL orderhed THEN DO:

/* find, calc & store release weight */
FOR EACH ttorderrel:
FOR EACH orderrel WHERE ttorderrel.company = orderrel.Company AND
ttorderrel.OrderNum = orderrel.OrderNum AND ttorderrel.OrderLine =
orderrel.OrderLine AND ttorderrel.OrderRelNum = orderrel.OrderRelNum:
FIND FIRST part WHERE ttorderrel.company = part.company AND
ttorderrel.PartNum = part.PartNum.
IF AVAIL part THEN DO:
relWeight = part.NetWeight * ttorderrel.OurReqQty.
ttorderrel.number01 = relWeight.
RUN lib\UpdateTableBuffer.p(input BUFFER OrderRel:HANDLE, 'Number01',
relWeight).
END.
END.
END.

/* roll up release weights into header */
FOR EACH orderrel WHERE ttorderhed.company = orderrel.company AND
ttorderhed.ordernum = orderrel.OrderNum:
relWeight = orderrel.number01.
hedWeight = hedWeight + relWeight.
END.
ttorderhed.number01 = hedWeight.
RUN lib\UpdateTableBuffer.p(input BUFFER OrderHed:HANDLE, 'Number01',
hedWeight).

END.
END.

FOR EACH ttorderdtl:
FIND FIRST orderdtl WHERE ttorderdtl.company = orderdtl.company AND
ttorderdtl.ordernum = orderdtl.OrderNum AND ttorderdtl.orderline =
orderdtl.Orderline.
IF AVAIL orderdtl THEN DO:

FOR EACH ttorderrel:
FOR EACH orderrel WHERE ttorderrel.company = orderrel.Company AND
ttorderrel.OrderNum = orderrel.OrderNum AND ttorderrel.OrderLine =
orderrel.OrderLine AND ttorderrel.OrderRelNum = orderrel.OrderRelNum:
FIND FIRST part WHERE ttorderrel.company = part.company AND
ttorderrel.PartNum = part.PartNum.
IF AVAIL part THEN DO:
relWeight = part.NetWeight * ttorderrel.OurReqQty.
ttorderrel.number01 = relWeight.
/* can i really skip this?... RUN lib\UpdateTableBuffer.p(input BUFFER
OrderRel:HANDLE, 'Number01', relWeight).*/
END.
END.
END.

/* roll up release weights into line */
linWeight = 0.
FOR EACH orderrel WHERE ttorderdtl.company = orderrel.company AND
ttorderdtl.ordernum = orderrel.OrderNum AND ttorderdtl.orderline =
orderrel.orderline:
relWeight = orderrel.number01.
linWeight = linWeight + relWeight.
END.
ttorderdtl.number01 = linWeight.
RUN lib\UpdateTableBuffer.p(input BUFFER OrderDtl:HANDLE, 'Number01',
linWeight).

END.
END.












Joe Rojas | Director of Information Technology | Mats Inc
dir: 781-573-0291 | cell: 781-408-9278 | fax: 781-232-5191
jrojas@... | www.matsinc.com Ask us about our clean, green and beautiful matting and flooring


This message is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the company.


[Non-text portions of this message have been removed]
Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.

Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.

Here's the tweaked wizard code that does the refresh:


private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
{
// ** Argument Properties and Uses **
// ** args.MethodName **
// ** Add Event Handler Code **

// ** Use MessageBox to find adapter method name
// EpiMessageBox.Show(args.MethodName)
switch (args.MethodName)
{
case "Update":
oTrans.Refresh();
// --above line is added tweak --
break;
}

}
If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.

Jim Kinneman
Encompass Solutions, Inc

--- In vantage@yahoogroups.com, "itwepicor" <itwepicor@...> wrote:
>
>
>
>
> Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
>
> Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
>
> Here's the tweaked wizard code that does the refresh:
>
>
> private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> {
> // ** Argument Properties and Uses **
> // ** args.MethodName **
> // ** Add Event Handler Code **
>
> // ** Use MessageBox to find adapter method name
> // EpiMessageBox.Show(args.MethodName)
> switch (args.MethodName)
> {
> case "Update":
> oTrans.Refresh();
> // --above line is added tweak --
> break;
> }
>
> }
>
The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?

--- In vantage@yahoogroups.com, "jckinneman" <jckinneman@...> wrote:
>
> If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
>
> Jim Kinneman
> Encompass Solutions, Inc
>
> --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> >
> >
> >
> >
> > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> >
> > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> >
> > Here's the tweaked wizard code that does the refresh:
> >
> >
> > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > {
> > // ** Argument Properties and Uses **
> > // ** args.MethodName **
> > // ** Add Event Handler Code **
> >
> > // ** Use MessageBox to find adapter method name
> > // EpiMessageBox.Show(args.MethodName)
> > switch (args.MethodName)
> > {
> > case "Update":
> > oTrans.Refresh();
> > // --above line is added tweak --
> > break;
> > }
> >
> > }
> >
>
Which fields from the order are not available? It is OK to look-up values from the part table since you are not updating it.

DEFINE VAR relWeight AS DECIMAL.
DEFINE VAR linWeight AS DECIMAL.
DEFINE VAR hedWeight AS DECIMAL.

FOR EACH ttorderhed:
/* find, calc & store release weight */
FOR EACH ttorderrel:
FIND FIRST part WHERE ttorderrel.company = part.company AND
ttorderrel.PartNum = part.PartNum no-lock no-error.
IF AVAIL part THEN DO:
relWeight = part.NetWeight * ttorderrel.OurReqQty.
ttorderrel.number01 = relWeight.
hedWeight = hedWeight + relWeight.
END.
ttorderhed.number01 = hedWeight.
END.

Jim Kinneman
Encompass Solutions, Inc
--- In vantage@yahoogroups.com, "itwepicor" <itwepicor@...> wrote:
>
>
>
> The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?
>
> --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> >
> > If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
> >
> > Jim Kinneman
> > Encompass Solutions, Inc
> >
> > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > >
> > >
> > >
> > >
> > > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> > >
> > > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> > >
> > > Here's the tweaked wizard code that does the refresh:
> > >
> > >
> > > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > > {
> > > // ** Argument Properties and Uses **
> > > // ** args.MethodName **
> > > // ** Add Event Handler Code **
> > >
> > > // ** Use MessageBox to find adapter method name
> > > // EpiMessageBox.Show(args.MethodName)
> > > switch (args.MethodName)
> > > {
> > > case "Update":
> > > oTrans.Refresh();
> > > // --above line is added tweak --
> > > break;
> > > }
> > >
> > > }
> > >
> >
>
Maybe all fields actually are there in the ttTables - I may have misspelled a field I was looking for, but still...

The ttTables in pre-processing seem "spotty" as to what they happen to provide access to, as opposed to post-processing where the ordinary tables contain committed & comprehensive data (as would be expected).

As evidence of what appears "spotty", here's full code to a simple pre-processing BPM example:

OUTPUT TO "c:\temp\dang.txt".
MESSAGE "code area #1".
FOR EACH ttorderhed:
MESSAGE "code area #2... " + STRING(ttorderhed.ordernum).
END.
MESSAGE "code area #3".
OUTPUT CLOSE.

CASE A: When this pre-processing BPM fires on a new order, it has no problem tapping the ttOrderHed temp table to get ordernum (which happens to be 0 at this early stage). The contents of the log file in this situation are as expected:

code area #1
code area #2... ttorderhed.ordernum = 0
code area #3

CASE B: But when it fires on an existing order that user is editing, then the log file reports only this!:

code area #1
code area #3

What the heck?! Where's "code area #2"?! It seems here in CASE B that pre-processing does not have a handle on ttOrderHed, whereas in CASE A it does.

My guess is that I need to modify the code to somehow explicitly address ttOrderHed to make it accessible - a way that will work for any state of order creation or editing.

Anybody know what code I might add to make it always able to get to "code area #2"...?





--- In vantage@yahoogroups.com, "jckinneman" <jckinneman@...> wrote:
>
> Which fields from the order are not available? It is OK to look-up values from the part table since you are not updating it.
>
> DEFINE VAR relWeight AS DECIMAL.
> DEFINE VAR linWeight AS DECIMAL.
> DEFINE VAR hedWeight AS DECIMAL.
>
> FOR EACH ttorderhed:
> /* find, calc & store release weight */
> FOR EACH ttorderrel:
> FIND FIRST part WHERE ttorderrel.company = part.company AND
> ttorderrel.PartNum = part.PartNum no-lock no-error.
> IF AVAIL part THEN DO:
> relWeight = part.NetWeight * ttorderrel.OurReqQty.
> ttorderrel.number01 = relWeight.
> hedWeight = hedWeight + relWeight.
> END.
> ttorderhed.number01 = hedWeight.
> END.
>
> Jim Kinneman
> Encompass Solutions, Inc
> --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> >
> >
> >
> > The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?
> >
> > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > >
> > > If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
> > >
> > > Jim Kinneman
> > > Encompass Solutions, Inc
> > >
> > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > >
> > > >
> > > >
> > > >
> > > > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> > > >
> > > > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> > > >
> > > > Here's the tweaked wizard code that does the refresh:
> > > >
> > > >
> > > > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > > > {
> > > > // ** Argument Properties and Uses **
> > > > // ** args.MethodName **
> > > > // ** Add Event Handler Code **
> > > >
> > > > // ** Use MessageBox to find adapter method name
> > > > // EpiMessageBox.Show(args.MethodName)
> > > > switch (args.MethodName)
> > > > {
> > > > case "Update":
> > > > oTrans.Refresh();
> > > > // --above line is added tweak --
> > > > break;
> > > > }
> > > >
> > > > }
> > > >
> > >
> >
>
You probably mentioned it but which method is the code running against? Depending on the method it may only have data under certain conditions, other times it may be empty at the time the method is called. It is not uncommon to need the same or very similar BPM on more than one method to cover all conditions and methods that may be called.

Jim Kinneman
Encompass Solutions, Inc

--- In vantage@yahoogroups.com, "itwepicor" <itwepicor@...> wrote:
>
> Maybe all fields actually are there in the ttTables - I may have misspelled a field I was looking for, but still...
>
> The ttTables in pre-processing seem "spotty" as to what they happen to provide access to, as opposed to post-processing where the ordinary tables contain committed & comprehensive data (as would be expected).
>
> As evidence of what appears "spotty", here's full code to a simple pre-processing BPM example:
>
> OUTPUT TO "c:\temp\dang.txt".
> MESSAGE "code area #1".
> FOR EACH ttorderhed:
> MESSAGE "code area #2... " + STRING(ttorderhed.ordernum).
> END.
> MESSAGE "code area #3".
> OUTPUT CLOSE.
>
> CASE A: When this pre-processing BPM fires on a new order, it has no problem tapping the ttOrderHed temp table to get ordernum (which happens to be 0 at this early stage). The contents of the log file in this situation are as expected:
>
> code area #1
> code area #2... ttorderhed.ordernum = 0
> code area #3
>
> CASE B: But when it fires on an existing order that user is editing, then the log file reports only this!:
>
> code area #1
> code area #3
>
> What the heck?! Where's "code area #2"?! It seems here in CASE B that pre-processing does not have a handle on ttOrderHed, whereas in CASE A it does.
>
> My guess is that I need to modify the code to somehow explicitly address ttOrderHed to make it accessible - a way that will work for any state of order creation or editing.
>
> Anybody know what code I might add to make it always able to get to "code area #2"...?
>
>
>
>
>
> --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> >
> > Which fields from the order are not available? It is OK to look-up values from the part table since you are not updating it.
> >
> > DEFINE VAR relWeight AS DECIMAL.
> > DEFINE VAR linWeight AS DECIMAL.
> > DEFINE VAR hedWeight AS DECIMAL.
> >
> > FOR EACH ttorderhed:
> > /* find, calc & store release weight */
> > FOR EACH ttorderrel:
> > FIND FIRST part WHERE ttorderrel.company = part.company AND
> > ttorderrel.PartNum = part.PartNum no-lock no-error.
> > IF AVAIL part THEN DO:
> > relWeight = part.NetWeight * ttorderrel.OurReqQty.
> > ttorderrel.number01 = relWeight.
> > hedWeight = hedWeight + relWeight.
> > END.
> > ttorderhed.number01 = hedWeight.
> > END.
> >
> > Jim Kinneman
> > Encompass Solutions, Inc
> > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > >
> > >
> > >
> > > The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?
> > >
> > > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > > >
> > > > If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
> > > >
> > > > Jim Kinneman
> > > > Encompass Solutions, Inc
> > > >
> > > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> > > > >
> > > > > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> > > > >
> > > > > Here's the tweaked wizard code that does the refresh:
> > > > >
> > > > >
> > > > > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > > > > {
> > > > > // ** Argument Properties and Uses **
> > > > > // ** args.MethodName **
> > > > > // ** Add Event Handler Code **
> > > > >
> > > > > // ** Use MessageBox to find adapter method name
> > > > > // EpiMessageBox.Show(args.MethodName)
> > > > > switch (args.MethodName)
> > > > > {
> > > > > case "Update":
> > > > > oTrans.Refresh();
> > > > > // --above line is added tweak --
> > > > > break;
> > > > > }
> > > > >
> > > > > }
> > > > >
> > > >
> > >
> >
>
ttOrderHed problem encountered in these methods where I've tried it:

SalesOrder.Update (pre-processing)
SalesOrder.MasterUpdate (preprocessing)

Is one of these other methods known as best for weight calcs?:

SalesOrder.ChangeSellingQtyMaster
SalesOrder.ChangeSellingQuantity
SalesOrder.ChangeSellingReqQty
SalesOrder.CheckSellingQuantityChange
SalesOrder.GetCalcQtyPref
SalesOrder.GetRows
SalesOrder.OnChangeOfFixedAmount
SalesOrder.SetCalcQtysPref
SalesOrder.UpdateExt

SalesOrder has 181 methods to choose from; ones above ones seem the most relevent. Argh.

--- In vantage@yahoogroups.com, "jckinneman" <jckinneman@...> wrote:
>
> You probably mentioned it but which method is the code running against? Depending on the method it may only have data under certain conditions, other times it may be empty at the time the method is called. It is not uncommon to need the same or very similar BPM on more than one method to cover all conditions and methods that may be called.
>
> Jim Kinneman
> Encompass Solutions, Inc
>
> --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> >
> > Maybe all fields actually are there in the ttTables - I may have misspelled a field I was looking for, but still...
> >
> > The ttTables in pre-processing seem "spotty" as to what they happen to provide access to, as opposed to post-processing where the ordinary tables contain committed & comprehensive data (as would be expected).
> >
> > As evidence of what appears "spotty", here's full code to a simple pre-processing BPM example:
> >
> > OUTPUT TO "c:\temp\dang.txt".
> > MESSAGE "code area #1".
> > FOR EACH ttorderhed:
> > MESSAGE "code area #2... " + STRING(ttorderhed.ordernum).
> > END.
> > MESSAGE "code area #3".
> > OUTPUT CLOSE.
> >
> > CASE A: When this pre-processing BPM fires on a new order, it has no problem tapping the ttOrderHed temp table to get ordernum (which happens to be 0 at this early stage). The contents of the log file in this situation are as expected:
> >
> > code area #1
> > code area #2... ttorderhed.ordernum = 0
> > code area #3
> >
> > CASE B: But when it fires on an existing order that user is editing, then the log file reports only this!:
> >
> > code area #1
> > code area #3
> >
> > What the heck?! Where's "code area #2"?! It seems here in CASE B that pre-processing does not have a handle on ttOrderHed, whereas in CASE A it does.
> >
> > My guess is that I need to modify the code to somehow explicitly address ttOrderHed to make it accessible - a way that will work for any state of order creation or editing.
> >
> > Anybody know what code I might add to make it always able to get to "code area #2"...?
> >
> >
> >
> >
> >
> > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > >
> > > Which fields from the order are not available? It is OK to look-up values from the part table since you are not updating it.
> > >
> > > DEFINE VAR relWeight AS DECIMAL.
> > > DEFINE VAR linWeight AS DECIMAL.
> > > DEFINE VAR hedWeight AS DECIMAL.
> > >
> > > FOR EACH ttorderhed:
> > > /* find, calc & store release weight */
> > > FOR EACH ttorderrel:
> > > FIND FIRST part WHERE ttorderrel.company = part.company AND
> > > ttorderrel.PartNum = part.PartNum no-lock no-error.
> > > IF AVAIL part THEN DO:
> > > relWeight = part.NetWeight * ttorderrel.OurReqQty.
> > > ttorderrel.number01 = relWeight.
> > > hedWeight = hedWeight + relWeight.
> > > END.
> > > ttorderhed.number01 = hedWeight.
> > > END.
> > >
> > > Jim Kinneman
> > > Encompass Solutions, Inc
> > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > >
> > > >
> > > >
> > > > The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?
> > > >
> > > > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > > > >
> > > > > If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
> > > > >
> > > > > Jim Kinneman
> > > > > Encompass Solutions, Inc
> > > > >
> > > > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> > > > > >
> > > > > > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> > > > > >
> > > > > > Here's the tweaked wizard code that does the refresh:
> > > > > >
> > > > > >
> > > > > > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > > > > > {
> > > > > > // ** Argument Properties and Uses **
> > > > > > // ** args.MethodName **
> > > > > > // ** Add Event Handler Code **
> > > > > >
> > > > > > // ** Use MessageBox to find adapter method name
> > > > > > // EpiMessageBox.Show(args.MethodName)
> > > > > > switch (args.MethodName)
> > > > > > {
> > > > > > case "Update":
> > > > > > oTrans.Refresh();
> > > > > > // --above line is added tweak --
> > > > > > break;
> > > > > > }
> > > > > >
> > > > > > }
> > > > > >
> > > > >
> > > >
> > >
> >
>
Typically I run a trace log on the transactions that I want to modify via a BPM. Looking through the trace long will list the methods that are called during the transaction. Not an exact science and doesn't always provide the complete picture. BPMs isn't always the solution, using embedded is sometimes the way to go.

Based on the systems I have worked on Epicor isn't the best nor the worst when it comes to documentation. From a positive standpoint they are working on it, something you can't say for all companies. Things are much improved from 5+ years ago when I started working on Epicor. As with most systems it takes time to get the feel of a product sort of like the time it takes to learn the culture of the company you are working at. Once you get an overall feel for Epicor the behavior is fairly consistent, again not perfect but usually.

Jim Kinneman


--- In vantage@yahoogroups.com, "itwepicor" <itwepicor@...> wrote:
>
>
>
> ttOrderHed problem encountered in these methods where I've tried it:
>
> SalesOrder.Update (pre-processing)
> SalesOrder.MasterUpdate (preprocessing)
>
> Is one of these other methods known as best for weight calcs?:
>
> SalesOrder.ChangeSellingQtyMaster
> SalesOrder.ChangeSellingQuantity
> SalesOrder.ChangeSellingReqQty
> SalesOrder.CheckSellingQuantityChange
> SalesOrder.GetCalcQtyPref
> SalesOrder.GetRows
> SalesOrder.OnChangeOfFixedAmount
> SalesOrder.SetCalcQtysPref
> SalesOrder.UpdateExt
>
> SalesOrder has 181 methods to choose from; ones above ones seem the most relevent. Argh.
>
> --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> >
> > You probably mentioned it but which method is the code running against? Depending on the method it may only have data under certain conditions, other times it may be empty at the time the method is called. It is not uncommon to need the same or very similar BPM on more than one method to cover all conditions and methods that may be called.
> >
> > Jim Kinneman
> > Encompass Solutions, Inc
> >
> > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > >
> > > Maybe all fields actually are there in the ttTables - I may have misspelled a field I was looking for, but still...
> > >
> > > The ttTables in pre-processing seem "spotty" as to what they happen to provide access to, as opposed to post-processing where the ordinary tables contain committed & comprehensive data (as would be expected).
> > >
> > > As evidence of what appears "spotty", here's full code to a simple pre-processing BPM example:
> > >
> > > OUTPUT TO "c:\temp\dang.txt".
> > > MESSAGE "code area #1".
> > > FOR EACH ttorderhed:
> > > MESSAGE "code area #2... " + STRING(ttorderhed.ordernum).
> > > END.
> > > MESSAGE "code area #3".
> > > OUTPUT CLOSE.
> > >
> > > CASE A: When this pre-processing BPM fires on a new order, it has no problem tapping the ttOrderHed temp table to get ordernum (which happens to be 0 at this early stage). The contents of the log file in this situation are as expected:
> > >
> > > code area #1
> > > code area #2... ttorderhed.ordernum = 0
> > > code area #3
> > >
> > > CASE B: But when it fires on an existing order that user is editing, then the log file reports only this!:
> > >
> > > code area #1
> > > code area #3
> > >
> > > What the heck?! Where's "code area #2"?! It seems here in CASE B that pre-processing does not have a handle on ttOrderHed, whereas in CASE A it does.
> > >
> > > My guess is that I need to modify the code to somehow explicitly address ttOrderHed to make it accessible - a way that will work for any state of order creation or editing.
> > >
> > > Anybody know what code I might add to make it always able to get to "code area #2"...?
> > >
> > >
> > >
> > >
> > >
> > > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > > >
> > > > Which fields from the order are not available? It is OK to look-up values from the part table since you are not updating it.
> > > >
> > > > DEFINE VAR relWeight AS DECIMAL.
> > > > DEFINE VAR linWeight AS DECIMAL.
> > > > DEFINE VAR hedWeight AS DECIMAL.
> > > >
> > > > FOR EACH ttorderhed:
> > > > /* find, calc & store release weight */
> > > > FOR EACH ttorderrel:
> > > > FIND FIRST part WHERE ttorderrel.company = part.company AND
> > > > ttorderrel.PartNum = part.PartNum no-lock no-error.
> > > > IF AVAIL part THEN DO:
> > > > relWeight = part.NetWeight * ttorderrel.OurReqQty.
> > > > ttorderrel.number01 = relWeight.
> > > > hedWeight = hedWeight + relWeight.
> > > > END.
> > > > ttorderhed.number01 = hedWeight.
> > > > END.
> > > >
> > > > Jim Kinneman
> > > > Encompass Solutions, Inc
> > > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > > >
> > > > >
> > > > >
> > > > > The durn ttxxx tables don't seem to expose all the fields/rows I need; that's at least one reason I'm still looking to iron out the post-processing aproach which posted sample code started me out on. Honestly, all I want to do is calculate release weight, line weight, and order weight for an order - certainly when order is saved, but also has to match reasonable user expectation that data behave properly throughout all screen entry & editing. That said, if you were yourself starting to build such a BPM from scratch, which route seems most workable to you? pre vs. post? tt vs. direct?
> > > > >
> > > > > --- In vantage@yahoogroups.com, "jckinneman" <jckinneman@> wrote:
> > > > > >
> > > > > > If the code you tried in the preprocessing BPM is pretty much the code you posted for the post processing you need to shift to working only with the ttxxx tables instead of the actual tables in pre-processing. Instead of using the tt table to look up a record in the actual table make the change to the tt table. The Base processing step which follows the pre-processing step will take the tt tables and update the actual tables with values from the matching TT table. After the base is complete any changes to the actual tables will be reflected in the UI and associated TT tables without a need for a refresh.
> > > > > >
> > > > > > Jim Kinneman
> > > > > > Encompass Solutions, Inc
> > > > > >
> > > > > > --- In vantage@yahoogroups.com, "itwepicor" <itwepicor@> wrote:
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > Yes, that makes sense. I had to run with sample code i found (& tweaked) which worked in post-processing but not in pre-processing... There may well have been a way to adjust the sample code to work in pre-processing, but new as i am to ABL i couldn't see how to do that. I'm guessing post-processing is also why user has to "Save" before they see calculations.
> > > > > > >
> > > > > > > Fortunately i did find other forum advice about how to fire an oTrans.Refresh() in script code, automatically after the "Save", using customization wizard to add a form event of AfterAdapterMethod for ordAdapter. So now whenever/however the order data is saved, it then immediately refreshes, and my users no longer get the annoying error saying "Row has been modified by another user and couldn't be updated. Please press the Refresh button and re-enter your changes." upon subsequent saves.
> > > > > > >
> > > > > > > Here's the tweaked wizard code that does the refresh:
> > > > > > >
> > > > > > >
> > > > > > > private void oTrans_ordAdapter_AfterAdapterMethod(object sender, AfterAdapterMethodArgs args)
> > > > > > > {
> > > > > > > // ** Argument Properties and Uses **
> > > > > > > // ** args.MethodName **
> > > > > > > // ** Add Event Handler Code **
> > > > > > >
> > > > > > > // ** Use MessageBox to find adapter method name
> > > > > > > // EpiMessageBox.Show(args.MethodName)
> > > > > > > switch (args.MethodName)
> > > > > > > {
> > > > > > > case "Update":
> > > > > > > oTrans.Refresh();
> > > > > > > // --above line is added tweak --
> > > > > > > break;
> > > > > > > }
> > > > > > >
> > > > > > > }
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>