T I P S & T R I C K S. A Brio Intelligence™ Developer’s JavaScript toolkit David Eastwood,...
-
Upload
amelia-lindsley -
Category
Documents
-
view
220 -
download
0
Transcript of T I P S & T R I C K S. A Brio Intelligence™ Developer’s JavaScript toolkit David Eastwood,...
T I P S & T R I C K S
T I P S & T R I C K S
A Brio Intelligence™ Developer’s JavaScript toolkit
David Eastwood,
Director
Maddox Ford Ltd www.maddoxford.co.uk
3T I P S & T R I C K S
Overview
• We were consistently needing to supply the same functionality for our Brio EIS development - often the same code was used in several places within the same application
• This led to the emergence of a function toolkit which has now been used in several major projects over the last 3 years
• Key samples of code are shown and described
• Other techniques such as error trapping are also discussed
4T I P S & T R I C K S
Software Versions
• The code featured has been developed using versions of Brio Intelligence from 6.0 to 6.6.1
• It works with both Designer and Insight (Client/Server and Plugins)
• The software has been used for live applications accessing Oracle, DB2 and SQLServer
5T I P S & T R I C K S
Origins of the work
• We were creating a series of Brio-based reporting applications used by relatively unskilled users to create operational reports and mid-level management reports
• These included– Shift activity rates in supermarket central depots– Printing delivery sheets for delivery runs– Summarising the status of automated test results in a
manufacturing plant– Workflow reports for an insurance broker
• Some utilities also emerged from conventional dashboard applications
6T I P S & T R I C K S
Requirements• Access to multiple databases for one report
• Multiple queries to create one report
• Inactivity timeouts from the RDBMS
• Creating a standardised look and feel for sets of up to 60 reports
• Automated export to Excel/PowerPoint
• Keep it simple!– Not too many controls and pictures
• Quick to build– Start from a template and add the query/reports– Add the EIS to a report - usually about 30 minutes
7T I P S & T R I C K S
Coding and naming conventions
• In order to speed up development we adhere to a fairly rigid naming convention for EIS objects - this means that scripts can be copied in and used with little or no modification
• JavaScript coding follows our coding standards to aid maintainability
8T I P S & T R I C K S
Naming conventions used
• Prefix name with variable type
• ‘g_’ prefix for globals
• Further ‘a’ prefix for function arguments
Type Prefix Example
Array a aSelections
Boolean b bInclude
Date d dRentDue
Label l lContinue
Number n nPrice
Object o oOLAPQuery
String s sFirstName
9T I P S & T R I C K S
Global functions
• Utilities held as a series of global functions– g_fname = fname
• Defined via a (hidden) button ‘Globals’ on the main EIS page
• Easy to redefine after code changes
• OnStartup event will define globals
//Declare globalsActiveDocument.Sections["Selector"].Shapes["cbGlobals"].OnClick()
10T I P S & T R I C K S
Error trapping
• Some utilities are error-trapped
• Other checks done in code
• Mostly omitted from these examples to simplify readability
• Need to use .toString() method– not .name or .message
11T I P S & T R I C K S
Utilities described:
• Purpose and features
• Arguments used
• Code sample
12T I P S & T R I C K S
Hiding the sections and toolbars
• g_showDeveloperView– standard function to show/hide toolbars etc.– will also hide query sections from end-users– usually placed behind a logo to switch modes
• arguments– abShow : true/false switch
13T I P S & T R I C K S
g_showDeveloperView
function showDeveloperView(abShow){ var nSecNum; //Number of Sections var nSecCount; //Section count ShowCatalog = abShow; ShowMenuBar = abShow; // note sometimes omit this command ShowStatusBar = abShow; Toolbars["Sections"].Visible = abShow; Toolbars["Formatting"].Visible = abShow; Toolbars["Standard"].Visible = abShow; //Loop turning section properties on/off
//This version only lets user see EIS & Report sections - adjust as required nSecNum = ActiveDocument.Sections.Count; for (nSecCount = 1; nSecCount <= nSecNum; nSecCount++){
if ( (ActiveDocument.Sections[nSecCount].Type != bqEIS) && (ActiveDocument.Sections[nSecCount].Type != bqReport) ) {
ActiveDocument.Sections[nSecCount].Visible = abShow;}
} //end for} //end of showDeveloperView definition
14T I P S & T R I C K S
Logon functions
• The g_reconnect function is used
• We also often reconnect before processing– some database connections have inactivity timeouts– also catches other database errors
//Disconnect from Queries and then Reconnect - in case of timeoutif( g_reconnect( "Query", g_sPkMSId, g_sPkMSPassword ) ){
ActiveDocument.Sections["Query"].Process()Console.Writeln("Query Processed")
}
15T I P S & T R I C K S
g_reconnect
/*--------------------------------------------------------------------------------------- Function: reconnect-- Result: boolean true if connected, else false-- Parameters: asQuery - Section Name-- asId - Userid-- asPw - Password---- Disconnect and reconnect query to database----------------------------------------------------------------------------------------*/
16T I P S & T R I C K S
g_reconnect
function reconnect( asQuery, asId, asPw) {var sOCEName = ActiveDocument. Sections[asQuery].DataModel.Connection.Filename
// open OCEActiveDocument. Sections[ asQuery ].DataModel.Connection.Open(sOCEName)
//Disconnect from database ActiveDocument.Sections[ asQuery ].DataModel.Connection.Disconnect(); // Set Query connection parameters ActiveDocument.Sections[ asQuery ].DataModel.Connection.Username = asId; ActiveDocument.Sections[ asQuery ].DataModel.Connection.SetPassword( asPw );
// Log Query on to database try{
ActiveDocument.Sections[ asQuery ].DataModel.Connection.Connect(); } catch(errConnect) {
Alert('Database connection error: '+errConnect.toString())return false;
} // Connected OK return true;} // End of reconnect definition
17T I P S & T R I C K S
Controlling limits
• When driving a query from an EIS page, you can either enter limit values on the EIS page or use the standard Limit dialogs
• We often customise Limit dialogs and allow the user to see variable limits - involves less code than setting limits on the EIS page
• Limits often need to be preset with sensible defaults
• On multi-query reports, we need to copy limits
18T I P S & T R I C K S
Setting limits
Limit values
1. Set values on EIS Page
2. Copy variable limit values
Limit Lim_1
Limit Lim_1
Limit Lim_1
Limit Lim_1(v1)
3. Process
1. Process Query 1
Limit Lim_1
Limit Lim_1
3. Process remaining queries
2. Copy limit values
19T I P S & T R I C K S
Setting date limits
• Set a limit to cover yesterday – 00:00:00 to 23:59:59
• Set a limit to cover the previous week
• One sample shown, many variants for other date/time intervals
20T I P S & T R I C K S
g_setLimitByDay - example
g_setLimitByDay("Query","Full Date",5)
Example written on 7 October 2002
7/10/02 in UK format!!
21T I P S & T R I C K S
g_setLimitByDay (1)
Usage:
g_setLimitByDay("Query","Full Date",1)
Syntax:
/*--------------------------------------------------------------------------------------- Function: setLimitByDay-- Parameters: asQueryName, asLimitName, adOffset---- Set custom limit on <asLimitName> in section <asQueryName>-- to between 00:00:00 <adOffset> days ago-- and 23:59:59 yesterday--------------------------------------------------------------------------------------*/
22T I P S & T R I C K S
g_setLimitByDay (2)
function setLimitByDay(asQueryName, asLimitName, adOffset) {
var dStart = new Date() - adOffset ;var dEnd = new Date() - 1; // i.e. yesterdayvar oLimit = ActiveDocument.Sections[asQueryName].Limits[asLimitName];
dStart.setHours(0); dStart.setMinutes(0); dStart.setSeconds(0); dEnd.setHours(23); //End datetime is 1 second to midnight dEnd.setMinutes(59); dEnd.setSeconds(59); oLimit.Operator =bqLimitOperatorBetween oLimit.SelectedValues.RemoveAll(); oLimit.CustomValues.RemoveAll(); oLimit.CustomValues.Add(dStart); oLimit.CustomValues.Add(dEnd); oLimit.SelectedValues.Add(dStart); oLimit.SelectedValues.Add(dEnd);}
23T I P S & T R I C K S
Copying limits
• Main purpose is to stop asking the user to enter the same limit twice
– Apply the same limits to queries against different databases
– Multiple queries against the same database– Union queries
24T I P S & T R I C K S
g_copyLimit
Usage:
g_copyLimit( "Query",'Create Date Time',"VRDT Query",'Create Date Time')
Syntax:/*------------------------------------------------------------------------------------------- Function: copyLimit -- Parameters: asSourceSection, asSourceLimitName,-- asDestSection,asDestLimitName---- Copies the selected CUSTOM values from one limit to another-- duplicates other settings (Ignore, Operator, Nulls etc)-- NOTE we can't seem to set limit values where the limit is set
on a computed column - we get an internal error------------------------------------------------------------------------------------------*/
25T I P S & T R I C K S
g_copylimit (1)function copyLimit(asSourceSection, asSourceLimitName,
asDestSection,asDestLimitName) {
var oSourceObj = ActiveDocument.Sections[asSourceSection].Limits[asSourceLimitName]
var oDestObj = ActiveDocument.Sections[asDestSection].Limits[asDestLimitName]
// read source limit settingsvar bIgnore = oSourceObj.Ignorevar bIncludeNulls= oSourceObj.IncludeNullsvar nNegate= oSourceObj.Negatevar nOperator= oSourceObj.Operatorvar nSelectedValuesCount= oSourceObj.SelectedValues.Countvar nSelVal
//… continue next slide
26T I P S & T R I C K S
g_copylimit (2)
//… continue from previous slide// set the limits on the second query
if (bIgnore) { oDestObj.Ignore= true // not much point copying the rest!
} else {
oDestObj.Ignore=bIgnore // set Ignore state to match sourceoDestObj.IncludeNulls = bIncludeNullsoDestObj.Negate=nNegateoDestObj.Operator = nOperatoroDestObj.SelectedValues.RemoveAll()oDestObj.CustomValues.RemoveAll()
for (var i=1; i<=nSelectedValuesCount; i++) {nSelVal=(oSourceObj.SelectedValues[i])oDestObj.CustomValues.Add(nSelVal)oDestObj.SelectedValues.Add(nSelVal)
} // end for all limit values} // end else
} // end function copyLimit
27T I P S & T R I C K S
Manipulation of EIS controls
• Functions to fill controls on an EIS page– Limit values in a Down, List Box etc– Show available sections in a Drop Down
• Functions to read values
• Selection controls, i.e Radio Buttons, Drop Downs etc, should be passive - they should not run processes.
• Control buttons should be used to actually run a process.
28T I P S & T R I C K S
Copying values to controls
• Only a few lines of code - we don’t generally write cover functions
// Populate List Box
var oProdLimit = ActiveDocument.Sections["Query"].Limits[”Prods"]
var nProds = oProdLimit .AvailableValues.Count;
lbProductList.RemoveAll();
for (i = 1 ; i <= nProds; i++) {
lbProductList.Add(oProdLimit .AvailableValues[i]);
}
29T I P S & T R I C K S
Dashboard functions
• Traffic lights
• Formatting numbers in JavaScript– When writing data values on an EIS page, the
underlying number is shown - not the formatted version seen in the source section
– No formatting functions in JavaScript
• Writing EIS settings to reports– Indicate values of user selection
30T I P S & T R I C K S
Sample dashboards (1)
31T I P S & T R I C K S
Sample dashboards (2)
32T I P S & T R I C K S
Sample dashboards (3)
33T I P S & T R I C K S
Traffic lights
• Simple manipulation of coloured objects
• Vary visible property
34T I P S & T R I C K S
g_format
Usage:
txtSales.Text = g_format({anumber},2)
Syntax:/*------------------------------------------------------------------------------------------------------ Function: format-- Parameters: anum,anDP---- Returns text string with number formatted to <anDP> places----------------------------------------------------------------------------------------------------*/
35T I P S & T R I C K S
g_format
function format(anum,anDP){
// round to right number of decimal places// eliminate fractional part for nowanum = Math.round(anum*Math.pow(10,anDP));anum = anum.toString()
if (anDP != 0) { // need to stick a decimal place into the stringanum = anum.slice(0,(anum.length - anDP)) + ' .' + anum.slice(anum.length - anDP)
}
return anum} // end format
36T I P S & T R I C K S
g_formatCurrency(1)
Usage:
txtSales.Text = g_formatCurrency({anumber},2)
Syntax:/*------------------------------------------------------------------------------------------------------ Function: format-- Parameters: anum---- Returns text string with number formatted to <anDP> places-- (usually 2 or 0), with separators every third place-- with a currency symbol prefixed---------------------------------------------------------------------------------------------------*/
37T I P S & T R I C K S
g_formatCurrency(2)function formatCurrency(anum,anDP){
var sCurrencySymbol = '£'; // edit to suitvar sSeparator = ',' ; var nPoint;var sOutput = ''; //blank// round to right number of decimal places// eliminate fractional part for nowanum = Math.round(anum*Math.pow(10,anDP));anum = anum.toString()
if (anDP != 0) { // need to stick a decimal place into the stringanum = anum.slice(0,(anum.length - anDP)) + '.' + anum.slice(anum.length - anDP)
}// standard format function to here, now add the Separators & Currency// continue next slide
38T I P S & T R I C K S
g_formatCurrency(3)// continue from previous slide
nPoint = anum.indexOf('.')if (nPoint == -1) {
nPoint = anum.length}
for (var i=0 ; i < nPoint; i++) {if (((nPoint - i)%3 == 0)&&( i!=0)) {
sOutput += sSeparator}// end if add separatorsOutput += anum.substr(i,1)
}// end for
sOutput += anum.substr(nPoint); // fails gracefully for 0 DP
return sCurrencySymbol + sOutput} // end format
39T I P S & T R I C K S
Writing EIS settings to reports
• Set a global variable
• Use this in the report expression
Global Variable
40T I P S & T R I C K S
Exporting to Excel(1)
• Covered in depth in my paper at Brio 2001
• Simple export via Clipboard or Export
• Fully automated via JOOLEObject– uses OLE Automation– some tricks needed
• All Excel methods can be called
41T I P S & T R I C K S
Exporting to Excel(2)
oExcel = new JOOLEObject("Excel.Application");
oExcel.Visible = true;
oExcel.Workbooks.Add;
ActiveDocument.Sections[”mysectionname"].Copy()
oExcel.Sheets.Item(1).Paste
42T I P S & T R I C K S
JOOLEObject pitfalls
• When calling methods with multiple arguments you need to supply the arguments in the reverse order to that shown in Microsoft documentation
Brio: Slide.Tags.Add("Value", "TAG LABEL");
Microsoft:Slide.Tags.Add("TAG LABEL", "Value")
• When selecting Items in a collection, use the .Item(n) method not [n]
43T I P S & T R I C K S
Development aids (1)
• Use the Brio Console window
• Don’t forget the Execution Window
• Copious use of Alerts and writeln
44T I P S & T R I C K S
Development aids (2)
• External JavaScript editor can be helpful with large scripts
45T I P S & T R I C K S
Development aids (3)
• Get a good JavaScript reference book
• Try to follow good JavaScript coding conventions
– MUCH easier to read code (even your own)– Be disciplined about where you put the
code
46T I P S & T R I C K S
Reference Material and Acknowledgements
• ‘JavaScript – The Definitive Guide’David Flanagan, O’Reilly
• Maddox Ford Brio Development StandardsAvailable from [email protected]
• Platypus JavaScript editorhttp://www.c-point.com/pjedit.htm
• Thanks to my colleagues for their input– especially Aelred Tobin
47T I P S & T R I C K S
Sample code
• Sample code available at the conference
• Download from Maddox Ford website– www.maddoxford.co.uk
• email to David Eastwood at Maddox Ford– [email protected]
T I P S & T R I C K S
The end