# Sage 100 Business Object Interface (BOI): Working VBScript Example

> Source: https://netray.co/erp-help/sage-100-business-object-interface-vbscript-example
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

The Sage 100 Business Object Interface exposes the same business objects the screens use through a COM object called ProvideX.Script. You initialise it with the MAS90\Home path, create an SY_Session object, log on, set the company, then create a business object such as AR_Customer_bus and read or write through it. Because it runs the real business logic, it is the supported way to write data in code, unlike direct file or ODBC writes.

## Kind

how-to

## System

small-erp

## Erp

Sage 100

## Module

Business Object Interface (BOI) / Integration

## Query

Sage 100 business object interface VBScript example

## Alternate Queries

- Sage 100 BOI ProvideX.Script SY_Session example
- how to create a sales order in Sage 100 with code
- Sage 100 COM automation nSetKeyValue nWrite
- Sage 100 BOI error sLastErrorMsg

## Applies To

Sage 100 Standard, Advanced and Premium (formerly Sage 100 ERP / MAS 90 / MAS 200), 32-bit and 64-bit clients; behaviour of the COM class depends on the installed version

## Steps

### Connect to Sage 100 through BOI and read a customer

**Items:**

On the machine that will run the script, make sure a Sage 100 workstation install is present, because the COM class is registered by the workstation setup. A server-only install is not enough for client scripts.

In Sage 100 Library Master, give the logon user a role that allows external access (look for the Allow External Access task permission in Role Maintenance, and the matching user-level setting). Without it the logon fails even with a valid password.

Create the ProvideX.Script object and call Init with the full path to the MAS90\Home folder as it appears to the machine running the script (a UNC path is safest).

Create the session with NewObject("SY_Session"), call nLogon, then nSetCompany with the company code and nSetDate and nSetModule for the module whose objects you will use.

Create the business object with NewObject("AR_Customer_bus", oSS), set the key with nSetKeyValue for each key segment, then call nSetKey to load the record.

Read fields with nGetValue (the field name carries the dollar suffix for string fields) and write with nSetValue followed by nWrite. Always test the return value; 1 means success and 0 means failure.

On any 0 return, read oSS.sLastErrorMsg for the session, or the business object's own sLastErrorMsg, and log it before you continue.

Release the objects in reverse order and set them to Nothing so the session and licence are freed.

## Sections

### A minimal read example

**Body:**

The pattern below logs on, selects a company, loads customer 01-ABF and prints the name and balance. The same shape applies to nearly every BOI object: AR_Customer_bus, AR_Invoice_bus, SO_SalesOrder_bus, IM_Item_bus, PO_PurchaseOrder_bus and others. The object names follow module prefix, entity, then _bus.

Two details trip people up. First, string fields carry a trailing dollar sign and numeric fields do not (CustomerName$ versus CurrentBalance). Second, nGetValue returns its result through a by-reference argument, so in VBScript you pass a variable rather than using the return value of the call.

**Code:**

Set oScript = CreateObject("ProvideX.Script")
oScript.Init "\\server\Sage\Sage 100 Advanced\MAS90\Home"
Set oSS = oScript.NewObject("SY_Session")
If oSS.nLogon() = 0 Then WScript.Echo oSS.sLastErrorMsg : WScript.Quit
oSS.nSetCompany "ABC"
oSS.nSetDate "A/R", "20260131"
oSS.nSetModule "A/R"
Set oCust = oScript.NewObject("AR_Customer_bus", oSS)
oCust.nSetKeyValue "ARDivisionNo$", "01"
oCust.nSetKeyValue "CustomerNo$", "ABF"
If oCust.nSetKey() = 1 Then
  oCust.nGetValue "CustomerName$", sName
  oCust.nGetValue "Balance", nBal
  WScript.Echo sName & " " & nBal
Else
  WScript.Echo oCust.sLastErrorMsg
End If

### Writing a record safely

**Body:**

For a new record call nSetKeyValue for the key segments, then nSetKey, which returns a value indicating the key does not exist yet; then use nSetValue for each field and finish with nWrite. For an existing record, nSetKey loads it and you call nSetValue then nWrite to update. If nWrite returns 0, the record is not saved, and sLastErrorMsg normally names the field that failed validation.

Because BOI runs the same validation as data entry, it enforces required fields, valid terms codes, credit-limit rules and the company's own UDF validation. That is the main reason to prefer it over writing directly to the .M4T data files or through ODBC. Direct file writes skip sort-file maintenance, audit trails and posting dependencies, and can corrupt data that Sage then reports as damaged files.

For sales orders, use SO_SalesOrder_bus for the header and its Lines child object (reached through the business object's GetChildHandle method) to add detail lines before the header write. Set SalesOrderNo to the next number via the object's own number-assignment logic instead of inventing one, so you do not collide with users entering orders at the same time.

### Why logon and Init fail

**Body:**

The most common failures are path and bitness. Init needs a folder the script's user account can read, and a scheduled task running as a service account often cannot see mapped drive letters, so use a UNC path. A 32-bit script host talking to a 64-bit-only install, or the reverse, produces a CreateObject failure; run the script with the matching WScript or CScript from SysWOW64 or System32.

If CreateObject itself fails, the COM class is not registered on that machine; run the workstation setup there. If nLogon returns 0, read sLastErrorMsg: typical text points to an invalid user or password, a user without external access, a company in the middle of an update, or a licence limit. Every BOI session consumes a Sage 100 user licence for as long as it is open, so unreleased sessions from crashed scripts can exhaust licences.

### Alternatives and when to use them

**Body:**

For reporting, ODBC with the Sage 100 driver is simpler and read-only, and fits Excel, Power BI and Crystal. For bulk imports of tabular data, the built-in Visual Integrator imports (Library Master, Main, Visual Integrator) call the same business logic and need no code. For larger programmatic integrations, Sage also publishes later web-service style options on newer releases, so check the release you run.

BOI is the right tool when the logic must be scripted: creating orders from a web store, posting a nightly batch from another system, or synchronising customers. Expect to write retry and error logging yourself, because the interface returns terse text.

## Pitfalls

- Writing to the data files or through ODBC instead of BOI: it bypasses validation and can corrupt sort files and break audit trails.
- Using a mapped drive letter in Init for a scheduled task: the service account does not see your drive mappings.
- Forgetting the dollar suffix on string field names, which returns empty values with no obvious error.
- Ignoring return values: BOI methods return 0 on failure and a script that keeps going will half-write documents.
- Leaving sessions open after errors, which holds Sage 100 licences until the process ends.
- Setting company code or module date inconsistently, so records are written with the wrong posting period or date.

## Ai Angle

An assistant grounded in the Sage 100 data dictionary can draft the BOI script for a stated task, check field names and types against the dictionary (including UDFs), and explain a returned sLastErrorMsg. Netray's ERPray approach is read-first: it answers questions over the data with the query shown, and any write goes through the business object layer with human approval rather than through direct file access. It does not replace testing the script against a copy company.

## Faq

### Is BOI the same as the Sage 100 ODBC driver?

**Answer:** No. ODBC is read-only access to the data tables for reporting and tools like Excel or Power BI. BOI is a COM interface to the business objects, so it can read and write while running the same validation and posting rules as the screens.

### Do I need a Sage 100 licence for each BOI script?

**Answer:** A BOI session logs on as a Sage 100 user and consumes a user seat while it is open. Plan for that in schedule design, and always close the session. Check your licence agreement for any rules on integration users.

### Why does CreateObject("ProvideX.Script") fail?

**Answer:** The COM class is registered by the Sage 100 workstation install, so a machine without that install, or a bitness mismatch between the script host and the install, fails at that line. Install the workstation setup and run the matching 32-bit or 64-bit script host.

### Can I use PowerShell or C# instead of VBScript?

**Answer:** Yes. Any COM-capable language can create ProvideX.Script. The method names and by-reference argument behaviour stay the same, but by-reference outputs need extra care in .NET, where a variant or ref parameter is required.

## Search terms

Sage 100 business object interface, Sage 100 BOI example, ProvideX.Script CreateObject, SY_Session nLogon, Sage 100 VBScript, AR_Customer_bus, SO_SalesOrder_bus, Sage 100 integration code, Sage 100 nSetKeyValue, MAS 90 BOI

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
