How To Create a QScript To Insert a Custom Rule

From Q
Jump to: navigation, search

If you need to re-use a custom rule in a number of different projects then it can sometimes be a good idea to write a QScript that will insert the rule for you. This is particularly the case if you are providing the rule for non-technical users. The benefit of using a QScript to insert a rule is that it avoids the necessity to cut and paste code from a file into the Q project - instead you can just run the QScript using Automate > Run QScript (Macro) from File.

Steps For Creating the QScript

Each of these steps is expanded upon below with a worked example.

  1. Create your custom rule.
  2. Format your custom rule as a string.
  3. Create the QScript to add the rule to a project. See Creating QScript files for instructions on how to create and save the QScript file.

Create Your Custom Rule

You should create your custom rule according to the steps described in Creating a Custom Rule.

In this example we will utilise the rule created in Creating a Custom Rule for showing only the top 5 rows of a table. The code for this rule is:

includeWeb('Table JavaScript Utility Functions');
// creating the form
form.setHeading('Selecting the number of rows to show on a table');
var label_statistic = form.newLabel('Number of rows:'); //creating the phrase 'Number of rows:' 
var numeric_up_down  = form.newNumericUpDown('threshold'); //creating a control where a user can enter a number.
numeric_up_down.setDefault(5);// specifying the default number of rows to be shown
numeric_up_down.setIncrement(1); // specifying that the user must enter whole numbers.
numeric_up_down.setMinimum(1); // preventing the user from having tables with less than 1 row
form.setInputControls([label_statistic, numeric_up_down]); // telling Q to create the form
// Extracting the number of rows provided by the user and assigning it to a variable.
var maximum_number_rows = numeric_up_down.getValue();
// Deleting the rows.
while(table.numberRows > maximum_number_rows) {
  deleteRowComplete(table.numberRows - 1);
}
// creating the form title
form.setSummary('Top ' + maximum_number_rows + ' rows');

Format Your Rule as a String

The code for the rule needs to be added as a string within the code for the QScript. This means that the entire block of code must be placed within quotes " ". The properly-formatted string to use for the example code above is as follows:

var rule_expression = "includeWeb('Table JavaScript Utility Functions');\r\n"
+ "// creating the form\r\n"
+ "form.setHeading('Selecting the number of rows to show on a table');\r\n"
+ "var label_statistic = form.newLabel('Number of rows:'); //creating the phrase 'Number of rows:' \r\n"
+ "var numeric_up_down  = form.newNumericUpDown('threshold'); //creating a control where a user can enter a number.\r\n"
+ "numeric_up_down.setDefault(5);// specifying the default number of rows to be shown\r\n"
+ "numeric_up_down.setIncrement(1); // specifying that the user must enter whole numbers.\r\n"
+ "numeric_up_down.setMinimum(1); // preventing the user from having tables with less than 1 row\r\n"
+ "form.setInputControls([label_statistic, numeric_up_down]); // telling Q to create the form\r\n"
+ "// Extracting the number of rows provided by the user and assigning it to a variable.\r\n"
+ "var maximum_number_rows = numeric_up_down.getValue();\r\n"
+ "// Deleting the rows.\r\n"
+ "while(table.numberRows > maximum_number_rows) {\r\n"
+ "  deleteRowComplete(table.numberRows - 1);\r\n"
+ "}\r\n"
+ "// creating the form title\r\n"
+ "form.setSummary('Top ' + maximum_number_rows + ' rows');\r\n";

There are several points that are essential to note:

  1. The code has been assigned into a JavaScript variable called rule_expression.
  2. Each line of code is surrounded in quotes "". This denotes a string in JavaScript. Single quotes can also be used, but caution is required when quote characters also appear in the code for the rule (see below).
  3. Each line after the first begins with a plus-sign. This combines the string from each line into a single string. You could put all of the code on one line within a single pair of quotes, but this makes your code difficult to read.
  4. There is a new-line instruction, \r\n, at the end of each line of code. This ensures that your code will be split across multiple lines (and hence will be readable) after it has been added to a project.
  5. The last line of the string is ended with a ; to indicate the end of the instruction (just like any other line of JavaScript).

Create the QScript to Add the Rule

The QScript for adding the rule needs to do two things. Firstly, it needs to create a new rule object in the project. This is done using the QScript function called newCustomRule(). Secondly, it needs to add the rule to at least one table. The best approach to satisfying this requirement is to apply the rule to any tables that the user has selected before they have run the script, and these tables are obtained using the function selectedItems(). The QScript below will add the rule to every table that is selected at the time the script is run.

var rule_expression = "includeWeb('Table JavaScript Utility Functions');\r\n"
+ "// creating the form\r\n"
+ "form.setHeading('Selecting the number of rows to show on a table');\r\n"
+ "var label_statistic = form.newLabel('Number of rows:'); //creating the phrase 'Number of rows:' \r\n"
+ "var numeric_up_down  = form.newNumericUpDown('threshold'); //creating a control where a user can enter a number.\r\n"
+ "numeric_up_down.setDefault(5);// specifying the default number of rows to be shown\r\n"
+ "numeric_up_down.setIncrement(1); // specifying that the user must enter whole numbers.\r\n"
+ "numeric_up_down.setMinimum(1); // preventing the user from having tables with less than 1 row\r\n"
+ "form.setInputControls([label_statistic, numeric_up_down]); // telling Q to create the form\r\n"
+ "// Extracting the number of rows provided by the user and assigning it to a variable.\r\n"
+ "var maximum_number_rows = numeric_up_down.getValue();\r\n"
+ "// Deleting the rows.\r\n"
+ "while(table.numberRows > maximum_number_rows) {\r\n"
+ "  deleteRowComplete(table.numberRows - 1);\r\n"
+ "}\r\n"
+ "// creating the form title\r\n"
+ "form.setSummary('Top ' + maximum_number_rows + ' rows');\r\n";

// Make the rule available in the project
var new_rule = project.rules.newCustomRule(rule_expression, {});

// Get the array of items that the user has selected before they run the script
var selected_items = project.report.selectedItems();

// Apply the rule to each selected items
selected_items.forEach(function (table) {
	table.rules.add(new_rule);
});

There are several elements of code that are essential to note:

  1. The expression for the rule needs to be defined above the rest of the code, which then adds the rule to the project.
  2. The rule must be added to the set of rules in the project before it can be added to any tables. This is done using project.rules.newCustomRule(), and the resulting rule is stored in the object called new_rule.
  3. The tables that have been selected by the user at the time the script was run are stored in an array called selected_items.
  4. The function forEach is used to loop over the array selected_items and perform the same action on each item in the array. In this case, the function inside forEach uses table.rules.add() to add the custom rule called new_rule to the table.

Using Strings

As discussed above, when you write the QScript for adding a rule the code for the rule needs to be introduced as a string. In the example above, the double-quotes " " were used to denote the string. However, the rule itself also contains strings, for example 'Number of rows:' is a string that is used as one of the labels in the rule. This string is denoted using single quotes ' '.

In JavaScript you can either use single quotes or double quotes to denote a string value. The most important thing to keep in mind is that you should choose one type of quote for the labels in the rule and use the other type to denote the rule expression within the QScript. Don't use both types of quote within the code for the rule as this will likely prevent your QScript from successfully applying the rule.

See also