Author Topic: Quickbooks SDK  (Read 17531 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Quickbooks SDK
« on: October 25, 2015, 09:58:36 PM »
Hi Mike,

I'm a bit rusty with COM programming and VB syntax. Can you tell me if all the calls in this example are methods? I'm still trying to get Dave's SB COM ext. module working. I was able to get the ObjectCreate to generate a session handle.
« Last Edit: October 26, 2015, 09:44:36 AM by John »

Mike Lobanovsky

  • Guest
Re: Quickbooks SDK
« Reply #1 on: October 26, 2015, 09:14:03 AM »
Yes, the OpenConnection(...), BeginSession(...), EndSession(...), and CloseConnection() procedures are all methods of class RequestProcessor, a running instance of which called qbXMLRP has just been created with the operator New.

The syntax shown up there is however inconsistent with the BASIC/VB6 tradition. Procedures used as commands (i.e. those that have their respective return values discarded) should either have no parentheses around their arguments, if any, or have parentheses and be preceeded with an obligatory CALL command. Parentheses without CALL won't compile.

So, whereas in C and the like the equivalent code must be:
Code: C
  1. ...
  2. qbXMLRP.OpenConnection("", "Sample App");
  3. ticket = qbXMLRP.BeginSession("", qb_FILEOPEN_DONOTCARE);
  4. ...
  5. qbXMLRP.EndSession(ticket);
  6. qbXMLRP.CloseConnection();
  7. ...

its valid VB6 variant should be either:
Code: Visual Basic
  1. ...
  2. qbXMLRP.OpenConnection "", "Sample App"
  3. ticket = qbXMLRP.BeginSession("", qbFileOpenDoNotCare) ' parens mandatory here!
  4. ...
  5. qbXMLRP.EndSession ticket
  6. qbXMLRP.CloseConnection
  7. ...

or:
Code: Visual Basic
  1. ...
  2. CALL qbXMLRP.OpenConnection("", "Sample App")
  3. ticket = qbXMLRP.BeginSession("", qbFileOpenDoNotCare) ' parens mandatory here!
  4. ...
  5. CALL qbXMLRP.EndSession(ticket)
  6. CALL qbXMLRP.CloseConnection()
  7. ...

Unparenthesized and CALLed parenthesized commands may be interleaved in user code but each of them must be properly formatted as described above. Interleaved programming style is however poor for quick understanding and easy maintenance of VB6 programs.
« Last Edit: October 26, 2015, 09:26:43 AM by Mike Lobanovsky »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #2 on: October 26, 2015, 09:45:46 AM »
Wow!

Thanks Mike for these COM tips. I'll give Dave's SB COM stuff another try.


Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #3 on: October 26, 2015, 07:51:04 PM »
Mike,

I was able to get Quickbooks to pop its authorization window with the BeginSession() call to ask if access is allowed. I still can't get a ticket though. (returns 0) :-[ I even tried to DIM the ticket variable to 256 spaces before use but no luck. What bothers me is I have yet to see a SB COM example where a method returns a value.

Code: ScriptBasic
  1. import COM.inc
  2.  
  3. oqbXMLRP = CreateObject("QBFC13.QBSessionManager")
  4. PRINT "oqbXMLRP: ", oqbXMLRP,"\n"
  5.  
  6. CallByName(oqbXMLRP, "OpenConnection", vbMethod, "", "Script BASIC")
  7.  
  8. ticket = CallByName(oqbXMLRP, "BeginSession", vbMethod, "", 2)
  9. PRINT "ticket: ",ticket,"\n"
  10.  
  11. xml_request = """
  12. <?qbxml version="8.0"?>
  13. <QBXML>
  14.   <QBXMLMsgsRq onError="stopOnError">
  15.      <AccountQueryRq requestID="1">
  16.      </AccountQueryRq>
  17.   </QBXMLMsgsRq>
  18. </QBXML>
  19. """
  20.  
  21. post = CallByName(oqbXMLRP, "ProcessRequest", vbMethod, ticket, xml_request)
  22.  
  23. PRINT post,"\n"
  24.  
  25. CallByName(oqbXMLRP, "EndSession", vbMethod, ticket)
  26.  
  27. CallByName(oqbXMLRP, "CloseConnection")
  28.  

« Last Edit: October 26, 2015, 09:51:30 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #4 on: October 26, 2015, 09:49:03 PM »
Mike,

Quote from: Dave's README

This is a script basic extension to add support for creating COM objects
and calling their methods.

The COM objects must support the IDispatch interface so they can be used from
scripting clients. (This is very common)

Visual Studio 2008 project files have been included. They are set to use
the script basic include directory as relative path ./../include/

The COM.dll will be compiled into the current directory.

Notes:

Script basic only supports several data types internally, COM supports
many.

In testing with VB6 COM objects, the VB6 methods were forgiving
with data types. If the VB6 method expected a byte type, it would accept
a long (VT_I4) so long as the value was < 255.

The two main types this extension handles are longs and strings which it will
proxy between script basic and COM types automatically.

The CallByName function accepts an arbitrary number of arguments. These are
translated and copied into a DISPPARAMS array to be passed to the COM object.

The prototype of this function is:

callbyname object, "procname", [vbcalltype = VbMethod], [arg0], [arg1] ...

Where object is a long type returned from CreateObject() export.

If you are working with embedding ScriptBasic in your own application,
you can also use CallByName to operate on host created COM objects such as
VB6 Form, Class and GUI objects.

All you need is for the host application to provide an ObjPtr() to the
script to give it full access.

More details on this are available here:
  http://sandsprite.com/blogs/index.php?uid=11&pid=310

The VB6_Example.dll is a sample COM object that COM_VB6_Example.sb script uses
to show the results of some tests with common data types, retrieving strings and
longs, displaying a UI, and manipulating VB6 Form COM objects

In order to use this ActiveX Dll on your system you will have to run regsvr32 on it
or compile it yourself. The easiest way to register it is

start -> run -> type regsvr32 -> drag and drop the dll file into the run textbox to
have its path added as the argument.

remember com.dll has to be in the script basic modules directory and
com.inc should be in the includes directory to use these samples.


Here is the Bitbucket Repository I created for the project.

John
« Last Edit: October 26, 2015, 10:06:37 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #5 on: October 26, 2015, 10:28:58 PM »
I forgot about Dave's COM object interface viewer addition.


Interface: IQBSessionManager
ProgID: QBFC13.QBSessionManager.1
CLSID: {22E885D7-FB0B-49E3-B905-CCA6BD526B52}
Sub OpenConnection(AppID As String, AppName As String)
Sub BeginSession(qbFile As String, openMode As ENOpenMode)
Sub EndSession()
Sub CloseConnection()
Function GetCurrentCompanyFileName() As String
Function CreateMsgSetRequest(Country As String, qbXMLMajorVersion As Integer, qbXMLMinorVersion As Integer) As Object
Function ToMsgSetResponse(qbXMLResponse As String, Country As String, qbXMLMajorVersion As Integer, qbXMLMinorVersion As Integer) As Object
Function DoRequests(request As Object) As Object
Sub GetVersion(MajorVersion As Object, MinorVersion As Object, releaseLevel As Object, releaseNumber As Object)
Function DoRequestsFromXMLString(qbXMLRequest As String) As Object
Get QBXMLVersionsForSession() As Array
Function CreateSubscriptionMsgSetRequest(qbXMLMajorVersion As Integer, qbXMLMinorVersion As Integer) As Object
Function ToSubscriptionMsgSetResponse(qbXMLSubscriptionResponse As String, qbXMLMajorVersion As Integer, qbXMLMinorVersion As Integer) As Object
Function DoSubscriptionRequests(request As Object) As Object
Function DoSubscriptionRequestsFromXMLString(qbXMLSubscriptionRequest As String) As Object
Function ToEventsMsgSet(qbXMLEventsResponse As String, qbXMLMajorVersion As Integer, qbXMLMinorVersion As Integer) As Object
Function ToMsgSetRequest(qbXMLRequest As String) As Object
Function IsErrorRecoveryInfo() As Boolean
Sub ClearErrorRecovery()
Let EnableErrorRecovery(Boolean)
Get EnableErrorRecovery() As Boolean
Let SaveAllMsgSetRequestInfo(Boolean)
Get SaveAllMsgSetRequestInfo() As Boolean
Function GetErrorRecoveryStatus() As Object
Function GetSavedMsgSetRequest() As Object
Get ErrorRecoveryID() As Object
Get ConnectionType() As ENConnectionType
Sub OpenConnection2(AppID As String, AppName As String, connType As ENConnectionType)
Get QBAuthPreferences() As Object
Sub CommunicateOutOfProcess(useOutOfProc As Boolean)
Sub CommunicateOutOfProcessEx(useOutOfProc As Boolean, outOfProcCLSID As String)
Get QBXMLVersionsForSubscription() As Array


Code: ScriptBasic
  1. import com.inc
  2.  
  3. oQBSession = CreateObject("QBFC13.QBSessionManager")
  4.  
  5. print "Typename = ", TypeName(oQBSession), "\n"
  6.  
  7. print "Launching DescribeInterface dialog...\n"
  8. DescribeInterface oQBSession
  9.  
  10. print "Shutting down QuickBooks and releasing object...\n"
  11. CallByName(oQBSession, "Quit")
  12. ReleaseObject(oQBSession)
  13.  

According to the interface viewer, BeginSession is a SUB and doesn't return a value.

I also found this reference for the QBFC13.dll. (QuickBooks SDK Foundation Classes)
« Last Edit: October 26, 2015, 11:37:46 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #6 on: October 27, 2015, 12:04:59 AM »
I found this code snippet in the QBFC Programmers Guide.

Quote
Some Commentary on the QBFC Code Snippet

The same commentary provided for the qbXML snippet above applies here. One interesting difference you’ll notice is the absence of the session ticket when you use QBFC. That is managed automatically by QBFC

QBSDK_ProGuide.pdf
« Last Edit: October 27, 2015, 12:39:03 AM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #7 on: October 27, 2015, 12:25:13 AM »
I think I'm close. All I need to do now is figure out how to return a string response from the object being returned. I know it's working due to the delay reading the QuickBooks database and building the response buffer.

Code: ScriptBasic
  1. import COM.inc
  2.  
  3. oqbXMLRP = CreateObject("QBFC13.QBSessionManager.1")
  4. PRINT "oqbXMLRP: ", oqbXMLRP,"\n"
  5.  
  6. CallByName(oqbXMLRP, "OpenConnection", vbMethod, "", "Script BASIC")
  7. CallByName(oqbXMLRP, "BeginSession", vbMethod, "", 2)
  8.  
  9. xml_request = """
  10. <?qbxml version="8.0"?>
  11. <QBXML>
  12.   <QBXMLMsgsRq onError="stopOnError">
  13.      <AccountQueryRq requestID="1">
  14.      </AccountQueryRq>
  15.   </QBXMLMsgsRq>
  16. </QBXML>
  17. """
  18.  
  19. response = CallByName(oqbXMLRP, "DoRequestsFromXMLString", vbMethod, xml_request)
  20.  
  21. PRINT response,"\n"
  22.  
  23. CallByName(oqbXMLRP, "EndSession", vbMethod)
  24. CallByName(oqbXMLRP, "CloseConnection", vbMethod)
  25.  


C:\qbooks>scriba getaccounts.sb
oqbXMLRP: 22304124
22307888

C:\qbooks>


QBFC Quick Reference
« Last Edit: October 27, 2015, 12:35:22 AM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #8 on: October 27, 2015, 01:17:48 AM »
Success!

Code: ScriptBasic
  1. IMPORT COM.inc
  2.  
  3. oqbXMLRP = VBNEW("QBFC13.QBSessionManager.1")
  4. VBCALL oqbXMLRP, "OpenConnection", vbMethod, "", "Script BASIC"
  5. VBCALL oqbXMLRP, "BeginSession", vbMethod, "", 2
  6.  
  7. xml_request = """
  8. <?qbxml version="8.0"?>
  9. <QBXML>
  10.   <QBXMLMsgsRq onError="stopOnError">
  11.      <AccountQueryRq requestID="1">
  12.      </AccountQueryRq>
  13.   </QBXMLMsgsRq>
  14. </QBXML>
  15. """
  16.  
  17. oResponse = VBCALL(oqbXMLRP, "DoRequestsFromXMLString", vbMethod, xml_request)
  18. xml_str = VBCALL(oResponse, "ToXMLString", vbMethod)
  19.  
  20. PRINT xml_str,"\n"
  21.  
  22. VBCALL oqbXMLRP, "EndSession", vbMethod
  23. VBCALL oqbXMLRP, "CloseConnection", vbMethod
  24. VBREL oResponse
  25. VBREL oqbXMLRP
  26.  


Note: Full response too large to post. This is the end of the response string returned.

<AccountRet>
<ListID>6A0002-1047416097</ListID>
<TimeCreated>2003-03-11T13:54:57-08:00</TimeCreated>
<TimeModified>2017-12-15T04:37:17-08:00</TimeModified>
<EditSequence>1513341437</EditSequence>
<Name>Purchase Orders</Name>
<FullName>Purchase Orders</FullName>
<IsActive>true</IsActive>
<Sublevel>0</Sublevel>
<AccountType>NonPosting</AccountType>
<SpecialAccountType>PurchaseOrders</SpecialAccountType>
<AccountNumber>2</AccountNumber>
<Balance>0.00</Balance>
<TotalBalance>0.00</TotalBalance>
<CashFlowClassification>NotApplicable</CashFlowClassification>
</AccountRet>
<AccountRet>
<ListID>8B0002-1047429302</ListID>
<TimeCreated>2003-03-11T17:35:02-08:00</TimeCreated>
<TimeModified>2017-12-15T04:37:17-08:00</TimeModified>
<EditSequence>1513341437</EditSequence>
<Name>Sales Orders</Name>
<FullName>Sales Orders</FullName>
<IsActive>true</IsActive>
<Sublevel>0</Sublevel>
<AccountType>NonPosting</AccountType>
<SpecialAccountType>SalesOrders</SpecialAccountType>
<AccountNumber>5</AccountNumber>
<Balance>0.00</Balance>
<TotalBalance>0.00</TotalBalance>
<CashFlowClassification>NotApplicable</CashFlowClassification>
</AccountRet>
</AccountQueryRs>
</QBXMLMsgsRs>
</QBXML>


C:\qbooks>
« Last Edit: October 29, 2015, 12:39:59 AM by John »

Mike Lobanovsky

  • Guest
Re: Quickbooks SDK
« Reply #9 on: October 28, 2015, 01:28:23 PM »
Congrats! :)

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Quickbooks SDK
« Reply #10 on: October 28, 2015, 02:31:30 PM »
Thanks but all the honours belong to Dave Zimmer and his amazing VB/C skills.

I'm working on translating the IDN SDK example  of creating a Sales Order in Script BASIC for QuickBooks. I'm starting to get my COM legs back.  :)

Here is a video clip of how to create a web based eCommerce (shopping cart) application and interface to QuickBooks.



« Last Edit: October 28, 2015, 03:13:26 PM by John »