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
<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>
<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).
{@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 . 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>
<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.
<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>
<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"/>
<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"/>
<block name="storeSelection" storechoice="1"> <sel value="store={@storechoice}"/> </block>
<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.