FormerMember

Object Reference Pointers

Posted By FormerMember

Within the ProvideX environment Sage 100 references their objects by an ID value starting at 100001 for SY_Session. When scripting is used, does 100 create an OLE reference (iDispatch pointer) to the object and pass that to WScript Host?  If so what is the variable name in ProvideX for the iDispatch pointer to the object?

Parents
  • FormerMember
    FormerMember

    Anyone?

    Should I assume that 100 is only passing state variables to the Script and it's the language or hosting environment creating its own set of COM  objects based on iDispatch pointers?

    Is Sage 100 BO just a custom object (OOP) implementation and the OLE layer is provided by PVXCOM.DLL? ProvideX native doesn't communicate with its objects internally via iDispatch and uses its internal ID references.

    Let me simplify my request. When are iDispatch pointers created when using customizer VBScript based scripts?

  • FormerMember
    FormerMember in reply to FormerMember

    This is encouraging but doesn't return an iDispatch pointer but the internal ProvideX object reference ID.

    obus = COM::CBN(osession, "nGetObject", :CALL, "AR_Customer_bus")
    PRINT obus, "\n" 

    C:\ScriptBasic\examples>sbc showcust.sb
    100063

    C:\ScriptBasic\examples>

    This is a list of the object handles from an OLE interface standpoint.

    C:\ScriptBasic\examples>sbc showcust.sb
    oscript: 8518836
    osession: 8517324
    oui: 8518404
    obus: 100063

    C:\ScriptBasic\examples>

    The obus object handle was returned from the GetObject method call.

    It sure would be nice to get a clear explanation of when OLE and the iDispatch interface comes into play. 

  • FormerMember
    FormerMember in reply to FormerMember

    I can create a Customer Maintenance screen (or any other) externally via BOI as if it was created via the 100 Launcher. Doing it this way I have iDispatch references to objects and my NOMADS events can callback to ScriptBasic functions to process the customization scripting. Downside is you need to create your own launcher for your custom 100 screens, 

    The ScriptBasic COM extension module already has a simplified C external function to callback to ScriptBasic's user functions and subs from ProvideX NOMADS events as a DLL call.

  • FormerMember
    FormerMember in reply to FormerMember

    Question: I have been pondering how I can use BOI external 100 module generation without a Sage 100 Launcher. Upside down

    Answer: Use a BI application like DataSelf to pop a Customer Maintenance screen if a customer code / name is clicked. This would work for Sales Orders, Invoicing or anything else Sage 100 has to offer. Sunglasses

    External BOI scripting offers a lot of possibilities.

  • FormerMember
    FormerMember in reply to FormerMember

    This has been a fun ride trying to find a way to use ScriptBasic as an internal scripting language. After giving up with trying to pass iDispatch pointers to objects I was ready to concede to using ScriptBasic for external BOI only. Then it hit me, why not use INVOKE WAIT to run ScriptBasic Windows to process the event. The Execute method of oScript can take you a long ways. A typical ScriptBasic script would execute in under 1/2 a second.

    This is still in theory phase as I still need to see if I can access the ProvideX objects of the running module with a PVXCOM connection from ScriptBasic. I'm not overly optimistic until I see objects. 

    Here is the code to run ScriptBasic.

    This is the pvxarg.sb script

    DECLARE SUB DLL ALIAS "dyc" LIB "dyc"                                                      
                                                                                               
    pvx_ss = COMMAND()                                                                         
                                                                                               
    DLL("ms,i,USER32.DLL,MessageBox,PZZL", 0, "ProvideX %SYS_SS = " & pvx_ss, "ScriptBasic", 0)
    

    This version gets the %SYS_SS from ProvideX using PVXCOM.

    DECLARE SUB DLL ALIAS "dyc" LIB "dyc"
    IMPORT COM.sbi
    
    oscript = COM::CREATE(:SET, "ProvideX.Script")
    COM::CBN oScript, "Init", :CALL, "C:\\Sage\\Sage 100 Standard\\MAS90\\Home"
    osession = COM::CBN(oscript, "NewObject", :SET, "SY_Session")
    COM::CBN osession, "nSetUser", :CALL, "UserID", "Password"
    COM::CBN osession, "nsetcompany", :CALL, "ABC"
    COM::CBN osession, "nSetModule", :CALL, "A/R"
    mdate = COM::CBN(osession, "sModuleDate", :GET)
    COM::CBN osession, "nSetDate", :CALL, "A/R", mdate
    
    pvx_ss = COM::CBN(oscript, "Evaluate", :CALL, "%SYS_SS")
    
    PRINT DLL("ms,i,USER32.DLL,MessageBox,PZZL", 0, "ProvideX %SYS_SS = " & pvx_ss, "ScriptBasic", 0)
    
    COM::CBN osession, "DropObject", :CALL
    COM::RELEASE osession
    COM::RELEASE oscript

  • FormerMember
    FormerMember in reply to FormerMember

    I don't think this is going to work as PVXCOM is its own instance of ProvideX with no connection to the current ruining module. It would be great if I could 'store' a proxy of the running objects for the PVXCOM connection.

    In this case ScriptBasic would be a DLL call in the same process as ProvideX is running.

  • FormerMember
    FormerMember in reply to FormerMember

    I have been tryiing to get a COM pointer using DEF OBJECT "ss_proxy, "*PROXY" and a ASOBJECT() method call with no luck. Can someone post a ProvideX script showing how this is done.?

  • FormerMember
    FormerMember in reply to FormerMember

    If you are looking for a way to expand the scope of Sage 100 without 100 source code modifications, ActiveX / OCX controls provide a seamless interface with your UI and BOI efforts. As a bonus these OCX controls can callback to ScriptBasic's function / sub routines on events for processing.

    Postgres SQL Mirroring is a great example of this direction in action.

  • FormerMember
    FormerMember in reply to FormerMember

    The 100 scripting docs indicate that ProvideX based scripts are executed one line at a time. Multi-line statements or line numbers aren't permitted.

    If you CALL your (text) script these limitations don't seem to apply. Active object access from this called script is what I'm currently looking at. I hope this doesn't turn into another dead end.

    test.pvs

  • FormerMember
    FormerMember in reply to FormerMember

    This might just work.

    ENTER ssobj
    MSGBOX  "Company Code: " + ssobj'CompanyCode$ + $0D0A$ + "Company Name: " + ssobj'CompanyName$,"ProvideX"
    EXIT
    

    Getting the object ID's to make further method and property calls seems available to the CALL program.
    ENTER ssobj
    MSGBOX STR(ssobj'GetObject("AR_CUSTOMER_BUS")) + " | " + STR(ssobj'GetObject("AR_CUSTOMER_SVC")) + " | " + STR(ssobj'GetObject("AR_CUSTOMER_UI")),"ProvideX"
    EXIT
  • FormerMember
    FormerMember in reply to FormerMember

    It seems I needed to do a PERFORM instead of a CALL to achieve the results I was looking for. ProvideX scripts definitely have an advantage over VBScript in a WSH container. Running scripts in this manner removes the "where do I need to run my script, on the client or the server".

    I highly recommend not trying this on a production 100 install until more testing has been done to validate that this direction isn't stepping on any 100 default logic.

    test.pvs

    MSGBOX CUSTOMERNO$ + $0A0D$ + CUSTOMERNAME$,"PVX-100"
    EXIT

  • in reply to FormerMember

    In a button script, the proper way to do that would be to set the MAS_SCR_PFM variable to the path to your script file to be PERFORM'ed.  This could be done using VBScript or JScript as the language.  The PERFORM'ed file will have access to all of the variables. 

    The other way to PERFORM your own file is to set the button up as a DDE link, in the application, type *PERFORM, in the topic, type the path (relative is supported) to your script file to be PERFORM'ed.

    Here is the content of TestStarPerform.pl.

    If _obj <> 0 Then {
    	MsgBox Str(_obj) + Sep + _obj'_class$
    }

Reply
  • in reply to FormerMember

    In a button script, the proper way to do that would be to set the MAS_SCR_PFM variable to the path to your script file to be PERFORM'ed.  This could be done using VBScript or JScript as the language.  The PERFORM'ed file will have access to all of the variables. 

    The other way to PERFORM your own file is to set the button up as a DDE link, in the application, type *PERFORM, in the topic, type the path (relative is supported) to your script file to be PERFORM'ed.

    Here is the content of TestStarPerform.pl.

    If _obj <> 0 Then {
    	MsgBox Str(_obj) + Sep + _obj'_class$
    }

Children
  • in reply to David Speck

    Also, you still need to be aware of certain things when on an Advanced install and need to script accordingly if you are dealing with anything other than the business objects.  You can set the MAS_SCR_PFM variable in a VBScript when it is running on either the client or the server so although you don't have to deal with the WSH aspect, you still need to be careful in your PERFORM'ed file to make sure you use the [wdx] flag when needed on an Advanced system and you want to interact with the workstation, such as DLLs or files.

  • FormerMember
    FormerMember in reply to David Speck

    Thanks David for your tips and cautions.

    I like your DDE suggestion. No need for NOMADS tricks.

    I"m trying to avoid having to do any scripting in a WSH control.

  • FormerMember
    FormerMember in reply to FormerMember

    Needs more work. The change isn't saved with the Accept of the record. If I switch tabs it doesn't save the change either.

    All variables that are changed or created during execution of the performed subprogram will be returned to the initiating program

    LET ADDRESSLINE2$="Hello from the PERFORM script."
    EXIT
    

  • FormerMember
    FormerMember in reply to FormerMember

    We got it to work. This saves the change when ACCEPT is clicked or a folder / tab is changed,

    Thanks David!

    rv=_obj'InvokeChange("ADDRESSLINE2$","Hello from the PERFORM script.")
    EXIT
    

  • FormerMember
    FormerMember in reply to FormerMember

    This is an example of calling ScriptBasic as a DLL from my Test Button in Customer Maintence.

    test.pvs

    rtn = DLL("sbscript.dll","sb","\ScriptBasic\examples\dllscript.sb" + $00$,"Hello ScriptBasic DLL" + $00$)
    EXIT
    

    dllscript.sb

    ' ScriptBasic DLL Script

    DECLARE SUB DLL ALIAS "dyc" LIB "dyc"

    cmd = COMMAND()

    DLL("ms,i,USER32.DLL,MessageBox,PZZL", 0, cmd & CHR(0), "ScriptBasic", 0)

  • FormerMember
    FormerMember in reply to FormerMember

    It looks like this thread has been repaired. 

    I also wanted to mention that ProvideX can return Windows pointers to it's variables with the MEM() function. This allows your ScriptBasic DLL based script to return results to ProvideX to be processed on the return of the ScriptBasic call.