Main Menu

Recent posts

#11
Language Features / MySQL Entension Module
Last post by root - May 23, 2026, 06:31 PM
ScriptBasic supports MySQL with a C API interface that is lightening fast. I don't have the MySQL Classic  Models example DB on my Windows laptop so these examples will be from my Linux servers.

' MySQL Test Program

IMPORT mysql.bas

dbh = mysql::RealConnect("localhost","root","PASSWORD","classicmodels")

mysql::query(dbh,"SELECT * FROM products LIMIT 25")

WHILE mysql::FetchHash(dbh,column)
  PRINT column{"productCode"}," - ",column{"productName"}," - ",FORMAT("%~$###.00~",column{"MSRP"}),"\n"
WEND

PRINTNL
PRINT "The database handle is: ",dbh,"\n"
PRINT "Affected rows by SELECT: ",mysql::AffectedRows(dbh),"\n"
PRINT "Character set name is: ",mysql::CharacterSetName(dbh),"\n"
PRINT "Last error is: ",mysql::ErrorMessage(dbh),"\n"
PRINT "Client info is: ",mysql::GetClientInfo(),"\n"
PRINT "Host info is: ",mysql::GetHostInfo(dbh),"\n"
PRINT "Proto info is: ",mysql::GetProtoInfo(dbh),"\n"
PRINT "Server info is: ",mysql::GetServerInfo(dbh),"\n"
PRINT "PING result: ",mysql::Ping(dbh),"\n"
PRINT "Thread ID: ",mysql::ThreadId(dbh),"\n"
PRINT "Status is: ",mysql::Stat(dbh),"\n"

mysql::Close(dbh)

Output:
rs@linux-dev:~/sbrt/examples$ sbc testmysql.sb
S10_1678 - 1969 Harley Davidson Ultimate Chopper - $ 95.70
S10_1949 - 1952 Alpine Renault 1300 - $214.30
S10_2016 - 1996 Moto Guzzi 1100i - $118.94
S10_4698 - 2003 Harley-Davidson Eagle Drag Bike - $193.66
S10_4757 - 1972 Alfa Romeo GTA - $136.00
S10_4962 - 1962 LanciaA Delta 16V - $147.74
S12_1099 - 1968 Ford Mustang - $194.57
S12_1108 - 2001 Ferrari Enzo - $207.80
S12_1666 - 1958 Setra Bus - $136.67
S12_2823 - 2002 Suzuki XREO - $150.62
S12_3148 - 1969 Corvair Monza - $151.08
S12_3380 - 1968 Dodge Charger - $117.44
S12_3891 - 1969 Ford Falcon - $173.02
S12_3990 - 1970 Plymouth Hemi Cuda - $ 79.80
S12_4473 - 1957 Chevy Pickup - $118.50
S12_4675 - 1969 Dodge Charger - $115.16
S18_1097 - 1940 Ford Pickup Truck - $116.67
S18_1129 - 1993 Mazda RX-7 - $141.54
S18_1342 - 1937 Lincoln Berline - $102.74
S18_1367 - 1936 Mercedes-Benz 500K Special Roadster - $ 53.91
S18_1589 - 1965 Aston Martin DB5 - $124.44
S18_1662 - 1980s Black Hawk Helicopter - $157.69
S18_1749 - 1917 Grand Touring Sedan - $170.00
S18_1889 - 1948 Porsche 356-A Roadster - $ 77.00
S18_1984 - 1995 Honda Civic - $142.25

The database handle is: 1
Affected rows by SELECT: 25
Character set name is: utf8mb4
Last error is:
Client info is: 8.0.44
Host info is: Localhost via UNIX socket
Proto info is: 10
Server info is: 8.0.44-0ubuntu0.24.04.2
PING result: -1
Thread ID: 0
Status is: Uptime: 837  Threads: 2  Questions: 1039  Slow queries: 0  Opens: 470  Flush tables: 3  Open tables: 389  Queries per second avg: 1.241
jrs@linux-dev:~/sbrt/examples$

THIS MySQL example is using AJAX to select the product line to display.This is running on the ScriptBasic web server.

' ScriptBasic AJAX & MySQL

IMPORT cgi.bas

cgi::Header 200,"text/html"
cgi::FinishHeader

PRINT """
<html>
<head>
<script>
function showItems(str) {
  if (str == "") {
    document.getElementById("results").innerHTML = "";
    return;
  } else {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("results").innerHTML = this.responseText;
      }
    };
    xmlhttp.open("GET","/home/qbo/getitems.sb?q="+str,true);
    xmlhttp.send();
  }
}
</script>
</head>
<body>

<form>
  <select name="items" onchange="showItems(this.value)">
    <option value="">Product Line</option>
    <option value="Classic Cars">Classic Cars</option>
    <option value="Motorcycles">Motorcycles</option>
    <option value="Planes">Planes</option>
    <option value="Ships">Ships</option>
    <option value="Trains">Trains</option>
    <option value="Trucks and Buses">Trucks and Buses</option>
    <option value="Vintage Cars">Vintage Cars</option>
  </select>
</form>
<br>
<div id="results"></div>

</body>
</html>
"""

' AJAX - getitems.sb

IMPORT cgi.bas
IMPORT mysql.bas

cgi::Header 200,"text/html"

PRINT """
<!DOCTYPE html>
<html>
<head>
<style>
table {
  width: 100%;
  border-collapse: collapse;
}

table, td, th {
  border: 1px solid black;
  padding: 5px;
}

th {text-align: left;}
</style>
</head>
<body>
"""

product_line = cgi::GetParam("q")

dbh = mysql::RealConnect("localhost","USER","PASSWORD","classicmodels")
mysql::query(dbh,"SELECT * FROM products WHERE productLine = '" & product_line & "'")

PRINT """
<table>
  <tr>
    <th>Product Code</th>
    <th>Product Line</th>
    <th>Product Vendor</th>
    <th>Product Name</th>
    <th>In Stock</th>
    <th>Cost</th>
    <th>MSRP</th>
  </tr>
"""

WHILE mysql::FetchHash(dbh,column)
  PRINT "  <tr>\n"
  PRINT "    <td>", column{"productCode"}, "</td>\n"
  PRINT "    <td>", column{"productLine"}, "</td>\n"
  PRINT "    <td>", column{"productVendor"}, "</td>\n"
  PRINT "    <td>", column{"productName"}, "</td>\n"
  PRINT "    <td align=\"right\">", column{"quantityInStock"}, "</td>\n"
  PRINT "    <td align=\"right\">", FORMAT("%~$###.00~",column{"buyPrice"}), "</td>\n"
  PRINT "    <td align=\"right\">", FORMAT("%~$###.00~",column{"MSRP"}), "</td>\n"
  PRINT "  </tr>\n"
WEND

PRINT """
</table>
</body>
</html>
"""

mysql::Close(dbh)
#12
BOI Overview / SBT Embedding
Last post by root - May 19, 2026, 07:11 PM
ScriptBasic can be embedded into other applications as a DLL interface. I wrote the SBT extension module which embeds ScriptBasic in ScriptBasic to help others with the ScriptBasic API. I also added the ability to embed ScriptBasic as a thread.

The following example demonstrates accessing the ScriptBasic API

' SBT Demo

IMPORT sbt.sbi

sb_code = """
FUNCTION prtvars(a, b, c)
  PRINT a,"\\n"
  PRINT FORMAT("%g\\n", b)
  PRINT c,"\\n"
  prtvars = "Function Return"
END FUNCTION

a = 0
b = 0
c = ""
"""

sb = SB_New()
SB_Configure sb, "C:/Windows/SCRIBA.INI_32"
SB_Loadstr sb, sb_code
SB_NoRun sb
' Call function before running script
funcrtn = SB_CallSubArgs(sb,"main::prtvars", 123, 1.23, "One,Two,Three")
PRINT funcrtn,"\n"
' Run script initializing globals
SB_Run sb, ""
' Assign variables values
SB_SetInt sb, "main::a", 321
SB_SetDbl sb, "main::b", 32.1
SB_SetStr sb, "main::c", "Three,Two,One" & CHR(0)
' Call function again with variables assigned in the previous step
SB_CallSubArgs sb, "main::prtvars", _
          SB_GetVar(sb, "main::a"), _
          SB_GetVar(sb, "main::b"), _
          SB_GetVar(sb, "main::c")
SB_Destroy sb

Output

C:\ScriptBasic\examples>sbc sbt_demo.sb
123
1.23
One,Two,Three
Function Return
321
32.1
Three,Two,One

C:\ScriptBasic\examples>


This is an example of embedding ScriptBasic as a thread process and using the MT extension module to share a common status variable among processes.

Code (main) Select

' SBT Main

IMPORT mt.sbi
IMPORT sbt.sbi

SB_ThreadStart("sbt_thread.sb", "","C:/Windows/SCRIBA.INI")

FOR x = 1 TO 10
  PRINT "M:",x,"\n"
  sb_msSleep(20)
NEXT

SB_msSleep(1000)

PRINT "Thread ",mt::GetVariable("thread_status"),"\n"

Code (thread) Select
' SBT Thread

IMPORT mt.sbi
IMPORT sbt.sbi

FOR x = 1 TO 10
  PRINT "T:",x,"\n"
  SB_msSleep(20)
NEXT

mt::SetVariable "thread_status","Completed"

SB_ThreadEnd

Output

C:\ScriptBasic\examples>sbc sbt_main.sb
T:1
T:2
M:1
T:3
M:2
M:3
T:4
M:4
T:5
M:5
T:6
T:7
M:6
M:7
T:8
T:9
M:8
M:9
T:10
M:10
Thread Completed

C:\ScriptBasic\examples>
#13
Language Features / cURL Internet Access
Last post by root - May 17, 2026, 04:59 PM
ScriptBasic provides a C API extension module for libcurl which offers HTML, REST and GraphQL direct access from your BOI scripts. This eliminates the need for third party emulations like ROI In-Synch.

This cURL example does a REST call to the Open Weather service and converts the JSON response to a ScriptBasic associative array. It displays the raw JSON and as a ScriptBasic array using the sbadump() debug function.

' OpenWeather - cURL & JSON Example
 
IMPORT curl.sbi
IMPORT webext.sbi
 
place = COMMAND()
 
ch = curl::init()
curl::option(ch, "URL", "http://api.openweathermap.org/data/2.5/weather?q=" & place & "&units=imperial&appid=APP KEY")
curl::option(ch, "CUSTOMREQUEST", "GET")
json = curl::perform(ch)
curl::finish(ch)
PRINT json,"\n\n"
web::json2sba(json)
web::sbadump(json)

PRINT "\nTempreture: ", json{"main"}{"temp"}, " F\n"
PRINT "Date: ", FORMATDATE("MM/DD/YEAR 0H:0m:0s",json{"dt"} + json{"timezone"}),"\n"

END

Output:

C:\ScriptBasic\examples>sbc weather.sb Lynden
{"coord":{"lon":-122.4521,"lat":48.9465},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":65.07,"feels_like":63.77,"temp_min":60.51,"temp_max":67.69,"pressure":1023,"humidity":53,"sea_level":1023,"grnd_level":1015},"visibility":10000,"wind":{"speed":11.5,"deg":240},"clouds":{"all":20},"dt":1779061311,"sys":{"type":2,"id":2043940,"country":"US","sunrise":1779020706,"sunset":1779076053},"timezone":-25200,"id":5802035,"name":"Lynden","cod":200}

coord
  lon = -122.452
  lat = 48.9465
weather
  [1]
      id = 801
      main = Clouds
      description = few clouds
      icon = 02d
base = stations
main
  temp = 65.07
  feels_like = 63.77
  temp_min = 60.51
  temp_max = 67.69
  pressure = 1023
  humidity = 53
  sea_level = 1023
  grnd_level = 1015
visibility = 10000
wind
  speed = 11.5
  deg = 240
clouds
  all = 20
dt = 1779061311
sys
  type = 2
  id = 2043940
  country = US
  sunrise = 1779020706
  sunset = 1779076053
timezone = -25200
id = 5802035
name = Lynden
cod = 200

Tempreture: 65.07 F
Date: 5/17/2026 16:41:51

C:\ScriptBasic\examples>
#14
Language Features / Re: ScriptBasic Syntax
Last post by root - May 16, 2026, 06:49 PM
FORMAT

The FORMAT function allows creating a formatted string with constants and variables. This uses the C style format stucture.

PRINT FORMAT("Today is %s %ith %i\n", "May", 16, 2026)

Output:

Today is May 16th 2026

To format a number based on a mask, the following statement can be used,

PRINT FORMAT("%~$##,##0.00-~", 1234),"\n"

Output:

$ 1,234.00

Date and Time

All time and date math is done by seconds past 1/1/1970.

NOW() returns the the current time based on timezone in seconds.

current_time = TIMEVALUE(year,month,day,hours,minutes,seconds)

PRINT TIMEVALUE(2026,5,16,18,25,0), "\n"

Output:

1778955900

GMTIME() returns the time in seconds but based on GMT time.

YEARDAY returns the day number of the year.

PRINT YEARDAY(NOW),"\n"

Output:

135

date_str = FORMATDATE("format",time)

     YEAR         four digit year
     YY           two digit year
     MON          three letter abbreviation of the month name
     MM           month
     0M           month with leading zero if needed
     *MONTH-NAME* name of the month
     DD           day of the month
     0D           day of the month with leading zero if needed
     WD           week day on a single digit starting with sunday=0
     WEEKDAY-NAME the name of the weekday
     WDN          three letter abbreviation fo the week day name
     HH           hours (24 hours notation)
     0H           hours with leading zero if needed (24 hours notation)
     hh           hours (12 hours notation)
     0h           hours with leading zero if needed (12 hours notation)
     mm           minutes
     0m           minutes with leading zero if needed
     am / pm      is am or pm

Any other characters in the format string will be retuened verbatim.

results = ADDDAY(NOW,7)  - This adds 7 days to the current time.

There are similar functions for year, month, hour, minute and seconds.

 
#15
Language Features / Re: ScriptBasic Syntax
Last post by root - May 14, 2026, 06:04 PM
The following ScriptBasic language functions save me a lot of time.

SPLIT

ScriptBasic only allows one statement per line. When I need to assign a group of variables, I use the SPLIT function.

SPLIT "1,2,3" BY "," TO a,b,c
SPLITA

This is a handy function for converting any delimited (including line terminators) list to an array.

SPLITA "1,2,3" BY "," TO a

LIKE

LIKE is used to parse a string and return data designated with the * wildcard character and returns the results using the JOKER() function.

eval_str = "This is an example string that will be searched by the LIKE function."

IF eval_str LIKE "*example * *" THEN
  PRINT JOKER(2),"\n"
END IF

Output:

string

ScriptBasic doesn't support the SELECT keyword and uses the IF block instead. This gives better granularity in determining the value.

a = 1
IF a = 1 THEN
  PRINT "a = 1\n"
ELSE IF a = 2 THEN
  PRINT "a = 2\n"
ELSE
  PRINT "a not in range\n"
END IF

Loop Structures

FOR / NEXT
DO / LOOP UNTIL
DO / LOOP WHILE
REPEAT / UNTIL
WHILE / WEND
#16
Language Features / Re: ScriptBasic Syntax
Last post by root - May 13, 2026, 04:11 PM
The ScriptBasic comment character ' is used as the first character of the line. Comments can't be added to the end of a line. The following example shows creating a multi-line comment. The """ feature also works with multi-line string. I use this extensively with outputting HTML with the ScriptBasic webserver.

' This is a single line comment.

'"""

This is a
multi-line comment

"""

PRINT "Hello, World!","\n"


Labels

ScriptBasic supports labels for GOTO, GOSUB and ON ERROR. I also use them to exit a FOR/NEXT loop with a GOTO.

MyLabel:

ScriptBasic also supports line numbers as a special form of label. If using line numbers from a legacy BASIC, you only need line numbers assigned for GOTO / GOSUB reference.

10 LET A$="Hello World!"
20 PRINT A$,"\n"
30 END

Note: LET is an optional keyword and used with legacy conversions to ScriptBasic.


MODULE

In ScriptBasic, namespaces provide a mechanism to organize code and avoid variable or function name collisions, especially when using external modules. The core command for managing these is MODULE, which defines a specific namespace for subsequent code.

Key Namespace Concepts in ScriptBasic
  • Module Definition: Using the MODULE name statement creates a new namespace. All global variables and functions declared after this statement belong to that namespace until the module is ended or changed.
  • Accessing Members: To call a function or access a variable inside a module from the main program, you use the double colon :: syntax, such as modulename::functionname.
  • The Main Namespace: Code that is not inside any MODULE block belongs to the default "main" namespace.
  • External Modules: Extension modules like those for cURL, MySQL and ODBC automatically introduce their own namespaces to keep their internal functions separate from your main script.
  • Nesting: ScriptBasic supports nested namespaces, which are managed internally via a namespace stack during syntax analysis.

This is the COM extension MODULE.

' COM/OLE Automation Extension Module Import

GLOBAL CONST :CALL   = 1
GLOBAL CONST :GET    = 2
GLOBAL CONST :LET    = 4
GLOBAL CONST :SET    = 8

MODULE COM

DECLARE SUB ::CREATE  ALIAS "CreateObject"      LIB "com"
DECLARE SUB ::CBN     ALIAS "CallByName"        LIB "com"
DECLARE SUB ::RELEASE ALIAS "ReleaseObject"     LIB "com"
DECLARE SUB ::GHO     ALIAS "GetHostObject"     LIB "com"
DECLARE SUB ::GHS     ALIAS "GetHostString"     LIB "com"
DECLARE SUB ::SVT     ALIAS "ShowVariantType"   LIB "com"
DECLARE SUB ::TN      ALIAS "TypeName"          LIB "com"
DECLARE SUB ::DI      ALIAS "DescribeInterface" LIB "com"
DECLARE SUB ::CB      ALIAS "SBCallBack"        LIB "com"

END MODULE
#17
Language Features / ScriptBasic Syntax
Last post by root - May 12, 2026, 02:28 PM
This thread will show some of the enhanced language features of ScriptBasic. With VBScript being deprecated by Microsoft, ScriptBasic is the only embedded BASIC scripting language available going forward.

Variables

In ScriptBasic, you don't declare types — the interpreter assigns and converts them automatically based on usage, making it dynamically typed but with predictable conversion rules. Variables are stored as a variant with the following internal types.
  • undef - Indicates the variable hasn't been assigned a value yet.
  • integer - Indicates this value is a whole number with a integer type.
  • real - Indicates a real floating point type.
  • string - Indicates a ScriptBasic string that can contain embedded nulls.
  • stringz - Indicates a null terminated C style string.
  • array - Indicates an array that could be indexed based, associative or a combination of both.

ScriptBasic string and array size is only limited to available memory. (WoW64 32 bit addressing)

These examples show how type is assigned at use. The & symbol indicates concatenating of strings.

a = 1
b = 2
c = "3"
d = "4"

PRINT a + b
PRINT a & b
PRINT c + d
PRINT c & d

Output:

3
12
7
34

The $ character can be used to append string variables and functions. This is optional and used mostly when converting other dialects of BASIC such as ProvideX. I rarely use the STR() and VAL() functions in ScriptBasic.

a$ = "A  String"
a$ = STR$(123)

Arrays

In ScriptBasic, arrays are flexible data structures created automatically as soon as you assign a value to a subscripted variable. They do not require a formal declaration or a fixed size, and they can hold elements of any data type.

Key Characteristics
  • Automatic Creation: There is no DIM statement; arrays are initialized the moment they are used.
  • Dynamic Sizing: Addressable indices increase automatically as needed.
  • Heterogeneous Content: A single array can store different types of data, such as integers, reals, and strings.
  • Uninitialized Elements: Elements that have not been assigned a value return undef.
Standard Arrays: Use square brackets [] for numeric indices.

a[0] = "Hello"
a[1] = 123.45

Multidimensional Arrays: Supported through nested brackets or comma-separated indices.

matrix[1][2] = 50
' or alternatively:
matrix[1, 2] = 50

Associative Mode: ScriptBasic allows arrays to function in an associative mode using curly braces {}.

user{"name"} = "ScriptBasic"
user{"age"} = 26

LBOUND / UBOUND: Used to determine the upper and lower boundaries of an array. An array index traditionally starts a index zero but can begin and end at users choice. Elements between define LBOUND / UBOUND are declared undef.

a[100] = 100
PRINT LBOUND(a)
PRINT UBOUND(a)
a[50] = 50
PRINT LBOUND(a)
PRINT UBOUND(a)

Output

100
100
50
100

Array element segments can be copied to a new array. I use this feature with JSON associative arrays responses to build update requests.
#18
BOI Overview / ScriptBasic BOI
Last post by root - May 11, 2026, 06:32 PM
ScriptBasic can be used for both internal and external BOI scripting. It's pretty much a line for line translation of VBScript COM syntax. The following is an example of using the customer business object to get the first key in the file.



ScriptBasic COM includes an interface viewer that makes working with the object ScriptBasic friendly.



#19
BOI Overview / VBScript Deprecation
Last post by root - May 11, 2026, 06:18 PM
If you are a Sage 100 partner or user that uses Custom Office with BOI (Business Object Interface) scripts that are written in Microsoft VBScript to Interface with ProvideX via a COM interface, take note.

Microsoft has deprecated VBScript in WSH (Windows Shell Host) which is an optional install on Windows 11 and to be removed in future (TBD) is the plan. VBScript: Officially deprecated by Microsoft as of October 2023. It is largely being replaced by Windows PowerShell for administrative tasks.

Microsoft is moving away from VBScript specifically because it is a common attack vector for malware.

ScriptBasic is an embeddable traditional BASIC scripting engine written in ANSI C with a 800 KB footprint. It supports COM to Interface with Sage 100 BOI. I have been using ScriptBasic for years for external BOI interfaces for clients.


Sage 100 currently supports WSH and ProvideX as scripting options. I'm in the process of adding ScriptBasic as an option. ScriptBasic COM is line for line equivalent to VBScript. I plan to write a script to convert VBScript code to ScriptBasic COM.

An added advantage of using ScriptBasic is beside COM support, you can make REST calls from your BOI scripts directly. ODBC, MySQL, SQLite and other extension modules are also available from within ScriptBasic.

The memory footprint for PowerShell typically starts around 30 MB to 100 MB for an idle session, but can quickly scale into the gigabytes depending on the scripts and data being processed. Because it is built on the .NET framework, it uses a managed memory model where memory is allocated and released through a garbage collector.

Windows Script Host (WSH) typically running via wscript.exe or cscript.exe is known for having a very low, lightweight memory footprint, often occupying only a few megabytes of RAM for simple scripts.
#20
Language Features / History and Resources
Last post by root - May 11, 2026, 05:51 PM
Birth of BASIC

ScriptBasic is written in ANSI C with an object like API. The scripting engine is embeddable, with a thread safe memory manager and virtually unlimited expandability. The core language uses one source tree for all platforms. Variables are maintained in a variant like structure and typeless until used. ScriptBasic runs as console and Windows interpreter, embedded as a DLL and as a multi-threaded webserver. A IDE / Debugger is included.



Script BASIC comes with an array of industry standard library extension modules and a multi-threaded proxy HTTPD application server running as an OS service.

Scripting doesn't get any easier and based on a language syntax we all grew up with.

My only complaint about ProvideX is everything is an emulation.

History:

ScriptBasic was created by Peter Verhas from Hungary in 2000. Peter moved on to work for a company in Switzerland as a Java developer. Peter created a ScriptBasic for Java.

I took over maintaining the project in 2006. I've added numerous C extension module libraries for seamless integration with the language. There have been others over the years contributing to the project to make it what it is today.

Repository

The ScriptBasic 32 bit Windows version is available in an Inno install and comes with examples showing how the extension modules are used.

ScriptBasic 32 bit Install


Documentation:

ScriptBasic User Guide

ScriptBasic Developer Guide

Banner Engineering is a commercial user of ScriptBasic for their line of controllers. They created their own copy of the documentation in a PDF. Banner added additional syntax that isn't in standard ScriptBasic.

Banner ScriptBasic User Guide