-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Documentation for the Keep Sorting and Filtering preference (#141) * Correct incremental-refresh.md * Update xmla-as-connectivity.md * Update incremental-refresh-setup.md Corrected misspelled word * Update dax-query.md Added a description of the new "Keep Sorting and Filtering" and its possible values. * Update the screenshot with the new preference Update the screenshot with the new Keep Sorting and Filtering preference in the Dax Query toolbar * Correct the image for the new preference * Correct png image * Update dax-query.md Updated the description of all the options in the DAX Query toolbar * Update dax-query.md Bold the bullet points titles for the different Keep Sorting and Filtering preferences * Transferable clarification (#142) * Update editions.md * Update editions.md * Add KB articles for each code action (#143) * initial work on KB articles for code actions (BPA rules to come later) * more code actions docs * additional KB docs * added additional KB docs * added remaining KB docs for all code actions in the "Improvements" and "Readability" categories * add missing kb articles * clarifications * revert deletion (#144) * User do/kb article uppercase (#145) * delete kb articles * re-add files with uppercase file name * added section about c# script limitations (#146) * Update code-actions.md (#147) typos and grammar --------- Co-authored-by: Maria José Ferreira <[email protected]> Co-authored-by: Daniel Otykier <[email protected]>
- Loading branch information
1 parent
6f1fe36
commit 06f37c2
Showing
38 changed files
with
1,371 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
uid: DI001 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Remove unused variable | ||
author: Daniel Otykier | ||
updated: 2024-12-19 | ||
--- | ||
|
||
Code action `DI001` (Improvement) **Remove unused variable** | ||
|
||
## Description | ||
|
||
Variables that are not being referenced anywhere, should be removed. | ||
|
||
## Example | ||
|
||
Change: | ||
```dax | ||
VAR _internetSalesTaxed = [Internet Sales] * 1.25 | ||
VAR _cogsTaxed = [Cost of Sales] * 1.25 | ||
VAR _internetSales = [Internet Sales] | ||
RETURN _internetSalesTaxed - _cogsTaxed | ||
``` | ||
To: | ||
```dax | ||
VAR _internetSalesTaxed = [Internet Sales] * 1.25 | ||
VAR _cogsTaxed = [Cost of Sales] * 1.25 | ||
RETURN _internetSalesTaxed - _cogsTaxed | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
Unused variables can make your code harder to read and understand. By removing them, you make your code more concise and easier to maintain. | ||
|
||
An unused variable is also an indication that the code may contain a mistake, or that the variable was intended to be used for something that was later removed. By removing the variable, you avoid potential confusion for other developers who may be reading your code. | ||
|
||
## Related to: | ||
|
||
- [DI002 - Remove all unused variables](xref:DI002) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
uid: DI002 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Remove unused variable | ||
author: Daniel Otykier | ||
updated: 2024-12-19 | ||
--- | ||
|
||
Code action `DI002` (Improvement) **Remove all unused variables** | ||
|
||
## Description | ||
|
||
Variables that are not being used (directly or indirectly through other variables) in the `RETURN` part of a variable block, should be removed. | ||
|
||
## Example | ||
|
||
Change: | ||
```dax | ||
VAR _internetSalesTaxed = [Internet Sales] * 1.25 | ||
VAR _cogs = [Cost of Sales] | ||
VAR _cogsTaxed = _cogs * 1.25 | ||
RETURN _internetSalesTaxed | ||
``` | ||
To: | ||
```dax | ||
VAR _internetSalesTaxed = [Internet Sales] * 1.25 | ||
RETURN _internetSalesTaxed | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
Unused variables can make your code harder to read and understand. By removing them, you make your code more concise and easier to maintain. | ||
|
||
An unused variable is also an indication that the code may contain a mistake, or that the variable was intended to be used for something that was later removed. By removing the variable, you avoid potential confusion for other developers who may be reading your code. | ||
|
||
If a variable is referenced by other variables, but none of the variables are used in the `RETURN` part of the variable block, it is safe to remove all of them. | ||
|
||
## Remarks | ||
|
||
This code action has an **(All occurrences)** variant, which will appear when multiple sections of code can be improved. This variant will apply the code action to all relevant sections of the document at once. | ||
|
||
## Related to: | ||
|
||
- [DI001 - Remove unused variable](xref:DI001) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
--- | ||
uid: DI003 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Remove table name | ||
author: Daniel Otykier | ||
updated: 2024-12-19 | ||
--- | ||
|
||
Code action `DI003` (Improvement) **Remove table name from measure references** | ||
|
||
## Description | ||
|
||
Measure references should not include the table name, as the table name is unnecessary when referencing measures. | ||
|
||
## Example | ||
|
||
Change: | ||
```dax | ||
'Internet Sales'[Internet Total Sales] * 1.25 | ||
``` | ||
To: | ||
```dax | ||
[Internet Total Sales] * 1.25 | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
In most situations, *column references* **must** be qualified by the table name. However, for *measure references*, the table name is always optional (since measure names are always unique within a model). | ||
|
||
Thus, a best practice is to always reference measures *without* the table name, and always reference columns *with* the table name. | ||
|
||
By applying this practice consistently, you make your code more concise and easier to read, and you make it easier to distinguish between measure references and column references. | ||
|
||
## Remarks | ||
|
||
This code action has an **(All occurrences)** variant, which will appear when multiple sections of code can be improved. This variant will apply the code action to all relevant sections of the document at once. | ||
|
||
## Related to: | ||
|
||
- [DI004 - Add table name to column references](xref:DI004) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
--- | ||
uid: DI004 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Add table name | ||
author: Daniel Otykier | ||
updated: 2024-12-19 | ||
--- | ||
|
||
Code action `DI004` (Improvement) **Add table name to column references** | ||
|
||
## Description | ||
|
||
Column references should always include the table name to avoid ambiguities, even when the table name is optional. | ||
|
||
## Example | ||
|
||
Change: | ||
```dax | ||
SUMX('Internet Sales', [Line Amount] * [Quantity]) | ||
``` | ||
To: | ||
```dax | ||
SUMX('Internet Sales', 'Internet Sales'[Line Amount] * 'Internet Sales'[Quantity]) | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
Since *measure* names are always unique within a model, it is always possible to reference a measure without specifying the table name. However, column names are not unique within a model, and it is therefore necessary to specify the table name when referencing a column, such as when using one of the aggregation functions, i.e.: `SUM('Sales'[Amount])`. | ||
|
||
However, there are situations in which the table qualifier is optional for column references. For example, this is the case when the column exists within an active row context (such as inside a [Calculated Column](https://learn.microsoft.com/en-us/analysis-services/tabular-models/ssas-calculated-columns-create-a-calculated-column?view=asallproducts-allversions)). Even so, providing the table name in this case is still valid, and helps avoid ambiguities and errors in case a measure with the same name is eventually added to the model. | ||
|
||
By applying this practice consistently, you make your code more concise and easier to read, and you make it easier to distinguish between measure references and column references. | ||
|
||
## Remarks | ||
|
||
This code action has an **(All occurrences)** variant, which will appear when multiple sections of code can be improved. This variant will apply the code action to all relevant sections of the document at once. | ||
|
||
## Related to: | ||
|
||
- [DI003 - Remove table name from measure references](xref:DI003) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
--- | ||
uid: DI005 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Rewrite table filter as scalar predicate | ||
author: Daniel Otykier | ||
updated: 2024-12-19 | ||
--- | ||
|
||
Code action `DI005` (Improvement) **Rewrite table filter as scalar predicate** | ||
|
||
## Description | ||
|
||
Rewrite [`CALCULATE`](https://dax.guide/CALCULATE) filter arguments as scalar predicates when possible, instead of using the [`FILTER`](https://dax.guide/FILTER) function. | ||
|
||
## Example 1 | ||
|
||
Change: | ||
```dax | ||
CALCULATE([Total Sales], FILTER(Products, Products[Color] = "Red")) | ||
``` | ||
To: | ||
```dax | ||
CALCULATE([Total Sales], KEEPFILTERS(Products[Color] = "Red")) | ||
``` | ||
|
||
## Example 2 | ||
|
||
Change: | ||
```dax | ||
CALCULATE([Total Sales], FILTER(ALL(Products), Products[Color] = "Red")) | ||
``` | ||
To: | ||
```dax | ||
CALCULATE([Total Sales], Products[Color] = "Red") | ||
``` | ||
|
||
## Example 3 | ||
|
||
Change: | ||
```dax | ||
CALCULATE( | ||
[Total Sales], | ||
FILTER( | ||
ALL(Products), | ||
Products[Color] = "Red" | ||
&& Products[Class] = "High-end" | ||
) | ||
) | ||
``` | ||
To: | ||
```dax | ||
CALCULATE( | ||
[Total Sales], | ||
Products[Color] = "Red", | ||
Products[Class] = "High-end" | ||
) | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
Filtering a table inside a `CALCULATE` filter argument is less efficient than filtering one or more columns from that table. By rewriting the filter as a scalar predicate, you make your code more efficient, consuming less memory and CPU resources. | ||
|
||
For example, an expression such as `FILTER(Sales, < condition >)` will iterate over all rows in the `Sales` table, evaluating the condition for each row. In contrast, an expression such as `Sales[Quantity] > 0` will only iterate over the `Quantity` column, which is much more efficient, and does not cause all the columns from the `Sales` table to be added to the filter context. | ||
|
||
By using scalar predicates, you also make your code more concise and easier to read. | ||
|
||
Behind the scenes, scalar predicates are syntax sugar for a table expression that also uses the `FILTER` function. However, the `FILTER` function is applied to a single column, which is more efficient than filtering the entire table. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
--- | ||
uid: DI006 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Split multi-column filter into multiple filters | ||
author: Daniel Otykier | ||
updated: 2024-12-19 | ||
--- | ||
|
||
Code action `DI006` (Improvement) **Split multi-column filter into multiple filters** | ||
|
||
## Description | ||
|
||
When using a single filter expression that combines multiple columns using `AND` (or the equivalent `&&` operator), better performance can often be achieved by specifying multiple filters, one for each column. | ||
|
||
## Example | ||
|
||
Change: | ||
```dax | ||
CALCULATE([Total Sales], Products[Color] = "Red" && Products[Class] = "High-end") | ||
``` | ||
To: | ||
```dax | ||
CALCULATE([Total Sales], Products[Color] = "Red", Products[Class] = "High-end") | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
Behind the scenes, a scalar predicate gets converted to a table expression that uses the `FILTER` function along with the specified condition. The table resulting from this expression has one column for each column in the filter expression. I.e.: | ||
|
||
```dax | ||
Products[Color] = "Red" && Products[Class] = "High-end" | ||
``` | ||
|
||
becomes: | ||
|
||
```dax | ||
FILTER(ALL(Products[Color], Products[Class]), Products[Color] = "Red" && Products[Class] = "High-end") | ||
``` | ||
|
||
The `ALL` function, when used with multiple column parameters, returns a table with all the unique combinations of the specified columns. This table is then filtered by the specified condition, and the resulting table then applies to the filter context of the `CALCULATE` or `CALCULATETABLE` function. | ||
|
||
However, when all operands in the filter condition are combined using `AND`, it is more efficient to separate these as individual filters. That way, instead of creating a table with all unique combinations of the columns, several smaller tables are created, each with a single column containing only the unique values of that column, that satisfy the filter criteria. This can result in a significant performance improvement, especially when the columns have a high cardinality and low correlation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
--- | ||
uid: DI007 | ||
category: Code actions | ||
sub-category: Improvements | ||
title: Simplify SWITCH statement | ||
author: Daniel Otykier | ||
updated: 2025-01-03 | ||
--- | ||
|
||
Code action `DI007` (Improvement) **Simplify SWITCH statement** | ||
|
||
## Description | ||
|
||
A [`SWITCH`](https://dax.guide/SWITCH) statement that specifies `TRUE()` for the **<Expression>** argument, and where all **<Value>** arguments are simple comparisons of the same variable/measure, can be simplified. | ||
|
||
## Example | ||
|
||
Change: | ||
```dax | ||
SWITCH( | ||
TRUE(), | ||
[Selected Currency] = "EUR", [Total Sales EUR], | ||
[Selected Currency] = "USD", [Total Sales USD], | ||
[Selected Currency] = "DKK", [Total Sales DKK], | ||
[Total Sales] | ||
) | ||
``` | ||
To: | ||
```dax | ||
SWITCH( | ||
[Selected Currency], | ||
"EUR", [Total Sales EUR], | ||
"USD", [Total Sales USD], | ||
"DKK", [Total Sales DKK], | ||
[Total Sales] | ||
) | ||
``` | ||
|
||
## Why is Tabular Editor suggesting this? | ||
|
||
A common DAX pattern to specify a conditional expression with more than 2 conditions, is to use the `SWITCH` statement with `TRUE()` as the first argument. By using this technique, one can then provide condition-expression-pairs for the remaining `SWITCH` arguments. The first condition that evaluates to `TRUE` will determine the result of the `SWITCH` statement. | ||
|
||
However, when all conditions are simple equality comparisons against the same value (`[Selected Currency]` in the example above), the `SWITCH` statement should be simplified to its intended form, where the first argument is the expression to evaluate, and the remaining arguments are pairs of values and results. The first value to match the expression will determine the result of the `SWITCH` statement. |
Oops, something went wrong.