JD Edwards C Business Function Skeleton Generator
This generator writes the header and source skeleton of a JD Edwards EnterpriseOne C business function (BSFN) that reads one record by key with JDB_FetchKeyed, returns a column to its data structure and raises a data dictionary error when the record is missing. It follows the 9.2 Tools API conventions for handles, Unicode strings and cleanup.
Fill in
From the table header file.
b550001.h
#ifndef __B550001_H
#define __B550001_H
#include <jde.h>
#include <f0101.h>
/* Paste the typedef generated from D550001 (Data Structure Design, Create Type Definition). */
#ifndef DATASTRUCTURE_D550001
#define DATASTRUCTURE_D550001
typedef struct tagDSD550001
{
MATH_NUMERIC mnAddressNumber;
JCHAR szNameAlpha[41];
JCHAR cErrorFlag;
} DSD550001, *LPDSD550001;
#define IDERRmnAddressNumber_1 1L
#define IDERRszNameAlpha_2 2L
#define IDERRcErrorFlag_3 3L
#endif
#if defined (JDEBFRTN)
#undef JDEBFRTN
#endif
#if defined (WIN32)
#if defined (WIN32)
#define JDEBFRTN(r) __declspec(dllexport) r
#else
#define JDEBFRTN(r) __declspec(dllimport) r
#endif
#else
#define JDEBFRTN(r) r
#endif
JDEBFRTN (ID) JDEBFWINAPI GetAddressBookName (LPBHVRCOM lpBhvrCom, LPVOID lpVoid, LPDSD550001 lpDS);
#endif /* __B550001_H */B550001.c
#include <b550001.h>
/* GetAddressBookName: fetch one F0101 record by key and return abalph. */
JDEBFRTN (ID) JDEBFWINAPI GetAddressBookName (LPBHVRCOM lpBhvrCom, LPVOID lpVoid, LPDSD550001 lpDS)
{
ID idReturnCode = ER_SUCCESS;
JDEDB_RESULT idJDBReturn = JDEDB_PASSED;
HUSER hUser = (HUSER) NULL;
HREQUEST hRequestF0101 = (HREQUEST) NULL;
KEY1_F0101 dsF0101Key;
F0101 dsF0101;
/* Validate pointers */
if ((lpBhvrCom == (LPBHVRCOM) NULL) || (lpVoid == (LPVOID) NULL) || (lpDS == (LPDSD550001) NULL))
{
jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, _J("4363"), (LPVOID) NULL);
return ER_ERROR;
}
lpDS->cErrorFlag = _J('0');
memset ((void *) &dsF0101Key, 0, sizeof (KEY1_F0101));
memset ((void *) &dsF0101, 0, sizeof (F0101));
/* Get a database user handle from the calling environment */
idJDBReturn = JDB_InitBhvr ((void *) lpBhvrCom, &hUser, (JCHAR *) NULL, JDEDB_COMMIT_AUTO);
if (idJDBReturn != JDEDB_PASSED)
{
return ER_ERROR;
}
/* Open the table on the index we fetch by, all columns */
idJDBReturn = JDB_OpenTable (hUser, NID_F0101, ID_F0101_ADDRESS, (NID *) NULL, (ushort) 0,
(JCHAR *) NULL, &hRequestF0101);
if (idJDBReturn == JDEDB_PASSED)
{
MathCopy (&dsF0101Key.aban8, &lpDS->mnAddressNumber);
idJDBReturn = JDB_FetchKeyed (hRequestF0101, ID_F0101_ADDRESS, (void *) &dsF0101Key, (short) 1,
(void *) &dsF0101, (int) FALSE);
if (idJDBReturn == JDEDB_PASSED)
{
jdeStrncpy (lpDS->szNameAlpha, dsF0101.abalph, DIM (lpDS->szNameAlpha) - 1);
}
else
{
lpDS->cErrorFlag = _J('1');
jdeErrorSet (lpBhvrCom, lpVoid, (ID) IDERRmnAddressNumber_1, _J("0002"), (LPVOID) NULL);
idReturnCode = ER_ERROR;
}
JDB_CloseTable (hRequestF0101);
}
else
{
idReturnCode = ER_ERROR;
}
JDB_FreeBhvr (hUser);
return idReturnCode;
}The typedef shown is an example: always generate the real one from your data structure in Object Management Workbench and paste it, so member names and lengths match. Take the index ID constant, the key structure and column member names from the table's generated header (for example f0101.h). Function and macro names follow the EnterpriseOne 9.2 Tools APIs; check the API reference for your Tools release if the build reports a signature mismatch.
Get your custom BSFN reviewed
Send us a C business function and we will check handle cleanup, Unicode handling and error reporting against the 9.2 Tools APIs.
Optional. The tool and every export work without this. No spam.
How to create it in EnterpriseOne
In Object Management Workbench add a data structure (D55xxxxx) with the key and output members, then a business function object (B55xxxxx) of type C, linking the function to that data structure. Use Create Type Definition on the data structure to get the typedef and paste it into the header, then replace the generated function body with this code. Build with BusBuild on the development client, test from a test application or the debugger, check in, and include the object in an update package so it reaches the enterprise server.
- Custom objects use system codes 55 to 59 so upgrades leave them alone
- The function name in OMW must match the C function name exactly
- Rebuild and redeploy the package after every change
What each API call does
JDB_InitBhvr gets a user handle tied to the caller's environment and transaction, with JDEDB_COMMIT_AUTO for auto commit. JDB_OpenTable takes the user handle, the table NID, the index ID, an optional column list and count, an optional data source override and returns a request handle. JDB_FetchKeyed takes the request handle, index, key structure, the number of key fields to use, the record buffer and a lock flag. jdeErrorSet attaches a data dictionary error to a data structure member so the calling application highlights it. JDB_CloseTable and JDB_FreeBhvr release the handles on every path.
Worked example
With the defaults, GetAddressBookName receives mnAddressNumber 4242, copies it into the F0101 key structure with MathCopy, fetches on index ID_F0101_ADDRESS and copies ABALPH into szNameAlpha with jdeStrncpy, bounded by the DIM of the target minus one for the terminator. If the address number does not exist it sets cErrorFlag to 1, raises error 0002 against the address number member and returns ER_ERROR, so an interactive form shows the error on the right field and a UBE can test the flag.
Common mistakes
Forgetting JDB_CloseTable or JDB_FreeBhvr on an error path leaks handles and eventually hurts the call object kernel. Using strcpy or char instead of jdeStrncpy and JCHAR breaks Unicode builds. Passing the wrong number of keys to JDB_FetchKeyed silently fetches a different record on a multi-field index. Hand typing the typedef instead of generating it leads to size mismatches that crash at runtime. And for simple reads, consider whether an existing Oracle business function, a table I/O in Named Event Rules or an orchestration data request already does the job.
Frequently Asked Questions
What is a business function in JDE?
A business function is reusable logic, written in C or in Named Event Rules, that applications, UBEs and orchestrations call through a data structure. Oracle ships thousands of them (for example the F0101 and F4211 master business functions). Custom ones are created in OMW with 55 to 59 system codes, built with BusBuild and deployed in packages.
When should I write a C business function instead of NER?
Use C when you need pointer work, caching, complex loops over many records, or APIs that Named Event Rules cannot call. Use NER for simple logic because it is easier to maintain and retrofit. Many teams default to NER and keep C for performance-sensitive or system-level code.
Where do I find the index ID and key structure for a table?
In the generated table header, for example f0101.h, which defines NID_F0101, the index ID constants (ID_F0101_ADDRESS for the primary index) and the key structures KEY1_F0101, KEY2_F0101 and so on, with lower case column members such as aban8. Open it from the include folder of your development client.
How do I debug a C business function?
Build it with debug information on the development client, attach the Visual Studio debugger to the client process that runs business functions, set a breakpoint and run the calling application. On the enterprise server, turn on jdedebug logging and read the jde and jdedebug logs for the call object kernel that ran it.
If you want developers and analysts to ask what a JD Edwards business function does, or where it is called, in plain English on your own servers, we can index your custom code for that.
Related Tools
JD Edwards Orchestrator and AIS REST Call Generator
Fill in your AIS host, orchestration name and inputs to get a working Python requests script and curl commands that call a JD Edwards EnterpriseOne 9.2 orchestration.
OracleJD Edwards Object Promotion Request Template
A change request form for promoting JDE objects through OMW project statuses and path codes, with testing evidence, package plan and rollback.
OracleJD Edwards Package Build and Deployment Checklist
Step-by-step checklist for building and deploying JDE packages: pre-build checks, build, deployment, verification and rollback.
OracleJD Edwards EnterpriseOne 9.2 Upgrade Retrofit Effort Calculator
Estimate retrofit and test hours, cost and duration for a JD Edwards EnterpriseOne upgrade to 9.2 from your counts of modified objects, and see how much replacing mods with UDOs saves.
More Developer Tools tools
See all- JD Edwards Orchestrator Groovy Custom Request Script Generator
- JD Edwards UDC Lookup SQL Generator (F0004, F0005)
- JD Edwards F0911Z1 Journal Entry Batch Input SQL Generator
- JD Edwards Received Not Vouchered SQL Generator (F43121, F4311)
- JD Edwards F3002 Multi-Level BOM Explosion SQL Generator
- SAP Sales Order ABAP SELECT Generator (VBAK, VBAP, VBFA)
- SAP Sales Order Create BAPI ABAP Generator (BAPI_SALESORDER_CREATEFROMDAT2)
- SAP ABAP Open Items SELECT Generator
- SAP ACDOCA SQL Query Generator
Keep exploring
Free tools
- JD Edwards EnterpriseOne Private AI Layer Blueprint GeneratorFill in your JD Edwards EnterpriseOne version, database, hosting and users to get a shareable architecture plan for a private, on-prem AI assistant.
- JD Edwards EnterpriseOne AI Assistant Sizing and Value CalculatorEstimate peak load, GPUs, index size, hours saved and payback for an on-prem AI assistant on JD Edwards EnterpriseOne.
- JD Edwards EnterpriseOne Core Table ReferenceSearchable list of the JD Edwards EnterpriseOne tables you query most often, with column prefix and the key fields to filter on.
ERP fixes and how-tos
- How to Add a Private AI Layer to JD Edwards EnterpriseOne On-PremAdd a private AI layer to JD Edwards EnterpriseOne: AIS data service, Orchestrator, Security Workbench mapping, a local model and human approval.
- JD Edwards business function (BSFN) errors: how to diagnose themJD Edwards business function errors range from missing package builds to unhandled C exceptions. Here is how to isolate which BSFN failed and why, using jde.log and Object Librarian.
- JD Edwards table conversion: how it works and how to run oneWhat a JD Edwards table conversion does to a JDE table's structure and data, when it runs in a package build, and how to run or design one manually.
Runs with your ERP
- Vertex Tax Connectors with JD Edwards EnterpriseOneHow Vertex calculates sales, use and VAT tax for JD Edwards EnterpriseOne and World, plus Oracle EBS and Cloud ERP: integration model, flows, setup, pitfalls.
- RF-SMART and JD Edwards EnterpriseOne: Barcode Scanning and Mobile WMSHow RF-SMART connects barcode scanning to JD Edwards EnterpriseOne and World: integration method, data flows, setup steps, pitfalls and where private AI helps.
- Oracle CPQ and JD Edwards EnterpriseOne: quote to sales orderHow Oracle CPQ integrates with JD Edwards EnterpriseOne: customer data into quotes, sales orders created from quotes, and status back, with setup and pitfalls.
AI on your ERP
- AI for JD Edwards EnterpriseOne Manufacturing, Without Leaving the F-Tables ExposedGrounded AI over JD Edwards EnterpriseOne Manufacturing: work orders, routings, and Orchestrator data, answered on-prem without sending F-table data to a public model.
- AI for JD Edwards Inventory Management and Shop Floor ManufacturingAI on JD Edwards EnterpriseOne inventory and manufacturing: item ledger, work orders, MRP messages and cost variances, answered in plain English on your own servers.
Integrations
- How to add AI agents to JD Edwards EnterpriseOneHow to add AI agents to JD Edwards EnterpriseOne: Orchestrator and AIS as the tool layer, read-only first, human approval on writes, on-prem models.
- How to use ChatGPT with JD Edwards EnterpriseOneHow to use ChatGPT with JD Edwards EnterpriseOne: custom GPT actions over AIS, exports versus live access, enterprise data controls, and private alternatives.