Stephen Smith's Blog

All things Sage 300…

How to Run Customized Sage 300 Screens from Sage CRM

with 2 comments


From the Sage 300 ERP to Sage CRM integration there is the ability to run a number of Sage 300 ERP screens. These are the older VB screens being run as ActiveX controls from the IE browser. Not to be confused with the newer Quote to Order web based screens. A common request is how to customize these screens to you run the customized screen from Sage CRM rather than the base screen.

This blog posting covers how to run customized screens from Sage CRM. As a bonus, as part of this it also shows how to wrap a Sage 300 screen, so that it handles version updates seamlessly and doesn’t require you to re-compile your solution when we release a new version of the base screen. As a result this mechanism requires you use VB to wrap the base control for deployment. The ideas presented here probably can be ported to other programming systems, but it may not be easy.

A sample project that wraps Order Entry is located on Google Drive here. This project will be used for most of the examples in the document, so feel free to load it up and follow along.  In order to view the wrapper, simply unzip the file, and open up the CRMOEOrderUI.vbp.

Create the Wrapper

The following instructions will show the basic steps on how to create a Sage 300 UI Browser Wrapper.  The wrapper can then be referenced by an ASP page. There should be a constant interaction between the UI, the wrapper, and the ASP page (ie. UI calls UI_OnUIAppOpened in the wrapper, the wrapper raises the UIWasUnLoaded event to the ASP page, and the ASP page in turn catches the event, and closes the window containing the wrapper (and attached Accpac UI).


1. Open up Visual Basic and select a new Active X Control. Click Open.


2. Go to Project/ References, and select ACCPAC COM API Object, ACCPAC Data Source Control, ACCPAC Signon Manager, VB IObjectSafety Interface, ACCPAC Application Installer, and ACCPAC Session Manager.


3. The project name determines the name of the wrapper (OCX).  In this case, the wrapper name will be “eCRMOEOrderUI”.

4. The name that you give the UserControl should be descriptive of what is contained on it.  In this case, give the UserControl the same name as the Accpac UI that is wrapped (in this case, OEOrderUI).


5. When you are coding refer to the Accpac UI as “UserControl” (ie. UserControl.Width, UserControl.height).

6. We use the VBControlExtender to wrap the Order Entry OCX control dynamically when UserControl_Show is called (see code for UserControl_Show accompanied with this document). When referencing elements and methods within the Order Entry OCX control you would use ctlDynamic.object. The control is installed and opened using the AccpacOcxRegHelper.CLS which makes entries in to the registry that allows the VBControlExtender to reference the control by name as opposed to CLSID which is returned from Roto.


7. Now you are ready to begin writing the code that will catch the events thrown by the Accpac UI, and raise your own events to the ASP that will contain your wrapper.

8. Go into your code view and begin instantiating your events, objects, and variables.

9. Begin by declaring your objects that are going to handle events thrown by the AccpacDataSource controls in the related Accpac OCX controls.  In this case, event handlers of the AccpacOE1100 class are being declared so that they can detect the events thrown by the class.


10. Next, declare the events that you will want to raise to the ASP page.


11. Declare your public variables


12. Declare your remaining variables.  In this case, mSignonMgr is going to be used to sign on the Accpac UI with the signon manager so that the signon screen does not keep popping up every time that the UI is loaded.  mlSignonID is going to be the signon ID.


13. Outline your functions that will be called by the ASP Page.  In this case, the ASP page will give the values that are to be used to populate the UI, or to insert the customer ID into the UI’s customer field for a new customer quote.

14. Next, list out the events that can be called by the UI AccpacDataSources.  In the screenshot below, you can see that the wrapper is checking the eReason variable being passed, and depending on what eReason is being passed, a different event will be raised to the ASP page (AddNew, Delete etc) in the RaiseEventEX sub.



15. Other functions are also called by the Accpac UI. The wrapper will be notified of these events through ctlDynamic_ObjectEvent (see below). Once the UI has opened ctlDynamic_ObjectEvent is called with an event name of  “OnUIAppOpened” and a private sub UI_OnUIAppOpened is called and objects in the wrapper are initialized, and the UIWasLoaded event is raised to the ASP page notifying it that the UI has been opened.

16. Finally, define the Get properties that are available to the ASP page so that it can resize its windows when the UI has been loaded onto the ASP page.  In this case, the ASP page will resize its windows to be the same width, height, and unit of measurement as the UI.


17. Now, you have successfully entered all the code that the wrapper will use to receive the function calls from the UI, as well as raise the events to the ASP page.

Customize the Sage CRM ASP Page

You now have a wrapped OCX now you can follow the ASP page in Sage CRM (for example, OE_OrderUI.asp as follows) to call your customized OCX.


Then it will open the OE Order Entry screen for order ORD000000000076.

In OE_OrderUI.asp file, it has following code:



eCRMOEOrderUI raises the following events:

UIWasLoaded(), UIWasUnLoaded(), AddNew(), Delete(), Update(), FieldChange(), Init(), Read(), Fetch()

eCRMOEOrderUI exposes the following Properties:

UIWidth(Read Only), UIHeight(Read Only), TwipsPerPixelX(Read Only), TwipsPerPixelX(Read Only)

eCRMOEOrderUI exposes the following Functions:

PopulateUI(OrderID As String, CustomerID As String);

CreateNewQuote(CustomerID As String);


<SCRIPT for=”eCRMOEOrderUI” Event=”UIWasLoaded()”>

var width  = eCRMOEOrderUI.UIWidth / eCRMOEOrderUI.TwipsPerPixelX;

var height = eCRMOEOrderUI.UIHeight / eCRMOEOrderUI.TwipsPerPixelY;

if ((BrowserDetect.browser==”Explorer”) && (BrowserDetect.version >= 7))


width  += 35;

height += 130;




width  += 35;

height += 100;


var left = (screen.width – width) / 2;

var top = (screen.height – height) / 2;

window.resizeTo(width, height);


PopulateUI(<%=EnESCDocNum%>, <%=EnESCCustomer%>);

width  = eCRMOEOrderUI.UIWidth  / eCRMOEOrderUI.TwipsPerPixelX;

height = eCRMOEOrderUI.UIHeight / eCRMOEOrderUI.TwipsPerPixelY;

BorderWidth  = ClientWidth()  – width;

BorderHeight = ClientHeight() – height;

bLoaded = true;




Hopefully you find this helpful in customizing Sage 300 ERP screens. Even if you don’t run them from Sage CRM, not having to re-build them for each Product Update can save you some time.

Written by smist08

October 11, 2014 at 4:14 pm

2 Responses

Subscribe to comments with RSS.

  1. […] Introduction From the Sage 300 ERP to Sage CRM integration there is the ability to run a number of Sage 300 ERP screens. These are the older VB screens being run as ActiveX controls from the IE bro…  […]

  2. That’s really neat Stephen, thanks for this insight.


    October 15, 2014 at 2:00 am

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: