How-toEpicor KineticBPM / Updating Data

Epicor BPM: Update a UD Field, a PO Cost or a Table, and Update vs UpdateExt

Question
epicor bpm update ud field

Also searched as

  • epicor bpm update table by query
  • epicor bpm update purchase order cost
  • epicor update vs updateext
  • epicor record in process unable to update
  • epicor bpm writeentry

Short answer

From a BPM you can update data three ways: change the incoming temp table row (best for the record being saved), call a business object Update or UpdateExt on another record, or write through Db and call Validate. UpdateExt returns errors in the dataset instead of throwing. A record in process error means the record is already being saved in the same call chain.

Applies to: Epicor Kinetic and 10.x. Use business object services for changes that must run business rules; direct Db writes bypass them.

How to update data from a BPM

  1. 1If the record is the one being saved, set the field on the ttTable row in a Pre or Post-Processing directive instead of calling another update.
  2. 2For a UD field, use the UD field helper on the row or the indexer with the column name, such as Character01.
  3. 3For another record, call the right business object: GetByID, change the row, set RowMod to U, then Update or UpdateExt.
  4. 4Prefer UpdateExt when you want to handle errors yourself, and check the returned error flag.
  5. 5For bulk changes, loop over a query result and call the service for each, in small batches.
  6. 6For a table with no service (such as a UD table), use Db, change the rows and call Db.Validate inside a transaction scope.
  7. 7Test with a record locked by another user to see the behaviour.

Updating a UD field and the incoming row

The cleanest update is on the data already in the call. In a Pre-Processing directive on SalesOrder.Update the header is in ttOrderHed, so setting the UD column there saves it with the order, in the same transaction, with no second call. Filter rows by Added or Updated.

Writing a UD field on a different record needs a service call or Db. If a row is also in the dataset being saved, the saved values can overwrite what you wrote, so do not update the same record two ways.

foreach (var hed in ttOrderHed.Where(r => r.Added() || r.Updated()))
{
    hed["Character01"] = "Approved";
}

Update vs UpdateExt, and updating a purchase order cost

Update(ref ds) throws a business object exception on the first validation error. UpdateExt(ref ds, out errorsOccurred) collects errors into the dataset error table and returns a flag, which suits bulk jobs where one bad record should not stop the rest. Use Update when you want failure to abort.

To change a PO line cost, load the PO with the PO service, change the unit cost on the detail row, set RowMod to U, and call Update. Respect the PO's release or approval state, because the service will reject changes to a closed or approved line. Never write cost columns directly with Db if you need the system to recalculate totals and approvals.

bool errors;
this.CallService<Erp.Contracts.POSvc>(svc =>
{
    var ds = svc.GetByID(poNum);
    var line = ds.PODetail.FirstOrDefault(l => l.POLine == poLine);
    if (line != null)
    {
        line.RowMod = "U";
        line.DocUnitCost = newCost;
        svc.UpdateExt(ref ds, out errors);
    }
});

Record in process, update by query, and logging

A record in process or unable to update message appears when your update targets a record already being saved in the same chain, or locked by another session. Fix by changing the incoming row instead, moving the update to a Standard post-processing directive that runs after the commit, or using an In-Transaction approach consistently. Do not retry in a loop.

Update by query means selecting a set with Db or a BAQ and then updating each through the service or Db. For logging what you did, writing to the Windows event log with EventLog.WriteEntry works on-prem but needs the event source to exist and permission, and is not available in cloud. A UD table log, or a PublishInfoMessage during testing, is safer.

Try it here, free

Epicor UD Table Design Worksheet

Open full tool

An editable worksheet for planning user defined tables and fields before you build them in Epicor, with a column count and key check.

Common pitfalls

  • !Calling Update on the same record you are already saving, causing recursion or record in process.
  • !Writing cost or status columns with Db and skipping business rules.
  • !Not setting RowMod to U, so the service ignores the change.
  • !Using Update in a loop where one error should not stop the batch.
  • !Relying on EventLog.WriteEntry in cloud tenants.

How an ERP-grounded AI assistant handles this

An assistant can review a BPM for the typical traps: a second update to the same record, a missing RowMod, a direct Db write to a business-rule table. It drafts and explains; your developer tests in a pilot company. Private on-prem models keep the code in-house.

Frequently asked questions

What is the difference between Update and UpdateExt in Epicor?

Update throws an exception on error. UpdateExt returns an error flag and puts messages in the dataset, so your code can continue or handle them. UpdateExt suits batch work.

How do I update a UD field from a BPM?

Set it on the ttTable row in the directive for the record being saved. For another record, load it through the service, change the UD column, set RowMod to U and call Update.

Why do I get record in process or unable to update?

The record is already being saved in the same call, or is locked. Change the incoming row, move the update to a post-processing Standard directive, or avoid a second update of the same record.

Can I update a table directly with Db?

Yes, for tables with no business rules such as UD tables. Use a transaction scope and call Db.Validate. For orders, POs and jobs use the service so rules run.

Related

Advanced

Epicor BPM TxScope: Standard vs In-Transaction Directives and When Functions Need a Transaction

A transaction scope groups database writes so they commit or roll back together. In Epicor BPM, a Standard directive runs outside the business object's database transaction, while an In-Transaction directive runs inside it, so an exception rolls back the whole save. In custom code you open your own scope with IceContext.CreateDefaultTransactionScope and call Complete.

How-to

Epicor BPM Custom Code Examples: Set, Query, Validate, Call and Refresh

A BPM Custom Code block is a C# snippet that runs inside a Method or Data directive and can read the incoming temp tables (ttOrderHed, ttOrderDtl and so on), query the database through Db, and call business objects. Below are tested-pattern examples for setting a field, looking up a record, validating and raising an error, and calling a service, plus how to make the client see data you changed.

How-to

Epicor Kinetic UD Tables and UD Fields: Setup, Studio Binding, BAQ and Security

UD tables (UD01, UD02 and so on) are Epicor's pre-built user-defined tables with a fixed set of key and data columns that you label and expose through a menu program. UD fields are extra columns on standard tables like OrderHed. Both are set up in system maintenance, shown in screens with Application Studio, and readable in BAQs.

Error fix

Epicor BPM Runtime Error: Where to Look and How to Fix It

A BPM runtime error is an exception thrown while a directive runs, so the user's save or action fails. Find the directive name and line in the client trace or server log, then check the usual causes: a null reference in custom code, a directive that no longer compiles after a change, conflicting directive order, or a lock or validation error from a nested update.

Error fix

Fixing Epicor BusinessObjectException: BPM Directive Errors

A BusinessObjectException that says "A Business Process Management (BPM) directive has raised the following error" means a directive on that business object stopped the transaction, either deliberately via a Raise Exception widget or accidentally via an unhandled .NET error in Custom Code. Expand the InnerException on the error dialog to see the real message and the directive name, then open BPM Designer for that object and method to find the widget that fired.

How-to

Fixing a Slow Epicor BAQ (Business Activity Query)

A slow BAQ in Epicor is usually caused by unindexed join columns, a subquery or calculated field forcing a table scan, or the BAQ pulling far more rows than the dashboard actually displays before filtering client-side. Fix it by reading the SQL Server execution plan Epicor generates, moving filters into the BAQ criteria instead of the dashboard filter panel, and replacing subqueries with joins where possible.

AI for ERP

AI for Epicor Kinetic, Beyond What Prism Covers

Add AI to Epicor Kinetic beyond Prism: private LLM over BAQs, BPM data, and REST v2, on-prem or private cloud, with honest guidance on when Prism already covers you.

Stuck on Epicor Kinetic?

Talk to engineers who work inside Epicor Kinetic every week, and who build private AI that answers these questions from your own ERP data.

Keep exploring

Free tools

ERP fixes and how-tos

Guides

AI on your ERP

Integrations

Comparisons

Software