An application that is integrated with QuickBooks via the SDK may need to be notified about actions occurring in a QuickBooks company file, including actions that add or change data values, at the time when the actions occur. These actions are referred to as events, and the SDK recognizes three types of events:
Any QuickBooks list or transaction object that is supported by the SDK is also supported by the event notification framework, and can be a source of data events.
Your application can receive notification about data events whether the changes are made directly in the QuickBooks UI or programmatically by an integrated application.
The event mechanism described on this page operates only when a company file has been opened in interactive mode through the QuickBooks UI. If QuickBooks is run in auto-login mode, also called unattended mode, event notifications are not sent to subscribing applications. (Auto-login mode is used where applications access company files without the QuickBooks UI running.)
Note
Note
Events are not supported for QuickBooks Simple Start edition or through QuickBooks Web Connector.
For all three types of events, the workflow is the same:
The application receiving the events handles them in a callback, as described later on this page.
To achieve the behavior described above, your development process should include all the following steps, in approximately the listed order:
In addition to developing the callback logic and the subscription request message, you need to consider how the callback portion of your application will be registered at deployment time, and how the subscription request will be sent to QuickBooks. The key point here is that the event-handling (callback) logic must be registered with its CLSID or PROGID before the subscription request is sent. A typical way to do this is described below. The documentation you supply with your application should instruct the QuickBooks installer/administrator how to perform the installation and authorization:
Again, the key points are to prepare a deployment procedure that registers the callback portion of your application before the subscription request is issued, and to supply the QuickBooks administrator/installer with sufficient documentation do the correct things during installation and setup.
In order to process events, your callback application must implement the required COM interface and it must account for the range of expected event behaviors. The COM interface is defined in the file SDKEvent.dll, located in the QuickBooks install directory.
In addition to implementing the callback class, you must import the required event library into the project that implements the callback.
1 | #import "sdkevent.dll" |
in the header file for the callback.
In Microsoft Visual Studio, remember to specify the QuickBooks executable path for the project. The methods for doing this is different for Visual Studio 6.0 and Visual Studio.NET:
The event notification framework uses COM to notify applications about events. Accordingly, for an application to receive notification messages about events it subscribes to, it must contain in implementation of the SDK’s COM interface for events – IQBEventCallback. As already mentioned above, the callback .exe must be registered before and event subscription requests are sent to QuickBoooks.
Note
Note
In-process COM servers are not allowed, only out-of-process local servers. Therefore, the requirement to implement the callback class in an .exe, not in a DLL.
You need to implement your callback logic in the Inform method defined in the the IQBEventCallback interface (IQBSDKCallback::Inform). The inform method returns the event notification string in XML format. The following is the virtual method signature for IQBSDKCallback::Inform:
1 | virtual HRESULT stdcall inform (/*[in]*/ BSTR eventXML ) = 0; |
If you use Visual Basic, you need to implement it by adding these lines,
1 2 | Implements QBSDKEVENTLib.IQBEventCallback Public Sub IQBEventCallback_inform(ByVal eventXML As String) |
followed by your callback implementation code.
Some other things to keep in mind as you develop a callback implementation are covered below.
In the subscription code you must supply the class ID (CLSID) or PROGID for the callback class. QuickBooks uses the CLSID/PROGID to invoke your application’s callback method when a subscribed event occurs.
In some programming languages you can use the PROGID instead of CLSID. For VB projects, the PROGID is the ’<Name of Project>.<Name of COM class>.
Note
Note
If you use CLSIDs in VB, you must set the VB project properties for binary compatibility or this value will change every time you compile and the CLSID won’t match the one expected by QuickBooks. You must remember to do this because the VB default for projects does not use binary compatibility.
To set binary compatibility, open your project, select the Project pull-down menu, and click on your application’s properties at the bottom of the pull-down. In the ensuing properties window, select the Component tab. In the ensuing tab window, select the option Binary Compatibility and click OK.
DeliveryPolicy determines whether QuickBooks will start your callback application when the application is not running. If your application specifies a delivery policy of “deliver always” then it will start up (if not running already) upon receiving the first subscribed QuickBooks event notification. If the subscription specifies “deliver only if running” then any events occurring when the application is not running are not delivered but are marked as “lost events.”
Regardless of the delivery policy, once your callback application starts, you should be aware that QuickBooks doesn’t release that callback application’s COM pointer until the company file closes. The callback application therefore cannot be dismissed by the user. So if you use a UI for your callback, you need to design the UI to handle this.
If your application needs to distinguish between being started by QuickBooks and being started by the user, you should add a command line argument to the shortcut for the .exe, because QuickBooks never passes a command line argument when starting the application.
If your application subscribes with a delivery policy of “deliver only if running,” then you may want to implement lost event handling, as described in Recovering from lost data events.
Your implementation of the IQBEventCallback routine should do minimal processing and should return quickly. Why is this a design requirement? First, your callback application cannot receive any other events until you return from your callback. Instead, QuickBooks maintains such events (except company file close) in a queue in the order in which they occur.
Once you return from the callback, QuickBooks will send the next event from this queue. It is therefore recommended that if the application needs to display some UI in the callback, it should choose to use non-blocking UI calls instead of blocking UI calls, so that the callback method can return without delay.
The queue contains a limited number of events. If the queue becomes full, events are no longer delivered to your application but are marked as lost events. If this is happening, your application is not processing events fast enough.
Note
Note
Even though your application does not receive more events until it has returned from its callback method, during this time other applications are free to receive events and QuickBooks itself is able to function normally. (QuickBooks can handle UI actions from the user, as well as SDK requests.)
Another reason for performing minimal processing in the callback implementation is that the callback application must be able to respond quickly to a company file close event.
If your callback makes SDK queries into QuickBooks, rather than caching the Request Processor pointer, we recommend that you make the BeginSession and EndSession calls within the callback.
In your implementation of the IQBEventCallback::Inform callback routine, you cannot invoke any QuickBooks SDK request that writes immediately to the QuickBooks company file, if the callback is a data event callback. As a result, you can only issue query requests, as well as make subscription changes, since they aren’t immediately written to the company file. The only exception to this is that you can also perform a DataEventRecoveryInfoDel request during a callback. See Recovering From Lost Data Events for information on data event recovery.
Also, in a data event callback, you cannot invoke the QuickBooks UI, that is, post some QuickBooks form.
Finally, you should not make SDK requests in the callback for company close events.
As noted above, an application is prevented from making data modifying requests in its callback routine. This is done to help avoid an infinite recursion problem, for example, where applications A and B each modify data in its callback that the other listens to, thus becoming locked in an infinite recursion.
Consequently, as much as possible, you should avoid writing to QuickBooks in direct response to events.
For ideas on how to work with these concerns, see the three sample set under \samples\qbdt\vb\qbxml\DataEvents.
When a subscribed event occurs, your application’s callback routine receives the event in the form of a qbXML aggregate, QBXMLEvents, which contains one of three sub-aggregates based on the type of event that occurred: DataEventRet, UIExtensionRet, and UIEventRet.
The path to the company file is included in all three types of event notifications. In addition, the following is included:
See the API Reference for a complete listing of the possible contents of the QBXMLEvents aggregate.
The callback that handles the incoming QuickBooks events must be an implementation of the SDK-defined callback interface, IQBEventCallback. This callback accepts the event XML string sent by QuickBooks and does whatever handling is desired. The best way to handle events is to hand them off to another application for queuing and processing.
Other than the Implements statement and the required input parameter, there are no restrictions on your callback other than the ones described above.
The following sample is excerpted from a more fully commented sample in the SDK called QBDataEventSubscriber, which is located at the QBSDK subdirectory (\samples\qbdt\vb\qbxml\DataEvents\QBDataEventManager).
The main items to take away from the sample are:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Implements QBSDKEVENTLib.IQBEventCallback Public Sub IQBEventCallback_inform(ByVal eventXML As String) ' You should treat this like interrupt handling in an OS, where ' you process the interrupt (event) as quickly as possible ' Display the event we received Dim tmpXML As String tmpXML = eventXML EventCounter = EventCounter + 1 QBDataEventManagerDisplay.eventXML.Text = Replace(tmpXML, vbLf, vbCrLf, 1, -1, vbTextCompare) QBDataEventManagerDisplay.eventLabel.Caption = "Received Event #" & EventCounter QBDataEventManagerDisplay.Show SetForegroundWindow QBDataEventManagerDisplay.hwnd 'Now check if it is a company close event or a data event If (InStr(1, eventXML, "CompanyFileEventOperation>Close<", vbTextCompare) > 0) Then 'Company close, shut ourselves down QBDataEventManagerDisplay.Hide Unload QBDataEventManagerDisplay End If 'Queue it up if we are supposed to be tracking events. If (QBDataEventManagerDisplay.Tracking) Then QBDataEventManagerDisplay.Debug.Text = "Queing event #" & EventCounter QBDataEventManagerDisplay.EventQueue.EnQueue (eventXML) End If End Sub |
The following subsections describe some event behaviors that you should be aware of when you design and implement a callback application.
QuickBooks doesn’t release a callback application’s COM pointer until the company file closes. Consequently, if the callback application has a UI that can be dismissed by the user, you should be aware that the callback app doesn’t really go away. It goes away only when the company file closes. If you use a UI for your callback, you need to design the UI to handle this.
Beginning with SDK 4.0, an application can choose not to receive its own data events when it makes its subscription. By default, however, applications do receive subscribed-to events for QuickBooks activity resulting from the application’s own add/mod/delete activities within QuickBooks. To avoid receiving your own events, set the DeliverOwnEvents field to False in the DataEventSubscriptionAdd request. You definitely want to do this when event notifications are being delivered to a different executable than the subscribing executable.
You should be aware that some QuickBooks actions may generate multiple events if the action affects different QuickBooks objects. For example, adding a new invoice in QuickBooks also affects accounts. Accordingly, when there is an InvoiceAdd event, there could be multiple AccountMod events.
If an end user adds or changes data in a custom field via the QuickBooks UI, or if an integrated application successfully issues a DataExtAdd or DataExtMod request for a custom field or private data extension, a Mod event is generated for the parent object, and the Time Modified value for the parent object is updated. For example, if a Customer has a custom field called “shoe size,” modifying the value of that custom field generates a Customer mod event and causes an update to the customer’s Time Modified field.
An application running on one machine with QuickBooks generally receives events only from events generated by that local QuickBooks. The application won’t receive events generated by interactive users sharing the same company file on other machines or by SDK clients running on other machines. If you need to track those remotely-made changes in the company file, you can can use the event recovery mechanism described under Recovering From Lost Data Events.
However, you should be aware that if the local QuickBooks needs to refresh its view of an object, because it is being edited locally, or because a list is being refreshed, or because an SDK client issues a query request, then events may be delivered that came from other machines.
The QuickBooks UI for authorizing an application to receive data, UI, and UI extension events is the same as for regular SDK calls. Notice that the QuickBooks UI prompts for permissions based on the callback’s certificate if it has been signed or the AppName specified in the subscription XML if the callback is not signed.
Once an application is authorized to access QuickBooks via the SDK, the application automatically has permission to receive event notifications. Similarly, once an application is authorized to receive events, it is automatically authorized to access QuickBooks via the SDK.
However, there is one difference worth noting. With standard SDK requests, when the user has chosen to be prompted before allowing access, a prompt will be displayed at each call to BeginSession. With events, when this same access level is chosen, a prompt will also be displayed each time the company file is opened in attended mode. Then, if the user grants the application permission by selecting “Yes, Always,” the application will receive events in future sessions without prompting. If the user selects “Yes, This time,” the application will receive events for as long as that company file remains open. If the user selects “Yes, Always,” the application will not be prompted in future sessions. In your documentation and messaging to your user, you should recommend that they choose “Yes, Always” as this will provide the best user experience.
If the company file is opened in unattended mode, a prompt will not be displayed and no events will be sent to the application while that company file remains open.
If your application is digitally signed, as described in Digitally signing your code, QuickBooks verifies that the correct application is receiving the notification to which your application is subscribed.
QuickBooks reads, encrypts, and stores the certificate information from the callback executable when the subscription request is made. Then, starting the callback application, QuickBooks reads the signature information from the callback executable that is about to be notified and makes sure that it matches the information that was read when the subscription request was made.
If the certificate is invalid or revoked, QuickBooks silently fails to start the application and an error is logged because it is considered disruptive to tell the user in the UI (which is what regular SDK requests do) in this case.
If the certificate is expired, and the user has chosen to be prompted about expired certificates, QuickBooks will also silently fail to start the application. However, if the user hasn’t chosen to be prompted about expired certificates, or has previously allowed access to an application even though it is expired, then the application will continue to receive events.
If the information does not match (meaning that the executable has been replaced), no notification will be sent, and for UI extensions an error dialog will be displayed (the same one that’s shown when the notification fails for any other reason).
If your application is not digitally signed, the SDK will send notification events without any verification.
The QB SDK includes an application template wizard that generates a great deal of the event code you need or may want to implement. It does a lot of the heavy lifting for you and we strongly recommend using this if you can. The information in this chapter is still useful background information, but the template will save you LOTS of time and potential mistakes. The template is for Visual Studio 2005 and later and works for C# applications. If you have VS 2005, this will be automatically installed for you in the templates directory.
For more information see “C# Project Wizard” in the QB SDK program group accessed from the Windows Start menu.
The following requests are available for managing event subscriptions.
Name | Description |
---|---|
DataEventSubscriptionAdd | Adds one or more subscriptions to the specified QuickBooks data events. |
DataEventSubscriptionQuery | Queries for subscriptions by SubscriberID and qbXML version. |
SubscriptionDel | Deletes all subscriptions matching subscriber ID and qbXML version. |
UIEventSubscriptionAdd | Adds one or more subscriptions to the specified QuickBooks UI events. |
UIEventSubscriptionQuery | Queries for subscriptions by SubscriberID and qbXML version. |
UIExtensionSubscriptionAdd | Adds one or more subscriptions to the specified QuickBooks UI extension events. |
UIExtensionSubscriptionQuery | Queries for subscriptions by SubscriberID and qbXML version. |
These requests are documented in the qbXML messages reference.
Your callback application receives all event notifications in the form of QBXMLEvents messages.
If you use QBFC, instead of calling QBSession manager to create a MsgsSetRq, call SessionManager. CreateSubscriptionMsgSetRequest() you must append the subscription request to an ISubscriptionMsgSetRequest object instantiated by the QBSessionManager methodand invoke the method DoSubscriptionRequests().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ‘ Build a 6.0 request set and create a data ext def add request Dim SubscriptionMessageSet As ISubscriptionMsgSetRequest Set SubscriptionMessageSet = SessionManager.CreateSubscriptionMsgSetRequest("US", 6, 0) SubscriptionMessageSet.Attributes.OnError = roeContinue ‘ Request will write to the custom field "Category" using a DataExtMod message ‘ (For private data, our first write to an object’s data ext MUST be a DataExtAdd) Dim EventSubscriptionAdd As IDataEventSubscriptionAdd Set EventSubscriptionAdd = SubscriptionMessageSet.AppendSubscriptionAddRq ‘ Now send the request to QuickBoooks Dim EventSubscriptionAddRs As ISubscriptionMsgSetResponse Set EventSubscriptionAddRs = SessionManager.DoSubscriptionRequests(SubscriptionMessageSet) SessionManager.EndSession SessionManager.CloseConnection Set SessionManager = Nothing |
If you use qbXML, you must invoke the requests to add, query, and delete subscriptions using the request processor’s ProcessSubscription method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version="1.0" ?> <?qbxml version="6.0"?> <QBXML> <QBXMLMsgsRq onError = "stopOnError"> <DataExtModRq requestID = "0"> <DataExtMod> <OwnerID>0</OwnerID> <DataExtName>Category</DataExtName> <ListDataExtType>Customer</ListDataExtType> <ListObjRef> <FullName>John Sidmark</FullName> </ListObjRef> <DataExtValue>Gold Member</DataExtValue> </DataExtMod> </DataExtModRq> </QBXMLMsgsRq> </QBXML> |
Note
Note
You cannot invoke QBXMLEvent, since that is a return-only message.
You need to supply the following information in your subscription requests:
Information | Description |
---|---|
Callback application name | The name of the application that contains the callback that handles the events. |
CLSID (or PROGID) | You must assign a CLSID (or a PROGID, depending on the programming language that you use and your own preferences) for the callback class that implements the SDK interface IQBEventCallback. The CLSID or ProgID must be registered in the Windows registry before the subscription request can be made successfully. Notice that you can only have one CLSID/PROGID per SubscriberID. For example, if you use the same SubscriberID to subscribe to data event, UI event, and UI extension events, then you will also need to specify the same CLSID. If you want multiple CLSIDs for your application (perhaps because you want one EXE to handle data events, another EXE to handling UI events, and still another EXE to handle UI extension events), you use a different SubscriberID to subscribe to each event type |
DeliveryPolicy | You need to specify the QBFC or qbXML value for “deliver only if running” if you want your application to receive events only when it is running. Specify the QBFC or qbXML value for “deliver always” if you want your application to be started up to receive the incoming events if the application isn’t running. Notice that the callback will be started up only once during the QuickBooks session. The actual values specified vary depending on whether QBFC or qbXML is used. |
subscriberID | This is a GUID that you must create for your application. You also use this value whenever you query or delete subscriptions. |
TrackLostEvents | For data events only. Specify the QBFC or qbXML value for “all” if you want a DataEventRecoveryTime to be recorded when there is a lost event. You would do this if you wanted to implement lost event recovery, as described lower on the page in “Recovering From Lost Data Events”. Specify the QBFC or qbXML value for “none” if your application does not care about lost events. |
Once your application is subscribed, your application will receive all the specified events. For example, if it is subscribed to CustomerAdd events it will receive notifications whenever a new customer is added in QuickBooks to any company file.
QuickBooks does not need to be running when you subscribe and unsubscribe an application. Notice that the subscribe or unsubscribe does not go into effect immediately, however. For data and UI events, the subscribe/unsubscribe goes into effect when the company file is next opened by QuickBooks. (Consequently, when you subscribe or unsubscribe, you should notify the user to reopen any company files that are currently open.) For UI extension events, the subscribe/unsubscribe goes into effect when QuickBooks is next started.
The event data that is returned can potentially differ depending on the qbXML version. For example, in the 4.0 qbXML spec, there is a new tag that could be returned in the QBXMLEvent response called CurrentWindow. If an application is designed for the 3.0 spec but not the 4.0 spec, how is this situation handled?
Beginning with SDK 4.0, the spec version that issued the original subscription request determines which data is returned in the response. For example, if your application subscribed using qbXML 3.0 (that is, the qbXML processing instruction is set like this: <?qbxml version=”3.0”?> ), then the QBXMLEvent data that is returned is the data from 3.0, that is, you don’t receive additional data made available in 4.0. If you needed that data, you would first do a 3.0 unsubscribe to get rid of the old subscription, then resubscribe using a qbXML 4.0 subscription request.
In addition, suppose you have a current subscription issued using qbXML 3.0. To delete that subscription, you have to issue a SubscriptionDel request with the qbXML version tag set to 3.0. The reason for this is that you might want to keep 3.0 spec subscriptions for backwards compatibility.
Note
Note
The application that makes a subscription request does not have to be the same application that will receive the event notification. (For example, your installation application might call a subscription request that specifies callback information for your main application.)
When you add a subscription, it applies to all company files on that machine. However, notice that the QuickBooks user must still authorize your application for each company file.
If you want events from only one particular company file, you can filter out the events from any unwanted company file by checking the CompanyFilePath element in the incoming event XML that your application receives.
There are a few situations in which data events aren’t sent to your application by QuickBooks. When this happens, the event notification framework provides a way for you to recover from these lost data events in order to synchronize the data your application maintains with the data in QuickBooks.
Data events can be lost due to a variety of conditions. There are basically two groups of causes: normal conditions and failure conditions. This distinction is important because the event notification system behaves differently depending on whether an event was lost due to failure conditions or not. If data events are lost due to normal conditions, attempts will still be made to deliver future events. If events are lost due to failure conditions, no attempt will be made to deliver future events during the rest of the current session with the company file.
Normal conditions leading to lost events. The list below describes normal conditions in which data events are lost for your application:
Failure conditions leading to lost data events. The list below describes failure conditions in which data events are lost for your application:
Note
Note
If data events are lost due to failure conditions, no more data events are sent to the application until the company file is re-opened.
Provided that you set the TrackLostEvents field in the data event subscription request to All, the DataEventRecoveryTime will be recorded whenever data events are lost, as described above. There are then two ways to check the DataEventRecoveryTime to determine if any events have been lost.
The first way is by examining a data event for the presence of the DataEventRecoveryTime field. If this field exists, then a data event was lost as of this time. The other way is by issuing a DataEventRecoveryInfoQuery request. If the response contains a DataEventRecoveryTime a data event was lost as of this time.
Notice that if more than one event was lost, the DataEventRecoveryTime will retain the time of the first lost event.
After you determine that data events have in fact been lost, you can query for all the objects your application cares about, with the FromModifiedDate filter set to the DataEventRecoveryTime. This will synchronize your records with the QuickBooks company file and account for any data events that were lost after the specified time.
Once you have done this, you must then clear the DataEventRecoveryTime using the DataEventRecoveryInfoDel request, specifying your application’s SubscriberID. By resetting this time, you are then guaranteed that any future existence of the DataEventRecoveryTime will indicate that data events have been lost from which your application has yet to recover.
There are special QuickBooks operations that affect an application’s subscriptions and data synchronization with QuickBooks. They are listed below:
Each of these is described in more detail in the following subsections.
After a company file goes through a restore, its application permission records (the information in the Preferences > Integrated Applications window) may not be current anymore; there may be applications whose permission records weren’t in the backup file that the company file restored to. Upon opening the company file after the restore operation, QuickBooks will prompt the user to grant permission for those applications that still have subscriptions so that they can keep receiving events after the user grants them permission again.
Any application that has data that needs to match what is currently in QuickBooks will need to resynchronize its data with QuickBooks after a restore. The LastRestoreTime in the company file is updated every time a restore happens. An application can use this timestamp to detect that a restore happened by saving this time when it first sees it and then comparing it with the one currently stored by QuickBooks. To get the current LastRestoreTime, an application can issue a CompanyActivityQuery request. Alternatively, the last restore timestamp is also included in an application’s first data event after a company file is opened, so that an application doesn’t need to make a separate query request. Notice that an application only needs to check this timestamp once while a company file is open, as a restore always involves closing and then reopening the company file.
No events are sent during the condense operation of a company file. Any application that has data that needs to match what is currently in QuickBooks will need to detect when a condense has happened and then synchronize any data changes after the condense operation.
After the application detects a condense, it can get all the data changes as a result of the condense by using LastCondenseTime as a filter in the queries (the FromModifiedDate and FromDeletedDate). A condense operation also always involves closing and then reopening the company file.
A list object in QuickBooks can be merged with another list object of the same type. After the merge operation, all transactions that reference the merged-from object will be changed to reference the merged-to object, and the merged-from object is deleted. For example, after the user merges object A to object B, all transactions that used to refer to object A will now refer to object B, and object A will be deleted.
An application can expect to get a merge event and a delete event during a merge operation, but it will not get any transaction modify events. For example, in the above scenario, an application will get a merge event on object A (containing the after-merge list ID, which is object B’s list ID) and a delete event on object A. However, the application is expected to walk its own transaction list and update any references to object A itself.
Both QBFC and qbXML support unsubscribing from events of a specified type: data events, UI events or UI extension events. The unsubscribe request specifies the type and the application. For example, if you unsubscribe from data events, the application is unsubscribed from all data events, if you unsubscribe from UI events, the application is unsubscribed from all UI events, and so on. Just like subscribing, the unsubscribe changes take effect only when the company file is next opened (for data events and UI events) or when QuickBooks is restarted (for UI extension events).
Note
Note
During your application’s uninstall, you should always unsubscribe from any events to which your application is subscribed.
There is no subscription Modify functionality. However, you can achieve the same result by deleting the subscription and adding a new subscription that contains all of the events of that type you want to receive, including ones that may have been in the previous subscription.
Both QBFC and qbXML support querying for the events that are currently under subscription. This is useful for determining the current subscription. The response returns different information depending on the query type. See the API Reference for more information.
This section describes implementation details for qbXML-based applications. In addition, the syntax and code samples shown are in Visual Basic. If you are programming in Visual C++, see the fully commented code samples located at the QBSDK install subdirectory – \samples\qbdt\cpp\qbxml\UIandEventTest.
Note
Note
If you have used previous versions of the SDK, you may have used the Request Processor named QBXMLRPLib. Starting with SDK 3.0, a new Request Processor is available, QBXMLRP2Lib.RequestProcessor2. Only this new Request Processor supports event subscription and other new features of SDK 3.0. Backwards compatibility with the old Request Processor is maintained in the new one.
To enable your application to receive and respond to QuickBooks events, you need to subscribe the application to the events and you need to handle those incoming events in your callback code. This section describes each of these coding activities.
Subscribing, unsubscribing, and querying for subscription data are performed via the Request Processor ProcessSubscription method call. (In Visual Basic, QBXMLRP2Lib.RequestProcessor2::ProcessSubscription.)
This method call takes a qbXML request string containing the desired subscription, subscription delete, or subscription query qbXML.
In order to subscribe an application to events, a qbXML-based application creates an instance of the Request Processor, connects to QuickBooks, builds the desired SubscriptionAddRq request, and makes a call to the method ProcessSubscription (QBXMLRP2Lib.RequestProcessor2::ProcessSubscription).
When you build the qbXML SubscriptionAdd request you use one of the following requests, depending on the type of subscription you are making:
For the full description of each of these subscription messages, see the API Reference.
The following sample is excerpted from a more fully commented sample in the SDK called QBDataEventSubscriber, which is located at the SDK installation subdirectory
\samples\qbdt\vb\qbxml\DataEvents\QBDataEventSubscriber. (Notice that sample does not check for errors or exceptions.)
The main items to take away from the sample are:
Note
Note
If an application attempts to subscribe before deleting its current subscription, it will generate an error. Your application must check for the error and act accordingly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | Private Sub SubscribeBtn_Click() ' Subscribe to events... Dim ConnOpen As Integer ConnOpen = 0 Dim QBXML As IXMLDOMElement Set QBXML = doc.createElement("QBXML") doc.appendChild QBXML Dim SubReq As IXMLDOMElement Set DataSubReq = doc.createElement("DataEventSubscriptionAddRq") SubReq.appendChild DataSubReq Dim DataSubAdd As IXMLDOMElement Set DataSubAdd = doc.createElement("DataEventSubscriptionAdd") DataSubReq.appendChild DataSubAdd Dim COMCallback As IXMLDOMElement Set COMCallback = doc.createElement("COMCallbackInfo") DataSubAdd.appendChild COMCallback AddSimpleElement doc, COMCallback, "AppName", "DataEventSample" Dim ListEventSub As IXMLDOMElement Set ListEventSub = doc.createElement("ListEventSubscription") DataSubAdd.appendChild ListEventSub AddSimpleElement doc, ListEventSub, "ListEventType", "Customer" AddSimpleElement doc, ListEventSub, "ListEventOperation", "Add" AddSimpleElement doc, ListEventSub, "ListEventOperation", "Modify" AddSimpleElement doc, ListEventSub, "ListEventOperation", "Delete" AddSimpleElement doc, ListEventSub, "ListEventOperation", "Merge" 'We're all done we are going to subscribe to the UIEvents for company 'otherwise QuickBooks won't be able to close Dim UISubReq As IXMLDOMElement Set UISubReq = doc.createElement("UIEventSubscriptionAddRq") SubReq.appendChild UISubReq Dim UISubAdd As IXMLDOMElement Set UISubAdd = doc.createElement("UIEventSubscriptionAdd") UISubReq.appendChild UISubAdd AddSimpleElement doc, UISubAdd, "SubscriberID", "{2B6C9DB4-EBE2-45E7-A14F-4E1C49C965F7}" ' Same Callback info as for DataEvents, and same delivery policy Set COMCallback = doc.createElement("COMCallbackInfo") UISubAdd.appendChild COMCallback AddSimpleElement doc, COMCallback, "AppName", "DataEventSample" AddSimpleElement doc, COMCallback, "ProgID", "QBDataEventManager.QBEventHandler" AddSimpleElement doc, UISubAdd, "DeliveryPolicy", "DeliverAlways" Dim UIEventSub As IXMLDOMElement Set UIEventSub = doc.createElement("CompanyFileEventSubscription") UISubAdd.appendChild UIEventSub ' We care only about the Close event, not the open event. AddSimpleElement doc, UIEventSub, "CompanyFileEventOperation", "Close" 'Send the subscription request to QuickBooks Dim subXML As String subXML = "<?xml version=""1.0""?>" & vbCrLf & "<?qbxml version=""3.0""?>" & vbCrLf & doc.xml saveXMLStream subXML Dim resp As String resp = RP.ProcessSubscription(subXML) ' We'll just show the response. MsgBox Prompt:=resp, Title:="Subscribe Complete" ' And finally close our connection to QuickBooks If (ConnOpen) Then RP.CloseConnection End If End Sub |
When you no longer want to receive events of a certain type, or want to change a subscription, you make a call to the same method used to start receiving the events in the first place, QBXMLRP2Lib.RequestProcessor2::ProcessSubscription, but instead of supplying a SubscriptionAdd request, you provide a SubscriptionDel request. This deletes all subscription information for your application’s SubscriberID for the type of events you specify (data, UI extension, or UI).
Notice that you cannot unsubscribe from a subset of the original subscription of any type using the SubscriptionDel request. This request deletes all subscriptions of the specified type for the application that invokes it.
When you build the qbXML SubscriptionDelRq request you use one of the following requests, depending on the type of subscription you are making:
For the full description of each of these subscription messages,see qbXML messages reference.
The following sample is excerpted from a more fully commented sample in the SDK called QBDataEventSubscriber, which is located at the QBSDK subdirectory \samples\qbdt\vb\qbxml\DataEvents\QBDataEventSubscriber.
The main items to take away from the sample are:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | Private Sub Unsubscribe_Click() 'Simply delete the subscriptions we set up in Subscribe_click Dim ConnOpen As Integer ConnOpen = 0 Dim RP As New QBXMLRP2Lib.RequestProcessor2 RP.OpenConnection "", "DataEventSample" ConnOpen = 1 ' Create the outer subscription request XML "envelope" Dim doc As New DOMDocument40 Dim QBXML As IXMLDOMElement Set QBXML = doc.createElement("QBXML") doc.appendChild QBXML Dim SubReq As IXMLDOMElement Set SubReq = doc.createElement("QBXMLSubscriptionMsgsRq") QBXML.appendChild SubReq ' Create a subscription delete request for the Data event subscription Dim DataSubDel As IXMLDOMElement Set DataSubDel = doc.createElement("SubscriptionDelRq") SubReq.appendChild DataSubDel AddSimpleElement doc, DataSubDel, "SubscriberID", "{2B6C9DB4-EBE2-45E7-A14F-4E1C49C965F7}" AddSimpleElement doc, DataSubDel, "SubscriptionType", "Data" 'Create subscription delete request for the UIEvent for company close Dim UISubDel As IXMLDOMElement Set UISubDel = doc.createElement("SubscriptionDelRq") SubReq.appendChild UISubDel AddSimpleElement doc, UISubDel, "SubscriberID", "{2B6C9DB4-EBE2-45E7-A14F-4E1C49C965F7}" AddSimpleElement doc, UISubDel, "SubscriptionType", "UI" 'Send the subscription delete requests to QuickBooks Dim subXML As String subXML = "<?xml version=""1.0""?>" & vbCrLf & "<?qbxml version=""3.0""?>" & vbCrLf & doc.xml saveXMLStream subXML Dim resp As String resp = RP.ProcessSubscription(subXML) ' Show the response MsgBox Prompt:=resp, Title:="Subscriptions Removed" ' Close the connection to QuickBooks. If (ConnOpen) Then RP.CloseConnection End If End Sub |