Overview

In AdvantageBuilder, a workflow is a set of macros that call each other, pass data, and optionally interact with GUI forms or schedules. The core of the workflow engine is the ability to call macros programmatically.

Workflows use two functions:

The bDisplayResult flag determines whether the macro's result is displayed. Both synchronous and asynchronous calls support result display. The params argument is optional for both sync and async calls.

Calling Macros from Other Macros

Workflows start with one macro calling another. You can call macros from PowerShell, JavaScriptV8, and JScript.

PowerShell - Simple Sequential Workflow


# Macro: Main Workflow
try {
    $bDisplayResult = $false

    # Call a helper macro without parameters
    $result = callMacro $bDisplayResult "Step 1 - Initialise" "Workflows\\Steps"

    # Build params object to send to next macro
    $param = @{
        previousResult = $result
        status         = $null
    }

    callMacro $bDisplayResult "Step 2 - Process" "Workflows\\Steps" $param

    alert("Workflow completed. Status: " + $param.status)
}
catch {
    alert("Workflow error: " + $_.Exception.Message)
}
    

JavaScriptV8 - Sequential Workflow


try {
    let bDisplayResult = false;

    let result = callMacro(bDisplayResult, "Step 1 - Initialise", "Workflows\\Steps");

    let param = {
        previousResult: result,
        status: null
    };

    callMacro(bDisplayResult, "Step 2 - Process", "Workflows\\Steps", param);

    alert("Workflow completed. Status: " + param.status);
}
catch (ex) {
    alert("Workflow error: " + ex.Message);
}
    

JScript - Sequential Workflow


try {
    var bDisplayResult = false;

    var result = callMacro(bDisplayResult, "Step 1 - Initialise", "Workflows\\Steps");

    var param = new Object();
    param.previousResult = result;
    param.status = null;

    callMacro(bDisplayResult, "Step 2 - Process", "Workflows\\Steps", param);

    alert("Workflow completed. Status: " + param.status);
}
catch(e) {
    alert("Workflow error: " + e.message);
}
    

Passing and Receiving Parameters

When you pass a parameter object to callMacro, the called macro can read and modify its properties. This is a simple and powerful way to pass data through a workflow. Passed parameters are accessed via args / $_args (javascript / powershell) variable inside the called/receiving macro.

PowerShell - Called Macro Receiving Parameters


# Macro: Step 2 - Process

try {
    if ($_args -ne $null) {
        $previousResult = $_args.previousResult
        $_args.status = "Processed: $previousResult"
    }
}
catch {
    alert("Step 2 error: " + $_.Exception.Message)
}
    

JavaScriptV8 - Called Macro Receiving Parameters


// Macro: Step 2 - Process
try {
    if (args != null) {
        let previousResult = args.previousResult;
        args.status = "Processed: " + previousResult;
    }
}
catch (ex) {
    alert("Step 2 error: " + ex.Message);
}
    

JScript - Called Macro Receiving Parameters


// Macro: Step 2 - Process
try {
    if (args != null) {
        var previousResult = args.previousResult;
        args.status = "Processed: " + previousResult;
    }
}
catch(e) {
    alert("Step 2 error: " + e.message);
}
    

Async Workflows with callMacroAsync

Use callMacroAsync when you want to start a macro and continue without waiting for it to finish. Both sync and async calls support result display via bDisplayResult.

JavaScriptV8 - Starting an Async Workflow


try {
    let bDisplayResult = true;

    let param = {
        jobId: 123,
        status: null
    };

    callMacroAsync(bDisplayResult, "Background Job", "Workflows\\Async", param);

    alert("Background job started.");
}
catch (ex) {
    alert("Async workflow error: " + ex.Message);
}
    

PowerShell - Starting an Async Workflow


try {
    $bDisplayResult = $true

    $param = @{
        jobId = 123
        status = $null
    }

    callMacroAsync $bDisplayResult "Background Job" "Workflows\\Async" $param

    alert("Background job started.")
}
catch {
    alert("Async workflow error: " + $_.Exception.Message)
}
    

GUI Workflows - Calling Macros from Web Pages

AdvantageBuilder can launch HTML forms and let JavaScript inside those pages call macros. This is ideal for interactive workflows where users click buttons, enter data, and see results.

Macro - Launching the GUI Form (legacy browser engine - IE)


<!-- JScript macro: Main GUI Workflow -->
launchHTMLForm(getGUIFilePath("CallingMacrosFromGUIDemo.html"));
    

HTML - Including DataSource.js and Workflow Scripts


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Calling Macros From Web Pages Demo</title>

    <script src="../Common/scripts/DataSource.js"></script>
    <script src="scripts/GeneralNumbers.js"></script>
    <script src="scripts/CallingMacrosFromGUIDemo.js"></script>
</head>
<body>
    <h3>Get the Shopping List</h3>

    <input type="button" value="Get Shopping List" onclick="getShoppingList()">

    <table cellspacing="2" cellpadding="2" border="0">
        <tr>
            <td class="label" style="vertical-align:top">Shopping List:</td>
            <td id="shoppingList"></td>
        </tr>
    </table>

    <h3>Calculate Sum</h3>

    <input type="text" id="txtNum1" name="txtNum1"
           onkeydown="ensureDecimalsOnly();" onchange="ensureNumeric();" style="text-align: right"> + 
    <input type="text" id="txtNum2" name="txtNum2"
           onkeydown="ensureDecimalsOnly();" onchange="ensureNumeric();" style="text-align: right"> 
    <input type="button" value="=" onclick="calculateSum()"> 
    <input type="text" id="txtSum" name="txtSum">
</body>
</html>
    

DataSource.js - Enabling Macro Calls in the Browser


try {
    var _server = new ActiveXObject('MSTools.Utils.AdvantageBuilder.BL.UserInteraction');
    eval(_server.SetupJS);
}
catch(e) {
    logMacroError(e.message, "DataSource.js : ActiveXObject error");
}
    

CallingMacrosFromGUIDemo.js - GUI Workflow Logic


function getShoppingList()
{
    var result = callMacro(false, "Get a shopping list", "Hello World\\Helper Macros");
    document.getElementById("shoppingList").innerText = result;
}

function calculateSum()
{
    var num1 = document.getElementById("txtNum1").value;
    var num2 = document.getElementById("txtNum2").value;

    if (isNaN(num1) || isNaN(num2))
    {
        alert("Please enter numbers");
    }
    else
    {
        var param = new Object();
        param.x = num1;
        param.y = num2;
        param.sum = null;

        callMacro(false, "Calculate Sum", "Hello World\\Helper Macros", param);

        document.getElementById("txtSum").value = param.sum;
    }
}
    

In this example, the GUI page calls macros to get a shopping list and to calculate a sum. The parameter object is modified by the macro and read back by the page, forming a complete GUI-driven workflow.

Macro - Launching the GUI Form (Edge WebView engine)


<!-- JavaScriptV8 macro: Main GUI Workflow -->
launchHTMLFormEdge(getGUIFilePath("CallingMacrosFromGUIDemoEdge.html"),"");
    

HTML - Including DataSource.js and Workflow Scripts


<html>
<head>
    <title>Calling Macros From Web Pages Demo</title>

    <script src="../Common/scripts/DataSource.js"></script>
    <script src="scripts/GeneralNumbers.js"></script>
    <script src="scripts/CallingMacrosFromGUIDemoEdge.js"></script>
</head>
<body>
    <h3>Get the Shopping List</h3>

    <input type="button" value="Get Shopping List" onclick="getShoppingList()">

    <table cellspacing="2" cellpadding="2" border="0">
        <tr>
            <td class="label" style="vertical-align:top">Shopping List:</td>
            <td id="shoppingList"></td>
        </tr>
    </table>

    <h3>Calculate Sum</h3>

    <input type="text" id="txtNum1" name="txtNum1"
           onkeydown="ensureDecimalsOnly();" onchange="ensureNumeric();" style="text-align: right"> + 
    <input type="text" id="txtNum2" name="txtNum2"
           onkeydown="ensureDecimalsOnly();" onchange="ensureNumeric();" style="text-align: right"> 
    <input type="button" value="=" onclick="calculateSum()"> 
    <input type="text" id="txtSum" name="txtSum">
</body>
</html>
    

DataSource.js - Enabling Macro Calls in the Browser


var _server = window._server || null;

var setup = atob(window._setupJS_base64);
(0, eval)(setup);    

    

CallingMacrosFromGUIDemoEdge.js - GUI Workflow Logic


async function getShoppingList()
{
    var result = await callMacro(false, "Get a shopping list", "Hello World\\Helper Macros");

    document.getElementById("shoppingList").innerText = result;
}

async function calculateSum()
{
	var num1 = document.getElementById("txtNum1").value;
	var num2 = document.getElementById("txtNum2").value;

	if(isNaN(num1) || isNaN(num2))
	{
		alert("Please enter numbers");
	}
	else
	{
		//define and initialise the parameter object
		var param = new Object();
		param.x = num1;
		param.y = num2;
		param.sum = null;

		//call the macro with parameter
		var result = await callMacro(false, "Calculate Sum Edge", "Hello World\\Helper Macros", param);

		//show the result
		document.getElementById("txtSum").value = result;
	}
}
    

In this example, the GUI page calls macros to get a shopping list and to calculate a sum. With the Edge/Chromium browser engine, the passed object cannot return values back by reference. So in this instance, the calculateSum macro returns value by feeding the result through the standard macro output - write() function. Also note that to get values from macros, you must utilise the async/await syntax.

Scheduling Macros

Workflows often require macros to run automatically at specific times. AdvantageBuilder allows you to schedule macros programmatically from PowerShell, JavaScriptV8, and JScript.

PowerShell — Add Macro Schedule


<!-- PowerShell -->
$schedulerId = addMacroSchedule 'Weekly Security Audit' 'System\\Security' 'Weekly' $null 'Monday,Tuesday' '14:10'
$schedulerId

$schedulerId = addMacroSchedule 'Monthly Report Generator' 'Reporting\\Monthly' 'Monthly' 1 '20,27' '14:10'
$schedulerId
    

JavaScriptV8 — Add Macro Schedule


<!-- JavaScriptV8 -->
var schedulerId = addMacroSchedule('Monthly Report Generator', 'Reporting\\Monthly', 'Monthly', 1, '16', '14:12');
writeln(schedulerId);

schedulerId = addMacroSchedule('Daily Data Sync', 'Data\\Sync', 'Daily', null, '', '21:13');
writeln(schedulerId);
    

PowerShell — Remove Macro Schedule


<!-- PowerShell -->
$success = removeMacroSchedule '6bd3d17d-d4fc-4341-90d6-d45df294222c'
$success
    

JScript — Remove Macro Schedule


<!-- JScript -->
var success = removeMacroSchedule("94433104-4f03-4c5f-8c85-43f746055d43");
writeln(success);
    

JavaScriptV8 — Remove Macro Schedule


<!-- JavaScriptV8 -->
var success = removeMacroSchedule("583b88cc-6525-4f4e-86df-646a10763fe1");
writeln(success);

success = removeMacroSchedule("710cfd4f-b11f-4649-8d74-c60ea0336270");
writeln(success);
    

Creating Macros Programmatically

Workflows can dynamically generate new macros. This allows scripts or AI-driven processes to create automation steps on the fly.

JavaScriptV8 — Create a New Macro Containing JScript Code


<!-- JavaScriptV8 -->
var sourceCode = "[!JSCRIPT]\\n" +
"alert('Hello');\\n" +
"[!/JSCRIPT]";

var macroName = "SendWelcomeEmail";
var macroPath = "Automation\\Email";

var success = createMacro(macroName, macroPath, sourceCode);

if(success){
    write('Success!!!');
}
else{
    write('FAIL :(');
}
    

Putting It All Together

A typical AdvantageBuilder workflow might:

By combining macro calls, parameter passing, scheduling, and GUI integration, you can build powerful workflows that automate complex tasks across scripting engines and user interfaces.

Continue to Getting Started