Applications that have successfully sent requests to QuickBooks and received a response can proceed to process the response. The basic steps for processing responses are listed below:
Prepare to receive a response set by creating an IMsgSetResponse
object.
1 | Dim myResponseMsgSet As IMsgSetResponse |
Populate the IMsgSetResponse by calling the connection manager’s DoRequest
method, in this format:
1 | set myResponseMsgSet = ConnectionManager.DoRequest (myRequestMsgSet) |
Create an IResponse
object and extract the individual responses from the response set object.
responseMsgSet.ResponseList.GetAt(index)
.Check the type of the IResponse
object. The type should mirror the request type, using the following naming convention: rtQBObjectTypeQBOperationTypeRs, where the QBObjectType and the QBOperationType are the values used in the request. The type is returned as an integer, but you
can compare it directly to one of the enumerated named types, as in:
1 2 3 4 | Dim responseType As Integer responseType = response.Type.GetValue If (responseType = rtItemInventoryAddRs) |
Extract the detail (the QuickBoooks object’s values) from the IResponse
object as a a response detail object. To do this you need to cast the detail to a specific IQBOjectRet type, where QBOject is the QuickBooks object that the request operated on. Every request objects has a
corresponding IQBOjectRet type, which is identified in the API Reference section. For example, if the request was an ItemInventoryAddRq
object, the response detail object is of type IItemInventoryRet
.
1 2 | Dim itemInventoryRet As IItemInventoryRet Set itemInventoryRet = response.Detail |
The examples that follow look in more detail at the code for working with response set objects and response objects.
You may also want to look more closely at the following topics:
Two examples of building a request follow, one using the QBFC classes, and the other using Microsoft’s XML (MSXML) API DOMDocument technology to build the request in qbXML.
The following example, in VisualBasic, follows the steps outlined above to process a response message set. The request was a single request, to add an item to inventory. The response object returned, following the naming convention described above, is rtItemInventoryAddRs
, and the response
detail object is of type IItemInventoryRet
.
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 | ' Create a QBSessionManager object: Dim SessionManager As QBSessionManager Set SessionManager = New QBSessionManager ' (Build the request message set) ' Prepare to receive a response by creating a response message set object: Dim responseMsgSet As IMsgSetResponse ' Call DoRequests and receive the response as an IMsgSetResponse object: Set responseMsgSet = sessionManager.DoRequests(requestMsgSet) ' Create an IResponse object and extract the first response from the ' response set object (in this case we know there is only one response). Dim response As IResponse Set response = responseMsgSet.ResponseList.GetAt(0) ' Make sure the response is not empty: If (Not response. Is Nothing) Then Dim responseType As Integer responseType = response.Type.GetValue ' Make sure the response type is the expected ItemInventoryAddRs type--we know ' to expect this type because the request was ItemInventoryAddRq: If (responseType = rtItemInventoryAddRs) Then ' Cast the IResponse.Detail as an IItemInventoryRet response detail object; Dim itemInventoryRet As IItemInventoryRet Set itemInventoryRet = response.Detail ' Read field values from the response detail object--in this example we're ' reading only the ListID of the item that was added by the request: Dim itemInventoryListID As String itemInventoryListID = itemInventoryRet.ListID.GetValue End If End If ' End the session: SessionManager.EndSession ' Close the connection: SessionManager.CloseConnection ' Clear the QBSessionManager Set SessionManager = Nothing |
Some points to notice about this example:
IItemInventoryAdd
objects, or request objects of other types, or both), fully populated them, appended them to the MessageSetRequest
, and passed a MessageSetRequest
containing multiple requests
with one call to DoRequests
.OpenConnection
and BeginSession
before creating and populating the request message set; the key point is that it had to successfully make those calls before it called DoRequests
.Notice that we make an implicit cast (something that is supported in VB) here and cast the response detail to the itemInventoryRet
type. In other languages, you must do an explicit cast. For example, in VB.Net: ‘itemInventoryRet = response.Detail as itemInventoryRet
.
The second example, also in Visual Basic, follows basically the same steps, except that the request is a query that returns multiple records. QBFC handles this by forming both the results object (IResult
) and the results detail object (in this case, ItemInventoryRetList
) as lists, and the
application handles it by iterating over the results detail list to populate a display.
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 | ' Call DoRequests to send the request message and get the response message set: Dim responseMsgSet As IMsgSetResponse Set responseMsgSet = sessionManager.DoRequests(requestMsgSet) ' Call GetAt, to extract the first IResponse object. This sample expects only one ' IResponse, because only one request was sent, but, because the request was a ' query, the the IResponse object will be a response list containing multiple ' response detail (*Ret) objects. Dim response As IResponse Set response = responseMsgSet.ResponseList.GetAt(0) 'Check for an empty/null response: If (Not response.Detail Is Nothing) Then ' Confirm that the response is the expected rtItemInventoryQueryRs Dim responseType As Integer responseType = response.Type.GetValue If (responseType = rtItemInventoryQueryRs) Then ' Cast the response detail as a list of response detail objects. The response ' detail object list is IItemInventoryRetList, which is identified in the API ' Reference as the appropriate response detail list object for this query: Dim itemInventoryRetList As IItemInventoryRetList Set itemInventoryRetList = response.Detail ' Define the individual response detail item; Dim itemInventoryRet As IItemInventoryRet ' Define an ItemFliexGrid control to display the query results: ItemFlexGrid.Rows = (1 + itemInventoryRetList.Count) ' Iterate over the response detail list and load field vlaues of each response ' detail object from the list into a separate row of the grid control: Dim j As Integer For j = 0 To itemInventoryRetList.Count - 1 Set itemInventoryRet = itemInventoryRetList.GetAt(j) Set itemInventoryRet = itemInventoryRetList.GetAt(j) If (Not itemInventoryRet.Desc1 Is Nothing) Then ItemFlexGrid.Col = 0 ItemFlexGrid.Row = j + 1 ItemFlexGrid.Text = itemInventoryRet.ListID.GetValue ItemFlexGrid.Col = 1 ItemFlexGrid.Text = itemInventoryRet.FullName.GetValue ItemFlexGrid.Col = 2 ItemFlexGrid.Text = itemInventoryRet.SalesDesc.GetValue ItemFlexGrid.Col = 3 ItemFlexGrid.Text = itemInventoryRet.QuantityOnHand.GetValue End If Next j End If End If |
Some points to notice about this example:
rtItemInventoryQueryRs
follows the naming convention for response objects that was described above.IItemInventoryRetList
is identified in the API Reference as the response detail type for an ItemInventoryQuery.ItemInventoryQuery
objects, or request objects of other types, or both), fully populated them, appended them to the MessageSetRequest
, and passed a MessageSetRequest
containing multiple
requests with one call to DoRequests
. In this case, the application would have had to iterate over the IMsgSetResponse
object to extract the individual IResponse
objects, and then.processed each IResponse
object as shown above.OpenConnection
, BeginSession
, etc. calls were omitted for the sake of brevity; the key point is that it had to successfully make those calls before it called DoRequests
, and make the corresponding ending calls after it processed the requests.For a complete list of response objects, see qbXML messages reference.
Building a qbXML request and sending it to QuickBooks is a matter of writing out a valid qbXML string that contains the requests you want and then using request processor methods to send them to QuickBooks. However, because building syntactically correct XML by hand is tedious and prone to error, we strongly recommend the use of a technology that does the XML formatting (the angle brackets, the start and end tags, and so on), so you can focus on the providing the qbXML elements that correctly define your requests and responses.
The following example uses of Microsoft XML (MSXML) API DOMDocument, a technology which is currently free from Microsoft to process the qbXML. When you process a response, refer to the API Reference for information about the elements present in each type of response.
The following VB code snippet shows the qbXML for adding a new customer, with just a few of the available fields filled out, to keep things simple. Once the request is filled out, our code snippet prepends the required header information and sends the completed XML string to qbXML via the request processor.
Prepare to receive a response set by creating an IMsgSetResponse object.
Receive the response set by calling the connection manager’s processRequest method, in this format:
1 2 3 | strXMLResponse = qbXMLRP.ProcessRequest (strTicket, strXMLRequest) ``strTicket``\ was returned by the begin session call, and ``strXMLRequest``\ was built by the process illustrated in `Building and sending requests </app/developer/qbdesktop/docs/develop/exploring-the-quickbooks-desktop-sdk/preparing-and-sending-requests>`__. |
Instantiate a new DOM document.
Load the response XML string into the DOM document.
Return the individual responses into a DOM node list.
For each response in the list:
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 | (Build a qbXML Request Set, strXMLRequest) ' Call ProcessRequest to send the request and receive the response: Dim qbXMLRP as QBXMLRP2Lib.RequestProcessor2 Dim strXMLResponse as String strXMLResponse = qbXMLRP.ProcessRequest (strTicket, strXMLRequest) ' Create an xmlDoc Object Dim xmlDoc As New DOMDocument40 ' Copy the response set into the XML document: Set xmlDoc = strXMLResponse ' Create variables to be used in processing the XML document: ' variables for the response status codes Dim retStatusCode As String Dim retStatusMessage As String Dim retStatusSeverity As String ' Objects for the XML nodes within the response: Dim objNodeList As IXMLDOMNodeList Dim objChild As IXMLDOMNode Dim custChildNode As IXMLDOMNode Dim attrNamedNodeMap As IXMLDOMNamedNodeMap Dim i As Integer Dim ret As Boolean Dim errorMsg As String ' Call getElementsByTagName to extract the elements demarcated by CustomerAddRs tags: Set objNodeList = xmlDoc.getElementsByTagName("CustomerAddRs") ' Loop through the list of CustomerAddRs elements: For i = 0 To (objNodeList.length - 1) ' Map the elements of CustomerAddRs tags to attributes of the NamedNodeMap Set attrNamedNodeMap = objNodeList.Item(i).Attributes ' Review the the status Code, info and Severity attributes: retStatusCode = attrNamedNodeMap.getNamedItem("statusCode").nodeValue retStatusSeverity = attrNamedNodeMap.getNamedItem ("statusSeverity").nodeValue retStatusMessage = attrNamedNodeMap.getNamedItem ("statusMessage").nodeValue ' Traverse the child nodes of CustomerAddRs node : For Each objChild In objNodeList.Item(i).childNodes ' Get the CustomerRet element If objChild.nodeName = "CustomerRet" Then ' Get the sub-elements in this element For Each custChildNode In objChild.childNodes If custChildNode.nodeName = "ListID" Then resListID = custChildNode.Text ElseIf custChildNode.nodeName = "Name" Then resCustName = custChildNode.Text ElseIf custChildNode.nodeName = "FullName" Then resCustFullName = custChildNode.Text End If Next End If ' End of customerRet Next ' End of customerAddret Next |