Wiki source code of 03ci. Calculation Builder
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | {{box cssClass="floatinginfobox" title="**Contents**"}} | ||
| 2 | {{toc/}} | ||
| 3 | {{/box}} | ||
| 4 | |||
| 5 | Used in front-end reporting and Index configuration, the CXAIR Calculation Builder provides an interactive interface to create additional fields, configure re-usable variables and utilise preconfigured functions to control data structures and reporting output. | ||
| 6 | |||
| 7 | New calculations can be derived when creating a report or at Index build-time. This guide will cover both front-end reporting techniques and, for system administrators, examples that have been used to enhance customer Indexes for end-users. | ||
| 8 | |||
| 9 | = Interface = | ||
| 10 | |||
| 11 | In the front-end, the Calculation Builder is accessed when creating Crosstab totals. There are two distinct uses when reporting: Measure Calculations and Cell Calculations. | ||
| 12 | |||
| 13 | == Measure Calculations == | ||
| 14 | |||
| 15 | Using the calculation as a **Measure** allows users to perform calculations at row-level based on the **Total Type** rather than a direct cell calculation using existing totals. | ||
| 16 | |||
| 17 | In the **Totals** tab, select a **Total Type** then select **Calculation** from the subsequently revealed **Measure** drop-down list: | ||
| 18 | |||
| 19 | [[image:CalcScreen1.png||height="293" width="600"]] | ||
| 20 | |||
| 21 | Clicking the **…** icon will open the Calculation Builder: | ||
| 22 | |||
| 23 | |||
| 24 | [[image:CalcScreen2a.png||height="328" width="600"]] | ||
| 25 | |||
| 26 | On the left of the pop-up window, a list of available **Fields** and **Filters** are displayed that can be directly referenced when building calculations, along with **Functions**, **Values** and **Syntax** drop-down lists. | ||
| 27 | |||
| 28 | Use the **Functions** list to select from the available calculation functions. Simply replace the template values contained within **<>** with actual values required for the function. | ||
| 29 | |||
| 30 | For example: | ||
| 31 | |||
| 32 | Floor(<Expression>) becomes Floor(Sales_Price) | ||
| 33 | |||
| 34 | Select an option from the **Values** list to add dynamic values based on the currently loaded Index. | ||
| 35 | |||
| 36 | The **Syntax** drop-down list contains a number of common structures to assist with the creation of calculations within the tool. It is recommended that users familiarise themselves with the structures found in this list when first using the Calculation Builder. | ||
| 37 | |||
| 38 | To test the validity of the currently entered syntax, click the **Validate** button. | ||
| 39 | \\A green tick icon will denote when the syntax is correct, allowing the **Apply** button to be clicked and the total added to the report. | ||
| 40 | |||
| 41 | Click the **Clear** button to remove all text, or to cancel any changes made to the calculation, click **Cancel**. | ||
| 42 | |||
| 43 | === Saving & Loading Calculations === | ||
| 44 | |||
| 45 | To save a calculation, click the **Save** button located at the bottom-right corner. | ||
| 46 | |||
| 47 | Saved calculations can be made available for other users who have access to the same Index by selecting the **Available as Aggregation** option. Type a **Name** in the textbox and click **Save**. To discard changes, click the **Cancel** button. | ||
| 48 | |||
| 49 | After saving a global calculation it will then be displayed under the Crosstab **Measure** drop-down list for use in any future reports using the same Index, or by other users with the relevant permissions. | ||
| 50 | |||
| 51 | To remove or edit a global calculation, open the Measure Calculation Builder and click the **Manage** button. This will display a list of any saved and global calculations. Click the **Load** button to load the calculation into the Calculation Builder for editing or click on the **Remove** button to delete the calculation. | ||
| 52 | |||
| 53 | === Adding Comments === | ||
| 54 | |||
| 55 | To add comments to a calculation, wrap the required comment in /*. For example: | ||
| 56 | |||
| 57 | /*This calculation brings back CASH only payments*/ | ||
| 58 | |||
| 59 | == Cell Calculations == | ||
| 60 | |||
| 61 | Using Cell Calculations, users can perform calculations based on existing totals that have already been specified in the report. | ||
| 62 | |||
| 63 | In the **Totals** tab, select Cell/Total Calculation from the **Total Type** drop-down list: | ||
| 64 | |||
| 65 | [[image:CalcScreen3.png||height="293" width="600"]] | ||
| 66 | |||
| 67 | Clicking the **…** icon will open the Calculation Builder: | ||
| 68 | |||
| 69 | [[image:CalcScreen4a.png||height="330" width="600"]] | ||
| 70 | |||
| 71 | Rather than a list of available fields, previously defined totals are now displayed. This allows calculations between totals to be defined that are run against the Index at report run-time. | ||
| 72 | |||
| 73 | To reference totals, their position or name can be used with the **Total** function. This uses the following syntax: | ||
| 74 | |||
| 75 | **Total( <Expression> )** | ||
| 76 | |||
| 77 | For example, **TOTAL(0)** can be used to reference the first total, with an incremental numeric value assigned to each total in turn. Alternatively, if the total has been named, the **Total** function is not required and the name in single quotes can be used, such as **'Sales'**. | ||
| 78 | |||
| 79 | Use the **Count** cell calculation functions to perform these aggregation functions while referencing the values from other totals. These functions will only appear in the cell calculation builder and use the following syntax, with the 'Expression' text representing the calculation logic that will be wrapped in the function: | ||
| 80 | |||
| 81 | **Count( <Expression> )** | ||
| 82 | |||
| 83 | To reference the actual runtime position of a total, use the following syntax: | ||
| 84 | |||
| 85 | **Total (n,True)** | ||
| 86 | |||
| 87 | Enter a value to reference the total position. This is especially useful when assigning saved queries to totals and calculating across them. | ||
| 88 | |||
| 89 | For a full list of functions available for cell calculations, see the Calculations Function Index. | ||
| 90 | |||
| 91 | == DrillThru == | ||
| 92 | |||
| 93 | To translate the calculation logic into syntax that can be parsed in the Query screen, the total logic or field must be wrapped in the **DrillThru** function. | ||
| 94 | |||
| 95 | For example: | ||
| 96 | |||
| 97 | **IF** | ||
| 98 | IF (Area_Name='Birmingham and North Midlands') {DrillThru(Cost_Price)} | ||
| 99 | |||
| 100 | IF (Area_Name='Birmingham and North Midlands') {DrillThru(1)} | ||
| 101 | |||
| 102 | **CASE** | ||
| 103 | CASE WHEN Area_Name = 'Birmingham and North Midlands' THEN DrillThru(Cost_Price) END | ||
| 104 | |||
| 105 | CASE WHEN Area_Name = 'Birmingham and North Midlands' THEN DrillThru(1) END | ||
| 106 | |||
| 107 | When referencing more than one total in a calculation, the **DrillThru** function is used to select the value that informs the drill operation. | ||
| 108 | |||
| 109 | For example, when deriving percentage values, the **DrillThru** function can be used to specify the numerator or denominator value. The following Row Total calculation calculates the percentage of branded items: | ||
| 110 | |||
| 111 | (sum(CASE WHEN Product_Type = 'Branded' THEN 1 ELSE 0 END)/sum( 1 ))*100 | ||
| 112 | |||
| 113 | The following calculation drills to the branded product transactions: | ||
| 114 | |||
| 115 | (sum(CASE WHEN Product_Type = 'Branded' THEN DrillThru( 1 ) ELSE 0 END)/sum( 1 ))*100 | ||
| 116 | |||
| 117 | The following calculation drills to the unbranded product transactions: | ||
| 118 | |||
| 119 | (sum(CASE WHEN Product_Type = 'Branded' THEN 1 ELSE DrillThru( 0 ) END)/sum( 1 ))*100 | ||
| 120 | |||
| 121 | The following calculation drills to both branded and unbranded product transactions: | ||
| 122 | |||
| 123 | (sum(CASE WHEN Product_Type = 'Branded' THEN 1 ELSE 0 END)/sum( DrillThru( 1 ) ))*100 | ||
| 124 | |||
| 125 | = Conditional Statements = | ||
| 126 | |||
| 127 | When creating calculations, utilising conditional statements is key to shaping output in both reporting and Index management. | ||
| 128 | |||
| 129 | == CASE Statements == | ||
| 130 | |||
| 131 | CASE statements use the following syntax: | ||
| 132 | |||
| 133 | CASE WHEN <Condition> THEN <Expression> ELSE <Expression> END | ||
| 134 | |||
| 135 | To populate the calculation builder with the required syntax structure, select the **CASE** option from the **Syntax** drop-down list. | ||
| 136 | |||
| 137 | First, a condition is specified. An expression is then defined that will be output when the condition is true, or not true. A CASE statement must always finish with END. | ||
| 138 | |||
| 139 | For example, the following syntax will filter the output to only include cash sales: | ||
| 140 | |||
| 141 | CASE WHEN MOP = 'Cash' THEN 1 ELSE 0 END | ||
| 142 | |||
| 143 | //‘When the MOP field contains the value ‘Cash’, then count the rowotherwise ignore it.’// | ||
| 144 | |||
| 145 | Here, the condition is that the ‘MOP’ (method of payment) field equals ‘Cash’, and the expression ‘1’. This Boolean flag means that the rows will be included. The ‘ELSE 0’ expression is another Boolean flag that will instead omit any rows that do not equal ‘Cash’. | ||
| 146 | |||
| 147 | Notice how the MOP value is specified in single quotes. This is due to the field containing string values. Numeric fields used in calculations do not require single quotes. | ||
| 148 | |||
| 149 | The ‘1’ and ‘0’ values in this statement represent the calculation logic that will be applied, in this case either including or omitting the rows based on the condition. These values can be changed to suit the required report. | ||
| 150 | |||
| 151 | For example: | ||
| 152 | |||
| 153 | CASE WHEN MOP = 'Cash' THEN Sales_Price ELSE 0 END | ||
| 154 | |||
| 155 | //'When the MOP field equals ‘Cash’, then apply the selected **Total Type** to the ‘Sales Price’ field for these rows in the output. Otherwise, exclude rows with other MOP values.’// | ||
| 156 | |||
| 157 | Here, the ‘1’ value in the previous example has been swapped for ‘Sales_Price’. This will result in the selected **Total Type** for the total being applied to this field for all cash transactions. Other rows will be omitted. | ||
| 158 | |||
| 159 | Notice how the specified field has an underscore rather than a space. To work correctly, a field must be entered exactly as it is stored in the Index. To ensure the field is entered correctly, single-click the field of interest in the **Fields** list of the Calculation Builder. | ||
| 160 | |||
| 161 | === Further Examples === | ||
| 162 | |||
| 163 | |CASE | ||
| 164 | WHEN In( Acc_ACC_PURPOSE_CODE,'FA', 'FP', 'PP', 'HPO', 'REL' ) THEN 1 | ||
| 165 | WHEN In( Acc_ACC_PURPOSE_CODE,'REN', 'RED', 'REO', 'REB') THEN 2 | ||
| 166 | ELSE 7 | ||
| 167 | END|CASE | ||
| 168 | WHEN | ||
| 169 | (C1_CPD_CUSTP_NATIONALITY = 'BRIT' ~|~| C1_CPD_CUSTP_NATIONALITY IS NULL) | ||
| 170 | && | ||
| 171 | (Addr_ADDR_COUNTRY_CODE = 'UK' ~|~| Addr_ADDR_COUNTRY_CODE IS NULL) | ||
| 172 | THEN 'N' | ||
| 173 | ELSE 'Y' | ||
| 174 | END | ||
| 175 | |||
| 176 | == IF Statements == | ||
| 177 | |||
| 178 | IF statements use the following syntax structure: | ||
| 179 | |||
| 180 | IF <Condition> { <Expression> } ELSE { <Expression> } | ||
| 181 | |||
| 182 | To populate the calculation builder with the required syntax structure, select the **IF** option from the **Syntax** drop-down list. | ||
| 183 | |||
| 184 | The syntax differs to a CASE statement, with the condition specified before defining expressions wrapped in curly brackets. | ||
| 185 | |||
| 186 | For example: | ||
| 187 | |||
| 188 | IF MOP = 'Cash' { 1 } ELSE { 0 } | ||
| 189 | |||
| 190 | //‘When the MOP field contains the value ‘Cash’, then count the row, otherwise ignore it.’// | ||
| 191 | |||
| 192 | This filters the output in the same way as the previously reviewed CASE statement. | ||
| 193 | |||
| 194 | Again, the ‘1’ and ‘0’ values in this statement represent the calculation logic that will be applied, in this case either including or omitting the rows based on the condition. These values can be changed to suit the required report. | ||
| 195 | |||
| 196 | For example: | ||
| 197 | |||
| 198 | IF MOP = 'Cash' { Sales_Price } ELSE { 0 } | ||
| 199 | |||
| 200 | //'If the MOP field equals ‘Cash’, then apply the selected Total Type to the ‘Sales Price’ field for these rows in the output. Otherwise, exclude rows with other MOP values.’// | ||
| 201 | |||
| 202 | As with the previous example, the ‘1’ value in the previous example has been swapped for ‘Sales_Price’. This will result in the selected **Total Type** for the total being applied to this field for all cash transactions. Other rows will be omitted. | ||
| 203 | |||
| 204 | = Dynamic Views = | ||
| 205 | |||
| 206 | A dynamic view is a distinct count of a pre-configured field setup by an administrator. | ||
| 207 | \\For example, adding a Dynamic View for an ‘Employee Name or ID’ would allow users to create reports that only count unique employees within their report. | ||
| 208 | |||
| 209 | When drilling through on a Dynamic View or when there is both an aggregation and a Dynamic View present, the first row found will be shown on the drill through results. | ||
| 210 | |||
| 211 | Use the **Dynamic View** drop-down list when creating Crosstab totals to select from the list of Dynamic Views added by the system administrator: | ||
| 212 | |||
| 213 | [[image:CalcScreen5.png||height="259" width="600"]] | ||
| 214 | |||
| 215 | Selecting **[Records]** from this list will perform the selected **Total Type** on the underlying rows with no distinct count applied. | ||
| 216 | |||
| 217 | **If a field doesn’t appear as an option under the Dynamic View drop list, contact you CXAIR administrator.** | ||
| 218 | |||
| 219 | Dynamic Views can also be used in the Query screen using the following syntax: | ||
| 220 | |||
| 221 | +<Field_Name>:"<Query>" +DYNAMICVIEW: "<Dynamic View Name>" | ||
| 222 | |||
| 223 | For example: | ||
| 224 | |||
| 225 | +Region_Name:"London" +DYNAMICVIEW: "Employees" | ||
| 226 | |||
| 227 | == Ordering Calculation Logic == | ||
| 228 | |||
| 229 | Understanding how Dynamic Views filter the data is vital to ensuring reporting figures are valid. | ||
| 230 | |||
| 231 | When a Dynamic View is invoked, the Index is scanned row-by-row until a match is found. The order in which rows are scanned is based on the underlying structure of the Index, not necessarily the order in which the data was ingested. | ||
| 232 | |||
| 233 | When the first unique record is identified, every other row containing this identifier is discarded and not included in the output. | ||
| 234 | |||
| 235 | When using the **Dynamic View** drop-down list functionality in a standard total, the distinct count is run against the records before any calculation logic is applied. In some circumstances, this may remove records of interest. | ||
| 236 | |||
| 237 | By using the **CountDistinct** and **SumDistinct** calculation functions, the distinct count can instead be run against the records after the calculation logic has been applied. | ||
| 238 | |||
| 239 | The calculations use the following syntax: | ||
| 240 | |||
| 241 | CountDistinct( <Expression> , <String Expression> ) | ||
| 242 | //Returns the distinct count from a dynamic view following the specified calculation logic.// | ||
| 243 | |||
| 244 | SumDistinct( <Expression> , <String Expression> ) | ||
| 245 | //Sums the distinct count from a dynamic view following the specified calculation logic.// | ||
| 246 | |||
| 247 | The following report contains two totals counting the number of unique employees that have processed cash transactions broken down by region: | ||
| 248 | |||
| 249 | [[image:CalcScreen6.png||height="215" width="400"]] | ||
| 250 | |||
| 251 | Both totals employ the same dynamic view, titled ‘Employees’, but at different stages of the calculation. | ||
| 252 | |||
| 253 | The first total, ‘Cash Transactions 1’, has the Total Type set to Sum, the Dynamic View drop-down list set to Employees and the following calculation: | ||
| 254 | |||
| 255 | CASE WHEN MOP = 'Cash' THEN 1 END | ||
| 256 | |||
| 257 | When this calculation is run, the dynamic view filters to only the first row for each employee before then filtering to cash transactions. This means that many cash transactions have been filtered from the reporting output - only if the first row found for an employee contains a cash transaction is it included. | ||
| 258 | |||
| 259 | The second total, **‘Cash Transactions 2’**, instead has the **Total Type** set to Sum, the **Dynamic View** drop-down list set to **[Records]** and the following calculation: | ||
| 260 | |||
| 261 | CountDistinct( CASE WHEN MOP = 'Cash' THEN 1 END , 'Employees' ) | ||
| 262 | |||
| 263 | This calculation first filters the rows based on the specified MOP value, then runs the distinct count against those records. This ensures all ‘Cash’ records are included in the result set before the distinct count of employees is run. | ||
| 264 | |||
| 265 | = Date Calculations = | ||
| 266 | |||
| 267 | When working with date fields in an Index, there are a number of ways values can be referenced to form the basis for new fields and calculated output when reporting. | ||
| 268 | |||
| 269 | == Reference Variables == | ||
| 270 | |||
| 271 | When using date differentials in calculations, the following dynamic syntax can be used to add and subtract from date values: | ||
| 272 | |||
| 273 | (% border="1" cellspacing="0" class="GridTable1Light-Accent12" style="border-collapse:collapse; border:solid #90c5f6 1.0pt; width:593px" %) | ||
| 274 | (% style="height:1.0pt" %)|(% nowrap="nowrap" style="background-color:#1eb1ed; background:#1eb1ed; border-bottom-width:90c5f6; border-bottom:solid #59a9f2 1.5pt; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; width:444.45pt" width="593" %)((( | ||
| 275 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 276 | (% style="color:white; height:1pt; line-height:115%" %)**Point in Time** | ||
| 277 | ))) | ||
| 278 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 279 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 280 | (% style="height:11.5pt; line-height:115%" %)NOW | ||
| 281 | ))) | ||
| 282 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 283 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 284 | (% style="height:11.5pt; line-height:115%" %)TODAY | ||
| 285 | ))) | ||
| 286 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 287 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 288 | (% style="height:11.5pt; line-height:115%" %)MONDAY | ||
| 289 | ))) | ||
| 290 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 291 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 292 | (% style="height:11.5pt; line-height:115%" %)TUESDAY | ||
| 293 | ))) | ||
| 294 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 295 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 296 | (% style="height:11.5pt; line-height:115%" %)WEDNESDAY | ||
| 297 | ))) | ||
| 298 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 299 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 300 | (% style="height:11.5pt; line-height:115%" %)THURSDAY | ||
| 301 | ))) | ||
| 302 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 303 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 304 | (% style="height:11.5pt; line-height:115%" %)FRIDAY | ||
| 305 | ))) | ||
| 306 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 307 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 308 | (% style="height:11.5pt; line-height:115%" %)SATURDAY | ||
| 309 | ))) | ||
| 310 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 311 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 312 | (% style="height:11.5pt; line-height:115%" %)SUNDAY | ||
| 313 | ))) | ||
| 314 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 315 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 316 | (% style="height:11.5pt; line-height:115%" %)FIRST_SECOND_OF_DAY | ||
| 317 | ))) | ||
| 318 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 319 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 320 | (% style="height:11.5pt; line-height:115%" %)LAST_SECOND_OF_DAY | ||
| 321 | ))) | ||
| 322 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 323 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 324 | (% style="height:11.5pt; line-height:115%" %)FIRST_MINUTE_OF_DAY | ||
| 325 | ))) | ||
| 326 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 327 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 328 | (% style="height:11.5pt; line-height:115%" %)LAST_MINUTE_OF_DAY | ||
| 329 | ))) | ||
| 330 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 331 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 332 | (% style="height:11.5pt; line-height:115%" %)FIRST_SECOND_OF_WEEK | ||
| 333 | ))) | ||
| 334 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 335 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 336 | (% style="height:11.5pt; line-height:115%" %)LAST_SECOND_OF_WEEK | ||
| 337 | ))) | ||
| 338 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 339 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 340 | (% style="height:11.5pt; line-height:115%" %)FIRST_DAY_OF_WEEK | ||
| 341 | ))) | ||
| 342 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 343 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 344 | (% style="height:11.5pt; line-height:115%" %)LAST_DAY_OF_WEEK | ||
| 345 | ))) | ||
| 346 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 347 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 348 | (% style="height:11.5pt; line-height:115%" %)FIRST_SECOND_OF_MONTH | ||
| 349 | ))) | ||
| 350 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 351 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 352 | (% style="height:11.5pt; line-height:115%" %)LAST_SECOND_OF_MONTH | ||
| 353 | ))) | ||
| 354 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 355 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 356 | (% style="height:11.5pt; line-height:115%" %)FIRST_DAY_OF_MONTH | ||
| 357 | ))) | ||
| 358 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 359 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 360 | (% style="height:11.5pt; line-height:115%" %)LAST_DAY_OF_MONTH | ||
| 361 | ))) | ||
| 362 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 363 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 364 | (% style="height:11.5pt; line-height:115%" %)FIRST_DAY_OF_QUARTER | ||
| 365 | ))) | ||
| 366 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 367 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 368 | (% style="height:11.5pt; line-height:115%" %)LAST_DAY_OF_QUARTER | ||
| 369 | ))) | ||
| 370 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 371 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 372 | (% style="height:11.5pt; line-height:115%" %)FIRST_SECOND_OF_YEAR | ||
| 373 | ))) | ||
| 374 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 375 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 376 | (% style="height:11.5pt; line-height:115%" %)LAST_SECOND_OF_YEAR | ||
| 377 | ))) | ||
| 378 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 379 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 380 | (% style="height:11.5pt; line-height:115%" %)FIRST_DAY_OF_YEAR | ||
| 381 | ))) | ||
| 382 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 383 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 384 | (% style="height:11.5pt; line-height:115%" %)LAST_DAY_OF_YEAR | ||
| 385 | ))) | ||
| 386 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 387 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 388 | (% style="height:11.5pt; line-height:115%" %)FIRST_SECOND_OF_FISCAL_YEAR | ||
| 389 | ))) | ||
| 390 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 391 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 392 | (% style="height:11.5pt; line-height:115%" %)LAST_SECOND_OF_FISCAL_YEAR | ||
| 393 | ))) | ||
| 394 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 395 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 396 | (% style="height:11.5pt; line-height:115%" %)FIRST_DAY_OF_FISCAL_YEAR | ||
| 397 | ))) | ||
| 398 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 399 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 400 | (% style="height:11.5pt; line-height:115%" %)LAST_DAY_OF_FISCAL_YEAR | ||
| 401 | ))) | ||
| 402 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 403 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 404 | (% style="height:11.5pt; line-height:115%" %)FIRST_DAY_OF_FISCAL_HALF_YEAR | ||
| 405 | ))) | ||
| 406 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 407 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 408 | (% style="height:11.5pt; line-height:115%" %)LAST_DAY_OF_FISCAL_HALF_YEAR | ||
| 409 | ))) | ||
| 410 | (% style="height:1.0pt" %)|(% nowrap="nowrap" style="background-color:#1eb1ed; background:#1eb1ed; border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 411 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 412 | (% style="color:white; height:1pt; line-height:115%" %)**Differentials** | ||
| 413 | ))) | ||
| 414 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 415 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 416 | (% style="height:11.5pt; line-height:115%" %)SECONDS | ||
| 417 | ))) | ||
| 418 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 419 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 420 | (% style="height:11.5pt; line-height:115%" %)MINUTES | ||
| 421 | ))) | ||
| 422 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 423 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 424 | (% style="height:11.5pt; line-height:115%" %)HOURS | ||
| 425 | ))) | ||
| 426 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 427 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 428 | (% style="height:11.5pt; line-height:115%" %)DAYS | ||
| 429 | ))) | ||
| 430 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 431 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 432 | (% style="height:11.5pt; line-height:115%" %)WEEKS | ||
| 433 | ))) | ||
| 434 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 435 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 436 | (% style="height:11.5pt; line-height:115%" %)MONTHS | ||
| 437 | ))) | ||
| 438 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 439 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 440 | (% style="height:11.5pt; line-height:115%" %)YEARS | ||
| 441 | ))) | ||
| 442 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 443 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 444 | (% style="height:11.5pt; line-height:normal" %)YEAR_SAME_WEEK | ||
| 445 | ))) | ||
| 446 | (% style="height:11.5pt" %)|(% nowrap="nowrap" style="border-bottom-width:90c5f6; border-left-width:1.0pt; border-right-width:1.0pt; border-style:solid; border-top-width:90c5f6; border-top:none; width:444.45pt" width="593" %)((( | ||
| 447 | (% style="margin-bottom:0cm; text-align:left; padding:0cm 5.4pt 0cm 5.4pt;text-align:left" %) | ||
| 448 | (% style="height:11.5pt; line-height:115%" %)WORKINGDAYS (When enabled by the system administrator) | ||
| 449 | ))) | ||
| 450 | |||
| 451 | Please note that using the **SECONDS** differential over thousands of records will increase the processing time. | ||
| 452 | |||
| 453 | == Adding and Subtracting from Dates == | ||
| 454 | |||
| 455 | Adding and subtracting from dates can be achieved a number of ways, such as wrapping the date field in the relevant point in time syntax and specifying a numeric value in the following format: | ||
| 456 | |||
| 457 | POINT IN TIME (<Date Field>)+<Numeric>DIFFERENTIAL | ||
| 458 | |||
| 459 | For example: | ||
| 460 | |||
| 461 | TODAY(Transaction_Date)+7DAYS | ||
| 462 | //Returns the referenced date field plus seven days.// | ||
| 463 | |||
| 464 | To reference numeric fields, use the following format: | ||
| 465 | |||
| 466 | POINT IN TIME(<Date Field>)+DIFFERENTIAL(<Numeric Field>) | ||
| 467 | |||
| 468 | For example: | ||
| 469 | NOW(Transaction_Date)+DAYS(Dispatch_Days) | ||
| 470 | //Returns the referenced date field and outputs field plus the number of months based on the numeric output of the calculation.// | ||
| 471 | |||
| 472 | LAST_DAY_OF_MONTH(SOC_CURR_PERIOD)-1MONTH | ||
| 473 | |||
| 474 | TODAY(LOAN_DATE)+MONTHS(Remaining_Term_in_Months)-1MONTH | ||
| 475 | |||
| 476 | Please note that **TODAY** will return the current date, while **NOW** will return the current date and time. | ||
| 477 | |||
| 478 | To reference calculations, use the following format: | ||
| 479 | |||
| 480 | POINT IN TIME(<Date Field>)+DIFFERENTIAL(<’Calculation’>) | ||
| 481 | |||
| 482 | For example: | ||
| 483 | |||
| 484 | FIRST_DAY_OF_MONTH(Transaction_Date)+WORKINGDAYS(‘Dispatch Days’) | ||
| 485 | //Returns the referenced date field and outputs the first day of the corresponding month plus the number of working days based on the numeric output of the calculation.// | ||
| 486 | |||
| 487 | Please note that calculations need to be referenced in single quotes. | ||
| 488 | |||
| 489 | == Reporting Examples == | ||
| 490 | |||
| 491 | A range of functions are available in the calculation builder that allow two or more dates to be referenced on a single row, with the output tailored to suit specific time differentials. | ||
| 492 | |||
| 493 | === Time in Department === | ||
| 494 | |||
| 495 | The following report shows the minutes between arrival and departure using sample A&E data: | ||
| 496 | |||
| 497 | [[image:CalcScreen7.png||height="220" width="400"]] | ||
| 498 | |||
| 499 | This report contains a single total using the **DateBetween** function: | ||
| 500 | |||
| 501 | DateBetween( <Date Expression> , <Date Expression> , <TIMEPERIOD> ) | ||
| 502 | //Returns the number of inclusive period values between two date expressions, except when a time is specified.// | ||
| 503 | |||
| 504 | First, the two date fields of interest are added and comma separated. Finally, the required time period is then added, also comma separated. | ||
| 505 | |||
| 506 | In this reporting example, the following calculation has been used: | ||
| 507 | |||
| 508 | DateBetween(Arrival_Date_Time,Left_Dept_Date_Time, SECONDS) | ||
| 509 | |||
| 510 | This compares two date fields on a single row and outputs the difference in seconds. The **Show Value As** drop-down list has then been set to Time Measure to format the output to HH:MM:SS. Please refer to the Reference Variables table earlier in the chapter to view the other possible differentials. | ||
| 511 | |||
| 512 | Furthermore, the dynamic point in time options also found in this table can be utilised when using the **DateBetween** function. For example: | ||
| 513 | |||
| 514 | DateBetween( TODAY, Closed_Date, MONTHS) | ||
| 515 | //Compares today’s date and the value in the Closed_Date field and returns a dynamic numeric value based on the date the report was run.// | ||
| 516 | |||
| 517 | === Average Dispatch Time === | ||
| 518 | |||
| 519 | The following report uses sample supermarket data to display the total number of orders, returns and the average number of days a before a product category order is dispatched: | ||
| 520 | |||
| 521 | [[image:CalcScreen8.png||height="289" width="550"]] | ||
| 522 | |||
| 523 | This report contains a single total using the **DaysBetween** function: | ||
| 524 | |||
| 525 | DaysBetween( <Date Expression> , <Date Expression>, <Optional Day(s)> ) | ||
| 526 | //Returns the number of inclusive period values between two date expressions.// | ||
| 527 | |||
| 528 | First, the two date fields of interest are added and comma separated. Optionally, days that are not required can be added, also comma separated. This is most commonly used to omit weekends by including SATURDAY and SUNDAY in the calculation logic. | ||
| 529 | |||
| 530 | In this reporting example, the following calculation has been used with the **Total Type** set to **Average**: | ||
| 531 | |||
| 532 | DaysBetween(Order_Date,Ship_Date, SATURDAY, SUNDAY) | ||
| 533 | |||
| 534 | This compares two date fields on a single row and outputs the difference in days, omitting any rows that have a day value of Saturday or Sunday. | ||
| 535 | |||
| 536 | As the **Total Type** has been set to average, the report then displays the average dispatch time, omitting weekends. The total then uses a descending **Row Sort** to order the output for each product category. | ||
| 537 | |||
| 538 | In this example, conditional formatting has also been applied. Should a product category take longer to dispatch than the previous month, the total will be highlighted red. For more information regarding variance reports, please refer to the [[Crosstab Reporting Guide>>doc:Technical Documentation.CXAIR.Reporting Guides.09a\. Crosstab Reporting Guide.WebHome]]. | ||
| 539 | |||
| 540 | === Average Turnaround Time in Days & Working Days === | ||
| 541 | |||
| 542 | The following report shows a small sample of mortgage applications along with two totals that display the average number of days taken for an application to be reviewed and accepted: | ||
| 543 | |||
| 544 | [[image:CalcScreen9.png||height="160" width="500"]] | ||
| 545 | |||
| 546 | This report contains two totals, using the previously detailed **DaysBetween** function and also the **CountWorkingDays** function: | ||
| 547 | |||
| 548 | CountWorkingDays( <Expression> , <Expression> ) | ||
| 549 | //Counts the number of working days between two date fields.// | ||
| 550 | |||
| 551 | Please note that working days and holidays need to be configured by an administrator. | ||
| 552 | |||
| 553 | This function uses the same logic as the **DaysBetween** function, but does not allow an optional expression to be added that omits certain days. Instead, two date fields of interest are added and comma separated. This returns a count of working days, as set by the administrator. | ||
| 554 | |||
| 555 | In this report, while both totals have the **Total Type** set to Average, the first total, ‘Avg Turnaround Time (Days)’, uses the following calculation logic: | ||
| 556 | |||
| 557 | DaysBetween(Date_received,Date_accepted) | ||
| 558 | |||
| 559 | This returns a count of days between the **Date_received** and **Date_accepted** fields, before averaging the output in the report. | ||
| 560 | |||
| 561 | The second total, ‘Avg Turnaround Time (Working Days)’ instead uses the CountWorkingDays function: | ||
| 562 | |||
| 563 | CountWorkingDays(Date_received,Date_accepted) | ||
| 564 | |||
| 565 | The second total references the working days and bank holiday specified by the system administrator to automatically omit non-working days, providing an accurate total without the need for further calculations. | ||
| 566 | |||
| 567 | By setting the working days for the system, all report creators can leverage this function for any Index containing two or more date fields. | ||
| 568 | |||
| 569 | === Time To Departure === | ||
| 570 | |||
| 571 | The following report displays three different ways in which date differentials can be expressed: | ||
| 572 | |||
| 573 | [[image:CalcScreen10.png||height="154" width="600"]] | ||
| 574 | |||
| 575 | This report contains three totals. The first, ‘Time to Departure’, uses the **ToJulianDayTime** function: | ||
| 576 | |||
| 577 | ToJulianDayTime( <Date Expression> ) | ||
| 578 | //Returns the Julian Daytime value of a datetime expression. The Julian daytime is the continuous count of seconds since the beginning of the Julian Period and is used when comparing two datetimes.// | ||
| 579 | |||
| 580 | In this reporting example, the following calculation has been used: | ||
| 581 | |||
| 582 | ToJulianDayTime( Departure_Datetime )-ToJulianDayTime( Attendance_Datetime ) | ||
| 583 | |||
| 584 | By wrapping the datetime fields in the **ToJulianTime** function, the values are converted to numeric values. This has a key performance advantage over the previous example where the **DateBetween** function was used, as simple arithmetic can be used to calculate output rather than the system conducting date differentials at report run time. The **Show Value As** drop-down list has then been set to Hours Measure to achieve the desired output. | ||
| 585 | |||
| 586 | The second total, ‘Days to Departure (Exclusive)’ uses the **ToJulianDay** function: | ||
| 587 | |||
| 588 | ToJulianDay( <Date Expression> ) | ||
| 589 | //Returns the Julian Day value of a date(time) expression. The Julian day is the continuous count of days since the beginning of the Julian Period and is used when comparing two dates.// | ||
| 590 | |||
| 591 | This works in the same way as the previous total, but is used for date fields rather than datetime fields. | ||
| 592 | |||
| 593 | The following calculation has been used: | ||
| 594 | |||
| 595 | ToJulianDay( Departure_Date )-ToJulianDay( Attendance_Date ) | ||
| 596 | |||
| 597 | This returns an exclusive count of days between the two date values, resulting in a value of 0 should both dates match. Should an inclusive value be required, the system requires a date differential to be calculated at run time rather than a numeric calculation. This is achieved using the third total in this report. | ||
| 598 | |||
| 599 | To achieve an inclusive value for the third total, ‘Days to Departure (Inclusive)’, the following calculation logic has been used: | ||
| 600 | |||
| 601 | DaysBetween(Attendance_Date,Departure_Date | ||
| 602 | |||
| 603 | This will return an inclusive value, resulting in a value of 1 if both values match. | ||
| 604 | |||
| 605 | === Calculating Age at the Time of an Appointment === | ||
| 606 | |||
| 607 | Converting a date value to a numeric Julian Day value is especially useful when calculating date differentials in calculations, such as when calculating age at the time of an appointment. This can be achieved using the following calculation logic: | ||
| 608 | |||
| 609 | In Years: | ||
| 610 | FLOOR((ToJulianDay(<Appointment Date>) - ToJulianDay(<Date of Birth>))/365.25) | ||
| 611 | |||
| 612 | In Days: | ||
| 613 | FLOOR((ToJulianDay(<Appointment Date>) - ToJulianDay(<Date of Birth>~)~)~) | ||
| 614 | |||
| 615 | By converting both fields to Julian Day values, a simple subtraction will result in a value that can then be divided by 365.25 to derive age in years. | ||
| 616 | |||
| 617 | === Order Confirmation Time === | ||
| 618 | |||
| 619 | Converting a date time value to a numeric Julian Day Time value means that calculations can be used to derive time differentials between two fields. For example, the following calculations show the time between an order being received and confirmed: | ||
| 620 | |||
| 621 | In Seconds: | ||
| 622 | (ToJulianDayTime( Order_Confirmed_Time ) - ToJulianDayTime( Order_Created_Time )) | ||
| 623 | |||
| 624 | In Minutes: | ||
| 625 | ToJulianDayTime( Order_Confirmed_Time ) - ToJulianDayTime( Order_Created_Time))/60 | ||
| 626 | |||
| 627 | = Extra Field Calculations = | ||
| 628 | |||
| 629 | //Please note that the following section applies to system administrators only.// | ||
| 630 | |||
| 631 | Supplementing Indexes with additional calculated fields allows administrators to provide pre-aggregated output that is calculated during build time. This can have an exponential impact on performance, significantly reducing report load times while also providing additional aggregations to end-users. | ||
| 632 | |||
| 633 | == Report Optimisation == | ||
| 634 | |||
| 635 | When there is regular use of common logic across multiple reports, such as removing dummy records or defining cohorts of interest using queries, this filtering process can be optimised using calculated fields to generate Boolean flags. | ||
| 636 | |||
| 637 | This has some key advantages. First, the integrity of the query is controlled by administrators rather than relying on users to build complex queries. This reduces the margin for error and ensures reports are always run against the same cohort of records. Furthermore, when the report is loaded, the query bar does not contain a long string of individual values, freeing up this space for users to add their own queries. | ||
| 638 | |||
| 639 | For example, the following query is used in reporting to select a cohort of patients: | ||
| 640 | |||
| 641 | ((Team_Code:("T1" OR "T2" OR "T3") AND Age:("0" OR "1" OR "2" OR "3" OR "4" OR "5" OR "6" OR "7" OR "8" OR "9" OR "10" OR "11" OR "12" OR "13" OR "14" OR "15" OR "16" OR "17" OR "18" OR "19")) AND Financial_Year:"2020-21") | ||
| 642 | |||
| 643 | While this does produce the report as expected, it can be optimised to instead use a Boolean flag as part of a calculated field. The above query can be translated to the simple CASE statement below: | ||
| 644 | |||
| 645 | CASE | ||
| 646 | WHEN In(TeamCode, 'T1', 'T2', 'T3') | ||
| 647 | && Age < 20 | ||
| 648 | && FinancialYear = '2020-21' | ||
| 649 | THEN 1 ELSE 0 | ||
| 650 | END | ||
| 651 | |||
| 652 | Reports can now reference the Boolean flag when referencing the cohort of patients, maintaining the integrity of the query and reducing load on the system when the report is run. | ||
| 653 | |||
| 654 | = {{id name="Functions"/}}Calculation Functions Index = | ||
| 655 | |||
| 656 | == Numeric Functions == | ||
| 657 | |||
| 658 | === Abs === | ||
| 659 | |||
| 660 | Abs( <Expression> ) | ||
| 661 | //A mathematical function that returns the absolute (positive) value of a numeric expression.// | ||
| 662 | |||
| 663 | **Arguments** | ||
| 664 | The expression has to be a numeric value. | ||
| 665 | |||
| 666 | **Examples** | ||
| 667 | Cost_Price = 0, Sale_Price = 1.69, Refund_Price = -1.69 | ||
| 668 | |||
| 669 | Abs( Cost_Price ) | ||
| 670 | would return 0 | ||
| 671 | |||
| 672 | Abs( Sale_Price ) | ||
| 673 | would return 1.69 | ||
| 674 | |||
| 675 | Abs( Refund_Price ) | ||
| 676 | would return 1.69 | ||
| 677 | |||
| 678 | === Ceil === | ||
| 679 | |||
| 680 | Ceil( <Expression>, <Optional Decimal Places> ) | ||
| 681 | //Returns a numeric value rounded up to the nearest whole number or to the specified number of decimal places.// | ||
| 682 | |||
| 683 | **Arguments** | ||
| 684 | The expression has to be a numeric value or numeric field. | ||
| 685 | |||
| 686 | **Examples** | ||
| 687 | Cost_Price = 1.49, Sale_Price = 1.69, Profit = 0.539 | ||
| 688 | |||
| 689 | Ceil( Cost_Price ) | ||
| 690 | would return 2.00 | ||
| 691 | |||
| 692 | Ceil( Sale_Price ) | ||
| 693 | would return 2.00 | ||
| 694 | |||
| 695 | Ceil( Profit, 1 ) | ||
| 696 | would return 0.6 | ||
| 697 | |||
| 698 | === Cos === | ||
| 699 | |||
| 700 | Cos( <Expression> ) | ||
| 701 | //Returns the cosine of the provided expression. The result is returned in radians NOT degrees.// | ||
| 702 | |||
| 703 | **Arguments** | ||
| 704 | The expression has to be a numeric value. | ||
| 705 | |||
| 706 | **Examples** | ||
| 707 | Value = 20 | ||
| 708 | Would return 0.41 | ||
| 709 | |||
| 710 | === CountWorkingDays === | ||
| 711 | |||
| 712 | CountWorkingDays( <Expression> , <Expression> ) | ||
| 713 | //Counts the number of working days between two date fields. Please note that working days and holidays need to be configured by an administrator.// | ||
| 714 | |||
| 715 | **Examples** | ||
| 716 | Transaction Date = 19/09/2019, Return Date = 24/09/2019, Working Days = Monday, Tuesday, Wednesday, Thursday and Friday | ||
| 717 | |||
| 718 | CountWorkingDays( Transaction_Date , Return_Date ) | ||
| 719 | would return 2 | ||
| 720 | |||
| 721 | === DateBetween === | ||
| 722 | |||
| 723 | DateBetween( <Date Expression> , <Date Expression> , <TIMEPERIOD> ) | ||
| 724 | //Returns the number of inclusive period values between two date expressions, except when a time is specified.// | ||
| 725 | |||
| 726 | **Arguments** | ||
| 727 | The expression must be a date(time) expression. A period must also be provided. This must be in UPPERCASE and can be one of the following: DAYS, WEEKS, MONTHS, YEARS, SECONDS, MINUTES OR HOURS. | ||
| 728 | |||
| 729 | **Examples** | ||
| 730 | Raised_Date = 09/12/2014 Closed_Date = 28/01/2015 | ||
| 731 | |||
| 732 | DateBetween( Raised_Date , Closed_Date , DAYS ) | ||
| 733 | would return 51 | ||
| 734 | |||
| 735 | DateBetween( Raised_Date , Closed_Date , WEEKS ) | ||
| 736 | would return 8 | ||
| 737 | |||
| 738 | DateBetween( Raised_Date , Closed_Date , MONTHS ) | ||
| 739 | would return 2 | ||
| 740 | |||
| 741 | DateBetween( Raised_Date , Closed_Date , YEARS ) | ||
| 742 | would return 1 | ||
| 743 | |||
| 744 | DateBetween( Raised_Date , Closed_Date , SECONDS) | ||
| 745 | would return 4320001 | ||
| 746 | |||
| 747 | DateBetween( Raised_Date , Closed_Date , MINUTES ) | ||
| 748 | would return 72001 | ||
| 749 | |||
| 750 | DateBetween( Raised_Date , Closed_Date , HOURS ) | ||
| 751 | would return 1201 | ||
| 752 | |||
| 753 | Please note that using **DateBetween(<>,<>, SECONDS)** over thousands of records will increase the processing time. | ||
| 754 | |||
| 755 | === DaysBetween === | ||
| 756 | |||
| 757 | DaysBetween( <Date Expression> , <Date Expression>, <Optional Day(s)> ) | ||
| 758 | //Returns the number of inclusive period values between two date expressions.// | ||
| 759 | |||
| 760 | **Arguments** | ||
| 761 | The expression must be a date(time) expression. It can also contain optional arguments to exclude named days of the week from the calculation, commonly used to exclude weekends from a calculation. | ||
| 762 | |||
| 763 | **Examples** | ||
| 764 | Raised_Date = 15/01/2015 Closed_Date = 28/01/2015 | ||
| 765 | |||
| 766 | DaysBetween( Raised_Date , Closed_Date ) | ||
| 767 | would return 14 | ||
| 768 | |||
| 769 | DaysBetween( Raised_Date , Closed_Date , SATURDAY, SUNDAY ) | ||
| 770 | would return 10 | ||
| 771 | |||
| 772 | This function is inclusive and returns ‘1’ if starting and finishing on the same day. | ||
| 773 | |||
| 774 | === Fact === | ||
| 775 | |||
| 776 | Fact( <Expression> ) | ||
| 777 | //Returns the factorial of a given number.// | ||
| 778 | |||
| 779 | **Examples** | ||
| 780 | Fact(3) | ||
| 781 | would return 6 | ||
| 782 | |||
| 783 | === Floor === | ||
| 784 | |||
| 785 | Floor( <Expression>, <Optional Decimal Places> ) | ||
| 786 | Returns a numeric value rounded down to the nearest whole number //or to the specified number of decimal places.//. | ||
| 787 | |||
| 788 | **Arguments** | ||
| 789 | The expression has to be a numeric value or numeric field. | ||
| 790 | |||
| 791 | **Examples** | ||
| 792 | Cost_Price = 1.49, Sale_Price = 1.69, Profit = 0.579 | ||
| 793 | |||
| 794 | Floor( Cost_Price ) | ||
| 795 | would return 1.00 | ||
| 796 | |||
| 797 | Floor( Sale_Price ) | ||
| 798 | would return 1.00 | ||
| 799 | |||
| 800 | Floor( Profit, 1 ) | ||
| 801 | would return 0.5 | ||
| 802 | |||
| 803 | === GCD === | ||
| 804 | |||
| 805 | GCD( <Expression> ) | ||
| 806 | //Returns the greatest common divisor of two given numbers.// | ||
| 807 | |||
| 808 | **Arguments** | ||
| 809 | The expression has to be a numeric value. | ||
| 810 | |||
| 811 | **Examples** | ||
| 812 | GCD (8, 12) | ||
| 813 | would return 4 | ||
| 814 | |||
| 815 | === IsNull === | ||
| 816 | |||
| 817 | IsNull( <Expression> , <Expression> ) | ||
| 818 | //Returns a second specified value if the first is NULL.// | ||
| 819 | |||
| 820 | **Arguments** | ||
| 821 | The expression can be a string, date or numeric value. | ||
| 822 | |||
| 823 | **Example** | ||
| 824 | |||
| 825 | IsNull(Surname,'No name provided') | ||
| 826 | |||
| 827 | Would return the string value in the event the Surname value is NULL. | ||
| 828 | |||
| 829 | === LCM === | ||
| 830 | |||
| 831 | //Returns the lowest common multiple of two given numbers.// | ||
| 832 | |||
| 833 | **Arguments** | ||
| 834 | The expression has to be a numeric value. | ||
| 835 | |||
| 836 | **Examples** | ||
| 837 | LCM (3, 4) | ||
| 838 | would return 12 | ||
| 839 | |||
| 840 | === Len === | ||
| 841 | |||
| 842 | Len( <String Expression> ) | ||
| 843 | //Returns the number of characters of the specified string expression.// | ||
| 844 | |||
| 845 | **This function is only available for Calculated Fields in a Data Source Group or ETL stage.** | ||
| 846 | |||
| 847 | **Arguments** | ||
| 848 | The expression can be a string or numeric value. | ||
| 849 | |||
| 850 | **Examples** | ||
| 851 | Name = ‘John Smith’, Loyalty_Points = 691 | ||
| 852 | |||
| 853 | Len( Name ) | ||
| 854 | would return 10 | ||
| 855 | |||
| 856 | Len( Loyalty_Points ) | ||
| 857 | would return 3 | ||
| 858 | |||
| 859 | === Log === | ||
| 860 | |||
| 861 | Log( <Expression> , <Expression> ) | ||
| 862 | //Returns the logarithm of a number, using a supplied base.// | ||
| 863 | |||
| 864 | **Examples** | ||
| 865 | Log(64,2) | ||
| 866 | would return 6 | ||
| 867 | |||
| 868 | === Max === | ||
| 869 | |||
| 870 | Max( <Expression> , <Expression> ) | ||
| 871 | //Returns the maximum value of the provided expressions.// | ||
| 872 | |||
| 873 | **Arguments** | ||
| 874 | The expressions can be a numeric field name, a date field name, a numeric value or a date value. A combination of a field name and a constant value can be used. | ||
| 875 | |||
| 876 | **Examples** | ||
| 877 | Cost_Price = 3.99, Sale_Price = 4.99, Trans = 25/01/2015 Return = 27/01/2015 | ||
| 878 | |||
| 879 | Max( Cost_Price, 1.99 ) | ||
| 880 | would return 3.99 | ||
| 881 | |||
| 882 | Max( Cost_Price, 5.99 ) | ||
| 883 | would return 5.99 | ||
| 884 | |||
| 885 | Max( Cost_Price, Sale_Price ) | ||
| 886 | would return 5.99 | ||
| 887 | |||
| 888 | Max( Trans, ToDate(2015,01,22) ) | ||
| 889 | would return 25/01/2015 (20150125000000) | ||
| 890 | |||
| 891 | Max( Trans, Return ) | ||
| 892 | would return 27/01/2015 (20150127000000) | ||
| 893 | |||
| 894 | === Mod === | ||
| 895 | |||
| 896 | Mod( <Expression> , <Expression> ) | ||
| 897 | //Returns the remainder after division.// | ||
| 898 | |||
| 899 | **Examples** | ||
| 900 | Mod(10,4) | ||
| 901 | would return 2 | ||
| 902 | |||
| 903 | === Power === | ||
| 904 | |||
| 905 | Power( <Expression> , <Expression> ) | ||
| 906 | //Returns the sum of the provided power values.// | ||
| 907 | |||
| 908 | **Example** | ||
| 909 | Power(2,3) | ||
| 910 | would return 8, as 2*2*2=8 | ||
| 911 | |||
| 912 | === Quotient === | ||
| 913 | |||
| 914 | Quotient( <Expression> , <Expression> ) | ||
| 915 | //Returns the result of an integer division without the remainder.// | ||
| 916 | |||
| 917 | **Examples** | ||
| 918 | Quotient(12,5) | ||
| 919 | would return 2 | ||
| 920 | |||
| 921 | === Round === | ||
| 922 | |||
| 923 | Round( <Expression>, <Optional Decimal Places> ) | ||
| 924 | //Returns a numeric value rounded to the nearest whole number or to the specified number of decimal places..// | ||
| 925 | |||
| 926 | **Arguments** | ||
| 927 | The expression has to be a numeric value or numeric field. | ||
| 928 | |||
| 929 | **Examples** | ||
| 930 | Cost_Price = 1.49, Sale_Price = 1.69, Profit = 0.579 | ||
| 931 | |||
| 932 | Round( Cost_Price ) | ||
| 933 | would return 1.00 | ||
| 934 | |||
| 935 | Round( Sale_Price ) | ||
| 936 | would return 2.00 | ||
| 937 | |||
| 938 | Round( Profit, 1 ) | ||
| 939 | would return 0.6 | ||
| 940 | |||
| 941 | === Sign === | ||
| 942 | |||
| 943 | Sign( <Expression> ) | ||
| 944 | //Returns the sign of a number. If the number is positive, the function will return 1. If the number is negative, the function will return will return -1. If the number if 0, the function will return 0./// | ||
| 945 | |||
| 946 | **Examples** | ||
| 947 | Sign(22) | ||
| 948 | would return 1 | ||
| 949 | |||
| 950 | === Sin === | ||
| 951 | |||
| 952 | Sin( <Expression> ) | ||
| 953 | //Returns the sine of the provided expression. The result is returned in radians NOT degrees.// | ||
| 954 | |||
| 955 | **Arguments** | ||
| 956 | The expression has to be a numeric value. | ||
| 957 | |||
| 958 | **Examples** | ||
| 959 | Sin(30) | ||
| 960 | would return -0.99 | ||
| 961 | |||
| 962 | === Sqrt === | ||
| 963 | |||
| 964 | Sqrt( <Expression> ) | ||
| 965 | //Returns the square root of the provided expression.// | ||
| 966 | |||
| 967 | **Arguments** | ||
| 968 | The expression has to be a numeric value. | ||
| 969 | |||
| 970 | **Examples** | ||
| 971 | Sqrt(81) | ||
| 972 | would return 9 | ||
| 973 | |||
| 974 | === Tan === | ||
| 975 | |||
| 976 | Tan( <Expression> ) | ||
| 977 | //Returns the tangent of the provided expression. The result is returned in radians NOT degrees.// | ||
| 978 | |||
| 979 | **Arguments** | ||
| 980 | The expression has to be a numeric value. | ||
| 981 | |||
| 982 | **Example** | ||
| 983 | Tan(50) | ||
| 984 | would return 0.96 | ||
| 985 | |||
| 986 | === ToDay === | ||
| 987 | |||
| 988 | ToDay( <Date Expression> ) | ||
| 989 | //Returns the day date part of a date(time) expression.// | ||
| 990 | |||
| 991 | **Arguments** | ||
| 992 | The expression must be a date or datetime expression. | ||
| 993 | |||
| 994 | **Examples** | ||
| 995 | Transaction_Date = 19/09/2021 | ||
| 996 | |||
| 997 | ToDay( Transaction_Date ) | ||
| 998 | would return 19 | ||
| 999 | |||
| 1000 | The numeric output of this function can then be used as part of other calculations. | ||
| 1001 | |||
| 1002 | === ToDayOfWeek === | ||
| 1003 | |||
| 1004 | ToDayOfWeek( <Date Expression> ) | ||
| 1005 | //Returns the weekday number of a date(time) expression, where Sunday = 1.// | ||
| 1006 | |||
| 1007 | **Arguments** | ||
| 1008 | The expression must be a date or datetime expression. | ||
| 1009 | |||
| 1010 | **Examples** | ||
| 1011 | Transaction_Date = 07/04/2021 (Wednesday) | ||
| 1012 | |||
| 1013 | ToDayOfWeek( Transaction_Date ) | ||
| 1014 | Would return 4 | ||
| 1015 | |||
| 1016 | === ToHour === | ||
| 1017 | |||
| 1018 | ToHour( <Date Expression> ) | ||
| 1019 | //Returns the hour datepart of a datetime expression.// | ||
| 1020 | |||
| 1021 | **Arguments** | ||
| 1022 | The expression must be a date or datetime expression. | ||
| 1023 | |||
| 1024 | **Examples** | ||
| 1025 | Transaction_Date = 22/01/2015 18:32:15 | ||
| 1026 | |||
| 1027 | ToHour( Transaction_Date ) | ||
| 1028 | would return 18 | ||
| 1029 | |||
| 1030 | === ToJulianDay === | ||
| 1031 | |||
| 1032 | ToJulianDay( <Date Expression> ) | ||
| 1033 | //Returns the Julian Day value of a date(time) expression. The Julian day is the continuous count of days since the beginning of the Julian Period and is used when comparing two dates.// | ||
| 1034 | |||
| 1035 | **Arguments** | ||
| 1036 | The expression must be a date or datetime expression. | ||
| 1037 | |||
| 1038 | **Examples** | ||
| 1039 | Raised_Date = 22/01/2015 Closed_Date = 25/01/2015 | ||
| 1040 | |||
| 1041 | ToJulianDay( Raised_Date ) | ||
| 1042 | would return 16457 | ||
| 1043 | |||
| 1044 | ToJulianDay( Closed_Date ) | ||
| 1045 | would return 16460 | ||
| 1046 | |||
| 1047 | ToJulianDay( Closed_Date ) - ToJulianDay( Raised_Date ) | ||
| 1048 | would return 3 (days) | ||
| 1049 | |||
| 1050 | === ToJulianDayTime === | ||
| 1051 | |||
| 1052 | ToJulianDayTime( <Date Expression> ) | ||
| 1053 | //Returns the Julian Daytime value of a datetime expression. The Julian daytime is the continuous count of seconds since the beginning of the Julian Period and is used when comparing two datetimes.// | ||
| 1054 | |||
| 1055 | **Arguments** | ||
| 1056 | The expression must be a datetime expression. | ||
| 1057 | |||
| 1058 | **Examples** | ||
| 1059 | Raised_Date = 28/01/2015 10:49:51 Closed_Date = 28/01/2015 14:01:44 | ||
| 1060 | |||
| 1061 | ToJulianDayTime( Raised_Date ) | ||
| 1062 | would return 1422442191 | ||
| 1063 | |||
| 1064 | ToJulianDayTime( Closed_Date ) | ||
| 1065 | would return 1422453704 | ||
| 1066 | |||
| 1067 | ToJulianDayTime( Closed_Date ) - ToJulianDayTime( Raised_Date ) | ||
| 1068 | would return 11513 (seconds) | ||
| 1069 | |||
| 1070 | === ToMinute === | ||
| 1071 | |||
| 1072 | ToMinute( <Date Expression> ) | ||
| 1073 | //Returns the minute datepart of a datetime expression.// | ||
| 1074 | |||
| 1075 | **Arguments** | ||
| 1076 | The expression must be a date or datetime expression. | ||
| 1077 | |||
| 1078 | **Examples ** | ||
| 1079 | Transaction_Date = 22/01/2015 18:32:15 | ||
| 1080 | |||
| 1081 | ToMinute( Transaction_Date ) | ||
| 1082 | would return 32 | ||
| 1083 | |||
| 1084 | === ToMonth === | ||
| 1085 | |||
| 1086 | ToMonth( <Date Expression> ) | ||
| 1087 | //Returns the month datepart of a date(time) expression.// | ||
| 1088 | |||
| 1089 | **Arguments** | ||
| 1090 | The expression must be a date or datetime expression. | ||
| 1091 | |||
| 1092 | **Examples** | ||
| 1093 | Transaction_Date = 22/01/2015 | ||
| 1094 | |||
| 1095 | ToMonth( Transaction_Date ) | ||
| 1096 | would return 1 | ||
| 1097 | |||
| 1098 | === ToSecond === | ||
| 1099 | |||
| 1100 | ToSecond( <Date Expression> ) | ||
| 1101 | //Returns the second datepart of a datetime expression.// | ||
| 1102 | |||
| 1103 | **Arguments** | ||
| 1104 | The expression must be a date or datetime expression. | ||
| 1105 | |||
| 1106 | **Examples** | ||
| 1107 | Transaction_Date = 22/01/2015 18:32:15 | ||
| 1108 | |||
| 1109 | ToSecond( Transaction_Date ) | ||
| 1110 | would return 15 | ||
| 1111 | |||
| 1112 | === ToNumber === | ||
| 1113 | |||
| 1114 | ToNumber( <Expression> ) | ||
| 1115 | //Converts string values into a number.// | ||
| 1116 | |||
| 1117 | **This function is only available for Calculated Fields in a Data Source Group or ETL stage.** | ||
| 1118 | |||
| 1119 | **Arguments** | ||
| 1120 | The expression must be a string value. | ||
| 1121 | |||
| 1122 | === ToWeek === | ||
| 1123 | |||
| 1124 | ToWeek( <Date Expression> ) | ||
| 1125 | //Returns the week datepart of a date(time) expression.// | ||
| 1126 | |||
| 1127 | **Arguments** | ||
| 1128 | The expression must be a date or datetime expression. | ||
| 1129 | |||
| 1130 | **Examples** | ||
| 1131 | Transaction_Date = 22/01/2015 | ||
| 1132 | |||
| 1133 | ToWeek( Transaction_Date ) | ||
| 1134 | would return 4 | ||
| 1135 | |||
| 1136 | === ToYear === | ||
| 1137 | |||
| 1138 | ToYear( <Date Expression> ) | ||
| 1139 | //Returns the year datepart of a date(time) expression.// | ||
| 1140 | |||
| 1141 | **Arguments** | ||
| 1142 | The expression must be a date or datetime expression. | ||
| 1143 | |||
| 1144 | **Examples** | ||
| 1145 | Transaction_Date = 22/01/2015 | ||
| 1146 | |||
| 1147 | ToYear( Transaction_Date ) | ||
| 1148 | would return 2015 | ||
| 1149 | |||
| 1150 | === Random === | ||
| 1151 | |||
| 1152 | Random( <Expression> ) | ||
| 1153 | //Generates a random number between 0 and 1.// | ||
| 1154 | |||
| 1155 | === Column === | ||
| 1156 | |||
| 1157 | Column( <Expression> , <Expression> ) | ||
| 1158 | //References the value of a total in a column.// | ||
| 1159 | |||
| 1160 | **This function is only available for Cell Calculations in Crosstabs.** | ||
| 1161 | |||
| 1162 | **Arguments** | ||
| 1163 | The first value is the position of the column, starting at 0 (zero) and the second value is the position of the total. | ||
| 1164 | |||
| 1165 | **Examples** | ||
| 1166 | Using this function in a Cell Calculations, it is possible to reference totals by their position rather than name. For example: | ||
| 1167 | |||
| 1168 | Column(0 ,1 ) + Column(1,1) | ||
| 1169 | |||
| 1170 | As 0 (zero) is the starting point, this calculation will add the second total of the first column to the second total of the second column. | ||
| 1171 | |||
| 1172 | **Reporting Examples** | ||
| 1173 | The following report displays a breakdown of credit card and debit card transactions: | ||
| 1174 | |||
| 1175 | [[image:CalcScreen11.png||height="255" width="600"]] | ||
| 1176 | |||
| 1177 | Using the Column function, totals can be referenced by their position rather than total name. The following cell calculation has been used to derive the ‘Total Cad Transactions’ total: | ||
| 1178 | |||
| 1179 | Column(0 ,0 ) + Column(0 ,1) | ||
| 1180 | |||
| 1181 | As only a single column value, 2019, has been added, the position 0 is referenced before referencing the first and second total, respectively. | ||
| 1182 | |||
| 1183 | === ColumnTotal, RowTotal, GrandTotal === | ||
| 1184 | |||
| 1185 | ColumnTotal( <Expression> ) | ||
| 1186 | //References the column total, row total and grand total, respectively.// | ||
| 1187 | |||
| 1188 | These functions are only available for cell calculations. | ||
| 1189 | |||
| 1190 | **Reporting Examples** | ||
| 1191 | The following report displays a number of totals based on card transactions for each region: | ||
| 1192 | |||
| 1193 | [[image:CalcScreen12.png||height="214" width="600"]] | ||
| 1194 | |||
| 1195 | The first total, ‘Card Transactions’, simply counts all rows that contain ‘Credit Card’ or ‘Debit Card’ values for the MOP (Method of payment) column. | ||
| 1196 | |||
| 1197 | The second total, ‘Card Transactions (Running Total)’ uses the same logic as the previous total and has the **Show Value As** drop-down list set to Running Total Down Columns to provide a running total. | ||
| 1198 | |||
| 1199 | The third total, ‘Total Card Transactions’, uses a Cell calculation with the following logic: | ||
| 1200 | |||
| 1201 | ColumnTotal(1) | ||
| 1202 | |||
| 1203 | Using this function, the Column Total value can referenced to allow for the fourth total, ‘% Running Total’ to be calculated using the following logic: | ||
| 1204 | |||
| 1205 | ('Card Transactions (Running Total)'/'Total Card Transactions')*100 | ||
| 1206 | |||
| 1207 | This methodology is applicable for both the RowTotal and GrandTotal functions, respectively. By referencing these values in a report, they can be leveraged in future Cell calculations to achieve the desired output. | ||
| 1208 | |||
| 1209 | === ColumnMin === | ||
| 1210 | |||
| 1211 | Column( <Expression> ) | ||
| 1212 | //References the minimum value of a total in a column.// | ||
| 1213 | |||
| 1214 | **This function is only available for Cell Calculations in Crosstabs.** | ||
| 1215 | |||
| 1216 | **Arguments** | ||
| 1217 | The expression should be the total from which you require the minimum value. | ||
| 1218 | |||
| 1219 | **Examples** | ||
| 1220 | A Crosstab has a Total called 'Sales'. To write out the minimum value from this total use the following syntax: | ||
| 1221 | |||
| 1222 | ColumnMin( 'Sales' ) | ||
| 1223 | |||
| 1224 | [[image:Screenshot 2022-05-19 at 10.18.13.png||height="196" width="263"]] | ||
| 1225 | |||
| 1226 | === ColumnMax === | ||
| 1227 | |||
| 1228 | Column( <Expression> ) | ||
| 1229 | //References the maximum value of a total in a column.// | ||
| 1230 | |||
| 1231 | **This function is only available for Cell Calculations in Crosstabs.** | ||
| 1232 | |||
| 1233 | **Arguments** | ||
| 1234 | The expression should be the total from which you require the maximum value. | ||
| 1235 | |||
| 1236 | **Examples** | ||
| 1237 | A Crosstab has a Total called 'Sales'. To write out the maximum value from this total use the following syntax: | ||
| 1238 | |||
| 1239 | ColumnMax( 'Sales' ) | ||
| 1240 | |||
| 1241 | [[image:Screenshot 2022-05-19 at 10.25.54.png||height="197" width="266"]] | ||
| 1242 | |||
| 1243 | == Date Functions == | ||
| 1244 | |||
| 1245 | **The following functions are available for Calculated Fields and Crosstab standard calculations (not cell calculations):** | ||
| 1246 | |||
| 1247 | === FromJulianDay === | ||
| 1248 | |||
| 1249 | FromJulianDay( <Date Expression> ) | ||
| 1250 | //Returns a date as a numeric field from a Julian day. The Julian day is the continuous count of days since the beginning of the Julian Period and can be used when comparing two dates.// | ||
| 1251 | |||
| 1252 | **Examples** | ||
| 1253 | Raised_Date = 16457 Closed_Date = 16460 | ||
| 1254 | |||
| 1255 | FromJulianDay( Raised_Date ) would return 20150122 | ||
| 1256 | |||
| 1257 | FromJulianDay( Closed_Date ) would return 20150125 | ||
| 1258 | |||
| 1259 | **Extra Field Example** | ||
| 1260 | The following example calculates the maximum difference between a referral date and appoint date on a row: | ||
| 1261 | |||
| 1262 | FromJulianDay( Max( ToJulianDay( Referral_Date ) , ToJulianDay( Appointment_Date ) ) ) | ||
| 1263 | |||
| 1264 | Converting back to a date value from a Julian Day allows numeric calculations between dates to be achieved while retaining the date format in a single calculation. | ||
| 1265 | |||
| 1266 | === FromJulianDayTime === | ||
| 1267 | |||
| 1268 | FromJulianDayTime( <Date Expression> ) | ||
| 1269 | //Returns a datetime expression from a Julian Daytime value. The Julian daytime is the continuous count of seconds since the beginning of the Julian Period and can be used when comparing two datetimes.// | ||
| 1270 | |||
| 1271 | **Example** | ||
| 1272 | Raised_Date = 1422442191 Closed_Date = 1422453704 | ||
| 1273 | |||
| 1274 | FromJulianDayTime( Raised_Date ) | ||
| 1275 | would return 20150128104951 | ||
| 1276 | |||
| 1277 | FromJulianDayTime( Closed_Date ) | ||
| 1278 | would return 20150128140144 | ||
| 1279 | |||
| 1280 | Converting back to a date value from a Julian Day allows numeric calculations between dates to be achieved while retaining the date format in a single calculation. | ||
| 1281 | |||
| 1282 | **Extra Field Example** | ||
| 1283 | The following example shows an extra field calculation that outputs the maximum value between two date times fields on a row: | ||
| 1284 | |||
| 1285 | In seconds: | ||
| 1286 | FromJulianDayTime( Max( ToJulianDayTime( Referral_Date_Time ) , ToJulianDayTime( Appointment_Date_Time ) ) ) | ||
| 1287 | |||
| 1288 | In minutes: | ||
| 1289 | FromJulianDayTime( Max( ToJulianDayTime( Referral_Date_Time ) , ToJulianDayTime( Appointment_Date_Time ) ) )/60 | ||
| 1290 | |||
| 1291 | === ToDate === | ||
| 1292 | |||
| 1293 | ToDate( <Expression> , <Expression> , <Expression> ) | ||
| 1294 | //Returns a date value.// | ||
| 1295 | |||
| 1296 | **Arguments** | ||
| 1297 | Each expression can either contain a date field or a numeric value. | ||
| 1298 | |||
| 1299 | The first expression contains the year element, the second expression contains the month element and the third expression contains the minute element. | ||
| 1300 | |||
| 1301 | **Examples** | ||
| 1302 | Raised_Date = 15/01/2015 Closed_Date = 16/01/2015 | ||
| 1303 | |||
| 1304 | ToDate( 2014, 11, 8 ) | ||
| 1305 | would return 08/11/2014 | ||
| 1306 | |||
| 1307 | ToDate ( ToYear(Raised_Date), ToMonth(Raised_Date), ToDay(Raised_Date) ) | ||
| 1308 | would return 15/01/2015 | ||
| 1309 | |||
| 1310 | ToDate ( ToYear(Raised_Date), 12, 1 ) | ||
| 1311 | would return 01/12/2015 | ||
| 1312 | |||
| 1313 | ToDate ( ToYear(Raised_Date), 12, ToDay(Closed_Date) ) | ||
| 1314 | would return 16/12/2015 | ||
| 1315 | |||
| 1316 | **The output value will be a date field when created as a Calculated Field for an Index. For a Crosstab, the output value will actually be a numeric representation of the date. However, the value can still be used for calculations that require date comparisons/logic.** | ||
| 1317 | |||
| 1318 | === ToDateTime === | ||
| 1319 | |||
| 1320 | ToDate( <Expression> , <Expression> , <Expression>, <Expression> , <Expression> , <Expression> ) | ||
| 1321 | //Returns a datetime value.// | ||
| 1322 | |||
| 1323 | **Arguments** | ||
| 1324 | Each expression can either contain a date field or a numeric value. | ||
| 1325 | |||
| 1326 | The first expression contains the year element, the second expression contains the month element and the third expression contains the minute element, the fourth expression contains the hour element, the fifth expression contains the minute element, the sixth expression contains the seconds element. | ||
| 1327 | |||
| 1328 | **Examples** | ||
| 1329 | Raised_Date = 15/01/2015 14:15:59 Closed_Date = 16/01/2015 17:11:23 | ||
| 1330 | |||
| 1331 | ToDateTime( 2014, 11, 8, 23, 59, 59 ) | ||
| 1332 | would return 08/11/2014 23:59:59 | ||
| 1333 | |||
| 1334 | ToDateTime( ToYear(Raised_Date), ToMonth(Raised_Date), ToDay(Raised_Date), ToHour(Raised_Date), ToMinute(Raised_Date), ToSecond(Raised_Date) ) | ||
| 1335 | would return 15/01/2015 14:15:59 | ||
| 1336 | |||
| 1337 | ToDateTime( ToYear(Raised_Date), 12, 1, 23, 59, 59 ) | ||
| 1338 | would return 01/12/2015 23:59:59 | ||
| 1339 | |||
| 1340 | ToDateTime( ToYear(Raised_Date), 12, ToDay(Closed_Date), ToHour(Raised_Date), 45, ToSecond(Closed_Date) ) | ||
| 1341 | would return 16/12/2015 14:45:23 | ||
| 1342 | |||
| 1343 | **The output value will be a date field when created as a Calculated Field for an Index. For a Crosstab, the output value will actually be a numeric representation of the date. However, the value can still be used for calculations that require date comparisons/logic.** | ||
| 1344 | |||
| 1345 | == String Functions == | ||
| 1346 | |||
| 1347 | **The following functions are available for Calculated Fields only (in Data Source Groups and ETL stage calculations).** | ||
| 1348 | |||
| 1349 | === Format === | ||
| 1350 | |||
| 1351 | Format( <Expression> , <Pattern> ) | ||
| 1352 | //Changes the format of a field or string.// | ||
| 1353 | |||
| 1354 | **Arguments** | ||
| 1355 | The string expression can be a field or a static string value. This can be a date, a string or a numeric value. This function will only output a string value. | ||
| 1356 | |||
| 1357 | **Example** | ||
| 1358 | Expression : 01/01/2010 | ||
| 1359 | |||
| 1360 | Format(Transaction_Date_Time, ‘dd/MM/yyyy hh:mm:ss’) | ||
| 1361 | would return 01/01/2010 00:00:00 | ||
| 1362 | |||
| 1363 | === IndexOf === | ||
| 1364 | |||
| 1365 | IndexOf( <String Expression> , <Expression> , <Optional Start Point> ) | ||
| 1366 | //Returns the position (numeric) of a specified character in a string expression.// | ||
| 1367 | |||
| 1368 | **Arguments** | ||
| 1369 | The string element can either be a field or a static string value. This is the string that will be parsed to look for an expression. The expression element specifies the character/string/value that is to be searched for. The expression element will accept a numeric value, a single string character or a strong expression. | ||
| 1370 | |||
| 1371 | There is also an optional expression for the start point of the search (in positional terms) e.g. Search for the first ‘&’ symbol that appears after the first ‘$’ symbol. | ||
| 1372 | |||
| 1373 | To include a special character in a search, prefix the desired character with the backslash character. For example, **\n** for a new line and **\t** for a tab space. | ||
| 1374 | |||
| 1375 | **Examples** | ||
| 1376 | Phrase = abc:123&456:Oscar:test | ||
| 1377 | |||
| 1378 | IndexOf( Phrase , ‘:’ ) | ||
| 1379 | would return a value of 3 (a numeric value) | ||
| 1380 | |||
| 1381 | IndexOf( Phrase , ‘a’ ) | ||
| 1382 | would return a value of 0 | ||
| 1383 | |||
| 1384 | IndexOf( Phrase , ‘:’, 5 ) | ||
| 1385 | would return a value of 11 | ||
| 1386 | |||
| 1387 | IndexOf( Phrase , ‘&’, 10 ) | ||
| 1388 | would return a value of -1 | ||
| 1389 | |||
| 1390 | IndexOf( Phrase , ‘:’, IndexOf(Phrase, ‘&’) ) | ||
| 1391 | would return a value of 11 | ||
| 1392 | |||
| 1393 | The first position is 0 (zero). If the expression being searched for is not found, -1 will be returned. | ||
| 1394 | |||
| 1395 | === LastIndexOf === | ||
| 1396 | |||
| 1397 | LastIndexOf( <String Expression> , <Expression> , <Optional Start Point> ) | ||
| 1398 | //Returns the last position (numeric) of a specified character in a string expression.// | ||
| 1399 | |||
| 1400 | **Arguments** | ||
| 1401 | The string element can either be a field or a static string value. This is the string that will be parsed to look for an expression. The expression element specifies the character/string/value that is to be searched for. The expression element will accept a numeric value, a single string character or a strong expression. | ||
| 1402 | |||
| 1403 | There is also an optional expression for the start point of the search (in positional terms) e.g. Search for the first ‘&’ symbol that appears after the first ‘$’ symbol. | ||
| 1404 | |||
| 1405 | **Examples** | ||
| 1406 | Phrase = abc:123&456:Oscar:test | ||
| 1407 | |||
| 1408 | LastIndexOf( Phrase , ‘:’ ) | ||
| 1409 | would return a value of 17 (a numeric value) | ||
| 1410 | |||
| 1411 | LastIndexOf( Phrase , ‘a’ ) | ||
| 1412 | would return a value of 15 | ||
| 1413 | |||
| 1414 | LastIndexOf( Phrase , ‘:’, 5 ) | ||
| 1415 | would return a value of 11 | ||
| 1416 | |||
| 1417 | LastIndexOf( Phrase , ‘&’, 15 ) | ||
| 1418 | would return a value of -1 | ||
| 1419 | |||
| 1420 | LastIndexOf( Phrase , ‘:’, LastIndexOf(Phrase, ‘&’) ) | ||
| 1421 | would return a value of 3 | ||
| 1422 | |||
| 1423 | The first position is 0 (zero). If the expression being searched for is not found, -1 will be returned. | ||
| 1424 | |||
| 1425 | (% style="color:#444444; font-family:inherit; font-size:20px; letter-spacing:0.1px" %)LTrim | ||
| 1426 | |||
| 1427 | LTrim( <String Expression> , <Expression> ) | ||
| 1428 | //Trims (removes) characters from left to right. Returns a string value.// | ||
| 1429 | |||
| 1430 | **Arguments** | ||
| 1431 | The string element can either be a field or a static string value. This is the string that will be trimmed. The expression element specifies how many characters of the string expression are to be trimmed (removed) from the left side of the string expression. The expression element will only accept a numeric value. | ||
| 1432 | |||
| 1433 | **Example** | ||
| 1434 | Status = underway | ||
| 1435 | |||
| 1436 | LTrim( Status , 5 ) | ||
| 1437 | would return way | ||
| 1438 | |||
| 1439 | **Not to be confused with SQL Server TRIM function.** | ||
| 1440 | |||
| 1441 | === LTrimSpaces === | ||
| 1442 | |||
| 1443 | LTrimSpaces( <String Expression> ) | ||
| 1444 | //Removes space padding to the left of a string.// | ||
| 1445 | |||
| 1446 | **Arguments** | ||
| 1447 | The string element can either be a field or a static string value. This is the string that will be trimmed. | ||
| 1448 | |||
| 1449 | **Examples** | ||
| 1450 | Value = “ Hat“ | ||
| 1451 | would return “Hat” | ||
| 1452 | |||
| 1453 | === Replace === | ||
| 1454 | |||
| 1455 | Replace( <String Expression> , <String Expression> , <String Expression> ) | ||
| 1456 | //Replaces part or all of a string with another string.// | ||
| 1457 | |||
| 1458 | **Arguments** | ||
| 1459 | The string expression can be a field or a static string value. This can be a date, a string or a numeric value. | ||
| 1460 | |||
| 1461 | **Example** | ||
| 1462 | Expression = Northern England and Ireland | ||
| 1463 | |||
| 1464 | Replace(Area_Name, ‘Northern England and Ireland’, ‘NE & I’) | ||
| 1465 | Would return NE & I | ||
| 1466 | |||
| 1467 | === RTrim === | ||
| 1468 | |||
| 1469 | RTrim( <String Expression> , <Expression> ) | ||
| 1470 | //Trims (removes) characters from right to left. Returns a string value.// | ||
| 1471 | |||
| 1472 | **Arguments** | ||
| 1473 | The string element can either be a field or a static string value. This is the string that will be trimmed. The expression element specifies how many characters of the string expression are to be trimmed (removed) from the right side of the string expression. The expression element will only accept a numeric value. | ||
| 1474 | |||
| 1475 | **Examples** | ||
| 1476 | Status = underway | ||
| 1477 | |||
| 1478 | RTrim( Status , 3 ) | ||
| 1479 | would return under | ||
| 1480 | |||
| 1481 | **Not to be confused with SQL Server TRIM function.** | ||
| 1482 | |||
| 1483 | === RtrimSpaces === | ||
| 1484 | |||
| 1485 | RTrimSpaces( <String Expression> ) | ||
| 1486 | //Removes space padding to the right of a string.// | ||
| 1487 | |||
| 1488 | **Arguments** | ||
| 1489 | The string element can either be a field or a static string value. This is the string that will be trimmed. | ||
| 1490 | |||
| 1491 | **Examples** | ||
| 1492 | Value = “Hat “ | ||
| 1493 | would return “Hat” | ||
| 1494 | |||
| 1495 | === Substring === | ||
| 1496 | |||
| 1497 | Substring( <String Expression> , <Expression> , <Expression> ) | ||
| 1498 | //Returns the specified part of a string expression.// | ||
| 1499 | |||
| 1500 | **Arguments** | ||
| 1501 | The string expression can be a field or a static string value. This can be a date, a string or a numeric value. The first expression is the start position of the substring. The second expression is the end position of the substring. | ||
| 1502 | |||
| 1503 | The start position of a string is 0 (zero). | ||
| 1504 | |||
| 1505 | The second expression is optional. Leaving this blank will return the remainder of the string expression after the specified start point. | ||
| 1506 | |||
| 1507 | **Examples** | ||
| 1508 | Phrase = price:3.99:cost:2.99 | ||
| 1509 | |||
| 1510 | Substring(Phrase, 6) | ||
| 1511 | would return 3.99:cost:2.99 | ||
| 1512 | |||
| 1513 | Substring(Phrase, 0, 5) | ||
| 1514 | would return price | ||
| 1515 | |||
| 1516 | In combination with IndexOf() the following can be used: | ||
| 1517 | Substring(Phrase, 0, IndexOf(Phrase, ‘:’)) | ||
| 1518 | would return price | ||
| 1519 | |||
| 1520 | Substring(Phrase, LastIndexOf(Phrase, ‘:’)) | ||
| 1521 | would return 2.99 | ||
| 1522 | |||
| 1523 | Substring(Phrase, IndexOf(Phrase, ‘:’)+1,IndexOf(Phrase,’:’,IndexOf(Phrase,’:’)+1)) | ||
| 1524 | would return 3.99 | ||
| 1525 | |||
| 1526 | === ToLower === | ||
| 1527 | |||
| 1528 | ToLower( <String Expression> ) | ||
| 1529 | //Returns the provided expression in lower case.// | ||
| 1530 | |||
| 1531 | **Arguments** | ||
| 1532 | The string element can either be a field or a static string value. | ||
| 1533 | |||
| 1534 | **Examples** | ||
| 1535 | Value = “Hat“ | ||
| 1536 | Would return “hat” | ||
| 1537 | |||
| 1538 | === ToString === | ||
| 1539 | |||
| 1540 | ToString( <Expression> ) | ||
| 1541 | //Returns the provided expression as a string.// | ||
| 1542 | |||
| 1543 | **Arguments** | ||
| 1544 | The string element can either be a field or a static numeric or date value. | ||
| 1545 | |||
| 1546 | **Examples** | ||
| 1547 | Expression = 30.9 | ||
| 1548 | Would return 30.9 as a string | ||
| 1549 | |||
| 1550 | === ToUpper === | ||
| 1551 | |||
| 1552 | ToUpper( <String Expression> ) | ||
| 1553 | //Returns the provided expression in upper case.// | ||
| 1554 | |||
| 1555 | **Arguments** | ||
| 1556 | The string element can either be a field or a static string value. | ||
| 1557 | |||
| 1558 | **Examples** | ||
| 1559 | Value = “Hat“ | ||
| 1560 | Would return “HAT” | ||
| 1561 | |||
| 1562 | == Boolean Functions == | ||
| 1563 | |||
| 1564 | === Contains === | ||
| 1565 | |||
| 1566 | Contains( <Expression> , <Expression> ) | ||
| 1567 | //A function used to search for a value.// | ||
| 1568 | |||
| 1569 | To include a special character in a search, prefix the desired character with the backslash character. For example, **\n** for a new line and **\t** for a tab space. | ||
| 1570 | |||
| 1571 | **Available for use in Calculated Fields in a Data Source Group or an ETL stage calculation.** | ||
| 1572 | |||
| 1573 | **Arguments** | ||
| 1574 | Can only be used as part of a CASE or IF statement as part of a calculated field. | ||
| 1575 | |||
| 1576 | **Examples** | ||
| 1577 | CASE WHEN Contains( MOP , 'Cash' ) THEN 1 ELSE 0 END | ||
| 1578 | would return an extra field containing 1 where MOP contains Cash, or 0 | ||
| 1579 | |||
| 1580 | === In === | ||
| 1581 | |||
| 1582 | In ( <Expression> , <Expression> ) | ||
| 1583 | Determines whether a specific value appears in a field. | ||
| 1584 | |||
| 1585 | **Available for use in both Crosstabs and Calculated Fields in Data Source Group and ETL stage calculation.** | ||
| 1586 | |||
| 1587 | **Arguments** | ||
| 1588 | The first expression is the field of interest and the second expression is the value(s) searched for. | ||
| 1589 | |||
| 1590 | **Examples** | ||
| 1591 | CASE WHEN In( Day_of_Week , 2, 3, 4) THEN 1 ELSE 0 END | ||
| 1592 | would count records where Day_of_Week = 2,3 or 4 | ||
| 1593 | |||
| 1594 | CASE WHEN In( MOP , 'Cash' , 'Vouchers') THEN 1 ELSE 0 END | ||
| 1595 | Would count records where cash or vouchers were used as the method of payment. | ||
| 1596 | |||
| 1597 | === IsFormat === | ||
| 1598 | |||
| 1599 | IsFormat( <String Expression> , <Pattern>) | ||
| 1600 | //Returns ‘True’ or ‘False’ on whether a field/string is in a specified format.// | ||
| 1601 | |||
| 1602 | **Available for use in Calculated Fields in a Data Source Group or an ETL stage calculation.** | ||
| 1603 | |||
| 1604 | **Arguments** | ||
| 1605 | The string expression can be a field or a static string value. This can be a date, a string or a numeric value. | ||
| 1606 | |||
| 1607 | **Examples** | ||
| 1608 | Expression: 10/05/2016 15:10:55 | ||
| 1609 | |||
| 1610 | IF IsFormat(Transaction_Date_Time, ‘dd/MM/yyyy hh:mm:ss’ THEN {1} ELSE {0} | ||
| 1611 | would return 1 | ||
| 1612 | |||
| 1613 | === Matches === | ||
| 1614 | |||
| 1615 | Matches( <Expression> , <Expression> ) | ||
| 1616 | //Used within a CASE or IF statement, returns whether a field matches a specified value.// | ||
| 1617 | |||
| 1618 | **Available for use in Calculated Fields in a Data Source Group or an ETL stage calculation.** | ||
| 1619 | |||
| 1620 | **Arguments** | ||
| 1621 | The string expression can be a field or a static string value. This can be a date, a string or a numeric value. | ||
| 1622 | |||
| 1623 | **Example** | ||
| 1624 | Expression = Male | ||
| 1625 | |||
| 1626 | CASE WHEN Matches( Gender , 'Male' ) THEN 1 ELSE 0 END | ||
| 1627 | would return 1 | ||
| 1628 | |||
| 1629 | === Within === | ||
| 1630 | |||
| 1631 | Within( <Period> , <Date Expression> , <Date Expression> , <Expression> ) | ||
| 1632 | or | ||
| 1633 | Within( <Period> , <Date Expression> , <Date Expression>, <Date Expression> , <Date Expression> , <Expression> ) | ||
| 1634 | //Returns any record (row of data) that satisfies the supplied parameters. Primarily to be used where true date values are not in place e.g. a week number and a year number as separate fields.// | ||
| 1635 | |||
| 1636 | **Arguments** | ||
| 1637 | The period refers to the period of time to be used by the range expression. This argument can contain DAYS, WEEKS, MONTHS, YEARS. | ||
| 1638 | |||
| 1639 | The first date expression is the date field to be used. This can be an actual date or a partial date. | ||
| 1640 | |||
| 1641 | The second date expression is the end point of the required date range. For example, to return all data for the previous month, the end point of the range would be: | ||
| 1642 | |||
| 1643 | FIRST_DAY_OF_MONTH-1DAY | ||
| 1644 | |||
| 1645 | The final expression is the range value of the within function. This is an array-based number and so will start at 0 (zero). | ||
| 1646 | |||
| 1647 | Additional Date Expressions can be used if only elements of a date are available as separate fields. | ||
| 1648 | |||
| 1649 | In this case, the structure of the arguments is as follows: | ||
| 1650 | |||
| 1651 | • Period (WEEKS, MONTHS, YEARS) | ||
| 1652 | • Date Expression (1st date element) | ||
| 1653 | • Date Expression (2nd date element) | ||
| 1654 | • Date Expression (1st date element end point) | ||
| 1655 | • Date Expression (2nd date element end point) | ||
| 1656 | • Expression (range value of the Within function) | ||
| 1657 | |||
| 1658 | **Examples** | ||
| 1659 | Within( WEEKS , Sales_Date , LAST_DAY_OF_WEEK-1WEEK , 0) | ||
| 1660 | would return all rows that have the Sales Date that exists in the previous week | ||
| 1661 | |||
| 1662 | Usage would be: | ||
| 1663 | CASE WHEN Within( WEEKS , Sales_Date , LAST-DAY_OF_WEEK-1WEEK , 0 ) THEN 1 END | ||
| 1664 | Within( WEEKS , Sales_Date , LAST_DAY_OF_WEEK-1WEEK , 3) | ||
| 1665 | would return all rows that have the Sales Date that exists in the previous 4 weeks | ||
| 1666 | |||
| 1667 | Usage would be: | ||
| 1668 | CASE WHEN Within( WEEKS , Sales_Date , LAST_DAY_OF_WEEK-1WEEK , 3) THEN 1 END | ||
| 1669 | Within( WEEKS , Sales_Date_Week , Sales_Date_Year, LAST_DAY_OF_WEEK-1WEEK, LAST_DAY_OF_WEEK-1WEEK, 0) | ||
| 1670 | would return all rows that have the Sales Date that exists in the previous week | ||
| 1671 | |||
| 1672 | === IsColumn === | ||
| 1673 | |||
| 1674 | IsColumn( <String Expression> ) | ||
| 1675 | //References a column or nested column.// | ||
| 1676 | |||
| 1677 | This function is only available for Crosstabs. | ||
| 1678 | |||
| 1679 | **Arguments** | ||
| 1680 | The string expression should be a case-sensitive reference to the name of a column value. The reference must be contained in single quotes. To reference a nested column value, use comma separated string values. | ||
| 1681 | |||
| 1682 | **Reporting Examples** | ||
| 1683 | In this report, two fields have been displayed on the column axis, with Area Name nested below Region Name: | ||
| 1684 | |||
| 1685 | [[image:CalcScreen13.png||height="113" width="550"]] | ||
| 1686 | |||
| 1687 | This report has been constructed using the **IsColumn** function so that the column outputs can be individually specified: | ||
| 1688 | |||
| 1689 | CASE | ||
| 1690 | WHEN IsColumn('London') | ||
| 1691 | THEN Price_EX_VAT | ||
| 1692 | ELSE Prince_INC_VAT | ||
| 1693 | END | ||
| 1694 | |||
| 1695 | For any values in the London column, the ‘Price_EX_VAT’ field is summed. For every other column, the ‘Price_INC_VAT’ field is summed. | ||
| 1696 | |||
| 1697 | Nested values can also be referenced by comma separating the string values. For example: | ||
| 1698 | |||
| 1699 | CASE | ||
| 1700 | WHEN IsColumn('London') THEN Price_EX_VAT | ||
| 1701 | WHEN IsColumn ('Midlands and East', 'East Anglia) THEN Price_EX_VAT | ||
| 1702 | ELSE Prince_INC_VAT | ||
| 1703 | END | ||
| 1704 | |||
| 1705 | In this next report, multiple outputs are specified in the calculation so that different totals can be specified for different columns: | ||
| 1706 | |||
| 1707 | [[image:CalcScreen15.png||height="173" width="400"]] | ||
| 1708 | |||
| 1709 | First, a ‘Costs’ total has been created by summing the ‘Cost Price’ field. This total is then hidden from the output using the **Hide Total in Table** option. | ||
| 1710 | |||
| 1711 | A cell calculation referencing this total has then been created using the following logic: | ||
| 1712 | |||
| 1713 | CASE | ||
| 1714 | WHEN IsColumn('London') THEN 'Costs'*1.4 | ||
| 1715 | WHEN IsColumn('Midlands and East') THEN 'Costs'*1.2 | ||
| 1716 | ELSE 'Costs'*1.1 | ||
| 1717 | END | ||
| 1718 | |||
| 1719 | Two columns have now been specified. Should any additional columns be added to the report, their totals will be calculated using the ‘ELSE’ figure. | ||
| 1720 | |||
| 1721 | === IsRow === | ||
| 1722 | |||
| 1723 | IsRow( <String Expression> ) | ||
| 1724 | //References a row or nested row.// | ||
| 1725 | |||
| 1726 | This function is only available for Crosstabs. | ||
| 1727 | |||
| 1728 | **Arguments** | ||
| 1729 | The string expression should be a case-sensitive reference to the name of a row value. The reference must be contained in single quotes. To reference a nested row value use comma separated string values. | ||
| 1730 | |||
| 1731 | **Examples** | ||
| 1732 | Much like the **IsColumn** function, using **IsRow** allows users to specify the output for specific areas of the report, this time at row level. | ||
| 1733 | |||
| 1734 | The following report is a transposed version of the example used for the **IsColumn** function, with the Region Name and Area Name fields now added to the row: | ||
| 1735 | |||
| 1736 | [[image:CalcScreen15.png||height="173" width="400"]] | ||
| 1737 | |||
| 1738 | The calculation has been tweaked to use the IsRow function to account for the axis change: | ||
| 1739 | |||
| 1740 | CASE | ||
| 1741 | WHEN IsRow('London') | ||
| 1742 | THEN Price_EX_VAT | ||
| 1743 | ELSE Prince_INC_VAT | ||
| 1744 | END | ||
| 1745 | |||
| 1746 | Nested values can also be referenced by comma separating the string values: | ||
| 1747 | |||
| 1748 | CASE | ||
| 1749 | WHEN IsRow('London') THEN Price_EX_VAT | ||
| 1750 | WHEN IsRow ('Midlands and East', 'East Midlands') THEN Price_EX_VAT | ||
| 1751 | ELSE Prince_INC_VAT | ||
| 1752 | END | ||
| 1753 | |||
| 1754 | === IsColumnTotal, IsGrandTotal, IsRowTotal, IsSubTotal === | ||
| 1755 | |||
| 1756 | IsColumnTotal(), IsGrandTotal(), IsRowTotal(), IsSubTotal() | ||
| 1757 | References a column total or nested column total, a grand total, a row total or nested row total and a subtotal, respectively. | ||
| 1758 | |||
| 1759 | **Arguments** | ||
| 1760 | The string expression should be a case-sensitive reference to the name of a row value. The reference must be contained in single quotes. To reference a nested row value use comma separated string values. | ||
| 1761 | |||
| 1762 | **Reporting Example** | ||
| 1763 | The following report has been constructed to omit a percentage value from the subtotal output: | ||
| 1764 | |||
| 1765 | [[image:CalcScreen16.png||height="256" width="550"]] | ||
| 1766 | |||
| 1767 | Using the following cell calculation, the ‘% Non-Branded Items’ total has been controlled to only be printed at column total, row total and grand total level: | ||
| 1768 | |||
| 1769 | CASE | ||
| 1770 | WHEN IsColumnTotal() THEN (('Non-Branded Sales'/'Total Transactions')*100) | ||
| 1771 | WHEN IsRowTotal() THEN (('Non-Branded Sales'/'Total Transactions')*100) | ||
| 1772 | WHEN IsGrandTotal() THEN (('Non-Branded Sales'/'Total Transactions')*100) | ||
| 1773 | WHEN IsSubTotal() THEN NULL | ||
| 1774 | END | ||
| 1775 | |||
| 1776 | The **IsColumnTotal**, **IsRowTotal** and **IsGrandTotal** functions have been used to specify the output of the percentage calculation. By specifying a NULL value for the **IsSubTotal** function, the total can be omitted from the sub total output. | ||
| 1777 | |||
| 1778 | == Aggregation Functions == | ||
| 1779 | |||
| 1780 | The following functions are available for Crosstabs only, unless otherwise specified, and produce an aggregated value. | ||
| 1781 | |||
| 1782 | === CountDistinct === | ||
| 1783 | |||
| 1784 | CountDistinct( <Expression>, <String Expression> ) | ||
| 1785 | //Returns a distinct count based on the value in the expression and the dynamic view being referenced.// | ||
| 1786 | |||
| 1787 | **Arguments** | ||
| 1788 | The expression output should be a numeric field. | ||
| 1789 | |||
| 1790 | **Examples** | ||
| 1791 | To return the number of employees who have handled a cash transaction: | ||
| 1792 | CountDistinct( CASE WHEN MOP = 'Cash' THEN 1 END , 'Employees' ) | ||
| 1793 | |||
| 1794 | It is important to not return anything other than 1 in the CASE logic as the CountDistinct will also count the employees who did not perform Cash transactions i.e. CountDistinct( CASE WHEN MOP = 'Cash' THEN 1 ELSE 0 END , 'Employees' ) will count the distinct employees returning 1 **and** the distinct employees returning 0. | ||
| 1795 | |||
| 1796 | === Average === | ||
| 1797 | |||
| 1798 | Average( <Expression> ) | ||
| 1799 | //Returns the average of all values in the specified expression (field). This only returns the average of fields that do not contain NULLs.// | ||
| 1800 | |||
| 1801 | **This option is only available when using the Row Total Total Type.** | ||
| 1802 | |||
| 1803 | **Arguments** | ||
| 1804 | The expression should be a numeric field. | ||
| 1805 | |||
| 1806 | **Examples** | ||
| 1807 | Average(Total_Value) | ||
| 1808 | |||
| 1809 | === AverageAll === | ||
| 1810 | |||
| 1811 | AverageAll( <Expression> ) | ||
| 1812 | //Returns the average of all values in the specified expression (field). This returns the average of ALL fields including those that contain NULLs.// | ||
| 1813 | |||
| 1814 | **This option is only available when using the Row Total Total Type.** | ||
| 1815 | |||
| 1816 | **Arguments** | ||
| 1817 | The expression should be a numeric field. | ||
| 1818 | |||
| 1819 | **Examples** | ||
| 1820 | AverageAll(Total_Value) | ||
| 1821 | |||
| 1822 | === PercentileSum === | ||
| 1823 | |||
| 1824 | PercentileSum(<Expression> ,<Expression> ,<Expression> ) | ||
| 1825 | //Returns the sum of n% of a specified expression (field).// | ||
| 1826 | |||
| 1827 | **Arguments** | ||
| 1828 | The first expression should be a numeric field, the second expression should be numeric and is the start point, in %, of the range to be used, and the third expression should be numeric and is the end point, in %, of the range to be used. | ||
| 1829 | |||
| 1830 | **Examples** | ||
| 1831 | To return the sum of the top 10% of values: | ||
| 1832 | PercentileSum(Sale_Price, 90, 100) | ||
| 1833 | |||
| 1834 | To return the sum of the bottom 25% of values: | ||
| 1835 | PercentileSum(Sale_Price, 0, 25) | ||
| 1836 | |||
| 1837 | === PercentileValue === | ||
| 1838 | |||
| 1839 | PercentileValue(<Expression> ,<Expression> ) | ||
| 1840 | //Returns the percentile value of the specified expression (field). This is the value below which a given percentage of observations in a group of observations falls. For example, the 20th percentile is the value below which 20% of the observations may be found.// | ||
| 1841 | |||
| 1842 | **Arguments** | ||
| 1843 | The first expression should be a numeric field and the second expression should be a numeric value that specifies the percentile value to be used by the function. | ||
| 1844 | |||
| 1845 | **Examples** | ||
| 1846 | To return the limit of the lower quartile (bottom 25%) of values: | ||
| 1847 | PercentileValue(Sale_Price, 25) | ||
| 1848 | |||
| 1849 | To return the limit of the median (bottom 50%) of values: | ||
| 1850 | PercentileValue(Sale_Price, 50) | ||
| 1851 | |||
| 1852 | === PercentileAverage === | ||
| 1853 | |||
| 1854 | PercentileAverage(<Expression> ,<Expression> ,<Expression>) | ||
| 1855 | //Returns the average of the values that are between a percentile range given for the specified expression (field).// | ||
| 1856 | |||
| 1857 | **Arguments** | ||
| 1858 | The first expression should be a numeric field, the second expression should be a numeric value that specifies the lower percentile value to be used by the function and the third expression should be a numeric value that specifies the upper percentile value to be used. | ||
| 1859 | |||
| 1860 | **Examples** | ||
| 1861 | To return the average of the lower quartile (bottom 25%) of values: | ||
| 1862 | PercentileAverage(Sale_Price, 0, 25) | ||
| 1863 | |||
| 1864 | To return the average of the values between the 25th percentile and the 50th percentile: | ||
| 1865 | PercentileAverage(Sale_Price, 25, 50) | ||
| 1866 | |||
| 1867 | === PercentileCount === | ||
| 1868 | |||
| 1869 | PercentileSum (<Expression> ,<Expression> ,<Expression>) | ||
| 1870 | //Returns the number of values that are between a percentile range given for the specified expression (field).// | ||
| 1871 | |||
| 1872 | **Arguments** | ||
| 1873 | The first expression should be a numeric field, the second expression should be a numeric value that specifies the lower percentile value to be used by the function and the third expression should be a numeric value that specifies the upper percentile value to be used. | ||
| 1874 | |||
| 1875 | **Examples** | ||
| 1876 | To return the number of values in the lower quartile (bottom 25%) of values: | ||
| 1877 | PercentileCount(Sale_Price, 0, 25) | ||
| 1878 | |||
| 1879 | To return the number of values between the 25th percentile and the 50th percentile: | ||
| 1880 | PercentileCount(Sale_Price, 25, 50) | ||
| 1881 | |||
| 1882 | === PercentileMin === | ||
| 1883 | |||
| 1884 | PercentileMin (<Expression> ,<Expression> ,<Expression>) | ||
| 1885 | //Returns the Minimum data value within a percentile range given for the specified expression (field).// | ||
| 1886 | |||
| 1887 | **Arguments** | ||
| 1888 | The first expression should be a numeric field, the second expression should be a numeric value that specifies the lower percentile value to be used by the function and the third expression should be a numeric value that specifies the upper percentile value to be used. | ||
| 1889 | |||
| 1890 | **Examples** | ||
| 1891 | To return the Minimum data value of the lower quartile (bottom 25%) of values: | ||
| 1892 | PercentileMin(Sale_Price, 0, 25) | ||
| 1893 | |||
| 1894 | To return the Minimum data value between the 25th percentile and the 50th percentile: | ||
| 1895 | PercentileMin(Sale_Price, 25, 50) | ||
| 1896 | |||
| 1897 | === PercentileMax === | ||
| 1898 | |||
| 1899 | PercentileMax (<Expression> ,<Expression> ,<Expression>) | ||
| 1900 | //Returns the Maximum data value within a percentile range given for the specified expression (field).// | ||
| 1901 | |||
| 1902 | **Arguments** | ||
| 1903 | The first expression should be a numeric field, the second expression should be a numeric value that specifies the lower percentile value to be used by the function and the third expression should be a numeric value that specifies the upper percentile value to be used. | ||
| 1904 | |||
| 1905 | **Examples** | ||
| 1906 | To return the Maximum data value of the lower quartile (bottom 25%) of values: | ||
| 1907 | PercentileMax(Sale_Price, 0, 25) | ||
| 1908 | |||
| 1909 | To return the Maximum data value between the 25th percentile and the 50th percentile: | ||
| 1910 | PercentileMax(Sale_Price, 25, 50) | ||
| 1911 | |||
| 1912 | === Sum === | ||
| 1913 | |||
| 1914 | Sum( <Expression> ) | ||
| 1915 | //Returns the sum of the values in the specified expression (field).// | ||
| 1916 | |||
| 1917 | **This option is only available when using the RowTotal total type.** | ||
| 1918 | |||
| 1919 | **Arguments** | ||
| 1920 | The expression should be a numeric field. | ||
| 1921 | |||
| 1922 | **Examples** | ||
| 1923 | Sum(Total_Value) | ||
| 1924 | |||
| 1925 | 7.5.9 CountDistinct / SumDistinct | ||
| 1926 | CountDistinct( <Expression> , <String Expression> ) | ||
| 1927 | //Returns the distinct count from a dynamic view following the specified calculation logic.// | ||
| 1928 | |||
| 1929 | SumDistinct( <Expression> , <String Expression> ) | ||
| 1930 | //Sums the distinct count from a dynamic view following the specified calculation logic.// | ||
| 1931 | |||
| 1932 | **Arguments** | ||
| 1933 | The expression represents the calculation logic and the string expression is the name of the dynamic view in single quotes. Dynamic Views can be selected from the **Values** drop-down list. | ||
| 1934 | |||
| 1935 | When using the Dynamic View drop-down list functionality in a standard total, the distinct count is run against the records before any calculation logic is applied. In some circumstances, this may remove records of interest. By using either calculation, the distinct count is run against the records after the calculation logic has been applied. | ||
| 1936 | |||
| 1937 | === SumDistinct === | ||
| 1938 | |||
| 1939 | SumDistinct( <Expression>, <String Expression> ) | ||
| 1940 | //Returns a distinct sum based on the value in the expression and the dynamic view being referenced.// | ||
| 1941 | |||
| 1942 | **Arguments** | ||
| 1943 | The expression output should be a numeric field. | ||
| 1944 | |||
| 1945 | **Examples** | ||
| 1946 | To return the number of employees who have handled a cash transaction: | ||
| 1947 | SumDistinct( CASE WHEN MOP = 'Cash' THEN Line_Price END , 'Employees' ) | ||
| 1948 | |||
| 1949 | === Max === | ||
| 1950 | |||
| 1951 | Max( <Expression>, <Expression>, TRUE ) | ||
| 1952 | //Returns the maximum value of two aggregations (from the same or different totals).// | ||
| 1953 | |||
| 1954 | **Arguments** | ||
| 1955 | The expressions should be a numeric values. They need to refer to the runtime cell position (starting position being 0) of an aggregated value. | ||
| 1956 | |||
| 1957 | **Examples** | ||
| 1958 | To return the maximum sales value of the years 2021 (position 3) and 2022 (position 4) in the Crosstab below, you would use the following syntax: | ||
| 1959 | Max( 3 , 4 , TRUE ) | ||
| 1960 | |||
| 1961 | [[image:Screenshot 2022-05-19 at 12.44.30.png||height="173" width="549"]] | ||
| 1962 | |||
| 1963 | === Min === | ||
| 1964 | |||
| 1965 | Min( <Expression>, <Expression>, TRUE ) | ||
| 1966 | //Returns the minimum value of two aggregations (from the same or different totals).// | ||
| 1967 | |||
| 1968 | **Arguments** | ||
| 1969 | The expressions should be a numeric values. They need to refer to the runtime cell position (starting position being 0) of an aggregated value. | ||
| 1970 | |||
| 1971 | **Examples** | ||
| 1972 | To return the minimum sales value of the years 2021 (position 3) and 2022 (position 4) in the Crosstab below, you would use the following syntax: | ||
| 1973 | Min( 3 , 4 , TRUE ) | ||
| 1974 | |||
| 1975 | [[image:Screenshot 2022-05-19 at 12.41.04.png||height="173" width="549"]] | ||
| 1976 | |||
| 1977 | == Miscellaneous Functions == | ||
| 1978 | |||
| 1979 | === FORMFIELD === | ||
| 1980 | |||
| 1981 | The following function is available for Crosstabs only and allow users to reference a filter, or elements of a filter, rather than allowing the filter to filter the data in the report. | ||
| 1982 | |||
| 1983 | FORMFIELD^<Identifier> | ||
| 1984 | //Returns the value of a filter.// | ||
| 1985 | |||
| 1986 | **Arguments** | ||
| 1987 | The expression should be the same as the data type of the filter. Filters must be referenced using double quotes ("). | ||
| 1988 | |||
| 1989 | **Examples** | ||
| 1990 | CASE WHEN ToMonth( Transaction_Month ) = ToMonth( FORMFIELD^"Transaction Month" ) && ToYear( Transaction_Year ) = ToYear( FORMFIELD^"Transaction Year" ) THEN Line_Price END | ||
| 1991 | |||
| 1992 | By enabling the Ignore option for the Transaction Month filter, changing its value will only affect this single total in the report. | ||
| 1993 | |||
| 1994 | To reference the higher and lower values from a range filter, enter ^HIGH and ^LOW, respectively, after the filter name. For example: | ||
| 1995 | |||
| 1996 | CASE WHEN Transaction_Date BETWEEN FORMFIELD^"Transaction Date"^LOW AND FORMFIELD^"Transaction Date"^HIGH THEN Cost_Price END | ||
| 1997 | |||
| 1998 | To reference FORMFIELD values in a multi-select drop list use the In() function. For example: | ||
| 1999 | |||
| 2000 | CASE WHEN In(FORMFIELD^"Product Group",Product_Group) THEN 1 END | ||
| 2001 | |||
| 2002 | For more FORMFIELD examples, please refer to the [[Crosstab Reporting Guide>>doc:Technical Documentation.CXAIR.Reporting Guides.09a\. Crosstab Reporting Guide.WebHome]]. | ||
| 2003 | |||
| 2004 | === Cell Referencing === | ||
| 2005 | |||
| 2006 | The following syntax is available for Cell/Total Calculations only and allow users to reference a cell in a Crosstab. | ||
| 2007 | |||
| 2008 | Sum(rows(<Row Name>),columns(<Column Name>),<Total Position>) | ||
| 2009 | //Returns the value of a cell.// | ||
| 2010 | |||
| 2011 | **Arguments** | ||
| 2012 | Note: this option is not available in the Functions drop list. | ||
| 2013 | |||
| 2014 | The syntax has to start with **Sum**. You can either reference a Row or a Column or both. Totals start at position 0 (zero). | ||
| 2015 | |||
| 2016 | **Example** | ||
| 2017 | For a Crosstab with Provinces as rows and Customer Segments as columns with 2 totals (Count and Sales). I can references the Ontario Corporate Sales by using: | ||
| 2018 | |||
| 2019 | Sum(rows('Ontario'),columns('Corporate'),1) | ||
| 2020 | |||
| 2021 | == String Calculation == | ||
| 2022 | |||
| 2023 | Allows a custom phrase to be displayed in a report and aggregation tooltips. | ||
| 2024 | |||
| 2025 | **Arguments** | ||
| 2026 | The phrase must be punctuated using double quotes ("). | ||
| 2027 | |||
| 2028 | **Examples** | ||
| 2029 | CASE WHEN 'Total' > 100 THEN "Check Source Data" END | ||
| 2030 | |||
| 2031 | To utilise String Calculations as part of an aggregation tooltip, navigate to the Tooltips tab of a total and click the New Tooltip button under the Aggregation Tooltips heading and select the relevant String Calculation total. | ||
| 2032 | |||
| 2033 | The following example utilises four totals: a count of transactions, % branded products sold, row count, average amount of branded items sold and the following String Calculation: | ||
| 2034 | |||
| 2035 | CASE | ||
| 2036 | WHEN Transactions < 100000 && '% Branded Products' < 'Branded Average' | ||
| 2037 | THEN 'Transactions' + " is quite a low value and the % branded sales (" +'% Branded Products' + ") is lower than the average of " + 'Branded Average' | ||
| 2038 | END | ||
| 2039 | |||
| 2040 | By referencing totals as part of the string values, the tooltip will display the hard-coded text alongside the dynamic aggregation values. | ||
| 2041 | |||
| 2042 | For more information regarding the make-up of this report, please refer to the [[Crosstab Reporting Guide>>doc:Technical Documentation.CXAIR.Reporting Guides.09a\. Crosstab Reporting Guide.WebHome]], where a detailed breakdown is available. |