Recent Posts

Pages: [1] 2 3 ... 10
1
Script BASIC / Re: ScriptBasic HTML Extension Module
« Last post by John Spikowski on November 28, 2021, 06:04:30 AM »
I found a great open source Bootstrap theme I plan to base the NOMADS replacement on.  Check out the menu options to show the interface components. Try it on your PC and phone.

Quote
Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.

Bootstrap was developed and being used by Twitter.

FYI Bootstrap 5 > no longer requires jQuery as a dependency. Using one framework makes my encapsulation much easier. 

Bootstrap Spur Demo



2
Script BASIC / Re: ScriptBasic HTML Extension Module
« Last post by John Spikowski on November 15, 2021, 09:53:30 PM »
I found a nice JQuery and Bootstap JavaScript routine to create resizable and moveable popup forms. I plan to used this with my ScriptBasic HTML extension module to create popup modal dialogs for functions like look-ups and previews.

I really like the Bootstrap framework for building form based browser applications. The library touts mobile first as their motto.

I'm looking forward to see if I can get Sage 100 working as a browser application using BOI and eliminating NOMADS.

Example  (right click / view source) to see how it's done.

I need to add an extension to Bootstrap to allow this to work on a phone. I'll update the example soon.


3
Script BASIC / ScriptBasic HTML Extension Module
« Last post by John Spikowski on November 14, 2021, 08:33:45 PM »
I've started work on a new extension module for the Business Application Server. (BAS)  The goal of the HTML extension module is to render HTML/JavaScript-AJAX/CSS page elements as extension module method calls and property settings. I'm going to use the IUP design concept for container and control rendering. This will allow desktop BASIC programmers to create browser applications with little knowledge of web programming.

I'm happy to report that the ScriptBasic COM extension module works great with the application server. You just can't instantiate any Windows UI components. (warning but obvious) It seems to work fine with BOI. Here is an example.

Code: Script BASIC
  1. ' BOI Customer Contact - Web Page
  2.  
  3. IMPORT cgi.sbi
  4. IMPORT com.sbi
  5.  
  6. cgi::Header 200,"text/html"
  7. cgi::FinishHeader
  8.  
  9. PRINT """
  10. <html>
  11. <header>
  12. <title>ScriptBasic 100 BOI</title>
  13. </header>
  14. <body>
  15. <table>
  16. <center><h1>ABC - Customer Contacts</h1></center>
  17. <table style="width:100%">
  18.  <tr>
  19.    <th>Customer Number</th>
  20.    <th>Company Name</th>
  21.    <th>Phone Number</th>
  22.  </tr>
  23. """
  24.  
  25. oscript = COM::CREATE(:SET, "ProvideX.Script")
  26. COM::CBN oScript, "Init", :CALL, "C:\\Sage\\Sage 100 Standard\\MAS90\\Home"
  27. osession = COM::CBN(oscript, "NewObject", :SET, "SY_Session")
  28. COM::CBN osession, "nSetUser", :CALL, "USER", "PASSWORD"
  29. COM::CBN osession, "nsetcompany", :CALL, "ABC"
  30. COM::CBN osession, "nSetDate", :CALL, "A/R", "20210722"
  31. COM::CBN osession, "nSetModule", :CALL, "A/R"
  32. ocust = COM::CBN(oscript, "NewObject", :SET, "AR_Customer_svc",  osession)
  33.  
  34. COM::CBN ocust,"nMoveFirst"
  35. DO UNTIL COM::CBN(ocust, "nEOF", :GET)
  36.   PRINT "  <tr>\n"
  37.   PRINT "    <td>", COM::CBN(ocust, "sARDIVISIONNO", :GET), "-", COM::CBN(ocust, "sCUSTOMERNO", :GET), "</td>\n"
  38.   PRINT "    <td>", COM::CBN(ocust, "sCUSTOMERNAME", :GET), "</td>\n"
  39.   PRINT "    <td>", COM::CBN(ocust, "sTELEPHONENO", :GET), "</td>\n"
  40.   COM::CBN ocust, "nMoveNext"
  41.   PRINT "  </tr>\n"
  42. LOOP
  43.  
  44. PRINT """
  45. </table>
  46. </body>
  47. </html>
  48. """
  49.  
  50. COM::CBN ocust, "DropObject"
  51. COM::RELEASE ocust
  52. COM::CBN osession, "DropObject"
  53. COM::RELEASE osession
  54. COM::RELEASE oscript
  55.  


Stay tuned, more to come.
4
Open Forum / Sage 100 Hosting
« Last post by John Spikowski on September 08, 2021, 11:40:27 PM »
I started a thread on Sage City about hosting options for Sage 100. Kevin complained that I was spamming the forum with my hosting preference. It seems half the partner base is offering some level of hosting services. In a nutshell hosting is renting someone else's computer to run your applacation so you don't have to. Hosting options vary with price and services provided. The larger players are replacing the partner as part of the on-boarding process to provide updates and resolve functionality issues. This is beyond the monthly hosting fees which doubles the cost of Sage 100 subscription fees. Most of the top tier hosting providers are using VMWare which adds another layer to the OS. To be profitable at hosting you need a lot of clients generating revenue with the hope things stay running on its own.   

A better option in my opinion is using an AWS EC2 instance which you own and control access to. This is the most reliable and secure option going. Amazon doesn't go cheap with their data centers. With a one-click install of a Windows Server 2016 instance AMI (Amazon Machine Image) everything is setup and ready to install your Sage 100 software and data. If your server instance runs 24/7 you are looking at a cost of around $150 / month. (much less if you hibernate your instance off hours) This hosting option allows you to use your existing Sage partner (or someone of your choosing) and Sage support to maintain your Sage software. AWS offers affordable support billed monthly. No long term contracts. You will have a one time RDS (Remote Desktop Server) license to buy based on the number of users needing shared access.

I offer my services as a migration project manager which can save you a lot of time. I have been using AWS EC2 for about 12 years hosting multiple open source projects.

Contact Info:

e-mail@johnspikowski.com
360-941-0452 (cell/text)
5
Script BASIC / VB6 OCX GUI
« Last post by John Spikowski on July 04, 2021, 05:48:35 PM »
This is an example of the OnLine Dictionary done with ScriptBasic and using a VB6 generated OCX for the UI. I also added resizing to this example.

OLD.sb
Code: Script BASIC
  1. IMPORT COM.sbi
  2.  
  3. servers[0]="dict.org"
  4. servers[1]="dict1.us.dict.org"
  5. servers[2]="all.dict.org"
  6.  
  7. FUNCTION btnFetch_Clicked
  8.   LOCAL dat, total, count
  9.   server_selection = COM::CBN(obj, "CurrentServer")
  10.   OPEN server_selection & ":2628" FOR SOCKET AS #1
  11.   PRINT#1,"SHOW DB\n"
  12.   LINE INPUT#1, dat
  13.   LINE INPUT#1, dat
  14.   count = 0
  15.   WHILE LEFT(dat, 1) <> "."
  16.     LINE INPUT#1, dat
  17.     IF LEFT(dat, 1) <> "." THEN total[count] = TRIM(dat)
  18.     count+=1
  19.   WEND
  20.   PRINT#1,"QUIT\n"
  21.   CLOSE(#1)
  22.   FOR cnt = 0 TO count - 2
  23.     COM::CBN obj, "AddDictionaries", :CALL, total[cnt]
  24.   NEXT
  25.   COM::CBN obj, "DefaultDictionary"
  26.   btnFetch_Clicked = TRUE
  27.   EXIT FUNCTION
  28.  
  29.  
  30. FUNCTION btnSearch_clicked
  31.   LOCAL dict, dat, total, info
  32.   whichDictionary = COM::CBN(obj, "CurrentDictionary")
  33.   searchword = COM::CBN(obj, "SearchWord", :GET)
  34.   dict = LEFT(whichDictionary, INSTR(whichDictionary, " "))
  35.   OPEN COM::CBN(obj, "CurrentServer") & ":2628" FOR SOCKET AS 1
  36.   IF COM::CBN(obj, "AllDict", :GET) THEN
  37.     PRINT#1,"DEFINE * " & searchword & "\n"
  38.   ELSE
  39.     PRINT#1,"DEFINE " & dict & " " & searchword & "\n"
  40.   END IF
  41.   REPEAT
  42.     LINE INPUT#1, dat
  43.     IF LEFT(dat, 3) = "151" THEN
  44.       total$ &= "------------------------------\r\n"
  45.       total$ &= RIGHT(dat, LEN(dat) - LEN(searchword) - LEN(dict))
  46.       total$ &= "------------------------------\r\n"
  47.       REPEAT
  48.         LINE INPUT#1, info
  49.         info = REPLACE(info, CHR(34), CHR(92) & CHR(34))
  50.         IF LEFT(info, 1) <> "." THEN total &= TRIM(info) & "\r\n"
  51.       UNTIL LEFT(info, 1) = "."
  52.       total &= "\r\n"
  53.     END IF
  54.   UNTIL LEFT(dat, 3) = "250" OR VAL(LEFT(dat, 3)) > 499
  55.   PRINT#1,"QUIT\n"
  56.   CLOSE(#1)
  57.   IF LEFT(dat, 3) = "552" THEN
  58.     total = "No match found."
  59.   ELSE IF LEFT(dat, 3) = "501" THEN
  60.     total = "Select a dictionary first!"
  61.   ELSE IF LEFT(dat, 3) = "550" THEN
  62.     total = "Invalid database!"
  63.   END IF
  64.   COM::CBN(obj, "SetTranslation", :CALL, total)
  65.   btnSearch_Clicked = TRUE
  66. EXIT FUNCTION
  67.  
  68. ' MAIN
  69.  
  70. obj = COM::CREATE(:SET, "OLD.OLDict")
  71. oCollection = COM::CBN(obj, "CallBackHandlers", :GET)
  72. COM::CBN oCollection, "Add", :CALL, ADDRESS(btnFetch_Clicked()), "win.btnFetch_Click"
  73. COM::CBN oCollection, "Add", :CALL, ADDRESS(btnSearch_Clicked()), "win.btnSearch_Click"
  74. FOR idx = 0 TO UBOUND(servers)
  75.   COM::CBN obj, "AddServer", :CALL, servers[idx]
  76. NEXT  
  77. COM::CBN obj, "DefaultServer"
  78. COM::CBN obj, "ShowOLD"
  79. COM::RELEASE obj
  80.  

VB6 Form
Code: Visual Basic
  1. Private Declare Function ext_SBCallBack Lib "COM.dll" Alias "SBCallBack" (ByVal EntryPoint As Long, ByVal arg As Long) As Long
  2. Private Declare Function ext_SBCallBackEx Lib "COM.dll" Alias "SBCallBackEx" (ByVal EntryPoint As Long, ByRef v As Variant) As Variant
  3.  
  4. Private m_owner As OLDict
  5. Private Type ControlPositionType
  6.     Left As Single
  7.     Top As Single
  8.     Width As Single
  9.     Height As Single
  10.     FontSize As Single
  11. End Type
  12.  
  13. Private m_ControlPositions() As ControlPositionType
  14. Private m_FormWid As Single
  15. Private m_FormHgt As Single
  16.  
  17.  
  18. Function ShowMain(owner As OLDict) As Long
  19.     On Error Resume Next
  20.     Set m_owner = owner
  21.     Me.Show 1
  22.     Set m_owner = Nothing
  23.     ShowMain = 0
  24.     Unload Me
  25. End Function
  26.  
  27. Private Function TriggerCallBack(nodeID As Long, argValue As Long) As Long
  28.     TriggerCallBack = ext_SBCallBack(nodeID, argValue)
  29. End Function
  30.  
  31. Private Function TriggerCallBackEx(nodeID As Long, v() As Variant)
  32.     TriggerCallBackEx = ext_SBCallBackEx(nodeID, v)
  33. End Function
  34.  
  35. Public Sub btnClear_Click()
  36.     win.serverList.Clear
  37.     win.dictTB.Text = ""
  38.     win.entry.Text = ""
  39.     win.btnFetch.SetFocus
  40.     End Sub
  41.  
  42. Private Sub btnExit_Click()
  43.     Set m_owner = Nothing
  44.     btnExit = 0
  45.     Unload Me
  46. End Sub
  47.  
  48. Private Sub btnFetch_Click()
  49.     Dim nodeID As Long
  50.     Dim arg As Long
  51.     Dim rtnVal As Long
  52.    
  53.     win.serverList.Clear
  54.     nodeID = m_owner.CallBackHandlers("win.btnFetch_Click")
  55.     arg = False
  56.     rtnVal = TriggerCallBack(nodeID, arg)
  57. End Sub
  58.  
  59. Private Sub btnSearch_Click()
  60.     Dim nodeID As Long
  61.     Dim arg As Long
  62.     Dim rtnVal As Long
  63.    
  64.     nodeID = m_owner.CallBackHandlers("win.btnSearch_Click")
  65.     arg = False
  66.     rtnVal = TriggerCallBack(nodeID, arg)
  67. End Sub
  68.  
  69. Private Sub btnAbout_Click()
  70.     MsgBox "Script BASIC VB6" & vbCrLf & "On Line Dictionary", vbInformation, "About"
  71. End Sub
  72.  
  73.  
  74. ' Save the form's and controls' dimensions.
  75. Private Sub SaveSizes()
  76. Dim i As Integer
  77. Dim ctl As Control
  78.  
  79.     ' Save the controls' positions and sizes.
  80.    ReDim m_ControlPositions(1 To Controls.Count)
  81.     i = 1
  82.     For Each ctl In Controls
  83.         With m_ControlPositions(i)
  84.             If TypeOf ctl Is Line Then
  85.                 .Left = ctl.X1
  86.                 .Top = ctl.Y1
  87.                 .Width = ctl.X2 - ctl.X1
  88.                 .Height = ctl.Y2 - ctl.Y1
  89.             Else
  90.                 .Left = ctl.Left
  91.                 .Top = ctl.Top
  92.                 .Width = ctl.Width
  93.                 .Height = ctl.Height
  94.                 On Error Resume Next
  95.                 .FontSize = ctl.Font.Size
  96.                 On Error GoTo 0
  97.             End If
  98.         End With
  99.         i = i + 1
  100.     Next ctl
  101.  
  102.     ' Save the form's size.
  103.    m_FormWid = ScaleWidth
  104.     m_FormHgt = ScaleHeight
  105. End Sub
  106.  
  107. Private Sub Form_Load()
  108.     SaveSizes
  109. End Sub
  110.  
  111. Private Sub Form_Resize()
  112.     ResizeControls
  113. End Sub
  114.  
  115. ' Arrange the controls for the new size.
  116. Private Sub ResizeControls()
  117. Dim i As Integer
  118. Dim ctl As Control
  119. Dim x_scale As Single
  120. Dim y_scale As Single
  121.  
  122.     ' Don't bother if we are minimized.
  123.    If WindowState = vbMinimized Then Exit Sub
  124.  
  125.     ' Get the form's current scale factors.
  126.    x_scale = ScaleWidth / m_FormWid
  127.     y_scale = ScaleHeight / m_FormHgt
  128.  
  129.     ' Position the controls.
  130.    i = 1
  131.     For Each ctl In Controls
  132.         With m_ControlPositions(i)
  133.             If TypeOf ctl Is Line Then
  134.                 ctl.X1 = x_scale * .Left
  135.                 ctl.Y1 = y_scale * .Top
  136.                 ctl.X2 = ctl.X1 + x_scale * .Width
  137.                 ctl.Y2 = ctl.Y1 + y_scale * .Height
  138.             Else
  139.                 ctl.Left = x_scale * .Left
  140.                 ctl.Top = y_scale * .Top
  141.                 ctl.Width = x_scale * .Width
  142.                 If Not (TypeOf ctl Is ComboBox) Then
  143.                     ' Cannot change height of ComboBoxes.
  144.                    ctl.Height = y_scale * .Height
  145.                 End If
  146.                 On Error Resume Next
  147.                 ctl.Font.Size = y_scale * .FontSize
  148.                 On Error GoTo 0
  149.             End If
  150.         End With
  151.         i = i + 1
  152.     Next ctl
  153. End Sub
  154.  

VB6 Class
Code: Visual Basic
  1. Public CallBackHandlers As New Collection
  2.  
  3. Public Function ShowOLD() As Long
  4.     ShowOLD = win.ShowMain(Me)
  5. End Function
  6.  
  7. Public Sub AddServer(server_url As String)
  8.     win.serverCombo.AddItem server_url
  9. End Sub
  10.  
  11. Public Sub DefaultServer()
  12.     win.serverCombo.ListIndex = 0
  13. End Sub
  14.  
  15. Public Function CurrentServer() As String
  16.     CurrentServer = win.serverCombo.List(win.serverCombo.ListIndex)
  17. End Function
  18.  
  19. Public Sub AddDictionaries(dictionary As String)
  20.     win.serverList.AddItem dictionary
  21. End Sub
  22.  
  23. Public Function CurrentDictionary() As String
  24.     CurrentDictionary = win.serverList.List(win.serverList.ListIndex)
  25. End Function
  26.  
  27. Public Sub DefaultDictionary()
  28.     win.serverList.ListIndex = 0
  29. End Sub
  30.  
  31. Public Sub SetTranslation(translation_text As String)
  32.     win.dictTB.Text = translation_text
  33. End Sub
  34.  
  35. Public Property Get SearchWord() As String
  36.     win.dictTB.SetFocus
  37.     SearchWord = win.entry.Text
  38. End Property
  39.  
  40. Public Property Get AllDict() As Long
  41.     AllDict = win.chkAll.Value
  42. End Property
  43.  
6
Script BASIC / IUP GUI
« Last post by John Spikowski on July 02, 2021, 09:08:31 PM »
A way to expand on your Sage 100 application is using the cross platform, open source IUP (Portable User Interface) library with ScriptBasic. This is an example of an online dictionary UI.

Code: Script BASIC
  1. ' IUP Online Dictionary
  2.  
  3. IMPORT iup.sbi
  4.  
  5. servers[0]="dict.org"
  6. servers[1]="dict1.us.dict.org"
  7. servers[2]="all.dict.org"
  8.  
  9. about="""This is a Demo
  10. of the IUP GUI Binding
  11. for Scriptbasic"""
  12.  
  13. ' Initialize IUP
  14. Iup::Open()
  15.  
  16. ' Create main window
  17.  
  18. win = Iup::Create("dialog")
  19.   Iup::SetAttributes(win, "TITLE=\"ScriptBasic IUP Online Dictionary\", SIZE=500x300")
  20.   Iup::SetCallback(win,"CLOSE_CB",ADDRESS(Win_exit()))
  21.  
  22. ' Create container to house ALL GUI objects
  23.  
  24. vbox = Iup::Create("vbox")
  25.   Iup::SetAttributes(vbox, "MARGIN=10x10")
  26.  
  27. ' Create server panel
  28.  
  29. topBox = Iup::Create("hbox")
  30.   Iup::SetAttributes(topBox, "GAP=10")
  31.   Iup::Append(vbox, topBox)
  32. serverFrame = Iup::Create("frame")
  33.   Iup::SetAttributes(serverFrame, "TITLE=Servers, EXPAND=YES")
  34.   Iup::Append(topBox, serverFrame)
  35. serverBox = Iup::Create("hbox")
  36.   Iup::SetAttributes(serverBox, "GAP=5")
  37.   Iup::Append(serverFrame, serverBox)
  38. serverCombo = Iup::Create("list")
  39.   Iup::SetAttributes(serverCombo, "DROPDOWN=YES, SIZE=120x, EXPAND=HORIZONTAL, VALUE=1")
  40.   Iup::Append(serverBox, serverCombo)
  41.   Iup::SetCallback(serverCombo, "ACTION", ADDRESS(serverCombo_selected()))
  42. btnFetch = Iup::Create("button")
  43.   Iup::SetAttributes(btnFetch, "TITLE=Fetch, SIZE = 50x")
  44.   Iup::Append(serverBox, btnFetch)
  45.   Iup::SetCallback(btnFetch, "ACTION", ADDRESS(btnFetch_clicked()))
  46.  
  47. ' Create control panel
  48.  
  49. controlFrame = Iup::Create("frame")
  50.   Iup::SetAttributes(controlFrame, "TITLE=Controls")
  51.   Iup::Append(topBox, controlFrame)
  52. controlBox = Iup::Create("hbox")
  53.   Iup::SetAttributes(controlBox, "GAP=5")
  54.   Iup::Append(controlFrame, controlBox)
  55. btnAbout = Iup::Create("button")
  56.   Iup::SetAttributes(btnAbout, "TITLE=About, SIZE = 50x")
  57.   Iup::Append(controlBox, btnAbout)
  58.   Iup::SetCallback(btnAbout, "ACTION", ADDRESS(btnAbout_clicked()))
  59. btnClear = Iup::Create("button")
  60.   Iup::SetAttributes(btnClear, "TITLE=Clear, SIZE = 50x")
  61.   Iup::Append(controlBox, btnClear)
  62.   Iup::SetCallback(btnClear, "ACTION", ADDRESS(btnClear_clicked()))
  63. btnExit = Iup::Create("button")
  64.   Iup::SetAttributes(btnExit, "TITLE=Exit, SIZE = 50x")
  65.   Iup::Append(controlBox, btnExit)
  66.   Iup::SetCallback(btnExit,"ACTION",ADDRESS(Win_exit()))
  67.  
  68. ' Create dictionary panel
  69.  
  70. dictFrame = Iup::Create("frame")
  71.   Iup::SetAttributes(dictFrame, "TITLE=Dictionaries")
  72.   Iup::Append(vbox, dictFrame)
  73. serverList = Iup::Create("list")
  74.   Iup::SetAttributes(serverList, "EXPAND=YES, VISIBLELINES=1")
  75.   Iup::Append(dictFrame, serverList)
  76.   Iup::SetCallback(serverList, "ACTION", ADDRESS(serverList_selected()))
  77.  
  78. ' Create text part
  79.  
  80. transFrame = IUP::Create("frame")
  81.   Iup::SetAttributes(transFrame, "TITLE=Translation")
  82.   Iup::Append(vbox, transFrame)
  83. text = Iup::Create("text")
  84.   Iup::SetAttributes(text, "MULTILINE=YES, EXPAND=YES")
  85.   Iup::Append(transFrame, text)
  86.  
  87. ' Create entry and search button
  88.  
  89. bottomBox = Iup::Create("hbox")
  90.   Iup::SetAttributes(bottomBox, "GAP=10")
  91.   Iup::Append(vbox, bottomBox)
  92. label = Iup::Create("label")
  93.   Iup::SetAttributes(label, "TITLE=\"Enter Word to Search For:\", SIZE=x12")
  94.   Iup::Append(bottomBox, label)
  95. entry = Iup::Create("text")
  96.   Iup::SetAttributes(entry, "EXPAND=HORIZONTAL")
  97.   Iup::Append(bottomBox, entry)
  98. btnSearch = Iup::Create("button")
  99.   Iup::SetAttributes(btnSearch,"TITLE=Search, SIZE=50x")
  100.   Iup::Append(bottomBox, btnSearch)
  101.   Iup::SetCallback(btnSearch, "ACTION", ADDRESS(btnSearch_clicked()))
  102. chkAll = Iup::Create("toggle")
  103.   Iup::SetAttributes(chkAll, "TITLE=ALL, SIZE=x12")
  104.   Iup::Append(bottomBox, chkAll)
  105. chkUTF = Iup::Create("toggle")
  106.   Iup::SetAttributes(chkUTF, "TITLE=UTF-8, SIZE=x12")
  107.   Iup::Append(bottomBox, chkUTF)
  108.  
  109. ' Add the main GUI container to the Window
  110.  
  111. Iup::Append(win, vbox)
  112.  
  113. ' Setup dialog defaults
  114.  
  115. Iup::Show(win)
  116. Iup::SetFocus(btnFetch)
  117. FOR i = 0 TO UBOUND(servers)
  118.   Iup::SetAttribute(serverCombo, "APPENDITEM", servers[i])
  119. NEXT
  120. Iup::SetAttribute(serverCombo, "VALUE", "1")
  121. Iup::Update(serverCombo)
  122. server_selection = servers[0]
  123.  
  124. ' Main processing loop
  125.  
  126. Iup::MainLoop()
  127. Iup::Close()
  128. END
  129.  
  130. ' Callback routines
  131.  
  132. SUB Win_exit
  133.   Iup::ExitLoop = TRUE
  134. END SUB
  135.  
  136. SUB btnAbout_clicked
  137.   Iup::Message("ABOUT", about)
  138. END SUB
  139.  
  140. SUB serverCombo_selected
  141.   server_selection = Iup::GetListText()
  142. END SUB
  143.  
  144. SUB serverList_selected
  145.   whichDictionary = Iup::GetListText()
  146. END SUB
  147.  
  148. SUB btnFetch_clicked
  149.   LOCAL dat, total, count
  150.   ON ERROR GOTO G_NetError
  151.   OPEN server_selection & ":2628" FOR SOCKET AS #1
  152.   PRINT#1,"SHOW DB\n"
  153.   LINE INPUT#1, dat
  154.   LINE INPUT#1, dat
  155.   count = 0
  156.   WHILE LEFT(dat, 1) <> "."
  157.     LINE INPUT#1, dat
  158.     IF LEFT(dat, 1) <> "." THEN total[count] = TRIM(dat)
  159.     count+=1
  160.   WEND
  161.   PRINT#1,"QUIT\n"
  162.   CLOSE(#1)
  163.   FOR cnt = 0 TO count - 2
  164.     Iup::SetAttribute(serverList, "APPENDITEM", total[cnt])
  165.   NEXT
  166.   Iup::SetAttribute(serverList, "VALUE", "1")
  167.   Iup::Update(serverCombo)
  168.   whichDictionary = total[0]
  169.   EXIT SUB
  170.  
  171.   G_NetError:
  172.   PRINT "Server ",server_selection," not available. (",ERROR,")\n"
  173. END SUB
  174.  
  175. SUB btnClear_clicked
  176.   Iup::ClearList(serverList)
  177.   Iup::SetAttribute(text, "VALUE", "")
  178.   Iup::SetAttribute(entry, "VALUE", "")
  179. END SUB
  180.  
  181. SUB btnSearch_clicked
  182.   LOCAL dict, dat, total, info
  183.   IUP::SetAttribute(text, "VALUE","Fetching....")
  184.   ON ERROR GOTO L_NetError
  185.   dict = LEFT(whichDictionary, INSTR(whichDictionary, " "))
  186.   OPEN server_selection & ":2628" FOR SOCKET AS 1
  187.   IF Iup::GetAttribute(chkAll, "VALUE") THEN
  188.     PRINT#1,"DEFINE * " & Iup::GetAttribute(entry,"VALUE") & "\n"
  189.   ELSE
  190.     PRINT#1,"DEFINE " & dict & " " & Iup::GetAttribute(entry,"VALUE") & "\n"
  191.   END IF
  192.   REPEAT
  193.     LINE INPUT#1, dat
  194.     IF LEFT(dat, 3) = "151" THEN
  195.       total$ &= "------------------------------\r\n"
  196.       total$ &= RIGHT(dat, LEN(dat) - LEN(Iup::GetAttribute(entry, "VALUE")) - LEN(dict))
  197.       total$ &= "------------------------------\r\n"
  198.       REPEAT
  199.         LINE INPUT#1, info
  200.         info = REPLACE(info, CHR(34), CHR(92) & CHR(34))
  201.         IF LEFT(info, 1) <> "." THEN total &= TRIM(info) & "\n"
  202.       UNTIL LEFT(info, 1) = "."
  203.       total &= "\n"
  204.     END IF
  205.   UNTIL LEFT(dat, 3) = "250" OR VAL(LEFT(dat, 3)) > 499
  206.   PRINT#1,"QUIT\n"
  207.   CLOSE(#1)
  208.   IF LEFT(dat, 3) = "552" THEN
  209.     total = "No match found."
  210.   ELSE IF LEFT(dat, 3) = "501" THEN
  211.     total = "Select a dictionary first!"
  212.   ELSE IF LEFT(dat, 3) = "550" THEN
  213.     total = "Invalid database!"
  214.   END IF
  215.   Iup::SetAttribute(text, "VALUE", total)
  216. EXIT SUB
  217.  
  218. L_NetError:
  219.   dat[0] = "Could not lookup word! (" & ERROR & ")"
  220.   Iup::SetAttribute(text, "VALUE", dat)
  221. END SUB
  222.  
7
Script BASIC / Re: ScriptLess Scripting
« Last post by John Spikowski on June 23, 2021, 02:28:39 PM »
Here is an example of creating the Sales Order entry screen in BOI.

Code: Script BASIC
  1. ' COM - BOI Sales Order
  2.  
  3. IMPORT COM.sbi
  4.  
  5. oscript = COM::CREATE(:SET, "ProvideX.Script")
  6. COM::CBN oScript, "Init", :CALL, "C:\\Sage\\Sage 100 Standard\\MAS90\\Home"
  7. osession = COM::CBN(oscript, "NewObject", :SET, "SY_Session")
  8. COM::CBN osession, "nSetUser", :CALL, "UserID", "Password"
  9. COM::CBN osession, "nsetcompany", :CALL, "ABC"
  10. COM::CBN osession, "nSetModule", :CALL, "S/O"
  11. mdate = COM::CBN(osession, "sModuleDate", :GET)
  12. COM::CBN osession, "nSetDate", :CALL, "S/O", mdate
  13. COM::CBN osession, "nSetProgram", :CALL, COM::CBN(osession, "nLookupTask", :CALL, "SO_SalesOrder_ui")
  14. oui = COM::CBN(oscript, "NewObject", :SET, "SO_SalesOrder_ui", osession)
  15. COM::CBN(oui, "nProcess", :CALL)
  16.  
  17. COM::CBN oui,"DropObject", :CALL
  18. COM::RELEASE oui
  19. COM::CBN osession, "DropObject", :CALL
  20. COM::RELEASE osession
  21. COM::RELEASE oscript
  22.  

8
Script BASIC / Re: ScriptLess Scripting
« Last post by John Spikowski on June 23, 2021, 01:23:32 AM »
After a lot of digging trying to create iDispatch pointers I could pass to ScriptBasic in a DLL call, it gets pretty ugly and I'm not sure the value created by ProvideX is actually an iDispatch pointer.

Code: [Select]
DEF OBJECT oSession_Proxy, "*PROXY";ON EVENT FROM oSession_Proxy PROCESS %SYS_SS;DEF OBJECT oSession_Variant, "*VARIANT";oSession_Variant'Val.Put(*oSession_Proxy);MSGBOX STR(oSession_Variant'Val)

See attached for the MSGBOX value.

I'm able to create a Customer Maintenance screen in ScriptBasic using BOI as if it was created from the 100 launcher. At least in this environment I have iDispatch pointers to all the 100 objects to script the screen in anyway I wish.

Code: Script BASIC
  1. ' COM - AR_Customer
  2.  
  3. IMPORT COM.sbi
  4.  
  5. oscript = COM::CREATE(:SET, "ProvideX.Script")
  6. COM::CBN oScript, "Init", :CALL, "C:\\Sage\\Sage 100 Standard\\MAS90\\Home"
  7. osession = COM::CBN(oscript, "NewObject", :SET, "SY_Session")
  8. COM::CBN osession, "nSetUser", :CALL, "UserID", "Password"
  9. COM::CBN osession, "nsetcompany", :CALL, "ABC"
  10. COM::CBN osession, "nSetModule", :CALL, "A/R"
  11. mdate = COM::CBN(osession, "sModuleDate", :GET)
  12. COM::CBN osession, "nSetDate", :CALL, "A/R", mdate
  13. COM::CBN osession, "nSetProgram", :CALL, COM::CBN(osession, "nLookupTask", :CALL, "AR_Customer_ui")
  14. oui = COM::CBN(oscript, "NewObject", :SET, "AR_Customer_ui", osession)
  15. COM::CBN oui, "nProcess", :CALL, "01MAVRK"
  16.  
  17. COM::CBN oui,"DropObject", :CALL
  18. COM::RELEASE oui
  19. COM::CBN osession, "DropObject", :CALL
  20. COM::RELEASE osession
  21. COM::RELEASE oscript
  22.  

I don't give up easy but trying to use ScriptBasic as an internal scripting engine seems like a waste of my time.
9
Script BASIC / ScriptLess Scripting
« Last post by John Spikowski on June 12, 2021, 10:44:17 PM »
I wanted to get ScriptBasic to work as my scripting engine for Sage 100 when the Sage Custom Office scripting solution falls short of my needs. I'm still putting the pieces together but here is a few examples I've got working so far. I should be able to create any type of control to script and not just buttons. Sage development personal has cautioned me that my direction may cause issues with existing functionality. I think they also feel better about keeping development within their defined scope.

My focus with Sage 100 is extending it externally without having to be a Master Developer to offer custom solutions.  Sage supports 100 if modifications are done via scripting as they can be turned off and default functionality restored for support debugging if a problem surfaces.

The Test Button attachment calls ScriptBasic as a DLL and runs the messagebox script with whatever Sage 100 variables I chose to pass. (script object, current business object, ...) Since ScriptBasic is seen as a DLL call in the same Windows process as Sage 100, I'm able to pass pointers to object references and use them within a ScriptBasic script.

The Zip Code attachment shows handling a focus event when the user enters an already defined 100 control.

I plan on using this scripting method with projects I do for clients.

ScriptBasic is a great option for external scripting and as a web server getting your business connected to the cloud.

 
10
Script BASIC / SBIDE
« Last post by John Spikowski on May 28, 2021, 08:13:17 PM »
I'm adding the core extension module FUNCTION/SUB syntax helpers to SBIDE's syntax tip help. After entering a keyword or extension function name and a ( the syntax tool tip will display. As you enter arguments the tool tip will move to the next argument. Once I completed the SBIDE enhancements I will post it here. I will include the updated SBIDE in the next Inno install build.

Hot Keys

ctrl-f - find/replace
ctrl-g - goto line
ctrl-z - undo
ctrl-y - redo

F2     - set breakpoint (runtime only)
F5     - go
F7     - single step
F8     - step over
F9     - step out

Pages: [1] 2 3 ... 10