Quick StartThe ReportMagic MenuSchedulesBatch JobsReport StudioFilesProfileAdminAccount DetailsMeraki WebHooksGetting StartedAbout ReportMagicRegistering and Logging InSearching ReportMagicConnections and AgentsWriting ReportsStarting Out With Report StudioCreating Report TemplatesRMScriptMacro ShorthandReporting on Different Periods of TimeSetting Macro Parameter DefaultsStoring Input and Output FilesReport VariablesUsing Variable ParametersSpecifying How Graphs LookStep-by-Step LogicMonitor Graph ExamplesStep-by-Step Jira Graph ExamplesSpecifying How Tables LookChanging Fonts and ColorsUsing Macros in PowerPoint TemplatesRestricted MacrosGenerating Reports Using SchedulesUsing HTML Forms in SchedulesSeeing How Reports RanViewing ReportsCached ValuesUsing AggregationsAdvanced Report StudioAPI AccessREST APIREST API - FilesAdvancedRole-Based Access Control (RBAC)SecurityMiscellaneousBadgesCertificationsTips, Tricks and Shortcut KeysMacrosAgentAgent.ConnectionAgent.ExecuteAgent.MonitorMagicNodeListAgent.MonitorMagicNodeMeasurementListAgent.MonitorMagicNodeMeasurementSummaryAgent.MonitorMagicNodePropertyListAgent.MonitorMagicNodeTypeListAgent.PropertyAgent.SqlAnalysisAgent.SqlGraphAgent.SqlListAgent.SqlTableAgent.SqlValueAgent.SqlValuesAgent.WebQueryAlertMagicAlertMagic.MetricsGraphAlertMagic.MetricsListAutoTaskAutoTask.AccountListAutoTask.AccountPropertyAutoTask.ConnectionAutoTask.CountAutoTask.FieldListAutoTask.FieldPropertyAutoTask.ListAutoTask.PropertyAutoTask.SummaryValueAutoTask.TicketListAutoTask.TicketPropertyAzureAzure.ConnectionAzure.LogAnalyticsGraphAzure.LogAnalyticsQueryAzure.LogAnalyticsScalarAzure.LogAnalyticsTableAzure.ResourceGroupListAzure.ResourceListAzure.ResourcePropertiesAzure.SentinelAlertRuleListAzure.SentinelConnectorListAzure.SentinelIncidentListAzure.SentinelThreatIndicatorListAzure.SentinelThreatIndicatorMetricListAzure.SubscriptionListBloggerBlogger.BlogPropertyBlogger.ConnectionBlogger.PageBlogger.PageListBlogger.PagePropertyBlogger.PostBlogger.PostListBlogger.PostPropertyCacheCache.ExpiresCache.GetCache.IsSetCache.SetCache.UnsetCertifyCertify.ConnectionCertify.DepartmentListCertify.DepartmentPropertyCherwellCherwell.BusinessObjectDefinitionListCherwell.BusinessObjectListCherwell.BusinessObjectSchemaCherwell.BusinessObjectSummaryCherwell.ConnectionCiscoCisco.ConnectionCisco.FirmwareVersionPropertyCisco.SecurityAdvisoryListCisco.SerialNumberPropertyCisco.SoftwareSuggestionListCiscoDnaCenterCiscoDnaCenter.ConnectionCiscoDnaCenter.SiteListCiscoDnaCenter.SitePropertyCloudHealthCloudHealth.AssetDetailsCloudHealth.AssetListCloudHealth.AvailableReportDimensionsCloudHealth.AvailableReportOptionsCloudHealth.AvailableReportsListCloudHealth.AwsAccountDetailsCloudHealth.AwsAccountsListCloudHealth.ConnectionCloudHealth.CustomerDetailsCloudHealth.CustomerListCloudHealth.CustomerReportDetailsCloudHealth.CustomerStatementDetailsCloudHealth.OrganisationAccountsListCloudHealth.OrganisationListCloudHealth.QueryConnectWiseManageConnectWiseManage.ConnectionConnectWiseManage.CountConnectWiseManage.DictionaryConnectWiseManage.ListConnectWiseManage.PropertyCoreArrayArray.CountBreakBreakpointCalculateColorCommentContinueConvertDeleteDeleteRowDocumentBookmarkDocumentBreakDocumentInsertSectionDocumentSectionEmailEmailFileEmailReportExecuteForEachFormatTableCellFormatTableRowIfIgnoreIncInsertTableCellImageIsSetLinearRegressionLinkMapObjectRandomRegexRepeatRowSearchAndReplaceSectionSettingsSleepStopStopwatchStringStringIndexSubstringSwitchThrowExceptionUnsetWarningDatabaseDatabase.ConnectionDatabase.GraphDatabase.ListDatabase.TableDatabase.ValueDatabase.ValuesDataMagicDataMagic.SyncDictionaryDictionary.ItemDictionary.KeysDictionary.ValuesDocumentDocument.SetPropertiesFileFile.CopyFile.CopyOutputFilesFile.Csv.CellFile.Csv.RowFile.Csv.RowCountFile.Csv.TableFile.EmbedFile.ExecuteFile.ExistsFile.ImageFile.InsertFile.ListFile.LoadListFile.LoadObjectFile.LoadStringFile.LoadVariablesFile.Xlsx.CellFile.Xlsx.RowFile.Xlsx.RowCountFile.Xlsx.TableFunctionFunction.CallFunction.DefineGoogleGoogle.ConnectionGoogle.TableGraphGraph.AddDataGraph.DeleteDataGraph.RenameDataGraph.UpdateGravatarGravatar.ImageHighlightHighlight.BearerSummaryHighlight.BroadbandSummaryHighlight.CellularSummaryHighlight.ConnectionHighlight.FolderListHighlight.HttpServerPerformanceSummaryHighlight.IcmpTcpUdpPerformanceSummaryHighlight.MosPerformanceSummaryHighlight.PrecisionPerformanceSummaryHighlight.TunnelSummaryHighlight.WatchNodeListHighlight.WirelessAccessPointSummaryHubSpotHubSpot.ListJarrayJarray.TableJiraJira.AttachmentImageJira.AttachmentListJira.AttachmentPropertyJira.ConnectionJira.GraphJira.InsertMarkupJira.IssueAnalysisJira.IssueCommentListJira.IssueCommentPropertyJira.IssueLastCommentPropertyJira.IssueListJira.IssuePropertyJira.IssueResponseTimeJira.LastImageJira.StatusListJira.TableJira.TimeInStateJira.UserListJira.UserPropertyJsonJson.ItemJson.ListKrokiKroki.ImageListList.AddList.AnalysisList.ComplementList.CountList.DequeueList.DuplicatesList.FirstList.GraphList.GroupByList.IndicesOfList.IntersectionList.ItemList.RangeList.SelectList.SelectColumnsList.SortList.SummaryValueList.TableList.UnionList.WhereLogicMonitorLogicMonitor.AccountPropertyLogicMonitor.AlertAnalysisLogicMonitor.AlertCalendarLogicMonitor.AlertCountLogicMonitor.AlertListLogicMonitor.AlertMapLogicMonitor.AlertPropertyLogicMonitor.AlertRuleListLogicMonitor.AlertRulePropertyLogicMonitor.AlertStatusLogicMonitor.AlertTableLogicMonitor.AppliesToFunctionListLogicMonitor.AppliesToFunctionPropertyLogicMonitor.AppliesToListLogicMonitor.AuditEventAnalysisLogicMonitor.BigNumberWidgetValuesLogicMonitor.ClearCacheLogicMonitor.CollectorExecuteLogicMonitor.CollectorGroupListLogicMonitor.CollectorGroupPropertyLogicMonitor.CollectorListLogicMonitor.CollectorPropertyLogicMonitor.CollectorVersionListLogicMonitor.CollectorVersionPropertyLogicMonitor.ConfigCheckListLogicMonitor.ConfigCheckPropertyLogicMonitor.ConfigSourceGroupListLogicMonitor.ConfigSourceListLogicMonitor.ConfigSourcePropertyLogicMonitor.ConfigSourceXmlLogicMonitor.ConnectionLogicMonitor.ConnectionApiTokenLogicMonitor.ConvertToLiveWidgetLogicMonitor.DashboardLogicMonitor.DashboardGroupListLogicMonitor.DashboardGroupPropertyLogicMonitor.DashboardListLogicMonitor.DashboardPropertyLogicMonitor.DashboardWidgetListLogicMonitor.DatamartSyncLogicMonitor.DataPointListLogicMonitor.DataPointPropertyLogicMonitor.DataSourceGraphListLogicMonitor.DataSourceGraphPropertyLogicMonitor.DataSourceGroupListLogicMonitor.DataSourceListLogicMonitor.DataSourcePropertyLogicMonitor.DataSourceXmlLogicMonitor.DeviceConfigSourceFileLogicMonitor.DeviceConfigSourceInstanceListLogicMonitor.DeviceConfigSourceListLogicMonitor.DeviceConfigSourcePropertyLogicMonitor.DeviceCountLogicMonitor.DeviceDataSourceListLogicMonitor.DeviceDataSourcePropertyLogicMonitor.DeviceGroupListLogicMonitor.DeviceGroupPropertyLogicMonitor.DeviceListLogicMonitor.DevicePropertyLogicMonitor.DeviceSlaWidgetPropertyLogicMonitor.DeviceTableLogicMonitor.EscalationChainDestinationListLogicMonitor.EscalationChainDestinationPropertyLogicMonitor.EscalationChainListLogicMonitor.EscalationChainPropertyLogicMonitor.EventSourceFilterListLogicMonitor.EventSourceFilterPropertyLogicMonitor.EventSourceGroupListLogicMonitor.EventSourceListLogicMonitor.EventSourcePropertyLogicMonitor.EventSourceXmlLogicMonitor.FinancialInformationLogicMonitor.ForecastLogicMonitor.GraphLogicMonitor.HistoricSdtListLogicMonitor.ImageLogicMonitor.InstanceAnalysisLogicMonitor.InstanceCountLogicMonitor.InstanceDetailsTableLogicMonitor.InstanceGroupCountLogicMonitor.InstanceGroupListLogicMonitor.InstanceListLogicMonitor.InstancePropertyLogicMonitor.IntegrationListLogicMonitor.IntegrationPropertyLogicMonitor.JobMonitorListLogicMonitor.JobMonitorPropertyLogicMonitor.LastMeasurementLogicMonitor.LogAnalysisLogicMonitor.LogicModuleMetadataPropertyLogicMonitor.LogicModuleUpdateListLogicMonitor.LogicModuleUpdatePropertyLogicMonitor.LogItemListLogicMonitor.NetscanGroupListLogicMonitor.NetscanGroupPropertyLogicMonitor.NetscanListLogicMonitor.NetscanPropertyLogicMonitor.NewUserMessagePropertyLogicMonitor.PaymentInformationLogicMonitor.PercentageAvailabilityLogicMonitor.PortalVersionLogicMonitor.PropertySourceGroupListLogicMonitor.PropertySourceJsonLogicMonitor.PropertySourceListLogicMonitor.PropertySourcePropertyLogicMonitor.QueryLogicMonitor.RecipientGroupListLogicMonitor.RecipientGroupPropertyLogicMonitor.RecycleBinItemListLogicMonitor.RecycleBinItemPropertyLogicMonitor.ReportGroupListLogicMonitor.ReportGroupPropertyLogicMonitor.ReportListLogicMonitor.ReportPropertyLogicMonitor.ResourceAnalysisLogicMonitor.ResourceGroupAnalysisLogicMonitor.RoleListLogicMonitor.RolePropertyLogicMonitor.SdtListLogicMonitor.SdtPercentageLogicMonitor.SdtPropertyLogicMonitor.SingleSignOnPropertyLogicMonitor.SlaWidgetValuesLogicMonitor.SnmpSysOidMapListLogicMonitor.SnmpSysOidMapPropertyLogicMonitor.SummaryValueLogicMonitor.SummaryValueListLogicMonitor.ThresholdLogicMonitor.TrafficTableLogicMonitor.UnmonitoredDeviceListLogicMonitor.UnmonitoredDevicePropertyLogicMonitor.UserApiTokenListLogicMonitor.UserApiTokenPropertyLogicMonitor.UserListLogicMonitor.UserPropertyLogicMonitor.WebsiteCheckpointDataListLogicMonitor.WebsiteCountLogicMonitor.WebsiteGroupAnalysisLogicMonitor.WebsiteGroupCountLogicMonitor.WebsiteGroupListLogicMonitor.WebsiteGroupPropertyLogicMonitor.WebsiteListLogicMonitor.WebsitePropertyLogicMonitor.WidgetStatusMagicSuiteMagicSuite.SubscriptionListMerakiMeraki.CameraImageMeraki.ConfigurationChangeListMeraki.ConnectionMeraki.DevicePropertyMeraki.DeviceUplinkPropertyMeraki.EndOfLifeMeraki.NetworkClientListMeraki.NetworkDeviceListMeraki.NetworkEventListMeraki.NetworkListMeraki.NetworkPropertyMeraki.NetworkSwitchPortsListMeraki.NetworkSwitchStackListMeraki.OrganizationDeviceLicenseListMeraki.OrganizationDeviceLicensePropertyMeraki.OrganizationDeviceListMeraki.OrganizationDeviceListStatusPropertyMeraki.OrganizationInventoryListMeraki.OrganizationLicenseStatePropertyMeraki.OrganizationListMeraki.OrganizationPropertyMeraki.OrganizationUplinkUsageMeraki.WirelessNetworkClientConnectionStatsPropertyMeraki.WirelessNetworkClientLatencyListMeraki.WirelessNetworkClientsConnectionStatsListMeraki.WirelessNetworkClientsLatencyListMeraki.WirelessNetworkConnectionStatsPropertyMeraki.WirelessNetworkDeviceConnectionStatsPropertyMeraki.WirelessNetworkDeviceLatencyListMeraki.WirelessNetworkDevicesConnectionStatsListMeraki.WirelessNetworkDevicesLatencyListMeraki.WirelessNetworkLatencyListMicrosoftDataverseMicrosoftDataverse.ConnectionMicrosoftDataverse.CountMicrosoftDataverse.EntityDefinitionsListMicrosoftDataverse.EntityListMicrosoftDataverse.EntityPropertyListMicrosoftDataverse.ListMicrosoftDataverse.PropertyMicrosoftGraphMicrosoftGraph.ConnectionMicrosoftGraph.MicrosoftDataverseConnectionMicrosoftGraph.QueryObjectObject.ArrayCountObject.PropertyObject.TypeObject.UnpackObject.UnpackVariablesOpenAiOpenAi.AnswerOpenAi.CompleteOpenAi.ConnectionOpenAi.ImageQuickBooksQuickBooks.ConnectionQuickBooks.PropertyReportMagicReportMagic.ApplyBrandReportMagic.BadgeListReportMagic.ConnectionListReportMagic.ConnectionPropertyReportMagic.ConnectionStatusPropertyReportMagic.FeedbackListReportMagic.FeedbackPropertyReportMagic.MacroGroupListReportMagic.MacroHelpReportMagic.MacroListReportMagic.ReportBatchJobCountReportMagic.ReportBatchJobListReportMagic.ReportBatchJobPropertyReportMagic.ReportConnectionSummaryReportMagic.ReportJobCountReportMagic.ReportJobListReportMagic.ReportJobPropertyReportMagic.ReportMacroCountReportMagic.ReportPropertyReportMagic.ReportScheduleCountReportMagic.ReportScheduleListReportMagic.ReportSchedulePropertyReportMagic.SetReportPropertyReportMagic.SystemPropertyReportMagic.TenantImageReportMagic.TopicHelpReportMagic.VersionSalesforceSalesforce.ConnectionSalesforce.ListSalesforce.PropertyServiceNowServiceNow.ConnectionServiceNow.CountServiceNow.CreateServiceNow.DeleteServiceNow.DictionaryServiceNow.ListServiceNow.PropertyServiceNow.UpdateShapeShape.AddShape.CloneShape.DeleteShape.FormatShape.HideShape.SetPropertyShape.SetTextSlackSlack.ConnectionSlack.MessageSlideSlide.DeleteSlide.DeleteSectionSlide.LinkSlide.MoveToSlide.RepeatSmtpSmtp.ConnectionSnmpSnmp.EnterprisePropertySolarWindsSolarWinds.ConnectionSolarWinds.SqlListSolarWinds.SqlTableSqlSql.AnalysisTableTable.ColumnCountTable.DeleteTable.FormatTable.GraphTable.MergeCellsTable.RowCountTable.SaveTable.SortTable.WorldMapTimeCalendarCronHumanReadableCronRunDateDateRangeDateTimeDateTime.IsInWorkHoursDateTime.WorkHoursDurationTimeSpanTogglToggl.ClientListToggl.ClientPropertyToggl.ConnectionToggl.ProjectListToggl.ProjectPropertyToggl.ProjectReportPropertyToggl.TimeEntryListToggl.TimeEntryPropertyToggl.UserListToggl.UserPropertyToggl.WorkspaceListToggl.WorkspacePropertyTwilioTwilio.ConnectionTwilio.SmsUkParliamentUkParliament.PetitionCountUkParliament.PetitionListUkParliament.PetitionPropertyVariableVariable.ImageVariable.ListVariable.PropertyWebWeb.ConnectionWeb.HtmlWeb.ImageWeb.QueryWeb.ScreenshotWeb.TableWeb.TextXlsxXlsx.AddAnalysisXlsx.EmbedZendeskZendesk.ConnectionZendesk.ListZendesk.PropertyZoho.DeskZoho.Desk.ZohoListZoho.Desk.ZohoProperty

Storing and Retrieving Variables

Storing Variables for Later Use

You can store the output of macros for input into later macros using the storeAs (or storeAsHidden) parameter. Please note that:
  • Variable names may only contain the following characters: AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_0123456789
  • Variable names must NOT start with any of: 0123456789

Please edit any older Templates or RMScript files which break these rules - you'll see a warning or error in the output, depending on the macro used.
The value will be stored, along with its type. So if you store 1234 as a 32-bit integer in variable "X", X will be treated as a 32-bit integer until either:
  • The end of the report or
  • You overwrite it with a value of a different type
It is best practice, when storing complex data structures, to avoid using strings and use lists instead. Many older Report Templates might store a table of data like this, which can fail if a special character, such as one of [, ; ^ " ` or =], is present in any of the cells:
[String: value=Col1^Col2^Col3;{Row1Col1Value}^{Row1Col2Value}^{Row1Col3Value};{Row2Col1Value}^{Row2Col2Value}^{Row2Col3Value}]

Instead, prefer the following, which has no such issues:

[Calculate: value=`list(list('Col1', 'Col2', 'Col3'), list(Row1Col1Value, Row1Col2Value, Row1Col3Value), list(Row2Col1Value, Row2Col2Value, Row2Col3Value))`]

Examples of Stored Variables

Macro Variable name Value type Value String inserted into report Notes
[String: value=Amanda, storeAs=FirstName] FirstName String Amanda Amanda FirstName is a string and will be visible in the output document.
[String: value=Jones, storeAsHidden=LastName] LastName String Jones LastName is a string and will not be visible in the output document because the variable was stored using storeAsHidden instead of storeAs.
[:Rachael,=>MiddleName] MiddleName String Rachael Here, the shorthand form of the String macro is used. MiddleName is a string and will not be visible in the output document because the variable was stored using the shorthand form of the storeAsHidden parameter.
[String: value="BA, MSc", storeAsHidden=Qualifications] Qualifications String BA, MSc Qualifications is a string. Note that because the string contains a comma, it was neccessary to surround the value with double quotes ("). You can allso use backtick (`) for the purpose, for example when storing a value containing double quotes.
[String: value=`Plum Tree Cottage`, storeAsHidden=HouseName] HouseName String Plum Tree Cottage HouseName is a string.
[String: value=`1234`, storeAsHidden=HouseNumber] HouseNumber String 1234 HouseNumber is a string, even though it might look like an integer. If you intended it to be an integer, use the [Calculate:] macro (see below).
[Calculate: value=`5678`, storeAsHidden=Steps] Steps Int32 5678 Steps is a 32-bit integer (Int32). The type was determined at runtime when the [Calculate:] macro was evaluated.
[=:17,=>Age1] Age1 Int32 17 Here, the shorthand form of the Calculate macro is used. Because the [Calculate:] macro will evaluate to a 32-bit integer, the output type will be Int32.
[=:17.0,=>Age2] Age2 Double 17 Because the [Calculate:] macro will evaluate to a fouble-precision floating point number, the output type will be Double.
[Calculate: value='448432899811', storeAsHidden=PhoneNumber] PhoneNumber String 448432899811 PhoneNumber is a string. The type was determined at runtime when the [Calculate:] macro was evaluated.
[Calculate: value=`if(customerIsUk, '08432 899 811', '+44 8432 899 811')`, storeAsHidden=FormattedPhoneNumber] FormattedPhoneNumber String "08432 899 811" or "+44 8432 899 811". PhoneNumber is a string. The output value will depending on whether this is a UK customer, but in either case the result will be a string.
[Calculate: value=`if(IdOutputType == 'text', '1234', 1234)`, storeAsHidden=Id] Id String or Int32 1234 The output type will depend on whether the variable IdOutputType is set to the string 'text'.
[Calculate: value=`list('a', 123, null)`, storeAsHidden=Things] Things List<object?> (list of nullable objects) [] { "a", 123, null } When ReportMagic produces lists, they will all be (in C# / .NET terms) lists of nullable objects. The objects in the list can be of any supported type.
[DateTime: format=yyyy-MM-01, storeAsHidden=RightNow, storeFormattedValueAs=FirstOfThisMonth] RightNow 2022-02-10T12:34:56Z DateTimeOffset 2022-02-01 This example assumes that the macro was run at 12:34:56 on the 10th February 2022 UTC. Like all macros, ReportMagic ALWAYS uses the UTC time zone. Note that the formatted output is stored in the variable FirstOfThisMonth as a string.

Retrieving data from variables

There are different ways to retrieve data from variables:
  • As part of an NCalc evaluation
  • Using "Early Evaluation"
  • Using "Late Evaluation"

Retrieving data as part of an NCalc evaluation

ReportMagic supports all the core NCalc functions, plus those provided by the PanoramicData.NCalcExtensions library. Many macros support evaluation using the NCalc functional language. Key such macros are:
  • [Calculate: value=`<NCALC OBJECT EXPRESSION GOES HERE>`, storeAsHidden=X]
  • [If: condition=`<NCALC BOOLEAN EXPRESSION GOES HERE>`]
NCalc expressions output a value of a given type. For macros that use the condition parameter (like [If:]), the resultant object must be a boolean type (either true or false). The [Calculate:] macro can output any supported type. These types include:
  • String
  • Int32
  • Double (64-bit double-precision floating point)
  • List<object?> (list of nullable objects)
NCalc evaluation should be used whenever possible, for example by using the [Calculate:] macro. This is because:
  • NCalc evaluation is strongly typed throughout, avoiding type errors.
  • The report author does not have to worry about whether a string contains special characters, such as [, ; ^ " ` =] and other special characters that might be parsed incorrectly.
  • The shorthand form of the [Calculate:] macro [=:] uses the fewest characters in the Report Template, which can be handy when templating tables.
For example, the following two macros are interpreted identically:
    [Calculate: value=A+B]
    [=:A+B]
You should avoid using early evaluation inside NCalc expressions.  It is unnecessary, more difficult to read and error-prone.  For example if A contained a single comma character:
    [Calculate: value=A+B]
...would work as expected, whereas:
    [Calculate: value={A}+{B}, comment="Don't do this!"]
would not. 

Retrieving data using "Early Evaluation"

To use "Early Evaluation", place curly braces around the variable name. This will modify the original macro text before it is interpreted. Early evaluation should generally be avoided, but there are times when it can be particularly useful:

  • When you want to debug macros
  • When you want to construct a macro as a string

Examples

A simple example is:
    From the desk of: [String: value={FirstName}][Calculate: value='{Surname}']
    Dear All,
    Please see your report attached.
    Best Wishes,
    [:{FirstName} {Surname}]
As ReportMagic reads each macro, it replaces the curly-brace tokens EARLY in the process, before the macro is evaluated, meaning that it would read the template as follows:
    From the desk of: [String: value=Amanda][Calculate: value='Jones']
    Dear All,
    Please see your report attached.
    Best Wishes,
    [String: value=Amanda Jones]
Here is an example of constructing a macro as a string:
    [String: value=`format=N5`, storeAsHidden=Format]
    [Calculate: value=Sqrt(2), {Format}]
ReportMagic would read the template as follows:
    [String: value=`format=N5`, storeAsHidden=Format]
    [Calculate: value=Sqrt(2), format=N5]
Pre-/post- increment/decrement
With Early Evaluation, you can also use pre-/post- increment/decrement in the same way as most C-like languages. For example:
    [String: value=0, storeAs=A] A is now 0
    [String: value={++A}, storeAs=B] A is now 1, B is now 1
    [String: value={A++}, storeAs=C] A is now 2, C is now 1
    [String: value={A--}, storeAs=D] A is now 1, D is now 2
    [String: value={--A}, storeAs=E] A is now 0, E is now 0

Retrieving data using "Late Evaluation"

Where a macro parameter should be set simply to the value in a variable name, you can use Late Evaluation. This sets the parameter later on during macro processing, so any stray characters in the variable will not be incorrectly interpreted.
For example, the following would not be correctly processed:
    [String: value=`A, B and C`, storeAsHidden=X]
    [String: value={X}]
...because the last macro would be interpreted as "value=A", with ReportMagic unable to interpret "B and C":
    [String: value=A, B and C, storeAsHidden=X]
With late evaluation, you would use:
    [String: value=`A, B and C`, storeAsHidden=X]
    [String: value={=X}]
This will put the string "A, B and C" into the last macro's value parameter at the very last minute.

With late evaluation, you can use any NCalc formula, so:
    [:AB, =>X]
    [:CD, =>Y]
    [String: value={=X + Y}]
...produces
    ABCD
Example 2:
    [=:10, =>P]
    [ForEach: values=`{=list(P * 2, P * 4, P * 6)}`, =>Q]
    [=:Q]
    [EndForEach:]
...produces
    20
    40
    60

Enclosing characters

For most macros, values don't need to be in quotes. However, if a parameter values contains commas, ReportMagic will interpret them as the end of a parameter. You can prevent this by protecting the value with double quotes (") or backtick (`). For example:
    [String: value="a, b and c", storeAs=A]
    [String: value=`a, b and c`, storeAs=A]
    [String: value=`"a, b and c"`, storeAs=A]
    He said [String: value=`{A}`]
Because it is not possible to protect values that MAY contain double quotes or backticks, Early Evaluation should always be avoided in these circumstances.

Output formatting and precision

When dealing with numbers, ReportMagic will always maintain full (64-bit) precision where appropriate. This is to avoid rounding errors later in the report. However, when numbers (and other types) are output in the report, the format can be set using C# formatting. For example:
    The square root of 2 is [Calculate: value=`Sqrt(2)`, storeAs=A] to 2 decimal places.
    If you square it, you get back to [Calculate: value=`Pow(A, 2)`]
If you try this in Report Studio, you can see in the "Variables" pane in the bottom right that A is stored as 1.4142135623730951, but the report output will show "1.41". If you want to show more precision in the report itself, you could do:
    The square root of 2 is [Calculate: value=`Sqrt(2)`, storeAs=A, format=N5] to 5 decimal places.
    If you square it, you get back to [Calculate: value=`Pow(A, 2)`]
If you want to maintain lower precision in your variable, simply use the round function in the [Calculate:] macro:
    [Calculate: value=`Round(A, 2)`]

Viewing Variables

Variables can be viewed in Report Studio at the lower-right of the screen.

There are 2 relevant tabs in the UI:

  • ALL VARIABLES
  • MACRO VARIABLES

The first tab shows all the variables created by the report in question. This means that, suppose a macro creates a variable called "My Variable", and stores in it a value of 1, then when any subsequent macros also save to the same variable, the first tab only shows the most recent value as it had been overwritten.

When a specific macro is clicked (i.e. the green, red, or orange squares) in the UI, the second tab shows only the variables created by that particular macro thus allowing you to see the 'history' of the variable at different times of the report.

Example:

Enter these macros into Report Studio:

    [String:value=1, storeAs=My Variable]
    [String:value=2, storeAs=My Variable]
    [String:value=3, storeAs=My Variable]

The "ALL VARIABLES" tab will show only ONE variable (My Variable) with the value 3.

However, click on the first macro block in the UI, and choose the "MACRO VARIABLES" tab.

The value of "My Variable" will be 1.

Next, click the second macro block, and in the same tab, the value of "My Variable" will be 2.

Similarly, when you select the third macro block, "My Variable" will be be shown as 3. This can be useful when 'debugging' your reports, as you can easily see the values created by specific macros, which may help to determine where potential macro problems are occurring.

Breaking Changes From Version 3.15

From 3.15, NCalc is stricter with curly brackets.  It is no longer valid to enclose numbers in curly bracket or leave stray curly brackets in the expression.  For example. the following are no longer allowed:

  • x>{3}
  • x>3}

Generally, in order to fix any errors which may have occurred due to this updated behaviour, removing curly brackets around numbers and removing stray curly brackets will solve the error.

You can use these two resources to assist in updating your NCalc if needed:

An unhandled error has occurred. Reload 🗙