Output and formatting

The first function that we describe here allows you write strings to the output window. You must be familiar with this function to be able to follow and reproduce the examples in this chapter.

Apart from strings, other values also frequently have to be output, such as numbers or dates and times. We will therefore also look at functions which take values like these and convert them to strings and format them for output.

As a starting point, you should now set up a project called Output formatting. We will add a number of tasks to this which illustrate the points discussed in this section.

Strings

Before TDM Studio can execute any kind of statement, it requires a task. Therefore please add one to your project now and name it Outputting strings.

In order to be able to create statements, we have to create a new template in the templates. This will be named Output of strings.

The template opens in the editor window, where you can enter the following line:

Trace(TRACELEVEL_INFO, "Hello TDM!");

You can save your changes by choosing File / Save in the menu bar.

Next, you drag and drop the template into the task created earlier, so that it can be executed.

To run the task, you select it in Project Explorer and choose Data / Generate Data Selected Task in the menu bar. Alternatively, you can right-click on the task and select the same command from the context menu.

The task is now executed and you can check the result in three different places:

First, in the Data Generation dialog that opens for every data generation process. A second way to check your output is in the Output window. If this is not visible on your screen, you can display it by choosing View / Output in the menu bar. It is shown in the screenshot below:

Output window

The third option is the log file, which contains a permanent record of the output. By default, a log is always written.

The easiest way of opening a log file is to use the context menu in Project Explorer. Right-click on the Logs node underneath the project name and select Open. This opens a Windows Explorer window of the directory in which the log files for the current project are saved. You can select and open the appropriate log file here.

The log file has the following entries for running the task Outputting strings:

5/16/2011 5:07:08 PM 15 INFORMATION: Generation started...

5/16/2011 5:07:08 PM 15 INFORMATION: Generation for task "String Output" started...

5/16/2011 5:07:08 PM 15 INFORMATION: Hello TDM!

5/16/2011 5:07:08 PM 1 INFORMATION: 1 templates have been processed.

5/16/2011 5:07:08 PM 1 INFORMATION: Data generation finished.

Should you not find similar entries in your log file after running the task, see chapter "Generation / Tracing" for information about how to control if logs are written. If your log file or your output window contains different information than displayed here, please see the same chapter for information about the options that control what is written to the log files and to the output window.

Meanwhile, let's return to our task output: As you can see, the log file also contains the generated data Hello TDM! in amongst the messages regarding start and completion of the data generation process. So the function Trace() that we used simply generates a log entry.

To give you a better understanding of the meaning of the line that we entered into the task variables, we shall explain the individual elements in detail below:

A) Trace

B) (

C) TRACELEVEL_INFO

D) ,

E) "Hello TDM!"

F) )

G) ;

Notes:

A) Trace is a name, a so-called identifier. Variables, constants and functions all have names, so that they can be identified. The name alone does not usually indicate whether it denotes a variable or for instance a function.

B) If an identifier is followed by an opening round bracket, then it always denotes a function. In the current example, it means that the statement calls a function with the name Trace.

Functions have a number of characteristics which are briefly summarized below:

The term "function" is a mathematical one. A mathematical function expects an input, carries out a calculation and then returns the result of the calculation. In general, the same applies to functions in TDM Studio. They take inputs (called arguments), carry out a calculation or an action and then return the result of the calculation or action.

Arguments in TDM Studio are always enclosed in round brackets. If a function expects more than one argument, the individual arguments are separated by commas inside the round brackets. If a function does not expect an argument, the pair of round brackets is empty.

In contrast to many other TDM Studio functions, Trace() does not return a result. This means that no result is processed, either. Functions that return results will be discussed later on in this chapter.

C) Once again, this line contains an identifier. You can see that it is not a function because the name is not followed by a pair of opening and closing round brackets. Instead, TRACELEVEL_INFO is a so-called constant. At this point, it is enough to know that TRACELEVEL_INFO represents a number. There are a number of different levels for the output of messages. There are error messages, warnings, information messages and debug messages. If the function Trace() is called with a simple number, as in:

Trace(3, "My message.");

then it is not obvious, which level this refers to. So to make the statement easier to understand, constants are used instead of plain numbers.

See chapter "Trace" for information on output levels that can be used and the names of the respective constants.

D) This comma separates the first argument (TRACELEVEL_INFO) from the second, which follows.

E) The second argument that Trace() expects is the message to be output. The message is a string, i.e. a sequence of characters. Strings are delimited by double quote marks. Everything between the quote marks is part of the string. However, the opening and closing quote marks must appear in the same line. How you can generate strings that span more than one line is described in see chapter "Strings".

F) This closing bracket ends the expected arguments and actually calls the function.

G) All the lines that you enter into templates and project or task variables in TDM Studio are statements. And because TDM Studio is generally statement- rather than line-oriented (with very few exceptions), statements have to be closed with a semicolon. This means that statements can be spread over several lines to make them more readable and easier to understand.

Numbers and Times

To output numbers and times with Trace(), they first have to be converted to strings. There are a number of options available for this which will be described below.

You can create a new task in your project for each of the following examples or alternatively, you can modify the same task as required. For reasons of brevity, we will not describe the steps that are necessary for creating the task, editing the text in the task variables and starting the task for each individual example.

Standard formatting

The simplest method for converting numbers and times to strings is the function Str().

Trace(TRACELEVEL_INFO, Str(12345.678));

Trace(TRACELEVEL_INFO, Str(CURRENTTIME));

The function Str() expects at least one argument, namely the value to be converted. It always returns a string. You can see at this point, that a function which returns a value can be used like a variable or a literal:

// Using a literal:

Trace(TRACELEVEL_INFO, "12345,678");

// Using a function:

Trace(TRACELEVEL_INFO, Str(12345.678));

Note the following: Decimal numbers are represented with a decimal point, not a decimal comma. They are not enclosed in quote marks or other delimiters. This also applies for whole numbers without a decimal point:

1234

1234.56

The entry

"12345,678"

is not a number but a string that contains only a number.

Executing the lines

Trace(TRACELEVEL_INFO, Str(12345));

Trace(TRACELEVEL_INFO, Str(12345.00));

Trace(TRACELEVEL_INFO, Str(12345.678));

Trace(TRACELEVEL_INFO, Str(12345.67866666677777));

Trace(TRACELEVEL_INFO, Str(CURRENTTIME));

Trace(TRACELEVEL_INFO, "'" + Str(NULL) + "'");

under an operating system with EN-US regional settings will return the following result:

12345

12345

12345.678

12345.6786666668

04/12/2009 11:24:31 AM

''

  • Numbers without decimal places are formatted without decimal places. Numbers do not display thousands separators.

  • Numbers with decimal places where the decimal places are zero are formatted like numbers without decimal places.

  • Numbers with decimal places where the decimal places are not zero are formatted with the respective number of decimal places. The character used for the decimal point depends on the current system settings.

  • Numbers with more than ten decimal places are rounded to ten digits after the decimal point.

  • Times are formatted as dates and times according to the current system settings.

  • NULL values are output as empty strings. In order to show that there was an output, the empty string in line 6 are enclosed in single quote marks.

Explicit formatting

To output numbers and dates in a specific format, you can add an additional argument to Str(), namely a string that contains formatting information:

A) Trace(TRACELEVEL_INFO, Str(12, "00000"));

B) Trace(TRACELEVEL_INFO, Str(12345, "N2"));

C) Trace(TRACELEVEL_INFO, Str(12345.678, "N2"));

D) Trace(TRACELEVEL_INFO, Str(12345.678, "C"));

E) Trace(TRACELEVEL_INFO, Str(CURRENTTIME, "yyyy-MM-dd HH-mm-ss"));

 

F) Trace(TRACELEVEL_INFO, "'" + Str(NULL, "00000") + "'");

Trace(TRACELEVEL_INFO, "'" + Str(NULL, "N2") + "'");

Trace(TRACELEVEL_INFO, "'" + Str(NULL, "C") + "'");

Trace(TRACELEVEL_INFO, "'" + Str(NULL, "yyyy-MM-dd HH-mm-ss") + "'");

Notes:

A) This formatting string can be used to format a whole number as five digits and to pad it with zeros, if necessary. Each zero in the formatting string means that a digit is output and that zero is used if no further digits are available.

B) This formatting string inserts thousands separators and two decimal places.

C) If the actual number has more decimal places than the formatting string allows, it is rounded to the number of decimal places specified.

D) This formatting string causes a currency format to be applied. This uses thousands separators, two decimal places and a currency symbol.

E) You can format a date in any format by using explicit placeholders for year, month and day. The same applies for times.

F) These lines show the output for the explicit formatting of NULL values. NULL values are never formatted so that the result is always an empty string. In order to show that there was an output, the results in this and the following lines are enclosed in single quote marks.

The result of the statements above is as follows:

00012

12,345.00

12,345.68

12.345,68 €

2009-04-12 15-03-10

''

''

''

''

Programmers who are familiar with .NET may be interested to know that the formatting statements exactly match those that can be used in the .NET method String.Format().

A complete listing of all the formats and placeholders can be found in the Microsoft Documentation on String.Format Method.

Formatting with country settings

If you do not want to use the current settings of the operating system for formatting numbers and dates, you can pass the settings for a particular country as an additional argument for Str():

Trace(TRACELEVEL_INFO,

Str(12345.678, "C", CreateCulture("en-US")));

Trace(TRACELEVEL_INFO,

Str(CURRENTTIME, CreateCulture("en-US")));

The function CreateCulture() generates an object with culture-specific information for the locale that was specified as its argument. en-US stands for US English. This means that numbers and dates are formatted as follows:

$12,345.68

4/12/2009 3:19:57 PM

Extended formatting

There is also an alternative method to Str() for formatting output. It is the function Format() which we shall take a closer look at in this section:

Trace(TRACELEVEL_INFO, Format("Whole number: {0}", 12345));

Trace(TRACELEVEL_INFO, Format("Decimal number: {0}", 12345.678));

Trace(TRACELEVEL_INFO,

Format(CreateCulture("en-US"), "Time: {0}", CURRENTTIME));

The first argument that Format() expects is either culture-specific information or an extended formatting string. This is followed by the elements to be formatted.

The extended formatting string is output like a string with all the characters that it contains. However, parts enclosed in curly brackets ({0}) are replaced by concretely formatted values, namely the values that follow as arguments of the formatting string.

The lines above return the following result:

Whole number: 12345

Decimal number: 12345.678

Time 4/12/2009 3:19:57 PM

This allows you to make several replacements in an extended formatting strings at the same time. The numbers in curly brackets specify the argument to be inserted:

Trace(TRACELEVEL_INFO,

Format("Two numbers: {0} and {1}", 12345, 54321));

The result is:

Two numbers: 12345 and 54321

The first argument that follows the extended formatting string has the index 0, the second has the index 1, etc. This means that {0} receives the value 12345 and {1} the value 54321.

After the indexes in the curly brackets, you can use the same formatting statements as in Str(). These statements are separated from the index by a colon:

Trace(TRACELEVEL_INFO, Format("Whole number: {0:00000}", 12));

Trace(TRACELEVEL_INFO, Format("Date: {0:D}", CURRENTTIME));

The result:

Whole number: 00012

Date: Monday, April 12, 2010

Programmers who are familiar with .NET may be interested to know that the function Format() works in the same way as the .NET method String.Format(). Once again, NULL values are not formatted but output as an empty string:

Trace(TRACELEVEL_INFO, Format("Whole number: '{0:00000}'", NULL));

Trace(TRACELEVEL_INFO, Format("Date: '{0:D}'", NULL));

The result is:

Whole number: ''

Date: ''