Macro Language: Blocks

1010data's Macro Language has been the foundational tool for power users since the system first went live. Not only do our most capable clients use the Macro Language to great effect, our own analysts use it to develop reports and analyses for our clients. A basic Macro Language statement looks like this:

<sel value="store=1"/>

In other words, there is an element that outlines the general purpose of the action (<sel/> ) and one or more attributes that tell the system exactly how to carry out the operation. In this case, we are selecting rows whose values in the store column equal 1. This simple but powerful formula made it possible for people who weren't necessarily programmers to perform highly sophisticated analyses on large sets of data.

However, there was a significant shortcoming: what if at some point in the future, a different value for store is needed? Or, even worse, what if the goal changes to select rows based on a different value and a different column altogether? In the past, whoever wrote the Macro Language query in question would simply have to edit their query to make the appropriate changes. However, thanks to developments in the Macro Language that have been taking place recently, this is no longer the case.

While making edits to the simple line of code above is not particularly challenging, queries beyond a certain level of complexity were more difficult. For instance, if that line was needed several times in the same query, the edits would have to be made every time it appeared. This paradigm also made sharing analyses with people who might care about different aspects of the same data more difficult.

With the inception of <block>, both of these shortcomings have been alleviated. First, <block> allows 1010data users to parameterize the values in their Macro Language code. <block> also creates a way for users to reuse snippets of Macro Language code as much as they want. There are some basic concepts and syntax one must grasp in order to use <block> correctly. However, once these basics are understood, the Macro Language becomes a much more powerful tool for 1010data query writers.

<block> Basics

The basic syntax of <block> is very straightforward. Here is the example above written as a <block> statement:
<block name="block_test" col="store" value="1">
    <sel value="{@col}={@value}"/>
</block>
The general idea for the above statement is to wrap the original selection statement in opening and closing <block> tags. Once a <block> has been created, it must be given a name so it can be referenced in the future by other pieces of Macro Language code. name is the only required attribute for a <block> statement. All other attributes are simply user-defined variables that can be inserted into statements within a block. These variables are defined in the following way:
<block name="[BLOCK_NAME]" [VAR_1]="" [VAR_2]="">

In the above line of code, the new block is given a name and two variables are defined (but have not been assigned a value).

Now that the variables are defined, they're inserted into a regular Macro Language expression as scalar values via the following syntax:
{@var1}

This syntax takes user-defined variables from an opening <block> tag and inserts them into Macro Language expressions. This process, which results in our original expression, is called expanding the block. You can see exactly how your <block> code will expand by clicking the Expand this query button at the top of the Edit Actions (XML) dialog, as shown below:

Clicking this button will launch a pop-up window that shows you what your query looks like after the <block> has been expanded and all parameterized values have been inserted into the statement, as shown below:

Reusing a <block>

As previously mentioned, one of the most powerful features of the <block> statement is the way it allows for the reuse of Macro Language code. There are several new elements designed to work with <block> to make reusing code easier. These specialized tags are: <library>, <import>, and <insert>. This section will briefly examine each.

<library>

The <library> element is designated for storing multiple <block> statements for reuse. If you have a collection of blocks that are related, or you simply want to make all your blocks available for your current query, the first step is to store the blocks in a <library>.

For example:

<library>
    <block name="sample_block_1" var1="">
       [CONTENTS_OF_BLOCK]
    </block>
    <block name="sample_block_2" var2="">
      [CONTENTS_OF_ANOTHER_BLOCK]
    </block>
</library>

The library above contains two blocks, sample_block_1 and sample_block_2. Once you have created a library, the next step is to save it as a Quick Query so it can be referenced later when you need it. To do this, click File > Save as Quick Query.... If you need to jog your memory on saving your work as a Quick Query, check out this handy tutorial.

Once the library is saved, you will be able to use any block stored within it by using the <import> and <insert> directives.

<import>

Once you've saved a library of blocks, you will eventually want to reuse the code. To see how this is done, first here's a sample <library>:
<library>
    <block name="storeSelection" storechoice="1">
        <sel value="store={@storechoice}"/>
    </block>
</library>

The above library has been saved as a Quick Query to pub.demo.retail.selectionlib.

There are two steps to making a <block> available in your current query. First, in order to use a block stored in a library you must import the library using the <import> operation. To do this, simply provide the path to your library in the path attribute:
<import path="pub.demo.retail.selectionlib"/>

Once you have added this code to your query, you will be able to use any <block> in the library that has been imported by referencing its name. This is done in the <insert> operation.

<insert>

The <insert> operation is used to make an individual <block> available. Notice that every <block> is given a name. This name is how you tell <insert> which <block> to make available in your current query. Here's what a sample looks like:
<insert block="storeSelection"/>
Using the <insert> element makes this block available in your code. Even better, if you combine this operation with the <import> operation, the <block> doesn't even need to physically appear in your query code. Here's a quick example:
<import path="pub.demo.retail.selectionlib"/>
<insert block="storeSelection"/>
The two lines in the example above perform the exact same action as:
<block name="storeSelection" storechoice="1">
        <sel value="store={@storechoice}"/>
    </block>
At the same time, the above code expands to:
<sel value="store=1"/>

While you could retype the line above a hundred times in a hundred different queries, you would need to change each and every one any time something about your analysis changed. Blocks and libraries give you tools to reuse your code, and to update every instance where it's in use by changing it in a single location. As you continue to explore these concepts, look for places where you reuse code and ask yourself if a <library> of <block> statements would be a better solution.