diff --git a/content/localization/de/3_0_10_de.md b/content/localization/de/3_0_10_de.md new file mode 100644 index 00000000..a3d2bdcb --- /dev/null +++ b/content/localization/de/3_0_10_de.md @@ -0,0 +1,50 @@ +# Tabular Editor 3.0.10 + +- Download [Tabular Editor 3.0.10 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.10](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.10 + +- Updated AMO/TOM to version [19.22.5](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Allow incremental search in "Select Item" dialogs, such as when adding tables to a diagram,see issue [#167](https://github.com/TabularEditor/TabularEditor3/issues/167). + +## Bugfixes in 3.0.10 + +- Fixed an issue with TOM Explorer losing current selection when trying to drag an object into a text editor +- Fixed an issue with the semantic analyzer causing false "A single value for column ... cannot be determined" errors, when a DAX expression somewhere in the model used ALLEXCEPT, see [#140](https://github.com/TabularEditor/TabularEditor3/issues/140). +- Macro recorder now works for calculation item expressions, format string expressions, measure detail rows expressions, and more, see [#143](https://github.com/TabularEditor/TabularEditor3/issues/143). +- Added the `Model.AddCalculationGroupTable()` method for C# script purposes. This also fixes issue [#144](https://github.com/TabularEditor/TabularEditor3/issues/144). +- DAX Script should no longer add extra indentation, see [#165](https://github.com/TabularEditor/TabularEditor3/issues/165). +- Fixed Pivot Grid connectivity issues, see [#166](https://github.com/TabularEditor/TabularEditor3/issues/166). +- Fixed issue with VertiPaq Analyzer data types, see [#169](https://github.com/TabularEditor/TabularEditor3/issues/169). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/de/3_0_1_de.md b/content/localization/de/3_0_1_de.md new file mode 100644 index 00000000..434caaaa --- /dev/null +++ b/content/localization/de/3_0_1_de.md @@ -0,0 +1,53 @@ +# Tabular Editor 3.0.1 + +- Download [Tabular Editor 3.0.1](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x86.msi) +- Download [Tabular Editor 3.0.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +## Known issues + +- Table Import Wizard didn't make it to this release. It will be available in 3.0.3 which is coming out very soon. As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## New features in 3.0.1: + +(The list below compares Tabular Editor 3.0.1 with the previous beta release) + +- Updated [EULA](https://tabulareditor.com/tabular-editor-software-license-agreement_ver-1-0/) and added [ThirdPartyNotices.txt](https://github.com/TabularEditor/TabularEditor3/blob/master/ThirdPartyNotices.txt) to installer. +- Schema Compare now also works with Provider (Legacy) Data Sources and Query partitions +- The first time you use the "Format DAX" button, Tabular Editor will ask for your consent to send DAX code to the www.daxformatter.com web service (an upcoming version of Tabular Editor 3 will feature offline DAX code formatting, making this consent obsolete). +- Improved some text strings on the Activation Wizard, and allow entering a new license key if the current license has expired. +- Added Connection String editor to property grid +- Added preferences for globally ignoring certain types of schema differences under Tools > Preferences > Schema Compare. + +## Bugfixes in 3.0.1: + +- Fixed issue [#5](https://github.com/TabularEditor/TabularEditor3/issues/5) +- Fixed issue [#6](https://github.com/TabularEditor/TabularEditor3/issues/6) +- Fixed issue [#7](https://github.com/TabularEditor/TabularEditor3/issues/7) +- Fixed issue [#8](https://github.com/TabularEditor/TabularEditor3/issues/8) +- Fixed issue [#9](https://github.com/TabularEditor/TabularEditor3/issues/9) +- Fixed issue [#13](https://github.com/TabularEditor/TabularEditor3/issues/13) +- Fixed a mapping issue with Update Table Schema (PQ type `decimal.type` now maps to Tabular type `Decimal` instead of `Double`). diff --git a/content/localization/de/3_0_2_de.md b/content/localization/de/3_0_2_de.md new file mode 100644 index 00000000..c20c3f38 --- /dev/null +++ b/content/localization/de/3_0_2_de.md @@ -0,0 +1,51 @@ +# Tabular Editor 3.0.2 + +- Download [Tabular Editor 3.0.2](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x86.msi) +- Download [Tabular Editor 3.0.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +## Known issues + +- Table Import Wizard didn't make it to this release. It will be available in 3.0.3 which is coming out very soon. As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## New features in 3.0.2: + +- You can now change your license key from the Help > About Tabular Editor dialog (option available only when no model is currently loaded). +- Added a "Revert" button in the main toolbar and File menu (you may need to restore the Default workspace to see it). When clicked, this button reloads the TOM from the connected source (Power BI model or Analysis Services database). It can be used to manually synchronize changes between the two, if the automatic option is disabled under Tools > Preferences. + +## Bugfixes in 3.0.2: + +- DAX Editor support for the TEXT / INTEGER keywords in the PATHITEM / PATHITEMREVERSE DAX functions. +- DAX Editor preferences are now persisted between sessions (see [#23](https://github.com/TabularEditor/TabularEditor3/issues/23)) +- Various DAX Editor autocomplete / calltip improvements. +- Fixed issue [#14](https://github.com/TabularEditor/TabularEditor3/issues/14) (object errors not shown in TOM Explorer) +- Support for KMeansClustering DAX extension function. +- Fixed bug with DAX Parser reporting errors on comparing a value with BLANK() in the SWITCH function. +- A few minor visual updates +- Fixed a crash that would occur when trying to execute a DAX script that edits/adds objects that are unsupported on a Power BI Desktop file (for example, [we cannot yet add calculated tables or calculated columns through external tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools)) +- DetailRowsExpressions are now editable on measures when connected to a Power BI Desktop file. +- Fixed a bug with SciLexer.dll that caused a crash immediately upon startup in some cases. +- Column names in the DAX query are now shown as-is (no adding of spaces before capital letters diff --git a/content/localization/de/3_0_3_de.md b/content/localization/de/3_0_3_de.md new file mode 100644 index 00000000..8c973acb --- /dev/null +++ b/content/localization/de/3_0_3_de.md @@ -0,0 +1,51 @@ +# Tabular Editor 3.0.3 + +- Download [Tabular Editor 3.0.3](https://cdn.tabulareditor.com/files/TabularEditor.3.0.3.x86.msi) +- Download [Tabular Editor 3.0.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.3.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## New features in 3.0.3: + +- Right-clicking on an item in the Processing View now lets you requeue that item or, if the item represents a single table, opens a data preview of that table. + +## Bugfixes in 3.0.3: + +- When the semantic analyzer detects an error on a calculated column/calculated table, it no longer modifies the columns on that table (this was previously causing relationships to be dropped in some circumstances) +- Fixed an issue with enabled-state of certain controls on the Find/Replace dialog +- Several bugfixes based on telemetry and error reports, such as: + - Copy/pasting columns with lineage tags now works + - Pasting a table over an existing one when the table is renamed no longer causes a crash + - "Revert" button now reconnects to AS before refresing the local TOM, instead of causing a crash + - Right-clicking in the property grid while it is empty no longer causes a crash + - And many, many others... +- Fixed MRUs not being properly saved for the "Server" dropdown +- Fixed several issues with the Workspace Mode not properly loading data source override values from the User Options file. See [#28](https://github.com/TabularEditor/TabularEditor3/issues/28). +- Fixed and improved several "phantom" DAX semantic errors (support for ROLLUPADDISSUBTOTAL, COUNTROWS with 0 arguments, etc.) +- Improved autocomplete / calltips for several DAX functions (TOPN, TOPNPERLEVEL, interval parameter for DATEADD/DATESINPERIOD/PARALLELPERIOD), after RETURN keyword, etc. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/de/3_0_4_de.md b/content/localization/de/3_0_4_de.md new file mode 100644 index 00000000..a5109c95 --- /dev/null +++ b/content/localization/de/3_0_4_de.md @@ -0,0 +1,55 @@ +# Tabular Editor 3.0.4 + +- Download [Tabular Editor 3.0.4](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x86.msi) +- Download [Tabular Editor 3.0.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Bugfixes in 3.0.4: + +- Refreshing the Best Practice Analyzer no longer causes a crash + +## New features in 3.0.3: + +- Right-clicking on an item in the Processing View now lets you requeue that item or, if the item represents a single table, opens a data preview of that table. + +## Bugfixes in 3.0.3: + +- When the semantic analyzer detects an error on a calculated column/calculated table, it no longer modifies the columns on that table (this was previously causing relationships to be dropped in some circumstances) +- Fixed an issue with enabled-state of certain controls on the Find/Replace dialog +- Several bugfixes based on telemetry and error reports, such as: + - Copy/pasting columns with lineage tags now works + - Pasting a table over an existing one when the table is renamed no longer causes a crash + - "Revert" button now reconnects to AS before refresing the local TOM, instead of causing a crash + - Right-clicking in the property grid while it is empty no longer causes a crash + - And many, many others... +- Fixed MRUs not being properly saved for the "Server" dropdown +- Fixed several issues with the Workspace Mode not properly loading data source override values from the User Options file. See [#28](https://github.com/TabularEditor/TabularEditor3/issues/28). +- Fixed and improved several "phantom" DAX semantic errors (support for ROLLUPADDISSUBTOTAL, COUNTROWS with 0 arguments, etc.) +- Improved autocomplete / calltips for several DAX functions (TOPN, TOPNPERLEVEL, interval parameter for DATEADD/DATESINPERIOD/PARALLELPERIOD), after RETURN keyword, etc. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/de/3_0_5_de.md b/content/localization/de/3_0_5_de.md new file mode 100644 index 00000000..60c2bf50 --- /dev/null +++ b/content/localization/de/3_0_5_de.md @@ -0,0 +1,45 @@ +# Tabular Editor 3.0.5 + +- Download [Tabular Editor 3.0.5](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x86.msi) +- Download [Tabular Editor 3.0.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.5: + +- Diagram view now looks much better (in both light and dark themes), and relationship routes are updated while tables are dragged around on the canvas. + +## Bugfixes in 3.0.5: + +- Expression Editor, if hidden, doesn't automatically pop up when selecting a diagram item / TOM explorer item. Instead, double-click on the item in the TOM Explorer or bring it back using the View menu (see issue [#43](https://github.com/TabularEditor/TabularEditor3/issues/43). +- DAX parser should no longer report circular dependencies when there are none (see issue [#63](https://github.com/TabularEditor/TabularEditor3/issues/63) and [#64](https://github.com/TabularEditor/TabularEditor3/issues/64)) +- Fixed an issue with DAX parser determination of SourceColumn values on CalculatedTableColumns, which could cause columns to be deleted (and by extension, relationships) upon model load. +- DAX parser now shows an error if certain keywords are used as DAX variables (which is not allowed). See issue [#58](https://github.com/TabularEditor/TabularEditor3/issues/58). +- Hitting ':' when starting a search, now immediately switches to "Entire Model" and Dynamic LINQ mode. +- Dynamic LINQ now also search partitions and calculation group items, see issue [#70](https://github.com/TabularEditor/TabularEditor3/issues/70). + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/de/3_0_6_de.md b/content/localization/de/3_0_6_de.md new file mode 100644 index 00000000..99868dec --- /dev/null +++ b/content/localization/de/3_0_6_de.md @@ -0,0 +1,36 @@ +# Tabular Editor 3.0.6 + +- Download [Tabular Editor 3.0.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.6](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.6: + +- Support for consultancy licenses. [More details](https://tabulareditor.com/consultancy-edition/). +- DAX queries now display row counts and timings (see issue [#10](https://github.com/TabularEditor/TabularEditor3/issues/10)) +- DAX queries are now limited to 1000 rows by default, to prevent timeouts/memory issues. This limit can be changed in Tools > Preferences > Data Browsing > DAX Query. +- Columns in the DAX query results can now be sorted and filtered (local sorting/filtering only). See issue [#60](https://github.com/TabularEditor/TabularEditor3/issues/60) +- Data from grids (DAX query results, Table Preview, etc.) can now be copied to the clipboard +- When copying a DAX expression the syntax highlighting is now preserved on the clipboard. See issue [#80](https://github.com/TabularEditor/TabularEditor3/issues/80). +- When adding a calculated table through a C# script expression, the semantic analyzer now immediately adds the calculated table columns to the table based on the DAX expression (instead of after script execution). +- Updated TOM client library to v. 19.22.0.1 +- Portable versions (.zip) now available. Remember that you have to [manually register Tabular Editor 3 with Power BI Desktop](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#registering-external-tools) if using the portable version. + +## Bugfixes in 3.0.6: + +- Can now use the `EvaluateDax`, `ExecuteCommand`, `SelectTable`, `SelectMeasure` etc. methods in C# scripts (similar to Tabular Editor 2.x), see [#44](https://github.com/TabularEditor/TabularEditor3/issues/44). +- The `CustomAction` C# script method now works properly, see [#79](https://github.com/TabularEditor/TabularEditor3/issues/79). +- Better reestablishing of connections to AS (should see fewer "connection lost" crashes) +- Best Practice Analyzer can now be instantiated through a C# script: `new TabularEditor.Shared.BPA.Analyzer();` - this is different than in Tabular Editor 2.x in which the Analyzer class resided in a different namespace. See issue [#45](https://github.com/TabularEditor/TabularEditor3/issues/45) +- Copy operations are now supported when folders are selected, see [#84](https://github.com/TabularEditor/TabularEditor3/issues/84) +- Improved filtering of date columns in the Table Preview, see [#77](https://github.com/TabularEditor/TabularEditor3/issues/77) +- Fixed a bug where semantic engine feature overrides were not in effect, see [#62](https://github.com/TabularEditor/TabularEditor3/issues/62). diff --git a/content/localization/de/3_0_7_de.md b/content/localization/de/3_0_7_de.md new file mode 100644 index 00000000..e3edd498 --- /dev/null +++ b/content/localization/de/3_0_7_de.md @@ -0,0 +1,32 @@ +# Tabular Editor 3.0.7 + +- Download [Tabular Editor 3.0.7 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.7](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.7 + +- Allow using a custom compiler for C# scripts, see issue [#97](https://github.com/TabularEditor/TabularEditor3/issues/97) +- Auto date/time column warnings can now be hidden (under Tools > Preferences > Tabular Editor > Hide auto/date time warnings). See issue [#99](https://github.com/TabularEditor/TabularEditor3/issues/99) + +## Bugfixes in 3.0.7 + +- "Standard Edition" has been renamed to "Business Edition" +- Fixed an issue with the semantic analyzer which would sometimes cause stack overflow exceptions and crash the tool (see issue [#95](https://github.com/TabularEditor/TabularEditor3/issues/95)). +- Fixed an issue with the semantic analyzer which would sometimes report non-existing circular dependency errors. +- Semantic analyzer now supports the SUBSTITUTEWITHINDEX DAX function +- Fixed an issue with some of the JOIN DAX functions (NATURALINNERJOIN, etc.) which would sometimes return the wrong set of columns (see issue [#103](https://github.com/TabularEditor/TabularEditor3/issues/103)) +- Autocomplete now only shows relevant columns/tables in RELATED and RELATEDTABLE (see issue [#112](https://github.com/TabularEditor/TabularEditor3/issues/112)) +- Autocomplete now works with ORDER BY (see issue [#53](https://github.com/TabularEditor/TabularEditor3/issues/53)) +- Editor now longer disappears when creating a folder, copy/pasting a single object, etc. (see issue [#90](https://github.com/TabularEditor/TabularEditor3/issues/90)) +- All relevant context menu items should now show for calculation groups (including refresh options), see issue [#100](https://github.com/TabularEditor/TabularEditor3/issues/100) +- Fixed an issue with DAX queries now returning any results when an ORDER BY statement was added to the query, see issue [#108](https://github.com/TabularEditor/TabularEditor3/issues/108) diff --git a/content/localization/de/3_0_8_de.md b/content/localization/de/3_0_8_de.md new file mode 100644 index 00000000..be62156c --- /dev/null +++ b/content/localization/de/3_0_8_de.md @@ -0,0 +1,59 @@ +# Tabular Editor 3.0.8 + +- Download [Tabular Editor 3.0.8 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.8](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.8 + +- Added option for executing only selected EVALUATE statements in DAX queries (shortcut Shift+F5), see issue [#47](https://github.com/TabularEditor/TabularEditor3/issues/47). +- Allow using shortcut Ctrl+/ to comment/uncomment code, see issue [#46](https://github.com/TabularEditor/TabularEditor3/issues/46). You can also change the comment style (-- or //) under Tools > Preferences > DAX Editor > General. +- DAX Script will now also script measure KPIs, calculated columns and calculated tables in the current selection. We also add comments to make the code more readable (this can be disabled under Tools > Preferences > DAX Scripting). +- There is now an option to automatically add a line break character at the beginning of all DAX expressions, when working against a Power BI model. This makes the code look better in the Power BI Desktop formula bar. This can be disabled under Tools > Preferences >, see issue [#26](https://github.com/TabularEditor/TabularEditor3/issues/26). +- When adding Windows AD Role Members, the Directory Object Picker dialog now appears, see issue [#152](https://github.com/TabularEditor/TabularEditor3/issues/152). +- The "Add Deployment Metadata" option is now available under Tools > Preferences > Model Deployment. +- Pivot Grid improvements: + - You can now drag TOM Explorer objects into all areas of the Pivot Grid, see [#49](https://github.com/TabularEditor/TabularEditor3/issues/49). + - Added TOM Explorer context menu option for adding measures, columns and hierarchies directly to a Pivot Grid. + - Added "Show field" button in Pivot Grid, to display all available fields on the connected database. + - Added a "Go to object" right-click menu option in the Pivot Grid. +- Relationship errors (ambiguous paths, invalid state, etc.) are now detected and indicated in the TOM Explorer + +## Bugfixes in 3.0.8 + +- Changed color of the "Execute query" exclamation mark from red to green. +- Fixed a crash when reversing relationships through the Diagram View +- Fixed an issue with the Relationship Editor where changes are not correctly saved +- Fixed a crash which would occur when TE3 is launched from PBI Desktop while an instance of SSAS is running on the local machine. +- Fixed a bug that prevented creation of new models with a workspace database on Power BI XMLA endpoint. +- Fixed a bug where code selection was cleared after using the Comment action. +- Deployment Wizard now remembers the last server used. +- DAX Script calculated column expressions should no longer give false semantic error messages about missing row context. +- Fixed a bug preventing Business Edition license holders to use the Visual Studio Integrated Workspace server. +- Fixed "successful" typo. +- Fixed an issue with auto formatter sometimes duplicating code when entering a right-parenthesis. +- Added "Save Model.bim backup" option in UI, see issue [#37](https://github.com/TabularEditor/TabularEditor3/issues/37). +- Perspective selection should no longer get "stuck", see issue [#52](https://github.com/TabularEditor/TabularEditor3/issues/52). +- Property grid now properly displays date formatting examples, see issue [#86](https://github.com/TabularEditor/TabularEditor3/issues/86). +- Fixed highlight color when searching, see issue [#98](https://github.com/TabularEditor/TabularEditor3/issues/98). +- "Find All" now works as expected, see issue [#107](https://github.com/TabularEditor/TabularEditor3/issues/107). +- Calculation Item that causes measure data types to decay to Variant is now correctly picked up, see issue [#111](https://github.com/TabularEditor/TabularEditor3/issues/111). +- Fixed false semantic error when using EARLIER in a filter, see issue [#118](https://github.com/TabularEditor/TabularEditor3/issues/118). +- Fixed false semantic error when using KEEPFILTERS, see issue [#122](https://github.com/TabularEditor/TabularEditor3/issues/122). +- Blank (or comment only) Detail Rows Expression no longer causes an error indication, see issue [#127](https://github.com/TabularEditor/TabularEditor3/issues/127). +- Fixed multiple credential prompts, see issue [#131](https://github.com/TabularEditor/TabularEditor3/issues/131). +- Fix vpax import issue, see issue [#133](https://github.com/TabularEditor/TabularEditor3/issues/133). +- Fixed property grid behavior when selecting a display folder, see issue [#134](https://github.com/TabularEditor/TabularEditor3/issues/134). +- Diagram no longer deletes table when hitting "Delete" (remove from diagram instead), see issue [#139 ](https://github.com/TabularEditor/TabularEditor3/issues/139). +- Pivot Grid should now handle date fields correctly, see issue [#142](https://github.com/TabularEditor/TabularEditor3/issues/142). +- Copying a calculation group will no longer create measures with duplicated names, and the precedence number will also be changed to ensure uniqueness, see issue [#155](https://github.com/TabularEditor/TabularEditor3/issues/155) and [#156](https://github.com/TabularEditor/TabularEditor3/issues/156). +- Uncomment Code button now works for lines that have indentation, see [#159](https://github.com/TabularEditor/TabularEditor3/issues/159). diff --git a/content/localization/de/3_0_9_de.md b/content/localization/de/3_0_9_de.md new file mode 100644 index 00000000..02494fd5 --- /dev/null +++ b/content/localization/de/3_0_9_de.md @@ -0,0 +1,63 @@ +# Tabular Editor 3.0.9 + +- Download [Tabular Editor 3.0.9 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.9](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Bugfixes in 3.0.9 + +- Included a missing DLL which would otherwise cause a crash when trying to add role members. + +## Improvements in 3.0.8 + +- Added option for executing only selected EVALUATE statements in DAX queries (shortcut Shift+F5), see issue [#47](https://github.com/TabularEditor/TabularEditor3/issues/47). +- Allow using shortcut Ctrl+/ to comment/uncomment code, see issue [#46](https://github.com/TabularEditor/TabularEditor3/issues/46). You can also change the comment style (-- or //) under Tools > Preferences > DAX Editor > General. +- DAX Script will now also script measure KPIs, calculated columns and calculated tables in the current selection. We also add comments to make the code more readable (this can be disabled under Tools > Preferences > DAX Scripting). +- There is now an option to automatically add a line break character at the beginning of all DAX expressions, when working against a Power BI model. This makes the code look better in the Power BI Desktop formula bar. This can be disabled under Tools > Preferences >, see issue [#26](https://github.com/TabularEditor/TabularEditor3/issues/26). +- When adding Windows AD Role Members, the Directory Object Picker dialog now appears, see issue [#152](https://github.com/TabularEditor/TabularEditor3/issues/152). +- The "Add Deployment Metadata" option is now available under Tools > Preferences > Model Deployment. +- Pivot Grid improvements: + - You can now drag TOM Explorer objects into all areas of the Pivot Grid, see [#49](https://github.com/TabularEditor/TabularEditor3/issues/49). + - Added TOM Explorer context menu option for adding measures, columns and hierarchies directly to a Pivot Grid. + - Added "Show field" button in Pivot Grid, to display all available fields on the connected database. + - Added a "Go to object" right-click menu option in the Pivot Grid. +- Relationship errors (ambiguous paths, invalid state, etc.) are now detected and indicated in the TOM Explorer + +## Bugfixes in 3.0.8 + +- Changed color of the "Execute query" exclamation mark from red to green. +- Fixed a crash when reversing relationships through the Diagram View +- Fixed an issue with the Relationship Editor where changes are not correctly saved +- Fixed a crash which would occur when TE3 is launched from PBI Desktop while an instance of SSAS is running on the local machine. +- Fixed a bug that prevented creation of new models with a workspace database on Power BI XMLA endpoint. +- Fixed a bug where code selection was cleared after using the Comment action. +- Deployment Wizard now remembers the last server used. +- DAX Script calculated column expressions should no longer give false semantic error messages about missing row context. +- Fixed a bug preventing Business Edition license holders to use the Visual Studio Integrated Workspace server. +- Fixed "successful" typo. +- Fixed an issue with auto formatter sometimes duplicating code when entering a right-parenthesis. +- Added "Save Model.bim backup" option in UI, see issue [#37](https://github.com/TabularEditor/TabularEditor3/issues/37). +- Perspective selection should no longer get "stuck", see issue [#52](https://github.com/TabularEditor/TabularEditor3/issues/52). +- Property grid now properly displays date formatting examples, see issue [#86](https://github.com/TabularEditor/TabularEditor3/issues/86). +- Fixed highlight color when searching, see issue [#98](https://github.com/TabularEditor/TabularEditor3/issues/98). +- "Find All" now works as expected, see issue [#107](https://github.com/TabularEditor/TabularEditor3/issues/107). +- Calculation Item that causes measure data types to decay to Variant is now correctly picked up, see issue [#111](https://github.com/TabularEditor/TabularEditor3/issues/111). +- Fixed false semantic error when using EARLIER in a filter, see issue [#118](https://github.com/TabularEditor/TabularEditor3/issues/118). +- Fixed false semantic error when using KEEPFILTERS, see issue [#122](https://github.com/TabularEditor/TabularEditor3/issues/122). +- Blank (or comment only) Detail Rows Expression no longer causes an error indication, see issue [#127](https://github.com/TabularEditor/TabularEditor3/issues/127). +- Fixed multiple credential prompts, see issue [#131](https://github.com/TabularEditor/TabularEditor3/issues/131). +- Fix vpax import issue, see issue [#133](https://github.com/TabularEditor/TabularEditor3/issues/133). +- Fixed property grid behavior when selecting a display folder, see issue [#134](https://github.com/TabularEditor/TabularEditor3/issues/134). +- Diagram no longer deletes table when hitting "Delete" (remove from diagram instead), see issue [#139 ](https://github.com/TabularEditor/TabularEditor3/issues/139). +- Pivot Grid should now handle date fields correctly, see issue [#142](https://github.com/TabularEditor/TabularEditor3/issues/142). +- Copying a calculation group will no longer create measures with duplicated names, and the precedence number will also be changed to ensure uniqueness, see issue [#155](https://github.com/TabularEditor/TabularEditor3/issues/155) and [#156](https://github.com/TabularEditor/TabularEditor3/issues/156). +- Uncomment Code button now works for lines that have indentation, see [#159](https://github.com/TabularEditor/TabularEditor3/issues/159). diff --git a/content/localization/de/3_10_0_de.md b/content/localization/de/3_10_0_de.md new file mode 100644 index 00000000..06fda77e --- /dev/null +++ b/content/localization/de/3_10_0_de.md @@ -0,0 +1,98 @@ +--- +uid: release-3-10-0 +--- + +# Tabular Editor 3.10.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.10.0 downloads: + +- Download [Tabular Editor 3.10.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.10.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.10.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x64.exe) | `478827F7C7096DA96C93CCA2F2232062E8B01E80AA4B698B9F9381C1DA35750B` | +| [TabularEditor.3.10.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.msi) | `4C07502FAB83777D00E8350430B8AA4C34AA0D5A7A134D3224E31C4D856D9156` | +| [TabularEditor.3.10.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.zip) | `8E8B34B768811B814F8254F11BA454EA7D5008F12E0599A9B0F4E159AC6830D0` | +| [TabularEditor.3.10.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x86.exe) | `E7F0D6DA19741C9DB0F75007FCA2302B0B12EF9AFD574F124B969EDC4A301B42` | +| [TabularEditor.3.10.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.msi) | `4D1E832080D763A83EDD0E930204EA86B0D7B946D46CB26593E7BDEE22967C86` | +| [TabularEditor.3.10.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.zip) | `8212D1E12E543AFDB50B0DEA592F9324E4F8F22D63CA067436A0DC3EEF024112` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.10.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/08/23/tabular-editor-3-august-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor now supports adding tables to [Direct Lake datasets](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview) through the Import Table Wizard. Moreover, you can update the schema of existing tables the usual way. Tabular Editor utilises the [SQL endpoint of your Fabric Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-endpoint) to obtain the table schemas. We've also published a [blog post on DirectLake, if you want to learn more](https://blog.tabulareditor.com/2023/08/23/fabric-direct-lake-dataset/). + +> [!NOTE] +> This version of Tabular Editor will let you import tables / update table schemas on models that already have a Direct Lake connection. The Import Table Wizard does not yet support creating a new Direct Lake connection on an empty model. This will be added in a future release. + +> [!WARNING] +> Once you make any changes to a Direct Lake dataset through the XMLA endpoint, you will [no longer be able to open that dataset in the Web Modelling feature of Fabric](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#enable-xmla-read-write:~:text=Direct%20Lake%20datasets%20created%20or%20modified%20by%20using%20XMLA%2Dbased%20tools%20cannot%20be%20opened%20in%20the%20Web%20modelling%20feature.). + +- C# scripts now support [preprocessor directives](xref:csharp-scripts#compatibility) to determine which version of Tabular Editor you're using. This allows you to write scripts that are compatible with both Tabular Editor 2 and Tabular Editor 3. + +## Improvements in 3.10.0 + +- We're now using using the latest version of [AMO/TOM](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/). This update adds support for Binary XML, which should help speed up XMLA operations. More details in this [Microsoft blog post](https://powerbi.microsoft.com/en-us/blog/improving-the-communication-performance-of-xmla-based-tools/). +- We also updated [TMDL to preview-3](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.65.12.3-TmdlPreview), which includes a number of bugfixes. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +- When cloning objects, we now add the suffix "-Copy" instead of " Copy", to reduce the risk of leaving trailing blanks in object names, see [#940](https://github.com/TabularEditor/TabularEditor3/issues/940). +- The auto-complete popup now automatically adjusts its width to fit the widest item inside of it. See [#965](https://github.com/TabularEditor/TabularEditor3/issues/965). +- When a backup .bim file is saved for a Power BI Desktop model, we now use the name of the .pbix file, instead of the database GUID, see [#958](https://github.com/TabularEditor/TabularEditor3/issues/958). +- Table Preview performance improvements. + +## Bugfixes in 3.10.0 + +- Fixed a bug that prevented Synonyms (linguistic metadata) to be persisted, when using Save to Folder. +- Fixed a bug where the backup .bim file had an incorrect timstamp, see [#967](https://github.com/TabularEditor/TabularEditor3/issues/967). +- Fixed a bug that prevented the user from cancelling the deployment when the backup save fails for any reason. +- Find Panel on Table Preview should now generate valid DAX search expressions behind the scenes, see [#955](https://github.com/TabularEditor/TabularEditor3/issues/955). +- Fixed an issue that caused the "Go to definition (F12)" action to be disabled when the caret was placed on a DAX function, see [#962](https://github.com/TabularEditor/TabularEditor3/issues/962). +- Fixed a bug that prevented loading models from .vpax files in some cases. +- The height of the "result count" panel in DAX queries should now automatically adjust to fit its content. +- The Properties grid now correctly displays multi-line expressions that happen to start with one or more line breaks, just like when editing the expression inside the grid. +- Fixed a bug that could cause Pivot Grid to get stuck in an infinite error-message loop, when columns that were added to the Pivot Grid were deleted from the remote model. +- Fixed a bug where macros added to the menu bar, would stop working after a restart of Tabular Editor. +- Fixed a bug where attempting to perform a Schema Update on multiple tables originating from the same source table, would fail for all except one. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_10_1_de.md b/content/localization/de/3_10_1_de.md new file mode 100644 index 00000000..73af292a --- /dev/null +++ b/content/localization/de/3_10_1_de.md @@ -0,0 +1,102 @@ +--- +uid: release-3-10-1 +--- + +# Tabular Editor 3.10.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.10.1 downloads: + +- Download [Tabular Editor 3.10.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.10.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.10.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x64.exe) | `67734FC61247C18E63F29AA4B18D73F05971D688B691F4DBD8246EB15052D999` | +| [TabularEditor.3.10.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.msi) | `3A1967110B8649D06E821F36744199302258B05AD9479F8DE688BEFDAE794E6F` | +| [TabularEditor.3.10.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.zip) | `689ED9836950660B32BB9C29BC91B44B7EA339B8B128E57E2A5A4FCF824B2A04` | +| [TabularEditor.3.10.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x86.exe) | `D7F75E8DDC6F08AE513977AB191F93BC876C94C1555C03CFDD340C3A53CD8F5B` | +| [TabularEditor.3.10.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.msi) | `59CCB76191C3A8A23093CB744B3D9681F5057318EAF4919183182D8557209C9B` | +| [TabularEditor.3.10.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.zip) | `5EDF7A7C37BB5F8F2C78593CA7324B50A6F28DD38334085844478AD44266B8DE` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.10.1 + +- Fixed a bug that caused a crash whenever the user attempted to type a DAX expression in the DAX Debugger's Watch Expression window. + +## New in 3.10.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/08/23/tabular-editor-3-august-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor now supports adding tables to [Direct Lake datasets](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview) through the Import Table Wizard. Moreover, you can update the schema of existing tables the usual way. Tabular Editor utilises the [SQL endpoint of your Fabric Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-endpoint) to obtain the table schemas. We've also published a [blog post on DirectLake, if you want to learn more](https://blog.tabulareditor.com/2023/08/23/fabric-direct-lake-dataset/). + +> [!NOTE] +> This version of Tabular Editor will let you import tables / update table schemas on models that already have a Direct Lake connection. The Import Table Wizard does not yet support creating a new Direct Lake connection on an empty model. This will be added in a future release. + +> [!WARNING] +> Once you make any changes to a Direct Lake dataset through the XMLA endpoint, you will [no longer be able to open that dataset in the Web Modelling feature of Fabric](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#enable-xmla-read-write:~:text=Direct%20Lake%20datasets%20created%20or%20modified%20by%20using%20XMLA%2Dbased%20tools%20cannot%20be%20opened%20in%20the%20Web%20modelling%20feature.). + +- C# scripts now support [preprocessor directives](xref:csharp-scripts#compatibility) to determine which version of Tabular Editor you're using. This allows you to write scripts that are compatible with both Tabular Editor 2 and Tabular Editor 3. + +## Improvements in 3.10.0 + +- We're now using using the latest version of [AMO/TOM](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/). This update adds support for Binary XML, which should help speed up XMLA operations. More details in this [Microsoft blog post](https://powerbi.microsoft.com/en-us/blog/improving-the-communication-performance-of-xmla-based-tools/). +- We also updated [TMDL to preview-3](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.65.12.3-TmdlPreview), which includes a number of bugfixes. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +- When cloning objects, we now add the suffix "-Copy" instead of " Copy", to reduce the risk of leaving trailing blanks in object names, see [#940](https://github.com/TabularEditor/TabularEditor3/issues/940). +- The auto-complete popup now automatically adjusts its width to fit the widest item inside of it. See [#965](https://github.com/TabularEditor/TabularEditor3/issues/965). +- When a backup .bim file is saved for a Power BI Desktop model, we now use the name of the .pbix file, instead of the database GUID, see [#958](https://github.com/TabularEditor/TabularEditor3/issues/958). +- Table Preview performance improvements. + +## Bugfixes in 3.10.0 + +- Fixed a bug that prevented Synonyms (linguistic metadata) to be persisted, when using Save to Folder. +- Fixed a bug where the backup .bim file had an incorrect timstamp, see [#967](https://github.com/TabularEditor/TabularEditor3/issues/967). +- Fixed a bug that prevented the user from cancelling the deployment when the backup save fails for any reason. +- Find Panel on Table Preview should now generate valid DAX search expressions behind the scenes, see [#955](https://github.com/TabularEditor/TabularEditor3/issues/955). +- Fixed an issue that caused the "Go to definition (F12)" action to be disabled when the caret was placed on a DAX function, see [#962](https://github.com/TabularEditor/TabularEditor3/issues/962). +- Fixed a bug that prevented loading models from .vpax files in some cases. +- The height of the "result count" panel in DAX queries should now automatically adjust to fit its content. +- The Properties grid now correctly displays multi-line expressions that happen to start with one or more line breaks, just like when editing the expression inside the grid. +- Fixed a bug that could cause Pivot Grid to get stuck in an infinite error-message loop, when columns that were added to the Pivot Grid were deleted from the remote model. +- Fixed a bug where macros added to the menu bar, would stop working after a restart of Tabular Editor. +- Fixed a bug where attempting to perform a Schema Update on multiple tables originating from the same source table, would fail for all except one. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_11_0_de.md b/content/localization/de/3_11_0_de.md new file mode 100644 index 00000000..582cd62b --- /dev/null +++ b/content/localization/de/3_11_0_de.md @@ -0,0 +1,86 @@ +--- +uid: release-3-11-0 +--- + +# Tabular Editor 3.11.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.11.0 downloads: + +- Download [Tabular Editor 3.11.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.11.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.11.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x64.exe) | `4E65D74F7535F7B5543AA592B2558DA20AA85958D8623558B75E65053BC50D6C` | +| [TabularEditor.3.11.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.msi) | `C334EDD03701D05F25255CE83375C72E0ACEE7866914D382CAC7E0A83B59FD46` | +| [TabularEditor.3.11.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.zip) | `06BA6B064CF193AD435F19999F6F71E54225C6B9BF733C944C8D7DE1834C8BD7` | +| [TabularEditor.3.11.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x86.exe) | `27275F6B65C4B63AE2FC96648BDA74D9A4F860D725DB1188DA7283DF63F5D504` | +| [TabularEditor.3.11.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.msi) | `D654E4A7BF27EAB5C87D1A8A60F1B8BCD6978AED6BF6C47C420B3F22579ACEAE` | +| [TabularEditor.3.11.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.zip) | `3D907626CDCA1DFD9D5CE3A474FFE8574267512C109FC7611A8A3BB020B4B8C9` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.11.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/09/25/september-release-tabular-editor-3-11-0/) to get a brief overview of the most important updates in this release. + +- As noted in [last months' release notes](xref:release-3-10-1), Tabular Editor did not let you create a [Direct Lake dataset](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview) from scratch. This is now possible! The only prerequisite is that the model does not already have any tables or explicit data sources defined, and that its Compatibility Mode is set to PowerBI. Check out our [blog post on DirectLake, if you want to learn more](https://blog.tabulareditor.com/2023/08/23/fabric-direct-lake-dataset/). + +> [!WARNING] +> Once you make any changes to a Direct Lake dataset through the XMLA endpoint, you will [no longer be able to open that dataset in the Web Modelling feature of Fabric](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#enable-xmla-read-write:~:text=Direct%20Lake%20datasets%20created%20or%20modified%20by%20using%20XMLA%2Dbased%20tools%20cannot%20be%20opened%20in%20the%20Web%20modelling%20feature.). + +## Improvements in 3.11.0 + +- We're now using using the latest version of [AMO/TOM](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) and [TMDL](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64), which includes a number of bugfixes and stability improvements. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +- Our DAX parser and autocomplete now supports the newly added 3rd parameter to [`MINX`](https://dax.guide/minx)/[`MAXX`](https://dax.guide/maxx). Moreover, we now also provide suggestions for the [`MATCHBY`](https://dax.guide/matchby) function, which can be used as an optional parameter of window functions. +- The Native Query option of the Table Import Wizard is now available when importing from Databricks, provided a catalog has been specified. + +## Bugfixes in 3.11.0 + +- The list of reserved table names in DAX has been updated using the `$system.discover_keywords` DMV. The consequence is that our built-in DAX formatter now correctly applies quotes on certain table names, which are also reserved words. For example, a reference to a table named `status` will now always be quoted. See [#991](https://github.com/TabularEditor/TabularEditor3/issues/991). +- Autocomplete now suggests proper keywords for the _<Skip>_ parameter of DAX window functions such as [`RANK`](https://dax.guide), etc. +- Batch Rename now works for folders, see [#797](https://github.com/TabularEditor/TabularEditor3/issues/797). +- Fixed some issues regarding custom layouts, see [#711](https://github.com/TabularEditor/TabularEditor3/issues/711). Also fixed an issue where customizations to the built-in menus, were not properly persisted. +- Fixed a bug in the Deployment Wizard, when the model contains an incremental refresh table with no partitions. In this case, the deployment wizard UI did not allow the user to skip partition deployment of this table which would cause an invalid TMSL to be generated generated (one with no partitions for the table in question). +- Fixed a bug, where running a DAX query with no whitespace between [`EVALUATE`](https://dax.guide) and the following expression would cause an error. +- Fixed numerous issues with the DAX debugger. See [#954](https://github.com/TabularEditor/TabularEditor3/issues/954), [#971](https://github.com/TabularEditor/TabularEditor3/issues/971) and [#984](https://github.com/TabularEditor/TabularEditor3/issues/984). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_12_0_de.md b/content/localization/de/3_12_0_de.md new file mode 100644 index 00000000..4363cf27 --- /dev/null +++ b/content/localization/de/3_12_0_de.md @@ -0,0 +1,97 @@ +--- +uid: release-3-12-0 +--- + +# Tabular Editor 3.12.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.12.0 downloads: + +- Download [Tabular Editor 3.12.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.12.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.12.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x64.exe) | `EF139EA10FF8D7376B36C505778F4030BF5FE5D4B4976DA6EBA4E594C857CAA4` | +| [TabularEditor.3.12.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.msi) | `12691A728D51D9CA27AEB5D99B8C8C5BC820633AFD1521DDE5AA7CFC7B5C1798` | +| [TabularEditor.3.12.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.zip) | `852F233CEA4724DA492ADD66FB5D1DF5BB6722D08BC04AC35AB37B71255C520F` | +| [TabularEditor.3.12.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x86.exe) | `83CD723B477421834AA640C01887AFC530366E321263E8929D3D12FB77713BB8` | +| [TabularEditor.3.12.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.msi) | `772C7BBA32F5603D51CD16DFB71E0D9CF56D33F34C3FB2E6B99FFDAB018A8CD5` | +| [TabularEditor.3.12.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.zip) | `94CA188CCCF73FC11CCF1862BE68C69475EE7EDAB9C4C03F5DEA25693BF4AE7D` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.12.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/11/27/tabular-editor-3-november-2023-release) to get a brief overview of the most important updates in this release. + +- Tabular Editor now displays a "What's New" page when the application is updated. The page informs you of new Tabular Editor features, along with community updates and other relevant news for Tabular Editor users. If the page is hidden, you can access it from the **Help > What's New**. You can disable this feature by unchecking **Tools > Preferences > Updates and Feedback > Show "What's New" page on startup**. +- When prototyping new measures, it is quite common to specify them within the `DEFINE` block of a DAX query. In this update, we've added an easy way to create/update model measures based on measures defined within the DAX query. On the toolbar, through the **Query** menu, and through the right-click context menu of the DAX query editor, you will see 4 new options light up, which work very similarly to the "Apply" actions in [DAX Scripts](https://docs.tabulareditor.com/te3/features/dax-scripts.html#shortcuts), with the exception that only a measures' name and expression is applied (since it's not possible to specify other properties like Description, Display Folder, etc. through a DAX query). More details in the [blog post](https://blog.tabulareditor.com). +- Please be aware that we're now using a new certificate to sign the binaries, in case your IT organization needs to expclitly approve 3rd party code certificates. The new certificate is issued by [GlobalSign GCC](https://www.globalsign.com/en) and the certificate is issued directly to [Tabular Editor ApS](https://tabulareditor.com/contact). + +## Improvements in 3.12.0 + +- We have hidden the special RowNumber column from the various VertiPaq Analyzer views, to align with other tools (DAX Studio, DAX Optimizer, etc.). +- AMO/TOM has been updated to [19.69.6.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64), meaning Tabular Editor 3 now supports the latest data modelling features. For example, we now support the `Model.DirectLakeBehavior` property, letting you control whether DirectQuery fallback on Direct Lake models should occur or not. +- TMDL has also been updated to the [latest version](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.69.6.2-TmdlPreview). + +> [!NOTE] +> **TMDL is still in preview and should not be used in production.** We're aware of a deserialization issue in AMO/TOM 19.69.6.2, when a table has an incremental refresh policy applied. This will be fixed in the next release of AMO/TOM. + +- You can now create BPA rules that inspect DAX tokens returned from the [`IDaxDependantObject.Tokenize()`](https://docs.tabulareditor.com/api/TabularEditor.TOMWrapper.Utils.DaxDependencyHelper.html#TabularEditor_TOMWrapper_Utils_DaxDependencyHelper_Tokenize_TabularEditor_TOMWrapper_IDaxDependantObject_) method, the same way as in TE2. +- We now show a warning in the DAX editor, when a variable is declared but never used. See [#934](https://github.com/TabularEditor/TabularEditor3/issues/934). Such variables should generally be removed to keep your DAX tidy. +- When importing tables or updating table schema from a T-SQL source, where the partition references a Stored Procedure, we now provide an option to execute the Stored Procedure, in cases where the resulting schema cannot be statically determined. This can happen, for example, when the stored procedure uses temp tables. The user is always prompted with an option to cancel the operation, before the stored procedure is executed. +- Tabular Editor now allows importing tables from Snowflake using Native Query, see [#949](https://github.com/TabularEditor/TabularEditor3/issues/949). **Note:** For this option to be available, you must specify a database name in the Snowflake connection dialog. +- You can now refresh individual tables or partitions in Direct Lake mode (this operation is also known as ["framing"](https://github.com/TabularEditor/TabularEditor3/issues/999)). +- Adding tables to a model in Direct Lake mode, will no longer prompt you for the type of partition to create (defaulting to an Entity Partition in Direct Lake mode). + +## Bugfixes in 3.12.0 + +- Fixed an issue where the **Rename Variable** context menu option would not always be available, see [#692](https://github.com/TabularEditor/TabularEditor3/issues/692). +- Fixed an issue where username/passwords were not properly persisted for ODBC data connections. Tabular Editor will now prompt if the ODBC credentials are missing. +- Fixed an issue where a Snowflake DSI ODBC connection string was not generated correctly, see [#993](https://github.com/TabularEditor/TabularEditor3/issues/993). +- When Tabular Editor generates T-SQL during table import/schema updates, we no longer use the `IIF` keyword, since this is not supported on Azure Synapse (dedicated SQL pools), see [#1007](https://github.com/TabularEditor/TabularEditor3/issues/1007). +- When Tabular Editor generates the deployment TMSL script, we now automatically add a dummy partition to tables governed by incremental refresh, in case no partitions have been defined (otherwise, deployment would fail). +- The Best Practice Analyzer should now gracefully handle BPA rules where the rule expression itself has an error (just like TE2). +- Fixed an issue where the **Last accessed** column of VertiPaq Analyzer did not show correct info. +- Fixed a minor glitch with VertiPaq Analyzer buttons not indicating correct state. +- Emojis in the DAX editor should no longer cause random crashes, although auto-complete, auto-formatting, etc. will still not work. +- Fixed an issue where setting the OLS Column Permission to "None" would cause the TOM Explorer to lock up. +- Fixed a glitch in the "Save as Macro" dialog, which could cause a crash in some cases. +- M partitions containing a comment on the last line should no longer produce an error when performing a schema update through Analysis Services/Power BI, see [#1167](https://github.com/TabularEditor/TabularEditor3/issues/1167). +- The auto-complete popup should now have a suitable width on its first appearance, see [#1152](https://github.com/TabularEditor/TabularEditor3/issues/1152). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_12_1_de.md b/content/localization/de/3_12_1_de.md new file mode 100644 index 00000000..eaa28e59 --- /dev/null +++ b/content/localization/de/3_12_1_de.md @@ -0,0 +1,103 @@ +--- +uid: release-2-12-1 +--- + +# Tabular Editor 3.12.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.12.1 downloads: + +- Download [Tabular Editor 3.12.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.12.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.12.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x64.exe) | `3FEFFC80E6C1C369A35A84624C8AD239A2EA1FDD8DCC5C64517F196302FE9BC4` | +| [TabularEditor.3.12.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.msi) | `BA514787D6602B40B2A281586B8FBD82CA10C877AAB83DCD1D863C8E9E673C63` | +| [TabularEditor.3.12.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.zip) | `1EB42BC752460726DADCBC130EC7E44FA69156542AD3119717245B17E5D139A4` | +| [TabularEditor.3.12.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x86.exe) | `AB68ECA42B80AD9D140E82970E76192BF4C68925A5E0906744EE607A5F9AB5CB` | +| [TabularEditor.3.12.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.msi) | `6D38264E8127CC66959306AE135C7CBAE1B56C1D92D9F291037CF8E1D9750A41` | +| [TabularEditor.3.12.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.zip) | `DA748A8B653A75F8E652EE055E0E47C320640CFCDE9D9140E278DE683EE8DF14` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.12.1 + +- Fixed an issue that caused a crash in the DAX Editor, when typing out new measure definitions in the query, see [#1183](https://github.com/TabularEditor/TabularEditor3/issues/1183). + +*** + +## New in 3.12.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +- Tabular Editor now displays a "What's New" page when the application is updated. The page informs you of new Tabular Editor features, along with community updates and other relevant news for Tabular Editor users. If the page is hidden, you can access it from the **Help > What's New**. You can disable this feature by unchecking **Tools > Preferences > Updates and Feedback > Show "What's New" page on startup**. +- When prototyping new measures, it is quite common to specify them within the `DEFINE` block of a DAX query. In this update, we've added an easy way to create/update model measures based on measures defined within the DAX query. On the toolbar, through the **Query** menu, and through the right-click context menu of the DAX query editor, you will see 4 new options light up, which work very similarly to the "Apply" actions in [DAX Scripts](https://docs.tabulareditor.com/te3/features/dax-scripts.html#shortcuts), with the exception that only a measures' name and expression is applied (since it's not possible to specify other properties like Description, Display Folder, etc. through a DAX query). More details in the [blog post](https://blog.tabulareditor.com). +- Please be aware that we're now using a new certificate to sign the binaries, in case your IT organization needs to expclitly approve 3rd party code certificates. The new certificate is issued by [GlobalSign GCC](https://www.globalsign.com/en) and the certificate is issued directly to [Tabular Editor ApS](https://tabulareditor.com/contact). + +## Improvements in 3.12.0 + +- We have hidden the special RowNumber column from the various VertiPaq Analyzer views, to align with other tools (DAX Studio, DAX Optimizer, etc.). +- AMO/TOM has been updated to [19.69.6.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64), meaning Tabular Editor 3 now supports the latest data modelling features. For example, we now support the `Model.DirectLakeBehavior` property, letting you control whether DirectQuery fallback on Direct Lake models should occur or not. +- TMDL has also been updated to the [latest version](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.69.6.2-TmdlPreview). + +> [!NOTE] +> **TMDL is still in preview and should not be used in production.** We're aware of a deserialization issue in AMO/TOM 19.69.6.2, when a table has an incremental refresh policy applied. This will be fixed in the next release of AMO/TOM. + +- You can now create BPA rules that inspect DAX tokens returned from the [`IDaxDependantObject.Tokenize()`](https://docs.tabulareditor.com/api/TabularEditor.TOMWrapper.Utils.DaxDependencyHelper.html#TabularEditor_TOMWrapper_Utils_DaxDependencyHelper_Tokenize_TabularEditor_TOMWrapper_IDaxDependantObject_) method, the same way as in TE2. +- We now show a warning in the DAX editor, when a variable is declared but never used. See [#934](https://github.com/TabularEditor/TabularEditor3/issues/934). Such variables should generally be removed to keep your DAX tidy. +- When importing tables or updating table schema from a T-SQL source, where the partition references a Stored Procedure, we now provide an option to execute the Stored Procedure, in cases where the resulting schema cannot be statically determined. This can happen, for example, when the stored procedure uses temp tables. The user is always prompted with an option to cancel the operation, before the stored procedure is executed. +- Tabular Editor now allows importing tables from Snowflake using Native Query, see [#949](https://github.com/TabularEditor/TabularEditor3/issues/949). **Note:** For this option to be available, you must specify a database name in the Snowflake connection dialog. +- You can now refresh individual tables or partitions in Direct Lake mode (this operation is also known as ["framing"](https://github.com/TabularEditor/TabularEditor3/issues/999)). +- Adding tables to a model in Direct Lake mode, will no longer prompt you for the type of partition to create (defaulting to an Entity Partition in Direct Lake mode). + +## Bugfixes in 3.12.0 + +- Fixed an issue where the **Rename Variable** context menu option would not always be available, see [#692](https://github.com/TabularEditor/TabularEditor3/issues/692). +- Fixed an issue where username/passwords were not properly persisted for ODBC data connections. Tabular Editor will now prompt if the ODBC credentials are missing. +- Fixed an issue where a Snowflake DSI ODBC connection string was not generated correctly, see [#993](https://github.com/TabularEditor/TabularEditor3/issues/993). +- When Tabular Editor generates T-SQL during table import/schema updates, we no longer use the `IIF` keyword, since this is not supported on Azure Synapse (dedicated SQL pools), see [#1007](https://github.com/TabularEditor/TabularEditor3/issues/1007). +- When Tabular Editor generates the deployment TMSL script, we now automatically add a dummy partition to tables governed by incremental refresh, in case no partitions have been defined (otherwise, deployment would fail). +- The Best Practice Analyzer should now gracefully handle BPA rules where the rule expression itself has an error (just like TE2). +- Fixed an issue where the **Last accessed** column of VertiPaq Analyzer did not show correct info. +- Fixed a minor glitch with VertiPaq Analyzer buttons not indicating correct state. +- Emojis in the DAX editor should no longer cause random crashes, although auto-complete, auto-formatting, etc. will still not work. +- Fixed an issue where setting the OLS Column Permission to "None" would cause the TOM Explorer to lock up. +- Fixed a glitch in the "Save as Macro" dialog, which could cause a crash in some cases. +- M partitions containing a comment on the last line should no longer produce an error when performing a schema update through Analysis Services/Power BI, see [#1167](https://github.com/TabularEditor/TabularEditor3/issues/1167). +- The auto-complete popup should now have a suitable width on its first appearance, see [#1152](https://github.com/TabularEditor/TabularEditor3/issues/1152). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_13_0_de.md b/content/localization/de/3_13_0_de.md new file mode 100644 index 00000000..b6f64ef0 --- /dev/null +++ b/content/localization/de/3_13_0_de.md @@ -0,0 +1,88 @@ +--- +uid: release-3-13-0 +--- + +# Tabular Editor 3.13.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.13.0 downloads: + +- Download [Tabular Editor 3.13.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.13.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.13.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x64.exe) | `7C22DC330D8F1F83C30FB4F84E6A038C1F4E08128BEA293E0559D6C5C2F80671` | +| [TabularEditor.3.13.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.msi) | `582DA8393AE8C51CA0DAC5B6980534957AAF2E729B5E0ECDB2ED943181A5860D` | +| [TabularEditor.3.13.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.zip) | `F7B0CCB25B3CEA478F921AF7C0FDA6979910D17F8BAF321E23986C800978811F` | +| [TabularEditor.3.13.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x86.exe) | `B851EE5B994F69B8BB0D806FA8147D2196D17D395D8D1601CC338E8D343526B1` | +| [TabularEditor.3.13.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.msi) | `30B15436DD7FB1BA8B9FFBEFBAB366A70B3EB21422ACEFE442EFF464E6E7E361` | +| [TabularEditor.3.13.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.zip) | `CED68ECC4821B9A21AB022AD61AB693A1FD4988F8C6D66BEC1B08E941295C7B3` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.13.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/12/15/tabular-editor-3-december-2023-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.13.0 + +- Unused variable warnings are now only shown when the variable declaration block is complete, and only the variable name itself is highlighted. Moreover, there is a new option where you can toggle off these warnings under **Tools > Preferences > DAX Editor > Code Assist**. +- VertiPaq Analyzer in TE3 now uses the same default settings as in DAX Studio. You can also configure the "Read statistics from DirectQuery tables" option now, under **Tools > Preferences > VertiPaq Analyzer**. +- We've made a small change to how the Refresh Policy on a table appears in the **Properties** view, to better align with [TOM](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.table.refreshpolicy?view=analysisservices-dotnet). This change also lets you add annotations/extended properties to Refresh Policies, which previously wasn't possible. C# scripts can still use the Refresh Policy properties directly on the `Table` object, but we recommend updating scripts to access these properties through the `Table.RefreshPolicy` object instead. +- When selecting a table or column in the TOM Explorer, we now highlight (with **bold** font) any relationships the object is involved in, see [#865](https://github.com/TabularEditor/TabularEditor3/issues/865). This feature can be disabled under **Tools > Preferences > TOM Explorer**. +- We now display the main storage mode (Import, DirectQuery, Direct Lake, etc.) of the model, in the title bar. +- In addition to tables, it is now possible to view relationships starting from a specific column in the "Dependencies" view. Right-click on a column and choose "Show dependencies", then choose the "Show relationships starting from this column" option, see [this comment](https://github.com/TabularEditor/TabularEditor3/issues/865#issuecomment-1490782086). +- We now show a warning in the **Messages** view when objects are in an unprocessed state. This applies to both tables, columns and partitions. It also solves [#1153](https://github.com/TabularEditor/TabularEditor3/issues/1153). +- We now show a warning in the **Messages** view when a column uses a sort-by-column that has `IsAvailableInMDX` set to **false** (as this would otherwise produce an error when the model is saved/deployed). See [#868](https://github.com/TabularEditor/TabularEditor3/issues/868). +- We've updated AMO/TOM to use the latest version [19.72.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). This library also includes an updated version of TMDL, which should fix a deserialization issue, when a table has incremental refresh policy applied. +- When serializing a model using TMDL, we now also output a `database.tmdl` file, which contains metadata at the database level (name, compatibility mode, compatibility level, etc.), which should improve the overall TMDL experience. + +> [!NOTE] +> **TMDL is still in preview and should not be used in production, as you may be impacted by breaking changes between updates.** +> If you encounter any issues opening a model that was saved as TMDL with an earlier version of Tabular Editor, a possible fix is to open the model from TMDL using the same earlier version of Tabular Editor, save it as a Model.bim file, and then use the latest version of Tabular Editor to open the Model.bim file and save it back to the TMDL format. + +## Bugfixes in 3.13.0 + +- Fixed an issue where undo'ing (Ctrl+Z) the removal of a Refresh Policy from a table, would not restore the configuration of that Refresh Policy. +- Fixed an issue where the DAX editor auto-complete would suggest incorrect items for window function parameters, when the window function was used as a filter argument for [`CALCULATE`](https://dax.guide/calculate/) or [`CALCULATETABLE`](https://dax.guide/calculatetable/). +- Fixed a bug that prevented adding/removing levels to hierarchies, when connected to an instance of Power BI Desktop, even though this is a [supported modeling operation](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). +- Fixed an issue where the "Calculate" refresh option did not appear for regular tables. +- Fixed an issue where evaluating only the current selection of a DAX Query would not work, if a line comment was directly above the first `EVALUATE` statement in the selection, see [#912](https://github.com/TabularEditor/TabularEditor3/issues/912). +- Tabular Editor should now let you "Open from folder", when the folder contains ".tmdl" files (previous versions of TMDL used the ".tmd" extension). See [#1175](https://github.com/TabularEditor/TabularEditor3/issues/1175). +- The logic for determining if a table is a "Date Table" was a bit too restrictive, which could cause false circular dependency errors in some cases, or incorrect display of overridden filter contexts in the DAX debugger (due to the implicit filter removal associated with date tables). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_14_0_de.md b/content/localization/de/3_14_0_de.md new file mode 100644 index 00000000..21f08807 --- /dev/null +++ b/content/localization/de/3_14_0_de.md @@ -0,0 +1,92 @@ +--- +uid: release-3-14-0 +--- + +# Tabular Editor 3.14.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.14.0 downloads: + +- Download [Tabular Editor 3.14.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.14.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.14.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x64.exe) | `E648B9F735D50B1F253FE6A5EA2FC036810F2C66525609C92D1463219A2EF9C1` | +| [TabularEditor.3.14.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.msi) | `0E3703B392FD8D586687BD31CA870BCB602CFAAAA355343C5229DD69AA54E105` | +| [TabularEditor.3.14.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.zip) | `26A700AF5F2A70107F96A3FDA2A7D66072C2FCD047BF541724A4FFB5B77DEC4A` | +| [TabularEditor.3.14.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x86.exe) | `69EECC729C418707E3472EFC58CD4D68D4B45C82540F9321C22CBA3C7D0D5357` | +| [TabularEditor.3.14.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.msi) | `13F064F0253C05B62F0319FE8C846F913386C31B2ED1103324CD0A52CDD2F353` | +| [TabularEditor.3.14.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.zip) | `2DAFAB4FFC17F42B27313791819A09E5905D65991F9971621BCC636C6422D5F6` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.14.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/02/20/tabular-editor-3-february-2024-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.14.0 + +- Calculated columns now show the "_fx_" glyph in the Table Preview, so they are easier to distinguish from non-calculated columns. +- The DAX query row limiter will now be disabled if a DAX query uses [`TOPN`](https://dax.guide/TOPN) or [`START AT`](https://dax.guide/st/start-at/), to avoid interfering with the returned results. +- The DAX auto-complete feature now supports any scalar expression in the [`ORDER BY`](https://dax.guide/st/order-by/) clause of a DAX query, and will also no longer suggest columns that are already specified earlier in the [`ORDER BY`](https://dax.guide/st/order-by/) clause. +- When importing/updating tables in a Direct Lake model, we now add the same annotations to tables and columns as if the model was created through the Power BI web modelling, ensuring that cross workspace models can refresh without issues, among other things. +- Support for [DAX `INFO` functions](https://powerbi.microsoft.com/en-us/blog/dax-query-view-introduces-new-info-dax-functions/) in editor auto-complete. These functions are only suggested in a DAX query, as they cannot be used in calculated items (e.g., columns, tables) or measures in a model. +- Updated TOM to [19.76.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64) which includes the latest version of TMDL (Preview-9). +- With TMDL Preview-9, we now have a set of new options available, for configuring how the TMDL is serialized. You can find these options under **Tools > Preferences > Save-to-folder** (for any models that were previously saved as TMDL, you can change these settings under **Model > Serialization options**): + +> [!IMPORTANT] +> TMDL is still a preview feature, meaning breaking changes could be introduced between new releases. If you face any issues deserializing a model after upgrading Tabular Editor, rollback to the latest version of Tabular Editor, then temporarily save the model as a regular .bim file, before serializing it to TMDL again using the latest version of Tabular Editor. + +![TMDL serialization settings](https://docs.tabulareditor.com/images/tmdl-options.png) + +> [!NOTE] +> We do not currently have any options available for customizing which objects get serialized as individual files, when using TMDL. If you would like to see this feature, [please let us know](https://github.com/TabularEditor/TabularEditor3/discussions/1198#discussioncomment-8382137)! + +## Bugfixes in 3.14.0 + +- Fixed an issue with Find/Replace unexpectedly searching/performing replaces outside of the current selection. +- Fixed an issue where the DAX autocomplete would not suggest a column after a binary operator, if that column was already used previously in the same filter expression, see [#1156](https://github.com/TabularEditor/TabularEditor3/issues/1156). +- Fixed an issue where unpinning the **Properties View** would cause all layout settings to be reset upon reopening TE3. +- The DAX Semantic Analyzer now properly handles [`ORDER BY`](https://dax.guide/st/order-by/) and [`START AT`](https://dax.guide/st/start-at/) expressions in DAX queries. Moreover, auto-complete works correctly within these clauses, and the automatic row limiter no longer generates invalid DAX when [`START AT`](https://dax.guide/st/start-at/) is present. See [#1182](https://github.com/TabularEditor/TabularEditor3/issues/1182). Lastly, the built-in DAX formatter should no longer crash when formatting a query containing [`START AT`](https://dax.guide/st/start-at/). +- Fixed a bug where the Data Preview grid seemed to support sorting by more than column. In reality, only the first column selected for sorting is effective, since the [`TOPNSKIP`](https://dax.guide/topnskip) function used to query the table does not support sorting on more than column. +- Fixed a bug that would cause documents to get "stuck" when restoring a layout through the **Window** menu. +- Fixed a bug that prevented certain types of errors to be shown in the **TOM Explorer** and the **Messages** view, see [1217](https://github.com/TabularEditor/TabularEditor3/issues/1217). +- Fixed a bug that could cause the application to hang during activation. +- Fixed an issue with extended properties on perspectives not being serialized when using (legacy) "Save to folder", see [#1165](https://github.com/TabularEditor/TabularEditor/issues/1165). +- Entering a '.' (dot) should no longer close the DAX auto-complete popup window when filtering DAX functions that have a dot in their name. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_15_0_de.md b/content/localization/de/3_15_0_de.md new file mode 100644 index 00000000..37452176 --- /dev/null +++ b/content/localization/de/3_15_0_de.md @@ -0,0 +1,97 @@ +--- +uid: release-3-15-0 +--- + +# Tabular Editor 3.15.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.15.0 downloads: + +- Download [Tabular Editor 3.15.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.15.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.15.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x64.exe) | `5E90A3990E015F719CD92B53B54738F26FEEA7826D465E81E815427C9070144F` | +| [TabularEditor.3.15.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.msi) | `A9925DC6E5D5D6AA1A73EBF0F1B385588DD8D4F68A8E950573344FB587ECCFCA` | +| [TabularEditor.3.15.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.zip) | `6CFA5AB78783F406EE511D73F646931A582FD51AEAC31E4AD065240453C7F13E` | +| [TabularEditor.3.15.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x86.exe) | `B8BBA2AFD6AB6277A465E680A3EAA85310BF27D24B23F7CC1B604F92E2D61A29` | +| [TabularEditor.3.15.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.msi) | `2F61FF655EFD4658D16AB69A0CA5BCB6282C4A01B2E355CF9E2EF52A4AF233C4` | +| [TabularEditor.3.15.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.zip) | `A8868D4BBB9D6A5B034B9292CBC395A639A03A7C163AF1EF8A9CA1DBE8F4EA0F` | + +*** + +### Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +## New in 3.15.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/04/24/tabular-editor-3-april-2024-release/) to get a brief overview of the most important updates in this release. + +- We have a new **Preview** feature this month: **DAX Optimizer integration**. If you have a DAX Optimizer account, you can connect to your workspaces, upload VPAX files, and view [DAX Optimizer](https://daxoptimizer.com) results directly in Tabular Editor. [More information](https://docs.tabulareditor.com/te3/features/dax-optimizer-integration). +- We now support adding [Data Coverage Definition expressions](https://learn.microsoft.com/en-us/analysis-services/tom/table-partitions?view=asallproducts-allversions#define-the-data-coverage-of-the-directquery-partition) to partitions in DirectQuery mode. +- Tabular Editor will now add a `__TEdtr` annotation to your model when metadata is saved to disk (either as Model.bim, Database.json or TMDL). This annotation is used by Microsoft for analytics about Tabular Editor usage for semantic models published to a Power BI or Fabric workspace. This annotation may also be required for certain features to work correctly in Power BI / Fabric, when a model was edited using Tabular Editor. +- The **New Model** dialog now has a **Direct Lake** checkbox\*, which will configure the model to use the new Direct Lake storage mode in Fabric. [More information](https://docs.tabulareditor.com/common/Datasets/direct-lake-dataset.html). Moreover, you can now explicitly choose the _Compatibility Mode_ when entering the _Compatibility Level_ manually. +- You can now export [obfuscated VPAX files](https://www.sqlbi.com/blog/marco/2024/03/15/vpax-obfuscator-a-library-to-obfuscate-vpax-files/) using Tabular Editor. This can be helpful when your metadata (object names and DAX expressions) are confidential, but you want to share the VPAX file with a person or service for optimization purposes. Find this option in the **VertiPaq Analyzer** view, on the dropdown next to the **Export** button. + +## Improvements in 3.15.0 + +- We've updated [AMO/TOM to 19.79.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). In this update, a bug that could sometimes cause overlapping policy range partitions to be generated, when invoking the "Apply Refresh Policy" option, has been fixed. +- Default _Compatibility Level_ for new Power BI / Fabric models set to 1605. +- When a Direct Lake model is initially deployed, we now perform an automatic refresh, which is a prerequisite to avoid DirectQuery fallback. Moreover, there is a new option (which is enabled by default), to also perform an automatic refresh whenever a Direct Lake model is saved, when new tables have been added. This preference is located under **Tools > Preferences > Model Deployment > Data Refresh**. +- Add new sorting option when scripting DAX items: when enabling "Sort scripted items alphabetically", all DAX items in the script will be sorted alphabetically by name. +- Add six new editor commands and default keyboard shortcuts to interact with foldable code regions in DAX editors: + - `Editor.Dax.CollapseAllFolds`: collapse/close all foldable regions in the document. Default shortcut: **Ctrl+Alt+[** + - `Editor.Dax.ExpandAllFolds`: expand/open all foldable regions in the document. Default shortcut: **Ctrl+Alt+]** + - `Editor.Dax.ToggleAllFolds`: toggle the state of all foldable regions between expanded and collapsed; this ensures that all folds end up in the same state. Default shortcut: **Ctrl+Alt+;** + - `Editor.Dax.CollapseFold`: collapse/close the foldable region that the cursor is currently positioned in. Default shortcut: **Ctrl+Shift+[** + - `Editor.Dax.ExpandFold`: expand/open the foldable region that the cursor is currently positioned in. Default shortcut: **Ctrl+Shift+]** + - `Editor.Dax.ToggleFold`: toggle the state of the foldable region that the cursor is in between the open and close states. Default shortcut: **Ctrl+Shift+;** +- The DAX editor now lets you delete individual words inside table/column/measure references when using **Ctrl+Backspace** or **Ctrl+Delete**. To delete the full reference, place the cursor at the beginning or end of the reference and use the same shortcuts. +- "database.tmdl" files are now also shown in the **Open Model from File** dialog, in addition to "model.tmdl" files. It doesn't matter which file is opened - Tabular Editor loads the full model metadata from both files in any case. +- When collecting VertiPaq Analyzer statistics for a Direct Lake model, only resident columns are queried by default. This considerable reduces the time it takes to collect statistics for large models. You can still choose to include non-resident columns by changing the **Statistics for Direct Lake models** setting under **Tools > Preferences > VertiPaq Analyzer**. +- Add preferences to control Currency formatting under **'Tools' > 'Preferences' > 'TOM Explorer' > 'Localization'**: previously, currency was hard coded to use a US Dollar symbol ($) at the beginning of the format string. Now, you can select either a standard formatting style from a searchable dropdown, or define your own custom symbol and positioning. + +## Bugfixes in 3.15.0 + +- Fixed an issue where customized keyboard shortcuts for "Editor.Dax.FormatLong" and "Editor.Dax.FormatShort" didn't work. +- Fixed a bug where macros would not be fully loaded, unless the macro definitions in the MacroActions.json file were ordered by macro ID, see [#1151](https://github.com/TabularEditor/TabularEditor3/issues/1151). +- If a table preview fails in the Import Table Wizard, it should now be possible to continue previewing other tables. +- Table previews in the Import Table Wizard, should now work correctly for Fabric Lakehouse SQL endpoints. +- When saving a model as TMDL, the default encoding is now UTF8 without Byte-Order-Marks (BOM), which should be compatible with Power BI Desktop. +- Fixed a bug where URL tooltips on the **What's New** page would linger on the screen. +- The built-in DAX formatter should no longer replace KPI references with their base measure reference. +- Fixed a bug where the "Ignore incremental refresh partitions" and "Ignore lineage tags" serialization settings were not being properly saved. + +\*=Direct Lake models require Fabric workspaces. As such, they are only accessible for Tabular Editor 3 Enterprise Edition customers. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +--- + diff --git a/content/localization/de/3_16_0_de.md b/content/localization/de/3_16_0_de.md new file mode 100644 index 00000000..7b3c4fba --- /dev/null +++ b/content/localization/de/3_16_0_de.md @@ -0,0 +1,99 @@ +--- +uid: release-3-16-0 +--- + +# Tabular Editor 3.16.0 + +## [**Downloads**](#tab/downloads) + +Tabular Editor 3.16.0 downloads: + +- Download [Tabular Editor 3.16.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.16.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.16.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x64.exe) | `95DADC45A7B6B242D1497A34F5B09ACEBE822E2315DEE9E2A4EDFC95B43FDE0F` | +| [TabularEditor.3.16.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.msi) | `BEF1D9CF4F60C09646F3FB4A355FBDC4DF4BA1920481A7AFF3584DBC0314ED6E` | +| [TabularEditor.3.16.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.zip) | `D3CE2DE02C9D68F67746344EAB05F2E5FDD7BB5CC238D0B2132CE5CCB61C729E` | +| [TabularEditor.3.16.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x86.exe) | `AC3CE7829E709A80332679A2FE63F9A5F929F7B235893BCBEE6A561BFA01EC7D` | +| [TabularEditor.3.16.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.msi) | `FF1D1475E129A0C2BFD2F06586428C3922C66CD00278149BDA9DB15167892C70` | +| [TabularEditor.3.16.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.zip) | `B78E689FAF6372FE84A05A97E9B48949F9C4E9CC58EC0C534BEC067627D304D6` | + +*** + +## Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +## New in 3.16.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/06/13/tabular-editor-3-july-2024-release/) to get a brief overview of the most important updates in this release. + +We have substantially overhauled how **Pivot Grids** work in this release. Some highlights include: + +- Pivot Grid layouts can now be saved and loaded to/from files! A new file format, `.te3pivot` is used to store a JSON representation of the Pivot Grid layout. +- Hidden objects (measures, columns, hierarchies) can now be used in a Pivot Grid, and object renames should no longer cause the Pivot Grid to lose its layout or clear any filters. +- A new and improved Pivot Grid **Field List**, which is now shown by default, and provides a more familiar experience when adding fields to the Pivot Grid. + +Head on over to the [Pivot Grid documentation](https://docs.tabulareditor.com/te3/features/pivot-grid.html) to learn more about these changes. + +## Improvements in 3.16.0 + +- Reduced the number of redundant error messages that are shown, when DAX expression contain syntax/semantic errors. +- DAX scripts now support unspecified/empty expressions. This allows you to specify a DAX script that does not modify existing expressions on objects, or a script that explicitly sets an expression to be empty. +- You can now export DAX query results to CSV/Excel. Look for the **Export data** and **Export data (all results)** options under the **Query** menu. +- When exporting VertiPaq Analyzer statistics, we now suggest a default name for the VPAX file based on the database name. +- We changed the default keyboard shortcuts for `Editor.Dax.CollapseAllFolds`, `Editor.Dax.ExpandAllFolds` and `Editor.Dax.ToggleAllFolds` from **Ctrl+Alt+(key)** to **Ctrl+Shift+(key)**. This is to avoid conflicts with certain characters that require the **AltGr** key (which is equivalent to **Ctrl+Alt**) to be typed on non-US keyboards. The **Ctrl+Shift+(key)** shortcuts were previously used by `Editor.Dax.CollapseFold`, `Editor.Dax.ExpandFold` and `Editor.Dax.ToggleFold`. Their defaults have been changed to **Ctrl+(key)**. +- Updated [AMO/TOM to 19.80.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Menus and toolbars are now locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option. +- Our DAX semantic analyzer now supports the `WITH VISUAL SHAPE` syntax used in DAX queries that contain [visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview). Note that debugging such queries is not yet supported (as only measures can be debugged, and visual calculations are not measures). +- Show a warning when debugging a Pivot Grid cell value or DAX query that includes calculation items in the filter context (which the TE3 debugger currently doesn't support). + +## Bugfixes in 3.16.0 + +- Pressing control-key combinations that do not have any keybinding assigned, should no longer cause special control chars to be inserted in code editors. +- Macros that have been modified and saved, should no longer execute multiple times when invoked through the UI. +- The `.Output()` method should now show the output dialog on subsequent macro executions, even when the **Don't show more outputs** option was checked on a previous execution. +- Unquoted table name references that also happen to be DAX keywords (such as `Currency`), will no longer be treated as keywords during auto-formatting (i.e. they will not be capitalized). Moreover, certain object properties in DAX scripts can now also be empty. View the updated [DAX Scripts documentation](https://docs.tabulareditor.com/te3/features/dax-scripts.html) for more information. +- Errors during DAX script execution are now handled gracefully, and the changes made by the script before the error was encountered, are automatically rolled back. +- Fixed a bug where macro buttons assigned to custom toolbars did not persist after restarting the application. +- Fixed a bug that would cause Tabular Editor to crash when using the `ForEach(IEnumerable, Action)` extension method in a C# script. +- Fixed bugs regarding removing/resetting shortcut keys, which did not work correctly for some commands. +- Fixed a bug where the Save button would remain disabled after a refresh operation finishes. +- Fixed a bug where certain actions could cause the **TOM Explorer** to lock up and not behave correctly until the application was restarted. +- Fixed a bug where deleting an object in the **TOM Explorer** would cause the selection to jump to the **Model** node, rather than the closest parent node of the deleted object. +- Fixed several bugs related to Pivot Grids. +- The semantic analyzer should no longer produce false errors when comparing against `BLANK()` in expressions such as `"string value" IN { BLANK() }`. +- Fixed a bug where changing serialization settings did not persist when a model was loaded from a TMDL folder. See [#1285](https://github.com/TabularEditor/TabularEditor3/issues/1285). +- When sorting a column in the Table Preview, where the column has `IsAvailableInMDX = false` (that is, no attribute hierarchies have been created for the column), we will now use `TOPN` queries to preview the data, since `TOPNSKIP` doesn't support sorting by columns with no attribute hierarchies. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_16_1_de.md b/content/localization/de/3_16_1_de.md new file mode 100644 index 00000000..60258642 --- /dev/null +++ b/content/localization/de/3_16_1_de.md @@ -0,0 +1,109 @@ +--- +uid: release-3-16-1 +--- + +# Tabular Editor 3.16.1 + +## [**Downloads**](#tab/downloads) + +Tabular Editor 3.16.1 downloads: + +- Download [Tabular Editor 3.16.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.16.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.16.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x64.exe) | `4B15F2DA8097C7E57A31683B395EAF0BBC9E8ACAC7AF29A2B5018863421C4DBC` | +| [TabularEditor.3.16.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.msi) | `0B9D8C2007227C8242EF96137096C7D968DEE1FABEABC0D6F2E42BBE4C9FEEF3` | +| [TabularEditor.3.16.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.zip) | `12701D66A239697901A26682B040C01053FBBB18784EA67038366ACBC47DF75B` | +| [TabularEditor.3.16.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x86.exe) | `8828CD47EFA8BFFF9B02684D448238B153D57FE573B048A6A629309147672326` | +| [TabularEditor.3.16.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.msi) | `5C005602A10F0C56BE12ABB4DD77F55E9D59C87D826585C9E4DB93A3C6192E91` | +| [TabularEditor.3.16.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.zip) | `CCC8C425C9E604A9A52998143C0BFFC72D6492FD03F65922E1D8B5C60279F254` | + +*** + +## Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +## Bugfixes in 3.16.1 + +- Fixed a bug that prevented saved diagram files (.te3diag) from being opened correctly, see [#1313](https://github.com/TabularEditor/TabularEditor3/issues/1313) + +## Improvements in 3.16.1 + +- DAX query results now use the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. + +*** + +## New in 3.16.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +We have substantially overhauled how **Pivot Grids** work in this release. Some highlights include: + +- Pivot Grid layouts can now be saved and loaded to/from files! A new file format, `.te3pivot` is used to store a JSON representation of the Pivot Grid layout. +- Hidden objects (measures, columns, hierarchies) can now be used in a Pivot Grid, and object renames should no longer cause the Pivot Grid to lose its layout or clear any filters. +- A new and improved Pivot Grid **Field List**, which is now shown by default, and provides a more familiar experience when adding fields to the Pivot Grid. + +Head on over to the [Pivot Grid documentation](https://docs.tabulareditor.com/te3/features/pivot-grid.html) to learn more about these changes. + +## Improvements in 3.16.0 + +- Reduced the number of useless/redundant error messages that are shown, when DAX expression contain syntax/semantic errors. +- DAX scripts now support unspecified/empty expressions. This allows you to specify a DAX script that does not modify existing expressions on objects, or a script that explicitly sets an expression to be empty. +- You can now export DAX query results to CSV/Excel. Look for the **Export data** and **Export data (all results)** options under the **Query** menu. +- When exporting VertiPaq Analyzer statistics, we now suggest a default name for the VPAX file based on the database name. +- We changed the default keyboard shortcuts for `Editor.Dax.CollapseAllFolds`, `Editor.Dax.ExpandAllFolds` and `Editor.Dax.ToggleAllFolds` from **Ctrl+Alt+(key)** to **Ctrl+Shift+(key)**. This is to avoid conflicts with certain characters that require the **AltGr** key (which is equivalent to **Ctrl+Alt**) to be typed on non-US keyboards. The **Ctrl+Shift+(key)** shortcuts were previously used by `Editor.Dax.CollapseFold`, `Editor.Dax.ExpandFold` and `Editor.Dax.ToggleFold`. Their defaults have been changed to **Ctrl+(key)**. +- Updated [AMO/TOM to 19.80.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Menus and toolbars are now locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option. +- Our DAX semantic analyzer now supports the `WITH VISUAL SHAPE` syntax used in DAX queries that contain [visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview). Note that debugging such queries is not yet supported (as only measures can be debugged, and visual calculations are not measures). +- Show a warning when debugging a Pivot Grid cell value or DAX query that includes calculation items in the filter context (which the TE3 debugger currently doesn't support). + +## Bugfixes in 3.16.0 + +- Pressing control-key combinations that do not have any keybinding assigned, should no longer cause special control chars to be inserted in code editors. +- Macros that have been modified and saved, should no longer execute multiple times when invoked through the UI. +- The `.Output()` method should now show the output dialog on subsequent macro executions, even when the **Don't show more outputs** option was checked on a previous execution. +- Unquoted table name references that also happen to be DAX keywords (such as `Currency`), will no longer be treated as keywords during auto-formatting (i.e. they will not be capitalized). Moreover, certain object properties in DAX scripts can now also be empty. View the updated [DAX Scripts documentation](https://docs.tabulareditor.com/te3/features/dax-scripts.html) for more information. +- Errors during DAX script execution are now handled gracefully, and the changes made by the script before the error was encountered, are automatically rolled back. +- Fixed a bug where macro buttons assigned to custom toolbars did not persist after restarting the application. +- Fixed a bug that would cause Tabular Editor to crash when using the `ForEach(IEnumerable, Action)` extension method in a C# script. +- Fixed bugs regarding removing/resetting shortcut keys, which did not work correctly for some commands. +- Fixed a bug where the Save button would remain disabled after a refresh operation finishes. +- Fixed a bug where certain actions could cause the **TOM Explorer** to lock up and not behave correctly until the application was restarted. +- Fixed a bug where deleting an object in the **TOM Explorer** would cause the selection to jump to the **Model** node, rather than the closest parent node of the deleted object. +- Fixed several bugs related to Pivot Grids. +- The semantic analyzer should no longer produce false errors when comparing against `BLANK()` in expressions such as `"string value" IN { BLANK() }`. +- Fixed a bug where changing serialization settings did not persist when a model was loaded from a TMDL folder. See [#1285](https://github.com/TabularEditor/TabularEditor3/issues/1285). +- When sorting a column in the Table Preview, where the column has `IsAvailableInMDX = false` (that is, no attribute hierarchies have been created for the column), we will not fallback to issue `TOPN` queries, since `TOPNSKIP` doesn't support sorting by columns with no attribute hierarchies. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_16_2_de.md b/content/localization/de/3_16_2_de.md new file mode 100644 index 00000000..8cded5ab --- /dev/null +++ b/content/localization/de/3_16_2_de.md @@ -0,0 +1,113 @@ +--- +uid: release-3-16-2 +--- + +# Tabular Editor 3.16.2 + +## [**Downloads**](#tab/downloads) + +Tabular Editor 3.16.2 downloads: + +- Download [Tabular Editor 3.16.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.16.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.16.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x64.exe) | `C689921E84B7FC10E4154EBE117E279E7C08C56BE7859E3FE3ABB0BB78CF532A` | +| [TabularEditor.3.16.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.msi) | `CCDB6707961BC23D2AF25247CF05070FDF2BE92EA96068FF05B2A6228FADD829` | +| [TabularEditor.3.16.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.zip) | `67800E0FC678D534D29DDCB2EA0887062A7F2CD7D8E86F2B158AFCAB48394307` | +| [TabularEditor.3.16.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x86.exe) | `E197015F85F7ED06B53955855F65CF8E89E6DFDEDE4E98C3A25DAE777F7D3F55` | +| [TabularEditor.3.16.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.msi) | `8EE5B7D7A1E94545EC53161F7DF0D2369F0DAB7A568277C060E765B983D6D18E` | +| [TabularEditor.3.16.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.zip) | `C692605E970A0F5B5A37E85C6FD6CFE72AC4D6DFC4B9866899188B7C1AE6EBE6` | + +*** + +## Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +*** + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in 3.16. + +## Improvements in 3.16.2 + +- Rolled back [AMO/TOM to 19.79.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/19.79.1.1), as the 19.80.0 version introduced various issues related to MFA authentication and other XMLA connectivity issues. See [#1317](https://github.com/TabularEditor/TabularEditor3/issues/1317) and [#1322](https://github.com/TabularEditor/TabularEditor3/issues/1322). + +## Bugfixes in 3.16.1 + +- Fixed a bug that prevented saved diagram files (.te3diag) from being opened correctly, see [#1313](https://github.com/TabularEditor/TabularEditor3/issues/1313) + +## Improvements in 3.16.1 + +- DAX query results now show the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. + +## New in 3.16.0 + +We have substantially overhauled how **Pivot Grids** work in this release. Some highlights include: + +- Pivot Grid layouts can now be saved and loaded to/from files! A new file format, `.te3pivot` is used to store a JSON representation of the Pivot Grid layout. +- Hidden objects (measures, columns, hierarchies) can now be used in a Pivot Grid, and object renames should no longer cause the Pivot Grid to lose its layout or clear any filters. +- A new and improved Pivot Grid **Field List**, which is now shown by default, and provides a more familiar experience when adding fields to the Pivot Grid. + +Head on over to the [Pivot Grid documentation](https://docs.tabulareditor.com/te3/features/pivot-grid.html) to learn more about these changes. + +## Improvements in 3.16.0 + +- Reduced the number of useless/redundant error messages that are shown, when DAX expression contain syntax/semantic errors. +- DAX scripts now support unspecified/empty expressions. This allows you to specify a DAX script that does not modify existing expressions on objects, or a script that explicitly sets an expression to be empty. +- You can now export DAX query results to CSV/Excel. Look for the **Export data** and **Export data (all results)** options under the **Query** menu. +- When exporting VertiPaq Analyzer statistics, we now suggest a default name for the VPAX file based on the database name. +- We changed the default keyboard shortcuts for `Editor.Dax.CollapseAllFolds`, `Editor.Dax.ExpandAllFolds` and `Editor.Dax.ToggleAllFolds` from **Ctrl+Alt+(key)** to **Ctrl+Shift+(key)**. This is to avoid conflicts with certain characters that require the **AltGr** key (which is equivalent to **Ctrl+Alt**) to be typed on non-US keyboards. The **Ctrl+Shift+(key)** shortcuts were previously used by `Editor.Dax.CollapseFold`, `Editor.Dax.ExpandFold` and `Editor.Dax.ToggleFold`. Their defaults have been changed to **Ctrl+(key)**. +- Updated [AMO/TOM to 19.80.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Menus and toolbars are now locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option. +- Our DAX semantic analyzer now supports the `WITH VISUAL SHAPE` syntax used in DAX queries that contain [visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview). Note that debugging such queries is not yet supported (as only measures can be debugged, and visual calculations are not measures). +- Show a warning when debugging a Pivot Grid cell value or DAX query that includes calculation items in the filter context (which the TE3 debugger currently doesn't support). + +## Bugfixes in 3.16.0 + +- Pressing control-key combinations that do not have any keybinding assigned, should no longer cause special control chars to be inserted in code editors. +- Macros that have been modified and saved, should no longer execute multiple times when invoked through the UI. +- The `.Output()` method should now show the output dialog on subsequent macro executions, even when the **Don't show more outputs** option was checked on a previous execution. +- Unquoted table name references that also happen to be DAX keywords (such as `Currency`), will no longer be treated as keywords during auto-formatting (i.e. they will not be capitalized). Moreover, certain object properties in DAX scripts can now also be empty. View the updated [DAX Scripts documentation](https://docs.tabulareditor.com/te3/features/dax-scripts.html) for more information. +- Errors during DAX script execution are now handled gracefully, and the changes made by the script before the error was encountered, are automatically rolled back. +- Fixed a bug where macro buttons assigned to custom toolbars did not persist after restarting the application. +- Fixed a bug that would cause Tabular Editor to crash when using the `ForEach(IEnumerable, Action)` extension method in a C# script. +- Fixed bugs regarding removing/resetting shortcut keys, which did not work correctly for some commands. +- Fixed a bug where the Save button would remain disabled after a refresh operation finishes. +- Fixed a bug where certain actions could cause the **TOM Explorer** to lock up and not behave correctly until the application was restarted. +- Fixed a bug where deleting an object in the **TOM Explorer** would cause the selection to jump to the **Model** node, rather than the closest parent node of the deleted object. +- Fixed several bugs related to Pivot Grids. +- The semantic analyzer should no longer produce false errors when comparing against `BLANK()` in expressions such as `"string value" IN { BLANK() }`. +- Fixed a bug where changing serialization settings did not persist when a model was loaded from a TMDL folder. See [#1285](https://github.com/TabularEditor/TabularEditor3/issues/1285). +- When sorting a column in the Table Preview, where the column has `IsAvailableInMDX = false` (that is, no attribute hierarchies have been created for the column), we will not fallback to issue `TOPN` queries, since `TOPNSKIP` doesn't support sorting by columns with no attribute hierarchies. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_17_0_de.md b/content/localization/de/3_17_0_de.md new file mode 100644 index 00000000..b559e81f --- /dev/null +++ b/content/localization/de/3_17_0_de.md @@ -0,0 +1,115 @@ +--- +uid: release-3-17-0 +--- + +# Tabular Editor 3.17.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.17.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.17.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.17.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.msi) + +Tabular Editor 3.17.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.17.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.exe) +- Download [Tabular Editor 3.17.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.17.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `9D0609022B672A1E47FF78D0DE2FA2C1451A1661E41D95391F33E6B5144BC58B` | +| [TabularEditor.3.17.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.msi) | .NET 8 | 64 bit | `8A9768B969A7D22D8956A11C6CF46AF78C6070B7153F08C44576360A7C278421` | +| [TabularEditor.3.17.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.zip) | .NET 8 | 64 bit | `7E279D9395D3F7EB426293589414D520033CE8621C2364882489080D07DB81A1` | +| [TabularEditor.3.17.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `0FAD1867F9496F3DCDC6B31AA163451102C42CFA6C5FE05B89114C76DD568ACA` | +| [TabularEditor.3.17.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.msi) | .NET 8 | 32 bit | `6CFD937E0B69F56800FF0411AAEA65CA2109316D4B1B2231E41634CBCEDDB096` | +| [TabularEditor.3.17.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.zip) | .NET 8 | 32 bit | `A81F137DE5EB572A06DB93865CB75818A595A80B30E486232A395ED5BABD114F` | +| [TabularEditor.3.17.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.exe) | .NET 6 | 64 bit | `4594B299DC4469EB5767F542F7CD242A10A7C89DEB52AE5987DACDE75B7C985C` | +| [TabularEditor.3.17.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.msi) | .NET 6 | 64 bit | `F77CEC56BAA47ACB1B981CB6C4117A4F3BC5C803C65532A7D4AEDFF03EA45E93` | +| [TabularEditor.3.17.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.zip) | .NET 6 | 64 bit | `C5B8A3F5AEBA292E3390036399BDC8551093A9030379D3BE359676EDF660C643` | +| [TabularEditor.3.17.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.exe) | .NET 6 | 32 bit | `34889BAE93D1C1E6C1BD7FCBF7B82F02DE974018B8C123D260EF894D0954F454` | +| [TabularEditor.3.17.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.msi) | .NET 6 | 32 bit | `28D167AF729AB0C1BAD6F76A010F5907DE7A5717B01E0ADAD7CBFB1ADD0E7917` | +| [TabularEditor.3.17.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.zip) | .NET 6 | 32 bit | `DED76DB0F699B6024F1AF768D32DF134B8D5CFED1B33C489FD2BE0349DD931CA` | + +*** + +## New in 3.17.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/08/14/tabular-editor-3-august-2024-release) to get a brief overview of the most important updates in this release. + +- We're excited to let you know, that Tabular Editor 3 is now available for [.NET 8](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8/overview). We will continue to support .NET 6 until the end of 2024, however we recommend switching to the .NET 8 version as soon as possible. In our testing, the .NET 8 version starts up ~20% faster, while also consuming less memory. +- The portable builds of Tabular Editor 3 now include the relevant .NET runtime, so you no longer need to install the .NET 6/8 Windows Desktop runtime separately. + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Improvements in 3.17.0 + +- DAX query results and table previews now show the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. +- Shared expressions can now be excluded from being deployed using the Deployment Wizard. This enhancement allows you to retain existing shared expressions on the destination server as-is, when deploying a model, even if shared expressions were created/deleted/modified in the model being deployed. +- The DAX debugger **Locals** window now lets you "inspect" results, similar to the **Watch** window. By default, inspector results are shown in a popup dialog rather than as a new DAX Query, but you can control this behavior under **Tools > Preferences > DAX Debugger**. Click the magnifying glass icon next to the value in the **Locals** or **Watch** view to inspect the value. See the updated [DAX Debugger documentation](xref:dax-debugger#locals) for more information. +- When debugging a scalar predicate in a filter argument of [`CALCULATE`](https://dax.guide/calculate) or [`CALCULATETABLE`](https://dax.guide/calculatetable), the **Locals** view now shows additional details about the scalar predicate and the resulting filter expression. See the updated [DAX Debugger documentation](xref:dax-debugger#scalar-predicates) for more information. +- DAX scripts can now be applied when the script contains semantic errors. A warning will be shown if there are any semantic errors to make the end user aware if they want to proceed with the current errors or cancel and fix the semantic errors. Syntax errors, on the other hand, will still prevent the script from being applied. +- Added auto-complete support for a few more DAX `INFO.*` functions. +- The DAX Optimizer Integration (Preview) feature now lets you switch between personal or group accounts in group licensing scenarios. You can choose which account you want to use, through the **Options** dropdow menu. See also [#1288](https://github.com/TabularEditor/TabularEditor3/issues/1288). Moreover, you can now change the _Fixed_ or _Ignored_ status of an issue directly from the DAX Optimizer Results view. +- The Table Import Wizard and Update Table Schema feature now supports **Databricks Multicloud**, in addition to **Azure Databricks**. For more information, see the discussion on [#1347](https://github.com/TabularEditor/TabularEditor3/discussions/1347). +- The Preferences for the VertiPaq Analyzer were expanded to configure the column batch size. This preference controls the number of columns processed at a time during column statistics analysis and it can be found under **Tools > Preferences > VertiPaq Analyzer**. The default value for this preference is 50. +- Custom formatting applied to Pivot Grids (icons, data bars, highlighted cells, etc.) is now preserved when the Pivot Grid layout is saved to a file and later reloaded. +- Pivot Grids now also preserve any sorting applied to fields when the grid is refreshed or when the grid layout is saved to a file and later reloaded. + +## Bugfixes in 3.17.0 + +- Fixed an bug introduced in 3.16.0, which caused an application freeze for several seconds after loading a diagram file (.te3diag) +- Fixed an issue that prevented saving the options in the "Find/Replace" dialog box between sessions, when using the "Find all" button. Now, the last search preferences will be retained in the next session. +- Fixed an issue that prevented the deployment of deletions for data sources, roles, and role members to an existing model. Previously, the corresponding checkboxes in the Deployment Wizard were disabled when there were no data sources or roles in the model. Now, these checkboxes remain enabled when deploying changes to an existing model, allowing for the deployment of these object's deletions. +- Fixed an issue that prevented files with the .ovpax extension from opening as a file or model. The possibility to open .ovpax files and models is now supported. +- Fixed a bug where the wrong file type might have been suggested by the file dialog window when exporting obfuscated files from the VertiPaq Analyzer. Now, when exporting an obfuscated file, the save dialog will correctly suggest using the ".ovpax" extension. +- Fixed a bug where toolbar buttons would stay disabled when the Expression Editor was docked as a tool window rather than as a document tab. +- Fixed a bug that prevented opening semantic models saved as ".tmdl" with [Power BI Project files (PBIP)](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview). +- Fixed a bug that caused the application to hang during manual activation. +- Macro recorder should no longer generate duplicate code. Moreover, the recorder should now also generate code when objects are deleted. +- **Auto formatting** settings for **DAX Editors**, including DAX Query, DAX Script, and DAX expressions in the Expression Editor, are now applied instantly, without the need to restart the application. +- Fixed an issue where unchecking the **Encrypt connection** option did not disable encryption in the connection string for Microsoft SQL Server data sources. +- Fixed a bug where ODBC username and password were not added to the connection string when importing tables or updating table schema. This issue would prevent users from importing tables or updating table schema when using ODBC connections against some data sources, such as Snowflake or Oracle. +- Fixed a bug where it was not possible to list the ODBC DSNs when importing tables, if no User DSNs were present on the machine. +- When querying schema information from an ODBC source, we now use various fallbacks, which should improve compatibility with more ODBC drivers, such as the Oracle in OraClient12Home1 driver. +- Fixed a bug where data sources referenced in M queries would appear as implicit data sources in the Import Table Wizard. +- Fixed a bug where some Pivot Grid toolbar buttons would remain disabled, after a Pivot Grid was reloaded from a file. +- Fixed a bug where constants in M expressions (such as `Order.Ascending`) would result in an **Unknown identifier** error, when using the **Update Table Schema** feature. See [#1362](https://github.com/TabularEditor/TabularEditor3/issues/1362). +- When using the DAX `DIVIDE` function with a non-numeric 3rd argument, the DAX parser now correctly determines the resulting data type to be Variant. +- Fixed a bug that prevented Tabular Editor from loading model metadata from a TMDL folder with no database.tmdl file. + +> [!NOTE] +> Microsoft has announced that [TMDL is in GA](https://powerbi.microsoft.com/en-us/blog/announcing-general-availability-of-tabular-model-definition-language-tmdl/) as of August 2nd, 2024. Please note that Tabular Editor 3 is using a version of the [AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/19.79.1.1), which was released before TMDL was announced as GA. This version should still be fully compatible with TMDL, however, we recommend keeping a backup of your TMSL (.bim) files, just in case. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_17_1_de.md b/content/localization/de/3_17_1_de.md new file mode 100644 index 00000000..2d2e31d5 --- /dev/null +++ b/content/localization/de/3_17_1_de.md @@ -0,0 +1,119 @@ +--- +uid: release-3-17-1 +--- + +# Tabular Editor 3.17.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.17.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.17.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.17.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.msi) + +Tabular Editor 3.17.1 **.NET 6** downloads: + +- Download [Tabular Editor 3.17.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.exe) +- Download [Tabular Editor 3.17.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.17.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `484500CF3604481EA6815430FAEFE25239A38AF0718A9C512D162C9CEE54D062` | +| [TabularEditor.3.17.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.msi) | .NET 8 | 64 bit | `F3B299C413B9016737AA355B0122FA70E960878AD5AC741FC8062FCDA4FAB03D` | +| [TabularEditor.3.17.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.zip) | .NET 8 | 64 bit | `3F339FA67969BF2E40C8A1DAAD31CDB138635B3F6B9ACE624CBD4C99EC2150E4` | +| [TabularEditor.3.17.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `27F4720A2A2B8C5374ECD1EE5FF8B8C6CBC18D24871FC189FD31D894C9CF21A4` | +| [TabularEditor.3.17.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.msi) | .NET 8 | 32 bit | `790C81816CD91E2F8AD0550B5425A21751BC62BA2FDA50F09F0FC1FEC8DB00F4` | +| [TabularEditor.3.17.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.zip) | .NET 8 | 32 bit | `3669E1275CB5A9796178BFA12A3BE300FB95E4574EFD196F56301826893282AB` | +| [TabularEditor.3.17.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.exe) | .NET 6 | 64 bit | `1A8D105C0E0568C759B8B927EB33F0E6BB7C65D5670F07A8FC745BAF609227C0` | +| [TabularEditor.3.17.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.msi) | .NET 6 | 64 bit | `E8BFF47E4C023B79C5320291135E9BF498F34F8B86D668E1CA0B04381826DF26` | +| [TabularEditor.3.17.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.zip) | .NET 6 | 64 bit | `DCED49B7C1247FBCF3003FC034A8BCB1760CB7082BC3FB3FA20F9E3041A0C9D4` | +| [TabularEditor.3.17.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.exe) | .NET 6 | 32 bit | `E1795E02E9DD33902BBF5C7ABD8FFD939CFBC9EFFCDFE13888E3AE25B3BFE3EC` | +| [TabularEditor.3.17.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.msi) | .NET 6 | 32 bit | `0194C67FC4F81F9A5AF8A379A75A68F6FE063378887A439F63F18EB43690F866` | +| [TabularEditor.3.17.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.zip) | .NET 6 | 32 bit | `21D1C7DA741D4153694A30588B488FB62D2129B06906E4FC7CA95EB3A063A9F1` | + +*** + +## Bugfixes in 3.17.1 + +- Fixed a bug related to OS regional settings, which would cause a crash upon entering the **Preferences** dialog for the first time. + +## New in 3.17.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/08/14/tabular-editor-3-august-2024-release) to get a brief overview of the most important updates in this release. + +- We're excited to let you know, that Tabular Editor 3 is now available for [.NET 8](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8/overview). We will continue to support .NET 6 until the end of 2024, however we recommend switching to the .NET 8 version as soon as possible. In our testing, the .NET 8 version starts up ~20% faster, while also consuming less memory. +- The portable builds of Tabular Editor 3 now include the relevant .NET runtime, so you no longer need to install the .NET 6/8 Windows Desktop runtime separately. + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Improvements in 3.17.0 + +- DAX query results and table previews now show the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. +- Shared expressions can now be excluded from being deployed using the Deployment Wizard. This enhancement allows you to retain existing shared expressions on the destination server as-is, when deploying a model, even if shared expressions were created/deleted/modified in the model being deployed. +- The DAX debugger **Locals** window now lets you "inspect" results, similar to the **Watch** window. By default, inspector results are shown in a popup dialog rather than as a new DAX Query, but you can control this behavior under **Tools > Preferences > DAX Debugger**. Click the magnifying glass icon next to the value in the **Locals** or **Watch** view to inspect the value. See the updated [DAX Debugger documentation](xref:dax-debugger#locals) for more information. +- When debugging a scalar predicate in a filter argument of [`CALCULATE`](https://dax.guide/calculate) or [`CALCULATETABLE`](https://dax.guide/calculatetable), the **Locals** view now shows additional details about the scalar predicate and the resulting filter expression. See the updated [DAX Debugger documentation](xref:dax-debugger#scalar-predicates) for more information. +- DAX scripts can now be applied when the script contains semantic errors. A warning will be shown if there are any semantic errors to make the end user aware if they want to proceed with the current errors or cancel and fix the semantic errors. Syntax errors, on the other hand, will still prevent the script from being applied. +- Added auto-complete support for a few more DAX `INFO.*` functions. +- The DAX Optimizer Integration (Preview) feature now lets you switch between personal or group accounts in group licensing scenarios. You can choose which account you want to use, through the **Options** dropdow menu. See also [#1288](https://github.com/TabularEditor/TabularEditor3/issues/1288). Moreover, you can now change the _Fixed_ or _Ignored_ status of an issue directly from the DAX Optimizer Results view. +- The Table Import Wizard and Update Table Schema feature now supports **Databricks Multicloud**, in addition to **Azure Databricks**. For more information, see the discussion on [#1347](https://github.com/TabularEditor/TabularEditor3/discussions/1347). +- The Preferences for the VertiPaq Analyzer were expanded to configure the column batch size. This preference controls the number of columns processed at a time during column statistics analysis and it can be found under **Tools > Preferences > VertiPaq Analyzer**. The default value for this preference is 50. +- Custom formatting applied to Pivot Grids (icons, data bars, highlighted cells, etc.) is now preserved when the Pivot Grid layout is saved to a file and later reloaded. +- Pivot Grids now also preserve any sorting applied to fields when the grid is refreshed or when the grid layout is saved to a file and later reloaded. + +## Bugfixes in 3.17.0 + +- Fixed an bug introduced in 3.16.0, which caused an application freeze for several seconds after loading a diagram file (.te3diag) +- Fixed an issue that prevented saving the options in the "Find/Replace" dialog box between sessions, when using the "Find all" button. Now, the last search preferences will be retained in the next session. +- Fixed an issue that prevented the deployment of deletions for data sources, roles, and role members to an existing model. Previously, the corresponding checkboxes in the Deployment Wizard were disabled when there were no data sources or roles in the model. Now, these checkboxes remain enabled when deploying changes to an existing model, allowing for the deployment of these object's deletions. +- Fixed an issue that prevented files with the .ovpax extension from opening as a file or model. The possibility to open .ovpax files and models is now supported. +- Fixed a bug where the wrong file type might have been suggested by the file dialog window when exporting obfuscated files from the VertiPaq Analyzer. Now, when exporting an obfuscated file, the save dialog will correctly suggest using the ".ovpax" extension. +- Fixed a bug where toolbar buttons would stay disabled when the Expression Editor was docked as a tool window rather than as a document tab. +- Fixed a bug that prevented opening semantic models saved as ".tmdl" with [Power BI Project files (PBIP)](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview). +- Fixed a bug that caused the application to hang during manual activation. +- Macro recorder should no longer generate duplicate code. Moreover, the recorder should now also generate code when objects are deleted. +- **Auto formatting** settings for **DAX Editors**, including DAX Query, DAX Script, and DAX expressions in the Expression Editor, are now applied instantly, without the need to restart the application. +- Fixed an issue where unchecking the **Encrypt connection** option did not disable encryption in the connection string for Microsoft SQL Server data sources. +- Fixed a bug where ODBC username and password were not added to the connection string when importing tables or updating table schema. This issue would prevent users from importing tables or updating table schema when using ODBC connections against some data sources, such as Snowflake or Oracle. +- Fixed a bug where it was not possible to list the ODBC DSNs when importing tables, if no User DSNs were present on the machine. +- When querying schema information from an ODBC source, we now use various fallbacks, which should improve compatibility with more ODBC drivers, such as the Oracle in OraClient12Home1 driver. +- Fixed a bug where data sources referenced in M queries would appear as implicit data sources in the Import Table Wizard. +- Fixed a bug where some Pivot Grid toolbar buttons would remain disabled, after a Pivot Grid was reloaded from a file. +- Fixed a bug where constants in M expressions (such as `Order.Ascending`) would result in an **Unknown identifier** error, when using the **Update Table Schema** feature. See [#1362](https://github.com/TabularEditor/TabularEditor3/issues/1362). +- When using the DAX `DIVIDE` function with a non-numeric 3rd argument, the DAX parser now correctly determines the resulting data type to be Variant. +- Fixed a bug that prevented Tabular Editor from loading model metadata from a TMDL folder with no database.tmdl file. + +> [!NOTE] +> Microsoft has announced that [TMDL is in GA](https://powerbi.microsoft.com/en-us/blog/announcing-general-availability-of-tabular-model-definition-language-tmdl/) as of August 2nd, 2024. Please note that Tabular Editor 3 is using a version of the [AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/19.79.1.1), which was released before TMDL was announced as GA. This version should still be fully compatible with TMDL, however, we recommend keeping a backup of your TMSL (.bim) files, just in case. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_18_0_de.md b/content/localization/de/3_18_0_de.md new file mode 100644 index 00000000..db4a88e2 --- /dev/null +++ b/content/localization/de/3_18_0_de.md @@ -0,0 +1,105 @@ +--- +uid: release-3-18-0 +--- + +# Tabular Editor 3.18.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.18.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.18.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.18.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.msi) + +Tabular Editor 3.18.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.18.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.exe) +- Download [Tabular Editor 3.18.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.18.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `BFA440499E7B3FC985971CD0E7FD3BA4C0E8B72CF4A4EA338C6452F1C4E0C6C9` | +| [TabularEditor.3.18.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.msi) | .NET 8 | 64 bit | `9B7FD24086ECA00CA21FE0534AC2AFB1F742181B318E0CC772956F4422E49FC7` | +| [TabularEditor.3.18.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.zip) | .NET 8 | 64 bit | `E69C894268FFEAFB52CFD87DD0D8F265816D1B334159D8F60B69800853221351` | +| [TabularEditor.3.18.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `666D717326A87358C285F6C3E57D213B812A7913935A2332E08C57572DE5CB81` | +| [TabularEditor.3.18.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.msi) | .NET 8 | 32 bit | `C0FCC0A23CDEA32383287F3E54A849A2830B79985E5DF3C597643AD8F9239555` | +| [TabularEditor.3.18.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.zip) | .NET 8 | 32 bit | `CF6FAF0E370B50CD9D87D2FD0B262B013F1B69DA321297D52D7D2B28F299350C` | +| [TabularEditor.3.18.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.exe) | .NET 6 | 64 bit | `79AF51FD6AB6F55ACAEC9A468D05B3D8FE061A7D68DBBF2C11D52683D72D693B` | +| [TabularEditor.3.18.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.msi) | .NET 6 | 64 bit | `3A5C8CBAEFF09F802C4B3F176349ECA3611CEDD70A7554450C31BCB45920C6C4` | +| [TabularEditor.3.18.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.zip) | .NET 6 | 64 bit | `538DF3C2A5DB59E2DA728EE857C57C2BBB2CBCFE749230FA50971D333145E223` | +| [TabularEditor.3.18.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.exe) | .NET 6 | 32 bit | `CB3BC45D7E44A689B6242F34463C4BE6179709E846867635CAFCBD3E0A15CCF6` | +| [TabularEditor.3.18.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.msi) | .NET 6 | 32 bit | `221BA75A2C3277732B65576572AF498FEDA0E64A00075E0B194AF9A7E16C9CBF` | +| [TabularEditor.3.18.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.zip) | .NET 6 | 32 bit | `02DF85DF19B4FF360413412A08020485BF40CFA5AD9BD4F99489D3D93664C1CB` | + +*** + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.18.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/10/31/tabular-editor-3-october-2024-release) to get a brief overview of the most important updates in this release. + +- Our **DAX Optimizer integration** is now out of preview, and we've also made a few updates, so that it now supports the [new evaluation metrics that were part of DAX Optimizer 1.2](https://www.tabulartools.com/blog/introducing-new-evaluation-metrics-in-dax-optimizer-1-2/). Oh, and by the way - all **Enterprise Edition** Tabular Editor 3 users now get 4 free DAX Optimizer runs per day. Download Tabular Editor 3.18.0 from one of the links above, and get your DAX Optimizer redemption code through the **Help > About Tabular Editor** menu item. +- We're happy to introduce a new feature across all DAX editors in Tabular Editor 3: **Code Actions**. This productivity feature discretely provides suggestions for improving your DAX code and lets you apply the suggestion with a single click. For example, the feature can be used to remove unused variables, follow best practices for column and measure references, rewrite table filters as [more efficient column filters](https://www.sqlbi.com/articles/filter-columns-not-tables-in-dax/), and [much, much more](xref:code-actions). We plan to add additional actions in future releases, so stay tuned! +- After we upgraded to the [latest version of the Microsoft AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices/), the behavior of the **Integrated** authentication option changed, such that the Entra ID account selector/MFA popup is no longer shown, if the Windows OS is already connected to an Entra ID account. As such, we've added a new authentication option, **Microsoft Entra MFA**, which will force the account selector/MFA popup to appear, letting you choose a different account than the one currently logged in to Windows, if needed. + +## Improvements in 3.18.0 + +- The user interface preferences have been expanded to allow hiding model source details from the title bar, helping to protect sensitive information during recordings and presentations. +- The user interface preferences now include a new "Recent Items" section. This section enables customization of the number of recent files and models displayed in the file menu and the servers displayed in recent connections. The new preferences also allow clearing these items. +- The Semantic Analyzer now shows a warning if a variable is used directly as the 1st argument of [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE). Since variables are unaffected by context transitions or modified filter contexts, using a variable this way is most likely unintentional. +- Our SQL editor now uses an improved color scheme, making it easier to distinguish SQL keywords from identifiers. +- Upgraded AMO/TOM and other dependencies to their latest versions. +- We're now using Compatibility Level 1606 for new Power BI / Fabric semantic models. At this level, a new Model property [ValueFilterBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.valuefilterbehaviortype?view=analysisservices-dotnet) is available, which can be used to control the _auto-exist_ behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/SUMMARIZECOLUMNS). +- We've added support for the TOM [ChangedProperties](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.changedproperty?view=analysisservices-dotnet) collection (on Tables, Measures, Columns, and a few other objects). This collection is used on composite or Direct Lake models, to indicate that a property (such as a column **Name**) has changed, and should no longer be synchronized from the underlying source. +- Upgraded VertiPaq Analyzer to latest version [(1.7.2)](https://github.com/sql-bi/VertiPaq-Analyzer/releases/tag/v1.7.2), which fixes an issue regarding extracting stats on a model containing Field Parameters / Group By Columns. +- Upgraded our version of the Snowflake .NET connector to v. 4.1.0. This addresses the following vulnerabilities: [CVE-2023-34230](https://nvd.nist.gov/vuln/detail/CVE-2023-34230) and [CVE-2023-51662](https://nvd.nist.gov/vuln/detail/CVE-2023-51662). +- The diagram component should now be considerably faster when working with large diagrams with many relationships. +- Columns in the Data Preview can now be hidden by right-clicking on the column header and selecting "Hide This Column". To show hidden columns, right-click on a column header and select "Column chooser". This will bring up a window from where you can access previously hidden columns. + +## Bugfixes in 3.18.0 + +- Fixed a bug where the "Server" dropdown in the **Load semantic model from database** dialog would not show recently used servers. +- Data Preview settings (sort order, filters, etc.) are now preserved after refreshing the preview, resolving a previous bug where settings were not maintained. +- Fixed a crash which could happen when undoing (Ctrl+Z) while or immediately after using the "Rename" refactoring in a DAX editor. +- The main UI is now properly locked from user interactions while the "Please wait" dialog is shown, such as when performing a table schema update. +- Semantic Analyzer should no longer show a warning when referencing the internal "FormatString" measure in a DAX expression. As a consequence, it is now possible to debug queries that contain such references (even though the FormatString expression itself cannot currently be debugged), see [#1377](https://github.com/TabularEditor/TabularEditor3/issues/1377). + +## Known issues in 3.18.0 + +- If you're getting the error message **Can't obtain account information for '(e-mail)' while trying to refresh the token.** it usually helps to perform the operation again. This is an issue in the newer versions of the AMO/TOM client libraries. You should also be able to avoid this issue by choosing the **Microsoft Entra MFA** authentication option, instead of the **Integrated** option, when initially connecting. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor your DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_18_1_de.md b/content/localization/de/3_18_1_de.md new file mode 100644 index 00000000..4b78f67b --- /dev/null +++ b/content/localization/de/3_18_1_de.md @@ -0,0 +1,122 @@ +--- +uid: release-3-18-1 +--- + +# Tabular Editor 3.18.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.18.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.18.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.18.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.msi) + +Tabular Editor 3.18.1 **.NET 6** downloads: + +- Download [Tabular Editor 3.18.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.exe) +- Download [Tabular Editor 3.18.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.18.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `BA7D2450DC4DC48BD04679828C47799E4036D3E28EE2B7B8FEB3AD84372C81B8` | +| [TabularEditor.3.18.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.msi) | .NET 8 | 64 bit | `BD8763B06EE2F8D821EC4491D1931DF5F9AEA52109F99400EA1E7556DA86A9A4` | +| [TabularEditor.3.18.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.zip) | .NET 8 | 64 bit | `24FF4ABC8EF8D890CE182FBB346A210F480EB9343123C37292258DDD97418F82` | +| [TabularEditor.3.18.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `F184D2F50FCA465230DB05237196AEF3B75286726ABF8CC05181023D0BB91289` | +| [TabularEditor.3.18.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.msi) | .NET 8 | 32 bit | `293D34EF6AF79102C89AA65579D06A169AB955FD75F55BEED919EC5C2A49E319` | +| [TabularEditor.3.18.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.zip) | .NET 8 | 32 bit | `3E3D185C5BEB2A6F32F6851AED5FB9696F012B83CE57D144FC0F4F361DB8DFC5` | +| [TabularEditor.3.18.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.exe) | .NET 6 | 64 bit | `E56BE607444CC2EDBB5328C3BDFED965EA5713BE48D4A9FA06A9011413BA4679` | +| [TabularEditor.3.18.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.msi) | .NET 6 | 64 bit | `8850C65EBA73A9EE89D0FCE4976681FB9CEBCA6F46170B6D0AD6198CBFC3D61E` | +| [TabularEditor.3.18.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.zip) | .NET 6 | 64 bit | `0BA57CFF5C0E928B2CE4EC69CDB8C3CF7273E5CA4FAA083BC58FD763636AD52F` | +| [TabularEditor.3.18.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.exe) | .NET 6 | 32 bit | `5813FF7B483594191150D32377A24C85ABD172BE1C7C1D3520A1B223E1646F4D` | +| [TabularEditor.3.18.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.msi) | .NET 6 | 32 bit | `E097DC640265B4F1DF9B867EDB28CBAE2BD474DCC766DE7333ACA354CEEAA318` | +| [TabularEditor.3.18.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.zip) | .NET 6 | 32 bit | `4D811E4D0EF0ACE08C7155F8F9A2613C8F5F861026E5ADFF9AE1F6794EE3D399` | + +*** + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Improvements in 3.18.1 + +- The Semantic Analyzer no longer displays an error when using a table table name as the name of a variable. **Note:** as of this writing, the ability to use table names for variables is supported in Power BI Desktop (October 2024) and in the Power BI Service. You can control the error behavior under **Tools > Preferences > DAX Editor > DAX Settings > Table-named variables**. +- We've updated the AMO/TOM client libraries to the latest version [19.86.6](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.86.6). This should fix the **Can't obtain account information for '(e-mail)' while trying to refresh the token.** issue that some users have experienced while connected to the Power BI XMLA endpoint, see [#1387](https://github.com/TabularEditor/TabularEditor3/issues/1387). +- A new option under **Tools > Preferences > Power BI** let you specify the default authentication mode to use when connecting to Power BI / Fabric workspaces or Azure Analysis Services. This lets you, for example, specify `Microsoft Entra MFA` by default, forcing the account selector/MFA popup to show up when connecting. +- For multi-user licenses, we now show an option to change the license key, if the number of users on the license has been exceeded. This way, you no longer have to manually reset the license key [through the Windows registry](https://docs.tabulareditor.com/te3/getting-started.html#changing-a-license-key-through-the-registry). + +## Bugfixes in 3.18.1 + +- When attempting to connect to the DAX Optimizer service with a Tabular Tools account that has not been completely set up, we now show a more descriptive error message, instead of throwing an unhandled exception. +- Fixed a bug where VPAX files created in Tabular Editor 3 would be reported as being corrupted when opened in the DAX Optimizer service. +- Fixed a bug where an empty VPAX file was uploaded to the DAX Optimizer service, if the collection of VPAX statistics failed during the upload process. +- Fixed a bug where semantic engine features were not always updated for the **Expression Editor**, when opening a new model (potentially causing false errors to appear in the editor). +- Semantic Analyzer should no longer cause an "An item with the same key has already been added." exception in models with complex, nested DAX expressions, see [#1390](https://github.com/TabularEditor/TabularEditor3/issues/1390) and [#1393](https://github.com/TabularEditor/TabularEditor3/issues/1393). +- Semantic Analyzer now correctly infers the data type of an expression such as `SELECTEDVALUE('MyTable'[String Column], BLANK())` (in this case, the resulting data type should be **String**, but previously it was inferred as **Variant**). +- Fixed a bug where the **Simplify variable** code actions would produce code that was not semantically equivalent to the original code. Moreover, this action will no longer cause a "loop" of code actions to be applied, see [#1386](https://github.com/TabularEditor/TabularEditor3/issues/1386). + +## New in 3.18.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/10/31/tabular-editor-3-october-2024-release) to get a brief overview of the most important updates in this release. + +- Our **DAX Optimizer integration** is now out of preview, and we've also made a few updates, so that it now supports the [new evaluation metrics that were part of DAX Optimizer 1.2](https://www.tabulartools.com/blog/introducing-new-evaluation-metrics-in-dax-optimizer-1-2/). Oh, and by the way - all **Enterprise Edition** Tabular Editor 3 users now get 4 free DAX Optimizer runs per day. Download Tabular Editor 3.18.0 from one of the links above, and get your DAX Optimizer redemption code through the **Help > About Tabular Editor** menu item. +- We're happy to introduce a new feature across all DAX editors in Tabular Editor 3: **Code Actions**. This productivity feature discretely provides suggestions for improving your DAX code and lets you apply the suggestion with a single click. For example, the feature can be used to remove unused variables, follow best practices for column and measure references, rewrite table filters as [more efficient column filters](https://www.sqlbi.com/articles/filter-columns-not-tables-in-dax/), and [much, much more](xref:code-actions). We plan to add additional actions in future releases, so stay tuned! +- After we upgraded to the [latest version of the Microsoft AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices/), the behavior of the **Integrated** authentication option changed, such that the Entra ID account selector/MFA popup is no longer shown, if the Windows OS is already connected to an Entra ID account. As such, we've added a new authentication option, **Microsoft Entra MFA**, which will force the account selector/MFA popup to appear, letting you choose a different account than the one currently logged in to Windows, if needed. + +## Improvements in 3.18.0 + +- The user interface preferences have been expanded to allow hiding model source details from the title bar, helping to protect sensitive information during recordings and presentations. +- The user interface preferences now include a new "Recent Items" section. This section enables customization of the number of recent files and models displayed in the file menu and the servers displayed in recent connections. The new preferences also allow clearing these items. +- The Semantic Analyzer now shows a warning if a variable is used directly as the 1st argument of [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE). Since variables are unaffected by context transitions or modified filter contexts, using a variable this way is most likely unintentional. +- Our SQL editor now uses an improved color scheme, making it easier to distinguish SQL keywords from identifiers. +- Upgraded AMO/TOM and other dependencies to their latest versions. +- We're now using Compatibility Level 1606 for new Power BI / Fabric semantic models. At this level, a new Model property [ValueFilterBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.valuefilterbehaviortype?view=analysisservices-dotnet) is available, which can be used to control the _auto-exist_ behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/SUMMARIZECOLUMNS). +- We've added support for the TOM [ChangedProperties](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.changedproperty?view=analysisservices-dotnet) collection (on Tables, Measures, Columns, and a few other objects). This collection is used on composite or Direct Lake models, to indicate that a property (such as a column **Name**) has changed, and should no longer be synchronized from the underlying source. +- Upgraded VertiPaq Analyzer to latest version [(1.7.2)](https://github.com/sql-bi/VertiPaq-Analyzer/releases/tag/v1.7.2), which fixes an issue regarding extracting stats on a model containing Field Parameters / Group By Columns. +- Upgraded our version of the Snowflake .NET connector to v. 4.1.0. This addresses the following vulnerabilities: [CVE-2023-34230](https://nvd.nist.gov/vuln/detail/CVE-2023-34230) and [CVE-2023-51662](https://nvd.nist.gov/vuln/detail/CVE-2023-51662). +- The diagram component should now be considerably faster when working with large diagrams with many relationships. +- Columns in the Data Preview can now be hidden by right-clicking on the column header and selecting "Hide This Column". To show hidden columns, right-click on a column header and select "Column chooser". This will bring up a window from where you can access previously hidden columns. + +## Bugfixes in 3.18.0 + +- Fixed a bug where the "Server" dropdown in the **Load semantic model from database** dialog would not show recently used servers. +- Data Preview settings (sort order, filters, etc.) are now preserved after refreshing the preview, resolving a previous bug where settings were not maintained. +- Fixed a crash which could happen when undoing (Ctrl+Z) while or immediately after using the "Rename" refactoring in a DAX editor. +- The main UI is now properly locked from user interactions while the "Please wait" dialog is shown, such as when performing a table schema update. +- Semantic Analyzer should no longer show a warning when referencing the internal "FormatString" measure in a DAX expression. As a consequence, it is now possible to debug queries that contain such references (even though the FormatString expression itself cannot currently be debugged), see [#1377](https://github.com/TabularEditor/TabularEditor3/issues/1377). + +## Known issues in 3.18.0 + +- If you're getting the error message **Can't obtain account information for '(e-mail)' while trying to refresh the token.** it usually helps to perform the operation again. This is an issue in the newer versions of the AMO/TOM client libraries. You should also be able to avoid this issue by choosing the **Microsoft Entra MFA** authentication option, instead of the **Integrated** option, when initially connecting. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor your DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_18_2_de.md b/content/localization/de/3_18_2_de.md new file mode 100644 index 00000000..912da159 --- /dev/null +++ b/content/localization/de/3_18_2_de.md @@ -0,0 +1,127 @@ +--- +uid: release-3-18-2 +--- + +# Tabular Editor 3.18.2 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.18.2 **.NET 8** downloads: + +- Download [Tabular Editor 3.18.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.18.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.msi) + +Tabular Editor 3.18.2 **.NET 6** downloads: + +- Download [Tabular Editor 3.18.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.exe) +- Download [Tabular Editor 3.18.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.18.2.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `A01E48D94F299EF1007CB9448EC032CC71BBAC6C70635F3B4FECE28912B7864A` | +| [TabularEditor.3.18.2.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.msi) | .NET 8 | 64 bit | `2EFEEE533A9ABD7CA0B318B7121F8B96D8ED8F6240273F1F85F143021FADD8C6` | +| [TabularEditor.3.18.2.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.zip) | .NET 8 | 64 bit | `B48731C3F6A931FF4F4DE464FBEB33A36E2AF47CEA70CBA5AAF0248B776E59B9` | +| [TabularEditor.3.18.2.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `461FD252C968D7F5DFA8056DC8BD8B4180F4CF45C47E4131501A868E7E70797A` | +| [TabularEditor.3.18.2.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.msi) | .NET 8 | 32 bit | `BDAB08680B239046CCBCB727AA0E884D2711AD0A87713B512BEDE628C23667DB` | +| [TabularEditor.3.18.2.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.zip) | .NET 8 | 32 bit | `A50CA2CC53B659BB8B29A9FFE78B1FD1A91FEFC65C5D507E0506D2AFE35F56CC` | +| [TabularEditor.3.18.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.exe) | .NET 6 | 64 bit | `57FA61B26152CF6DB811E316943D97D4467DB336301C6520423F695A862547A1` | +| [TabularEditor.3.18.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.msi) | .NET 6 | 64 bit | `F4E6C8E4C895AB364D3DCF0926175F981E7A1DBD8F7F7D83C5831B96450E8AE2` | +| [TabularEditor.3.18.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.zip) | .NET 6 | 64 bit | `4B83EB04FCF2E82433A4B76FBA260485A4FAE15F84920C4197D2C502BA98D090` | +| [TabularEditor.3.18.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.exe) | .NET 6 | 32 bit | `2609223F9D88E5229E09C9A6A5AA7E419EBD2D57719E38B7A5E9E05E78D6AC3B` | +| [TabularEditor.3.18.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.msi) | .NET 6 | 32 bit | `223FF7F181EF2F633274295E54B2D2C2D442D675404158BE27BEB37F6B5B1CB4` | +| [TabularEditor.3.18.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.zip) | .NET 6 | 32 bit | `7884B5649DE1A1A78163C9AD6A50F2BE9B6BBD5949E1F5C53503A2C857819EA7` | + +*** + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Bugfixes in 3.18.2 + +- Fixed a regression related to OS regional settings, which would cause a crash upon entering the Preferences dialog for the first time. +- Fix flickering in the Data Refresh view and show proper warning icon for warning messages in the output + +## Improvements in 3.18.1 + +- The Semantic Analyzer no longer displays an error when using a table table name as the name of a variable. **Note:** as of this writing, the ability to use table names for variables is supported in Power BI Desktop (October 2024) and in the Power BI Service. You can control the error behavior under **Tools > Preferences > DAX Editor > DAX Settings > Table-named variables**. +- We've updated the AMO/TOM client libraries to the latest version [19.86.6](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.86.6). This should fix the **Can't obtain account information for '(e-mail)' while trying to refresh the token.** issue that some users have experienced while connected to the Power BI XMLA endpoint, see [#1387](https://github.com/TabularEditor/TabularEditor3/issues/1387). +- A new option under **Tools > Preferences > Power BI** let you specify the default authentication mode to use when connecting to Power BI / Fabric workspaces or Azure Analysis Services. This lets you, for example, specify `Microsoft Entra MFA` by default, forcing the account selector/MFA popup to show up when connecting. +- For multi-user licenses, we now show an option to change the license key, if the number of users on the license has been exceeded. This way, you no longer have to manually reset the license key [through the Windows registry](https://docs.tabulareditor.com/te3/getting-started.html#changing-a-license-key-through-the-registry). + +## Bugfixes in 3.18.1 + +- When attempting to connect to the DAX Optimizer service with a Tabular Tools account that has not been completely set up, we now show a more descriptive error message, instead of throwing an unhandled exception. +- Fixed a bug where VPAX files created in Tabular Editor 3 would be reported as being corrupted when opened in the DAX Optimizer service. +- Fixed a bug where an empty VPAX file was uploaded to the DAX Optimizer service, if the collection of VPAX statistics failed during the upload process. +- Fixed a bug where semantic engine features were not always updated for the **Expression Editor**, when opening a new model (potentially causing false errors to appear in the editor). +- Semantic Analyzer should no longer cause an "An item with the same key has already been added." exception in models with complex, nested DAX expressions, see [#1390](https://github.com/TabularEditor/TabularEditor3/issues/1390) and [#1393](https://github.com/TabularEditor/TabularEditor3/issues/1393). +- Semantic Analyzer now correctly infers the data type of an expression such as `SELECTEDVALUE('MyTable'[String Column], BLANK())` (in this case, the resulting data type should be **String**, but previously it was inferred as **Variant**). +- Fixed a bug where the **Simplify variable** code actions would produce code that was not semantically equivalent to the original code. Moreover, this action will no longer cause a "loop" of code actions to be applied, see [#1386](https://github.com/TabularEditor/TabularEditor3/issues/1386). + +## New in 3.18.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/10/31/tabular-editor-3-october-2024-release) to get a brief overview of the most important updates in this release. + +- Our **DAX Optimizer integration** is now out of preview, and we've also made a few updates, so that it now supports the [new evaluation metrics that were part of DAX Optimizer 1.2](https://www.tabulartools.com/blog/introducing-new-evaluation-metrics-in-dax-optimizer-1-2/). Oh, and by the way - all **Enterprise Edition** Tabular Editor 3 users now get 4 free DAX Optimizer runs per day. Download Tabular Editor 3.18.0 from one of the links above, and get your DAX Optimizer redemption code through the **Help > About Tabular Editor** menu item. +- We're happy to introduce a new feature across all DAX editors in Tabular Editor 3: **Code Actions**. This productivity feature discretely provides suggestions for improving your DAX code and lets you apply the suggestion with a single click. For example, the feature can be used to remove unused variables, follow best practices for column and measure references, rewrite table filters as [more efficient column filters](https://www.sqlbi.com/articles/filter-columns-not-tables-in-dax/), and [much, much more](xref:code-actions). We plan to add additional actions in future releases, so stay tuned! +- After we upgraded to the [latest version of the Microsoft AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices/), the behavior of the **Integrated** authentication option changed, such that the Entra ID account selector/MFA popup is no longer shown, if the Windows OS is already connected to an Entra ID account. As such, we've added a new authentication option, **Microsoft Entra MFA**, which will force the account selector/MFA popup to appear, letting you choose a different account than the one currently logged in to Windows, if needed. + +## Improvements in 3.18.0 + +- The user interface preferences have been expanded to allow hiding model source details from the title bar, helping to protect sensitive information during recordings and presentations. +- The user interface preferences now include a new "Recent Items" section. This section enables customization of the number of recent files and models displayed in the file menu and the servers displayed in recent connections. The new preferences also allow clearing these items. +- The Semantic Analyzer now shows a warning if a variable is used directly as the 1st argument of [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE). Since variables are unaffected by context transitions or modified filter contexts, using a variable this way is most likely unintentional. +- Our SQL editor now uses an improved color scheme, making it easier to distinguish SQL keywords from identifiers. +- Upgraded AMO/TOM and other dependencies to their latest versions. +- We're now using Compatibility Level 1606 for new Power BI / Fabric semantic models. At this level, a new Model property [ValueFilterBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.valuefilterbehaviortype?view=analysisservices-dotnet) is available, which can be used to control the _auto-exist_ behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/SUMMARIZECOLUMNS). +- We've added support for the TOM [ChangedProperties](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.changedproperty?view=analysisservices-dotnet) collection (on Tables, Measures, Columns, and a few other objects). This collection is used on composite or Direct Lake models, to indicate that a property (such as a column **Name**) has changed, and should no longer be synchronized from the underlying source. +- Upgraded VertiPaq Analyzer to latest version [(1.7.2)](https://github.com/sql-bi/VertiPaq-Analyzer/releases/tag/v1.7.2), which fixes an issue regarding extracting stats on a model containing Field Parameters / Group By Columns. +- Upgraded our version of the Snowflake .NET connector to v. 4.1.0. This addresses the following vulnerabilities: [CVE-2023-34230](https://nvd.nist.gov/vuln/detail/CVE-2023-34230) and [CVE-2023-51662](https://nvd.nist.gov/vuln/detail/CVE-2023-51662). +- The diagram component should now be considerably faster when working with large diagrams with many relationships. +- Columns in the Data Preview can now be hidden by right-clicking on the column header and selecting "Hide This Column". To show hidden columns, right-click on a column header and select "Column chooser". This will bring up a window from where you can access previously hidden columns. + +## Bugfixes in 3.18.0 + +- Fixed a bug where the "Server" dropdown in the **Load semantic model from database** dialog would not show recently used servers. +- Data Preview settings (sort order, filters, etc.) are now preserved after refreshing the preview, resolving a previous bug where settings were not maintained. +- Fixed a crash which could happen when undoing (Ctrl+Z) while or immediately after using the "Rename" refactoring in a DAX editor. +- The main UI is now properly locked from user interactions while the "Please wait" dialog is shown, such as when performing a table schema update. +- Semantic Analyzer should no longer show a warning when referencing the internal "FormatString" measure in a DAX expression. As a consequence, it is now possible to debug queries that contain such references (even though the FormatString expression itself cannot currently be debugged), see [#1377](https://github.com/TabularEditor/TabularEditor3/issues/1377). + +## Known issues in 3.18.0 + +- If you're getting the error message **Can't obtain account information for '(e-mail)' while trying to refresh the token.** it usually helps to perform the operation again. This is an issue in the newer versions of the AMO/TOM client libraries. You should also be able to avoid this issue by choosing the **Microsoft Entra MFA** authentication option, instead of the **Integrated** option, when initially connecting. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor your DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_19_0_de.md b/content/localization/de/3_19_0_de.md new file mode 100644 index 00000000..3ecec622 --- /dev/null +++ b/content/localization/de/3_19_0_de.md @@ -0,0 +1,115 @@ +--- +uid: release-3-19-0 +--- + +# Tabular Editor 3.19.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.19.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.19.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.19.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.msi) + +Tabular Editor 3.19.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.19.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.exe) +- Download [Tabular Editor 3.19.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.19.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `8F5B7C34E176EC2A62B2E5A9DE661DFC8B10FC2590BBBFAB14EC9D06B147A0AC` | +| [TabularEditor.3.19.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.msi) | .NET 8 | 64 bit | `20E4BFFCB4075251706D0C93C3A2C62F4E7A7A400BFCBA910EA1481DB5FBF1C6` | +| [TabularEditor.3.19.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.zip) | .NET 8 | 64 bit | `96C35863B2A269E51C805FF587422C68774CF85B941F5F026214CE3397452865` | +| [TabularEditor.3.19.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `C1A05DBDBF519F648BD9A93397604E3434CB535C719CD8742C94A7A375754FC7` | +| [TabularEditor.3.19.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.msi) | .NET 8 | 32 bit | `220A0F308176CCBAE275550D385EB494EB25EC1EE4012D50F25327E5BE1AB446` | +| [TabularEditor.3.19.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.zip) | .NET 8 | 32 bit | `5033510733AD854E0DB8F1E07E67772ACC4674CDD877DBAE85AA0A11483FB8DA` | +| [TabularEditor.3.19.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.exe) | .NET 6 | 64 bit | `D46E23C0A07DCE8F23CBC68E761EE3080614E0B074387A890AD96F3BAA4C44C9` | +| [TabularEditor.3.19.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.msi) | .NET 6 | 64 bit | `D4232D572749D526AB12D8A9585CAE67B26BE5074D3FC080C440B08CC4F956BF` | +| [TabularEditor.3.19.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.zip) | .NET 6 | 64 bit | `20633917724A65B4BED74BEDBF079156461727DD61272A40E304B7E11717775F` | +| [TabularEditor.3.19.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.exe) | .NET 6 | 32 bit | `BF36180EB0CAEDCAFB858A44C011FBB78B9754A3F4FC4945BBC647DCD36AC9E3` | +| [TabularEditor.3.19.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.msi) | .NET 6 | 32 bit | `2087C1A2261955ED7390A56ED9FF6009DA8CFE036752C272F6AC8D7E35A22657` | +| [TabularEditor.3.19.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.zip) | .NET 6 | 32 bit | `1724276318F02CC12782E4F8225722B1410A9797AE6871C26C29F59D40EE0A0B` | + +*** + +> [!IMPORTANT] +> .NET 6 is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.19.0 + +This release is all about quality-of-life improvements and bugfixes. + +Check out our [release blog](https://blog.tabulareditor.com/2024/12/19/tabular-editor-3-december-2024-release/) for a brief overview and a video showing the most important updates in this release. + +- Our DAX code editors now support the **Expand selection** shortcut (Ctrl+Shift+E), which expands the selection to the next logical code block. This is useful, for example, when the cursor is inside a DAX function call, and you want to select the entire function call. Repeatedly pressing Ctrl+Shift+E will expand the selection to the next logical code block, eventually selecting the entire DAX expression. +- We've modified how execution of DAX queries work, due to [popular demand](https://github.com/TabularEditor/TabularEditor3/discussions/1359): + - The **Execute** action (F5) will now execute only the selected portion of the query when text is selected. If no text is selected, the entire query will be executed. + - **Execute Selection** (Shift+F5) will also execute the selected portion similar to the **Execute** action above, but when nothing is selected this action only executes the `EVALUATE` statement under the cursor. + - We've introduced an **Execute full query** action (no default keybinding), in case you need a way to execute the full query without changing your current selection. + - Last, but certainly not least, you can now _execute partial code_. To do this, simply select a portion of code, such as a table or scalar expression anywhere inside your query (even in comments) and hit F5. Tabular Editor will take care of wrapping scalar expressions in curly braces, wrapping column references in a call to [`DISTINCT`](https://dax.guide/DISTINCT), and adding the `EVALUATE` statement, such that a valid DAX query will be sent to the server. +- Across all of our DAX editors, the vertical scrollbar will now indicate the location of any warnings/errors, as well as applicable [Code Actions](xref:code-actions) in the **Improvements** and **Readability** categories. Mouse over the scrollbar indicator to see a tooltip with a description of the issue, and click to navigate directly to it. This is especially useful when working with large DAX expressions, queries or scripts. If you find this feature distracting, it can be toggled off under **Tools > Preferences > Text Editors > Show indicators on scrollbar**. +- Pin, Unpin, and Delete functionality for the Recent Files and Recent Models menus: Added the ability to pin items to the top of the "Recent Files" and "Recent Models" menus, unpin them, or delete them entirely using a new right-click pop-up menu. Pinned items are visually marked with an icon and prioritized at the top of the menus. + +> [!NOTE] +> As a reminder, all shortcuts can be customized under **Tools > Preferences > Keyboard**. The shortcut keys mentioned in this document are the default settings. + +## Improvements in 3.19.0 + +- We have improved the **Data Refresh** view so progress events that relate to the same table, are now being grouped together. This makes it easier to understand the progress of the refresh operation, especially when refreshing large models with many tables. +- When jumping to a specific line of code outside the range of code currently visible in the editor, we now scroll the editor such that the destination line is vertically placed at the center of the editor, rather than near the top/bottom. +- A new right-click menu action has been added to the DAX query results grid, which will let you show the actual query that was executed (as Tabular Editor may modify the query to add a row limit, or to turn a partial selection into a valid query as mentioned above). +- The "Load Semantic Model from Database" dialog now restores preferences for recently connected servers, including Authentication mode, username (excluding passwords), connection mode, and status bar color. +- Updated AMO/TOM to [19.87.2](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.87.2). +- Our offline schema detection (based on our M query parser) now fully supports the use of `PowerPlatform.Dataflows`, see [#970](https://github.com/TabularEditor/TabularEditor3/issues/970). +- When copying/duplicating tables in the model, the inserted table is typically renamed (to ensure uniqueness of table names in the model). When this happens, we now automatically fix-up DAX expressions of objects within that table. For example, calculated columns or Row-Level Security filter expressions on the table, are now updated to use the name of the inserted table. You can toggle off this behavior under **Tools > Preferences > Modeling operations > Clipboard operations**. +- The summary page of the **Deployment Wizard** has been slightly improved, so that it now shows the source and destination Compatibility Levels in case they differ. It also shows a warning icon and a tooltip if the source Compatibility Level is lower than the destination. + +## Bugfixes in 3.19.0 + +- The **Data Refresh** view will no longer scroll to the top when new progress events are added to the list. +- Data Refresh operations are disabled when connected to a model in Power BI Desktop, as Desktop does not support refresh operations initiated from external tools. +- Fixed an issue with the [**Rewrite table filter as scalar predicate**](https://docs.tabulareditor.com/te3/features/code-actions.html#improvements) code action not properly qualifying columns with the table name after the rewrite, potentially causing the resulting DAX to be invalid. +- Fixed an issue with the [**Split multi-column filter into multiple filters**](https://docs.tabulareditor.com/te3/features/code-actions.html#improvements) action, where filters would be deleted, when the original filter contained more than 2 operands. +- When hitting F12 (Go to definition) on an object reference inside a **DAX Script**, the editor will now correctly jump to the object definition inside the script (if it is present), rather than switch to the **Expression Editor**. +- When connected to the Power BI XMLA endpoint or an instance of Azure Analysis Services, attempting to impersonate multiple roles in a Pivot Grid, a Data Preview, or a DAX Query, should now work correctly (instead of only the first role in the list being applied). +- Various bugfixes in the M analyzer, to support more complex M queries for purposes of offline schema detection. For example, we are now able to correctly infer the table schema resulting from an M query that uses a custom function, such as the one in [this discussion](https://github.com/TabularEditor/TabularEditor3/discussions/1413#discussioncomment-11532634). +- Fixed a bug which would cause a crash when selecting both a table and a column (in another table) in the TOM Explorer, and then invoking the right-click menu. +- Fixed an issue where clicking the "Back" button in the deployment wizard after selecting the Microsoft Entra MFA authentication option incorrectly triggered a login pop-up. The "Back" button now properly navigates to the previous step without attempting to authenticate. +- Fixed "Object reference not set to an instance of an object" bug when clicking on the "Export build..." button in the **Deployment Wizard** (regression in 3.17.0). +- Fixed the _JSON DDL request failed: Unrecognised JSON Property: expressions_-error upon deploying a model against Analysis Services on SQL Server 2016 or 2017, while the "Deploy shared expressions" option was unchecked. +- Fixed the _Value cannot be null. (Parameter 'source')_ when attempting to import or update the table schema from a Dataflows entity that does not define any columns. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_1_0_de.md b/content/localization/de/3_1_0_de.md new file mode 100644 index 00000000..79223bfd --- /dev/null +++ b/content/localization/de/3_1_0_de.md @@ -0,0 +1,67 @@ +# Tabular Editor 3.1.0 + +- Download [Tabular Editor 3.1.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.0](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## New features in 3.1.0 + +- The Table Import Wizard is finally here! And it's better than ever before. Read [this article](https://docs.tabulareditor.com/te3/importing-tables.html) for more information. It currently works for SQL, ODBC and OLE DB, but let us know if you need support for other types of data sources. +- Offline (i.e. without being connected to Analysis Services) detection of table schema changes now works - even for M partitions and implicit data sources. +- Objects can now be shown/hidden in perspectives through the TOM context menu, similar to TE2. +- The Import/Export translations option is now available, similar to TE2. +- Added the Batch Rename Dialog, similar to TE2 (the dialog shows up when selecting multiple objects and hitting "F2" for rename). +- Added the Mark as Date Table dialog, similar to TE2. + +## Improvements in 3.1.0 + +- Copying a single cell from a DAX query result now formats the value such that it can be easily pasted into a DAX expression, see [#200](https://github.com/TabularEditor/TabularEditor3/issues/200). +- Added "Delete relationship" option to diagram context menu, see [#195](https://github.com/TabularEditor/TabularEditor3/issues/195). +- Added "Remove field" option to Pivot Grid context menu. +- Model-wide actions such as Create Table, Refresh, Import Tables, etc. are now available through the "Model" menu. +- AuthenticationKind property on Structured Data Sources now has a dropdown. The Options property can now be edited as well and the Query property has been exposed. +- TOM Explorer context menu items have been rearranged to align better with TE2. +- Role members can now be edited directly by right-clicking on a role. +- Dependencies can now be copied from the Dependency View to either Text/JSON format, similar to TE2. +- New skin palette options for the "Basic" and "Bezier" skins (which are vector based, and thus look much better in Hi-DPI than the VS-like skins). Find the new palettes at the bottom of the "Window" menu. + +## Bugfixes in 3.1.0 + +- Fixed an issue with the Select Database dialog when sorting the databases, see [#201](https://github.com/TabularEditor/TabularEditor3/issues/201). +- Fixed a crash with the Select Display Folder dialog, see [#199](https://github.com/TabularEditor/TabularEditor3/issues/199). +- Fixed a crash when switching from the Classic workspace, see [#198](https://github.com/TabularEditor/TabularEditor3/issues/198). +- Translations and perspective info is now retained when dragging/dropping calculated columns or measures between tables, see [#194](https://github.com/TabularEditor/TabularEditor3/issues/194). +- Fixed an issue with unwanted newlines in M code, see [#193](https://github.com/TabularEditor/TabularEditor3/issues/193). +- Fixed a focus issue with the Add Table to Diagram dialog, see [#183](https://github.com/TabularEditor/TabularEditor3/issues/183). +- Fixed a crash when right-clicking various places in a Pivot Grid, see [#175](https://github.com/TabularEditor/TabularEditor3/issues/175). +- Fixed an issue with unwanted TOM refreshes from interfering external change traces. +- Fixed an issue with Workspace Mode warning about Unsaved Changes +- Remove memberId property when deploying roles, see [TE2 #906](https://github.com/TabularEditor/TabularEditor/issues/906). +- Fixed issue with TOM Explorer copy/paste ops (possible related to [#184](https://github.com/TabularEditor/TabularEditor/issues/184)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_1_1_de.md b/content/localization/de/3_1_1_de.md new file mode 100644 index 00000000..aca7b216 --- /dev/null +++ b/content/localization/de/3_1_1_de.md @@ -0,0 +1,62 @@ +# Tabular Editor 3.1.1 + +- Download [Tabular Editor 3.1.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.1](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.1 + +- Shared Expressions (Power Query / M expressions) can now be serialized as individual files. You can control the serialization under **Tools > Preferences > Save-to-folder** or for an existing model under **Model > Serialization options...** ([#218](https://github.com/TabularEditor/TabularEditor3/issues/218)) +- New options for controlling how perspective memberships are applied to new objects under **Tools > Preferences > Modeling Operations** (see issue [#216](https://github.com/TabularEditor/TabularEditor3/issues/216)). +- `PrivacySetting` property can now be excluded from serialization, to prevent issues with Microsoft.AnalysisServices.Deployment. This is controlled under **Model > Serialization options...** (see issue [#210](https://github.com/TabularEditor/TabularEditor3/issues/210)). +- You can now define enums, structs and classes directly within a C# script, making it easier to structure and reuse C# code. +- VertiPaq Analyzer now has an option to collect statistics from data (**Tools > Preferences > VertiPaq Analyzer**), improving the quality of the statistics, for example when columns have IsAvailableInMDX = false. See issue [#190](https://github.com/TabularEditor/TabularEditor3/issues/290). +- When a new model is created, Tabular Editor 3 now prompts if the model should be saved as a file or folder, the first time it is saved. You can also set the default mode under **Tools > Preferences > General > Default save format for new models**. See issue [#50](https://github.com/TabularEditor/TabularEditor3/issues/50). +- Improved startup performance (some users have reported additional startup time gains by adding the `-multicorejit` switch to the TabularEditor3.exe shortcut). +- Restructured the "Model" menu to make options such as "New calculation group" readily available. +- Updated AMO/TOM client libraries to [19.26.1.7](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Model Role Members can now be iterated individually in the Best Practice Analyzer +- "Workspace" within the "Window" menu has been renamed to "Layout" to avoid confusion with [Workspace Mode](https://docs.tabulareditor.com/te3/tutorials/workspace-mode.html). +- Added Ctrl+Shift+D as a shortcut for "Deploy" +- Support for new DAX functions ([`HASH`](https://dax.guide/hash), [`NAMEOF`](https://dax.guide/nameof), [`COLUMNSTATISTICS`](https://dax.guide/columnstatistics), [`BITAND`](https://dax.guide/bitand), [`BITLSHIFT`](https://dax.guide/bitlshift), [`BITOR`](https://dax.guide/bitor), [`BITRSHIFT`](https://dax.guide/bitrshift), [`BITXOR`](https://dax.guide/bitxor)) and support for optional column name parameter in [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). + +## Bugfixes in 3.1.1 + +- TOM Explorer should no longer freeze or crash when deleting objects (see issues [#223](https://github.com/TabularEditor/TabularEditor3/issues/223), [#209](https://github.com/TabularEditor/TabularEditor3/issues/209)). +- Fixed a color issue with dark themes in editors ([#207](https://github.com/TabularEditor/TabularEditor3/issues/207)) and icons ([#215](https://github.com/TabularEditor/TabularEditor3/issues/215)) +- Tables are now sorted alphabetically in the "Create/Edit Relationship" dialog (see issue [#214](https://github.com/TabularEditor/TabularEditor3/issues/214) +- Fixed an issue with C# scripts that prevented saving them as macros (see issue [#208](https://github.com/TabularEditor/TabularEditor3/issues/208)). +- Fixed an issue with data source passwords/credentials not being properly applied to workspace database (see issue [#205](https://github.com/TabularEditor/TabularEditor3/issues/205)). +- "Select all columns" checkbox should no longer cause a crash (see issue [#204](https://github.com/TabularEditor/TabularEditor3/issues/204)). +- Tabular Editor now always looks in the installation directory when a script references external DLL's (using the `#r` precompiler directive), see issue [#192](https://github.com/TabularEditor/TabularEditor3/issues/192). +- Fixed a bug with linguistic schema that caused Q&A to stop working some cases +- Filtering on a date column in Data Preview should no longer cause a crash +- When selecting all perspectives in the TOM Explorer perspectives-dropdown, objects that do not included in any perspectives are no longer shown. Also fixed an issue with the dropdown box not updating perspective names. +- Allow using certain DAX keywords as variables (`WEEK`, `DAY`, `INTEGER`, etc.) without showing an error. +- Fix issue with serialization options not being stored the first time a model is saved. +- Fixed an issue with the DAX parser which would cause a crash upon loading a model (see [#229](https://github.com/TabularEditor/TabularEditor3/issues/229)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_1_2_de.md b/content/localization/de/3_1_2_de.md new file mode 100644 index 00000000..913d4ed4 --- /dev/null +++ b/content/localization/de/3_1_2_de.md @@ -0,0 +1,69 @@ +# Tabular Editor 3.1.2 + +- Download [Tabular Editor 3.1.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.2](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Bugfixes in 3.1.2 + +- Fixed an issue with Update Table Schema not working for SQL DW / Synapse SQL Pool data sources, see [#231](https://github.com/TabularEditor/TabularEditor3/issues/231). +- Fixed an issue where ignored rules were still considered by the Best Practice Analyzer, see [#203](https://github.com/TabularEditor/TabularEditor3/issues/203). +- Fixed an issue where models could not be saved to disk (file or folder) due to a JSON serialization error, see [#232](https://github.com/TabularEditor/TabularEditor3/issues/232). +- Fixed an issue that caused a crash when inspecting the property values of a Structured Data Source. + +## Improvements in 3.1.1 + +- Shared Expressions (Power Query / M expressions) can now be serialized as individual files. You can control the serialization under **Tools > Preferences > Save-to-folder** or for an existing model under **Model > Serialization options...** ([#218](https://github.com/TabularEditor/TabularEditor3/issues/218)) +- New options for controlling how perspective memberships are applied to new objects under **Tools > Preferences > Modeling Operations** (see issue [#216](https://github.com/TabularEditor/TabularEditor3/issues/216)). +- `PrivacySetting` property can now be excluded from serialization, to prevent issues with Microsoft.AnalysisServices.Deployment. This is controlled under **Model > Serialization options...** (see issue [#210](https://github.com/TabularEditor/TabularEditor3/issues/210)). +- You can now define enums, structs and classes directly within a C# script, making it easier to structure and reuse C# code. +- VertiPaq Analyzer now has an option to collect statistics from data (**Tools > Preferences > VertiPaq Analyzer**), improving the quality of the statistics, for example when columns have IsAvailableInMDX = false. See issue [#190](https://github.com/TabularEditor/TabularEditor3/issues/290). +- When a new model is created, Tabular Editor 3 now prompts if the model should be saved as a file or folder, the first time it is saved. You can also set the default mode under **Tools > Preferences > General > Default save format for new models**. See issue [#50](https://github.com/TabularEditor/TabularEditor3/issues/50). +- Improved startup performance (some users have reported additional startup time gains by adding the `-multicorejit` switch to the TabularEditor3.exe shortcut). +- Restructured the "Model" menu to make options such as "New calculation group" readily available. +- Updated AMO/TOM client libraries to [19.26.1.7](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Model Role Members can now be iterated individually in the Best Practice Analyzer +- "Workspace" within the "Window" menu has been renamed to "Layout" to avoid confusion with [Workspace Mode](https://docs.tabulareditor.com/te3/tutorials/workspace-mode.html). +- Added Ctrl+Shift+D as a shortcut for "Deploy" +- Support for new DAX functions ([`HASH`](https://dax.guide/hash), [`NAMEOF`](https://dax.guide/nameof), [`COLUMNSTATISTICS`](https://dax.guide/columnstatistics), [`BITAND`](https://dax.guide/bitand), [`BITLSHIFT`](https://dax.guide/bitlshift), [`BITOR`](https://dax.guide/bitor), [`BITRSHIFT`](https://dax.guide/bitrshift), [`BITXOR`](https://dax.guide/bitxor)) and support for optional column name parameter in [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). + +## Bugfixes in 3.1.1 + +- TOM Explorer should no longer freeze or crash when deleting objects (see issues [#223](https://github.com/TabularEditor/TabularEditor3/issues/223), [#209](https://github.com/TabularEditor/TabularEditor3/issues/209)). +- Fixed a color issue with dark themes in editors ([#207](https://github.com/TabularEditor/TabularEditor3/issues/207)) and icons ([#215](https://github.com/TabularEditor/TabularEditor3/issues/215)) +- Tables are now sorted alphabetically in the "Create/Edit Relationship" dialog (see issue [#214](https://github.com/TabularEditor/TabularEditor3/issues/214) +- Fixed an issue with C# scripts that prevented saving them as macros (see issue [#208](https://github.com/TabularEditor/TabularEditor3/issues/208)). +- Fixed an issue with data source passwords/credentials not being properly applied to workspace database (see issue [#205](https://github.com/TabularEditor/TabularEditor3/issues/205)). +- "Select all columns" checkbox should no longer cause a crash (see issue [#204](https://github.com/TabularEditor/TabularEditor3/issues/204)). +- Tabular Editor now always looks in the installation directory when a script references external DLL's (using the `#r` precompiler directive), see issue [#192](https://github.com/TabularEditor/TabularEditor3/issues/192). +- Fixed a bug with linguistic schema that caused Q&A to stop working some cases +- Filtering on a date column in Data Preview should no longer cause a crash +- When selecting all perspectives in the TOM Explorer perspectives-dropdown, objects that do not included in any perspectives are no longer shown. Also fixed an issue with the dropdown box not updating perspective names. +- Allow using certain DAX keywords as variables (`WEEK`, `DAY`, `INTEGER`, etc.) without showing an error. +- Fix issue with serialization options not being stored the first time a model is saved. +- Fixed an issue with the DAX parser which would cause a crash upon loading a model (see [#229](https://github.com/TabularEditor/TabularEditor3/issues/229)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_1_3_de.md b/content/localization/de/3_1_3_de.md new file mode 100644 index 00000000..93cf4fc9 --- /dev/null +++ b/content/localization/de/3_1_3_de.md @@ -0,0 +1,73 @@ +# Tabular Editor 3.1.3 + +- Download [Tabular Editor 3.1.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.3](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Bugfixes in 3.1.3 + +- Fixed a memory leak that occurs when the application is idle. This issue has existed since v. 3.1.1. + +## Bugfixes in 3.1.2 + +- Fixed an issue with Update Table Schema not working for SQL DW / Synapse SQL Pool data sources, see [#231](https://github.com/TabularEditor/TabularEditor3/issues/231). +- Fixed an issue where ignored rules were still considered by the Best Practice Analyzer, see [#203](https://github.com/TabularEditor/TabularEditor3/issues/203). +- Fixed an issue where models could not be saved to disk (file or folder) due to a JSON serialization error, see [#232](https://github.com/TabularEditor/TabularEditor3/issues/232). +- Fixed an issue that caused a crash when inspecting the property values of a Structured Data Source. + +## Improvements in 3.1.1 + +- Shared Expressions (Power Query / M expressions) can now be serialized as individual files. You can control the serialization under **Tools > Preferences > Save-to-folder** or for an existing model under **Model > Serialization options...** ([#218](https://github.com/TabularEditor/TabularEditor3/issues/218)) +- New options for controlling how perspective memberships are applied to new objects under **Tools > Preferences > Modeling Operations** (see issue [#216](https://github.com/TabularEditor/TabularEditor3/issues/216)). +- `PrivacySetting` property can now be excluded from serialization, to prevent issues with Microsoft.AnalysisServices.Deployment. This is controlled under **Model > Serialization options...** (see issue [#210](https://github.com/TabularEditor/TabularEditor3/issues/210)). +- You can now define enums, structs and classes directly within a C# script, making it easier to structure and reuse C# code. +- VertiPaq Analyzer now has an option to collect statistics from data (**Tools > Preferences > VertiPaq Analyzer**), improving the quality of the statistics, for example when columns have IsAvailableInMDX = false. See issue [#190](https://github.com/TabularEditor/TabularEditor3/issues/290). +- When a new model is created, Tabular Editor 3 now prompts if the model should be saved as a file or folder, the first time it is saved. You can also set the default mode under **Tools > Preferences > General > Default save format for new models**. See issue [#50](https://github.com/TabularEditor/TabularEditor3/issues/50). +- Improved startup performance (some users have reported additional startup time gains by adding the `-multicorejit` switch to the TabularEditor3.exe shortcut). +- Restructured the "Model" menu to make options such as "New calculation group" readily available. +- Updated AMO/TOM client libraries to [19.26.1.7](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Model Role Members can now be iterated individually in the Best Practice Analyzer +- "Workspace" within the "Window" menu has been renamed to "Layout" to avoid confusion with [Workspace Mode](https://docs.tabulareditor.com/te3/tutorials/workspace-mode.html). +- Added Ctrl+Shift+D as a shortcut for "Deploy" +- Support for new DAX functions ([`HASH`](https://dax.guide/hash), [`NAMEOF`](https://dax.guide/nameof), [`COLUMNSTATISTICS`](https://dax.guide/columnstatistics), [`BITAND`](https://dax.guide/bitand), [`BITLSHIFT`](https://dax.guide/bitlshift), [`BITOR`](https://dax.guide/bitor), [`BITRSHIFT`](https://dax.guide/bitrshift), [`BITXOR`](https://dax.guide/bitxor)) and support for optional column name parameter in [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). + +## Bugfixes in 3.1.1 + +- TOM Explorer should no longer freeze or crash when deleting objects (see issues [#223](https://github.com/TabularEditor/TabularEditor3/issues/223), [#209](https://github.com/TabularEditor/TabularEditor3/issues/209)). +- Fixed a color issue with dark themes in editors ([#207](https://github.com/TabularEditor/TabularEditor3/issues/207)) and icons ([#215](https://github.com/TabularEditor/TabularEditor3/issues/215)) +- Tables are now sorted alphabetically in the "Create/Edit Relationship" dialog (see issue [#214](https://github.com/TabularEditor/TabularEditor3/issues/214) +- Fixed an issue with C# scripts that prevented saving them as macros (see issue [#208](https://github.com/TabularEditor/TabularEditor3/issues/208)). +- Fixed an issue with data source passwords/credentials not being properly applied to workspace database (see issue [#205](https://github.com/TabularEditor/TabularEditor3/issues/205)). +- "Select all columns" checkbox should no longer cause a crash (see issue [#204](https://github.com/TabularEditor/TabularEditor3/issues/204)). +- Tabular Editor now always looks in the installation directory when a script references external DLL's (using the `#r` precompiler directive), see issue [#192](https://github.com/TabularEditor/TabularEditor3/issues/192). +- Fixed a bug with linguistic schema that caused Q&A to stop working some cases +- Filtering on a date column in Data Preview should no longer cause a crash +- When selecting all perspectives in the TOM Explorer perspectives-dropdown, objects that do not included in any perspectives are no longer shown. Also fixed an issue with the dropdown box not updating perspective names. +- Allow using certain DAX keywords as variables (`WEEK`, `DAY`, `INTEGER`, etc.) without showing an error. +- Fix issue with serialization options not being stored the first time a model is saved. +- Fixed an issue with the DAX parser which would cause a crash upon loading a model (see [#229](https://github.com/TabularEditor/TabularEditor3/issues/229)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_1_4_de.md b/content/localization/de/3_1_4_de.md new file mode 100644 index 00000000..dcbbc973 --- /dev/null +++ b/content/localization/de/3_1_4_de.md @@ -0,0 +1,48 @@ +# Tabular Editor 3.1.4 + +- Download [Tabular Editor 3.1.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.4](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.4 + +- Added a few toolbar shortcuts to menus (for example, you can now manage BPA rules under **Tools > Manage BPA rules...**) +- Can now create DAX scripts for calculated columns and calculated tables by selecting them in the TOM Explorer and right-clicking +- Improved error message behavior in Pivot Grid +- Added "Launch Tabular Editor 3" button to installer, see [#202](https://github.com/TabularEditor/TabularEditor3/issues/202) + +## Bugfixes in 3.1.4 + +- Columns/measures with brackets in their names and tables with single quotes in their name now no longer generates a false semantic error, see [#239](https://github.com/TabularEditor/TabularEditor3/issues/239). +- Fixed a bug that caused a false semantic error when using certain words as variable names. +- Fixed a bug that could sometimes cause a crash while defining a variable in DAX. +- Fixed a bug that caused a false semantic error when using TOPNSKIP with certain arguments. +- The `SelectObject` method (and methods that wrap it) now returns null when the user hits the "Cancel" button, see [#247](https://github.com/TabularEditor/TabularEditor3/issues/247). +- Fixed an issue with the `ExportProperties` / `ImportProperties` methods not working for object collections, see [#245](https://github.com/TabularEditor/TabularEditor3/issues/245). +- Fixed an issue that prevented pasting calculation items, see [#237](https://github.com/TabularEditor/TabularEditor3/issues/237) +- Fixed a "Duplicate key" error which would occur when updating a table schema for a table that contained similarly named columns (i.e. "Customer Key" and "CustomerKey"). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_1_5_de.md b/content/localization/de/3_1_5_de.md new file mode 100644 index 00000000..39fcf1ae --- /dev/null +++ b/content/localization/de/3_1_5_de.md @@ -0,0 +1,47 @@ +# Tabular Editor 3.1.5 + +- Download [Tabular Editor 3.1.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.5](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.5 + +- You can now **impersonate** users or roles on DAX queries, Pivot Grids and Table Previews. This is useful for testing RLS and OLS settings. [More information](https://docs.tabulareditor.com/onboarding/refresh-preview-query.html#impersonation). +- DAX scripts now support calculation groups and calculation items. This allows you to view all calculation group logic (including format string expressions) in a single document. [Example](https://docs.tabulareditor.com/onboarding/dax-script-introduction.html#example-3-calculation-group). +- When right-clicking on a measure reference in a DAX query or DAX script, there is now an option to add the definition of that measure [including all dependencies](https://docs.tabulareditor.com/onboarding/dax-script-introduction.html#define-measures). +- You can now pan diagrams by dragging an empty area (see [#275](https://github.com/TabularEditor/TabularEditor3/issues/275)). + +## Bugfixes in 3.1.5 + +- Fixed issue with the built-in schema updater when a `null` value is encountered in an M expression (see [#282](https://github.com/TabularEditor/TabularEditor3/issues/282)). +- Semantic analyzer no longer reports an error when using the `RELATED` function in an argument to `SELECTCOLUMNS`(when no name argument is specified). +- Macros can now be edited/renamed without disappearing from toolbar customizations (see [#266](https://github.com/TabularEditor/TabularEditor3/issues/266)). +- All custom toolbars can now be renamed/deleted after restarting the application (see [#260](https://github.com/TabularEditor/TabularEditor3/issues/260)). +- Fixed selection/context menu when selecting a folder of folders (see [#248](https://github.com/TabularEditor/TabularEditor3/issues/248)). +- Prevented crash when simultaneously selecting tables/table objects. +- Fixed various issues/crashes when importing tables (ODBC NullReferenceException, and more). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_1_6_de.md b/content/localization/de/3_1_6_de.md new file mode 100644 index 00000000..337c12d5 --- /dev/null +++ b/content/localization/de/3_1_6_de.md @@ -0,0 +1,66 @@ +# Tabular Editor 3.1.6 + +- Download [Tabular Editor 3.1.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.6](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.6 + +- DAX editor improvements: + - **Offline DAX formatting now available**. The "Format DAX" buttons and shortcuts (F6) now use the built-in DAX formatter instead of www.daxformatter.com. The built-in formatter has a few more configuration options and also fixes column and measure references that do not follow best practices, and more. Since the built-in formatter does not perform a web request, it is also significantly faster. If you encounter an issue with the built-in formatter, you can disable it by enabling the \*\*Use daxformatter.com instead of built-in formatter" under **Tools > Preferences > DAX Editor**. + - You can now configure keywords/functions to be formatted with different casing, based on your preferences. Find the settings under **Tools > Preferences > DAX Editor > Auto Formatting**, see [#58](https://github.com/TabularEditor/TabularEditor3/issues/58). [More details](xref:personalizing-te3#dax-settings). + - Added an option for "Debug comma" formatting for DAX queries (puts all commas in front of the line, for easy comment/uncomment of subexpressions), see [#96](https://github.com/TabularEditor/TabularEditor3/issues/96). + - You can now select an entire object reference (measure, column, etc.) by double-clicking on it (previously, only the word under the cursor would get selected). + - When a subexpression is selected and an opening brace (parenthesis or curly brace) is entered, the selection is wrapped with a matching closing brace, see [#48](https://github.com/TabularEditor/TabularEditor3/issues/48). + - Code assist no longer interferes when writing comments. +- TE3 can now import and update table schemas from Snowflake (Power BI data models only). +- Updated TOM to 19.27.2.1 +- C# script method `SelectObjects` is now available, which prompt the user to select one or more objects given a list of objects. +- New option, **Tools > Preferences > TOM Explorer > Show full branch**. When this is checked, filtering the TOM Explorer will also show all child objects, even when they do not match the filter string. See [#276](https://github.com/TabularEditor/TabularEditor3/issues/276). +- New option, **Tools > Preferences > TOM Explorer > Always show delete warnings**. When this is checked, all delete operations will display a confirmation dialog. When unchecked, only multi-select deletions and deletion of objects referenced by other objects will display the confirmation dialog (remember, every operation can be undone in Tabular Editor). See [#10](https://github.com/TabularEditor/TabularEditor3/issues/10). +- Added the "Apply Refresh Policy" menu option on tables, when applicable. See [Configure Incremental Refresh with Tabular Editor](https://www.youtube.com/watch?v=icCGFG6KpIA) for more information, see also [#291](https://github.com/TabularEditor/TabularEditor3/issues/291). +- Added the DAX dependency view to the **View** menu, and added a checkbox that lets the dependency view track the current selection in the TOM Explorer, see[#10](https://github.com/TabularEditor/TabularEditor3/issues/10). + +## Bugfixes in 3.1.6 + +- The Preferences, SelectItems and Save/Edit Macro dialogs can now be resized, see[#51](https://github.com/TabularEditor/TabularEditor3/issues/51). +- When an "Update table schema" operation is performed against a Power BI Desktop model that uses native queries for data import, we will bring the PBI Desktop instance to the front, as a dialog pops up in Desktop which needs to be accepted, before the "Update table schema" operation can complete, see issue [#55](https://github.com/TabularEditor/TabularEditor3/issues/55). +- Taskbar icon should no longer break when upgrading. See[#163](https://github.com/TabularEditor/TabularEditor3/issues/163). +- When updating table schemas, you will now be shown a connection dialog that allows you to change the auth mode. See[#262](https://github.com/TabularEditor/TabularEditor3/issues/262). +- The `MemberId` role member property is now removed automatically only when deploying a model to Azure AS or Power BI. See [#263](https://github.com/TabularEditor/TabularEditor3/issues/263). +- Fixed an issue with freezing UI when queuing multiple refresh operations, see [#281](https://github.com/TabularEditor/TabularEditor3/issues/281). +- AAD object picker should now produce a well-formed object name. See[#286](https://github.com/TabularEditor/TabularEditor3/issues/286). +- When executing a DAX script that creates a calculation group, the ordinals are now assigned correctly, see [#296](https://github.com/TabularEditor/TabularEditor3/issues/296). +- CTRL + arrows can now be used to expand/collapse all nodes in the TOM Explorer, similar to TE 2.x, see [#297](https://github.com/TabularEditor/TabularEditor3/issues/297). +- When executing a DAX script that creates a calculation group, the column name is now assigned correctly, see [#298](https://github.com/TabularEditor/TabularEditor3/issues/298). +- Fixed a bug where DAX script locales were not updated correctly when switching between US/Non-US mode. +- Fixed a crash that would occur when trying to connect to an AS server contains databases with no compatibility level (happens when connecting to an instance of AS tabular that shares its data dir with an instance of AS multidimensional). +- Fixed a bug that would sometimes cause the "Update table schema" feature to report all columns as missing from the source. +- Fixed an issue with the Table Preview feature, that would cause grid columns to be configured incorrectly, when using impersonation. +- Fixed an issue with semantic change notification bar not disappearing when saving the model. +- Fixed an issue with property grid edits not being committed automatically when saving the model. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_1_7_de.md b/content/localization/de/3_1_7_de.md new file mode 100644 index 00000000..6462ffc9 --- /dev/null +++ b/content/localization/de/3_1_7_de.md @@ -0,0 +1,53 @@ +# Tabular Editor 3.1.7 + +- Download [Tabular Editor 3.1.7 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.7](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.7 + +- When a DAX query causes Analysis Services to return an error message, that message is now displayed in place of the previous result grid. +- Grids can now be zoomed (ctrl+mouse wheel)! +- Various auto-complete improvements and auto-indent improvements. +- A new right-click menu makes it easy to add table permissions to roles (previously, you would have to add a table permission by assigning an RLS expression or specify an OLS setting). See issue [#257](https://github.com/TabularEditor/TabularEditor3/issues/257). You can add multiple table permissions across multiple roles at once. +- The "Select database" dialog now remembers sort order of columns. See [#321](https://github.com/TabularEditor/TabularEditor3/issues/321). + +## Bugfixes in 3.1.7 + +- Fix issue with SaveModelMetadataBackup not working for database IDs (when IDs and Names are different). +- Fix crash when resetting auto format preferences +- Fix missing export of TOM in VPAX. Fix message dialog when VPAX contains TOM. +- Improved DAX (offline) formatting, see issue [#306](https://github.com/TabularEditor/TabularEditor3/issues/306). +- Fixed issue with `FormatDax(...)` and `CallDaxFormatter()` helper functions when using the default (offline) formatter, see [#307](https://github.com/TabularEditor/TabularEditor3/issues/307). +- Fixed an issue with auto-complete sometimes getting "stuck". +- Fewer windows/dialogs should have display scaling issues when the Windows display resolution or scaling is changed. See [#308](https://github.com/TabularEditor/TabularEditor3/issues/308) and [#81](https://github.com/TabularEditor/TabularEditor3/issues/81). +- Auto-formatter should no longer repeat multi-line comment blocks. See [#319](https://github.com/TabularEditor/TabularEditor3/issues/319]. +- Fixed an issue with the background semantic analysis reporting invalid DAX errors, see [#311](https://github.com/TabularEditor/TabularEditor3/issues/311). +- Opening the BPA manager through the menu bar should no longer cause a crash, see [#312](https://github.com/TabularEditor/TabularEditor3/issues/312). +- Saving a model in workspace mode, that was loaded from a Database.json file, should no longer cause a "Save failed!" error, see issue [#322](https://github.com/TabularEditor/TabularEditor3/issues/322). +- Comments are now correctly retained when applying a DAX script, see issue [#323](https://github.com/TabularEditor/TabularEditor3/issues/323). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_20_0_de.md b/content/localization/de/3_20_0_de.md new file mode 100644 index 00000000..f8dd0c34 --- /dev/null +++ b/content/localization/de/3_20_0_de.md @@ -0,0 +1,117 @@ +--- +uid: release-3-20-0 +--- + +# Tabular Editor 3.20.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.20.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.20.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.20.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) + +Tabular Editor 3.20.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.20.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe) +- Download [Tabular Editor 3.20.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.20.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `0E2CA7EF182E7D8DD3D4CFE7F3AB550236BF7AA7E8EDC7AB01E739A3441F2333` | +| [TabularEditor.3.20.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi) | .NET 8 | 64 bit | `7B38FF22B71FB7C0B4AE7E258FFB9AFF4D7D32835AEED2A5382405D539B68710` | +| [TabularEditor.3.20.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip) | .NET 8 | 64 bit | `3CA79DC8E8F58DDADDE068774106193D46A59BFF85E604B429DE732D4B23CAEA` | +| [TabularEditor.3.20.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `9CEF083B2F972E5A380BBCFF79F349D7860D81DC7A50F05BBA52305C75E7A071` | +| [TabularEditor.3.20.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) | .NET 8 | 32 bit | `86ABFC4EBEFC905F996D335515C761C63F9A9BDA3A13C6CE018E523DD8705182` | +| [TabularEditor.3.20.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) | .NET 8 | 32 bit | `1A2E934CF58AF8B42B1D6A94B91138C1854D6FD127FE28CB38DE3395111A880F` | +| [TabularEditor.3.20.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe) | .NET 6 | 64 bit | `964C72AF3DECF1FD6988998FA8963828C6A62CA4FA978D44DC10DE1983D1C562` | +| [TabularEditor.3.20.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi) | .NET 6 | 64 bit | `502378EFE2C5D3EFD77D4493ECFFBC01D1D9402E57DB471DD3E578526730959C` | +| [TabularEditor.3.20.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip) | .NET 6 | 64 bit | `E2108460A36871D872F29DC8FE17C2385B3299D326ED3FFD402A551AB57A4A40` | +| [TabularEditor.3.20.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) | .NET 6 | 32 bit | `9050A1D090D8D11263C2F85FDFB79CA84201F3A8D80444B7E0EDC4C2DE46DEB8` | +| [TabularEditor.3.20.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) | .NET 6 | 32 bit | `E8C8EC487D293CA22014A35120C7E936E69CAEC541670C145F06BE5E9F68C1B0` | +| [TabularEditor.3.20.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) | .NET 6 | 32 bit | `235A4D73BA4377E7D6DC625121060DB84B64C32FE37230B678EE463F3F3ADAC7` | + +*** + +> [!IMPORTANT] +> .NET 6 is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization, as we will stop providing .NET 6 builds of Tabular Editor 3 during 2025. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.20.0 + +Check out our [release blog](https://blog.tabulareditor.com/2025/02/21/tabular-editor-3-february-2025-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.20.0 + +- All [code actions](xref:code-actions) now show a tooltip in the context menu when hovering over the menu item, with a short description of the action. The tooltip also contains a link to a knowledge-base (KB) article with more information about the action. +- We've also added a few new code actions in this release, based on popular demand. For example, we will now suggest that you use the `IN` operator instead of using a compound expression with `OR` / `||`. View the [full list of available code actions here](xref:code-actions#list-of-code-actions). +- Introduced a new user interface preference labeled "Use compact file paths" to toggle between displaying compact (shortened) file paths and full file paths in the Recent Files and Recent Models menus. +- When editing a model that's loaded in Power BI Desktop (January 2025 or newer), Tabular Editor will now let you edit any object and property by default, except tables and partitions, in alignment with the modeling operations supported by the new [TMDL View](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-tmdl-view) in Power BI Desktop. +- When changing the DAX expression of a calculated table, Tabular Editor 3 will now attempt to infer the resulting columns of the table, even if the expression has an error. +- A new DAX Query preference labeled "Keep existing sorting and filtering in the result grid" has been added to the DAX Query menus and toolbar, allowing users to control how sorting and filtering are preserved in the result grids between query executions. +- We've made several improvements to our **Diagram View**. Most importantly, it now renders much faster, especially when many tables/relationships are present. But there are also several visual tweaks. +- We've improved the C# auto-complete feature, so that it now shows only items that are relevant for the current target. For example, if you type `Selected.Column.DataType = `, the listbox will now only show the valid [`DataType` enum values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.datatype?view=analysisservices-dotnet#fields). Moreover, if the same type exists in different namespaces, we now show the namespace in a parenthesis, to disambiguate the items in the list. +- Updated AMO/TOM to the latest version [19.88.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). +- We have added auto-complete support to the new DAX scalar inspection functions, [`ISINT64`](https://dax.guide/isint64), [`ISBOOLEAN`](https://dax.guide/isboolean), [`ISDOUBLE`](https://dax.guide/isboolean), [`ISDECIMAL`](https://dax.guide/isdecimal), [`ISDATETIME`](https://dax.guide/isdatetime), [`ISSTRING`](https://dax.guide/isstring), and [`ISNUMERIC`](https://dax.guide/isnumeric). + +## Bugfixes in 3.20.0 + +- The **Rewrite using ISBLANK** DAX Code Action will no longer trigger when using non-strict equality comparisons, e.g. `x = BLANK()`, as this is semantically different from `ISBLANK(x)`. +- Various bugfixes for unhandled exceptions in the DAX Editor. +- The Semantic Analyzer now correctly shows an error message if using a group-by column within a call to [`SUMMARIZE`](https://dax.guide/summarize), which has no relation to the base table. +- When creating VPAX files through the **DAX Optimizer** view, we will now use the **Full** extraction mode for Direct Lake models, producing a VPAX file that is valid for DAX Optimizer analysis. +- Various Pivot Grid bugfixes and stability improvements. +- Fixed a bug where unassigning/resetting an Editor shortcut, would not be effective until restarting the application. +- Fixed a bug where certain editor shortcuts (such as "Duplicate Line (Ctrl+D)") would trigger an action in the TOM Explorer with the same key binding, even when the editor was focused. +- Fixed a bug where adding a level to a hierarchy in a Power BI Desktop model, would not include the column reference, causing an error when attempting to save the change. +- Fixed a bug that would cause a crash when executing a DAX script containing certain syntax or errors. +- Creating and editing DAX scripts should no longer cause the UI to lock up, which could happen when the script contained syntax or semantic errors. +- Fixed a bug that would sometimes cause the **Data Refresh** view to lock up/crash while a refresh was in progress. +- Fixed a bug causing a crash when loading a model and then navigating to a partition with a [Data Coverage Definition](https://learn.microsoft.com/en-us/analysis-services/tom/table-partitions?view=asallproducts-allversions#define-the-data-coverage-of-the-directquery-partition). +- The auto-complete feature of C# scripts should now work correctly when making multiple insertions in the script, such as in [#1327](https://github.com/TabularEditor/TabularEditor3/issues/1327). +- Hitting F12 (Go to Definition) on a measure format string expression reference, will now correctly navigate to the referenced measure's format string expression property, rather than the base expression property. +- Fixed an issue with our Semantic Analyzer, that didn't correctly detect when a relationship was activated by the [`USERELATIONSHIP`](https://dax.guide/userelationship) function. +- Fixed an issue with false circular dependency errors appearing while editing the DAX of calculated columns. +- Fixed a bug that prevented **TE3 Business Edition** license holders to connect to Power BI Premium-Per-User (PPU) workspaces, in some regions. + +> [!IMPORTANT] +> Due to technical limitations, previous versions of TE3 might sometimes allow **Business Edition** license holders to connect to Power BI Premium / Fabric Capacity workspaces, even though [this is not allowed per the Business Edition license terms](xref:editions). If you are facing issues connecting to the Power BI XMLA endpoint after upgrading to 3.20.0, please reach out to [licensing@tabulareditor.com](mailto:licensing@tabulareditor.com) so we can assist you in finding a suitable solution going forward. + +## Known issues in 3.20.0 + +- The Semantic Analyzer doesn't correctly detect relationship activations with `USERELATIONSHIP` when there are only inactive relationships between two tables. +- The Semantic Analyzer doesn't always infer the correct data type for the column returned by the [`GENERATESERIES`](https://dax.guide/generateseries) function. +- The new **Diagram view** does not correctly indicate bi-directional relationships. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_20_1_de.md b/content/localization/de/3_20_1_de.md new file mode 100644 index 00000000..049b4894 --- /dev/null +++ b/content/localization/de/3_20_1_de.md @@ -0,0 +1,115 @@ +--- +uid: release-3-20-1 +--- + +# Tabular Editor 3.20.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.20.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.20.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.20.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) + +Tabular Editor 3.20.1 **.NET 6** downloads: + +- Download [Tabular Editor 3.20.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe) +- Download [Tabular Editor 3.20.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.20.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `4A5BB249049A32A3C2BA14140AFF6BDE6340DEDA217E4E1D6D33A9699E8D0558` | +| [TabularEditor.3.20.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi) | .NET 8 | 64 bit | `189EB204E1ED778F66132019BBAB70CAC7A6C8C2B04955BF45C80F6E7CC52B19` | +| [TabularEditor.3.20.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip) | .NET 8 | 64 bit | `6B324C0D6EFD1C7453302F6C8AF1F49A0C8D127C7FCEE9880A652279E2850016` | +| [TabularEditor.3.20.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `735297DAC09D7342F556C52D81224B6A91B1E7E7837102520114A310939E3C9F` | +| [TabularEditor.3.20.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) | .NET 8 | 32 bit | `2C0D29C4030882BB445DF5A00A5CF3D821A30FD3B2D6A182BEE1917D873F3E9F` | +| [TabularEditor.3.20.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) | .NET 8 | 32 bit | `3180ED45BFF0BF6D720A851415B36A52E155671B38E7E515A75CABCEF1F8E1E0` | +| [TabularEditor.3.20.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe) | .NET 6 | 64 bit | `04B2999366C284AC520A4234BA51BA2D9D3E05D4753FFF7DE5B8FF28B1AB56A9` | +| [TabularEditor.3.20.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi) | .NET 6 | 64 bit | `3E45C228B500D538B9AD7E373F938F4F3B7E2B10B7E61AFC4FED6946CE97B467` | +| [TabularEditor.3.20.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip) | .NET 6 | 64 bit | `C40BF90E2D3DD3226EB35B6BB32D1876736D3B044787416C0EF07536FFE6AB89` | +| [TabularEditor.3.20.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) | .NET 6 | 32 bit | `40FF4D8860C065455A7BDE98EA7241FF174BE059610B8E3589FA6FF41539D6DB` | +| [TabularEditor.3.20.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) | .NET 6 | 32 bit | `4F04C3097862C40C37C366BE2DB00994D7791F1BEDCD8DE18140BBEC960D0266` | +| [TabularEditor.3.20.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) | .NET 6 | 32 bit | `39D8D73522089C4E547455E183082312E4067F54D4CC53A5115110B5194229E7` | + +*** + +> [!IMPORTANT] +> .NET 6 is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization, as we will stop providing .NET 6 builds of Tabular Editor 3 during 2025. Alternatively, use our portable builds, which include the required .NET runtime. + +## Bugfixes in 3.20.1 + +- Fixed an issue that prevented users from authenticating against Azure Databricks using "Azure AD" (aka. "Entra ID") authentication. See [#1451](https://github.com/TabularEditor/TabularEditor3/issues/1451). + +## New in 3.20.0 + +Check out our [release blog](https://blog.tabulareditor.com/2025/02/21/tabular-editor-3-february-2025-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.20.0 + +- All [code actions](xref:code-actions) now show a tooltip in the context menu when hovering over the menu item, with a short description of the action. The tooltip also contains a link to a knowledge-base (KB) article with more information about the action. +- We've also added a few new code actions in this release, based on popular demand. For example, we will now suggest that you use the `IN` operator instead of using a compound expression with `OR` / `||`. View the [full list of available code actions here](xref:code-actions#list-of-code-actions). +- Introduced a new user interface preference labeled "Use compact file paths" to toggle between displaying compact (shortened) file paths and full file paths in the Recent Files and Recent Models menus. +- When editing a model that's loaded in Power BI Desktop (January 2025 or newer), Tabular Editor will now let you edit any object and property by default, except tables and partitions, in alignment with the modeling operations supported by the new [TMDL View](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-tmdl-view) in Power BI Desktop. +- When changing the DAX expression of a calculated table, Tabular Editor 3 will now attempt to infer the resulting columns of the table, even if the expression has an error. +- A new DAX Query preference labeled "Keep existing sorting and filtering in the result grid" has been added to the DAX Query menus and toolbar, allowing users to control how sorting and filtering are preserved in the result grids between query executions. +- We've made several improvements to our **Diagram View**. Most importantly, it now renders much faster, especially when many tables/relationships are present. But there are also several visual tweaks. +- We've improved the C# auto-complete feature, so that it now shows only items that are relevant for the current target. For example, if you type `Selected.Column.DataType = `, the listbox will now only show the valid [`DataType` enum values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.datatype?view=analysisservices-dotnet#fields). Moreover, if the same type exists in different namespaces, we now show the namespace in a parenthesis, to disambiguate the items in the list. +- Updated AMO/TOM to the latest version [19.88.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). +- We have added auto-complete support to the new DAX scalar inspection functions, [`ISINT64`](https://dax.guide/isint64), [`ISBOOLEAN`](https://dax.guide/isboolean), [`ISDOUBLE`](https://dax.guide/isboolean), [`ISDECIMAL`](https://dax.guide/isdecimal), [`ISDATETIME`](https://dax.guide/isdatetime), [`ISSTRING`](https://dax.guide/isstring), and [`ISNUMERIC`](https://dax.guide/isnumeric). + +## Bugfixes in 3.20.0 + +- The **Rewrite using ISBLANK** DAX Code Action will no longer trigger when using non-strict equality comparisons, e.g. `x = BLANK()`, as this is semantically different from `ISBLANK(x)`. +- Various bugfixes for unhandled exceptions in the DAX Editor. +- The Semantic Analyzer now correctly shows an error message if using a group-by column within a call to [`SUMMARIZE`](https://dax.guide/summarize), which has no relation to the base table. +- When creating VPAX files through the **DAX Optimizer** view, we will now use the **Full** extraction mode for Direct Lake models, producing a VPAX file that is valid for DAX Optimizer analysis. +- Various Pivot Grid bugfixes and stability improvements. +- Fixed a bug where unassigning/resetting an Editor shortcut, would not be effective until restarting the application. +- Fixed a bug where certain editor shortcuts (such as "Duplicate Line (Ctrl+D)") would trigger an action in the TOM Explorer with the same key binding, even when the editor was focused. +- Fixed a bug where adding a level to a hierarchy in a Power BI Desktop model, would not include the column reference, causing an error when attempting to save the change. +- Fixed a bug that would cause a crash when executing a DAX script containing certain syntax or errors. +- Creating and editing DAX scripts should no longer cause the UI to lock up, which could happen when the script contained syntax or semantic errors. +- Fixed a bug that would sometimes cause the **Data Refresh** view to lock up/crash while a refresh was in progress. +- Fixed a bug causing a crash when loading a model and then navigating to a partition with a [Data Coverage Definition](https://learn.microsoft.com/en-us/analysis-services/tom/table-partitions?view=asallproducts-allversions#define-the-data-coverage-of-the-directquery-partition). +- The auto-complete feature of C# scripts should now work correctly when making multiple insertions in the script, such as in [#1327](https://github.com/TabularEditor/TabularEditor3/issues/1327). +- Hitting F12 (Go to Definition) on a measure format string expression reference, will now correctly navigate to the referenced measure's format string expression property, rather than the base expression property. +- Fixed an issue with our Semantic Analyzer, that didn't correctly detect when a relationship was activated by the [`USERELATIONSHIP`](https://dax.guide/userelationship) function. +- Fixed an issue with false circular dependency errors appearing while editing the DAX of calculated columns. +- Fixed a bug that prevented **TE3 Business Edition** license holders to connect to Power BI Premium-Per-User (PPU) workspaces, in some regions. + +> [!IMPORTANT] +> Due to technical limitations, previous versions of TE3 might sometimes allow **Business Edition** license holders to connect to Power BI Premium / Fabric Capacity workspaces, even though [this is not allowed per the Business Edition license terms](xref:editions). If you are facing issues connecting to the Power BI XMLA endpoint after upgrading to 3.20.0, please reach out to [licensing@tabulareditor.com](mailto:licensing@tabulareditor.com) so we can assist you in finding a suitable solution going forward. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_21_0_de.md b/content/localization/de/3_21_0_de.md new file mode 100644 index 00000000..18bd250d --- /dev/null +++ b/content/localization/de/3_21_0_de.md @@ -0,0 +1,91 @@ +--- +uid: release-3-21-0 +--- + +# Tabular Editor 3.21.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.21.0 downloads: + +- Download [Tabular Editor 3.21.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.21.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.21.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `A3F944C0945B3FD3AD0595A05D1BCAFAF6BBB8DCFB48F40002C799F91415764E` | +| [TabularEditor.3.21.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi) | .NET 8 | 64 bit | `251510EB41FDEA73CB21C7637FD9CD2F74691B416894B318A5BDAEE96595BEAD` | +| [TabularEditor.3.21.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip) | .NET 8 | 64 bit | `385A8F00F76A1621B063DA1B3AEA2FA726F308E1A2E829D8FF27FC743B0A57E1` | +| [TabularEditor.3.21.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `CF4BAA7B9E74E9EE19BE41DA195DBD260F4922081F44FCC7CC66AD12A702FBD5` | +| [TabularEditor.3.21.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) | .NET 8 | 32 bit | `81425B72EA2E1CB5E2A8101ECC7F0F2B259E4FD90482CAD7B0F9DCAB3F5CE298` | +| [TabularEditor.3.21.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) | .NET 8 | 32 bit | `99BE7DA061A0C47A1D5BA1169D9DDAA521CDB974F135004478334BDD0E469D0B` | + +*** + +> [!IMPORTANT] +> We are no longer providing .NET 6 builds of Tabular Editor 3, as this is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime), please contact your IT organization. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.21.0 + +Check out our [release blog](https://tabulareditor.com/blog/tabular-editor-3-april-2025-release) to get a brief overview of the most important updates in this release. + +## Improvements in 3.21.0 + +- We've made even more visual tweaks and improvements to our **Diagram view** in this release: + - Icons visually indicate column data types. + - Double-arrows when a relationship uses bi-directional cross filtering + - A chevron button in the top-right corner of the table allows you to quickly toggle between various ways of displaying the columns in the table: All columns, key columns only, or no columns at all. + - Various font size adjustments and other minor tweaks +- Updated AMO/TOM to the latest version [19.94.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.94.1.1). +- We have added a new property on the `Model` object, `MetadataSource`, which includes information about where the model metadata was loaded from. This is useful for C# scripts, for example if a script needs to iterate files in the same folder structure that the model metadata was loaded from. See the [API docs](https://docs.tabulareditor.com/api/TabularEditor.TOMWrapper.Model.html#TabularEditor_TOMWrapper_Model_MetadataSource) for more information. +- DAX Optimizer users can now also view the results for RLS and Calculation Item expressions through our **DAX Optimizer Integration**. +- You can now script individual objects as [TMDL (Tabular Model Definition Language)](https://learn.microsoft.com/en-us/analysis-services/tmdl/tmdl-overview?view=asallproducts-allversions) through the **TOM Explorer**. This is useful when you want to copy TMDL scripts from Tabular Editor to Power BI Desktop. Right-click an object and choose **Export script > TMDL**. You'll have the option of exporting the script to a file or directly to the clipboard. + +## Bugfixes in 3.21.0 + +- Sorting by "Progress" or "Duration" in the **Data Refresh** view should now work correctly. Moreover, the "Duration" is no longer reset at the end of the refresh operation, for certain objects. +- Various bugfixes related to the view of progress events in the **Data Refresh** view. For example, progress events should now arrive even if a previous session has expired (for example when Tabular Editor was idle for 60 minutes or more). +- When partition deployment is disabled, or enabled but with incremental refresh partitions skipped, we now also leave the refresh policy settings on the table untouched (i.e. **Source Expression**, **Polling Expression**, etc.) +- The Semantic Analyzer should no longer report an error when tables are connected by only inactive relationships, and a relationship is activated using the [`USERELATIONSHIP`](https://dax.guide/userelationship/) function. +- Fixed a bug where the Semantic Analyzer determined the wrong resulting data type when using the [`GENERATESERIES`](https://dax.guide/generateseries/) function. +- Fixed a bug with the Semantic Analyzer reporting false "not found" errors when [`DEFINE`ing](https://dax.guide/DEFINE) and referencing tables and columns inside a DAX script/query. +- It is no longer possible to assign an empty name to an object through the **TOM Explorer**. +- Certain words that were previously treated as reserved keywords, will no longer produce a semantic error, when used as unquoted table / variable references. +- Fixed a bug where the DAX debugger didn't correctly gray out the inactive branch when using IF.EAGER or IF with only 2 parameters. +- When opening a model with a workspace connection (i.e. Tabular Editor 3's Workspace Mode feature), we now correctly show the Microsoft Entra MFA prompt, if this was the authentication method used when the connection to the workspace database was originally established. +- Our code editors now fully supports wide characters / unicode emojis (note, this is not an endorsement of emojis in DAX, but it is now possible to use them without breaking the editor :)). +- If the .tmuo file contains invalid JSON, Tabular Editor will now show an error message and continue loading the model without the options specified in the file, instead of causing an unhandled exception. +- Fixed a bug where the Refresh Policy options would not appear in the **Properties** grid on a table in a model loaded from disk, if the table did not have any partitions specified in the loaded metadata. +- The `Ctrl+U` (Uncomment Code) and `Ctrl+/` (Toggle comments) shortcuts were not working properly because of conflicts with other editor keyboard shortcuts. We have removed the default shortcuts from the conflicting commands. If you need keyboard bindings for the _Editor.Lowercase_ and _Editor.Uppercase_ commands (previously `Ctrl+U` and `Ctrl+Shift+U` respectively), you can set these up through **Tools > Preferences > Keyboard**. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_22_0_de.md b/content/localization/de/3_22_0_de.md new file mode 100644 index 00000000..eadc242a --- /dev/null +++ b/content/localization/de/3_22_0_de.md @@ -0,0 +1,92 @@ +--- +uid: release-3-22-0 +--- + +# Tabular Editor 3.22.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.22.0 downloads: + +- Download [Tabular Editor 3.22.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.22.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.22.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `07CEF5470991300856C4F6057A95CE547DBC5F6803E4283063ACE11CA8397D3B` | +| [TabularEditor.3.22.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi) | .NET 8 | 64 bit | `1DD07DDF45997F5314656A7F600E1DBC11CBF623A0F09A9B1EF9C975E70ABDB5` | +| [TabularEditor.3.22.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip) | .NET 8 | 64 bit | `6CABFD02E7C04D319DDB85581B7EB13633F5AB0716F5B5612738A3BEC498D917` | +| [TabularEditor.3.22.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `A5DB72C8FF6CBDCC167C8368B1ECA92567041E4A716F6971B5C15204FEBD797B` | +| [TabularEditor.3.22.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) | .NET 8 | 32 bit | `01960E2F3D493FB9FB96FC946A5BE522D191DDBFCECF79AD5ACD4DF1D249D3E9` | +| [TabularEditor.3.22.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) | .NET 8 | 32 bit | `8558D7BE5C01ED04E19B17330A5215EA92BAAEE82C4E5EB4F5436CC62CA04F02` | + +*** + +## New in 3.22.0 + +Check out our [release blog](https://tabulareditor.com/blog/tabular-editor-3-june-2025-release) to get a brief overview of the most important updates in this release. + +(**Enterprise Edition only**) Tabular Editor 3 now fully supports Direct Lake on OneLake and Direct Lake on SQL. This means: + +- The Table Import Wizard has new import options for Fabric Warehouses and Lakehouses. You no longer need to know the SQL analytics endpoint of the Warehouse/Lakehouse you wish to connect to. Instead, we show you a list of all the Warehouses/Lakehouses in your workspace, allowing you to choose the one you wish to use. +- On the last page of the Table Import Wizard, you can choose whether to use Direct Lake in OneLake or SQL mode, or whether to configure the table for plain old "import" mode. +- When the model contains tables in Direct Lake on OneLake mode, you can now also add tables in Import mode, in order to create mixed mode/hybrid models. +- When previewing data in Direct Lake tables, we no longer restrict the number of rows returned (so you can freely scroll through all the data in the table, just like in Import mode). Be aware that all columns are swapped into the Semantic Model in the Fabric capacity when you perform a data preview. Consider using a DAX Query if you are concerned about memory consumption on your Fabric capacity. + +> [!NOTE] +> We no longer configure Direct Lake models to use a case _sensitive_ collation. If you plan to use Direct Lake on SQL with a Fabric Warehouse that uses a case sensitive collation, you must manually fill out the **Collation** property of your semantic model _before_ adding any tables or other objects. + +For more information, view our [Direct Lake Guidance article](xref:direct-lake-guidance). + +## Improvements in 3.22.0 + +- When saving a model as a single file, the **Save file** dialog now suggests "model.bim" as the default file name. +- Updated various dependencies to their latest versions, including [AMO/TOM to 19.98.0.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). This update fixes longstanding authentication issues with Work or School accounts and repeated sign in promts. +- Changed the default Compatibility Level for new Power BI / Fabric semantic models to **1609**, which allows you to control how [Selection Expressions](https://powerbi.microsoft.com/en-us/blog/deep-dive-into-selection-expressions-for-calculation-groups/) on your Calculation Groups behave by default, through the Model [SelectionExpressionBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.model.selectionexpressionbehavior?view=analysisservices-dotnet) property. +- DAX query editor support for the [`MPARAMETER`](https://dax.guide/st/mparameter/) keyword, see [#1467](https://github.com/TabularEditor/TabularEditor3/issues/1467). +- Our DAX editors now support **word based** auto complete search terms. In other words, if you type `sales ytd` in the editor, the auto complete will now suggest measures such as `[Sales Margin YTD]`, `[Sales Revenue YTD]`, etc. +- With the June 2025 update of Power BI Desktop, [external tools can now perform any write operation on the semantic model](https://powerbi.microsoft.com/en-us/blog/power-bi-june-2025-feature-summary/#post-30307-_Toc269410729). As such, we no longer restrict the modeling operations available in Tabular Editor, when connecting to a model in this or newer versions of Power BI Desktop. + +## Bugfixes in 3.22.0 + +- Added exception handling when encountering IOException's during save-to-folder operations (where we sometimes need to delete folders in the folder structure, which can be blocked by file system locks placed by version control systems). +- Fixed a bug where certain keyboard shortcuts (both default and customized) didn't work when the "What's new" page was focused. +- When assigning a custom keyboard shortcut that is already assigned to another command, we now show a warning message and remove the shortcut from the other command, to avoid ambiguity. +- Fixed a bug where the Semantic Analyzer showed a false error message when using unqualified column references in a DAX window function. See [#1460](https://github.com/TabularEditor/TabularEditor3/issues/1460). +- Fixed a bug that could sometimes cause the **Data Refresh** view to freeze, requiring an app restart to resolve. See [#1461](https://github.com/TabularEditor/TabularEditor3/issues/1461). +- Fixed several smaller DAX editor issues related to auto complete, auto formatting, and syntax highlighting of keywords. +- Query Group names (i.e. "display folders" for Shared M expressions and M partitions) can now be modified. Also, if pasting an object with a query group into a model that doesn't contain said query group, it will be created automatically, so as to avoid the error message on subsequent Save / Deployment of the model. +- If pasting an object containing a Shared Expression reference to a model that does not contain the Shared Expression, we remove the reference to avoid "object does not exist" errors when saving/deploying the model to Analysis Services / Power BI. +- Fixed a bug where it was sometimes not possible to Undo previous changes, after saving the model metadata back to the server. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_22_1_de.md b/content/localization/de/3_22_1_de.md new file mode 100644 index 00000000..b7400e58 --- /dev/null +++ b/content/localization/de/3_22_1_de.md @@ -0,0 +1,95 @@ +--- +uid: release-3-22-1 +--- + +# Tabular Editor 3.22.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.22.1 downloads: + +- Download [Tabular Editor 3.22.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.22.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.22.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `F8BA7D9FFA0E334F0506822CE41FE18F3E0F41499E7B729CEE8D0D6FCA4C50A7` | +| [TabularEditor.3.22.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi) | .NET 8 | 64 bit | `EEB0101CA523A633AAD233087977F574B68945F051F1E0030CCA60C0B8E331D9` | +| [TabularEditor.3.22.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip) | .NET 8 | 64 bit | `1A4F9D02004996C4A921AE78E9827314EFA95AA88D2BC59BF569AD4F3EA83362` | +| [TabularEditor.3.22.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `B04C58D262AE1F0C32DD940F0BE96A3245F5AB0FA82066F6CAAFC21B2B09C85A` | +| [TabularEditor.3.22.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) | .NET 8 | 32 bit | `8AFD8E7589830D2385957B073E965EFEB439438950797F5BBBAE29BB5E454E34` | +| [TabularEditor.3.22.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) | .NET 8 | 32 bit | `70E6F993C8C2D11D4A09DB9D1C8D6CF93F83E72105824F6ACDDB0C5D1B2DA477` | + +*** + +> [!IMPORTANT] +> We are no longer providing .NET 6 builds of Tabular Editor 3, as this is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime), please contact your IT organization. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.22.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +(**Enterprise Edition only**) Tabular Editor 3 now fully supports Direct Lake over OneLake and Direct Lake over SQL. This means: + +- The Table Import Wizard has new import options for Fabric Warehouses and Lakehouses. You no longer need to know the SQL analytics endpoint of the Warehouse/Lakehouse you wish to connect to. Instead, we show you a list of all the Warehouses/Lakehouses in your workspace, allowing you to choose the one you wish to use. +- On the last page of the Table Import Wizard, you can choose whether to use Direct Lake in OneLake or SQL mode, or whether to configure the table for plain old "import" mode. +- When the model contains tables in Direct Lake over OneLake mode, you can now also add tables in Import mode, in order to create mixed mode/hybrid models. +- When previewing data in Direct Lake tables, we no longer restrict the number of rows returned (so you can freely scroll through all the data in the table, just like in Import mode). Be aware that all columns are swapped into the Semantic Model in the Fabric capacity when you perform a data preview. Consider using a DAX Query if you are concerned about memory consumption on your Fabric capacity. + +> [!NOTE] +> We no longer configure Direct Lake models to use a case _sensitive_ collation. If you plan to use Direct Lake over SQL with a Fabric Warehouse that uses a case sensitive collation, you must manually fill out the **Collation** property of your semantic model _before_ adding any tables or other objects. + +## Improvements in 3.22.0 + +- When saving a model as a single file, the **Save file** dialog now suggests "model.bim" as the default file name. +- Updated various dependencies to their latest versions, including [AMO/TOM to 19.98.0.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). This update fixes longstanding authentication issues with Work or School accounts and repeated sign in promts. +- DAX query editor support for the [`MPARAMETER`](https://dax.guide/st/mparameter/) keyword, see [#1467](https://github.com/TabularEditor/TabularEditor3/issues/1467). +- Our DAX editors now support **word based** auto complete search terms. In other words, if you type `sales ytd` in the editor, the auto complete will now suggest measures such as `[Sales Margin YTD]`, `[Sales Revenue YTD]`, etc. +- With the June 2025 update of Power BI Desktop, [external tools can now perform any write operation on the semantic model](https://powerbi.microsoft.com/en-us/blog/power-bi-june-2025-feature-summary/#post-30307-_Toc269410729). As such, we no longer restrict the modeling operations available in Tabular Editor, when connecting to a model in this or newer versions of Power BI Desktop. + +## Bugfixes in 3.22.1 + +- Fixed a bug where the **Data Refresh** view would turn blank and not show additional refresh operations until the app was restarted. See [#1461](https://github.com/TabularEditor/TabularEditor3/issues/1461). + +## Bugfixes in 3.22.0 + +- Added exception handling when encountering IOException's during save-to-folder operations (where we sometimes need to delete folders in the folder structure, which can be blocked by file system locks placed by version control systems). +- Fixed a bug where certain keyboard shortcuts (both default and customized) didn't work when the "What's new" page was focused. +- When assigning a custom keyboard shortcut that is already assigned to another command, we now show a warning message and remove the shortcut from the other command, to avoid ambiguity. +- Fixed a bug where the Semantic Analyzer showed a false error message when using unqualified column references in a DAX window function. See [#1460](https://github.com/TabularEditor/TabularEditor3/issues/1460). +- Fixed a bug that could sometimes cause the **Data Refresh** view to freeze, requiring an app restart to resolve. See [#1461](https://github.com/TabularEditor/TabularEditor3/issues/1461). +- Fixed several smaller DAX editor issues related to auto complete, auto formatting, and syntax highlighting of keywords. +- Query Group names (i.e. "display folders" for Shared M expressions and M partitions) can now be modified. Also, if pasting an object with a query group into a model that doesn't contain said query group, it will be created automatically, so as to avoid the error message on subsequent Save / Deployment of the model. +- Fixed a bug where it was sometimes not possible to Undo previous changes, after saving the model metadata back to the server. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_23_0_de.md b/content/localization/de/3_23_0_de.md new file mode 100644 index 00000000..90d599b7 --- /dev/null +++ b/content/localization/de/3_23_0_de.md @@ -0,0 +1,105 @@ +--- +uid: release-3-23-0 +--- + +# Tabular Editor 3.23.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.23.0 downloads: + +- Download [Tabular Editor 3.23.0 (x64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.23.0 (ARM64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.23.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe) | .NET 8 | x64 | `AFC65EB335297D644071565277A79AC28F425E77915A43FE4140FDAA73298E52` | +| [TabularEditor.3.23.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi) | .NET 8 | x64 | `08430DFA78C8565DDB93352963EA5AF90718F454BCC2D8EE7CE4B96BD8D4A50C` | +| [TabularEditor.3.23.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip) | .NET 8 | x64 | `B38957E4E9AF4D4ECBFF86820F4318081A663BF0F94F18038A5A009823D4F8EA` | +| [TabularEditor.3.23.0.Installer.ARM64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) | .NET 8 | ARM64 | `936E0D27006C337E20C03445D8D030E74D4CB0E811EF2F8E4EEE06EA360963F1` | +| [TabularEditor.3.23.0.ARM64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) | .NET 8 | ARM64 | `8EC2BC63BFBBF39314E39D795507E24DC3D6CD16F4D90DEE0E2ECD1BF0753924` | +| [TabularEditor.3.23.0.ARM64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) | .NET 8 | ARM64 | `FAB055031ABABB1F390F8E1DEE1BD3B1FDC5D09102D1B052830EF8CB7167CB22` | + +*** + +> [!NOTE] +> We are now providing native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) builds in addition to regular 64-bit (x64) builds. 32-bit (x86) builds have been discontinued. + +## New in 3.23.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +- Tabular Editor 3 now supports **DAX User-Defined Functions (UDFs)**. This is a big, important feature, and we can't do it justice in a few bullet points. Please check out the [dedicated documentation section](xref:udfs) to learn more. +- As if one big feature wasn't enough, we also added support for **Calendars** in this release. Again, please see the [dedicated documentation section](xref:calendars) to learn more. + +> [!NOTE] +> [Tabular Editor 3.23.1](xref:release-3-23-1) contains several important bugfixes related to UDFs and Calendars, so if you plan to use these features, we recommend updating to 3.23.1. + +- The **Table Import Wizard** now supports **Fabric SQL Databases** and **Fabric Mirrored Databases** as data sources, both for Import and Direct Lake mode models, in line with the [announcement in the Power BI Desktop July 2025 update](https://powerbi.microsoft.com/en-us/blog/power-bi-july-2025-feature-summary/#post-30545-_Toc203388697). +- Native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) support. +- Preparations for upcoming Power BI features (which we can't disclose just yet). + +## Improvements in 3.23.0 + +- Main window now remembers its position & size. Can be disabled in Preferences > Tabular Editor > User Interface > Layout. +- Messages view now copies the selected cell rather than the whole row by default, Ctrl+Shift+C can be used to copy the whole row as before. There is a new right click context menu with these (Copy Cell, Copy Row) options as well. +- Updated 3rd party dependencies including AMO/TOM to [v. 19.103.2](https://www.nuget.org/packages/Microsoft.AnalysisServices/). +- A new word wrap option is now exposed in toolbar, menu (Edit > Word Wrap) and preferences window (Text Editors > General). Line wrap indicators can also be enabled in the preferences. +- The C# script editor's auto complete now provides more flexible search (i.e. search for partial matches and search by capital letters). +- You can now use the "Apply" or "Apply selection" action on DAX queries containing [`DEFINE COLUMN`](https://www.sqlbi.com/articles/introducing-define-column-in-dax-queries/) or [`DEFINE TABLE`](https://www.sqlbi.com/articles/introducing-define-table-in-dax-queries/) statements, in addition to `DEFINE MEASURE` statements. This will create the corresponding calculated columns or calculated tables in the model, or update their DAX expressions if they already exist. +- Peek definition window now lets user scroll the main DAX editor instead of swallowing mouse scroll inputs while the mouse is on it. +- Peek definition window height is now adjusted more tightly. +- Semantic Analyzer no longer shows "Multiple column cannot be converted to a scalar value" errors, when there are other, more indicative error messages. + +## Bugfixes in 3.23.0 + +- Fixed a bug where you would have to enable **Allow unsupported modelling operations** in order to make any changes to a model in Power BI Desktop, even though modelling operations were supported. +- Fixed a bug where main window exceeds screen dimensions depending on resolution and DPI scaling. +- Fixed toolbar customization settings such as "Large icons", "Show ScreenTips on toolbars" etc. not persisting after restarting TE3. +- Fixed a visual glitch where TOM Explorer's Perspective and Language drop-down controls have duplicate buttons. +- Fixed a bunch of issues with "Peek definiton" feature: + - Peek definition is closed on undo/redo operations + - Peek definition is invisible when used on the last line of DAX editor + - Peek definition turns invisible when the line ending of the peeked reference is deleted + - Peek definition is also closed when trying to instead close auto-complete popup with ESC + - Peek definition is also closed when trying to instead clear rectangular-selection with ESC + - When a new line is added to the left of peeked reference, peek definition turns invisible and empty padding space incorrectly appears above the peeked reference + - Fix empty padding space appearing under the wrong line if the caret is on a different line than the peeked reference when the peek definition is triggered +- Calltips in the C# code editor are now sized correctly, ensuring that all of the calltip text is visible. +- Fixed a bug where Fabric Warehouses were not correctly listed in the Fabric connection dialog (instead they were shown as type "Unknown"). +- DAX autocomplete should no longer suggest `DAY` for the <Interval> parameter of the [`PARALLELPERIOD`](https://dax.guide/parallelperiod) function, as this is not a valid value for that parameter. +- Calltips will now update correctly when swapping between different syntax alternatives using the up/down arrows. +- Fixed a bug where code actions did not update correctly when switching between objects. +- Fix line numbers in code editors getting cut off when zoomed in. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_23_1_de.md b/content/localization/de/3_23_1_de.md new file mode 100644 index 00000000..a045c071 --- /dev/null +++ b/content/localization/de/3_23_1_de.md @@ -0,0 +1,78 @@ +--- +uid: release-3-23-1 +--- + +# Tabular Editor 3.23.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.23.1 downloads: + +- Download [Tabular Editor 3.23.1 (x64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.23.1 (ARM64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.23.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe) | .NET 8 | x64 | `9FD7A96EC346CB7C32C3EE9468A0542A41AF25204C2C1D2DE79D16B32AFD7505` | +| [TabularEditor.3.23.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi) | .NET 8 | x64 | `F65112E90C0E49CD767C2FBFDA43D6E7FEDA7ADF2A07C08FC49F7D283BCA1BF4` | +| [TabularEditor.3.23.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip) | .NET 8 | x64 | `C25883760ED505437B78F69A1B5DA6471E083AB897FE32D6313EDCC155ABEE69` | +| [TabularEditor.3.23.1.Installer.ARM64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) | .NET 8 | ARM64 | `DCCBAC2ED50459D40AECD5487E6F59EDA4C7863428FD68C126A6F4C4BE729362` | +| [TabularEditor.3.23.1.ARM64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) | .NET 8 | ARM64 | `53CDFD40F4CAF622054459B31A9AD72EABC25392CC2023A236971D388F8F9A5A` | +| [TabularEditor.3.23.1.ARM64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) | .NET 8 | ARM64 | `C97DC82AF4234162405AE25B77157C8B73837A1D336E2F9BEE66BAFA1D1AF28C` | + +*** + +> [!NOTE] +> We are now providing native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) builds in addition to regular 64-bit (x64) builds. 32-bit (x86) builds have been discontinued. + +## New in 3.23.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +- Tabular Editor 3 now supports **DAX User-Defined Functions (UDFs)**. This is a big, important feature, and we can't do it justice in a few bullet points. Please check out the [dedicated documentation section](xref:udfs) to learn more. +- As if one big feature wasn't enough, we also added support for **Calendars** in this release, including DAX parser and editor support for 8 new DAX functions related to week-based time intelligence. Again, please see the [dedicated documentation section](xref:calendars) to learn more. + +## Improvements in 3.23.1 + +- We added Compatibility Level 1700 (SQL Server 2025) to the dropdown in the **New Model** dialog. Moreover, the default Compatibility Level for Power BI models has been updated to 1702 (which is needed for UDFs and Calendars). + +## Bugfixes in 3.23.1 + +- This update fixes several bugs related to UDFs and Calendars compared to 3.23.0. Mostly related to our built-in DAX parser, but also several tweaks and stability improvements for things like autocomplete, formatting, etc. +- We have downgraded the version of MSAL (Microsoft.Identity.Client) library to [4.72.1](https://www.nuget.org/packages/Microsoft.Identity.Client/4.72.1), as the newer versions of this library (used in the previous release of Tabular Editor 3), do not work well with the AS client library, [causing the application to hang when using the Microsoft Entra ID authentication option](https://github.com/TabularEditor/TabularEditor3/issues/1485). +- Removed the **Duplicate** and **Cut/Copy/Paste/Delete** actions for Calculated Table Columns, as these objects cannot be manually added/removed from tables, and doing so would cause issues upon saving the changes to Analysis Services / Power BI. You should modify the DAX of the calculated table instead. +- Mirrored Azure Databricks catalogs are now also shown in the Table Import Wizard UI, when choosing the **Fabric Mirrored Database** option. +- Fixed an issue where opening a model created with older versions of Power BI Desktop would cause a "The given key 'Extended Properties' was not present in the dictionary" error. +- Fixed a bug that prevented forward references in DAX script object properties. I.e. you no longer get an error if the `FormatString` property of a measure references a measure defined later in the script. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_2_0_de.md b/content/localization/de/3_2_0_de.md new file mode 100644 index 00000000..43b9aed2 --- /dev/null +++ b/content/localization/de/3_2_0_de.md @@ -0,0 +1,45 @@ +# Tabular Editor 3.2.0 + +- Download [Tabular Editor 3.2.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.0](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.2.0 + +- We are proud to introduce the **DAX debugger** in this update of Tabular Editor 3. Check out [this article](https://docs.tabulareditor.com/te3/features/dax-debugger.html) to get started. +- Application startup time and footprint has been greatly improved. +- We have overhauled the layout customizations engine to address various issues (disappearing expression editors, missing toolbar buttons, etc.) **Please be aware that any layout customizations you have previously made will no longer work in v. 3.2.0**. +- Updated TOM to [19.32.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). + +## Bugfixes in 3.2.0 + +- Fixed an issue with the `CallDaxFormatter` method not respecting short/long formatting default, see [#324](https://github.com/TabularEditor/TabularEditor3/issues/324). +- Fixed an issue with formatting of calculation item properties in a DAX script. +- 3rd party assemblies can now be loaded from locations other than the installation folder, see [#340](https://github.com/TabularEditor/TabularEditor3/issues/340). +- Fixes an issue with automatic formula fixup when a column that was referenced in a CROSSFILTER or USERELATIONSHIP function call was renamed. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_2_1_de.md b/content/localization/de/3_2_1_de.md new file mode 100644 index 00000000..1de0a5b9 --- /dev/null +++ b/content/localization/de/3_2_1_de.md @@ -0,0 +1,65 @@ +# Tabular Editor 3.2.1 + +- Download [Tabular Editor 3.2.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.1](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.2.1 + +- The debugger has been improved in various ways. For example, it is now easier to manage Watch expressions through a right-click context menu. You can also quickly add a measure, a variable reference, or a subexpression to the Watch expression view by right-clicking in the editor. See [this article](https://docs.tabulareditor.com/te3/features/dax-debugger.html) for more information. +- A new serialization option is available, which ensures that the JSON arrays for roles/perspectives are sorted by name when saved to disk, see [#341](https://github.com/TabularEditor/TabularEditor3/issues/341). Find the new option under **Tools > Preferences > File Formats > Sort arrays by name** (or to change the setting for an existing model go to **Model > Serialization options...**). + +## Bugfixes in 3.2.1 + +- Debugger now supports DAX queries that use the ROLLUPGROUP function. +- Fixed a bug with inverse filter being sent to the DAX debugger when starting from a Pivot Grid with a filter on a column containing two unique values. +- General DAX debugger stability improvements, see [#369]((https://github.com/TabularEditor/TabularEditor3/issues/369). +- The step over (F10) and step in (F11) shortcuts in the DAX debugger now behave more intuitively. +- Fix crash on model load when TOM Explorer has not yet been initialized, see issue [#357](https://github.com/TabularEditor/TabularEditor3/issues/357). +- Fixed an issue with workspace layout not being restored correctly on application restart or when switching between layouts. +- Ensure content of auto-hide panels is loaded when the panel is expanding +- Semantic analyzer should no longer report an error when the 3rd arg of the [SEARCH](https://dax.guide/search) or [FIND](https://dax.guide/find) functions is omitted. +- Semantic analyzer should no longer report errors when using the [ROLLUPGROUP](https://dax.guide/rollupgroup) and [ROLLUP](https://dax.guide/rollup) DAX functions (sometimes seen in queries generated by PBI Desktop). +- Various offline DAX formatter improvements, to make the offline formatter more consistent with https://daxformatter.com. +- Fix issue with comment frames being added to the previous expression in a DAX script, see [#331](https://github.com/TabularEditor/TabularEditor3/issues/331). +- Fix application crash at launch, issue [#328](https://github.com/TabularEditor/TabularEditor3/issues/328). +- Allow setting translated properties of multiple objects at once, see issue [#359](https://github.com/TabularEditor/TabularEditor3/issues/359). +- Fix refresh progress indicator "stuck", see issue [#360](https://github.com/TabularEditor/TabularEditor3/issues/360). +- Fix diagram font scaling, see issue [#351](https://github.com/TabularEditor/TabularEditor3/issues/351). +- Fix call tree rendering in high-dpi, see issue [#355](https://github.com/TabularEditor/TabularEditor3/issues/355). +- Ensure DAX scripts are parsed immediately when loaded from a file, see issue [#352](https://github.com/TabularEditor/TabularEditor3/issues/352). +- Fix bug that caused TE3 to stop syncing metadata from AS after the first change, see [#353](https://github.com/TabularEditor/TabularEditor3/issues/353). +- Fix issue with dependency tree not getting correctly rebuilt in some cases, see [#364](https://github.com/TabularEditor/TabularEditor3/issues/364). +- Replace existing table should no longer cause a crash, see issue [#368](https://github.com/TabularEditor/TabularEditor3/issues/368). +- Fix BPA not running until BPA view is first shown, see issue [#367](https://github.com/TabularEditor/TabularEditor3/issues/367). +- Use a single partition for AS change detection when connected to AS standard tier (which doesn't allow tables with multiple partitions). See [#336](https://github.com/TabularEditor/TabularEditor3/discussions/336). +- Inherit perspective membership for columns added through schema compare. See issue [#342](https://github.com/TabularEditor/TabularEditor3/discussions/342). +- Use default network credentils for web proxy (should solve issue with 407-errors when connecting to AS behind proxy). +- Semantic analyzer should no longer report an error when variable references are quoted, see issue [#302](https://github.com/TabularEditor/TabularEditor3/discussions/302). +- Improved display of error messages from Pivot Grids (they now appear in the **Messages view**). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_2_2_de.md b/content/localization/de/3_2_2_de.md new file mode 100644 index 00000000..a09dbdd6 --- /dev/null +++ b/content/localization/de/3_2_2_de.md @@ -0,0 +1,75 @@ +# Tabular Editor 3.2.2 + +- Download [Tabular Editor 3.2.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.2](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Improvements in 3.2.2 + +- Added support for Query Groups (aka. Power Query "folders") on partitions and named expressions +- Prompt for first partition type. See [#406](https://github.com/TabularEditor/TabularEditor3/issues/406) +- Aligned display of relationship names to be similar to how VertiPaq Analyzer in DAX Studio displays the names. +- Allow debug commas in the Expression Editor, see [#407](https://github.com/TabularEditor/TabularEditor3/issues/407) +- Allow doubleclicking on any expression object in the TOM Explorer (such as partitions) to bring the quick editor into view +- Changed "Mixed" label to "Hybrid" on tables that contain multiple partitions types +- Pivot Grid: + - Pivot Grid now displays a grand total when slicing on a field that only has a single value (when field is used in the rows/columns area) + - Fields added to the Pivot Grid through the TOM Explorer context menu are now added "right-most".- Focus pivot grid cell on right-click +- DAX debugger improvements: + - Can now view and enable/disable individual filters from the outer filter context + - Added tooltips for watch/locals value types. + - Better determination and ordering of local items from current call (includes subexpressions within the same evaluation context, etc.) + - No longer shows a context transition on the evaluation context stack, when debugging a measure reference (step into the measure reference to see the context transition) + - No longer use TREATAS against SSAS 2016 + - Improved F10 (step over) within measures + - Improved auto-complete for Watch expression editor (is now able to suggest row context columns, variables, etc.) +- Updated TOM to [19.34.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/) + +## Bugfixes in 3.2.2 + +- Added more TOM properties, i.e.: Refresh Policy Mode (used to set up Hybrid tables refresh policy) +- Fix activation wizard hang, see [#419](https://github.com/TabularEditor/TabularEditor3/issues/419) +- Make sure custom toolbars can still be dragged/docked and customized after first layout restore. See issue [#413](https://github.com/TabularEditor/TabularEditor3/issues/413) +- Fix issue with properties panel not showing when invoking through context menu, see [#375](https://github.com/TabularEditor/TabularEditor3/issues/375) +- Prevent crash when navigating to Data Refresh from status bar, see issue [#370](https://github.com/TabularEditor/TabularEditor3/issues/370) +- Fixed an issue where application crashes when closing while a refresh is running in the background. +- Prevent expression editor from appearing when clicking in the Diagram. See issue [#43](https://github.com/TabularEditor/TabularEditor3/issues/43). Also improves behavior of selecting/dragging columns in the diagram view. +- Added missing fields to VeritPaq Analyzer, see [#372](https://github.com/TabularEditor/TabularEditor3/issues/372) +- Improved Pivot Grid behavior of calculation group columns. See [#412](https://github.com/TabularEditor/TabularEditor3/issues/412) +- Ensure Dependency View is updated every time a semantic analysis completes (such as when a model is modified through Power BI), see [#401](https://github.com/TabularEditor/TabularEditor3/issues/401) +- Do not suggest calc group functions in auto-complete, unless writing a calc item expression, see issue [#387](https://github.com/TabularEditor/TabularEditor3/issues/387) +- Fixed an issue where after uncommenting a selection, "undo" no longer behaves correctly. See [#301](https://github.com/TabularEditor/TabularEditor3/issues/301) +- Added shortcuts for comment (Ctrl+Shift+K)/uncomment (Ctrl+Shift+U). See [#371](https://github.com/TabularEditor/TabularEditor3/issues/371) +- Added shortcuts (Alt+Up/Down arrow) for moving selected lines up/down in text editors. See [#371](https://github.com/TabularEditor/TabularEditor3/issues/371) +- Fix stackoverflow exception when dragging windows around in certain ways. See [#354](https://github.com/TabularEditor/TabularEditor3/issues/354) +- Fix bug with macro recorder not stopping when a C# script view is closed, causing subsequent crash when a model object or property is changed. +- Macro recorder now also produces code for calc item expression changes as well as hierarchy level and calc item ordinal changes. See [#230](https://github.com/TabularEditor/TabularEditor3/issues/230) +- Debugger: Fix DAX generation for variables in outer filter context, see issue [#418](https://github.com/TabularEditor/TabularEditor3/issues/418) +- Check for and delete TablePermissions with invalid table references upon model load (previously, TE would not allow loading a model with such invalid references) +- Clear filter when a field is removed/hidden from a Pivot Grid, see issue [#427](https://github.com/TabularEditor/TabularEditor3/issues/427) + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_2_3_de.md b/content/localization/de/3_2_3_de.md new file mode 100644 index 00000000..4d989808 --- /dev/null +++ b/content/localization/de/3_2_3_de.md @@ -0,0 +1,64 @@ +# Tabular Editor 3.2.3 + +- Download [Tabular Editor 3.2.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.3](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Improvements in 3.2.3 + +- Updated TOM to [19.36.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/) +- Use compatibility level 1569 for new PBI models +- Allow serialization of CalculationGroups and CalculationItems using ExportProperties. See [#976](https://github.com/TabularEditor/TabularEditor/issues/976) +- Allow specifying MemberID on .AddExternalMember and .AddWindowsMember, see [#484](https://github.com/TabularEditor/TabularEditor3/issues/484) and [#483](https://github.com/TabularEditor/TabularEditor3/issues/483) +- Allow specifying raw XMLA in calls to ExecuteCommand, as discussed in [#495](https://github.com/TabularEditor/TabularEditor3/issues/495) +- Allow copying Pivot Grid MDX query to clipboard by right-clicking anywhere in the Pivot Grid, see [#494](https://github.com/TabularEditor/TabularEditor3/issues/494). +- Improved BPA view (show severity, category) as well as tooltips. See [#489](https://github.com/TabularEditor/TabularEditor3/issues/489). +- Change default on the VertiPaq Analyzer "Read statistics from data" setting to "false" to align with DAX Studio / Bravo. +- Added new option to make Auto Complete popups less aggressive (only popup after entering a letter character), see[#459](https://github.com/TabularEditor/TabularEditor3/issues/459/). Locate this setting under **Tools > Preferences > DAX Editor > Code Assist**. + +## Bugfixes in 3.2.3 + +- Fix issue with table permissions not being properly deserialized. See [#446](https://github.com/TabularEditor/TabularEditor3/issues/446). +- Fix crash during startup with certain layouts, see issue [#455](https://github.com/TabularEditor/TabularEditor3/issues/455). +- Fixed an issue that could cause the application to crash when measures or other objects have curly braces in their names. +- Remove asterisk'ed properties (keys, passwords) when "Include sensitive" is set to false. See [#479](https://github.com/TabularEditor/TabularEditor3/issues/479). +- Fix save-to-folder serialization when using invalid file/folder names as object names, or when an object name contains a trailing space. Similar to [#952](https://github.com/TabularEditor/TabularEditor/issues/952) and [#978](https://github.com/TabularEditor/TabularEditor/issues/978). +- Show all refresh options if at least 1 non-calculated table is selected, see issue [#487](https://github.com/TabularEditor/TabularEditor3/issues/487) +- Fix semantic analyzer column lineage issue with UNION, see [#482](https://github.com/TabularEditor/TabularEditor3/issues/482). +- Fix issue with shortcuts not working on floating windows, see [#480](https://github.com/TabularEditor/TabularEditor3/issues/480). +- Do not show "EnableRefreshPolicy" property for calc tables, calc groups, or DirectQuery tables, see [#470](https://github.com/TabularEditor/TabularEditor3/issues/470). +- Fix Import Table Wizard issue when creating new structured data sources in some scenarios (for example, Oracle data sources). +- Fix crash when trying to add Structured ODBC data source through Import wizard. +- Fix diagram select issue when clicking on a column in another table. +- Fix issue with TOM explorer not updating to show the proper object type of a partition when its mode is changed +- Fix format of measures displayed in Pivot Grid, see [#492](https://github.com/TabularEditor/TabularEditor3/issues/492) +- Auto-complete should not insert parentheses if there's already an opening parenthesis by the cursor, see[#459](https://github.com/TabularEditor/TabularEditor3/issues/459/) +- Fixed autocomplete for CONVERT 2nd param (data type), see [#474](https://github.com/TabularEditor/TabularEditor3/issues/474). +- Starting a new rename operation should complete any existing ones, see[#461](https://github.com/TabularEditor/TabularEditor3/issues/461/). +- Fix issue with multiple EVALUATE statements not respecting ORDER BY when executing selection only. Also fixed an issue where ORDER BY didn't work on tables with names that are also DAX functions. See [#472](https://github.com/TabularEditor/TabularEditor3/issues/472) + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_3_0_de.md b/content/localization/de/3_3_0_de.md new file mode 100644 index 00000000..bb6daadf --- /dev/null +++ b/content/localization/de/3_3_0_de.md @@ -0,0 +1,87 @@ +# Tabular Editor 3.3.0 + +- Download [Tabular Editor 3.3.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.3.0](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +Tabular Editor 3 is now using [.NET 6](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-6) (we've been using .NET Framework 4.8.2 until now). With .NET 6, Microsoft has provided a unified and modern application development platform, which includes multiple performance improvements and security updates. As a Tabular Editor 3 user, you shouldn't notice any differences other than a slightly increased download size and possible performance improvements. + +**NOTE**: You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0. Make sure to grab the **Desktop** runtime that matches your version of Tabular Editor 3: + +- [.NET Desktop Runtime x64](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.6-windows-x64-installer) +- [.NET Desktop Runtime x86](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.6-windows-x86-installer) + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_3_1_de.md b/content/localization/de/3_3_1_de.md new file mode 100644 index 00000000..298364d0 --- /dev/null +++ b/content/localization/de/3_3_1_de.md @@ -0,0 +1,101 @@ +# Tabular Editor 3.3.1 + +- Download [Tabular Editor 3.3.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.1](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) as well as the [Microsoft Visual C++ Redistributable package](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.1 + +- New Installer which automatically downloads and installs missing .NET Runtime and VC++ prerequisites, if they are missing. +- Added support for the DAX [`NETWORKDAYS`](https://dax.guide/NETWORKDAYS/) function. +- Updated TOM to [19.42.0.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) + +## Bugfixes in 3.3.1 + +- Fixed an issue with C# tooltips not showing xmldoc comments, unless application launched from installation folder. +- Semantic Analyzer now correctly reports an error when using special MDX reserved keywords as unquoted table references. +- Fixed an issue where attempting to deploy a model loaded from a .pbit file would fial. +- Fixed an issue with compilation of C# scripts and macros. See [#570](https://github.com/TabularEditor/TabularEditor3/issues/570), [#573](https://github.com/TabularEditor/TabularEditor3/issues/573) and [#580](https://github.com/TabularEditor/TabularEditor3/issues/580). +- Fixed an issue that prevented loading models containing calculation groups with one or more erroneous measures, see [#571](https://github.com/TabularEditor/TabularEditor3/issues/571). +- Fixed an issue with the diagram not automatically refreshing after reloading a model, see [#572](https://github.com/TabularEditor/TabularEditor3/issues/572). +- Fixed an issue that prevented the C# script engine from importing certain DLLs, see [#574](https://github.com/TabularEditor/TabularEditor3/issues/574). +- Fixed an issue that prevented connecting to Power BI Desktop after making a choice in the "Local instances" dropdown, see [#579](https://github.com/TabularEditor/TabularEditor3/issues/579). +- Fixed an issue where the TOM Explorer would select all objects (even when filtering the TOM Explorer), when pressing CTRL+A, see [#582](https://github.com/TabularEditor/TabularEditor3/issues/582). +- Various stability improvements based on anonymous telemetry/error reports. + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_3_2_de.md b/content/localization/de/3_3_2_de.md new file mode 100644 index 00000000..da2b57e1 --- /dev/null +++ b/content/localization/de/3_3_2_de.md @@ -0,0 +1,106 @@ +# Tabular Editor 3.3.2 + +- Download [Tabular Editor 3.3.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.2](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) as well as the [Microsoft Visual C++ Redistributable package](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.3.2 + +- Fixed a bug in the installer, which caused some files not to be updated when performing an in-place upgrade, which in turn could cause application crashes and other issues, see [#586](https://github.com/TabularEditor/TabularEditor3/issues/586). +- Added support for the `ExpressionSource` property on the [NamedExpression](xref:TabularEditor.TOMWrapper.NamedExpression) class. + +## Improvements in 3.3.1 + +- New Installer which automatically downloads and installs missing .NET Runtime and VC++ prerequisites, if they are missing. +- Added support for the DAX [`NETWORKDAYS`](https://dax.guide/NETWORKDAYS/) function. +- Updated TOM to [19.42.0.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) + +## Bugfixes in 3.3.1 + +- Fixed an issue with C# tooltips not showing xmldoc comments, unless application launched from installation folder. +- Semantic Analyzer now correctly reports an error when using special MDX reserved keywords as unquoted table references. +- Fixed an issue where attempting to deploy a model loaded from a .pbit file would fial. +- Fixed an issue with compilation of C# scripts and macros. See [#570](https://github.com/TabularEditor/TabularEditor3/issues/570), [#573](https://github.com/TabularEditor/TabularEditor3/issues/573) and [#580](https://github.com/TabularEditor/TabularEditor3/issues/580). +- Fixed an issue that prevented loading models containing calculation groups with one or more erroneous measures, see [#571](https://github.com/TabularEditor/TabularEditor3/issues/571). +- Fixed an issue with the diagram not automatically refreshing after reloading a model, see [#572](https://github.com/TabularEditor/TabularEditor3/issues/572). +- Fixed an issue that prevented the C# script engine from importing certain DLLs, see [#574](https://github.com/TabularEditor/TabularEditor3/issues/574). +- Fixed an issue that prevented connecting to Power BI Desktop after making a choice in the "Local instances" dropdown, see [#579](https://github.com/TabularEditor/TabularEditor3/issues/579). +- Fixed an issue where the TOM Explorer would select all objects (even when filtering the TOM Explorer), when pressing CTRL+A, see [#582](https://github.com/TabularEditor/TabularEditor3/issues/582). +- Various stability improvements based on anonymous telemetry/error reports. + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_3_3_de.md b/content/localization/de/3_3_3_de.md new file mode 100644 index 00000000..e30e1a99 --- /dev/null +++ b/content/localization/de/3_3_3_de.md @@ -0,0 +1,132 @@ +# Tabular Editor 3.3.3 + +- Download [Tabular Editor 3.3.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.3](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.3 + +- **The Import Table Wizard now allows you to import tables from a Power BI Dataflow.** Note that this option is only available when working on Power BI datasets. Moreover, Tabular Editor can now perform a schema update of tables based on Power BI dataflows, even when working offline (i.e. when not connected to the Power BI XMLA endpoint). +- C# scripts: Entering a closing parenthesis or bracket now closes the auto-complete box. Moreover, the pre-selection of the auto-complete box based on the current search string has been improved. +- C# scripts: Runtime error messages now include stack traces, making debugging easier. +- The default compatibility level for new Power BI datasets is now 1570. +- Under **Tools > Preferences > File formats**, we now have a set of options that allow you to specify the default compatibility level and whether or not to use a workspace database, when creating a new model. +- Instead of throwing a connection error, SQL server connections that fail because of an untrusted certificate, now prompt you if you want to trust the certificate and reconnect. +- It is now possible to disable automatic formula fix-up (under Tools > Preferences > Modeling Operations), see also [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- Added an .msi version of the installer, which is useful for unattended installations or installations through software packaging. +- 32 bit installers should now allow installation on 64 bit systems (but not vice versa). +- Added "Lock column width" right-click menu option on TOM Explorer, table preview, VertiPaq analyzer, etc. When checked, columns are always resized to match the width of the grid, changing the behavior of "Best fit (All columns)". This solves issue [#603](https://github.com/TabularEditor/TabularEditor3/issues/603) and also addresses one of the suggestions in [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- More column options in DAX query results, when right-clicking on a result column header. For example, you can hide/show columns, display a find panel for quickly filtering using a text string, and even group by columns to display the query results hierarchically. Note that sorting/grouping/filtering of query results only happens locally on the cached result (which is typically the first 1000 rows of a query). Adjust your DAX query if you need to perform these operations on the full set of data. +- BPA rules can now be downloaded from URLs using basic authentication, see [#604](https://github.com/TabularEditor/TabularEditor3/issues/604). + +## Bugfixes in 3.3.3 + +- Fix several issues related to macro compilation/execution, see [#587](https://github.com/TabularEditor/TabularEditor3/issues/587) and [#573](https://github.com/TabularEditor/TabularEditor3/issues/573). +- Fix issue with calls to `FormatDax` through scripts not working when using daxformatter.com, see [#592](https://github.com/TabularEditor/TabularEditor3/issues/592). +- Fix issue with scripts not able to call the Error and Warning global methods +- Fix issue with macros not being able to compile when the code contains an aliased using directive +- Fix issue with macros NullReferenceException when calling methods like EvaluateDax, etc. +- Fixed syntax highlighting of unquoted table references which are also keywords (for example 'Currency' is valid as an unquoted table reference in DAX, but it was previously colored as if it was a keyword) +- Got rid of the Visual C++ Redistributable dependency, which, when not installed, caused Tabular Editor to crash often. + +## Bugfixes in 3.3.2 + +- Fixed a bug in the installer, which caused some files not to be updated when performing an in-place upgrade, which in turn could cause application crashes and other issues, see [#586](https://github.com/TabularEditor/TabularEditor3/issues/586). +- Added support for the `ExpressionSource` property on the [NamedExpression](xref:TabularEditor.TOMWrapper.NamedExpression) class. + +## Improvements in 3.3.1 + +- New Installer which automatically downloads and installs missing .NET Runtime and VC++ prerequisites, if they are missing. +- Added support for the DAX [`NETWORKDAYS`](https://dax.guide/NETWORKDAYS/) function. +- Updated TOM to [19.42.0.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) + +## Bugfixes in 3.3.1 + +- Fixed an issue with C# tooltips not showing xmldoc comments, unless application launched from installation folder. +- Semantic Analyzer now correctly reports an error when using special MDX reserved keywords as unquoted table references. +- Fixed an issue where attempting to deploy a model loaded from a .pbit file would fial. +- Fixed an issue with compilation of C# scripts and macros. See [#570](https://github.com/TabularEditor/TabularEditor3/issues/570), [#573](https://github.com/TabularEditor/TabularEditor3/issues/573) and [#580](https://github.com/TabularEditor/TabularEditor3/issues/580). +- Fixed an issue that prevented loading models containing calculation groups with one or more erroneous measures, see [#571](https://github.com/TabularEditor/TabularEditor3/issues/571). +- Fixed an issue with the diagram not automatically refreshing after reloading a model, see [#572](https://github.com/TabularEditor/TabularEditor3/issues/572). +- Fixed an issue that prevented the C# script engine from importing certain DLLs, see [#574](https://github.com/TabularEditor/TabularEditor3/issues/574). +- Fixed an issue that prevented connecting to Power BI Desktop after making a choice in the "Local instances" dropdown, see [#579](https://github.com/TabularEditor/TabularEditor3/issues/579). +- Fixed an issue where the TOM Explorer would select all objects (even when filtering the TOM Explorer), when pressing CTRL+A, see [#582](https://github.com/TabularEditor/TabularEditor3/issues/582). +- Various stability improvements based on anonymous telemetry/error reports. + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_3_4_de.md b/content/localization/de/3_3_4_de.md new file mode 100644 index 00000000..6f476f96 --- /dev/null +++ b/content/localization/de/3_3_4_de.md @@ -0,0 +1,73 @@ +# Tabular Editor 3.3.4 + +- Download [Tabular Editor 3.3.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.4](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.4 + +- Updated TOM to v. [19.46.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Updated Microsoft.Data.SqlClient to v. [5.0.0](https://www.nuget.org/packages/Microsoft.Data.SqlClient). +- Updated SciLexer.dll to v. 4.4.6, which is not affected by [this CVE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2019-16294). +- Multiple minor fixes and improvements. +- New/Edit Relationship dialog improvements: Columns are sorted alphabetically and by matching type. We now also suggest the "to-column" based on the name of the "from-column". +- Changed default CL for new Power BI datasets to 1571 and added support for the [ObjectTranslation.Altered](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.objecttranslation.altered?view=analysisservices-dotnet) property, which should be set to "true" to prevent metadata translations from being overwritten from the source, when creating DirectQuery over AS datasets. +- Added a new shortcut, **Ctrl+Alt+S**, to save the current model. See [#595](https://github.com/TabularEditor/TabularEditor3/issues/595), [#561](https://github.com/TabularEditor/TabularEditor3/issues/561). +- Added shortcut **Ctrl+Shift+F6** for Debug Comma DAX formatting. See [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- Offline Schema Detection should now work when parameters such as Server Name and Database Name are stored in shared M expressions. + +## Bugfixes in 3.3.4 + +- Fixed an issue where the Udate Table Schema option would report all columns as removed, see [#612](https://github.com/TabularEditor/TabularEditor3/issues/612). +- Fix false semantic analyzer errors when using nested filter expressions. +- Fix false semantic analyzer errors when using `NATURALINNERJOIN` / `NATURALLEFTOUTERJOIN` on tables that are joind by relationships instead of common columns. +- Fix issue when trying to show connection dialog for ODBC connectors, see [#448](https://github.com/TabularEditor/TabularEditor3/issues/448) +- AAD authentication with Microsoft.Data.SqlClient now displays a modal popup (instead of opening the OS browser) +- Fix issue with SQL Server connection dialog "advanced button" sometimes causing a crash. +- Table Import Wizard now allows previewing data on Azure Synapse (the NOLOCK hint is no longer added to the data preview query) +- 32 bit installer should now correctly check for the 32 bit .NET Desktop Runtime +- DAX autocomplete can now also suggest Variant-typed scalar variables, see [#615](https://github.com/TabularEditor/TabularEditor3/issues/615) +- Fixed an issue with the DAX debugger not being able to display local/watch expressions with nested conditional branches. +- Include SciLexer.dll in application folder instead of extracting/Loading it to %LocalAppData%\Temp. Should prevent the "Exception has been thrown by the target of an invocation" error seen sometimes when group policy prevents loading DLLs from this location. +- Fixed an issue with the Property Grid not being able to set nested properties on multiple selections. See [#614](https://github.com/TabularEditor/TabularEditor3/issues/614). +- Fixed an issue where the Property Grid did not refresh to show dynamically added/removed properties, for example when toggling the "Incremental Refresh Policy" property. +- Fixed an issue where an AAS Developer Tier instance would be regarded as a Standard Tier instance, preventing connectivity with TE3 Business Edition +- Fix issue with NAMEOF autocomplete not showing all column/measure references in some situations, see [#620](https://github.com/TabularEditor/TabularEditor3/issues/620). +- Fixed an issue with certain DAX keywords (START, ORDER, RETURN, etc.) not being treated as an error, when used as table references without quotes. This bug also prevented proper formatting of code containing a quoted reference to such tables. +- Fixed the "4096 (0x1000) is an invalid culture identifier", see [#576](https://github.com/TabularEditor/TabularEditor3/issues/576). +- Prevent find/replace search crash, see [#611](https://github.com/TabularEditor/TabularEditor3/issues/611). +- Show all properties when in read-only mode, see [#596](https://github.com/TabularEditor/TabularEditor3/issues/596). +- Removed animation for pinned/unpinned windows, see [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- Don't autobrace in DAX comments, see [#597](https://github.com/TabularEditor/TabularEditor3/issues/597). +- Fix issue with default CL value causing crash in Preferences dialog when set to a non-standard value. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_3_5_de.md b/content/localization/de/3_3_5_de.md new file mode 100644 index 00000000..7a9bcd86 --- /dev/null +++ b/content/localization/de/3_3_5_de.md @@ -0,0 +1,80 @@ +# Tabular Editor 3.3.5 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.3.5 downloads: + +- Download [Tabular Editor 3.3.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.5 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.3.5.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x64.exe) | `5DEBB2304B418C4654BADCB18A477192D95A1308EA0BFF64E9C886846D991F6B` | +| [TabularEditor.3.3.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.msi) | `CC5A83963C4C69C3778E0729A0726B473BA9E85F895CDD9F60C6D480A8C81C9A` | +| [TabularEditor.3.3.5.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.zip) | `C7F2FEDC9F00EE0EFC7633AA72FB7C338FCFFDF952FCB2054B6E7A353972E187` | +| [TabularEditor.3.3.5.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x86.exe) | `0684C85CFD1ADA9290924345B17FCA5743D4B94C9D22E21D50DFE10D0B27676D` | +| [TabularEditor.3.3.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.msi) | `3A1BF0431BC0271598139D5AA28007D05E1B6C2D800953AAD29091606C2C3CD5` | +| [TabularEditor.3.3.5.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.zip) | `92F7014F15513BBF41AF4800FD8CCDF83B20C13D3C78005C96CE45F8CF7E8DF1` | + +*** + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.5 + +- New splash screen and icon, matching our new website brand. +- Updated TOM to [19.48.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Tabular Editor 3 now has a set of [configurable policies](https://docs.tabulareditor.com/common/policies.html), which let IT organisations govern certain Tabular Editor 3 features. +- Column widths can now be locked on the Messages, Macros and BPA views. +- Improved the Macros view with a right-click menu and toolbar buttons to open/edit macros. +- Added semantic analyzer and autocomplete support for the [`EVALUATEANDLOG`](https://dax.guide/evaluateandlog) and [`SAMPLEAXISWITHLOCALMINMAX`](https://dax.guide/sampleaxiswithlocalminmax) DAX functions. +- The "Revert" File menu option is now also available when a model was loaded from disk. +- DAX debugger now supports more types of DAX queries, specifically it is now possible to debug cell values when the query uses [`ADDCOLUMNS`](https://dax.guide/addcolumns), [`CALCULATETABLE`](https://dax.guide/calculatetable), [`SAMPLE`](https://dax.guide/sample), [`SAMPLEAXISWITHLOCALMINMAX`](https://dax.guide/sampleaxiswithlocalminmax), [`SUBSTITUTEWITHINDEX`](https://dax.guide/substitutewithindex) and [`SUMMARIZE`](https://dax.guide/summarize). This should ensure that most types of queries generated by PBI Desktop can be used with the TE3 debugger. Note that only cell values that originate from explicit measures can be debugged. +- Added a "Step into selection" option in the DAX debugger to make navigation easier. Use the shortcut key (Ctrl+B) or right-click anywhere in the code and choose "Step into selection" to navigate. +- Better visualisation of objects with errors/warnings in the TOM Explorer. Better icons in the Data Refresh tab. + +## Bugfixes in 3.3.5 + +- More reliable detection of Azure AS Developer tier (D1), which would sometimes prevent Business Edition customers from accessing the AAS instance. +- Allow role name changes in PBI Desktop restricted mode, see [#624](https://github.com/TabularEditor/TabularEditor3/issues/624). +- Fix SortByColumn not settable, see [#625](https://github.com/TabularEditor/TabularEditor3/issues/625). +- Fixed an issue that would prevent Tabular Editor to connect to ODBC data sources, when connection string properties were specified as "Extended Properties" in the connection string. +- Use TOP row limit clause for Snowflake ODBC by default. +- Fix issue with wait spinner overlapping "SelectItem" dialog when executed as script/macro. See [#622](https://github.com/TabularEditor/TabularEditor3/issues/622). +- Fixed an issue with how the debugger handles (blank) and binary values in filters. +- Automatic fallback to `Protocol Format=xml` if the connection fails due to invalid Binary XML. See [#637](https://github.com/TabularEditor/TabularEditor3/issues/637). +- Fix "Batch rename" not available in Power BI Desktop models. +- Add M parser support for special characters, see [#638](https://github.com/TabularEditor/TabularEditor3/issues/638). +- Treat 'version' as a DAX reserved word (i.e. always quote and show an error if used unquoted or as a variable name). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/de/3_3_6_de.md b/content/localization/de/3_3_6_de.md new file mode 100644 index 00000000..7c106038 --- /dev/null +++ b/content/localization/de/3_3_6_de.md @@ -0,0 +1,86 @@ +# Tabular Editor 3.3.6 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.3.6 downloads: + +- Download [Tabular Editor 3.3.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.6 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.3.6.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x64.exe) | `87D03220E55CF557356B82B718E80723FC2C92C840452A2B584488990E7CE04F` | +| [TabularEditor.3.3.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.msi) | `372543CF203E5796F917F370FE9533C8C26BF549EE730A8FAEA366B8D473BA8A` | +| [TabularEditor.3.3.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.zip) | `58025CA72C569DB9F1FDAA02A7EBEDB00FB0C22B39C669454219AABC9F5291AC` | +| [TabularEditor.3.3.6.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x86.exe) | `4699A0C2B0C67EFD2301F1F4F886A6B58160925AC2CBBEE83C49CFB7B4ADBF9D` | +| [TabularEditor.3.3.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.msi) | `F37723385F9B0EB80F797D4853E5250D3E1B152FAAC3F4BBD0FAE06B5F441090` | +| [TabularEditor.3.3.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.zip) | `5DC066325E635769487EE23D52BECF410665028C20C76E4A51CB1647E83DD783` | + +*** + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.6 + +- Updated TOM to [19.52.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Added support for measure Format String expressions (Compatibility Level 1601 or higher). +- Table `SourceExpression` and `PollingExpression` M queries can now be edited through the primary Expression Editor. +- Right-clicking on an expression property (such as `SourceExpression`, `PollingExpression`, `FormatStringExpression`, etc.) in the property grid now has a shortcut to edit the value in the primary Expression Editor. +- A Data Column's `SourceColumn` property value now appears in the "Expression" column of the TOM Explorer +- Added TOM Explorer and VertiPaq Analyzer column header tooltips. +- M parser improvements and support for additional M functions when performing offline Schema Updates, including support for CommandTimeout, and other connection options. +- Tabular Editor now displays a toast notification when a data refresh operation finishes in the background. This can be disabled under **Tools > Preferences > Features > Notifications**. +- Added support for new DAX functions ([OFFSET](https://dax.guide/offset), [TOJSON](https://dax.guide/tojson), [TOCSV](https://dax.guide/tocsv), and more). +- Macros are now compiled in a background thread, which improves application start-up time, and also fixes [#708](https://github.com/TabularEditor/TabularEditor3/issues/708). +- Updated to use the latest version of [VertiPaq Analyzer](https://github.com/sql-bi/VertiPaq-Analyzer). +- Added Compatibility Level 1600 as new default for SQL Server 2022 models. + +## Bugfixes in 3.3.6 + +- DAX debugger now correctly preserves the original query expression when debugging, thus preserving the original shadow filter context and any auto-exist modifications to table filters. Among other things, this means that expressions containing `ALLSELECTED` can now be debugged properly, see [#669](https://github.com/TabularEditor/TabularEditor3/issues/669). +- Improved async connectivity during Table Import Wizard / Schema Update. Also improved error handling - for example when SQL connection fails due to a missing certificate. +- Fixed an issue with the Delete button not working in the Macros view. +- Fixed an issue with the M parser not supporting records when the field name contains a space, such as `[Order Date]`. This should allow the Schema Update feature to work in offline mode, when an M expression contains such a record reference. +- Fixed a bug where the .tmuo file was not updated when using workspace mode with a folder structure, causing credentials to not be saved between sessions. +- Fixed a bug that allows searching all expression properties, see [#663](https://github.com/TabularEditor/TabularEditor3/issues/663). +- Fixed an issue where the debugger script did not close when closing a model. +- Removed the possibility of adding partitions to calculated tables. +- Fixed an issue where the application would sometimes crash when using the Find/Replace dialog. +- Fixed incorrect tooltip for New DAX Script button, see [#678](https://github.com/TabularEditor/TabularEditor3/issues/678). +- Fixed an issue where floating docs being closed would not prompt for save, see [#673](https://github.com/TabularEditor/TabularEditor3/issues/673). +- Fixed an issue where the column filter on a Data Preview, would sometimes crash the application when toggling (All) or (Blank) values. +- Fixed an issue with Snowflake data type inference when using Schema Update or Table Import Wizard (NUMBER columns would get imported as Double when they should be imported as Int64 or Decimal). +- Semantic Analyzer should no longer report an error when extension columns are used in [SUMMARIZE](https://dax.guide/summarize). +- Semantic Analyzer now reports an error when 'ID' is used as a table reference without quotes. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_4_0_de.md b/content/localization/de/3_4_0_de.md new file mode 100644 index 00000000..52fef2a1 --- /dev/null +++ b/content/localization/de/3_4_0_de.md @@ -0,0 +1,104 @@ +# Tabular Editor 3.4.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.4.0 downloads: + +- Download [Tabular Editor 3.4.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.4.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.4.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x64.exe) | `FC244BDF95D4401B36816F743BF872E2533800DDC1EDD3FAA5679F20B584F762` | +| [TabularEditor.3.4.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.msi) | `FEE6D3ABE2EE58CEC3D2DFF1A83475347C70645AB3604B92FB3FBE586C9B01DD` | +| [TabularEditor.3.4.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.zip) | `0E62FBA977DEDC80ABA49DE469B8DDD8987C11641F722207A0CF6C03333D1682` | +| [TabularEditor.3.4.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x86.exe) | `E2C7BDA32F12B8778F6E6FD468E6298061FE96D88CBCBC5629137B70100ECC88` | +| [TabularEditor.3.4.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.msi) | `717889EA2808F96E26869A6522D331F92935A7F3C7D50D51023A2127CADB2A98` | +| [TabularEditor.3.4.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.zip) | `A6CB763B9476A92E781221C9278DFB4D0813D81C0B951C0350E96FFBF86AE37E` | + +*** + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New features in 3.4.0 + +- Updated TOM to [19.54.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Tabular Editor 3 now supports the [new DAX window functions](https://pbidax.wordpress.com/2022/12/15/introducing-dax-window-functions-part-1/) announced in the Power BI Desktop December 2022 update. +- Customizable keyboard shortcuts are here! Do you want to always use CTRL+S to save the model, regardless of context? Do you want to assign a hotkey to perform a model refresh? How about an editor shortcut to [select all occurrences of current selection](https://github.com/TabularEditor/TabularEditor3/issues/630)? Find this feature under **Tools > Preferences > Keyboard**. More info [here](xref:preferences#tabular-editor--keyboard). +- All code editors now allow multiple selections (i.e. hold down CTRL and drag using the mouse, to create a new selection), in addition to rectangular selections (holding down ALT while dragging or using SHIFT + arrow keys). + +## Minor improvements in 3.4.0 + +- Tabular Editor 3 now displays the correct icon in the Power BI External Tools ribbon. +- Consolidated editing of Column-type properties in the property grid. You can now specify a column by typing its name in the property grid. When more than 7 columns are present, a "select column" dialog appears instead of a dropdown. This also fixes [#738](https://github.com/TabularEditor/TabularEditor3/issues/738). +- Removed square brackets from column names in Table Preview +- It is now possible to connect and select a different Power BI workspace in the Import Table Wizard. +- Pivot Grid field list is now a dockable window, see [#742](https://github.com/TabularEditor/TabularEditor3/issues/742). +- DAX calltips are now formatted correctly when the source descriptions contain HTML tags. +- All code editors now have much improved rectangular selections, when using the keyboard to perform selection. Moreover, copy/paste now works more intuitively with rectangular selections. +- Added option to lock menus and toolbar, to prevent accidentally dragging them around, in the Tools > Customize dialog (under the "Options" tab). +- Scintilla multiple selection add next/add each now respects search flags specified in the Find Dialog. +- Allow File.SaveModel shortcut to work regardless of context, see [#762](https://github.com/TabularEditor/TabularEditor3/issues/762). +- It is now possible to cancel a long-running save operation, such as when the database is locked by a refresh operation. See [#730](https://github.com/TabularEditor/TabularEditor3/issues/730). +- Create/edit relationship dialog can now be resized, see [#732](https://github.com/TabularEditor/TabularEditor3/issues/732). +- Allow arrow key expand/collapse on all tree lists (including BPA, dependency view and data refresh view), see [#775](https://github.com/TabularEditor/TabularEditor3/issues/775). +- We've listened to your feedback! "Show relationships from table" is now back in the Dependency View, see [#731](https://github.com/TabularEditor/TabularEditor3/issues/731). + +## Bugfixes in 3.4.0 + +- The AAD connect dialog should now show up as a modal dialog in all cases. +- Create undo transaction when multiple objects are edited in batch +- An object property (such as SortByColumn) can now be cleared by right-clicking and choosing "Reset". +- Right-click shortcut for editing table expression properties (SourceExpression, PollingExpression, etc.) are now available, see [#721](https://github.com/TabularEditor/TabularEditor3/issues/721). +- Pivot Grid should no longer freeze when fields are dragged on top of it, see [#676](https://github.com/TabularEditor/TabularEditor3/issues/676). +- Fix issue [#723](https://github.com/TabularEditor/TabularEditor3/issues/723). +- Fixed an issue that prevented table schema updates and crashed the Import Table Wizard, when attempting to import from an existing Power BI Dataflow, specified in the .tmuo file. +- Fixed an issue with the DAX debugger generating invalid watch expression DAX queries, see [#770](https://github.com/TabularEditor/TabularEditor3/issues/770). +- Fixed an issue which would sometimes cause the debugger windows to crash (showing red crosses on a white background). +- Fixed an issue where the Import Table Wizard would sometimes show Dataflows with no names. +- "Revert" button should always be enabled now. Moreover, a confirmation prompt is only shown when changes have been made. See [#729](https://github.com/TabularEditor/TabularEditor3/issues/729). +- Showing the field list no longer clears the Pivot Gird, see [#741](https://github.com/TabularEditor/TabularEditor3/issues/741). +- Fixed an issue where columns in the TOM Explorer would sometims be "cut off" when the application is launched. +- TOM Explorer now only allows adding EntityPartitions on Power BI datasets +- Fix dependency view crash issue, see [#758](https://github.com/TabularEditor/TabularEditor3/issues/758) +- Fixed an issue where floating windows could spawn outside the visible screen area when the application is restarted, see [#652](https://github.com/TabularEditor/TabularEditor3/issues/652). +- Fix issue with recent server not being persisted. +- Fixed a few bugs related to how actions appear in the "Model" and/or "Context" menu. For example, "Script DAX" in the Model menu, only scripted objects within the current selection, where as it was intended to script all objects in the model. +- Fix horizontal scrollbar behavior of text editors. +- SQL Connection Dialog should now persist its changes to the connection string, see [#755](https://github.com/TabularEditor/TabularEditor3/issues/755). +- Selecting a database after filtering the list in the "Choose database" dialog, now ensures that the correct database is actually loaded. See [#761](https://github.com/TabularEditor/TabularEditor3/issues/761). +- Fix issue when scrolling through tables (see [#733](https://github.com/TabularEditor/TabularEditor3/issues/733), and row count not updating when applying filter criteria. + +_The Tabular Editor 3 team wishes you all a great holiday season and a happy new year!_ + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_4_1_de.md b/content/localization/de/3_4_1_de.md new file mode 100644 index 00000000..d681e071 --- /dev/null +++ b/content/localization/de/3_4_1_de.md @@ -0,0 +1,92 @@ +# Tabular Editor 3.4.1 + +# [**Downloads**](#tab/downloads) + +> [!WARNING] +> This build has an error that causes the Semantic Analyzer to report incorrect "circular dependency" errors in DAX calculations. We recommend upgrading to [3.4.2](3_4_2.md) instead. + +Tabular Editor 3.4.1 downloads: + +- Download [Tabular Editor 3.4.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.4.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.4.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x64.exe) | `AFBB88611C71DA2BC546A15194CC55A646F9CE7BA4952BF839DA1E41E679A3AC` | +| [TabularEditor.3.4.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.msi) | `635CEB55B229937A15A1537919D7B8E555835BDF4F680D18E2716E1012D167E3` | +| [TabularEditor.3.4.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.zip) | `3A41845DB69F80F6887236B8469080B28FB6ACCBDBA4ACFAB6466E2938257DE2` | +| [TabularEditor.3.4.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x86.exe) | `5D9B05EFC3B5577F7FC199D1B6197493DF4E948A5F527BBD14453C44C49C9A54` | +| [TabularEditor.3.4.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.msi) | `F6B53BB2E0D3D323ECE9CACA46EDFB08A5194BAAC141FB037DFCB40FF6FBE23A` | +| [TabularEditor.3.4.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.zip) | `EC71D1A9648605E0ADBE5F0371EA1B552B46F93930806B599FBD1AFDCE8B9212` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New features in 3.4.1 + +- Updated TOM to [19.55.3](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- New [Perspective Editor](xref:perspective-editor) view. + +## Minor improvements in 3.4.1 + +- DAX debugger now supports window functions ([`OFFSET`](https://dax.guide/offset), [`INDEX`](https://dax.guide/index) and [`WINDOW`](https://dax.guide/window)). +- DAX debugger now lets you debug a measure that is being referenced in a table constructor, such as `EVALUATE { [Internet Sales] }` or in the [`ROW`](https://dax.guide/row) function. +- The **Evaluation Context** view now shows the expression of table variables used as filters. +- Resetting the window layout through the **Window** menu, now no longer affects toolbar buttons (these can be modified or reset through the **Tools > Customize** dialog). + +## Bugfixes in 3.4.1 + +- Fixed an issue with the search box above the keyboard command list in the preferences dialog. +- DAX editors now deal correctly with nested comments, see [#681](https://github.com/TabularEditor/TabularEditor3/issues/681). +- Attempting to debug query-scoped measures no longer causes a crash. +- Fixed an issue that caused relationship lines in the diagram view to become "stuck", see [#787](https://github.com/TabularEditor/TabularEditor3/issues/787). +- When tracking TOM Explorer selection in the dependency view, application should no longer crash when selecting a relationships, see [#782](https://github.com/TabularEditor/TabularEditor3/issues/782). +- Fixed the "DataSourceConverter cannot convert from TabularEditor.TOMWrapper.ProviderDataSource" error, when attempting to change or reset the DataSource property on a partition. +- Tabular Editor 3 should no longer replace blank characters at the end of file names with `%20`, when using "Save to folder". +- Expression Editor should no longer be empty until its header is clicked, see [#739](https://github.com/TabularEditor/TabularEditor3/issues/739). +- DAX debugger now correctly simulates the auto-exist behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/summarizecolumns). +- Fixed an issue where the presence of `ALL()`, `ALLSELECTED()`, and other filter removal functions, did not cause outer filters to be striked out (indicating that the filters had been overwritten) in the **Evaluation Context** view. +- Fixed the missing context menu option to refresh a Calculated Table or Calculation Group. +- Fixed an issue that would sometimes cause a crash when attempting to perform a schema update. +- It is now no longer possible to debug a measure that has been removed from the model (which would otherwise cause a crash). +- Better exception handling when objects are pasted into the TOM Explorer. +- Fixed an issue that would cause a crash when an object is deleted while being shown in the **Search Results** view. +- Fixed an issue that would cause a crash in the **Table Preview**, when columns or tables were deleted. +- Semantic Analyzer no longer reports an error when the `` parameter of a window function is left blank, or when it contains extension columns. See [#807](https://github.com/TabularEditor/TabularEditor3/issues/807). +- The "Reset" button in the Customize dialog should no longer remove all buttons from a toolbar. +- C# script editor should no longer insert an additional tab or newline character when performing an auto complete by pressing one of these keys. +- Fixed an issue when calling the `DependsOn.Deep()` method through a C# script. +- DAX editor should no longer crash while attempting to autoformat the code. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_4_2_de.md b/content/localization/de/3_4_2_de.md new file mode 100644 index 00000000..0fe4efea --- /dev/null +++ b/content/localization/de/3_4_2_de.md @@ -0,0 +1,61 @@ +# Tabular Editor 3.4.2 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.4.2 downloads: + +- Download [Tabular Editor 3.4.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.4.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.4.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x64.exe) | `A29C41F0EFCA0FC34D515C49B1EA1F74D0205A953851F20D50AA2513D86C4A64` | +| [TabularEditor.3.4.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.msi) | `177F3B15C3248561B01F528FD62BE804CF92176EB17B6CC10C7FF362F69A81CC` | +| [TabularEditor.3.4.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.zip) | `F586BCA4807D31F2DE47C3E1464D47936B4FAAA20138B7C509FBD757F666E642` | +| [TabularEditor.3.4.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x86.exe) | `0D323514339011C0AE057F1ADC102D1B141B91A5DB8DD5CDFC8E9FD8231AF1DE` | +| [TabularEditor.3.4.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.msi) | `CE838594BDD8AE4A875DBA07C479A063270666CF63D19D93D81F9D0C5ED2E172` | +| [TabularEditor.3.4.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.zip) | `50AB9A22CF9332CA8B2793D26CFCF74DDAF11BF281BD00103AE37772FE9ADADF` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.4.2 + +- Fixed an issue with the Semantic Analyzer reporting "circular dependency" errors, when there are none. See [#811](https://github.com/TabularEditor/TabularEditor3/issues/811). +- Find/Replace should no longer replace all occurrences in the document, when setting "Look in" to "Selection", see [#293](https://github.com/TabularEditor/TabularEditor3/issues/293). +- Copy/pasting cultures between models should no longer cause a crash, see issue [#798](https://github.com/TabularEditor/TabularEditor3/issues/798). Note that ObjectTranslations referring to objects that do not exist in the destination model, are deleted. +- DAX debugger should now allow inspecting multi-row watch expressions in all cases. +- DAX debugger should no longer crash when attempting to debug the result of a query such as `EVALUATE { [Measure that uses ALLSELECTED] }` + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_5_0_de.md b/content/localization/de/3_5_0_de.md new file mode 100644 index 00000000..c1a15d17 --- /dev/null +++ b/content/localization/de/3_5_0_de.md @@ -0,0 +1,90 @@ +--- +uid: release-3-5-0 +--- + +# Tabular Editor 3.5.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.5.0 downloads: + +- Download [Tabular Editor 3.5.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.5.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.5.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x64.exe) | `AD96A3A2A5672D412C2DF74939AF36EA888483137753D6048AD66D3C84386723` | +| [TabularEditor.3.5.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.msi) | `3DBA3D9054A1422A7C7DEF83EFB1458935A77143B1C887A2EC628F58D8B2E52A` | +| [TabularEditor.3.5.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.zip) | `56E7658E9C4C11DC3E31DEF0E27717DB8CF67185E6A00C7B28E02EFA1EF8F5FC` | +| [TabularEditor.3.5.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x86.exe) | `2C2B2D756087CEF15461693F830DA83CBFEF472CD2D3E6AFEB3164059BA2D8AD` | +| [TabularEditor.3.5.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.msi) | `0B0A206DB149C5C53A4A765AD2E014657DA3DF8B70DFCD0464A4E22CA1871F45` | +| [TabularEditor.3.5.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.zip) | `EC06DFBBBF2F70B111532967D4B8A618317B9B201ED7B75FAC3B2CB050626831` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.5.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/03/15/tabular-editor-3-march-2023-release/) to get an overview of the most important updates in this release. + +- Updated TOM to [19.57.2.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- This release introduces **Table Groups** which lets you organise tables into "folders" in the TOM Explorer. [Learn more](xref:table-groups). +- Default shortcut for uncommenting code now set to Ctrl+U +- Tabular Editor will now attempt to automatically reconnect to Analysis Services, when the session timeout has expired. This means it should no longer be necessary to close and reopen table previews, DAX query windows and Pivot Grids. See [#650](https://github.com/TabularEditor/TabularEditor3/issues/650), [#803](https://github.com/TabularEditor/TabularEditor3/issues/803). +- Added a new set of overloaded C# script methods `Macro(...)`. These are an alias for `CustomAction(...)`. The API documentation has been updated accordingly. +- When using Tabular Editor in **Workspace Mode**, incremental refresh partitions are not overridden upon workspace database updates. Moreover, a new serialization option **Ignore incremental refresh partitions** is now available, and enabled by default for new models. This option will make sure that partitions governed by incremental refresh, are not serialized when saving a model as a .bim or folder structure. This makes it easier to integrate models using incremental refresh with version control. +- Added toolbar button to toggle display folders in the **Perspective Editor view**. Toggling a Display Folder in the Perspective Editor, will toggle all objects within that folder. The Perspective Editor now also provides a visual indication if a table or folder contains both items that are included in the perspective, and items that are not. +- Tabular Editor now has full support for Oracle data sources. You must have the [ODP.NET managed drivers](https://www.oracle.com/database/technologies/odac-downloads.html) installed, which is also a requirement if you want to import data from Oracle in Power BI Desktop. + +## Bugfixes in 3.5.0 + +- Auto-format should no longer erase code when the DAX Editor is configured to use tabs +- "Open macro" button in the **Macros** view will now be enabled whenever a macro is selected +- It should no longer be necessary to reset the window layout, in order for the **Perspective Editor** view to appear +- Main Menu bar will no longer reset when a macro is added as a new button +- Fixed a bug that sometimes prevented Tabular Editor from opening a .bim file or .json folder structure containing Power BI specific TOM properties. +- `ResolveObjectPath` now supports the "old" path format, similar to TE2. See [#1077](https://github.com/TabularEditor/TabularEditor/issues/1077). +- BPA rules that rely on the `Expression` property on tables, should no longer fail. +- Macros can now be saved/compiled even if their name contains a double quote. +- Fixed various issues with the `CustomAction(...)` C# script method. +- Perspective Editor now correctly deals with hidden tables containing visible measures. +- Fixed an issue that prevented setting the **Default Measure** property on the Model object through the **Properties View**. +- **Calculate Table** context menu option will no longer show when working offline. +- Fixed an issue that caused the C# autocomplete dropdown to "absorb" a period key press. +- Fixed an issue with the semantic analyzer reporting incorrect parameter usage to the DAX [XIRR](https://dax.guide/xirr) function. +- Relationship Editor now allows creating relationships between columns of different, but compatible, data types. +- Fixed the "The key didn't match any rows" error, when attempting to perform a schema update on a table using an M Partition. +- Tables using incremental refresh policy now work with the Update Table Schema feature. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_5_1_de.md b/content/localization/de/3_5_1_de.md new file mode 100644 index 00000000..8d0492df --- /dev/null +++ b/content/localization/de/3_5_1_de.md @@ -0,0 +1,72 @@ +--- +uid: release-3-5-1 +--- + +# Tabular Editor 3.5.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.5.1 downloads: + +- Download [Tabular Editor 3.5.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.5.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.5.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x64.exe) | `02B75E0FE9CE11619078DC85BD18BE807AB4541BFEEC54C4A98395A11E91D9D3` | +| [TabularEditor.3.5.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.msi) | `B6FB6E49825CDE135E35461073F4BAB567D557CB9BB8BF6E2CCC3F22A9B21A0D` | +| [TabularEditor.3.5.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.zip) | `D01E533144582980D407CE7870421C69398AC6677DBB9119020A7FC836F4C5DC` | +| [TabularEditor.3.5.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x86.exe) | `2389206632421968499CBEFF74AECE4BD592E157EDE32AA5F5C953A5213B21C9` | +| [TabularEditor.3.5.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.msi) | `D1AFEA6FB0781349074B9B91723EE2058651B6B77AD81778606E88D870EF432D` | +| [TabularEditor.3.5.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.zip) | `B0241F8C4067A849EEF04CFF9E67E0DBC80E29EB0F9BDDA167D967C123081259` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes and improvements in 3.5.1 + +- Updated TOM to [19.60.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Fixed an issue with the Edit Relationship dialog showing an incompatible data type warning, even if the data types on both columns are identical, see [#855](https://github.com/TabularEditor/TabularEditor3/issues/855). Moreover, when connected to an instance of Analysis Services, the dialog now displays RI violation and duplicate value warnings. +- Fixed an issue that would sometimes cause the application to freeze when opening a file or folder structure from disk. +- Fixed an issue that prevented editing RLS expressions when a role contained a "." in its name. +- When an object is shown in multiple display folders, the TOM Explorer didn't correctly refresh its properties in all places. This has been fixed. +- "Model" is now treated as a reserved word in the Semantic Analyzer, see [#852](https://github.com/TabularEditor/TabularEditor3/issues/852). +- The .pbitool file (used for External Tool integration with PBI Desktop) now uses the updated TE3 icon. +- The Create Workspace Database dialog now validates the database name, preventing special characters that are not supported by Analysis Services. +- Fixed an issue with auto-indent overwriting characters in the DAX editor. See [#857](https://github.com/TabularEditor/TabularEditor3/issues/857). +- You can now create add tables/calculation groups directly to a table group through the table group's right-click context menu. +- Fixed an regression in 3.5.0, where importing columns or performing a schema update on a table from an MS SQL-flavored data source, would result in the wrong data type being assigned to the column. +- Fixed an issue where closing a bracket or parenthesis would sometimes "snap" the cursor to the wrong position in the DAX editor. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_6_0_de.md b/content/localization/de/3_6_0_de.md new file mode 100644 index 00000000..6ded9dd5 --- /dev/null +++ b/content/localization/de/3_6_0_de.md @@ -0,0 +1,83 @@ +--- +uid: release-3-6-0 +--- + +# Tabular Editor 3.6.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.6.0 downloads: + +- Download [Tabular Editor 3.6.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.6.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.6.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x64.exe) | `3D19445617BE4D8091DDF1F5C54D8783A2BFF49B5CD628F2D0725ED858D70981` | +| [TabularEditor.3.6.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.msi) | `C295556551595351BFDB1CDC0C6990BDF187493CC4233BD3C099439FFFD390B6` | +| [TabularEditor.3.6.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.zip) | `971B6EC8AAB6BBEE77769FD81873D371B4BEA3417CC2689C571D868B0234AE10` | +| [TabularEditor.3.6.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x86.exe) | `05411C0D29025BCCAED2A90DE95759A2C7476CFBFCDB1B52CBFDF9A753C1A94E` | +| [TabularEditor.3.6.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.msi) | `E4DA4EBEA597419E2FA753E4CE9AC798193812D1D350C8EC1222762CE34E15AC` | +| [TabularEditor.3.6.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.zip) | `CB3DD1ED971C31781F13932AA3F3C9C3AB662AB8185243C7F672B398262CB5FB` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.6.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/04/19/tabular-editor-3-april-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor 3 now has native support for **Databricks**. This means you can now connect to a Databricks SQL endpoint when importing tables using the Table Import Wizard. For more information, see our [release blog post](https://blog.tabulareditor.com/2023/04/19/tabular-editor-3-april-2023-release). +- We added support for the new DAX functions [`RANK`](https://dax.guide/rank) and [`ROWNUMBER`](https://dax.guide/rownumber) introduced in the [April 2023 update of Power BI Desktop](https://powerbi.microsoft.com/en-us/blog/power-bi-april-2023-feature-summary/). In addition, our code complete now shows all available keywords for the <Blanks> and <Order> arguments of the window and [`ORDERBY`](https://dax.guide/orderby) functions. + +## Minor improvements in 3.6.0 + +- We no longer perform a (potentiallys slow) conflict check before saving changes to the workspace database. The assumption is that each developer uses their own personal workspace database, so conflicts should not occur. +- C# scripting: The `IAnnotationObject` interface has been extended with a `ClearAnnotations()` method. +- When adding a dynamic format string expression to a measure, we now clear the static format string property (as it is not possible for measures to have both static and dynamic format strings assigned). +- Updated TOM to [19.61.1.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Default Compatibility Level for new Power BI models created with Tabular Editor, is now 1601. Moreover, the "create new model" dialog now lets you specify any compatibility level. + +## Bugfixes in 3.6.0 + +- Oracle download instructions updated to instruct users to use the ODAC (not ODP.NET) drivers. +- Removed restrictions on special characters in database names, when opening or creating a new database. +- Fixed an issue that caused the database name property within the .bim / database.json file, to be updated with the name of the workspace database. +- DAX debugger stability improvements. +- .tmuo files are no longer saved, when the "Create user options (.tmuo) file" option is unchecked. +- Fixed an issue where code complete would sometimes "absorb" closing brackets. +- Semantic Analyzer no longer reports an error when using [`SELECTEDMEASURE`](https://dax.guide/selectedmeasure) (and related functions) in the context of measure expressions and format string expressions. +- Fixed an issue where the M query generated for new tables imported from an existing implicit (SQL) data source, would not work correctly when attempting to refresh the table. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_7_0_de.md b/content/localization/de/3_7_0_de.md new file mode 100644 index 00000000..c11fd521 --- /dev/null +++ b/content/localization/de/3_7_0_de.md @@ -0,0 +1,100 @@ +--- +uid: release-3-7-0 +--- + +# Tabular Editor 3.7.0 + +> [!IMPORTANT] +> A bug preventing creation of new models with workspace databases was identified in this version of Tabular Editor 3. Please use [version 3.7.1](xref:release-3-7-1) instead. + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.7.0 downloads: + +- Download [Tabular Editor 3.7.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.7.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.7.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x64.exe) | `ECE2DF7E9C43E9647CA3BC3DA7AC0E0110B57E82C40A70C4A81843F77FEC5907` | +| [TabularEditor.3.7.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.msi) | `E31DF5C97BA5650E91636ECC24FD8DAE68CC6E0717FFE32A94A76500A31271EE` | +| [TabularEditor.3.7.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.zip) | `91E0A94B943D256666055F4799280D25D00F65B14F658ADD41D8247BC8814A8C` | +| [TabularEditor.3.7.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x86.exe) | `EEAFA4229DEA82FD94B8CF735AC97A4319DA697A2F26376D6F7D527AEE29112A` | +| [TabularEditor.3.7.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.msi) | `C92577A971733C2F3E3A1852629B4F6A9C6D0AB9FE979337483EDFA3066306C8` | +| [TabularEditor.3.7.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.zip) | `390375585D0C4E97C53A79690D35A354EB131A3F5B60A072FA7E0909B8CE3DA0` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.7.0 + +Check out our [release blog](https://blog.tabulareditor.com/?p=2146) to get an overview of the most important updates in this release. + +- This release introduces the [Metadata Translations Editor](xref:metadata-translation-editor), which provides a fast an easy way to view, compare and edit all metadata translations applied across model objects. +- Tabular Editor 3 now supports the new [Tabular Model Definition Language (TMDL)](https://powerbi.microsoft.com/en-us/blog/announcing-public-preview-of-the-tabular-model-definition-language-tmdl/) as a format for saving/loading model metadata. You can enable TMDL (preview) serialization mode under **Preferences > Tools > Save-to-folder**. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work.\*\*. + +## Minor improvements in 3.7.0 + +- Now using latest version of [VertiPaq Analyzer](https://github.com/sql-bi/VertiPaq-Analyzer). This fixes an issue with collecting stats on models with Dynamic Format Strings, among other things. +- We now show a more meaningful error message, when a paste operation fails because of incompatible model metadata. +- Analysis Services trace events that are received after a data refresh job completes, are now correctly assigned to that job, enabling proper propagation of error/warning messages, as well as progress counts. See [#735](https://github.com/TabularEditor/TabularEditor3/issues/735). +- The data preview window is now able to use the DAX [`OFFSET`](https://dax.guide/offset) function, which enables the preview to show all rows of non-DirectQuery tables, even when a model is in DirectQuery mode (such as when hybrid tables are present in the model), see [#500](https://github.com/TabularEditor/TabularEditor3/issues/500), [#837](https://github.com/TabularEditor/TabularEditor3/issues/837). +- When deplying a model as a new database, we now add a dummy partition to tables that use incremental refresh policy, when no partitions are present in the model metadata, to ensure the deployment succeeds. +- Data preview retains any filters applied, when a table is refreshed/processed. See [#780](https://github.com/TabularEditor/TabularEditor3/issues/780). +- When a table does not contain columns in a non-queryable state, the data preview now uses the table name directly in the generated DAX query, instead of wrapping it in a call to [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). This should speed up the data preview on older versions of Analysis Services. See [#126](https://github.com/TabularEditor/TabularEditor3/issues/126). +- TE3 now uses the latest version of [Microsoft.Identity.Client](https://www.nuget.org/packages/Microsoft.Identity.Client). +- Offline schema detection now supports using Shared (M) Expressions which define custom functions. + +## Bugfixes in 3.7.0 + +- There was a problem in the newest version of AdomdClient used in 3.6.0, which causes a Pivot Grid to fail with an XML error message, when connected to the Power BI XMLA endpoint. We have downgraded AdomdClient to [19.55.3.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64/19.55.3.1), which solves this issue for now. +- Fixed an issue where local instances of Power BI Desktop were not shown in the "Local instances" dropdown. +- Fixed an issue where TE3 would not allow loading a model that did not have a database name specified. +- The "Please Wait" dialogs should no longer obstruct Azure AD sign-in windows. +- Stability improvements. +- Fixed an issue where the application would crash when attempting to copy/paste measures with dynamic format strings, see [#1099](https://github.com/TabularEditor/TabularEditor/issues/1099). +- DAX scripting of measures with format strings/dynamic format strings, now works as intended. +- Query-scoped columns are now handled correctly by the DAX semantic analyzer and auto-complete feature. See [#890](https://github.com/TabularEditor/TabularEditor3/issues/890). +- Open Model/File dialogs now correctly filters "database.json" files instead of showing all .json files in a folder. +- Fixed some visual issues with buttons on various prompt dialogs. +- Fixed an issue where the database selection is incorrect, when the list is filtered. See [#886](https://github.com/TabularEditor/TabularEditor3/issues/886). +- Fixed an issue where the "Save Model" action (Ctrl+Alt+S) was not enabled, even though the message bar indicated that the model had unsaved changes. +- Fixed an issue with "phantom" semantic errors in the DAX Editor, see [#792](https://github.com/TabularEditor/TabularEditor3/issues/792). +- Preview data should now respect the format string assigned to a column, see [#820](https://github.com/TabularEditor/TabularEditor3/issues/820). +- DAX query results should now show the time portion of DateTime values, when it is not 00:00:00. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_7_1_de.md b/content/localization/de/3_7_1_de.md new file mode 100644 index 00000000..651c3e82 --- /dev/null +++ b/content/localization/de/3_7_1_de.md @@ -0,0 +1,101 @@ +--- +uid: release-3-7-1 +--- + +# Tabular Editor 3.7.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.7.1 downloads: + +- Download [Tabular Editor 3.7.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.7.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.7.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x64.exe) | `C1A2DBF3E8800BC0F55C4D4B6A2FF4989952015C182C079EE2A4579A6426BDF3` | +| [TabularEditor.3.7.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.msi) | `D9EDEF51E8113FD871485C2C5F647016B99FEAC582A1528CA8E8AD5EFD08CE40` | +| [TabularEditor.3.7.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.zip) | `168E49DB30597419D44352DED0E020EF711C306D906985929F14DCEB15654DB1` | +| [TabularEditor.3.7.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x86.exe) | `4F26EA53998852F7768DA81F94D05C4540101F3639AA4045F66CE6AE2ADD7EA2` | +| [TabularEditor.3.7.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.msi) | `5A3D57DB293CFE09AB9C8FF46FCECA34BBDC0A773B7990F6BEDDE00C1C6945EE` | +| [TabularEditor.3.7.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.zip) | `3B63395FC1CD8C5B1D4B7DBA2E0FAAD86D7ECD93D1ADE7B524CD4FE16F235456` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.7.1 + +- Fixed the "Object reference not set to an instance of an object", which would occur when attempting to create a new model using a workspace database. + +## New in 3.7.0 + +Check out our [release blog](https://blog.tabulareditor.com/?p=2146) to get an overview of the most important updates in this release. + +- This release introduces the [Metadata Translations Editor](xref:metadata-translation-editor), which provides a fast an easy way to view, compare and edit all metadata translations applied across model objects. +- Tabular Editor 3 now supports the new [Tabular Model Definition Language (TMDL)](https://powerbi.microsoft.com/en-us/blog/announcing-public-preview-of-the-tabular-model-definition-language-tmdl/) as a format for saving/loading model metadata. You can enable TMDL (preview) serialization mode under **Preferences > Tools > Save-to-folder**. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work.\*\*. + +## Minor improvements in 3.7.0 + +- Now using latest version of [VertiPaq Analyzer](https://github.com/sql-bi/VertiPaq-Analyzer). This fixes an issue with collecting stats on models with Dynamic Format Strings, among other things. +- We now show a more meaningful error message, when a paste operation fails because of incompatible model metadata. +- Analysis Services trace events that are received after a data refresh job completes, are now correctly assigned to that job, enabling proper propagation of error/warning messages, as well as progress counts. See [#735](https://github.com/TabularEditor/TabularEditor3/issues/735). +- The data preview window is now able to use the DAX [`OFFSET`](https://dax.guide/offset) function, which enables the preview to show all rows of non-DirectQuery tables, even when a model is in DirectQuery mode (such as when hybrid tables are present in the model), see [#500](https://github.com/TabularEditor/TabularEditor3/issues/500), [#837](https://github.com/TabularEditor/TabularEditor3/issues/837). +- When deplying a model as a new database, we now add a dummy partition to tables that use incremental refresh policy, when no partitions are present in the model metadata, to ensure the deployment succeeds. +- Data preview retains any filters applied, when a table is refreshed/processed. See [#780](https://github.com/TabularEditor/TabularEditor3/issues/780). +- When a table does not contain columns in a non-queryable state, the data preview now uses the table name directly in the generated DAX query, instead of wrapping it in a call to [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). This should speed up the data preview on older versions of Analysis Services. See [#126](https://github.com/TabularEditor/TabularEditor3/issues/126). +- TE3 now uses the latest version of [Microsoft.Identity.Client](https://www.nuget.org/packages/Microsoft.Identity.Client). +- Offline schema detection now supports using Shared (M) Expressions which define custom functions. + +## Bugfixes in 3.7.0 + +- There was a problem in the newest version of AdomdClient used in 3.6.0, which causes a Pivot Grid to fail with an XML error message, when connected to the Power BI XMLA endpoint. We have downgraded AdomdClient to [19.55.3.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64/19.55.3.1), which solves this issue for now. +- Fixed an issue where local instances of Power BI Desktop were not shown in the "Local instances" dropdown. +- Fixed an issue where TE3 would not allow loading a model that did not have a database name specified. +- The "Please Wait" dialogs should no longer obstruct Azure AD sign-in windows. +- Stability improvements. +- Fixed an issue where the application would crash when attempting to copy/paste measures with dynamic format strings, see [#1099](https://github.com/TabularEditor/TabularEditor/issues/1099). +- DAX scripting of measures with format strings/dynamic format strings, now works as intended. +- Query-scoped columns are now handled correctly by the DAX semantic analyzer and auto-complete feature. See [#890](https://github.com/TabularEditor/TabularEditor3/issues/890). +- Open Model/File dialogs now correctly filters "database.json" files instead of showing all .json files in a folder. +- Fixed some visual issues with buttons on various prompt dialogs. +- Fixed an issue where the database selection is incorrect, when the list is filtered. See [#886](https://github.com/TabularEditor/TabularEditor3/issues/886). +- Fixed an issue where the "Save Model" action (Ctrl+Alt+S) was not enabled, even though the message bar indicated that the model had unsaved changes. +- Fixed an issue with "phantom" semantic errors in the DAX Editor, see [#792](https://github.com/TabularEditor/TabularEditor3/issues/792). +- Preview data should now respect the format string assigned to a column, see [#820](https://github.com/TabularEditor/TabularEditor3/issues/820). +- DAX query results should now show the time portion of DateTime values, when it is not 00:00:00. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_8_0_de.md b/content/localization/de/3_8_0_de.md new file mode 100644 index 00000000..bde45799 --- /dev/null +++ b/content/localization/de/3_8_0_de.md @@ -0,0 +1,83 @@ +--- +uid: release-3-8-0 +--- + +# Tabular Editor 3.8.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.8.0 downloads: + +- Download [Tabular Editor 3.8.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.8.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.8.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x64.exe) | `0FB0AB8BD7E209E739786F1E348645D40AEFFB2D1963E44231164A1783D5A928` | +| [TabularEditor.3.8.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.msi) | `0F4FC4B7F0F483E58D5752AFCF7C28C03F29FD739093688D48E1C6C34186CEF1` | +| [TabularEditor.3.8.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.zip) | `448B9BBB5EEAC450CF4A9654E002A5C471843FD9D49882D9646C3EC34822165A` | +| [TabularEditor.3.8.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x86.exe) | `6018121D47096E7086C66CD9B142112F8D5D999F779E6DB1799E39298F41FEE9` | +| [TabularEditor.3.8.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.msi) | `6DEA4B5E29B67CA6B42446C6F8A29B9E9A7A89F72076232E46C4FFC301758EB5` | +| [TabularEditor.3.8.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.zip) | `69A3858F2B43C0338DE805902DF3B5FEF66DD713FFE2A4A66124B46BD0D803BD` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.8.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/06/26/tabular-editor-3-june-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor 3 now lets you open [Power BI Desktop project (.pbip) files](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview) or folders containing .pbip files. When such a folder contains multiple datasets, a list is shown, letting you select which one to open. +- The [June 2023 update of Power BI Desktop](https://powerbi.microsoft.com/en-us/blog/power-bi-june-2023-feature-summary/) now supports a much larger range of modelling operations that can be performed through external tools ("hardening"). In other words, when you connect Tabular Editor to Power BI Desktop (June 2023 or newer), you will now be able to add/edit calculated columns, calculated tables, relationships, hierarchies, and much more. +- We're now using the latest version of TOM/AMO ([19.65.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64)). + +> [!NOTE] +> TMDL and Power BI Desktop Projects (.pbip) is still in preview, and as such, these features must also be considered preview features of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work.\*\*. + +## Bugfixes in 3.8.0 + +- Dependency view now has much better performance for models with large and complex dependency graphs. +- Some users have reported that editing certain properties, through the **Properties view**, caused the application to crash. This should no longer be the case. +- Semantic Analyzer should no longer report errors when a DAX query contains both query-scoped columns and query-scoped tables. +- Semantic Analyzer now correctly handles DAX expressions containing UTF-32 characters (emojis), although the DAX editor still has issues dealing with these. In general, we recommend avoiding the use of emojis in DAX expressions. +- Fixed a bug where repeatedly hitting Ctrl+Z (Undo) would clear the Expression Editor and even bring in unrelated expressions. +- Perspective Editor now correctly updates to reflect when new objects are added/removed to/from the model. +- VertiPaq Analyzer should no longer crash when a model contains Dynamic Format Strings. +- Fixed a regression with importing tables from Snowflake, which caused columns to have incorrect datatypes assigned. +- Fixed a regression with update schema/importing tables Snowflake, where the implicit data source properties had to be re-entered in the connection dialog. +- Fixed an issue where the toolbar buttons related to the Expression Editor would disappear, if the Expression Editor was docked as a tool window (i.e. not as a document window). +- DAX editors now perform a new semantic analysis, when changes that can impact DAX semantics are made to the model. This should ensure that the error messages shown in the DAX editor are always valid. +- Fixed an issue where the DAX debugger would be unavailable, even for seemingly simple DAX queries. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/3_9_0_de.md b/content/localization/de/3_9_0_de.md new file mode 100644 index 00000000..6366f42e --- /dev/null +++ b/content/localization/de/3_9_0_de.md @@ -0,0 +1,95 @@ +--- +uid: release-3-9-0 +--- + +# Tabular Editor 3.9.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.9.0 downloads: + +- Download [Tabular Editor 3.9.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.9.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.9.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x64.exe) | `4D7F3932425BBC06F7933C1930B0B619D5CB6AC8AE0C511F9FB8B17BF3BDBDD6` | +| [TabularEditor.3.9.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.msi) | `79F6A150059E104CD43D7923D591A45C689C2D53C6207C439CB826E8AE32F72C` | +| [TabularEditor.3.9.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.zip) | `EBB35030615A0E2DF2ACCC8888A524867718EB2123A8B4D78BCB8BB6407B3F33` | +| [TabularEditor.3.9.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x86.exe) | `80B74191635224DDBDDBC717CCBD300018F3733974259FBB1A2721204B09FCAD` | +| [TabularEditor.3.9.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.msi) | `295E2378110C202263255CB0781EE5C68804B390923AEB499DB586FD42B94528` | +| [TabularEditor.3.9.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.zip) | `6B14274436F1FD43C16026690FA449EDA6C86D3A6FF27A61DCCD29ED20AF0A4E` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.9.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/07/21/tabular-editor-3-july-2023-release/) to get an overview of the most important updates in this release. + +- Customers on one of the Azure for Government cloud, can now specify the base url that Tabular Editor 3 should use, when connecting to the Power BI REST API, such as when importing tables from a Power BI Dataflow. This setting is specified under **Tools > Preferences > Power BI > Power BI Service**. +- When selecting more than one cell in a DAX query result or a Pivot Grid, we now show a summary of the values selected in the application status bar (sum, minimum, maximum, average, etc.). Hold down Shift/Ctrl to select ranges the way you'd usually do. Shift+click on a column header will select all cells in that column. See [#475](https://github.com/TabularEditor/TabularEditor3/issues/475). + +## Improvements in 3.9.0 + +- We've rearranged some of the pages and sections of the preferences dialog, making it easier to navigate. +- We're now using the latest version of TOM/AMO ([19.65.7.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64)) and [TMDL preview-3](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.65.7.2-TmdlPreview). +- We've also updated AdomdClient to [19.65.7.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64/), which should improve the performance of our Pivot Grid component. +- VertiPaq Analyzer has been updated to version [1.2.18](https://www.nuget.org/packages/Dax.Metadata). +- When a calculated table is left with a blank expression, we now show the error icon immediately in the TOM Explorer. +- It is now possible to add objects to Pivot Grids or Diagrams, even when those documents do not have focus (assuming no more than one such document is open). Moreover, you can now create a Pivot Grid by right-clicking on a measure, saving a few clicks, when you just need to test the value of a measure. +- We now show an error message, if attempting to assign an expression that produces a value of type 'Variant' to a calculated column (this is not allowed). +- We've added a separate option for saving zipped model.bim backups under **Tools > Preferences > Model Deployment**. You can now choose to have backups saved upon every deployment, upon every save (while connected to an instance of Analysis Services), or both. Note, this feature is not available for TE3 Desktop Edition. This also fixed issue [#796](https://github.com/TabularEditor/TabularEditor3/issues/796). +- We've added additional info columns to VertiPaq Analyzer, to align with those available in [DAX Studio](https://daxstudio.org). + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +## Bugfixes in 3.9.0 + +- Fix false "Circular dependency" errors, encountered both in the DAX Editor, as well as in the TOM Explorer / Messages View. See issues [#920](https://tabulareditor.zendesk.com/agent/tickets/920) and [#931](https://github.com/TabularEditor/TabularEditor3/issues/931). +- Fixed an issue that prevented the Search and Replace dialog from searching in floating (undocked) document windows. +- Various stability improvements (should fix [#937](https://github.com/TabularEditor/TabularEditor3/issues/937), among other things). +- Fixed a crash that would occur when attempting to format DAX code containing window functions. +- Fixed a bug that caused Tabular Editor to use the System proxy when choosing Proxy Type "None" under **Tools > Preferences > Proxy settings**, and vice versa. +- Semantic Analyzer now works correctly with the [`DETAILROWS`](https://dax.guide/detailrows) function, see [#938](https://github.com/TabularEditor/TabularEditor3/issues/938). +- Fixed an issue where changing the name of a macro would not update the folder structure of macros, until the application was restarted. +- Fixed a bug that caused certain column and hierarchy properties to be read-only, preventing users from correctly setting up calculated tables, relationships, etc., while connected to Power BI Desktop. See [#929](https://github.com/TabularEditor/TabularEditor3/issues/929) and [#930](https://github.com/TabularEditor/TabularEditor3/issues/930). +- Fixed a crash in the DAX editor, when using the [`WINDOW`](https://dax.guide/window) function with certain parameters. +- Fixed an issue with the M parser not interpreting `[]` correctly, preventing the offline schema comparer from inferring metadata from an M expression such as `PowerPlatform.Dataflows([])`. See [#936](https://github.com/TabularEditor/TabularEditor3/issues/936). +- Fixed an issue where the PivotGrid would crash if a measure had a malformed format string assigned. +- Fixed an issue where the Semantic Analyzer would assign "Variant" as the data type of an expression resulting from the use of [`SWITCH`](https://dax.guide/switch) with one or more branches returning [`BLANK`](https://dax.guide/blank). +- Fixed a few bugs related to column filters on table previews. When getting the list of unique values of a column, we now read the first 5000 values (in ascending order). Previously, only 500 values were read, with no ordering specified, causing inconsistent behavior. See [#924](https://github.com/TabularEditor/TabularEditor3/issues/924). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/de/Advanced-Filtering-of-the-Explorer-Tree_de.md b/content/localization/de/Advanced-Filtering-of-the-Explorer-Tree_de.md new file mode 100644 index 00000000..11ffa926 --- /dev/null +++ b/content/localization/de/Advanced-Filtering-of-the-Explorer-Tree_de.md @@ -0,0 +1,87 @@ +# Advanced Object Filtering + +This article describes how to use the "Filter" textbox within Tabular Editor - an incredibly useful feature when navigating complex models. + +## Filtering Mode + +As of [2.7.4](https://github.com/TabularEditor/TabularEditor/releases/tag/2.7.4), Tabular Editor now lets you decide how the filter should apply to objects in the hierarchy, and how search results are displayed. This is controlled using the three right-most toolbar buttons next to the Filter button: + +![image](https://user-images.githubusercontent.com/8976200/46567931-08a4b480-c93d-11e8-96fd-e197e87a0587.png) + +- ![image](https://user-images.githubusercontent.com/8976200/46567944-44d81500-c93d-11e8-91e2-d9822078dba7.png) **Hierarchical by parent**: The search will apply to _parent_ objects, that is Tables and Display Folders (if those are enabled). All child items will be displayed, when a parent item matches the search criteria. +- ![image](https://user-images.githubusercontent.com/8976200/46567940-2ffb8180-c93d-11e8-9fba-84fbb79b6bb3.png) **Hierarchical by children**: The search will apply to _child_ objects, that is Measures, Columns, Hierarchies, etc. Parent objects will only be displayed if they have at least one child object matching the search criteria. +- ![image](https://user-images.githubusercontent.com/8976200/46567941-37bb2600-c93d-11e8-9c02-86502f41bce8.png) **Flat**: The search will apply to all objects, and results will be displayed in a flat list. Objects that contain child items will still display these in a hierarchical manner. + +## Simple search + +Type anything into the Filter textbox and hit [Enter] to do a simple case-insensitive search within object names. For example, typing "sales" in the Filter textbox, using the "By Parent" filtering mode, will produce the following results: + +![image](https://user-images.githubusercontent.com/8976200/46568002-5f5ebe00-c93e-11e8-997b-7f89dfd92076.png) + +Expanding any of the tables will reveal all measures, columns, hierarchies and partitions of the table. If we change the filtering mode to "By Child", the results will look like this: + +![image](https://user-images.githubusercontent.com/8976200/46568016-9f25a580-c93e-11e8-9bc2-c0a16a890256.png) + +Notice how the "Employee" table now appears in the list, since it has a couple of child items (columns in this case), that contain the word "sales". + +## Wildcard search + +When typing in a string in the Filter textbox, you can use the wildcard `?` to denote any single character, and `*` to denote any sequence of characters (zero or more). So typing `*sales*` would produce exactly the same results as shown above, however typing `sales*` will only show objects whose name _starts_ with the word "sales" (again, this is case-insensitive). + +Searching for `sales*` by parent: + +![image](https://user-images.githubusercontent.com/8976200/46568043-19eec080-c93f-11e8-8d81-2a6214bfa572.png) + +Searching for `sales*` by child: + +![image](https://user-images.githubusercontent.com/8976200/46568117-f9733600-c93f-11e8-96ab-f87769b8097c.png) + +Flat search for `sales*` (toggle info columns [Ctrl]+[F1] to show detailed information about each object): + +![image](https://user-images.githubusercontent.com/8976200/46568118-042dcb00-c940-11e8-82d1-516207450559.png) + +Wildcards can be placed anywhere in the string, and you can include as many as you need. If that's not complex enough, read on... + +## Dynamic LINQ search + +You can also use [Dynamic LINQ](https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions) to search for objects, which is the same thing you do when creating [Best Practice Analyzer rules](/Best-Practice-Analyzer). To enable Dynamic LINQ mode in the filter box, simply put a `:` (colon) in front of your search string. For example, to view all objects whose name end with "Key" (case-sensitive) write: + +``` +:Name.EndsWith("Key") +``` + +...and hit [Enter]. In "Flat" filtering mode, the result looks like this: + +![image](https://user-images.githubusercontent.com/8976200/46568130-33dcd300-c940-11e8-903c-193e1acde0ad.png) + +For case-insensitive search in Dynamic LINQ, you can either convert the input string using something like: + +``` +:Name.ToUpper().EndsWith("KEY") +``` + +or you can supply the [StringComparison](https://docs.microsoft.com/en-us/dotnet/api/system.string.endswith?view=netframework-4.7.2#System_String_EndsWith_System_String_System_StringComparison_) argument, like: + +``` +:Name.EndsWith("Key", StringComparison.InvariantCultureIgnoreCase) +``` + +You are not restricted to searching within the names of objects. Dynamic LINQ search strings can be as complex as you like, to evaluate any property (as well as sub-properties) of an object. So if you want to find all objects having an expression that contains the word "TODO", you would use the following search filter: + +``` +:Expression.ToUpper().Contains("TODO") +``` + +As another example, the following will display all hidden measures in the model that are not referenced by anything else: + +``` +:ObjectType="Measure" and (IsHidden or Table.IsHidden) and ReferencedBy.Count=0 +``` + +You can also use Regular Expressions. The following will find all columns whose name contains the word "Number" OR "Amount": + +``` +:ObjectType="Column" and RegEx.IsMatch(Name,"(Number)|(Amount)") +``` + +Note, that the display options (the toolbar buttons directly above the tree), may affect the results when using "By Parent" and "By Child" filtering mode. For example, the above LINQ filter only returns columns, but if your display options are currently set to not show columns, nothing will be displayed. diff --git a/content/localization/de/Advanced-Scripting-and-Dynamic-LINQ-quiz_de.md b/content/localization/de/Advanced-Scripting-and-Dynamic-LINQ-quiz_de.md new file mode 100644 index 00000000..ec2025a6 --- /dev/null +++ b/content/localization/de/Advanced-Scripting-and-Dynamic-LINQ-quiz_de.md @@ -0,0 +1,108 @@ +Are you a Tabular Editor pro? + +Test your knowledge of Tabular Editor's Advanced Scripting and Dynamic LINQ filter expressions. All the questions here may be answered using just one line of code. + +If you're new to these features, the solutions presented here (both the C# and Dynamic LINQ version), provides a lot of useful information on how this stuff works, so make sure to check them out. + +*** + +#### Question #1) Total number of measures + +- How would you obtain the total number of measures in your model? + +
C# script solution +
Model.AllMeasures.Count().Output();
Explanation: The Model object represents the root of the TOM tree. It supports most of the properties found in the API documentation with the addition of a number of extra properties and methods, that are only available inside Tabular Editor. The AllMeasures property is one of these extra properties, added for convenience. It simply returns a collection of all measures across all tables in the model. All collections (or more precisely, enumerables) support the powerful .NET LINQ methods. Count() is one such method, which simply returns the number of elements in the collection as an integer. Once we have that, the only thing left is to Output() it.

+
+ +
Dynamic LINQ solution +
:ObjectType="Measure"
Explanation: When you put a ':' as the first character of the Filter textbox, you enable Dynamic LINQ filtering. What that means is, that Tabular Editor evaluates the expression after the ':' character against every object in the TOM tree, returning only those objects where the expression evaluates to true. Putting the expression above into the Filter textbox, will have Tabular Editor display all objects whose ObjectType property is "Measure". The search result count at the bottom of the screen, should then tell you how many measures you have in total.

+
+ +*** + +#### Question #2) Find all measures with "TODO" in their expression + +- What's the easiest way to find all measures that contain the word "TODO" inside their Expression property? + +
C# script solution +
Model.AllMeasures.Where(m => m.Expression.Contains("TODO")).Output();
Explanation: The first part of this script is the same as in question 1. Where(x => y) is another .NET LINQ method, that filters the preceding collection based on a so-called predicate. The predicate is expressed using the special C# Lambda notation x => y. On the left side of the arrow, you declare a variable with a name of your choice. The expression to the right of the arrow will be evaluated for every object in the collection, using the variable on the left to represent individual objects. This expression can be any valid C# expression that evaluates to a boolean value (true or false). Thus, the Where method simply filters the collection to return only those objects where the Lambda expression evaluates to true. So in the example above, we decide to use m as the name of our variable, which will represent the individual measures of our model. But we only want to keep measures whose Expression property Contains the word "TODO". Makes sense?

+
+ +
Dynamic LINQ solution +
:ObjectType="Measure" and Expression.Contains("TODO")
Explanation: The first part of this Dynamic LINQ expression is identical to question 1. Dynamic LINQ lets you use many different operators such as and or or to express complex logic. Notice how the second part of the expression is similar to the C# Lambda expression used above, except that we don't declare a variable to represent the measure. Since Dynamic LINQ is evaluated against every object in the TOM tree, any property or method name we add to the expression will implicitly be evaluated against the current object. Since different types of objects have different properties, no error is produced if the Filter box contains an invalid expression. However, when writing Dynamic LINQ expressions within the Best Practice Analyzer, an error will be shown if you try to access a property or method that doesn't exist on the chosen object types. +
+ +*** + +#### Question #3) Count the number of direct measure dependencies + +- How can we know the number of measures that directly reference the currently selected measure? You can always check your answer against the "Show dependencies" dialog. + +
C# script solution +
Selected.Measure.ReferencedBy.Measures.Count().Output();
Explanation: Selected.Measure refers to the currently selected measure in the explorer tree. All objects that can be referenced through DAX (measures, tables, columns, KPIs) have the ReferencedBy property, which is a special collection of objects that directly reference the former. Although we could use the LINQ-method .OfType<Measure>() to filter the collection to measures only, this particular collection contains a set of convenient properties that does this for us. One of them, is Measures.

+
+ +
Dynamic LINQ solution +
:ObjectType="Measure" and DependsOn.Measures.Any(Name="Reseller Total Sales")
Explanation: It's not possible to create a Dynamic LINQ filter expression based on the current selection, so instead we consider a specific measure in this example, [Reseller Total Sales]. The example here, will return all those objects who have a direct dependency on a measure named "Reseller Total Sales". The reason we're using "DependsOn" instead of "ReferencedBy" here, is that search filter expressions are evaluated against every single object in the model. That's the opposite of what we're doing in the C# script, where we already have a handle to a specific measure and want to obtain the list of measures referencing that measure. +
+ +*** + +#### Question #4) Recursively count the number of measure dependencies + +- Let's go deeper. How would you obtain the number of measures that depend recursively on the currently selected measure? + +
C# script solution +
Selected.Measure.ReferencedBy.Deep().OfType<Measure>().Count().Output();
+Here, we add the Deep() method to recursively traverse the dependency tree, to get a collection of all objects that reference the original measure either directly, or indirectly through other objects. We have to manually filter this collection to objects of type "Measure", to avoid seeing Calculated Columns, RLS Expressions, etc. The only thing left then, is to Count() the number of items in this result and Output() it to the screen.

By the way, if we wanted to display a list of these measures instead of just the count, we could write: +
Selected.Measure.ReferencedBy.Deep().OfType().Output();
+
+ +
Dynamic LINQ solution +
:ObjectType="Measure" and DependsOn.Deep().Any(Name="Reseller Total Sales")
Explanation: All methods that can be called using C# may also be called using Dynamic LINQ. So just like we did above, we're calling the Deep() method to recursively traverse the dependency tree upwards, to find all objects that have a dependency on an object named "Reseller Total Sales". Strictly speaking, this is not exactly the same as the C# expression above, as we would also get a positive hit on non-measure type objects with the name "Reseller Total Sales". To work around that, we could either explicitly state that we only want to consider measures... +
:DependsOn.Deep().Any(Name="Reseller Total Sales" and ObjectType="Measure")
+...or we could use the DaxObjectFullName property to check for a hit (column names would be fully qualified, and measures must be uniquely named across the entire model): +
:DependsOn.Deep().Any(DaxObjectFullName="[Reseller Total Sales]")
+
+ +*** + +#### Question #5) List all related dimensions + +- Given a fact table `'Reseller Sales'`, how do we obtain a list of all related dimension tables? + +
C# script solution +
var t = Model.Tables["Reseller Sales"];
+t.UsedInRelationships.Where(r => r.FromTable == t).Select(r => r.ToTable).Output();
Explanation: Okay, I admit, this one is a little tricky and because I used a variable to hold the given table, we end up with 2 lines of code instead of one. The naïve approach would be to simply write t.RelatedTables.Output();, but since the question specifically asked us to output only related dimension tables, we need to consider only those relationships where our given table is on the "From" side. That is the purpose of t.UsedInRelationships.Where(r => r.FromTable == t). If we just wanted the list of outgoing relationships, we'd be done here, but since we want a list of the tables pointed to by those relationships, we need to project this list to get the `ToTable` property of each relationship. That's exactly what .Select(r => r.ToTable) does. Makes sense? Now check out the Dynamic LINQ solution below.

+ +
Dynamic LINQ solution +
:UsedInRelationships.Any(ToTable=current and FromTable.Name = "Reseller Sales")
Explanation: Let's read this expression from left to right, keeping in mind that this is evaluated for every object in the model. UsedInRelationships is a list of relationships in which the current object participates. At this point, we've ruled out anything that's not a table or a column object, as these are the only ones that have the UsedInRelationships property. To filter anything that's not a dimension table, we only want to consider relationships pointing to the current object, from the table in question. .Any( ... ) evaluates to true if at least one of the relationships satisfies the condition: ToTable=current and FromTable.Name = "Reseller Total Sales". The special keyword current refers to the current object being evaluated. As we're equating this with the ToTable property of the relationship, we're ruling out columns from the search result, as this property can only be of type Table. FromTable.Name = ... is self-explanatory. +
+ +*** + +#### Question #6) Find all objects with the words "Total" and "Amount" (in that order) in their name + +![image](https://user-images.githubusercontent.com/8976200/44931220-c2dd4680-ad15-11e8-9e52-29ec07f1edb6.png) + +Hint: The regular expression for that would be `Total.*Amount` + +
C# script solution +
Model.AllMeasures.Where(m => System.Text.RegularExpressions.Regex.IsMatch(m.Name, "Total.*Amount")).Output();
Explanation: This one is actually quite annoying to do in the Advanced Script tab. Strictly speaking, we would actually have to search all the collections (Tables, AllMeasures, AllColumns, AllHierarchies, ...) and then concatenate the result, if we wanted to see them all in one view. Additionally, since the System.Text.RegularExpressions namespace is not in scope by default, the script is not really that typing-friendly. Check out the Dynamic LINQ solution instead.

+ +
Dynamic LINQ solution +
:Regex.IsMatch(Name, "Total.*Amount")
+Beautiful, isn't it? +
+ +*** + +#### Question #7) Same as #6 but with a case-_in_sensitive search + +
C# script solution +
Model.AllMeasures.Where(m => System.Text.RegularExpressions.Regex.IsMatch(m.Name, "Total.*Amount", RegexOptions.IgnoreCase)).Output();
+ +
Dynamic LINQ solution +
:Regex.IsMatch(Name, "Total.*Amount", "IgnoreCase")
+ +#### Stay tuned for more... diff --git a/content/localization/de/Advanced-Scripting_de.md b/content/localization/de/Advanced-Scripting_de.md new file mode 100644 index 00000000..98e98b2a --- /dev/null +++ b/content/localization/de/Advanced-Scripting_de.md @@ -0,0 +1,266 @@ +# Advanced Scripting + +This is an introduction to the Advanced Scripting capabilities of Tabular Editor. Information in this document is subject to change. Also, make sure to check out our script library @csharp-script-library, for some more real-life examples of what you can do with the scripting capabilities of Tabular Editor. + +## What is Advanced Scripting? + +The goal of the UI of Tabular Editor is to make it easy to perform most tasks commonly needed when building Tabular Models. For example, changing the Display Folder of multiple measures at once is just a matter of selecting the objects in the explorer tree and then dragging and dropping them around. The right-click context menu of the explorer tree provides a convenient way to perform many of these tasks, such as adding/removing objects from perspectives, renaming multiple objects, etc. + +There may be many other common workflow tasks, which are not as easily performed through the UI however. For this reason, Tabular Editor introduces Advanced Scripting, which lets advanced users write a script using C# syntax, to more directly manipulate the objects in the loaded Tabular Model. + +## Objects + +The [scripting API](xref:api-index) provides access to two top-level objects, `Model` and `Selected`. The former contains methods and properties that allow you to manipulate all objects in the Tabular Model, whereas the latter exposes only objects that are currently selected in the explorer tree. + +The `Model` object is a wrapper of the [Microsoft.AnalysisServices.Tabular.Model](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) class, exposing a subset of its properties, with some additional methods and properties for easier operations on translations, perspectives and object collections. The same applies to any descendant objects, such as Table, Measure, Column, etc. which all have corresponding wrapper objects. Please see for a complete listing of objects, properties and methods in the Tabular Editor wrapper library. + +The main advantage of working through this wrapper is, that all changes will be undoable from the Tabular Editor UI. Simply press CTRL+Z after executing a script, and you will see that all changes made by the script are immediately undone. Furthermore, the wrapper provides convenient methods that turn many common tasks into simple one-liners. We will provide some examples below. It is assumed that the reader is already somewhat familiar with C# and LINQ, as these aspects of Tabular Editors scripting capabilities will not be covered here. Users unfamiliar with C# and LINQ should still be able to follow the examples given below. + +## Setting object properties + +If you want to change a property of one object in particular, obviously the easiest way to do so would be directly through the UI. But as an example, let us see how we could achieve the same thing through scripting. + +Say you want to change the Format String of your [Sales Amount] measure in the 'FactInternetSales' table. If you locate the measure in the explorer tree, you can simply drag it onto the script editor. Tabular Editor will then generate the following code, which represents this particular measure in the Tabular Object Model: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"] +``` + +Adding an extra dot (.) after the right-most bracket, should make the autocomplete menu pop up, showing you which properties and methods exist on this particular measure. Simply choose "FormatString" in the menu, or write the first few letters and hit Tab. Then, enter an equal sign followed by "0.0%". Let us also change the Display Folder of this measure. Your final code should look like this: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"].FormatString = "0.0%"; +Model.Tables["FactInternetSales"].Measures["Sales Amount"].DisplayFolder = "New Folder"; +``` + +**Note:** Remember to put the semicolon (;) at the end of each line. This is a requirement of C#. If you forget it, you will get a syntax error message when trying to execute the script. + +Hit F5 or the "Play" button above the script editor to execute the script. Immediately, you should see the measure moving around in the explorer tree, reflecting the changed Display Folder. If you examine the measure in the Property Grid, you should also see that the Format String property has changed accordingly. + +### Working with multiple objects at once + +Many objects in the object model, are actually collections of multiple objects. For example, each Table object has a Measures collection. The wrapper exposes a series of convenient properties and methods on these collections, to make it easy to set the same property on multiple objects at once. This is described in detail below. Additionally, you may use all the standard LINQ extension methods to filter and browse the objects of a collection. + +Below is a few examples of the most commonly used LINQ extension methods: + +- `Collection.First([predicate])` Returns the first object in the collection satisfying the optional [predicate] condition. +- `Collection.Any([predicate])` Returns true if the collection contains any objects (optionally satisfying the [predicate] condition). +- `Collection.Where(predicate)` Returns a collection that is the original collection filtered by the predicate condition. +- `Collection.Select(map)` Projects each object in the collection into another object according to the specified map. +- `Collection.ForEach(action)` Performs the specified action on each element in the collection. + +In the above examples, `predicate` is a lambda expression that takes a single object as input, and returns a boolean value as output. For example, if `Collection` is a collection of measures, a typical `predicate` could look like: + +`m => m.Name.Contains("Reseller")` + +This predicate would return true only if the Name of the measure contains the character string "Reseller". Wrap the expression in curly braces and use the `return` keyword, if you need more advanced logic: + +```csharp +.Where(obj => { + if(obj is Column) { + return false; + } + return obj.Name.Contains("test"); +}) +``` + +Going back to the examples above, `map` is a lambda expression that takes a single object as input, and returns any single object as output. `action` is a lambda expression that takes a single object as input, but does not return any value. + +Use the IntelliSense functionality of the Advanced Script editor to see what other LINQ methods exist, or refer to the [LINQ-to-Objects documentation](https://msdn.microsoft.com/en-us/library/9eekhta0.aspx). + +## Working with the **Model** object + +To quickly reference any object in the currently loaded Tabular Model, you can drag and drop the object from the explorer tree and into the Advanced Scripting editor: + +![Dragging and dropping an object into the Advanced Scripting editor](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/DragDropTOM.gif) + +Please refer to the [TOM documentation](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) for an overview of which properties exist on the Model and its descendant objects. Additionally, refer to for a complete listing of the properties and methods exposed by the wrapper object. + +## Working with the **Selected** object + +Being able to explicitly refer to any object in the Tabular Model is great for some workflows, but sometimes you want to cherry pick objects from the explorer tree, and then execute a script against only the selected objects. This is where the `Selected` object comes in handy. + +The `Selected` object provides a range of properties that make it easy to identify what is currently selected, as well as limiting the selection to objects of a particular type. When browsing with Display Folders, and one or more folders are selected in the explorer tree, all their child items are considered to be selected as well. +For single selections, use the singular name for the type of object you want to access. For example, + +`Selected.Hierarchy` + +refers to the currently selected hierarchy in the tree, provided that one and only one hierarchy is selected. Use the plural type name, in case you want to work with multiselections: + +`Selected.Hierarchies` + +All properties that exist on the singular object, also exist on its plural form, with a few exceptions. This means that you can set the value of these properties for multiple objects at once, with just one line of code and without using the LINQ extension methods mentioned above. For example, say you wanted to move all currently selected measures into a new Display Folder called "Test": + +`Selected.Measures.DisplayFolder = "Test";` + +If no measures are currently selected in the tree, the above code does nothing, and no error is raised. Otherwise, the DisplayFolder property will be set to "Test" on all selected measures (even measures residing within folders, as the `Selected` object also includes objects in selected folders). If you use the singular form `Measure` instead of `Measures`, you will get an error unless the current selection contains exactly one measure. + +Although we cannot set the Name property of multiple objects at once, we still have some options available. If we just want to replace all occurrences of some character string with another, we can use the provided "Rename" method, like so: + +```csharp +Selected.Measures + .Rename("Amount", "Value"); +``` + +This would replace any occurence of the word "Amount" with the word "Value" in the names of all currently selected measures. +Alternatively, we may use the LINQ ForEach()-method, as described above, to include more advanced logic: + +```csharp +Selected.Measures + .ForEach(m => if(m.Name.Contains("Reseller")) m.Name += " DEPRECATED"); +``` + +This example will append the text " DEPRECATED" to the names of all selected measures where the names contain the word "Reseller". Alternatively, we could use the LINQ extension method `Where()` to filter the collection before applying the `ForEach()` operation, which would yield exactly the same result: + +```csharp +Selected.Measures + .Where(m => m.Name.Contains("Reseller")) + .ForEach(m => m.Name += " DEPRECATED"); +``` + +## Helper methods + +To make debugging scripts easier, Tabular Editor provides a set of special helper methods. Internally, these are static methods decorated with the `[ScriptMethod]`-attribute. This attribute allows scripts to call the methods directly, without the need to specify a namespace or class name. Plugins may also use the `[ScriptMethod]` attribute to expose public static methods for scripting in a similar way. + +As of 2.7.4, Tabular Editor provides the following script methods. Note that some of these may be invoked as extension methods. For example, `object.Output();` and `Output(object);` are equivalent. + +- `Output(object);` - displays detailed information about the specified object or collection of objects in a popup dialog. When executed through the UI, the user has an option to ignore additional popups. When executed through the CLI, the information is outputted to the console. +- `SaveFile(filePath, content);` - convenient way to save text data to a file. +- `ReadFile(filePath);` - convenient way to load text data from a file. +- `ExportProperties(objects, properties);` - convenient way to export a set of properties from multiple objects as a TSV string. +- `ImportProperties(tsvData);` - convenient way to load properties into multiple objects from a TSV string. +- `CustomAction(name);` - invoke a Custom Action by name. +- `CustomAction(objects, name);` - invoke a Custom Action on the specified objects. +- `ConvertDax(dax, useSemicolons);` - converts a DAX expression between US/UK and non-US/UK locales. If `useSemicolons` is true (default) the `dax` string is converted from the native US/UK format to non-US/UK. That is, commas (list separators) will be converted to semicolons and periods (decimal separators) will be converted to commas. Vice versa if `useSemicolons` is set to false. +- `FormatDax(IEnumerable objects, bool shortFormat, bool? skipSpace)` - formats DAX expressions on all objects in the provided collection +- `FormatDax(IDaxDependantObject obj)` - queues an object for DAX expression formatting when script execution is complete, or when the `CallDaxFormatter` method is called. +- `CallDaxFormatter(bool shortFormat, bool? skipSpace)` - formats all DAX expressions on objects enqueued so far +- `Info(string);` - Displays an informational message in a popup dialog. When the script is running in the CLI, an information message is written to the console. +- `Warning(string);` - Displays a warning message in a popup dialog. When the script is running in the CLI, a warning message is written to the console. +- `Error(string);` - Displays an error message in a popup dialog. When the script is running in the CLI, an error message is written to the console. + +You can find an updated list of all helper methods [here](xref:script-helper-methods). + +### Debugging scripts + +As mentioned above, you can use the `Output(object);` method to pause script execution, and open a dialog box with information about the passed object. You can also use this method as an extension method, invoking it as `object.Output();`. The script is resumed when the dialog is closed. + +The dialog will appear in one of four different ways, depending on the kind of object being output: + +- Singular objects (such as strings, ints and DateTimes, except any object that derives from TabularNamedObject) will be displayed as a simple message dialog, by invoking the `.ToString()` method on the object: + +![image](https://user-images.githubusercontent.com/8976200/29941982-9917d0cc-8e94-11e7-9e78-24aaf11fd311.png) + +- Singular TabularNamedObjects (such as Tables, Measures or any other TOM NamedMetadataObject available in Tabular Editor) will be shown in a Property Grid, similar to when an object has been selected in the Tree Explorer. Properties on the object may be edited in the grid, but note that if an error is encountered at a later point in the script execution, the edit will be automatically undone, if "Rollback on error" is enabled: + +![image](https://user-images.githubusercontent.com/8976200/29941852-2acc9846-8e94-11e7-9380-f84fef26a78c.png) + +- Any IEnumerable of objects (except TabularNamedObjects) will be displayed in a list, where each list item shows the `.ToString()` value and type of the object in the IEnumerable: + +![image](https://user-images.githubusercontent.com/8976200/29942113-02dad928-8e95-11e7-9c04-5bb87b396f3f.png) + +- Any IEnumerable of TabularNamedObjects will cause the dialog to display a list of the objects on the left, and a Property Grid on the right. The Property Grid will be populated from whatever object is selected in the list, and properties may be edited just as when a single TabularNamedObject is being output: + +![image](https://user-images.githubusercontent.com/8976200/29942190-498cbb5c-8e95-11e7-8455-32750767cf13.png) + +You can tick the "Don't show more outputs" checkbox at the lower left-hand corner, to prevent the script from halting on any further `.Output()` invocations. + +## .NET references + +[Tabular Editor version 2.8.6](https://github.com/TabularEditor/TabularEditor/tree/2.8.6) makes it a lot easier to write complex scripts. Thanks to the new pre-processor, you can now use the `using` keyword to shorten class names, etc. just like in regular C# source code. In addition, you can include external assemblies by using the syntax `#r ""` similar to .csx scripts used in Azure Functions. + +For example, the following script will now work as expected: + +```csharp +// Assembly references must be at the very top of the file: +#r "System.IO.Compression" + +// Using keywords must come before any other statements: +using System.IO.Compression; +using System.IO; + +var xyz = 123; + +// Using statements still work the way they're supposed to: +using(var data = new MemoryStream()) +using(var zip = new ZipArchive(data, ZipArchiveMode.Create)) +{ + // ... +} +``` + +By default, Tabular Editor applies the following `using` keyword (even though they are not specified in the script), to make common tasks easier: + +```csharp +using System; +using System.Linq; +using System.Collections.Generic; +using Newtonsoft.Json; +using TabularEditor.TOMWrapper; +using TabularEditor.TOMWrapper.Utils; +using TabularEditor.UI; +``` + +In addition, the following .NET Framework assemblies are loaded by default: + +- System.Dll +- System.Core.Dll +- System.Data.Dll +- System.Windows.Forms.Dll +- Microsoft.Csharp.Dll +- Newtonsoft.Json.Dll +- TomWrapper.Dll +- TabularEditor.Exe +- Microsoft.AnalysisServices.Tabular.Dll + +## Compiling with Roslyn + +If you prefer to compile your scripts using the new Roslyn compiler introduced with Visual Studio 2017, you can set this up under File > Preferences > General, starting with Tabular Editor version 2.12.2. This allows you to use newer C# language features such as string interpolation. Simply specify the path to the directory that holds the compiler executable (`csc.exe`) and specify the language version as an option for the compiler: + +![image](https://user-images.githubusercontent.com/8976200/92464140-0902f580-f1cd-11ea-998a-b6ecce57b399.png) + +### Visual Studio 2017 + +For a typical Visual Studio 2017 Enterprise installation, the Roslyn compiler is located here: + +``` +c:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Roslyn +``` + +This includes the C# 6.0 language features by default. + +![image](https://user-images.githubusercontent.com/8976200/92464584-a52cfc80-f1cd-11ea-9b66-3b47ac36f6c6.png) + +### Visual Studio 2019 + +For a typical Visual Studio 2019 Community installation, the Roslyn compiler is located here: + +``` +c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn +``` + +The compiler that ships with VS2019 supports C# 8.0 language features, which can be enabled by specifying the following as compiler options: + +``` +-langversion:8.0 +``` + +### Visual Studio 2022 + +For a typical Visual Studio 2022 **Community Edition**, the Roslyn compiler is located here: + +``` +C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\csc.exe +``` + +If you use another edition of Visual Studio 2022, the path might be slightly different. For example, for the **Enterprise Edition**, it is located here: + +``` +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\Roslyn +``` + +The compiler that ships with the most recent update of VS2022 supports [C# 12.0 language features](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12), which can be enabled by specifying the following as compiler options: + +``` +-langversion:12.0 +``` diff --git a/content/localization/de/Advanced-features_de.md b/content/localization/de/Advanced-features_de.md new file mode 100644 index 00000000..eff815cc --- /dev/null +++ b/content/localization/de/Advanced-features_de.md @@ -0,0 +1,113 @@ +# Advanced Features + +In addition to the features mentioned in the [Features at a glance](/te2/Features-at-a-glance) article, Tabular Editor also supports the following features for advanced usage. + +## Replace tables + +As of version 2.7, you can now replace a table simply by copying (CTRL+C) one table - even from another instance of Tabular Editor - and then selecting the table you want to replace, before hitting paste (CTRL+V). A prompt will ask you to confirm whether you really want to replace the table ("Yes"), insert as a new table ("No") or cancel the operation entirely: + +![image](https://user-images.githubusercontent.com/8976200/36545892-40983114-17ea-11e8-8825-e8de6fd4e284.png) + +If you choose "Yes", the selected table will be replaced with the table in the clipboard. Furthermore, all relationships pointing to or from that table will be updated to use the new table. For this to work, columns participating in relationships must have the same name and data type in both the original table, and the inserted table. + +## Roles and Row-Level Security + +As of version 2.1, Roles are now visible in the Explorer Tree. You can right-click the tree to create new roles, delete or duplicate existing roles. You can view and edit the members of each role, by locating the role in the Explorer Tree, and navigating to the "Role Members" property in the Property Grid. Note that when deploying, the [Deployment Wizard](/te2/Advanced-features#deployment-wizard) does not deploy role members by default. + +The biggest advantage of working with Roles through Tabular Editor, is that each Table object has a "Row Level Filters" property, which lets you view and edit the filters defined on that table, across all roles: + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/RLSTableContext.png) + +Of course, you can also view the filters across all tables in one particular role, similar to the UI of SSMS or Visual Studio: + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/RLSRoleContext.png) + +## View Table Partitions + +TODO + +## DAX Expression Editor + +TODO + +## Script Editor + +TODO (For now, please view [this article](/te2/Advanced-Scripting)) + +## Scripting/referencing objects + +You can use drag-and-drop functionality, to script out objects in the following ways: + +- Drag one or more objects to another Windows application (text editor or SSMS) + JSON code representing the dragged object(s) will be created. When dragging the Model node, a Table, a Role or a Data Source, a "createOrReplace" script is created. + +- Dragging an object (measure, column or table) into the DAX expression editor, will insert a fully-qualified DAX-reference to the object in question. + +- Dragging an object to the Advanced Script editor, will insert the C# code necessary to access the object through the TOM tree. + +## Deployment Wizard + +Tabular Editor comes with a deployment wizard that provides a few benefits compared to deploying from SSDT - especially when deploying to an existing database. After choosing a server and a database to deploy to, you have the following options for the deployment at hand: + +![Deployment Wizard](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Deployment.png) + +Leaving the "Deploy Connections" box unchecked, will make sure that all the data sources on the target database stay untouched. You will get an error if your model contains one or more tables with a data source, that does not already exist in the target database. + +Similarly, leaving out "Deploy Table Partitions", will make sure that existing partitions on your tables are not changed, leaving the data in the partitions intact. + +When the "Deploy Roles" box is checked, the roles in the target database will be updated to reflect what you have in the loaded model, however if the "Deploy Role Members" is unchecked, the members of each role will be unchanged in the target database. + +## Metadata Backup + +If you wish, Tabular Editor can automatically save a backup copy of the existing model metadata, prior to each save (when connected to an existing database) or deployment. This is useful if you're not using a version control system, but still need to rollback to a previous version of your model. + +To enable this setting, go to "File" > "Preferences", enable the checkbox and choose a folder to place the metadata backups: + + + +If the setting is enabled, a compressed (zipped) version of the existing model metadata will be saved to this location whenever you use the Deployment Wizard, or when you click the "Save" button while connected to a (workspace) database. + +## Formula Fix-up and Formula Dependencies + +Tabular Editor continuously parses the DAX expressions of all measures, calculated columns and calculated tables in your model, to construct a dependency tree of these objects. This dependency tree is used for the Formula Fix-up functionality, which may be enabled under "File" > "Preferences". Formula Fix-up automatically updates the DAX expression of any measure, calculated column or calculated table, whenever an object that was referenced in the expression is renamed. + +To visualize the dependency tree, right-click the object in the explorer tree and choose "Show dependencies..." + +![image](https://cloud.githubusercontent.com/assets/8976200/22482528/b37d27e2-e7f9-11e6-8b89-c503f9fffcac.png) + +## Import/Export Translations + +Select one or more cultures in the Explorer Tree, right-click and choose "Export Translations..." to generate a .json file that can be imported later in either Tabular Editor or Visual Studio. Choose "Import Translations..." to import a corresponding .json file. You can choose whether to overwrite existing translations. If you don't, translations defined in the .json file will only be applied to objects that do not already have a translation for the given culture. + +## Folder Serialization + +This feature allows you to more easily integrate your SSAS Tabular Models in a file-based source control environment such as TFS, SubVersion or Git. By choosing "File" > "Save to Folder...", Tabular Editor will deconstruct the Model.bim file and save its content as separate files in a folder structure similar to the structure of the JSON within the Model.bim. When subsequently saving the model, only files with changed metadata will be touched, meaning most version control systems can easily detect which changes have been done to the model, making source merging and conflict handling a lot easier, than when working with a single Model.bim file. + +![image](https://cloud.githubusercontent.com/assets/8976200/22483167/5e07ad52-e7fc-11e6-890f-5c0d20fff0cb.png) + +By default, objects are serialized down to the lowest object level (meaning measures, columns and hierarchies are stored as individual .json files). + +Additionally, Tabular Editor's [command-line syntax](xref:command-line-options) supports loading a model from this folder structure and deploying it directly to a database, making it easy for you to automate builds for continuous integration workflows. + +If you want to customize the granularity at which metadata is saved to individual files, go to File > Preferences and click the "Save to folder"-tab. Here, it's possible to toggle some serialization options which are passed to the TOM when serializing into JSON. Furthermore, you can check/uncheck the types of objects for which individual files will be generated. In some Version Control scenarios, you might want to store everything related to one table in a file on its own, where as in other scenarios you may need individual files for columns and measures. + +These settings are saved in an annotation on the model, the first time you use the Save to Folder function, so that the settings are reused when the model is loaded and the "Save"-button is subsequently clicked. If you want to apply new settings, use "File > Save to Folder..." again. + + + +## User Settings Files + +When Tabular Editor is executed, it writes some additional files to the disk at various locations. What follows is a description of these files and their content: + +### In %ProgramData%\TabularEditor + +- **BPARules.json** Best Practice Analyzer rules that are available to all users. +- **TOMWrapper.dll** This file is used when executing scripts inside Tabular Editor. You can also reference the .dll in your own .NET projects, to utilise the wrapper code. If you are having issues executing advanced scripts after upgrading Tabular Editor, please delete this file and restart Tabular Editor. +- **Preferences.json** This file stores all preferences set in the File > Preferences dialog. + +### In %AppData%\Local\TabularEditor + +- **BPARules.json** Best Practice Analyzer rules that are available only to the current user. +- **CustomActions.json** Custom script actions that can be invoked from the right-click menu or the Tools-menu of the Explorer Tree. These actions can be created on the Advanced Script Editor tab. +- **RecentFiles.json** Stores a list of recently opened .bim files. The last most 10 items in this list is displayed in the File > Recent Files menu. +- **RecentServers.json** Stores a list of recently accessed server names. These are displayed in the dropdown portion of the "Connect to Database" dialog box and in the Deployment Wizard. diff --git a/content/localization/de/Best-Practice-Analyzer-Improvements_de.md b/content/localization/de/Best-Practice-Analyzer-Improvements_de.md new file mode 100644 index 00000000..e78c71ab --- /dev/null +++ b/content/localization/de/Best-Practice-Analyzer-Improvements_de.md @@ -0,0 +1,68 @@ +# Best Practice Analyzer Improvements + +As of [Tabular Editor 2.8.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.8.1), the Best Practice Analyzer has received a major overhaul. + +The first thing you'll notice, is that Tabular Editor now reports the number of Best Practice issues directly within the main UI: + +![image](https://user-images.githubusercontent.com/8976200/53631987-baee5880-3c0b-11e9-9d66-e906cccce2be.png) + +Whenever a change is made to the model, the Best Practice Analyzer scans your model for issues in the background. You can disable this feature under File > Preferences. + +Clicking the link (or pressing F10), brings up the new and improved Best Practice Analyzer UI: + +![image](https://user-images.githubusercontent.com/8976200/53631947-9eeab700-3c0b-11e9-9217-5739d4de2f88.png) + +If you've used the Best Practice Analyzer in previous versions, the first thing you'll notice is that the UI has been completely redesigned, making it take up less real estate on your screen. This allows you to dock the window on one side of your desktop, while keeping the main window in the other side, allowing you to work with both at once. + +The Best Practice Analyzer window continuously lists all the **effective rules** on your model as well as the objects that are in violation of each rule. Right-clicking anywhere inside the list or using the toolbar buttons at the top of the window, let's you perform the following actions: + +- **Manage rules...**: This opens the Manage Rules UI, which we will cover below. This UI can also be accessed through the "Tools > Manage BPA Rules..." menu of the main UI. +- **Go to object...**: Choosing this option or double-clicking on an object in the list, takes you to the same object in the main UI. +- **Ignore item/items**: Selecting one or more objects in the list and choosing this option, will apply an annotation to the chosen objects indicating that the Best Practice Analyzer should ignore the objects going forward. If you ignored an object by mistake, toggle the "Show ignored" button at the top of the screen. This will let you unignore an object that was previously ignored. +- **Ignore rule**: If you've selected one or more rules in the list, this option will put an annotation at the model level that indicates, that the selected rule should always be ignored. Again, by toggling the "Show ignored" button, you can unignore rules as well. +- **Generate fix script**: Rules that have an easy fix (meaning the issue can be resolved simply by setting a single property on the object), will have this option enabled. By clicking, you will get a C# script copied into your clipboard. This script can then be subsequently pasted into the [Advanced Scripting](/Advanced-Scripting) area of Tabular Editor, where you can review it before executing it to apply the fix. +- **Apply fix**: This option is also available for rules than have an easy fix, as mentioned above. Instead of copying the script to the clipboard, it will be executed immediately. + +## Managing Best Practice Rules + +If you need to add, remove or modify the rules applying to your model, there's a brand new UI for that as well. You can bring it up by clicking the top-left button on the Best Practice Analyzer window, or by using the "Tools > Manage BPA Rules..." menu item in the main window. + +![image](https://user-images.githubusercontent.com/8976200/53632990-2f29fb80-3c0e-11e9-82fe-ee9c921662c7.png) + +This UI contains two lists: The top list represents the **collections** of rules that are currently loaded. Selecting a collection in this list, will display all the rules that are defined within this collection in the bottom list. By default, three rule collections will show up: + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%AppData%\..\Local\TabularEditor\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +If the same rule (by ID) is located in more than one collection, the order of precedence is from top to bottom, meaning a rule defined within the model takes precedence over a rule, with the same ID, defined on the local machine. This allows you to override existing rules, for example to take model specific conventions into account. + +At the top of the list, you'll see a special collection called **(Effective rules)**. Selecting this collection will show you the list of rules that actually apply to the currently loaded model, respecting the precedence of rules with identical ID's, as mentioned above. The lower list will indicate which collection a rule belongs to. Also, you will notice that a rule will have its name striked out, if a rule with a similar ID exists in a collection of higher precedence: + +![image](https://user-images.githubusercontent.com/8976200/53633831-74e7c380-3c10-11e9-925e-1419987f5a17.png) + +### Adding additional collections + +A new feature in Tabular Editor 2.8.1, is the possibility of including rules from other sources on a model. If, for example, you have a rules file located on a network share, you can now include that file as a rule collection in the current model. If you have write access to the location of the file, you'll also be able to add/modify/remove rules from the file. Rule collections that are added this way take precedence over rules that are defined within the model. If you add multiple such collections, you can shift them up and down to control their mutual precedence. + +Click the "Add..." button to add a new rule collection to the model. This provides the following options: + +![image](https://user-images.githubusercontent.com/8976200/53634211-7cf43300-3c11-11e9-8fed-7df113264a6f.png) + +- **Create new Rule File**: This will create a new, empty, .json file at the specified location, which you can subsequently add rules to. When choosing the file, notice that there is an option for using relative file paths. This is useful when you want to store the rule file in the same code repository as the current model. However, please be aware that a relative rule file reference only works, when the model has been loaded from disk (since there is no working directory when loading a model from an instance of Analysis Services). +- **Include local Rule File**: Use this option if you already have a .json file containing rules, that you want to include in your model. Again, you have the option of using relative file paths, which may be beneficial if the file is located close to the model metadata. If the file is located on a network share (or generally, on a drive different than where the currently loaded model metadata resides), you can only include it using an absolute path. +- **Include Rule File from URL**: This option lets you specify an HTTP/HTTPS URL, that should return a valid rule definition (json). This is useful if you want to include rules from an online source, for example the [standard BPA rules](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json) from the [BestPracticeRules GitHub site](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules). Note that rule collections added from online sources will be read-only. + +### Modifying rules within a collection + +The lower part of the screen will let you add, edit, clone and delete rules within the currently selected collection, provided you have write access to the location where the collection is stored. Also, the "Move to..." button allows you to move or copy the selected rule to another collection, making it easy to manage multiple collections of rules. The UI for editing a rule definition is unchanged from previous versions of Tabular Editor, so please refer to the [old Best Practice Analyzer article](/Best-Practice-Analyzer#rule-expression-samples) for more information on how to use that. + +### Rule Description Placeholders + +One small improvement compared to previous versions, is that you can now use the following placeholder values within the Best Practice Rule's description. This provides more customisable descriptions that will appear as tooltips in the Best Practice UI: + +- `%object%` returns a fully qualified DAX reference (if applicable) to the current object +- `%objectname%` returns only the name of the current object +- `%objecttype%` returns the type of the current object + +![image](https://user-images.githubusercontent.com/8976200/53671918-587f7180-3c78-11e9-855f-ed497f2c0c98.png) diff --git a/content/localization/de/Best-Practice-Analyzer_de.md b/content/localization/de/Best-Practice-Analyzer_de.md new file mode 100644 index 00000000..3a91ba69 --- /dev/null +++ b/content/localization/de/Best-Practice-Analyzer_de.md @@ -0,0 +1,148 @@ +# Best Practice Analyzer + +> [!NOTE] +> Some of the information and screenshots in this article is outdated, as the Best Practice Analyzer has received a [complete overhaul in Tabular Editor v. 2.8.1](Best-Practice-Analyzer-Improvements.md). Information on Dynamic LINQ (rule expressions) is still up-to-date. + +Inspired by [this excellent suggestion](https://github.com/TabularEditor/TabularEditor/issues/39), I am proud to present the Best Practice Analyzer (BPA) - a brand new feature of Tabular Editor. Go to the Tools-menu and click "Best Practice Analyzer...", this will open the following window (you can continue working on your model in the main window, while the BPA window stays open): + +![image](https://cloud.githubusercontent.com/assets/8976200/25298153/07cb3ae0-26f3-11e7-84cb-1c27a5911560.png) + +BPA lets you define rules on the metadata of your model, to encourage certain conventions and best practices while developing in SSAS Tabular. + +Clicking one of the rules in the top list, will show you all objects that satisfy the conditions of the given rule in the bottom list: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298226/9c036214-26f3-11e7-97ea-03ef82366eb5.png) + +Double-clicking an object in the list switches the focus back to the main Tabular Editor window, where the object will be selected in the Explorer Tree ("Go to object..."). It is also possible to specify that a rule should be ignored entirely (can also be done by removing the checkmarks from the rule list), or ignored only for a specific object. Ignores are stored in the metadata annotations of the Model.bim file. + +To create a new rule, simply click "Add rule..." while you have a Tabular Model loaded in Tabular Editor. This opens a new window, where you can give your rule a name, a description and specify the conditions of the rule: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298330/4178cbe4-26f4-11e7-97ee-d80c1dbc54ed.png) + +A visual rule builder is planned for a later release. For now, you specify the rule condition using a [Dynamic LINQ expression](https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions) that allows you to access all properties on the type(s) of object(s) specified in the dropdown. All objects that satisfy the condition will show up in the BPA UI when the rule is selected. + +By default, a rule created this way will be added to the metadata annotations of the Model object and stored in the Model.bim file or the connected database, when you click "Save" in Tabular Editor. You can promote a rule stored locally in a model to a "global" rule. Global rules are stored in your %AppData%\Local\TabularEditor folder in a file called "BPARules.json". You can also put the BPARules.json in the %ProgramData%\TabularEditor folder, to make the rules available to all users on the machine. + +Note that the rule ID's must always be unique. In case a rule within the model metadata has the same ID as a rule in the %AppData% or %ProgramData% folder, the order of precedence is: + +- Rules stored locally in the model +- Rules stored in the %AppData%\Local folder +- Rules stored in the %ProgramData% folder + +## Rule Expression Samples + +In this section, you'll see some examples of Dynamic LINQ expressions that can be used to define rules. The expression that is entered in the Rule Expression Editor, will be evaluated whenever focus leaves the textbox, and any syntax errors will be shown on top of the screen: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380170/9f01634e-29af-11e7-952e-e10a1f28df32.png) + +Your rule expressions may access any public properties on the objects in the TOM. If you try to access a property that does not exist on that type of object, an error will also be shown: + +![image](https://cloud.githubusercontent.com/assets/8976200/25381302/798bab98-29b3-11e7-931e-789e5286fc45.png) + +"Expression" does not exist on the "Column" object, but if we switch the dropdown to "Calculated Columns", the statement above works fine: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380451/87b160da-29b0-11e7-8e2e-c4e47593007d.png) + +Dynamic LINQ supports all the standard arithmetic, logical and comparison operators, and using the "."-notation, you can access subproperties and -methods of all objects. + +``` +String.IsNullOrWhitespace(Expression) and not Name.StartsWith("Dummy") +``` + +The above statement, applied to Calculated Columns, Calculated Tables or Measures, flags those that have an empty DAX expression unless the object's name starts with the text "Dummy". + +Using LINQ, we can also work with collections of objects. The following expression, applied to tables, will find those that have more than 10 columns which are not organized in Display Folders: + +``` +Columns.Count(DisplayFolder = "") > 10 +``` + +Whenever we use a LINQ method to iterate over a collection, the expression used as an argument to the LINQ method is evaluated on the items in the collection. Indeed, DisplayFolder is a property on columns that does not exist at the Table level. + +Here, we see this rule in action on the Adventure Works tabular model. Note how the "Reseller" table shows up as being in violation, while the "Reseller Sales" does not show up (columns in the latter have been organized in Display Folders): + +![image](https://cloud.githubusercontent.com/assets/8976200/25380809/d9d1c3a4-29b1-11e7-839e-29450ad39c8a.png) + +To refer to the parent object inside a LINQ method, use the special "outerIt" syntax. This rule, applied to tables, will find those that contain columns whose name does not start with the table name: + +``` +Columns.Any(not Name.StartsWith(outerIt.Name)) +``` + +It would probably make more sense to apply this rule to Columns directly, in which case it should be written as: + +``` +not Name.StartsWith(Table.Name) +``` + +To compare against enumeration properties, simply pass the enumerated value as a string. This rule, will find all columns whose name end with the word "Key" or "ID", but where the SummarizeBy property has not been set to "None": + +``` +(Name.EndsWith("Key") or Name.EndsWith("ID")) and SummarizeBy <> "None" +``` + +## Finding unused objects + +When building Tabular Models it is important to avoid high-cardinality columns at all costs. Typical culprits are system timestamps, technical keys, etc. that have been imported to the model by mistake. In general, we should make sure that the model only contains columns that are actually needed. Wouldn't it be nice if the Best Practice Analyzer could tell us which columns are likely not needed at all? + +The following rule will report columns that: + +- ...are hidden (or whose parent table is hidden) +- ...are not referenced by any DAX expressions (considers all DAX expressions in the model - even drillthrough and RLS filter expressions) +- ...do not participate in any relationships +- ...are not used as the "Sort By"-column of any other column +- ...are not used as levels of a hierarchy. + +The Dynamic LINQ expression for this BPA rule is: + +``` +(IsHidden or Table.IsHidden) +and ReferencedBy.Count = 0 +and (not UsedInRelationships.Any()) +and (not UsedInSortBy.Any()) +and (not UsedInHierarchies.Any()) +``` + +The same technique can be used to find unused measures. It's a little simpler, since measures can't participate in relationships, etc. So instead, let's spice things up a bit, by also considering whether any downstream objects that reference a given measure, are visible or not. That is, if measure [A] is referenced by measure [B], and both measure [A]" and [B] are hidden, and no other DAX expressions refer to these two measures, we should let the developer know that it is safe to remove both of them: + +``` +(IsHidden or Table.IsHidden) +and not ReferencedBy.AllMeasures.Any(not IsHidden) +and not ReferencedBy.AllColumns.Any(not IsHidden) +and not ReferencedBy.AllTables.Any(not IsHidden) +and not ReferencedBy.Roles.Any() +``` + +## Fixing objects + +In some cases, it is possible to automatically fix the issues on objects satisfying the criteria of a rule. For example when it's just a matter of setting a simple property on the object. Take a closer look at the JSON behind the following rule: + +```json +{ + "ID": "FKCOLUMNS_HIDDEN", + "Name": "Hide foreign key columns", + "Category": null, + "Description": "Columns used on the Many side of a relationship should be hidden.", + "Severity": 1, + "Scope": "Column", + "Expression": "Model.Relationships.Any(FromColumn = outerIt) and not IsHidden and not Table.IsHidden", + "FixExpression": "IsHidden = true", + "Compatibility": [ + 1200, + 1400 + ], + "IsValid": false +} +``` + +This rule finds all columns that are used in a relationship (on the "Many"/"From" side), but where the column or its parent table are not hidden. It is recommended that such columns are never shown, as users should filter data using the related (dimension) table instead. So the fix in this case, would be to set the columns IsHidden property to true, which is exactly what the "FixExpression" string above does. To see this in action, right-click any objects that violate the rule, and choose "Generate Fix Script". This puts a small script into the clipboard, which can be pasted into the Advanced Script Editor, from where you can easily review the code and execute it: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298489/9035bab6-26f5-11e7-8134-8502daaf4132.png) + +Remember that you can always undo (CTRL+Z) changes done to a model after script execution. + +Feedback on this new tool is most welcome! In the future, we plan to provide a set of universal Best Practices that will ship with Tabular Editor to get you started. Furthermore, plans are in motion to make the Best Practice Analyzer available as a plug-in to Visual Studio, so those of you not using Tabular Editor can still benefit from it. + +## Official Best Practice Rules + +Microsoft has provided a set of standard Best Practice Rules. The definition of these rules is available in [this GitHub repository](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules). Microsoft encourages community contributions and feedback to this repository. For more details and background on these rules, please view [this official blogpost](https://powerbi.microsoft.com/en-us/blog/best-practice-rules-to-improve-your-models-performance/). diff --git a/content/localization/de/Command-line-Options_de.md b/content/localization/de/Command-line-Options_de.md new file mode 100644 index 00000000..78a929c4 --- /dev/null +++ b/content/localization/de/Command-line-Options_de.md @@ -0,0 +1,268 @@ +--- +uid: command-line-options +title: Command Line +author: Daniel Otykier +updated: 2021-08-26 +--- + +# Command Line + +Tabular Editor can be executed from the command-line to perform various tasks, which may be useful in Automated Build and Deployment scenarios, etc. + +**Note:** Since TabularEditor.exe is a WinForms application, executing it directly from a windows command-prompt will cause the thread to return immediately to the prompt. This may cause issues in command scripts, etc. To wait for TabularEditor.exe to complete its command-line tasks, always execute it using: `start /wait TabularEditor ...` + +To view the command-line options available in Tabular Editor, run the following command: + +**Windows Command line:** + +```shell +start /wait TabularEditor.exe /? +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru -ArgumentList "/?" +``` + +Output: + +```cmd +Usage: + +TABULAREDITOR ( file | server database | -L [name] ) [-S script1 [script2] [...]] + [-SC] [-A [rules] | -AX rules] [(-B | -F | -TMDL) output [id]] [-V | -G] [-T resultsfile] + [-D [server database [-L user pass] [-F | -O [-C [plch1 value1 [plch2 value2 [...]]]] + [-P [-Y]] [-S] [-R [-M]]] + [-X xmla_script]] [-W] [-E]] + +file Full path of the Model.bim file or database.json model folder to load. +server Server\instance name or connection string from which to load the model +database Database ID of the model to load. If blank (") picks the first available + database on the server. +-L / -LOCAL Connects to a Power BI Desktop (local) instance of Analysis Services. If no + name is specified, this assumes that exactly 1 instance is running. Otherwise, + name should match the name of the .pbix file loaded in Power BI Desktop. +-S / -SCRIPT Execute the specified script on the model after loading. + scriptN Full path of one or more files containing a C# script to execute or an inline + script. +-SC / -SCHEMACHECK Attempts to connect to all Provider Data Sources in order to detect table schema + changes. Outputs... + ...warnings for mismatched data types and unmapped source columns + ...errors for unmapped model columns. +-A / -ANALYZE Runs Best Practice Analyzer and outputs the result to the console. + rules Optional path of file or URL of additional BPA rules to be analyzed. If + specified, model is not analyzed against local user/local machine rules, + but rules defined within the model are still applied. +-AX / -ANALYZEX Same as -A / -ANALYZE but excludes rules specified in the model annotations. +-B / -BIM / -BUILD Saves the model (after optional script execution) as a Model.bim file. + output Full path of the Model.bim file to save to. + id Optional id/name to assign to the Database object when saving. +-F / -FOLDER Saves the model (after optional script execution) as a Folder structure. + output Full path of the folder to save to. Folder is created if it does not exist. + id Optional id/name to assign to the Database object when saving. +-TMDL Saves the model (after optional script execution) as a TMDL folder structure. + output Full path of the TMDL folder to save to. Folder is created if it does not exist. + id Optional id/name to assign to the Database object when saving. +-V / -VSTS Output Visual Studio Team Services logging commands. +-G / -GITHUB Output GitHub Actions workflow commands. +-T / -TRX Produces a VSTEST (trx) file with details on the execution. + resultsfile File name of the VSTEST XML file. +-D / -DEPLOY Command-line deployment + If no additional parameters are specified, this switch will save model metadata + back to the source (file or database). + server Name of server to deploy to or connection string to Analysis Services. + database ID of the database to deploy (create/overwrite). + -L / -LOGIN Disables integrated security when connecting to the server. Specify: + user Username (must be a user with admin rights on the server) + pass Password + -F / -FULL Deploy the full model metadata, allowing overwrite of an existing database. + -O / -OVERWRITE Allow deploy (overwrite) of an existing database. + -C / -CONNECTIONS Deploy (overwrite) existing data sources in the model. After the -C switch, you + can (optionally) specify any number of placeholder-value pairs. Doing so, will + replace any occurrence of the specified placeholders (plch1, plch2, ...) in the + connection strings of every data source in the model, with the specified values + (value1, value2, ...). + -P / -PARTITIONS Deploy (overwrite) existing table partitions in the model. + -Y / -SKIPPOLICY Do not overwrite partitions that have Incremental Refresh Policies defined. + -S / -SHARED Deploy (overwrite) shared expressions. + -R / -ROLES Deploy roles. + -M / -MEMBERS Deploy role members. + -X / -XMLA No deployment. Generate XMLA/TMSL script for later deployment instead. + xmla_script File name of the new XMLA/TMSL script output. + -W / -WARN Outputs information about unprocessed objects as warnings. + -E / -ERR Returns a non-zero exit code if Analysis Services returns any error messages after + the metadata was deployed / updated. +``` + +> [!WARNING] +> The addition of the `-S` / `-SHARED` deployment option flag in [Tabular Editor 2.27.0](https://github.com/TabularEditor/TabularEditor/releases/tag/2.27.0) is a **breaking change**. If you're using the Tabular Editor CLI to perform deployments and you are upgrading from an earlier version of Tabular Editor, make sure to include that flag in your CLI commands, as **shared expressions will otherwise not be deployed**. + +> [!TIP] +> The `-F` flag was introduced in [Tabular Editor 2.27.0](https://github.com/TabularEditor/TabularEditor/releases). It is used to perform a "full" deployment and is equivalent to specifying `-O -C -P -S -R -M`. + +## Connecting to Azure Analysis Services + +You can use any valid SSAS connection string in place of a server name in the command. The following command loads a model from Azure Analysis Services and saves it locally as a Model.bim file: + +**Windows Command Line:** + +```shell +start /wait TabularEditor.exe "Provider=MSOLAP;Data Source=asazure://northeurope.asazure.windows.net/MyAASServer;User ID=xxxx;Password=xxxx;Persist Security Info=True;Impersonation Level=Impersonate" MyModelDB -B "C:\Projects\FromAzure\Model.bim" +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -ArgumentList "`"Provider=MSOLAP;Data Source=asazure://northeurope.asazure.windows.net/MyAASServer;User ID=xxxx;Password=xxxx;Persist Security Info=True;Impersonation Level=Impersonate`" MyModelDB -B C:\Projects\FromAzure\Model.bim" +``` + +If you prefer to connect using a Service Principal (Application ID and Key) instead of Azure Active Directory authentication, you can use the following connection string: + +``` +Provider=MSOLAP;Data Source=asazure://northeurope.asazure.windows.net/MyAASServer;User ID=app:@;Password=;Persist Security Info=True;Impersonation Level=Impersonate +``` + +## Automating script changes + +If you have created a script inside Tabular Editor, and you want to apply this script to a Model.bim file prior to deployment, you can use the command-line option "-S" (Script): + +**Windows Command Line:** + +```shell +start /wait TabularEditor.exe "C:\Projects\MyModel\Model.bim" -S "C:\Projects\MyModel\MyScript.cs" -D localhost\tabular MyModel +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -ArgumentList "`"C:\Projects\MyModel\Model.bim`" -S `"C:\Projects\MyModel\MyScript.cs`" -D `"localhost\tabular`" `"MyModel`"" +``` + +This command will load the Model.bim file in Tabular Editor, apply the specified script and deploy the modified model to the "localhost\tabular" server as a new database "MyModel". Use the "-O" (Overwrite) switch if you want to overwrite an existing database on the server with the same name. + +You can use the "-B" (Build) switch instead of the "-D" (Deploy) switch, to output the modified model as a new Model.bim file, instead of deploying it directly to a server. This is useful if you want to deploy the model using another deployment tool, or if you want to inspect the model in Visual Studio or Tabular Editor prior to deployment. It could also be useful for automated build scenarios, where you want to store the modified model as an artifact of the release, before deploying. + +## Modifying connection strings during deployment + +Let's assume you have a model containing a Data Source with the following connection string: + +``` +Provider=SQLOLEDB.1;Data Source=sqldwdev;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DW +``` + +During deployment, you want to modify the string, to point to a UAT or production database. The best way to do this, is to first use a script, that changes the entire connection string into a placeholder value, and then use the -C switch to swap the placeholder with the actual connection string. + +Put the following script into a file called "ClearConnectionStrings.cs" or similar: + +```csharp +// This will replace the connection string of all Provider (legacy) data sources in the model +// with a placeholder based on the name of the data source. E.g., if your data source is called +// "SQLDW", the connection string after running this script would be "SQLDW": + +foreach(var ds in Model.DataSources.OfType()) + ds.ConnectionString = ds.Name; +``` + +We can instruct Tabular Editor to execute the script, and then perform placeholder swapping using the following command: + +**Windows Command Line:** + +```shell +start /wait TabularEditor.exe "Model.bim" -S "ClearConnectionStrings.cs" -D localhost\tabular MyModel -C "SQLDW" "Provider=SQLOLEDB.1;Data Source=sqldwprod;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DW" +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -ArgumentList "Model.bim -S ClearConnectionStrings.cs -D localhost\tabular MyModel -C SQLDW `"Provider=SQLOLEDB.1;Data Source=sqldwprod;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DW`"" +``` + +The command above, will deploy the Model.bim file as a new SSAS database "MyModel" on the "localhost\tabular" SSAS instance. Before deployment, the script is used to replace all connection strings on provider (legacy) data sources, with the name of the data source, to be used as a placeholder. Assuming we only have a single data source called "SQLDW", the -C switch will then update the connection string, replacing "SQLDW" with the entire string specified. + +This technique is useful for scenarios, where you want to deploy the same model to multiple environments that should process data from different (identical) sources - for example, a production, pre-prod or UAT database. If using Azure DevOps (see below), consider using a variable to store the actual connection string to be used, instead of hardcoding it in the command. + +## Integration with Azure DevOps + +If you want to use the Tabular Editor CLI inside an Azure DevOps pipeline, you should use the "-V" switch on any TabularEditor.exe command executed by your script. This switch will cause Tabular Editor to output logging commands in a [format readable by Azure DevOps](https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md). These allow Azure DevOps to react properly to errors, etc. + +When performing deployment through the command-line, information about unprocessed objects will be outputted to the prompt. In automated deployment scenarios, you may want your build agent to react to situations where objects become unprocessed, for example when adding new columns, changing the DAX expression of a calculated table, etc. In this case, you can use the "-W" switch in addition to the "-V" switch mentioned above, to output this information as warnings. Doing so, will cause the deployment to return the "SucceededWithIssues" status to Azure DevOps, after deployment is completed. You may also use the "-E" switch if you want the deployment to return status "Failed" in case the server reports any DAX errors back after successful deployment. + +`start /wait` is not necessary when executing TabularEditor.exe within a Command Line Task in an Azure DevOps pipeline. This is because the Command Line Task will not complete, until all threads spawned by the task have terminated. In other words, you need only use `start /wait` if you have additional commands following the call to TabularEditor.exe, and in this case, make sure to use `start /B /wait`. The `/B` switch is required in order for the output from TabularEditor.exe to be correctly piped back to the pipeline log. + +```shell +TabularEditor.exe "C:\Projects\My Model\Model.bim" -D ssasserver databasename -O -C -P -S -V -E -W +``` + +Or with multiple commands: + +```shell +start /B /wait TabularEditor.exe "C:\Projects\Finance\Model.bim" -D ssasserver Finance -O -C -P -S -V -E -W +start /B /wait TabularEditor.exe "C:\Projects\Sales\Model.bim" -D ssasserver Sales -O -C -P -S -V -E -W +``` + +The figure below shows what such a build looks like in Azure DevOps: + +![image](https://user-images.githubusercontent.com/8976200/27128146-bc044356-50fd-11e7-9a67-b893fc48ea50.png) + +If the deployment fails for any reason, Tabular Editor returns the "Failed" status to Azure DevOps, regardless of whether or not you are using the "-W" switch. + +For more information on Azure DevOps and Tabular Editor, [take a look at this blog series](https://tabulareditor.github.io/2019/02/20/DevOps1.html) (especially [chapter 3](https://tabulareditor.github.io/2019/10/08/DevOps3.html) and onward). + +### Azure DevOps PowerShell Task + +If you prefer to use a PowerShell task instead of a command line task, you must execute TabularEditor.exe using the `Start-Process` cmdlet, as demonstrated above. In addition, make sure to pass the process exit code as the exit parameter in your PowerShell script, so that errors occurring in Tabular Editor will cause the PowerShell task to fail: + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -argumentList "`"C:\Projects\My Model\Model.bim`" -D ssasserver databasename -O -C -P -S -V -E -W" +exit $p.ExitCode +``` + +## Running the Best Practice Analyzer + +You can use the "-A" switch to have Tabular Editor scan your model for all objects that are in violation of any Best Practice Rules defined on the local machine (in the %AppData%\..\Local\TabularEditor\BPARules.json file), or as annotations within the model itself. Alternatively, you can specify a path of a .json file containing Best Practice Rules after the "-A" switch, to scan the model using the rules defined in the file. Objects that are in violation will be outputted to the console. + +If you're also using the "-V" switch, the severity level of each rule will determine how the rule violation is reported to the build pipeline: + +- Severity = 1 will be informational only +- Severity = 2 will cause a WARNING +- Severity >= 3 will cause an ERROR + +## Performing a data source schema check + +As of [version 2.8](https://github.com/TabularEditor/TabularEditor/releases/tag/2.8), you can use the -SC (-SCHEMACHECK) switch to validate table source queries. This is equivalent to invoking the [Refresh Table Metadata UI](xref:importing-tables-te2#refreshing-table-metadata) except that no changes will be made to the model, but schema differences will be reported to the console. Changed Data Types and columns that were added to the source will be reported as warnings. Missing source columns will be reported as errors. If both the -SC (-SCHEMACHECK) and -S (-SCRIPT) switch are specified, the schema check will run AFTER the script has successfully executed, allowing you to modify Data Source properties before the schema check is performed, for example in order to specify a credential password. + +You can also annotate tables and columns if you want the schema check to treat them in a specific way. [More information here](xref:importing-tables-te2#ignoring-objects). + +## Command Line output and Exit Codes + +The command line provides various details, depending on the switches used and any events encountered during execution. Exit Codes were introduced in [version 2.7.4](https://github.com/TabularEditor/TabularEditor/releases/tag/2.7.4). + +| Level | Command | Message | Clarification | +| ----------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Error | (Any) | Invalid argument syntax | Invalid arguments were provided to the Tabular Editor CLI | +| Error | (Any) | File not found: ... | | +| Error | (Any) | Error loading file: ... | The file is corrupt or does not contain valid TOM metadata in a JSON format | +| Error | (Any) | Error loading model: ... | Not able to connect to the provided Analysis Services instance, database not found, database metadata corrupt or database not of a supported compatibility level | +| Error | -SCRIPT | Specified script file not found | | +| Error | -SCRIPT | Script compilation errors: | Script contained invalid C# syntax. Details will be outputted on the following lines. | +| Error | -SCRIPT | Script execution error: ... | Unhandled exception when executing the script. | +| Information | -SCRIPT | Script line #: ... | Use of the `Info(string)` or `Output(string)` methods within the script. | +| Warning | -SCRIPT | Script warning: ... | Use of the `Warning(string)` method within the script. | +| Error | -SCRIPT | Script error: ... | Use of the `Error(string)` method within the script. | +| Error | -FOLDER, -BIM | -FOLDER and -BIM arguments are mutually exclusive. | Tabular Editor can not save the currently loaded model to a folder structure and a .bim file in a single execution. | +| Error | -ANALYZE | Rulefile not found: ... | | +| Error | -ANALYZE | Invalid rulefile: ... | The specified BPA rulefile is corrupt or does not contain valid JSON. | +| Information | -ANALYZE | ... violates rule ... | Best Practice Analyzer results for rules of severity level 1 or lower. | +| Warning | -ANALYZE | ... violates rule ... | Best Practice Analyzer results for rules of severity level 2. | +| Error | -ANALYZE | ... violates rule ... | Best Practice Analyzer results for rules of severity level 3 or higher. | +| Error | -DEPLOY | Deployment failed! ... | Failure reason returned directly from Analysis Service instance (for example: Database not found, Database override not allowed, etc.) | +| Information | -DEPLOY | Unprocessed object: ... | Objects that are in state "NoData" or "CalculationNeeded" after succesful deployment. Use the -W switch to treat these as Level=Warning. | +| Warning | -DEPLOY | Object not in "Ready" state: ... | Objects that are in state "DependencyError", "EvaluationError" or "SemanticError" after succesful deployment. If using the -W switch, also includes objects in state "NoData" or "CalculationNeeded". | +| Warning | -DEPLOY | Error on X:... | Objects containing invalid DAX after succesful deployment (measures, calculated columns, calculated tables, roles). Use the -E switch to treat these as Level=Error. | + +If any of the "Error" level outputs are encountered, Tabular Editor will return Exit Code = 1. Otherwise 0. diff --git a/content/localization/de/Custom-Actions_de.md b/content/localization/de/Custom-Actions_de.md new file mode 100644 index 00000000..c7cce03f --- /dev/null +++ b/content/localization/de/Custom-Actions_de.md @@ -0,0 +1,70 @@ +# Custom Actions + +> [!NOTE] +> Please note that this functionality is unrelated to the Custom Actions feature available for Multidimensional models. + +Say you have created a useful script using the `Selected` object, and you want to be able to execute the script several times on different objects in the explorer tree. Instead of hitting the "Play" button whenever you want to execute the script, Tabular Editor lets you save it as a Custom Action: + +![image](https://user-images.githubusercontent.com/8976200/33581673-0db35ed0-d952-11e7-90cd-e3164e198865.png) + +After saving the custom action, you will see that it is now available directly from the right-click context menu of the explorer tree, making it very easy to invoke the script on any objects selected in the tree. You can create as many custom actions as you want. Use backslashes (\\) in the names to create a submenu structure within the context menu. + +![Custom Actions show up directly in the context menu](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/InvokeCustomAction.png) + +Custom Actions are stored in the CustomActions.json file within %AppData%\Local\TabularEditor. In the above example, the contents of this file will look like this: + +```json +{ + "Actions": [ + { + "Name": "Custom Formatting\\Number with 1 decimal", + "Enabled": "true", + "Execute": "Selected.Measures.ForEach(m => m.FormatString = \"0.0\";", + "Tooltip": "Sets the FormatString property to \"0.0\"", + "ValidContexts": "Measure, Column" + } + ] +} +``` + +As you can see, `Name` and `Tooltip` gets their values from whatever was specified when the action was saved. `Execute` is the actual script to be executed when the action is invoked. Note that any syntax errors in the CustomActions.json file will cause Tabular Editor to skip loading all Custom Actions entirely, so make sure you can successfully execute a script inside the Advanced Scripting editor, before saving it as a Custom Action. + +The `ValidContexts` property holds a list of object types for which the Action will be available. When selecting objects in the tree, a selection containing any objects different from the types listed in the `ValidContexts` property will hide the action from the context menu. + +## Controlling Action Availability + +If you need even more control on when an action can be invoked from the context menu, you can set the `Enabled` property to a custom expression that must return a boolean value, indicating whether the action will be available for the given selection. By default, the `Enabled` property has the value "true", which means that the action will always be enabled within the valid context. Keep this in mind, when using the singular object references on the `Selected` object, such as `Selected.Measure` or `Selected.Table`, as these will throw an error if the current selection does not contain exactly one of that type of object. In such a case, it is recommended to use the `Enabled` property to check that one and only one object of the required type, has been selected: + +```json +{ + "Actions": [ + { + "Name": "Reset measure name", + "Enabled": "Selected.Measures.Count == 1", + "Execute": "Selected.Measure.Name == \"New Measure\"", + "ValidContexts": "Measure" + } + ] +} +``` + +This will disable the context menu item, unless exactly one measure has been selected in the tree. + +## Reusing custom actions + +Release 2.7 introduces a new script method `CustomAction(...)`, which may be called to invoke previously saved Custom Actions. You can use this method as a stand-alone method (similar to `Output(...)`), or you can use it as an extension method on any set of objects: + +```csharp +// Executes "My custom action" against the current selection: +CustomAction("My custom action"); + +// Executes "My custom action" against all tables in the model: +CustomAction(Model.Tables, "My custom action"); + +// Executes "My custom action" against every measure in the current selection whose name starts with "Sum": +Selected.Measures.Where(m => m.Name.StartsWith("Sum")).CustomAction("My custom action"); +``` + +Note that you must specify the full name of the Custom Action, including any context menu folder names. + +If no action with the given name is found, an error is raised when the script is executed. diff --git a/content/localization/de/DI001_de.md b/content/localization/de/DI001_de.md new file mode 100644 index 00000000..3afd7558 --- /dev/null +++ b/content/localization/de/DI001_de.md @@ -0,0 +1,43 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/de/DI002_de.md b/content/localization/de/DI002_de.md new file mode 100644 index 00000000..0a691706 --- /dev/null +++ b/content/localization/de/DI002_de.md @@ -0,0 +1,48 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/de/DI003_de.md b/content/localization/de/DI003_de.md new file mode 100644 index 00000000..531867b8 --- /dev/null +++ b/content/localization/de/DI003_de.md @@ -0,0 +1,44 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/de/DI004_de.md b/content/localization/de/DI004_de.md new file mode 100644 index 00000000..828627ff --- /dev/null +++ b/content/localization/de/DI004_de.md @@ -0,0 +1,44 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/de/DI005_de.md b/content/localization/de/DI005_de.md new file mode 100644 index 00000000..303fe0e3 --- /dev/null +++ b/content/localization/de/DI005_de.md @@ -0,0 +1,78 @@ +--- +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], ALL(Products), 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], + ALL(Products), + 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. \ No newline at end of file diff --git a/content/localization/de/DI006_de.md b/content/localization/de/DI006_de.md new file mode 100644 index 00000000..f60c71bd --- /dev/null +++ b/content/localization/de/DI006_de.md @@ -0,0 +1,46 @@ +--- +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. \ No newline at end of file diff --git a/content/localization/de/DI007_de.md b/content/localization/de/DI007_de.md new file mode 100644 index 00000000..b4b153ec --- /dev/null +++ b/content/localization/de/DI007_de.md @@ -0,0 +1,46 @@ +--- +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. \ No newline at end of file diff --git a/content/localization/de/DI008_de.md b/content/localization/de/DI008_de.md new file mode 100644 index 00000000..7275d066 --- /dev/null +++ b/content/localization/de/DI008_de.md @@ -0,0 +1,70 @@ +--- +uid: DI008 +category: Code actions +sub-category: Improvements +title: Remove superfluous CALCULATE +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI008` (Improvement) **Remove superfluous CALCULATE** + +## Description + +Do not explicitly call [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE), when it is not necessary. + +### Example 1 - Measure reference with no filter context modifiers + +In the below examples, `[Total Sales]` is a measure reference. + +Change: + +```dax +CALCULATE([Total Sales]) +``` + +To: + +```dax +[Total Sales] +``` + +### Example 2 - Measure reference in a row context + +Change: + +```dax +AVERAGEX(Product, CALCULATE([Total Sales])) +``` + +To: + +```dax +AVERAGEX(Product, [Total Sales]) +``` + +### Example 3 - Constant values are not affected by filter context modifications + +Change: + +```dax +VAR _salesWithTax = [Total Sales] * 1.25 +RETURN + CALCULATE(_salesWithTax, Product[Color] = "Red") +``` + +To: + +```dax +VAR _salesWithTax = [Total Sales] * 1.25 +RETURN + _salesWithTax +``` + +## Why is Tabular Editor suggesting this? + +The `CALCULATE` function is used to modify the filter context of a calculation and force a context transition when needed. However, when the expression is not impacted by a context transition, and the filter context is not modified, the `CALCULATE` function is superfluous and can be removed (Example 1). This can make the code easier to read and understand. + +Moreover, if the `CALCULATE` function is only used to enforce a context transition and not modify the filter context (i.e. no filter arguments), but the expression is a simple measure reference, then the `CALCULATE` function can be removed (Example 2), since measure references perform implicit context transitions, when evaluated in a row context. + +Lastly, if the expression is constant (such as when referencing a variable that was defined outside of the `CALCULATE` function, such as in Example 3 above), the modified filter context will not affect the result of the expression, and the `CALCULATE` function including all filter arguments can be removed. \ No newline at end of file diff --git a/content/localization/de/DI009_de.md b/content/localization/de/DI009_de.md new file mode 100644 index 00000000..1eaba092 --- /dev/null +++ b/content/localization/de/DI009_de.md @@ -0,0 +1,32 @@ +--- +uid: DI009 +category: Code actions +sub-category: Improvements +title: Avoid calculate shortcut syntax +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI009` (Improvement) **Avoid calculate shortcut syntax** + +## Description + +Do not use the calculate shortcut syntax. + +### Example + +Change: + +```dax +[Total Sales](Products[Color] = "Red") +``` + +To: + +```dax +CALCULATE([Total Sales], Products[Color] = "Red") +``` + +## Why is Tabular Editor suggesting this? + +The calculate shortcut syntax is a shorthand for the `CALCULATE` function, where the first argument is the measure to evaluate, and the second argument is the filter expression. While this syntax is valid, it is not recommended, as it can be confusing to read and understand. It is better to use the `CALCULATE` function explicitly, as it makes the code more readable and maintainable. \ No newline at end of file diff --git a/content/localization/de/DI010_de.md b/content/localization/de/DI010_de.md new file mode 100644 index 00000000..56111791 --- /dev/null +++ b/content/localization/de/DI010_de.md @@ -0,0 +1,34 @@ +--- +uid: DI010 +category: Code actions +sub-category: Improvements +title: Use MIN/MAX instead of IF +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI010` (Improvement) **Use MIN/MAX instead of IF** + +## Description + +When a conditional expression is used to return the minimum or maximum of two values, it is more efficient and compact to use the [`MIN`](https://dax.guide/MIN) or [`MAX`](https://dax.guide/MAX) function. + +### Example + +Change: + +```dax +IF([Total Sales] > 0, [Total Sales], 0)) +``` + +To: + +```dax +MAX([Total Sales], 0) +``` + +## Why is Tabular Editor suggesting this? + +A common anti-pattern in DAX is to use an `IF` statement to return the smaller or larger of two values, by first comparing them, and then returning the appropriate value. However, this pattern can be simplified by using the `MIN` or `MAX` functions, which are more efficient and easier to read. The `MIN` function, when called with two arguments, returns the smallest value of the two arguments, while the `MAX` function returns the largest value. By using these functions, the code becomes more concise and easier to understand. + +Moreover, if any measure references are included in the arguments, they are only evaluated once, which can improve performance. \ No newline at end of file diff --git a/content/localization/de/DI011_de.md b/content/localization/de/DI011_de.md new file mode 100644 index 00000000..edc71011 --- /dev/null +++ b/content/localization/de/DI011_de.md @@ -0,0 +1,34 @@ +--- +uid: DI011 +category: Code actions +sub-category: Improvements +title: Use ISEMPTY instead of COUNTROWS +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI011` (Improvement) **Use ISEMPTY instead of COUNTROWS** + +## Description + +When checking if a table is empty, it is more efficient to use the [`ISEMPTY`](https://dax.guide/ISEMPTY) function than to count the rows of the table. + +### Example + +Change: + +```dax +IF(COUNTROWS(Products) = 0, "No products", "Products exist") +``` + +To: + +```dax +IF(ISEMPTY(Products), "No products", "Products exist") +``` + +## Why is Tabular Editor suggesting this? + +When checking if a table is empty, a common anti-pattern in DAX is to use the `COUNTROWS` function to count the rows of the table, and then compare the result to zero. However, this pattern is inefficient, as it requires the engine to count all rows of the table, even if the only thing we are interested in is whether the table is empty or not. + +By using the `ISEMPTY` function, the engine can stop counting rows as soon as it finds the first row, which is much more efficient. The `ISEMPTY` function returns `TRUE` if the table is empty, and `FALSE` otherwise, which makes it a more efficient and readable way to check if a table is empty. \ No newline at end of file diff --git a/content/localization/de/DI012_de.md b/content/localization/de/DI012_de.md new file mode 100644 index 00000000..11950544 --- /dev/null +++ b/content/localization/de/DI012_de.md @@ -0,0 +1,34 @@ +--- +uid: DI012 +category: Code actions +sub-category: Improvements +title: Use DIVIDE instead of division +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI012` (Improvement) **Use DIVIDE instead of division** + +## Description + +When using an arbitrary expression in the denominator of a division, use [`DIVIDE`](https://dax.guide/DIVIDE) instead of the division operator, to avoid division by zero errors. + +### Example + +Change: + +```dax +[Total Sales] / [Total Cost] +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +## Why is Tabular Editor suggesting this? + +When dividing two numbers in DAX, it is common to use the division operator `/`. However, if the denominator is zero, the result of the division is an error. This can be problematic in certain scenarios, as it can cause the entire expression to fail. Downstream measures may use [`IFERROR`](https://dax.guide/IFERROR) to handle this, but a more elegant and better performing solution is to use the `DIVIDE` function, which returns a specific value or (Blank) if the denominator is zero. This makes the code more robust and easier to read. + +Tabular Editor will not suggest this action if the denominator is guaranteed to be non-zero, such as when dividing by a (non-zero) constant, in which case the division operator `/` is preferred. \ No newline at end of file diff --git a/content/localization/de/DI013_de.md b/content/localization/de/DI013_de.md new file mode 100644 index 00000000..d64ae31e --- /dev/null +++ b/content/localization/de/DI013_de.md @@ -0,0 +1,32 @@ +--- +uid: DI013 +category: Code actions +sub-category: Improvements +title: Use division instead of DIVIDE +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DI013` (Improvement) **Use division instead of DIVIDE** + +## Description + +When the 2nd argument of [`DIVIDE`](https://dax.guide/DIVIDE) is a non-zero constant, it is more efficient to use the division operator. + +### Example + +Change: + +```dax +DIVIDE([Total Sales], 1.25) +``` + +To: + +```dax +[Total Cost] / 1.25 +``` + +## Why is Tabular Editor suggesting this? + +The `DIVIDE` function is a robust way to handle division by zero errors, as it returns a specific value or (Blank) if the denominator is zero. However, when the denominator is guaranteed to be non-zero, such as when dividing by a (non-zero) constant, the division operator `/` is more efficient and easier to read. By using the division operator, the code becomes more concise and easier to understand. \ No newline at end of file diff --git a/content/localization/de/DI014_de.md b/content/localization/de/DI014_de.md new file mode 100644 index 00000000..190db2d9 --- /dev/null +++ b/content/localization/de/DI014_de.md @@ -0,0 +1,46 @@ +--- +uid: DI014 +category: Code actions +sub-category: Improvements +title: Replace IFERROR with DIVIDE +author: Daniel Otykier +updated: 2025-01-08 +--- + +Code action `DI014` (Improvement) **Replace IFERROR with DIVIDE** + +## Description + +Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IFERROR`](https://dax.guide/IFERROR) to provide an alternate result when a division has a zero demoninator. + +### Example 1 + +Change: + +```dax +IFERROR([Total Sales] / [Total Cost], BLANK()) +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +### Example 2 + +Change: + +```dax +IFERROR(([Total Sales] - [Total Cost]) / [Total Cost], 1) +``` + +To: + +```dax +DIVIDE([Total Sales] - [Total Cost], [Total Cost], 1) +``` + +## Why is Tabular Editor suggesting this? + +A common anti-pattern in DAX is to check for division-by-zero errors by using the `IFERROR` function. This pattern should be avoided, as evaluation errors add overhead to the query execution. Instead, the `DIVIDE` function should be used, as it checks that the denominator is not zero before the division is carried out. Moreover, using floating point arithmetics, the `DIVIDE` function is more robust and handles edge cases better than the `IFERROR` function. By using the `DIVIDE` function, the code becomes more concise and easier to understand. \ No newline at end of file diff --git a/content/localization/de/DI015_de.md b/content/localization/de/DI015_de.md new file mode 100644 index 00000000..3134307b --- /dev/null +++ b/content/localization/de/DI015_de.md @@ -0,0 +1,46 @@ +--- +uid: DI015 +category: Code actions +sub-category: Improvements +title: Replace IF with DIVIDE +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DI015` (Improvement) **Replace IF with DIVIDE** + +## Description + +Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IF`](https://dax.guide/IF), to more easily check for zero or blank in the demoninator. + +### Example 1 + +Change: + +```dax +IF([Total Cost] = 0, BLANK(), [Total Sales] / [Total Cost]) +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +### Example 2 + +Change: + +```dax +IF([Total Cost] <> 0, [Total Sales] / [Total Cost]) +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +## Why is Tabular Editor suggesting this? + +The `DIVIDE` function is a more concise and readable way to handle division by zero or blank values. By using `DIVIDE`, you make your code more robust and easier to understand. Moreover, the `DIVIDE` function is more efficient than using `IF` to check for zero or blank values, as it only evaluates the denominator once. \ No newline at end of file diff --git a/content/localization/de/DR001_de.md b/content/localization/de/DR001_de.md new file mode 100644 index 00000000..188d8122 --- /dev/null +++ b/content/localization/de/DR001_de.md @@ -0,0 +1,58 @@ +--- +uid: DR001 +category: Code actions +sub-category: Readability +title: Convert to scalar predicate +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DR001` (Readability) **Convert to scalar predicate** + +## Description + +A column filter can be written more concisely as a scalar predicate, without explicitly using the [`FILTER`](https://dax.guide/FILTER) function. + +### Example 1 + +Change: + +```dax +CALCULATE( + [Invoice Amount], + FILTER(ALL('Document'[Document Type]), 'Document'[Document Type] = "Sales Order") +) +``` + +To: + +```dax +CALCULATE( + [Invoice Amount], + 'Document'[Document Type] = "Sales Order" +) +``` + +### Example 2 + +Change: + +```dax +CALCULATE( + [Invoice Amount], + FILTER(VALUES('Document'[Document Type]), 'Document'[Document Type] = "Sales Order") +) +``` + +To: + +```dax +CALCULATE( + [Invoice Amount], + KEEPFILTERS('Document'[Document Type] = "Sales Order") +) +``` + +## Why is Tabular Editor suggesting this? + +A scalar predicate is a simpler and more concise way (e.g. "syntax sugar") to express a column filter, compared to using the `FILTER` function explicitly. By using a scalar predicate, the code becomes easier to read and understand, as it removes unnecessary complexity and makes the intent of the filter expression more clear. \ No newline at end of file diff --git a/content/localization/de/DR002_de.md b/content/localization/de/DR002_de.md new file mode 100644 index 00000000..1cc27e87 --- /dev/null +++ b/content/localization/de/DR002_de.md @@ -0,0 +1,36 @@ +--- +uid: DR002 +category: Code actions +sub-category: Readability +title: Use aggregator instead of iterator +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DR002` (Readability) **Use aggregator instead of iterator** + +## Description + +Use an aggregator function instead of an iterator function when possible, to simplify the code. + +### Example + +Change: + +```dax +SUMX(Sales, Sales[Line Amount]) +``` + +To: + +```dax +SUM(Sales[Line Amount]) +``` + +## Why is Tabular Editor suggesting this? + +When you need to aggregate the values of a single column only, aggregator functions ([`SUM`](https://dax.guide), [`MIN`](https://dax.guide), [`MAX`](https://dax.guide), etc.) use simpler, more concise syntax, than their equivalent iterator functions ([`SUMX`](https://dax.guide), [`MINX`](https://dax.guide), [`MAXX`](https://dax.guide), etc.) and should be preferred to make the code more readable. + +## Related to: + +- [DR003 - Use VALUES instead of SUMMARIZE](xref:DR003) \ No newline at end of file diff --git a/content/localization/de/DR003_de.md b/content/localization/de/DR003_de.md new file mode 100644 index 00000000..63f2c47e --- /dev/null +++ b/content/localization/de/DR003_de.md @@ -0,0 +1,36 @@ +--- +uid: DR003 +category: Code actions +sub-category: Readability +title: Use VALUES instead of SUMMARIZE +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DR003` (Readability) **Use VALUES instead of SUMMARIZE** + +## Description + +When [`SUMMARIZE`](https://dax.guide/SUMMARIZE) only specifies a single column, and that column belongs to the table specified in the first argument, the code can be more concisely written using [`VALUES`](https://dax.guide/VALUES). + +### Example + +Change: + +```dax +SUMMARIZE(Sales, Sales[Product Key]) +``` + +To: + +```dax +VALUES(Sales[Product Key]) +``` + +## Why is Tabular Editor suggesting this? + +The `SUMMARIZE` function is a powerful function that can be used to group data and calculate aggregates. However, when you only need to retrieve the distinct values of a single column, the `VALUES` function is more concise and easier to read. By using the `VALUES` function, the code becomes more readable and the intent of the expression is clearer. + +## Related to: + +- [DR002 - Use aggregator instead of iterator](xref:DR002) \ No newline at end of file diff --git a/content/localization/de/DR004_de.md b/content/localization/de/DR004_de.md new file mode 100644 index 00000000..f1a7cb7f --- /dev/null +++ b/content/localization/de/DR004_de.md @@ -0,0 +1,48 @@ +--- +uid: DR004 +category: Code actions +sub-category: Readability +title: Prefix variable +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR004` (Readability) **Prefix variable** + +## Description + +It is recommended to use a consistent prefix for variables, to more easily distinguish them from table references. The default prefix is `_`, but you can configure which prefix to use, to match your preferred style, under **Tools > Preferences > DAX Editor > Code Actions**. + +### Example + +Change: + +```dax +VAR sales = SUM('Internet Sales'[Sales Amount]) +RETURN sales * 1.25; +``` + +To: + +```dax +VAR _sales = SUM('Internet Sales'[Sales Amount]) +RETURN _sales * 1.25; +``` + +## Why is Tabular Editor suggesting this? + +This code action is designed to improve the readability of your DAX code. By using a consistent naming convention for your variables, it is easier to understand the purpose of each variable, and to distinguish between variables and tables. + +Moreover, using a special character (such as an underscore) as a prefix for variables can help to avoid naming conflicts with table names, in case a table with the same name as the variable is added to the model in the future. + +## 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: + +- [DR005 - Prefix temporary column](xref:DR005) + +## Further reading: + +- [SQLBI: Naming variables in DAX](https://www.sqlbi.com/blog/marco/2019/01/15/naming-variables-in-dax/) \ No newline at end of file diff --git a/content/localization/de/DR005_de.md b/content/localization/de/DR005_de.md new file mode 100644 index 00000000..3741704e --- /dev/null +++ b/content/localization/de/DR005_de.md @@ -0,0 +1,50 @@ +--- +uid: DR005 +category: Code actions +sub-category: Readability +title: Prefix temporary column +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR005` (Readability) **Prefix temporary column** + +## Description + +It is recommended to use a consistent prefix for temporary columns, to more easily distinguish them from base columns or measures. The default prefix is `@` but you can configure which prefix to use, to match your preferred style, under **Tools > Preferences > DAX Editor > Code Actions**. + +### Example + +Change: + +```dax +ADDCOLUMNS( + 'Sales', + "Sales With Tax", 'Sales'[Sales Amount] * 1.25 +) +``` + +To: + +```dax +ADDCOLUMNS( + 'Sales', + "@Sales With Tax", 'Sales'[Sales Amount] * 1.25 +) +``` + +## Why is Tabular Editor suggesting this? + +This code action is designed to improve the readability of your DAX code. By using a consistent naming convention for your temporary columns, it is easier to understand the purpose of each column, and to distinguish between base columns, measures, and extension columns. + +## 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: + +- [DR004 - Prefix variable](xref:DR004) + +## Further reading: + +- [SQLBI: Naming temporary columns in DAX](https://www.sqlbi.com/articles/naming-temporary-columns-in-dax/) \ No newline at end of file diff --git a/content/localization/de/DR006_de.md b/content/localization/de/DR006_de.md new file mode 100644 index 00000000..ab5b8691 --- /dev/null +++ b/content/localization/de/DR006_de.md @@ -0,0 +1,48 @@ +--- +uid: DR006 +category: Code actions +sub-category: Readability +title: Move constant aggregation to variable +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR006` (Readability) **Move constant aggregation to variable** + +## Description + +When an aggregation function is used inside an iterator or a scalar predicate, the aggregation produces the same result for every row of the iteration, and therefore the aggregation could be moved to a DAX variable outside of the iteration. + +### Example + +Change: + +```dax +CALCULATE( + [Total Sales], + 'Date'[Date] = MAX('Date'[Date]) +) +``` + +To: + +```dax +VAR _maxDate = MAX('Date'[Date]) +RETURN + CALCULATE( + [Total Sales], + 'Date'[Date] = _maxDate + ) +``` + +## Why is Tabular Editor suggesting this? + +A common point of confusion for new DAX developers is the concept of row context and filter context. When an aggregation is used inside an iterator or a scalar predicate, the aggregation produces the same result for every row of the iteration. This is what enables syntax such as `'Date'[Date] = MAX('Date'[Date])`. While this syntax works and is efficient, it can be confusing to new developers - especially those with a SQL background, where this kind of syntax would be considered an error. + +Historically, variables were not supported in DAX, so the only way to achieve this kind syntax was to use the aggregation directly in the iterator. However, with the introduction of variables in DAX, it is now possible to move the aggregation to a variable outside of the iteration. This makes the code more readable and easier to understand for new developers. It also makes it easier to debug the code, as you can inspect the value of the variable outside of the iteration. + +## Remarks + +By default, Tabular Editor uses `_` as a prefix for variables. You can change the prefix under **Tools > Preferences > DAX Editor > Code Actions**. + +The name assigned to the variable is the concatenation of the aggregation function and the column name. If the variable name is not unique within the scope, a number is appended to make it unique. \ No newline at end of file diff --git a/content/localization/de/DR007_de.md b/content/localization/de/DR007_de.md new file mode 100644 index 00000000..49e33716 --- /dev/null +++ b/content/localization/de/DR007_de.md @@ -0,0 +1,38 @@ +--- +uid: DR007 +category: Code actions +sub-category: Readability +title: Simplify 1-variable block +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR007` (Readability) **Simplify 1-variable block** + +## Description + +A variable block with only one variable can be simplified by moving the expression directly into the `RETURN` part of the block. This assumes the variable is only referenced once without any context modifiers. + +### Example + +Change: + +```dax +VAR _sales = [Total Sales] +RETURN + _sales * 1.25 +``` + +To: + +```dax +[Total Sales] * 1.25 +``` + +## Why is Tabular Editor suggesting this? + +When variable declarations are sufficiently simple, and when the variable is used exactly once in the `RETURN` part of the code without any context modifications, there is no need to declare the variable at all. This makes the code more concise and easier to read. + +## Related to: + +- [DR008 - Simplify multi-variable block](xref:DR008) \ No newline at end of file diff --git a/content/localization/de/DR008_de.md b/content/localization/de/DR008_de.md new file mode 100644 index 00000000..16243251 --- /dev/null +++ b/content/localization/de/DR008_de.md @@ -0,0 +1,43 @@ +--- +uid: DR008 +category: Code actions +sub-category: Readability +title: Simplify multi-variable block +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR008` (Readability) **Simplify multi-variable block** + +## Description + +A variable block with multiple variables where each is a simple measure reference, which are only used once in the `RETURN` section without any context modifiers, should be simplified. + +### Example + +Change: + +```dax +VAR _sales = [Total Sales] +VAR _cost = [Total Cost] +RETURN + _sales - _cost +``` + +To: + +```dax +[Total Sales] - [Total Cost] +``` + +## Why is Tabular Editor suggesting this? + +A common pattern in DAX is to declare a variable for each measure that is used in a calculation. This is a good practice when the value of a measure is needed in multiple places in the calculation (for performance reasons). However, when each such variable is used exactly once in the `RETURN` part of the code, in an evaluation context that would not change the result of the measure, there is no need to declare the variables at all. Instead, referencing the measures directly in the calculation should be preferred to make the code more concise and easier to read. + +## Remarks: + +The [DAX Debugger in Tabular Editor 3](xref:dax-debugger) will show the values of measures used in the calculation within the **Locals** view. This makes it easy to inspect the values of the measures during debugging, even when their values are not stored in variables. + +## Related to: + +- [DR007 - Simplify 1-variable block](xref:DR007) \ No newline at end of file diff --git a/content/localization/de/DR009_de.md b/content/localization/de/DR009_de.md new file mode 100644 index 00000000..b77682b8 --- /dev/null +++ b/content/localization/de/DR009_de.md @@ -0,0 +1,33 @@ +--- +uid: DR009 +category: Code actions +sub-category: Readability +title: Rewrite using DISTINCTCOUNT +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR009` (Readability) **Rewrite using DISTINCTCOUNT** + +## Description + +Instead of using a combination of [`COUNTROWS`](https://dax.guide/COUNTROWS) and [`DISTINCT`](https://dax.guide/DISTINCT) to count the number of distinct values in a column, use the [`DISTINCTCOUNT`](https://dax.guide/DISTINCTCOUNT) function. + +### Example + +Change: + +```dax +COUNTROWS(DISTINCT(Sales[CalendarDate])) +``` + +```` + +To: +```dax +DISTINCTCOUNT(Sales[CalendarDate]) +```` + +## Why is Tabular Editor suggesting this? + +While both options produce the same result and the same query plan (i.e. identical performance), the `DISTINCTCOUNT` function is more concise and easier to read than the combination of `COUNTROWS` and `DISTINCT`. By using `DISTINCTCOUNT`, the code becomes more readable and the intent of the expression is clearer. \ No newline at end of file diff --git a/content/localization/de/DR010_de.md b/content/localization/de/DR010_de.md new file mode 100644 index 00000000..cbaf0069 --- /dev/null +++ b/content/localization/de/DR010_de.md @@ -0,0 +1,36 @@ +--- +uid: DR010 +category: Code actions +sub-category: Readability +title: Rewrite using COALESCE +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR010` (Readability) **Rewrite using COALESCE** + +## Description + +Instead of using [`IF`](https://dax.guide/IF) to return the first non-blank value from a list of expressions, use the [`COALESCE`](https://dax.guide/COALESCE) function. + +### Example + +Change: + +```dax +IF( + ISBLANK(Product[Long Description]), + Product[Short Description], + Product[Long Description] +) +``` + +To: + +```dax +COALESCE(Product[Long Description], Product[Short Description]) +``` + +## Why is Tabular Editor suggesting this? + +The `COALESCE` function is a more concise and easier to read way of returning the first non-blank value from a list of expressions. By using `COALESCE`, the code becomes more readable and the intent of the expression is clearer. \ No newline at end of file diff --git a/content/localization/de/DR011_de.md b/content/localization/de/DR011_de.md new file mode 100644 index 00000000..061a242d --- /dev/null +++ b/content/localization/de/DR011_de.md @@ -0,0 +1,48 @@ +--- +uid: DR011 +category: Code actions +sub-category: Readability +title: Rewrite using ISBLANK +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR011` (Readability) **Rewrite using ISBLANK** + +## Description + +Instead of comparing an expression with the value returned by [`BLANK()`](https://dax.guide/BLANK), use the [`ISBLANK`](https://dax.guide/ISBLANK) function. + +### Example + +Change: + +```dax +IF( + Document[Type] == BLANK(), + [Sales Amount], + [Sales Amount] * 1.25 +) +``` + +To: + +```dax +IF( + ISBLANK(Document[Type]), + [Sales Amount], + [Sales Amount] * 1.25 +) +``` + +## Why is Tabular Editor suggesting this? + +The `ISBLANK` function is a more concise and easier to read way of checking if an expression returns a blank value. By using `ISBLANK`, the code becomes more readable and the intent of the expression is clearer. + +## Remarks + +This code action only applies to [strict equality comparison (==)](https://dax.guide/op/strictly-equal-to/) with `BLANK()`. The regular equality comparison `Document[Type] = BLANK()` does not produce the same result as `ISBLANK(Document[Type])` if `[Type]` is an empty string, or zero (in which case `ISBLANK(Document[Type])` would return `FALSE` while `Document[Type] = BLANK()` would return `TRUE`). + +## Further reading + +- [SQLBI: Handling BLANK in DAX](https://www.sqlbi.com/articles/blank-handling-in-dax/) \ No newline at end of file diff --git a/content/localization/de/DR012_de.md b/content/localization/de/DR012_de.md new file mode 100644 index 00000000..40df35c4 --- /dev/null +++ b/content/localization/de/DR012_de.md @@ -0,0 +1,41 @@ +--- +uid: DR012 +category: Code actions +sub-category: Readability +title: Remove unnecessary BLANK +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR012` (Readability) **Remove unnecessary BLANK** + +## Description + +Some DAX functions, such as [`IF`](https://dax.guide/IF) and [`SWITCH`](https://dax.guide/SWITCH) already return [`BLANK()`](https://dax.guide/BLANK) when the condition is false, so there is no need to explicitly specify `BLANK()`. + +### Example + +Change: + +```dax +SWITCH( + Document[Type], + "Invoice", [Invoice Amount], + "Credit Note", [Credit Note Amount], + BLANK() +) +``` + +To: + +```dax +SWITCH( + Document[Type], + "Invoice", [Invoice Amount], + "Credit Note", [Credit Note Amount] +) +``` + +## Why is Tabular Editor suggesting this? + +The `BLANK()` function is redundant when used as the last argument in an `IF` or `SWITCH` function, as these functions already return `BLANK()` when the condition is false. By removing the `BLANK()` function, the code becomes more concise and easier to read. \ No newline at end of file diff --git a/content/localization/de/DR013_de.md b/content/localization/de/DR013_de.md new file mode 100644 index 00000000..2b6404dd --- /dev/null +++ b/content/localization/de/DR013_de.md @@ -0,0 +1,46 @@ +--- +uid: DR013 +category: Code actions +sub-category: Readability +title: Simplify negated logic +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR013` (Readability) **Simplify negated logic** + +## Description + +When a logical expression is negated, it is often more readable to rewrite the expression using the inverted operator. + +### Example 1 + +Change: + +```dax +NOT([Sales Amount] = [Budget Amount]) +``` + +To: + +```dax +[Sales Amount] <> [Budget Amount] +``` + +### Example 2 + +Change: + +```dax +NOT([Cost Amount] < [Sales Amount]) +``` + +To: + +```dax +[Cost Amount] >= [Sales Amount] +``` + +## Why is Tabular Editor suggesting this? + +Negated logic can be harder to read and understand than non-negated logic. By removing the negation (the [`NOT`](https://dax.guide/NOT) operator) and inverting the comparison operator, the code becomes more concise and easier to read. \ No newline at end of file diff --git a/content/localization/de/DR014_de.md b/content/localization/de/DR014_de.md new file mode 100644 index 00000000..9e5216ba --- /dev/null +++ b/content/localization/de/DR014_de.md @@ -0,0 +1,32 @@ +--- +uid: DR014 +category: Code actions +sub-category: Readability +title: Simplify using IN +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR014` (Readability) **Simplify using IN** + +## Description + +Rewrite compound predicates (equality comparisons of the same expression that are combined using [`OR`](https://dax.guide/OR) or [`||`](https://dax.guide/op/or/)) with the [`IN`](https://dax.guide/IN) operator. + +### Example + +Change: + +```dax +IF(Document[Type] = "Invoice" || Document[Type] = "Credit Note", 1, 0) +``` + +To: + +```dax +IF(Document[Type] IN {"Invoice", "Credit Note"}, 1, 0) +``` + +## Why is Tabular Editor suggesting this? + +The `IN` operator is more concise and easier to read than multiple `||` operators or `OR` function calls. It also makes it easier to add or remove values from the list of values to compare against. \ No newline at end of file diff --git a/content/localization/de/FAQ_de.md b/content/localization/de/FAQ_de.md new file mode 100644 index 00000000..b2da1fda --- /dev/null +++ b/content/localization/de/FAQ_de.md @@ -0,0 +1,21 @@ +# Frequently Asked Questions + +## What is Tabular Editor? + +Essentially, Tabular Editor provides a UI for editing the metadata making up an Analysis Services Tabular Model. The main difference between using Tabular Editor for editing a model versus using Visual Studio, is that Tabular Editor does not load any _data_ - only _metadata_. This means that no validations or calculations are performed when you create and modify measures, display folders, etc. Validations and calculations are performed only when the user chooses to persist the changes to the database. This provides a better developer experience for medium to large sized models, which tend to be slow to work with in Visual Studio. + +Additionally, Tabular Editor has a lot of [features](Features-at-a-glance.md) that will generally boost your productivity and make certain tasks easier. + +## Why do we need yet another tool for SSAS Tabular? + +Working with Analysis Services Tabular, you may already be familiar with SQL Server Data Tools (Visual Studio), [DAX Editor](https://www.sqlbi.com/tools/dax-editor/), [DAX Studio](https://www.sqlbi.com/tools/dax-studio/), [BISM Normalizer](http://bism-normalizer.com/) and [BIDSHelper](https://bidshelper.codeplex.com/). These are all excellent tools, each with their own purposes. Tabular Editor is not intended to replace any of these tools, but should rather be seen as a supplement to them. Please view the [Features at a glance](Features-at-a-glance.md) article, to see why Tabular Editor is justified. + +## Why isn't Tabular Editor available as a plug-in for Visual Studio? + +While a better user experience for working with Tabular Models inside Visual Studio would definitely be appreciated, a stand-alone tool provides some benefits over a plug-in: First of all, you **don't need a Visual Studio/SSDT installation to use Tabular Editor**. Tabular Editor only requires the AMO libraries, which is quite a small installation compared to VS. Secondly, TabularEditor.exe can be executed with command-line options for deployment, scripting, etc., which would not be possible in a .vsix (plug-in) project. + +Also worth mentioning: Tabular Editor can be downloaded as a [standalone .zip file](https://github.com/TabularEditor/TabularEditor/releases/latest/download/TabularEditor.Portable.zip), meaning you do not need to install anything. In other words, you can run Tabular Editor without having admin rights on your Windows machine. Simply download the zip file, extract it, and run TabularEditor.exe. + +## What features are planned for upcoming releases? + +You can view the current roadmap [here](Roadmap.md). diff --git a/content/localization/de/Features-at-a-glance_de.md b/content/localization/de/Features-at-a-glance_de.md new file mode 100644 index 00000000..febd7ca2 --- /dev/null +++ b/content/localization/de/Features-at-a-glance_de.md @@ -0,0 +1,90 @@ +# Basic Features + +The following article will give you a quick overview of the most important features of Tabular Editor. + +## Load/save Model.bim files + +Hitting CTRL+O shows an Open File dialog, which lets you select a Model.bim file to load in Tabular Editor. The file must be of Compatibility Level 1200 or newer (JSON format). CTRL+S saves any changes you make in Tabular Editor back to the file (we recommend backing up your Model.bim files before using Tabular Editor). If you want to deploy the loaded model to an Analysis Services server instance, see [Deployment](/te2/Features-at-a-glance#deployment) below. + +## Connect/deploy to SSAS Tabular Databases + +Hitting CTRL+SHIFT+O lets you open a Tabular Model directly from a Tabular Database that has already been deployed. Enter the server address and (optionally) provide a username and password. After hitting "OK", you will be prompted with a list of databases and the server. Select the one you want to load, and click "OK" again. + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Connect.png) + +The dialog shown also lets you connect to Azure Analysis Services instances, if you provide the full name of the Azure AS instance, starting with "azureas://". The "Local Instance" dropdown, may be used to browse and connect to any running instances of Power BI Desktop or Visual Studio Integrated Workspaces. **Note that although Tabular Editor can make changes to a Power BI model through the TOM, this is not supported by Microsoft and may corrupt your .pbix file. Proceed at your own risk!** + +Any time you press CTRL+S after the database has been loaded, the database will be updated with any changes you've made in Tabular Editor. Client tools (Excel, Power BI, DAX Studio, etc.) should be able to immediately view the changes in the database after this. Note that you may need to manually recalculate objects in the model, depending on the changes made, to successfully query the model. + +If you want to save the connected model to a Model.bim file, choose "Save As..." from the "File" menu. + +## Deployment + +If you want to deploy the currently loaded model to a new database, or overwrite an existing database with the model changes (for example when loading from a Model.bim file), use the Deployment Wizard under "Model" > "Deploy...". The wizard will guide you through the deployment process, and allow you to choose which areas of the model to deploy. More information can be found [here](/te2/Advanced-features#deployment-wizard). + +## Hierarchical display + +Objects of the loaded model are shown in the Explorer Tree, on the left side of the screen. By default, all object types (visible tables, roles, relationships, etc.) are shown. If you only want to see tables, measures, columns and hierarchies, go to the "View" menu and toggle off "Show all object types". + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/AllObjectTypes.png) + +Expanding a table in the "Tables" group, you will find the measures, columns and hierarchies contained in the table presented in their respective display folders by default. This way, objects are arranged similar to how end-users would see them in client tools: + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/DisplayFolders.png) + +Use the buttons immediately above the Explorer Tree, to toggle invisible objects, display folders, measures, columns and hierarchies, or to filter objects by name. You can rename an object by selecting it in then hitting F2. This also works for display folders. If you double-click a measure or calculated column, you may edit its [DAX expression](/te2/Advanced-features#dax-expression-editor). Right-clicking will show a context menu, providing a range of handy shortcuts for operations such as setting visibility, perspective inclusion, adding columns to a hierarchy, etc. + +## Editing properties + +The Property Grid on the lower right side of the screen, shows most of the properties for the object(s) selected in the Explorer Tree. If you select multiple objects at once, the Property Grid lets you simultaneously edit properties for the selected objects. This is useful for example when setting the Format String property. Examples of properties you can set through the Property Grid: + +- Name (you can rename objects directly in the Explorer Tree by hitting F2) +- Description +- Display Folder (can also be renamed directly in the Explorer Tree, also [drag/drop](/te2/Features-at-a-glance#drag-and-drop-objects)) +- Hidden (can be set for multiple objects through the right-click context menu in the Explorer Tree) +- Format String + +Different properties exist, depending on what kind of object was selected. + +## Duplicate objects and batch renamings + +The right-click context menu in the Explorer Tree lets you duplicate measures and columns. The duplicated objects will have their names suffixed by "copy". Furthermore, you can perform batch renames by selecting multiple objects and right-clicking in the Explorer Tree. + +![](https://github.com/TabularEditor/TabularEditor/blob/master/Documentation/BatchRename.png) + +You may use RegEx for your renamings, and optionally choose whether translations should be renamed as well. + +## Drag and drop objects + +By far the most useful feature of Tabular Editor, when working on models with many measures/columns organised in display folders. Check out the animation below: + +![](https://github.com/TabularEditor/TabularEditor/blob/master/Documentation/DragDropFolders.gif) + +Notice how the display folder property of every single object below the folder is changed, when the entire folder is dragged. No more going over measures/columns one-by-one, to change the display folder structure. What you see is what you get. + +(This works with translations too!) + +## Working with Perspectives and Translations + +You can add/edit existing perspectives and translations (cultures), by clicking the Model node in the Explorer Tree, and locating the relevant properties at the bottom of the property grid. Alternatively, when your Explorer Tree is [showing all object types](/te2/Features-at-a-glance#hierarchical-display), you can view and edit perspectives, cultures and roles directly in the tree. + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/RolesPerspectivesTranslations.png) + +You can duplicate an existing perspective, role or translation by opening the right-click menu and choose "Duplicate". This will create an exact copy of the object, which you can then modify to your needs. + +To view perspectives and/or translations "in action", use the two dropdown lists in the toolbar near the top of the screen. Choosing a perspective will hide all objects that are not included in that perspective, while choosing a translation will show all objects in the tree using the translated names and display folders. When hitting F2 to change the names of objects/display folders or when dragging objects around in the tree, the changes will only apply to the selected translation. + +## Perspectives/Translations within object context + +When one or more objects are selected in the tree, you will find 4 special property collections within the Property Grid: + +- **Captions**, **Descriptions** and **Display Folders** shows a list of all cultures in the model, with the translated names, descripions and display folders respectively of the selected objects for each culture. +- **Perspectives** shows a list of all perspectives in the model, with an indication of whether or nor the selected objects belong to each perspective. + +You can use these collections in the Property Grid to change the translations and perspective inclusions for one or more objects at at time. + +## Undo/Redo support + +Any change you make in Tabular Editor can be undone using CTRL+Z and subsequently redone using CTRL+Y. There is no limit to the number of operations that can be undone, but the stack is reset when you open a Model.bim file or load a model from a database. + +When deleting objects from the model, all translations, perspectives and relationships that reference the deleted objects are also automatically deleted (where as Visual Studio normally shows an error message that the object cannot be deleted). If you make a mistake, you can use the Undo functionality to restore the deleted object, which will also restore any translations, perspectives or relationships that were deleted. Note that even though Tabular Editor can detect DAX formula dependencies, Tabular Editor will not warn you in case you delete a measure or column which is used in the DAX expression of another measure or calculated column. diff --git a/content/localization/de/FormatDax_de.md b/content/localization/de/FormatDax_de.md new file mode 100644 index 00000000..1dedadba --- /dev/null +++ b/content/localization/de/FormatDax_de.md @@ -0,0 +1,62 @@ +# FormatDax deprecation + +The `FormatDax` method (which is one of the available [helper methods](/Advanced-Scripting.md#helper-methods) in Tabular Editor) has been deprecated with the release of Tabular Editor 2.13.0. + +The reason for the deprecation is that the web service at https://www.daxformatter.com/ was starting to experience a heavy load of multiple request in quick succession, which were causing issues at their end. This is because the `FormatDax` method performs a web request each time it is called in a script, and many people have been using scripts such as the following: + +**Don't do this!** + +```csharp +foreach(var m in Model.AllMeasures) +{ + // DON'T DO THIS + m.Expression = FormatDax(m.Expression); +} +``` + +This is fine for small models with a few tens of measures, but the traffic on www.daxformatter.com indicates that a script such as the above is being executed across multiple models with thousands of measures, even several times per day! + +To address this issue, Tabular Editor 2.13.0 will show a warning when `FormatDax` is called more than three times in a row, using the syntax above. In addition, subsequent calls will be throttled with a 5 second delay between each call. + +## Alternative syntax + +Tabular Editor 2.13.0 introduces two different ways of calling FormatDax. The above script can be rewritten into either of the following: + +```csharp +foreach(var m in Model.AllMeasures) +{ + m.FormatDax(); +} +``` + +...or simply...: + +```csharp +Model.AllMeasures.FormatDax(); +``` + +Both these approaches will batch all www.daxformatter.com calls into a single request. You may also use the global method syntax if you prefer: + +```csharp +foreach(var m in Model.AllMeasures) +{ + FormatDax(m); +} +``` + +...or simply...: + +```csharp +FormatDax(Model.AllMeasures); +``` + +## More details + +Technically, `FormatDax` has now been implemented as two overloaded extension methods: + +1. `void FormatDax(this IDaxDependantObject obj)` +2. `void FormatDax(this IEnumerable objects, bool shortFormat = false, bool? skipSpaceAfterFunctionName = null)` + +Overload #1 above will queue the provided object for formatting when script execution completes, or when a call is made to the new `void CallDaxFormatter()` method. Overload #2 will immediately call www.daxformatter.com with a single web request that will format all DAX expressions for all the objects provided in the enumerable. You may use either of these methods as you see fit. + +Note that the new method does not take any string arguments. It considers all DAX properties on the provided object for formatting (for measures, this is the Expression and DetailRowsExpression properties, for KPIs, this is the StatusExpression, TargetExpression and TrendExpression, etc.). diff --git a/content/localization/de/Getting-Started_de.md b/content/localization/de/Getting-Started_de.md new file mode 100644 index 00000000..a889f917 --- /dev/null +++ b/content/localization/de/Getting-Started_de.md @@ -0,0 +1,109 @@ +--- +uid: getting-started-te2 +title: Getting Started +author: Daniel Otykier +updated: 2021-09-21 +--- + +# Getting Started + +## Installation + +Simply download the .msi file from the [Release page](https://github.com/TabularEditor/TabularEditor/releases/latest) and run the .msi installation. + +## Prerequisites + +None. + +> [!NOTE] +> Tabular Editor uses the [Tabular Object Model](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) to load and save metadata to and from Model.bim files or existing databases. This is included in the .msi installer. Visit the official Microsoft documentation for [Analysis Services Client Libraries](https://docs.microsoft.com/en-us/azure/analysis-services/analysis-services-data-providers). + +## System requirements + +- **Operating system:** Windows 7, Windows 8, Windows 10, Windows Server 2016, Windows Server 2019 or newer +- **.NET Framework:** [4.6](https://dotnet.microsoft.com/download/dotnet-framework) + +## Working with Tabular Editor + +The recommended workflow is to set up the tables and relationships using SSDT as normal, and then use Tabular Editor to do the rest. That is: Create calculated columns, measures, hierarchies, perspectives, translations, display folders, and every other kind of fine-tuning you can think of. + +Load a Model.bim file by choosing the Open > From File... option in the File menu (CTRL+O), or open an existing database from an instance of Analysis Services by choosing the Open > From DB... option. In the latter case, you will be prompted for a server name and optional credentials: + +![Connecting to an already deployed Tabular Model](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Connect.png) + +This also works with the new Azure Analysis Services PaaS. The "Local Instance" dropdown, may be used to browse and connect to any running instances of Power BI Desktop or Visual Studio Integrated Workspaces. **Note that although Tabular Editor can make changes to a Power BI model through the TOM, not all modeling operations are supported by Microsoft. [More information](/te2/Power-BI-Desktop-Integration.html)** + +After clicking "OK", you will be presented with a list of databases on the server. + +This is how the UI looks after a model has been loaded into Tabular Editor: + +![The main UI of Tabular Editor](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Main%20UI.png) + +The tree on the left side of the screen, displays all tables in the Tabular Model. Expanding a table will show all columns, measures and hierarchies within the table, grouped by their Display Folders. Use the buttons just above the tree, to toggle display folders, hidden objects, certain types of objects, or filter out objects by names. Right-clicking anywhere in the tree, will bring up a context menu with common actions, such as adding new measures, making an object hidden, duplicating objects, deleting objects, etc. Hit F2 to rename the currently selected object or multiselect and right-click to batch rename multiple objects. + +![Batch Renaming lets you rename multiple objects simultaneously](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/BatchRename.png) + +On the top right side of the main UI, you see the DAX Editor, which may be used to edit the DAX expression of any measure or calculated column in the model. Click the "DAX Formatter" button to automatically format the code through www.daxformatter.com. + +Use the property grid in the lower right corner, to examine and set properties of objects, such as Format String, Description along with translations and perspective memberships. You can also set the Display Folder property here, but it's easier to simply drag and drop objects within the tree to update their Display Folder (try selecting multiple objects using CTRL or SHIFT). + +To edit perspectives or translations (cultures), select the "Model" object in the tree, and locate the "Model Perspectives" or "Model Cultures" properties, in the property grid. Click the small elipsis button to open a collection editor for adding/removing/editing perspectives/cultures. + +![Editing perspectives - click the elipsis button to the right](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Edit%20Perspectives.png) + +To save your changes back to the Model.bim file, click the save button or hit CTRL+S. If you opened an existing Tabular Database, the changes are saved directly back to the database. You will be prompted if the database was changed since you loaded it into Tabular Editor. You can always undo your changes by pressing CTRL+Z. + +If you want to deploy your model to another location, go to the "Model" menu and choose "Deploy". + +## Deployment + +Tabular Editor comes with a deployment wizard that provides a few benefits compared to deploying from SSDT - especially when deploying to an existing database. After choosing a server and a database to deploy to, you have the following options for the deployment at hand: + +![Deployment Wizard](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Deployment.png) + +Leaving the "Deploy Connections" box unchecked, will make sure that all the data sources on the target database stay untouched. You will get an error if your model contains one or more tables with a data source, that does not already exist in the target database. + +Similarly, leaving out "Deploy Table Partitions", will make sure that existing partitions on your tables are not changed, leaving the data in the partitions intact. + +When the "Deploy Roles" box is checked, the roles in the target database will be updated to reflect what you have in the loaded model, however if the "Deploy Role Members" is unchecked, the members of each role will be unchanged in the target database. + +## Command Line usage + +You can use the command line for automated deployment. All deployment options that are available through the GUI, are also available through the command line. + +### Deployment Examples + +`TabularEditor.exe c:\Projects\Model.bim` + +Opens the Tabular Editor GUI and loads the specified Model.bim file (without deploying anything). + +`TabularEditor.exe c:\Projects\Model.bim -deploy localhost AdventureWorks` + +Deploys the specified Model.bim file to the SSAS instance running on localhost, overwriting or creating the AdventureWorks database. The GUI will not be loaded. + +By default, partitions, data sources and roles will not be overwritten in the target database. This behaviour can be changed by adding one or more of the following switches to the command above: + +- `-P` Overwrite **p**artitions +- `-C` Overwrite **c**onnections (data sources) +- `-R` Overwrite **r**oles +- `-M` Overwrite role **m**embers + +More information on command-line options can be found [here](/te2/Command-line-Options.html). + +> [!NOTE] +> Since TabularEditor.exe is a Windows Forms application, running it from the command line will execute the application in a different thread, returning control to the caller immediately. This may cause issues when running deployments as part of a batch job where you need to await succesful deployment before proceeding with the job. If you experience these issues, use `start /wait` to let TabularEditor finish its job before returning control to the caller: +> +> `start /wait TabularEditor.exe c:\Projects\Model.bim -deploy localhost AdventureWorks` + +## Advanced Scripting + +Tabular Editor lets you use C# to script changes to the loaded model. This is practical when you want to apply several changes to many objects at once. The Advanced Script editor has access to two objects: + +- `Selected` which represents all objects that are currently selected in the explorer tree. +- `Model` which represents the entire Tabular Object Model tree. + +The Advanced Script editor has some limited IntelliSense functionality to get you started: + +![IntelliSense helps you create scripts for Tabular Editor](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/AdvancedEditor%20intellisense.png) + +More documentation and examples on Advanced Scripting, can be [found here](/te2/Advanced-Scripting.html). diff --git a/content/localization/de/Importing-Tables_de.md b/content/localization/de/Importing-Tables_de.md new file mode 100644 index 00000000..d279fe06 --- /dev/null +++ b/content/localization/de/Importing-Tables_de.md @@ -0,0 +1,151 @@ +--- +uid: importing-tables-te2 +title: Importing Tables +author: Daniel Otykier +updated: 2020-05-03 +--- + +'# Importing Tables + +If you already have a Legacy Data Source in your model, you can right click it, and choose "Import Tables...". Tabular Editor will attempt to connect using the data provider and credentials specified in the Data Source. If successful, you should get a list of all the databases, tables and views accessible through the Data Source: + +![image](https://user-images.githubusercontent.com/8976200/49701892-35ea3900-fbf2-11e8-951a-8858179426c6.png) + +Clicking a table or view on the left-hand side will display a preview of the data on the right. You can deselect columns that you do not want to include, although [the data import best practice](https://www.sqlbi.com/articles/data-import-best-practices-in-power-bi/) suggests to always use views, and include only columns in those views that are needed in the Tabular Model. The UI will show you the resulting SQL query. By default, Tabular Editor will import a table/view using `SELECT * FROM ...`, but if you toggle any column in the preview, the resulting query will include an explicit list of columns. To switch back to `SELECT * FROM ...`, toggle the "Select all columns" checkbox in the upper right corner. + +You can select multiple tables/views to import at once. When you click "Import", all selected tables/views will be imported as new tables with all columns populated from the metadata. A single partition will be created on each table, holding the resulting SQL query from the UI. + +That's it! No more going back and forth between Tabular Editor and SSDT. + +## A note on Legacy vs. Structured Data Sources + +As there is currently no way for Tabular Editor to infer the metadata returned from M (Power Query) expressions, this UI only supports Legacy (aka. Provider) Data Sources. If you must use Structured Data Sources, you can still use a temporary Legacy connection to import the table schema initially (assuming your data source can be accessed through SQL, OLE DB or ODBC), and then manually switch the partitions on the imported tables, to use the Structured Data Sources. If you are importing data from "exotic" data sources, such as web services, Azure Data Lake Storage, etc. schema metadata can not be imported automatically, but [there is an option for providing the metadata information through the clipboard](/Importing-Tables#power-query-data-sources). + +In general, though, it is recommended to always use a Legacy connection for the following types of sources: + +- SQL Server databases +- Azure SQL Databases +- Azure SQL Data Warehouse +- Azure Databricks (through ODBC) +- Any relational OLEDB data source +- Any relational ODBC source + +For authentication using Azure Active Directory with MFA, please see here. + +## Importing without a pre-existing Data Source + +If your model does not yet contain any data sources, you can import tables by going to the "Model" menu and clicking "Import Tables...". The resulting UI looks like this: + +![image](https://user-images.githubusercontent.com/8976200/49702141-74cdbe00-fbf5-11e8-8a88-5bc2a0a6c80d.png) + +Leaving the selection at "Create a new Data Source and add it to the model" will display the Connection Dialog UI when clicking "Next". This dialog lets you specify the connection details: + +![image](https://user-images.githubusercontent.com/8976200/49702167-a5adf300-fbf5-11e8-8d06-d6670ad456d4.png) + +When clicking "OK", a (Legacy) Data Source using the specified connection will be created in your model, and you will be taken to the import page shown above. + +The next option on the list, "Use a temporary connection", will not cause a new Data Source to be added to the model. This means that you are responsible for assigning a Data Source to the partitions of the newly imported table, before deploying the model. + +The last option, "Manually import metadata from another application", is used when you want to import a new table based on a list of column metadata. This is useful for Structured (Power Query) Data Sources, [see below](/Importing-Tables#power-query-data-sources). + +## SQL capabilities + +For non-SQL Server data sources (or more precisely, data sources that do not use the Native SQL Client driver), please pay attention to the two dropdown-boxes near the bottom of the screen: + +![image](https://user-images.githubusercontent.com/8976200/51613859-b952b600-1f24-11e9-8fd7-7c5269aaab26.png) + +The "Reduce rows using"-dropdown lets you specify which row reduction clause to use, when querying the source for preview data, since the Table Import Wizard will only retrieve 200 rows of data from the source table or view. You can choose between the most common row reduction clauses, such as "TOP", "LIMIT", "FETCH FIRST", etc. + +The "Identifier quotes"-dropdown lets you specify how object names (column, tables) should be quoted in the generated SQL statements. This applies to both the data preview, as well as the SQL statement used in the table partition query, when the table is imported to the tabular model. By default, square brackets are used, but this can be changed to other common types of identifier quotes. + +## Changing the source of a table + +Another way to bring up the import page, is to right-click on an existing table (that uses a Legacy Data Source), and choose "Select Columns...". If that table was previously imported using the UI, the import page should show up with the source table/view and imported columns pre-selected. You may add/remove columns or even choose an entirely different table to be imported in place of the table you selected in your model. Keep in mind that any columns in your table, that were deselected or no longer exists in your source table/view will be removed from your model. You can always undo operations such as this using CTRL+Z. + +## Refreshing Table Metadata + +As of version 2.8, Tabular Editor has a new UI feature that lets you easily check for schema drift. That is, detecting columns that had their data type changed, or were added or removed to source tables and views. This check may be invoked at the Model level (again, this only applies to Legacy Data Sources), at the Data Source level, at the Table level or at the Partition level. This is done by right-clicking the object and choosing "Refresh Table Metadata..." + +![image](https://user-images.githubusercontent.com/8976200/49702346-7e582580-fbf7-11e8-9a62-04c6963179e5.png) + +Changes are detected based on the "Source Column" and "Data Type" properties of all data columns on the respective tables. If any changes are detected, Tabular Editor will display the above UI, detailing the changes. You may deselect changes that you do not want to apply to your model, although keep in mind that some changes may cause processing errors (for example, source columns that do not exist in the source table/view/query). + +This mechanism (as well as the Import Table UI) uses the FormatOnly-flag, when querying the metadata from the source. This means that you can have table partitions that use Stored Procedures. The FormatOnly-flag ensures that the Stored Proc is never executed directly. Instead, static analysis is performed by the server, in order to return only metadata describing the result set that would be returned from the Stored Proc upon execution. Depending on your RDBMS, there may be some limitations of the FormatOnly-flag when used with Stored Procedures. For more information on this topic when using SQL Server as a data source, please see [this article](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql?view=sql-server-2017#remarks). + +### CLI support + +You can perform a schema check at the model level from the command line by using the `-SC` flag. Note that the schema check, when executed through the CLI, will only report mapping issues. It will not make any changes to your model. This is useful if you're using Tabular Editor within CI/CD pipelines, as mapping issues could potentially cause problems after deploying your model to a test/production environment. + +### Ignoring objects + +As of Tabular Editor 2.9.8, you can exclude objects from schema checks / metadata refresh. This is controlled by setting an annotation on the objects that you wish to leave out. As the annotation name, use the codes listed below. You can leave the annotation value blank or set it to "1", "true" or "yes". Setting the annotation value to "0", "false" or "no" will effectively disable the annotation, as if it didn't exist: + +**Table flags:** + +- `TabularEditor_SkipSchemaCheck`: Causes Tabular Editor to completely skip a schema check on this table. +- `TabularEditor_IgnoreSourceColumnAdded`: Tabular Editor will ignore additional columns that are not mapped to any table columns on this table. +- `TabularEditor_IgnoreDataTypeChange`: Tabular Editor will ignore mismatched data types on any column of the table. +- `TabularEditor_IgnoreMissingSourceColumn`: Tabular Editor will ignore imported columns where the source column apparently does not exist in the source. + +**Column flags:** + +- `TabularEditor_IgnoreDataTypeChange`: Tabular Editor will ignore mismatched data type on this specific column. +- `TabularEditor_IgnoreMissingSourceColumn`: Tabular Editor will ignore an apparently missing source column for this specific column. + +The flags impact schema checking through both the UI and the CLI. + +### Treating warnings as errors + +By default, the CLI will report an error when a partition query could not be executed, or when the imported table contains a column that does not match any column in the source query. The CLI will report a warning when a column's data type does not match the column in the source query, or if the source query contains columns that are not mapped to any columns in the imported table. The CLI will also report a warning when source queries of different partitions on the same table, do not return the same columns. + +Starting with Tabular Editor version 2.14.1, you can change the behaviour of the CLI such that all warnings as listed above are reported as errors. To do this, add the following annotation at the **model** level: + +- `TabularEditor_SchemaCheckNoWarnings`: Causes Tabular Editor to treat all schema check warnings as errors. + +## Azure Active Directory with MFA + +If you want to import tables from an Azure SQL Database or Azure Synapse SQL pool, you will likely need Azure Active Directory multi-factor authentication. Unfortunately, this is not supported by the SQL Native Client provider used in .NET Framework. Instead, use the MSOLEDBSQL provider (which also has the benefit that it is generally faster than the native client, when Analysis Services reads data from the table). Make sure you have the [latest (x86) version](https://docs.microsoft.com/en-us/sql/connect/oledb/download-oledb-driver-for-sql-server?view=sql-server-ver15) of this driver installed, to make this work on your local machine. + +Here are step by step instructions to set up the data source to work with MFA: + +1. Create a new legacy data source and add it to your model. Model > New Data Source (Legacy) +2. Specify `System.Data.OleDb` as the Provider property and use a connection string that looks as follows, substituting the correct server, database and user names: + +### For Synapse SQL pools: + +``` +Provider=MSOLEDBSQL;Data Source=-ondemand.sql.azuresynapse.net;User ID=daniel@adventureworks.com;Database=;Authentication=ActiveDirectoryInteractive +``` + +### For Azure SQL databases: + +``` +Provider=MSOLEDBSQL;Data Source=.database.windows.net;User ID=daniel@adventureworks.com;Database=;Authentication=ActiveDirectoryInteractive +``` + +3. To import tables from this source, right-click on the data source and choose "Import Tables...", the Import Table Wizard UI should appear showing a list of tables/views from the source. Note, that for Synapse SQL pools, you may have to specify "TOP (without NOLOCK)" as a row clause, in order for the data preview to work. +4. When deploying your model to Analysis Services, you will most likely need to specify other credentials, such as a Service Principal application ID and secret or a SQL account, in order for Analysis Services to authenticate itself against the source when refreshing table data. This can be specified using TMSL or SSMS post-deployment, or you can set this up as [part of your CI/CD deployment pipeline](https://tabulareditor.com/2020/06/20/DevOps5.html#creating-your-first-release-pipeline). + +## Manually importing schema/metadata + +If you're using a data source not supported by the Import Tables Wizard, you have the option of manually importing metadata. This option provides a UI where you can enter or paste in a table schema on the left hand side, which will be automatically parsed for column name and data type information. Alternatively, you can manually type each column name on the right hand side and choose a data type in the drop down. Either way, this is faster than manually creating a table and adding individual data columns through the main UI. When you're done, hit "Import!", adjust the table name and partition expression. + +When parsing the text on the left hand side, Tabular Editor searches for certain keywords, in order to determine how the information is structured. It's pretty liberal in the way it interprets data, so you can, for example, paste in a list of columns from a CREATE TABLE SQL script, or the output of the Power Query `Table.Schema(...)` function as described below. The only requirements is that each line of text represents one column of source data. + +![image](https://user-images.githubusercontent.com/8976200/70419758-6f07f400-1a66-11ea-838d-9a587c8021ca.png) + +## Power Query data sources + +Since there is no officially supported way to execute or validate a Power Query/M expression, Tabular Editor only has limited support for Power Query data sources. As of 2.9.0, you may use the "Manually import metadata from another application"-option of the Import Table Wizard, as described above, to import a schema from a Power Query query in Excel or Power BI Desktop. The workflow is the following: + +- First, make sure your model contains a Power Query Data Source. Right-click Data Sources > New Data Source (Power Query). If you're going to load data from a SQL Server, specify "tds" as the protocol and fill out the Database, Server and AuthenticationKind properties. + ![image](https://user-images.githubusercontent.com/8976200/70418811-6dd5c780-1a64-11ea-8332-d074c6b2d5c2.png) +- For other types of data sources, it may be easier to create the initial model and first few tables in SSDT, to figure out how the Data Source should be configured, and then use the technique below only when adding additional tables. +- Use Power Query within Excel or Power BI Desktop to connect to your source data and apply any transformations needed. +- Using Power Query's Advanced Editor, add a step that uses the `Table.Schema(...)` [M function](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the previous output: + ![image](https://user-images.githubusercontent.com/8976200/70416018-5562ae80-1a5e-11ea-8962-529304ce83f0.png) +- Select the full output preview, copy it into the clipboard (CTRL+A, CTRL+C) and paste it into the schema/metadata textbox in the Import Tables Wizard: + ![image](https://user-images.githubusercontent.com/8976200/70416817-2e0ce100-1a60-11ea-9e2b-430cecf88d0a.png) +- Click "Import!" and provide a proper name for your table. +- Lastly, paste the original M expression you used in Excel/Power BI, from before you modified it with the `Table.Schema(...)` function, into the partition on the newly created table. Modify the M expression to point to the source you specified in the first step: + ![image](https://user-images.githubusercontent.com/8976200/70418985-dae95d00-1a64-11ea-8bfb-8dda16c33742.png) diff --git a/content/localization/de/Keyboard-Shortcuts_de.md b/content/localization/de/Keyboard-Shortcuts_de.md new file mode 100644 index 00000000..8fae7189 --- /dev/null +++ b/content/localization/de/Keyboard-Shortcuts_de.md @@ -0,0 +1,64 @@ +# Keyboard Shortcuts + +As of version 2.7.3, Tabular Editor now supports the following keyboard shortcuts: + +| General | Shortcut | +| ---------------------------------------------------------- | ------------------------------------ | +| New model | Ctrl+N | +| Load model from a file | Ctrl+O | +| Load model from a database | Ctrl+Shift+O | +| Save model | Ctrl+S | +| Copy selection | Ctrl+C | +| Cut selection | Ctrl+X | +| Paste | Ctrl+V | +| Undo | Ctrl+Z | +| Redo | Ctrl+Y | +| Select All | Ctrl+A | +| ~Launch Deployment Wizard~ | ~F6~ | +| Launch Best Practice Analyzer | F10 | + +| Expression Editor | Shortcut | +| ------------------------------------------- | --------------- | +| Find | Ctrl+F | +| Find and replace | Ctrl+H | +| Go to definition | F12 | +| Navigate back | Alt+Left arrow | +| Navigate forward | Alt+Right arrow | +| Format DAX | F6 | +| Format DAX (Short lines) | Ctrl+F6 | +| Comment lines | Ctrl+Shift+C | +| Uncomment lines | Ctrl+Shift+U | + +| Script Editor | Shortcut | +| ---------------- | -------- | +| Find | Ctrl+F | +| Find and replace | Ctrl+H | +| Run script | F5 | + +| Explorer tree | Shortcut | +| ----------------------------------------------- | ----------------------------- | +| Navigate up or down | Up / Down arrow | +| Expand / collapse current node | Right / Left arrow | +| Expand / collapse current node and all subnodes | Ctrl+Right / Left arrow | +| Expand / collapse entire tree | Ctrl+Shift+Right / Left arrow | +| Toggle measures | Ctrl+1 | +| Toggle columns | Ctrl+2 | +| Toggle hierarchies | Ctrl+3 | +| Toggle display folders | Ctrl+4 | +| Toggle hidden objects | Ctrl+5 | +| Toggle Metadata Columns | Ctrl+F1 | +| Toggle Alphabetical Ordering | Ctrl+F2 | +| Toggle all object types | Ctrl+F3 | +| Filter | Ctrl+F | +| Toggle filter | Ctrl+Shift+F | +| Edit Expression | Enter | +| Navigate back | Alt+Left arrow | +| Navigate forward | Alt+Right arrow | +| Show dependencies | F3 | +| Make invisible | Ctrl+I | +| Make visible | Ctrl+U | +| Create new measure | Alt+1 | +| Create new calculated column | Alt+2 | +| Create new hierarchy | Alt+3 | +| Create new data column | Alt+4 | +| Create new table | Alt+5 | diff --git a/content/localization/de/Maintaining-Calculations-using-Scripting_de.md b/content/localization/de/Maintaining-Calculations-using-Scripting_de.md new file mode 100644 index 00000000..c7d0d4b5 --- /dev/null +++ b/content/localization/de/Maintaining-Calculations-using-Scripting_de.md @@ -0,0 +1,19 @@ +This article demonstrates how you can use the Advanced Scripting feature in Tabular Editor, to maintain DAX logic across several objects in a consistent way. In the [Useful Script Snippets article](/Useful-script-snippets), we already saw [how we can use Custom Actions to quickly generate many measures](/Useful-script-snippets#generate-time-intelligence-measures) with similar logic, which can be useful when creating Time Intelligence calculations, for example. + +In this article, we're going to expand on this idea by creating a scripting "framework", which will allow us to centrally define all the calculations we need within a TSV file (Tabulator Separated Values). The advantages of using a TSV file is that it can be easily edited within Excel, while at the same time being easy to parse and load from within a script in Tabular Editor. + +For this article, we will focus on the Internet Sales fact and related dimensions of good 'ol Adventure Works: + +![image](https://user-images.githubusercontent.com/8976200/44193845-85cd5d80-a134-11e8-8f39-2da1380fdc63.png) + +The fact table has a number of numeric columns which are simply aggregated up as seven simple `SUM` measures: + +![image](https://user-images.githubusercontent.com/8976200/44196409-270be200-a13c-11e8-9994-0a8f2fa19e1a.png) + +For the purposes of this article, we'll call these the **base measures**. In real life, the formula of the base measures could be more complex, but that does not matter in general, as we will see in a moment. The central idea, is that we will use our TSV file to define a set of formulas involving the base measures as well as filter contexts that will be applied outside the calculations. + +\*\*\* TODO \*\*\* + +, as long as the calculations we are trying to build can still be constructed from one or more base measures, evaluated within any valid filter context. + +\*\*\* TODO \*\*\* diff --git a/content/localization/de/Master-model-pattern_de.md b/content/localization/de/Master-model-pattern_de.md new file mode 100644 index 00000000..d8dad54f --- /dev/null +++ b/content/localization/de/Master-model-pattern_de.md @@ -0,0 +1,325 @@ +# Master Model Pattern + +It is not uncommon to have several Tabular models in an organisation, with a substantial amount of functional overlap. For the development team, keeping these models up to date with shared features can be a pain point. In this article, we'll see an alternate approach that may be suitable in situations where it makes sense to combine all these models into a single "Master" model, that is then deployed partially into several different subset models. Tabular Editor enables this approach by utilising perspectives in a special way (while still allowing perspectives to work the usual way). + +**Disclaimer:** While this technique works, it is not supported by Microsoft, and there is a fair amount of learning, scripting and hacking involved. Decide for yourself whether you think it's the right approach for your team. + +For simplicity, consider the AdventureWorks sample model: + +![image](https://user-images.githubusercontent.com/8976200/43959290-895c1c96-9cae-11e8-8112-008f54cb400a.png) + +Let's say that for some reason, these is a need to deploy everything relating to Internet Sales as one model, and everything relating to Reseller Sales as another. This could be for security reasons, performance, scalability, or maybe even because your team is servicing a number of external clients, where each client needs their own copy of the model, containing both shared and specific functionality. + +Instead of actually maintaining one development branch for each of the different versions, the technique presented here, lets you maintain just one model using metadata to indicate how the model should be split upon deployment. + +## (Ab)using perspectives + +The idea is quite simple. Start by adding a number of new perspectives to your model, corresponding to the number of target models you need to deploy to. Make sure to prefix these perspectives in a consistent way, to separate them from user-oriented perspectives: + +![image](https://user-images.githubusercontent.com/8976200/43960154-6b637042-9cb1-11e8-906b-6671bbb9558e.png) + +Here, we use a `$`-sign as the prefix on the perspective names. Later on we will see how these perspectives are stripped from the model, so that end users will not see them. They are only used by the model developers. + +Now, simply add all objects needed in the individual models to these perspectives. Use the Perspective dropdown in Tabular Editor to confirm that a model contains the necessary objects. Here's a handy script that can be used to ensure that all dependencies are included in the perspective as well: + +```csharp +// Look through all hierarchies in the current perspective: +foreach(var h in Model.AllHierarchies.Where(h => h.InPerspective[Selected.Perspective])) +{ + // Make sure columns used in hierarchy levels are included in the perspective: + foreach(var level in h.Levels) { + level.Column.InPerspective[Selected.Perspective] = true; + } +} + +// Loop through all measures and columns in the current perspective: +foreach(var obj in Model.AllMeasures.Cast() + .Concat(Model.AllColumns).Where(m => m.InPerspective[Selected.Perspective]) + .OfType().ToList()) +{ + // Loop through all objects that the current object depends on: + foreach(var dep in obj.DependsOn.Deep()) + { + // Include columns, measure and table dependencies: + var columnDep = dep as Column; if(columnDep != null) columnDep.InPerspective[Selected.Perspective] = true; + var measureDep = dep as Measure; if(measureDep != null) measureDep.InPerspective[Selected.Perspective] = true; + var tableDep = dep as Table; if(tableDep != null) tableDep.InPerspective[Selected.Perspective] = true; + } +} + +// Look through all columns that have a SortByColumn in the current perspective: +foreach(var c in Model.AllColumns.Where(c => c.InPerspective[Selected.Perspective] && c.SortByColumn != null)) +{ + c.SortByColumn.InPerspective[Selected.Perspective] = true; +} +``` + +**Explanation:** First, the script loops through all hierarchies in the current perspective (the perspective currently selected in the dropdown at the top of the screen). For every such hierarchy, it ensures that all columns used as hierarchy levels appear in the perspective. Next, the script loops through all columns and measures of the current perspective. For each of these objects, all DAX dependencies in the form of measure-, column- or table references are also included in the perspective. Please note that expressions such as `DISTINCTCOUNT('Customer'[CustomerId])` will result in all columns of the 'Customer' table being included in the perspective, as Tabular Editor treats such an expression as having a dependency both on the [CustomerId] column itself, and on the 'Customer' table. Lastly, the script ensures that any columns that are used as a "Sort By"-column, are also included in the perspective. + +I recommend saving this script as a Custom Action at the Model level, to make it easy to invoke it going forward. + +By the way, if you want to make a copy of a perspective, you can already do that through the UI. Click on the "Perspectives" node in the explorer tree, and then click the ellipsis button in the property grid: + +![image](https://user-images.githubusercontent.com/8976200/44028910-c7ffab80-9efb-11e8-813a-5b0f5c137bab.png) + +This will open a dialog that lets you create and delete perspectives, as well as clone existing perspectives: + +![image](https://user-images.githubusercontent.com/8976200/44028953-f13c91ca-9efb-11e8-936a-1f0e1d4eb93f.png) + +To supplement this, here's a script that removes all invisible and unused objects from a perspective, in case you need to clean up a bit: + +```csharp +// Loop through all columns of the current perspective: +foreach(var c in Model.AllColumns.Where(c => c.InPerspective[Selected.Perspective])) { + if( + // If the column is hidden (or the parent table is hidden): + (c.IsHidden || c.Table.IsHidden) + + // And not used in any relationships: + && !c.UsedInRelationships.Any() + + // And not used as the SortByColumn for any other columns in the perspective: + && !c.UsedInSortBy.Any(sb => !sb.IsHidden && sb.InPerspective[Selected.Perspective]) + + // And not used in any hierarchies in the perspective: + && !c.UsedInHierarchies.Any(h => h.InPerspective[Selected.Perspective]) + + // And not referenced in any DAX expression for other visible objects in the perspective: + && !c.ReferencedBy.Deep().OfType() + .Any(obj => obj.InPerspective[Selected.Perspective] && !(obj as IHideableObject).IsHidden) + + // And not referenced by any roles: + && !c.ReferencedBy.Roles.Any() ) + { + // If all of the above, then the column can be removed from the current perspective: + c.InPerspective[Selected.Perspective] = false; + } +} + +// Loop through all measures of the current perspective: +foreach(var m in Model.AllMeasures.Where(m => m.InPerspective[Selected.Perspective])) { + if( + // If the measure is hidden (or the parent table is hidden): + (m.IsHidden || m.Table.IsHidden) + + // And not referenced in any DAX expression for other visible objects in the perspective: + && !m.ReferencedBy.Deep().OfType() + .Any(obj => obj.InPerspective[Selected.Perspective] && !(obj as IHideableObject).IsHidden) + ) + { + // If all of the above, then the column can be removed from the current perspective: + m.InPerspective[Selected.Perspective] = false; + } +} +``` + +**Explanation:** The script first loops through all columns of the currently selected perspective. It removes a column from the perspective only if all of the following are true: + +- The column is hidden (or the table in which the column resides is hidden) +- The column does not participate in any relationships +- The column is not used as the SortByColumn of any other visible column in the perspective +- The column is not used as a level in any hierarchies in the perspective +- The column is not directly or indirectly referenced in any DAX expressions on other visible objects in the perspective +- The column is not used in any row level filter expressions + +For measures, we do the same thing, but simplified to only remove measures that meet the following criteria: + +- The measure is hidden (or the table in which the measure resides is hidden) +- The measure is not directly or indirectly referenced in any DAX expressions on other visible objects in the perspective + +If you're a team of developers working on the model, you should already be using Tabular Editors ["Save to Folder" functionality](/Advanced-features#folder-serialization) together with a source control environment such as Git. Make sure to check the "Serialize perspectives per-object" option under "File" > "Preferences" > "Save to Folder", to avoid getting heaps of merge conflicts on your perspective definitions. + +![image](https://user-images.githubusercontent.com/8976200/44029969-935e0efe-9eff-11e8-93de-c1223f7ebe7f.png) + +## Adding more fine-grained control + +By now, you've probably guessed that we're going to use scripting to create one version of the model for every of our prefixed developer perspectives. The script will simply remove all objects from the model, that are not included in a given developer perspective. However, before we do that, there are a couple more situations we need to handle. + +### Controlling non-perspective objects + +Some objects, such as perspectives, data sources and roles, are not included nor excluded from perspectives themselves, but we may still need a way to specify which of our model versions they should belong to. For this, we're going to use annotations. So going back to our Adventure Works model, we may want the "Inventory" and "Internet Operation" perspectives to appear in "$InternetModel" and "$ManagementModel", while "Reseller Operation" should appear in "$ResellerModel" and "$ManagementModel". + +So let's add a new annotation called "DevPerspectives" on each of the 3 original perspectives, and let's just supply the names of the developer perspectives as a comma-separated string: + +![image](https://user-images.githubusercontent.com/8976200/44032304-01bdcc70-9f07-11e8-9b28-db0912ea1ade.png) + +When adding new _user_ perspectives to the model, remember to add the same annotation and provide the names of the developer perspectives that you want the _user_ perspective included in. When scripting the final model versions later on, we will use the information in these annotations to include the perspectives needed. We can do the same thing for data sources and roles. + +### Controlling object metadata + +There may also be situations where the same measure should have slightly different expressions or format strings across the different model versions. Again, we can use annotation to provide the metadata per developer perspective, and then apply the metadata when we script out the final model. + +The easiest way to get all object properties serialized into text, would probably be the [ExportProperties](/Useful-script-snippets#export-object-properties-to-a-file) script function. However, that's a little overkill for our use case, so let's just specify directly which properties we want to store as annotations. Create the following script: + +```csharp +foreach(var m in Selected.Measures) { + m.SetAnnotation(Selected.Perspective.Name + "_Expression", m.Expression); + m.SetAnnotation(Selected.Perspective.Name + "_FormatString", m.FormatString); + m.SetAnnotation(Selected.Perspective.Name + "_Description", m.Description); +} +``` + +And save it as a custom action named "Save Metadata as Annotations": + +![image](https://user-images.githubusercontent.com/8976200/44033695-7a754482-9f0b-11e8-937b-0bc0987ce7cb.png) + +Similarly, save the following script as a custom action called "Load Metadata from Annotations": + +```csharp +foreach(Measure m in Selected.Measures) { + var expr = m.GetAnnotation(Selected.Perspective.Name + "_Expression"); if(expr == null) continue; + m.Expression = expr; + m.FormatString = m.GetAnnotation(Selected.Perspective.Name + "_FormatString"); + m.Description = m.GetAnnotation(Selected.Perspective.Name + "_Description"); +} +``` + +The idea is that we create one annotation for each of the properties we would like to maintain different versions of, per developer perspective. If you need to maintain other properties than those shown in the script (Expression, FormatString, Description) separately, just add them to the script. You can do the same thing for other object types, but it probably won't make sense for much other than measures and perhaps calculated columns and partitions (to maintain different query expressions per model version, for example). + +Use your new custom actions to apply model version specific changes to the developer perspectives (or add the annotations by hand). For example, in our Adventure Works sample, we want the [Day Count] measure to have a different expression in the $ResellerModel perspective, so we apply the changes to the measure, and invoke the "Save Metadata as Annotations" action while having selected the "$ResellerModel" perspective in the dropdown: + +![image](https://user-images.githubusercontent.com/8976200/44033944-3104e414-9f0c-11e8-9f06-396bf85a0e4f.png) + +In the screenshot above, we have 3 annotations for each of the developer perspectives. In reality, though, we would only need to create these annotations for those developer perspectives where the properties should differ from their native values. + +## Altering partition queries + +We can use a similar technique to apply changes to partition queries between the different versions. For example, we may want different SQL `WHERE` criterias on some partition queries depending on the version. Let's start by creating a set of new annotations on our _table_ objects, to specify the base SQL query we want our partitions to use for each version. Here, for example, we want to restrict which records are included in the Product table on two of our three versions: + +![image](https://user-images.githubusercontent.com/8976200/44736562-69221580-aaa4-11e8-82ee-88388015d30d.png) + +For tables that have multiple partitions, we specify the WHERE criteria using "placeholders", that will be replaced later on: + +![image](https://user-images.githubusercontent.com/8976200/44737015-b3f05d00-aaa5-11e8-9bad-cadd5b4dae35.png) + +Define the placeholder values within each partition (note, you must be using [Tabular Editor v. 2.7.3](https://github.com/TabularEditor/TabularEditor/releases/tag/2.7.3) or newer to edit partition annotations through the UI): + +![image](https://user-images.githubusercontent.com/8976200/44737199-2a8d5a80-aaa6-11e8-8813-8189b593da98.png) + +In dynamic partitioning scenarios, don't forget to include these annotations in the script you're using when creating the new partitions. In the next section, we'll see how to apply these placeholder values during deployment. + +## Deploying different versions + +Finally, we are ready to deploy our model as 3 different versions. Unfortunately, the Deployment Wizard UI in Tabular Editor cannot split up the model for us based on the perspectives and annotations we created, so we'd have to create an additional script, that strips down our model to a specific version. This script can then be executed as part of a command-line deployment, so that the whole deployment process can be packaged in a command file, a PowerShell executable or maybe even integrated in your build/automated deployment process? + +The script we need looks like the following. The idea is that we create one script per developer perspective. Save the script as a text file and name it something like `ResellerModel.cs`: + +```csharp +var version = "`$`ResellerModel"; // TODO: Replace this with the name of your developer perspective + +// Remove tables, measures, columns and hierarchies that are not part of the perspective: +foreach(var t in Model.Tables.ToList()) { + if(!t.InPerspective[version]) t.Delete(); + else { + foreach(var m in t.Measures.ToList()) if(!m.InPerspective[version]) m.Delete(); + foreach(var c in t.Columns.ToList()) if(!c.InPerspective[version]) c.Delete(); + foreach(var h in t.Hierarchies.ToList()) if(!h.InPerspective[version]) h.Delete(); + } +} + +// Remove user perspectives based on annotations and all developer perspectives: +foreach(var p in Model.Perspectives.ToList()) { + if(p.Name.StartsWith("`$`")) p.Delete(); + + // Keep all other perspectives that do not have the "DevPerspectives" annotation, while removing + // those that have the annotation, if is not specified in the annotation: + if(p.GetAnnotation("DevPerspectives") != null && !p.GetAnnotation("DevPerspectives").Contains(version)) + p.Delete(); +} + +// Remove data sources based on annotations: +foreach(var ds in Model.DataSources.ToList()) { + if(ds.GetAnnotation("DevPerspectives") == null) continue; + if(!ds.GetAnnotation("DevPerspectives").Contains(version)) ds.Delete(); +} + +// Remove roles based on annotations: +foreach(var r in Model.Roles.ToList()) { + if(r.GetAnnotation("DevPerspectives") == null) continue; + if(!r.GetAnnotation("DevPerspectives").Contains(version)) r.Delete(); +} + +// Modify measures based on annotations: +foreach(Measure m in Model.AllMeasures) { + var expr = m.GetAnnotation(version + "_Expression"); if(expr == null) continue; + m.Expression = expr; + m.FormatString = m.GetAnnotation(version + "_FormatString"); + m.Description = m.GetAnnotation(version + "_Description"); +} + +// Set partition queries according to annotations: +foreach(Table t in Model.Tables) { + var queryWithPlaceholders = t.GetAnnotation(version + "_PartitionQuery"); if(queryWithPlaceholders == null) continue; + + // Loop through all partitions in this table: + foreach(Partition p in t.Partitions) { + + var finalQuery = queryWithPlaceholders; + + // Replace all placeholder values: + foreach(var placeholder in p.Annotations.Keys) { + finalQuery = finalQuery.Replace("%" + placeholder + "%", p.GetAnnotation(placeholder)); + } + + p.Query = finalQuery; + } +} + +// TODO: Modify other objects based on annotations, if applicable... +``` + +**Explanation:** First, we remove all tables, columns, measures and hierarchies, that are not part of the perspective defined in line 1 of the script. Then, we remove any additional objects where we may have applied the "DevPerspectives" annotation as described previously, along with all the developer perspectives themselves. Afterwards, we apply any changes to measure expressions, format strings or descriptions based on the annotations, if any. Finally, we apply partition queries as defined in annotations (if any), while also replacing placeholder values with the annotated values (if any). + +Note that we could also just add additional specific model changes directly to this script, if we wanted to, but the whole point of this exercise was how we can maintain several models directly from within Tabular Editor. The script above is the same, regardless of which version we want to deploy (except, of course, for line 1). + +Finally, we can load our Model.bim file, execute the script, and deploy the modified model in one go, using the following [command line syntax](/Command-line-Options): + +```sh +start /wait /d "c:\Program Files (x86)\Tabular Editor" TabularEditor.exe Model.bim -S ResellerModel.cs -D localhost AdventureWorksReseller -O -R +``` + +To deploy the Internet or Management versions, we would need to do the same, providing the corresponding scripts: + +```sh +start /wait /d "c:\Program Files (x86)\Tabular Editor" TabularEditor.exe Model.bim -S InternetModel.cs -D localhost AdventureWorksInternet -O -R +start /wait /d "c:\Program Files (x86)\Tabular Editor" TabularEditor.exe Model.bim -S ManagementModel.cs -D localhost AdventureWorksManagement -O -R +``` + +This assumes that you are executing the command line within the directory of your Model.bim file (or Database.json file if using the "Save to Folder"-functionality). The -S switch instructs Tabular Editor to apply the supplied script to the model, and the -D switch performs the deployment. The -O switch allows overwriting an existing database with the same name, and the -R switch indicates that we also want to overwrite roles of the target database. + +## Master model processing + +If you have a dedicated processing server and large amounts of data overlap between the individual models, it may make sense for you to process the data into the master model first, before splitting it up. This way, you can avoid processing the same data several times, into individual models. **This assumes, however, that you are not processing any tables where the partition query has been changed between versions, as shown in [this section](/Master-model-pattern#altering-partition-queries).** The recipe for this is outlined below: + +1. (Optional - in case there were metadata changes) Deploy your master model to your processing server +2. Perform the processing you need on your master model (do not process tables that have version-specific partition queries). +3. Synchronise the master model into every individual model and use the command above to strip down the individual models after synchronisation, followed by a ProcessRecalc if necessary. +4. (Optional) Process any tables on the individual models, that have version-specific partition queries. + +## Tips and tricks + +When you're starting to use custom annotations a lot, there may be situations where you want to list all objects with a specific annotation. This is where the Dynamic LINQ expressions of the Filter-box comes in handy. + +First off, let's say we wanted to find all objects where we added an annotation with the name "$InternetModel_Expression". Type the following into the filter textbox and hit ENTER: + +``` +:GetAnnotation("`$`InternetModel_Expression")<>null +``` + +Or, if you want to find all objects, that have an annotation ending with the word "_Expression", use: + +``` +:GetAnnotations().Any(EndsWith("_Expression")) +``` + +Note that these functions are case-sensitive, so if your annotation was written in lowercase, the above filter would not catch it. + +You could also search for objects where the annotation had a specific value: + +``` +:GetAnnotation(`$`InternetModel_Description).Contains("TODO") +``` + +## Conclusion + +The technique described here can be very helpful when maintaining many similar models with a lots of shared functionality, such as Calendar tables and other common dimensions. The scripts used can be neatly reused as Custom Actions within Tabular Editor, while the actual deployment can be automated in various ways. diff --git a/content/localization/de/Power-BI-Desktop-Integration_de.md b/content/localization/de/Power-BI-Desktop-Integration_de.md new file mode 100644 index 00000000..3fe205f7 --- /dev/null +++ b/content/localization/de/Power-BI-Desktop-Integration_de.md @@ -0,0 +1,25 @@ +# Power BI Desktop Integration + +As of July 2020, [Power BI Desktop adds support for External Tools](https://docs.microsoft.com/da-dk/power-bi/create-reports/desktop-external-tools). This allows Tabular Editor to perform certain modeling operations when working with Imported or DirectQuery data in Desktop. + +![image](https://user-images.githubusercontent.com/8976200/87296924-dcea3180-c507-11ea-9cf9-2f647d26a2a9.png) + +## Prerequisites + +- [July 2020 version of Power BI Desktop](https://www.microsoft.com/en-us/download/details.aspx?id=58494) (or newer) +- [Latest version of Tabular Editor](https://github.com/TabularEditor/TabularEditor/releases/latest) +- Enable [Enhanced Metadata](https://docs.microsoft.com/en-us/power-bi/connect-data/desktop-enhanced-dataset-metadata) under Power BI Desktop's Preview Features + +Also, it is highly recommended that [automatic date/time](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-auto-date-time) is **disabled** (Power BI Desktop setting under "Data Load"). + +## Supported Modeling Operations + +By default, Tabular Editor will only let you edit a limited number of objects and properties when connected to a Power BI Desktop model. These are: + +- Measures (add/remove/edit any property) +- Calculation Groups and Calculation Items (add/remove/edit any property) +- Perspectives (add/remove/edit any property) +- Translations (add/remove) + - You can apply metadata translations to any object in the model, although be aware that Power BI Desktop does not yet support translations to the default model culture. + +**Note:** If you enable the "Allow unsupported Power BI features (experimental)" option under Tabular Editor's File > Preferences dialog, Tabular Editor will let you edit **any** object and property, potentially causing model changes that are not supported by Power BI Desktop, which may cause a crash or a corrupt .pbix file. In this case, Microsoft Support will not be able to help you, so use at your own risk, and keep a backup of your .pbix file just in case. diff --git a/content/localization/de/RW001_de.md b/content/localization/de/RW001_de.md new file mode 100644 index 00000000..847d77fb --- /dev/null +++ b/content/localization/de/RW001_de.md @@ -0,0 +1,35 @@ +--- +uid: RW001 +category: Code actions +sub-category: Rewrites +title: Rewrite TOTALxTD using CALCULATE +author: Daniel Otykier +updated: 2025-02-10 +--- + +Code action `RW001` (Rewrites) **Rewrite TOTALxTD using CALCULATE** + +## Description + +Functions such as [`TOTALMTD`](https://dax.guide/TOTALMTD), [`TOTALQTD`](https://dax.guide/TOTALQTD) and [`TOTALYTD`](https://dax.guide/TOTALYTD) can be rewritten using the [`CALCULATE`](https://dax.guide/CALCULATE) function. + +### Example + +Change: + +```dax + TOTALYTD([Total Sales], 'Date'[Date]) +``` + +To: + +```dax +CALCULATE([Total Sales], DATESYTD('Date'[Date])) +``` + +## Why is Tabular Editor suggesting this? + +This rewrite is useful in case you want to add additional filters or modify the calculation context. + +> [!NOTE] +> This code action is in the **Rewrites** category, which means that it does not represent a general recommendation or best practice. Instead, the code action provides a quick way to rewrite the code in a different way, for example as part of a larger refactoring. After applying the code action and until further edits are made, you may see an **Improvement** or **Readability** code action that suggests to modify the code back to its original state. \ No newline at end of file diff --git a/content/localization/de/RW002_de.md b/content/localization/de/RW002_de.md new file mode 100644 index 00000000..8c873a72 --- /dev/null +++ b/content/localization/de/RW002_de.md @@ -0,0 +1,61 @@ +--- +uid: RW002 +category: Code actions +sub-category: Rewrites +title: Rewrite using FILTER +author: Daniel Otykier +updated: 2025-02-10 +--- + +Code action `RW002` (Rewrites) **Rewrite using FILTER** + +## Description + +A scalar predicate in a filter argument to `CALCULATE` is equivalent to a 1-column table expression that uses `FILTER`. + +### Example 1 + +Change: + +```dax +CALCULATE([Total Sales], Products[Color] = "Red") +``` + +To: + +```dax +CALCULATE( + [Total Sales], + FILTER( + ALL(Products[Color]), + Products[Color] = "Red") + ) +) +``` + +### Example 2 + +Change: + +```dax +CALCULATE([Total Sales], KEEPFILTERS(Products[Color] = "Red")) +``` + +To: + +```dax +CALCULATE( + [Total Sales], + FILTER( + VALUES(Products[Color]), + Products[Color] = "Red") + ) +) +``` + +## Why is Tabular Editor suggesting this? + +This rewrite is useful in case you want to add more complex filtering logic. + +> [!NOTE] +> This code action is in the **Rewrites** category, which means that it does not represent a general recommendation or best practice. Instead, the code action provides a quick way to rewrite the code in a different way, for example as part of a larger refactoring. After applying the code action and until further edits are made, you may see an **Improvement** or **Readability** code action that suggests to modify the code back to its original state. \ No newline at end of file diff --git a/content/localization/de/RW003_de.md b/content/localization/de/RW003_de.md new file mode 100644 index 00000000..18689b8b --- /dev/null +++ b/content/localization/de/RW003_de.md @@ -0,0 +1,32 @@ +--- +uid: RW003 +category: Code actions +sub-category: Rewrites +title: Invert IF +author: Daniel Otykier +updated: 2025-02-10 +--- + +Code action `RW003` (Rewrites) **Invert IF** + +## Description + +To improve readability, it is sometimes useful to invert `IF` statements. + +### Example + +Change: + +```dax +IF(a < b, "B is greater", "A is greater") +``` + +To: + +```dax +IF(a > b, "A is greater", "B is greater") +``` + +## Why is Tabular Editor suggesting this? + +This code action provides a quick way to invert the logic of an `IF` statement, which can make the code easier to read. The readability of the code is subjective and depends on the context, which is why this code action is in the **Rewrites** category rather than the **Readability** category. \ No newline at end of file diff --git a/content/localization/de/Roadmap_de.md b/content/localization/de/Roadmap_de.md new file mode 100644 index 00000000..f445bd1c --- /dev/null +++ b/content/localization/de/Roadmap_de.md @@ -0,0 +1,95 @@ +# Roadmap + +- Scripting objects into TMSL or DAX (compatible with DAX Editor) +- IntelliSense in DAX expression editor +- Create plug-in for Visual Studio, to launch Tabular Editor +- Tabular Editor plug-in architecture / public API for developers +- Automated build, test, publishing and documentation using VSTS +- [Done] Formula fix-up (i.e. automatically fixing DAX expressions when renaming objects) +- [Done] UI for showing object dependencies +- [Done] Scripting changes from the command-line +- [Done] Possibility to read/edit more object types (tables, partitions, data columns) +- [Done] Split a Model.bim into multiple json files (for example, one file per table) for better integration into Source Control workflows. +- [Done] Import/export translations + +## Scripting objects into TMSL or DAX + +It should be possible, when selecting one or more objects in the explorer tree, to generate a script for these objects. In fact, this is already possible by dragging and dropping the objects into another text editor (or SSMS), but there should be a similar right-click option to more clearly communicate to end-users what's going on. It should be possible to generate both TMSL scripts (for SSMS) or DAX-style code, usable in [DAX Editor](https://github.com/DaxEditor/). + +Today, measures and calculated columns can be dragged between instances of Tabular Editor to copy them between models, but to better expose this functionality, there should be an UI option for importing a provided piece of TMSL, either from the clipboard or from a file. See [this issue](https://github.com/TabularEditor/TabularEditor/issues/69). Lastly, the standard copy-paste shortcuts should be enabled. + +## Create plug-in for Visual Studio, to launch Tabular Editor + +A simple context menu extension to Visual Studio, that will simply ensure the Model.bim file is closed and then launch TabularEditor.exe with the Model.bim file loaded. + +## IntelliSense in DAX expression editor + +When writing DAX code in the expression editor, an autocompletebox should pop-up to help complete table names, column names, measure names or functions (and their arguments). + +See also [this issue](https://github.com/TabularEditor/TabularEditor/issues/64). + +## Tabular Editor plug-in architecture / public API for developers + +People who prefer to script tabular models using C# can already today use the TOMWrapper.dll instead of using the Analysis Services TOM API directly. This provides some benefits, for example, the TOMWrapper namespace makes it easier to work with perspectives and translations, thanks to the convenient methods and properties available. + +Taking this one step further, it would be interesting to expose more Tabular Editor functionality to developers: + +- Parsing of DAX objects +- Accessing Best Practice Analyzer results +- Tabular Editor UI (making it possible to create "plug-ins" for Tabular Editor with/without custom UI) + +## Automated build, test, publishing and documentation using VSTS + +DevOps using VSTS and general clean-up of Tabular Editor source code. + +## Formula fix-up + +When any model object is renamed, all DAX expressions refering that object should be updated to reflect the changed name. + +**Update**: As of 2.2, this feature can now be toggled on under "File" > "Preferences". + +## UI for showing object dependencies + +Right-clicking a measure or calculated column should display a dependency tree in a pop-up dialog. It should be possible to show either objects that depend on the chosen object, or objects on which the chosen object depend. + +**Update**: As of 2.2, this feature is available. Simply right-click an object and choose "Show dependencies...". + +## Scripting changes from the command-line + +Today, it is possible to deploy a model directly from the command-line. Similarly, it should be possible to pipe in a .cs file, containing a C# script to be executed on the model. After script execution, it should be possible to save or deploy the updated model. This requires a few changes to the current command-line options. + +**Update**: As of 2.3, scripts can be executed from the command-line, by using the "-S" switch. Deployment works as usual, but if you want to save the modified model as a .bim, you can use the "-B" switch. + +## Possibility to read/edit more object types + +Tabular Editor currently only lets end-users read and edit a subset of the objects in the Tabular Object Model. It is desirable to allow all objects in the model tree, to be accessible in Tabular Editor: Relationships, KPIs, Calculated Tables and Roles should be directly editable. Data Sources, tables, data columns and table partitions should be editable with some constraints (for example, we should not expect Tabular Editor to be able to fetch data schemas from arbitrary data sources and queries). + +**Update**: As of 2.1, many new object types are now visible directly in the Tree Explorer. Using the right-click menu, you can create, duplicate and delete many of these objects (roles, perspectives, translations). We're still lacking support for creating/deleting relationships and data sources, but this will come in a future release. + +**Update**: As of 2.2, we can now create and delete relationships. More object types comming later. + +**Update**: As of 2.3, tables, partitions and data columns can now be edited. Visual Studio is now only needed to create the blank model itself - everything else can be done in Tabular Editor. + +**Update**: Previous update was a lie! I forgot about KPIs - but they can now be created/edited/deleted as of version 2.4. + +## Split a Model.bim into multiple json files + +The layout and structure of the Model.bim file, makes it horrible for purposes of source control and versioning. Not only is the entire Tabular Object Model written into just one file, the file also contains "ModifiedTime" information everywhere in the structure, making source control DIFF operations useless. + +For better release management workflows with Tabular Models, it would be interesting if Tabular Editor could save/load a Model.bim file as a folder structure with individual files for measures, calculated columns, etc. There should be command-line options available for exporting/importing Model.bim files from/to this format, and it should be possible to deploy directly from this format (in cases where you don't need the Model.bim file itself). These individual files should contain the same JSON as the Model.bim file, but without the "ModifiedTime" information, so that they can easily be used in a version control system, allowing multiple developers to work on the same model at once. + +**Update**: [Available in 2.2](/Advanced-features#folder-serialization). + +**Update**: As of 2.3, options exist to store Perspective and Translation metadata as annotations on the individual objects. This is useful for source control scenarios with multiple developers, to avoid having single files that gets lots of edits when developers change translations, perspective memberships, etc. + +## Power BI Compatibility + +Today, it is already possible to connect Tabular Editor to a model hosted by Power BI Desktop. The approach is similar to what is [described here for Excel and SSMS](http://biinsight.com/connect-to-power-bi-desktop-model-from-excel-and-ssms/). Doing this, it is actually possible to add Display Folders to the Power BI Desktop model, and they actually stay in Power BI, even after saving and reopening the .pbix file. However, it seems that there are some compatibility level issues, which should be looked into before proceeding. + +**Update**: As of 2.1, Tabular Editor now detects running instances of Power BI Desktop and Visual Studio Integrated Workspaces. You can connect to these instances and make changes as you would normal instances, although this approach of changing Power BI and Integrated Workspace models is not supported by Microsoft. + +## Import/Export translations + +This is a standard feature in SSDT, which would be useful to have in Tabular Editor as well. + +**Update**: [Available in 2.2](/Advanced-features#import-export-translations). diff --git a/content/localization/de/SQL-Server-2017-support_de.md b/content/localization/de/SQL-Server-2017-support_de.md new file mode 100644 index 00000000..c2ec8f4d --- /dev/null +++ b/content/localization/de/SQL-Server-2017-support_de.md @@ -0,0 +1,35 @@ +# SQL Server 2017 Support + +Starting from version 2.3, Tabular Editor now also supports SQL Server 2017 (Compatibility Level 1400). This means that the Tabular Editor UI exposes some of the new functionality described [here](https://blogs.msdn.microsoft.com/analysisservices/2017/04/19/whats-new-in-sql-server-2017-ctp-2-0-for-analysis-services/). + +Please note, however, that you need to download the [proper build of Tabular Editor](https://github.com/TabularEditor/TabularEditor/releases/tag/2.5-CL1400) to use these features. This is because a new set of client libraries are provided by Microsoft for SQL Server 2017 / SSDT 17.0, and these libs are incompatible with the SQL Server 2016-build of Tabular Editor. The new libraries can be obtained through the new [version of SSDT](https://docs.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt) (requires Visual Studio 2015). + +If you don't need Compatibility Level 1400 features, you can still use the SQL Server 2016-build of [Tabular Editor](https://github.com/TabularEditor/TabularEditor/releases/tag/2.5). + +Here is a quick rundown of how the new features are used in Tabular Editor: + +## Date Relationships + +All relationships now expose the "Join on Date Behavior" property in the property grid: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297821/9dd46be0-26f0-11e7-92bf-10a921ed20dc.png) + +## Variations (column/hierarchy reuse) + +You can set up variations on a column, by expanding the "Variations" property in the property grid: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297845/c69ecc5a-26f0-11e7-93af-b7a2a0cc9310.png) + +Note that you can also specify **Object Level Security** at the column level. + +Clicking the ellipsis button opens the Variations Collection Editor, from where you can set up how columns and hierarchies are resurfaced in Power BI: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297884/fd4faf58-26f0-11e7-9a1a-df7a1b05f663.png) + +Remember to set the "Show As Variations Only" property to "True" at the table level: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297917/2c1e4b64-26f1-11e7-8ce6-a62aef2b7d8a.png) + +**Detail Row Expressions** can be set directly on tables and measures. At this time, however, no syntax highlighting or IntelliSense is available. + +Hierarchy objects exposes a new **Hide Members** property that is useful for ragged hierarchies. diff --git a/content/localization/de/TabularEditor.TOMWrapper_de.md b/content/localization/de/TabularEditor.TOMWrapper_de.md new file mode 100644 index 00000000..1a349020 --- /dev/null +++ b/content/localization/de/TabularEditor.TOMWrapper_de.md @@ -0,0 +1,2354 @@ +# TabularEditor.TOMWrapper Reference + +This is auto-generated documentation for the TOMWrapper API. Use CTRL+F or the sidebar on the right, to locate a specific class, property or method. + +## `AddObjectType` + +```csharp +public enum TabularEditor.TOMWrapper.AddObjectType + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | ---------------- | ------- | +| `1` | Measure | | +| `2` | CalculatedColumn | | +| `3` | Hierarchy | | + +## `CalculatedColumn` + +Base class declaration for CalculatedColumn + +```csharp +public class TabularEditor.TOMWrapper.CalculatedColumn + : Column, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject, IExpressionObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | ------------------ | ---------------------------------------------------------------------------- | +| `Dictionary>` | Dependencies | | +| `String` | Expression | Gets or sets the Expression of the CalculatedColumn. | +| `Boolean` | IsDataTypeInferred | Gets or sets the IsDataTypeInferred of the CalculatedColumn. | +| `CalculatedColumn` | MetadataObject | | +| `Boolean` | NeedsValidation | | + +Methods + +| Type | Name | Summary | +| -------------------- | -------------------------------------------------------------------------------------------------------- | ------- | +| `TabularNamedObject` | Clone(`String` newName = null, `Boolean` includeTranslations = True) | | +| `TabularNamedObject` | CloneTo(`Table` table, `String` newName = null, `Boolean` includeTranslations = True) | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | + +## `CalculatedTable` + +```csharp +public class TabularEditor.TOMWrapper.CalculatedTable + : Table, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IHideableObject, IDescriptionObject, IAnnotationObject, ITabularObjectContainer, IDetailObjectContainer, ITabularPerspectiveObject, IDaxObject, IDynamicPropertyObject, IErrorMessageObject, IExpressionObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | --------------- | ------- | +| `Dictionary>` | Dependencies | | +| `String` | Expression | | +| `Boolean` | NeedsValidation | | +| `String` | ObjectTypeName | | + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `void` | CheckChildrenErrors() | | +| `Boolean` | Editable(`String` propertyName) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | ReinitColumns() | Call this method after the model is saved to a DB, to check for changed columns (in case of expression changes) | + +## `CalculatedTableColumn` + +Base class declaration for CalculatedTableColumn + +```csharp +public class TabularEditor.TOMWrapper.CalculatedTableColumn + : Column, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject + +``` + +Properties + +| Type | Name | Summary | +| ----------------------- | ------------------ | --------------------------------------------------------------------------------- | +| `Column` | ColumnOrigin | Gets or sets the ColumnOrigin of the CalculatedTableColumn. | +| `Boolean` | IsDataTypeInferred | Gets or sets the IsDataTypeInferred of the CalculatedTableColumn. | +| `Boolean` | IsNameInferred | Gets or sets the IsNameInferred of the CalculatedTableColumn. | +| `CalculatedTableColumn` | MetadataObject | | +| `String` | SourceColumn | Gets or sets the SourceColumn of the CalculatedTableColumn. | + +## `Column` + +Base class declaration for Column + +```csharp +public abstract class TabularEditor.TOMWrapper.Column + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `Alignment` | Alignment | Gets or sets the Alignment of the Column. | +| `String` | DataCategory | Gets or sets the DataCategory of the Column. | +| `DataType` | DataType | Gets or sets the DataType of the Column. | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | +| `String` | Description | Gets or sets the Description of the Column. | +| `String` | DisplayFolder | Gets or sets the DisplayFolder of the Column. | +| `Int32` | DisplayOrdinal | Gets or sets the DisplayOrdinal of the Column. | +| `String` | ErrorMessage | Gets or sets the ErrorMessage of the Column. | +| `String` | FormatString | Gets or sets the FormatString of the Column. | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsAvailableInMDX | Gets or sets the IsAvailableInMDX of the Column. | +| `Boolean` | IsDefaultImage | Gets or sets the IsDefaultImage of the Column. | +| `Boolean` | IsDefaultLabel | Gets or sets the IsDefaultLabel of the Column. | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Column. | +| `Boolean` | IsKey | Gets or sets the IsKey of the Column. | +| `Boolean` | IsNullable | Gets or sets the IsNullable of the Column. | +| `Boolean` | IsUnique | Gets or sets the IsUnique of the Column. | +| `Boolean` | KeepUniqueRows | Gets or sets the KeepUniqueRows of the Column. | +| `Column` | MetadataObject | | +| `Column` | SortByColumn | Gets or sets the SortByColumn of the Column. | +| `String` | SourceProviderType | Gets or sets the SourceProviderType of the Column. | +| `ObjectState` | State | Gets or sets the State of the Column. | +| `AggregateFunction` | SummarizeBy | Gets or sets the SummarizeBy of the Column. | +| `Table` | Table | | +| `Int32` | TableDetailPosition | Gets or sets the TableDetailPosition of the Column. | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Column. | +| `TranslationIndexer` | TranslatedDisplayFolders | Collection of localized Display Folders for this Column. | +| `ColumnType` | Type | Gets or sets the Type of the Column. | +| `IEnumerable` | UsedInHierarchies | Enumerates all hierarchies in which this column is used as a level. | +| `IEnumerable` | UsedInRelationships | Enumerates all relationships in which this column participates (either as or ). | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `void` | Delete() | | +| `String` | GetAnnotation(`String` name) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `ColumnCollection` + +Collection class for Column. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.ColumnCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------------------- | ------------------- | ------- | +| `Alignment` | Alignment | | +| `String` | DataCategory | | +| `DataType` | DataType | | +| `String` | Description | | +| `String` | DisplayFolder | | +| `Int32` | DisplayOrdinal | | +| `String` | FormatString | | +| `Boolean` | IsAvailableInMDX | | +| `Boolean` | IsDefaultImage | | +| `Boolean` | IsDefaultLabel | | +| `Boolean` | IsHidden | | +| `Boolean` | IsKey | | +| `Boolean` | IsNullable | | +| `Boolean` | IsUnique | | +| `Boolean` | KeepUniqueRows | | +| `Table` | Parent | | +| `Column` | SortByColumn | | +| `String` | SourceProviderType | | +| `AggregateFunction` | SummarizeBy | | +| `Int32` | TableDetailPosition | | + +Methods + +| Type | Name | Summary | +| --------------------- | ---------------------------------- | ------- | +| `IEnumerator` | GetEnumerator() | | +| `String` | ToString() | | + +## `Culture` + +Base class declaration for Culture + +```csharp +public class TabularEditor.TOMWrapper.Culture + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| ----------------------------- | ---------------------------- | ------- | +| `String` | DisplayName | | +| `Culture` | MetadataObject | | +| `String` | Name | | +| `ObjectTranslationCollection` | ObjectTranslations | | +| `String` | StatsColumnCaptions | | +| `String` | StatsColumnDisplayFolders | | +| `String` | StatsHierarchyCaptions | | +| `String` | StatsHierarchyDisplayFolders | | +| `String` | StatsLevelCaptions | | +| `String` | StatsMeasureCaptions | | +| `String` | StatsMeasureDisplayFolders | | +| `String` | StatsTableCaptions | | +| `Boolean` | Unassigned | | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `CultureCollection` + +Collection class for Culture. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.CultureCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------- | ------ | ------- | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `CultureConverter` + +```csharp +public class TabularEditor.TOMWrapper.CultureConverter + : TypeConverter + +``` + +Methods + +| Type | Name | Summary | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | CanConvertFrom(`ITypeDescriptorContext` context, `Type` sourceType) | | +| `Boolean` | CanConvertTo(`ITypeDescriptorContext` context, `Type` destinationType) | | +| `Object` | ConvertFrom(`ITypeDescriptorContext` context, `CultureInfo` culture, `Object` value) | | +| `Object` | ConvertTo(`ITypeDescriptorContext` context, `CultureInfo` culture, `Object` value, `Type` destinationType) | | +| `StandardValuesCollection` | GetStandardValues(`ITypeDescriptorContext` context) | | +| `Boolean` | GetStandardValuesExclusive(`ITypeDescriptorContext` context) | | +| `Boolean` | GetStandardValuesSupported(`ITypeDescriptorContext` context) | | + +## `Database` + +```csharp +public class TabularEditor.TOMWrapper.Database + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------ | ------- | +| `Nullable` | CompatibilityLevel | | +| `Nullable` | CreatedTimestamp | | +| `String` | ID | | +| `Nullable` | LastProcessed | | +| `Nullable` | LastSchemaUpdate | | +| `Nullable` | LastUpdate | | +| `String` | Name | | +| `String` | ServerName | | +| `String` | ServerVersion | | +| `Database` | TOMDatabase | | +| `Nullable` | Version | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `DataColumn` + +Base class declaration for DataColumn + +```csharp +public class TabularEditor.TOMWrapper.DataColumn + : Column, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject + +``` + +Properties + +| Type | Name | Summary | +| ------------ | -------------- | ---------------------------------------------------------------- | +| `DataColumn` | MetadataObject | | +| `String` | SourceColumn | Gets or sets the SourceColumn of the DataColumn. | + +## `DataSource` + +Base class declaration for DataSource + +```csharp +public abstract class TabularEditor.TOMWrapper.DataSource + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------------------------------------------------------------------------- | +| `String` | Description | Gets or sets the Description of the DataSource. | +| `DataSource` | MetadataObject | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this DataSource. | +| `DataSourceType` | Type | Gets or sets the Type of the DataSource. | + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------ | ------- | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `DataSourceCollection` + +Collection class for DataSource. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.DataSourceCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------- | ----------- | ------- | +| `String` | Description | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `Dependency` + +```csharp +public struct TabularEditor.TOMWrapper.Dependency + +``` + +Fields + +| Type | Name | Summary | +| --------- | -------------- | ------- | +| `Int32` | from | | +| `Boolean` | fullyQualified | | +| `Int32` | to | | + +## `DependencyHelper` + +```csharp +public static class TabularEditor.TOMWrapper.DependencyHelper + +``` + +Static Methods + +| Type | Name | Summary | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `void` | AddDep(this `IExpressionObject` target, `IDaxObject` dependsOn, `Int32` fromChar, `Int32` toChar, `Boolean` fullyQualified) | | +| `String` | NoQ(this `String` objectName, `Boolean` table = False) | Removes qualifiers such as ' ' and [ ] around a name. | + +## `DeploymentMode` + +```csharp +public enum TabularEditor.TOMWrapper.DeploymentMode + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | -------------- | ------- | +| `0` | CreateDatabase | | +| `1` | CreateOrAlter | | + +## `DeploymentOptions` + +```csharp +public class TabularEditor.TOMWrapper.DeploymentOptions + +``` + +Fields + +| Type | Name | Summary | +| ---------------- | ----------------- | ------- | +| `Boolean` | DeployConnections | | +| `DeploymentMode` | DeployMode | | +| `Boolean` | DeployPartitions | | +| `Boolean` | DeployRoleMembers | | +| `Boolean` | DeployRoles | | + +Static Fields + +| Type | Name | Summary | +| ------------------- | ------------- | ------- | +| `DeploymentOptions` | Default | | +| `DeploymentOptions` | StructureOnly | | + +## `DeploymentResult` + +```csharp +public class TabularEditor.TOMWrapper.DeploymentResult + +``` + +Fields + +| Type | Name | Summary | +| ----------------------- | -------- | ------- | +| `IReadOnlyList` | Issues | | +| `IReadOnlyList` | Warnings | | + +## `DeploymentStatus` + +```csharp +public enum TabularEditor.TOMWrapper.DeploymentStatus + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | --------------- | ------- | +| `0` | ChangesSaved | | +| `1` | DeployComplete | | +| `2` | DeployCancelled | | + +## `Folder` + +Represents a Folder in the TreeView. Does not correspond to any object in the TOM. Implements IDisplayFolderObject since a Folder can itself be located within another display folder. Implements IParentObject since a Folder can contain child objects. + +```csharp +public class TabularEditor.TOMWrapper.Folder + : IDetailObject, ITabularTableObject, ITabularNamedObject, ITabularObject, INotifyPropertyChanged, ITabularObjectContainer, IDetailObjectContainer, IErrorMessageObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------ | ------------------------ | ------- | +| `IDetailObjectContainer` | Container | | +| `Culture` | Culture | | +| `String` | DisplayFolder | | +| `String` | ErrorMessage | | +| `String` | FullPath | | +| `TabularModelHandler` | Handler | | +| `Int32` | MetadataIndex | | +| `Model` | Model | | +| `String` | Name | | +| `ObjectType` | ObjectType | | +| `Table` | ParentTable | | +| `String` | Path | | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDisplayFolders | | +| `TranslationIndexer` | TranslatedNames | | + +Events + +| Type | Name | Summary | +| ----------------------------- | --------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | CheckChildrenErrors() | | +| `void` | Delete() | Deleting a folder does not delete child objects - it just removes the folder. Any child folders are retained (but will be moved up the display folder hierarchy). | +| `IEnumerable` | GetChildren() | | +| `IEnumerable` | GetChildrenByFolders(`Boolean` recursive = False) | | +| `void` | SetFolderName(`String` newName) | | +| `void` | UndoSetPath(`String` value) | | + +Static Methods + +| Type | Name | Summary | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `Folder` | CreateFolder(`Table` table, `String` path = , `Boolean` useFixedCulture = False, `Culture` fixedCulture = null) | | + +## `FolderHelper` + +```csharp +public static class TabularEditor.TOMWrapper.FolderHelper + +``` + +Static Methods + +| Type | Name | Summary | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------- | ------- | +| `String` | ConcatPath(this `String` path, `String` additionalPath) | | +| `String` | ConcatPath(this `IEnumerable` pathBits) | | +| `IDetailObjectContainer` | GetContainer(this `IDetailObject` obj) | | +| `String` | GetDisplayFolder(this `IDetailObject` folderObject, `Culture` culture) | | +| `String` | GetFullPath(`ITabularNamedObject` obj) | | +| `Boolean` | HasAncestor(this `IDetailObject` child, `ITabularNamedObject` ancestor, `Culture` culture) | | +| `Boolean` | HasParent(this `IDetailObject` child, `ITabularNamedObject` parent, `Culture` culture) | | +| `Int32` | Level(this `String` path) | | +| `String` | PathFromFullPath(`String` path) | | +| `void` | SetDisplayFolder(this `IDetailObject` folderObject, `String` newFolderName, `Culture` culture) | | +| `String` | TrimFolder(this `String` folderPath) | | + +## `Hierarchy` + +Base class declaration for Hierarchy + +```csharp +public class TabularEditor.TOMWrapper.Hierarchy + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IDescriptionObject, IAnnotationObject, ITabularObjectContainer, ITabularPerspectiveObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------------ | ------------------------------------------------------------------------------------------- | +| `String` | Description | Gets or sets the Description of the Hierarchy. | +| `String` | DisplayFolder | Gets or sets the DisplayFolder of the Hierarchy. | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Hierarchy. | +| `LevelCollection` | Levels | | +| `Hierarchy` | MetadataObject | | +| `Boolean` | Reordering | Set to true, when multiple levels are going to be re-ordered as one action. | +| `ObjectState` | State | Gets or sets the State of the Hierarchy. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Hierarchy. | +| `TranslationIndexer` | TranslatedDisplayFolders | Collection of localized Display Folders for this Hierarchy. | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | ------------------------------------------------------------------------------------------------- | ------- | +| `Level` | AddLevel(`Column` column, `String` levelName = null, `Int32` ordinal = -1) | | +| `Level` | AddLevel(`String` columnName, `String` levelName = null, `Int32` ordinal = -1) | | +| `void` | AddLevels(`IEnumerable` columns, `Int32` ordinal = -1) | | +| `void` | CompactLevelOrdinals() | | +| `void` | Delete() | | +| `void` | FixLevelOrder(`Level` level, `Int32` newOrdinal) | | +| `String` | GetAnnotation(`String` name) | | +| `IEnumerable` | GetChildren() | | +| `void` | Init() | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | SetLevelOrder(`IList` order) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `HierarchyCollection` + +Collection class for Hierarchy. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.HierarchyCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ------------- | ------- | +| `String` | Description | | +| `String` | DisplayFolder | | +| `Boolean` | IsHidden | | +| `Table` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `HierarchyColumnConverter` + +```csharp +public class TabularEditor.TOMWrapper.HierarchyColumnConverter + : TableColumnConverter + +``` + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------- | ------- | +| `Boolean` | GetStandardValuesExclusive(`ITypeDescriptorContext` context) | | +| `Boolean` | IsValid(`ITypeDescriptorContext` context, `Object` value) | | + +## `IAnnotationObject` + +```csharp +public interface TabularEditor.TOMWrapper.IAnnotationObject + : ITabularObject, INotifyPropertyChanged + +``` + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------ | ------- | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `IClonableObject` + +```csharp +public interface TabularEditor.TOMWrapper.IClonableObject + +``` + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------- | ------- | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | + +## `IDaxObject` + +```csharp +public interface TabularEditor.TOMWrapper.IDaxObject + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | ----------------- | ------- | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | + +## `IDescriptionObject` + +Objects that can have descriptions + +```csharp +public interface TabularEditor.TOMWrapper.IDescriptionObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------- | +| `String` | Description | | +| `TranslationIndexer` | TranslatedDescriptions | | + +## `IDetailObject` + +Represents an object than can be contained in a Display Folder. Examples: - Measures - Columns - Hierarchies - Folders + +```csharp +public interface TabularEditor.TOMWrapper.IDetailObject + : ITabularTableObject, ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------------ | ------- | +| `String` | DisplayFolder | | +| `TranslationIndexer` | TranslatedDisplayFolders | | + +## `IDetailObjectContainer` + +Represents an objects that can contain other objects as well as display folders. Examples: - Folders - Table + +```csharp +public interface TabularEditor.TOMWrapper.IDetailObjectContainer + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------- | ----------- | ------- | +| `Table` | ParentTable | | + +Methods + +| Type | Name | Summary | +| ---------------------------- | -------------------------------------------------------------------- | ------- | +| `IEnumerable` | GetChildrenByFolders(`Boolean` recursive = False) | | + +## `IErrorMessageObject` + +Objects that can have error messages + +```csharp +public interface TabularEditor.TOMWrapper.IErrorMessageObject + +``` + +Properties + +| Type | Name | Summary | +| -------- | ------------ | ------- | +| `String` | ErrorMessage | | + +## `IExpressionObject` + +```csharp +public interface TabularEditor.TOMWrapper.IExpressionObject + : IDaxObject, ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | --------------- | ------- | +| `Dictionary>` | Dependencies | | +| `String` | Expression | | +| `Boolean` | NeedsValidation | | + +## `IHideableObject` + +Objects that can be shown/hidden + +```csharp +public interface TabularEditor.TOMWrapper.IHideableObject + +``` + +Properties + +| Type | Name | Summary | +| --------- | -------- | ------- | +| `Boolean` | IsHidden | | + +## `IntelliSenseAttribute` + +```csharp +public class TabularEditor.TOMWrapper.IntelliSenseAttribute + : Attribute, _Attribute + +``` + +Properties + +| Type | Name | Summary | +| -------- | ----------- | ------- | +| `String` | Description | | + +## `ITabularNamedObject` + +```csharp +public interface TabularEditor.TOMWrapper.ITabularNamedObject + : ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | --------------- | ------- | +| `Int32` | MetadataIndex | | +| `String` | Name | | +| `TranslationIndexer` | TranslatedNames | | + +## `ITabularObject` + +```csharp +public interface TabularEditor.TOMWrapper.ITabularObject + : INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------------ | ---------- | ------- | +| `Model` | Model | | +| `ObjectType` | ObjectType | | + +## `ITabularObjectCollection` + +```csharp +public interface TabularEditor.TOMWrapper.ITabularObjectCollection + : IEnumerable + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | -------------- | ------- | +| `String` | CollectionName | | +| `TabularModelHandler` | Handler | | +| `IEnumerable` | Keys | | + +Methods + +| Type | Name | Summary | +| -------------------------- | ---------------------------------------------------- | ------- | +| `void` | Add(`TabularNamedObject` obj) | | +| `void` | Clear() | | +| `Boolean` | Contains(`Object` value) | | +| `Boolean` | Contains(`String` key) | | +| `ITabularObjectCollection` | GetCurrentCollection() | | +| `Int32` | IndexOf(`TabularNamedObject` obj) | | +| `void` | Remove(`TabularNamedObject` obj) | | + +## `ITabularObjectContainer` + +TabularObjects that can contain other objects should use this interface. + +```csharp +public interface TabularEditor.TOMWrapper.ITabularObjectContainer + +``` + +Methods + +| Type | Name | Summary | +| ---------------------------------- | -------------------------------- | ------- | +| `IEnumerable` | GetChildren() | | + +## `ITabularPerspectiveObject` + +Objects that can be shown/hidden in individual perspectives + +```csharp +public interface TabularEditor.TOMWrapper.ITabularPerspectiveObject + : IHideableObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------- | ------- | +| `PerspectiveIndexer` | InPerspective | | + +## `ITabularTableObject` + +Object that belongs to a specific table. + +```csharp +public interface TabularEditor.TOMWrapper.ITabularTableObject + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------- | ----- | ------- | +| `Table` | Table | | + +Methods + +| Type | Name | Summary | +| ------ | --------------------------- | ------- | +| `void` | Delete() | | + +## `KPI` + +Base class declaration for KPI + +```csharp +public class TabularEditor.TOMWrapper.KPI + : TabularObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, IDescriptionObject, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------------------------------------------------------------------ | +| `String` | Description | Gets or sets the Description of the KPI. | +| `Measure` | Measure | Gets or sets the Measure of the KPI. | +| `KPI` | MetadataObject | | +| `String` | StatusDescription | Gets or sets the StatusDescription of the KPI. | +| `String` | StatusExpression | Gets or sets the StatusExpression of the KPI. | +| `String` | StatusGraphic | Gets or sets the StatusGraphic of the KPI. | +| `String` | TargetDescription | Gets or sets the TargetDescription of the KPI. | +| `String` | TargetExpression | Gets or sets the TargetExpression of the KPI. | +| `String` | TargetFormatString | Gets or sets the TargetFormatString of the KPI. | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this KPI. | +| `String` | TrendDescription | Gets or sets the TrendDescription of the KPI. | +| `String` | TrendExpression | Gets or sets the TrendExpression of the KPI. | +| `String` | TrendGraphic | Gets or sets the TrendGraphic of the KPI. | + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------ | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `Level` + +Base class declaration for Level + +```csharp +public class TabularEditor.TOMWrapper.Level + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject, ITabularTableObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | -------------------------------------------------------------------- | +| `Column` | Column | Gets or sets the Column of the Level. | +| `String` | Description | Gets or sets the Description of the Level. | +| `Hierarchy` | Hierarchy | Gets or sets the Hierarchy of the Level. | +| `Level` | MetadataObject | | +| `Int32` | Ordinal | Gets or sets the Ordinal of the Level. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Level. | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| `void` | Delete() | Deletes the level from the hierarchy. | +| `String` | GetAnnotation(`String` name) | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `LevelCollection` + +Collection class for Level. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.LevelCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ----------- | ----------- | ------- | +| `String` | Description | | +| `Hierarchy` | Parent | | + +Methods + +| Type | Name | Summary | +| --------- | --------------------------------------- | ------- | +| `void` | Add(`Level` item) | | +| `Boolean` | Remove(`Level` item) | | +| `String` | ToString() | | + +## `LogicalGroup` + +```csharp +public class TabularEditor.TOMWrapper.LogicalGroup + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged, ITabularObjectContainer + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | --------------- | ------- | +| `Int32` | MetadataIndex | | +| `Model` | Model | | +| `String` | Name | | +| `ObjectType` | ObjectType | | +| `TranslationIndexer` | TranslatedNames | | + +Events + +| Type | Name | Summary | +| ----------------------------- | --------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | -------------------------------- | ------- | +| `IEnumerable` | GetChildren() | | + +## `LogicalTreeOptions` + +```csharp +public enum TabularEditor.TOMWrapper.LogicalTreeOptions + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | -------------- | ------- | +| `1` | DisplayFolders | | +| `2` | Columns | | +| `4` | Measures | | +| `8` | KPIs | | +| `16` | Hierarchies | | +| `32` | Levels | | +| `64` | ShowHidden | | +| `128` | AllObjectTypes | | +| `256` | ShowRoot | | +| `447` | Default | | + +## `Measure` + +Base class declaration for Measure + +```csharp +public class TabularEditor.TOMWrapper.Measure + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IExpressionObject, IDaxObject, IAnnotationObject, ITabularPerspectiveObject, IDynamicPropertyObject, IClonableObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | ------------------------ | ------------------------------------------------------------------------- | +| `DataType` | DataType | Gets or sets the DataType of the Measure. | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | +| `Dictionary>` | Dependencies | | +| `String` | Description | Gets or sets the Description of the Measure. | +| `String` | DisplayFolder | Gets or sets the DisplayFolder of the Measure. | +| `String` | ErrorMessage | Gets or sets the ErrorMessage of the Measure. | +| `String` | Expression | Gets or sets the Expression of the Measure. | +| `String` | FormatString | Gets or sets the FormatString of the Measure. | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Measure. | +| `Boolean` | IsSimpleMeasure | Gets or sets the IsSimpleMeasure of the Measure. | +| `KPI` | KPI | Gets or sets the KPI of the Measure. | +| `Measure` | MetadataObject | | +| `Boolean` | NeedsValidation | | +| `ObjectState` | State | Gets or sets the State of the Measure. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Measure. | +| `TranslationIndexer` | TranslatedDisplayFolders | Collection of localized Display Folders for this Measure. | + +Methods + +| Type | Name | Summary | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `TabularNamedObject` | Clone(`String` newName = null, `Boolean` includeTranslations = True) | | +| `TabularNamedObject` | CloneTo(`Table` table, `String` newName = null, `Boolean` includeTranslations = True) | | +| `void` | Delete() | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `MeasureCollection` + +Collection class for Measure. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.MeasureCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | --------------- | ------- | +| `String` | Description | | +| `String` | DisplayFolder | | +| `String` | Expression | | +| `String` | FormatString | | +| `Boolean` | IsHidden | | +| `Boolean` | IsSimpleMeasure | | +| `KPI` | KPI | | +| `Table` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `Model` + +Base class declaration for Model + +```csharp +public class TabularEditor.TOMWrapper.Model + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject, ITabularObjectContainer + +``` + +Fields + +| Type | Name | Summary | +| -------------- | ------------------ | ------- | +| `LogicalGroup` | GroupDataSources | | +| `LogicalGroup` | GroupPerspectives | | +| `LogicalGroup` | GroupRelationships | | +| `LogicalGroup` | GroupRoles | | +| `LogicalGroup` | GroupTables | | +| `LogicalGroup` | GroupTranslations | | + +Properties + +| Type | Name | Summary | +| --------------------------- | ---------------------- | -------------------------------------------------------------------- | +| `IEnumerable` | AllColumns | | +| `IEnumerable` | AllHierarchies | | +| `IEnumerable` | AllLevels | | +| `IEnumerable` | AllMeasures | | +| `String` | Collation | Gets or sets the Collation of the Model. | +| `String` | Culture | Gets or sets the Culture of the Model. | +| `CultureCollection` | Cultures | | +| `Database` | Database | | +| `DataSourceCollection` | DataSources | | +| `DataViewType` | DefaultDataView | Gets or sets the DefaultDataView of the Model. | +| `ModeType` | DefaultMode | Gets or sets the DefaultMode of the Model. | +| `String` | Description | Gets or sets the Description of the Model. | +| `Boolean` | HasLocalChanges | Gets or sets the HasLocalChanges of the Model. | +| `IEnumerable` | LogicalChildGroups | | +| `Model` | MetadataObject | | +| `PerspectiveCollection` | Perspectives | | +| `RelationshipCollection2` | Relationships | | +| `ModelRoleCollection` | Roles | | +| `String` | StorageLocation | Gets or sets the StorageLocation of the Model. | +| `TableCollection` | Tables | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Model. | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | ------------------------------------------------------------------------------------------ | ------- | +| `CalculatedTable` | AddCalculatedTable() | | +| `Perspective` | AddPerspective(`String` name = null) | | +| `SingleColumnRelationship` | AddRelationship() | | +| `ModelRole` | AddRole(`String` name = null) | | +| `Table` | AddTable() | | +| `Culture` | AddTranslation(`String` cultureId) | | +| `String` | GetAnnotation(`String` name) | | +| `IEnumerable` | GetChildren() | | +| `void` | Init() | | +| `void` | LoadChildObjects() | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `ModelRole` + +Base class declaration for ModelRole + +```csharp +public class TabularEditor.TOMWrapper.ModelRole + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------------------------------------------------------------------------ | +| `String` | Description | Gets or sets the Description of the ModelRole. | +| `ModelRole` | MetadataObject | | +| `ModelPermission` | ModelPermission | Gets or sets the ModelPermission of the ModelRole. | +| `RoleRLSIndexer` | RowLevelSecurity | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this ModelRole. | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------------------------ | ------- | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `void` | Delete() | | +| `String` | GetAnnotation(`String` name) | | +| `void` | InitRLSIndexer() | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `ModelRoleCollection` + +Collection class for ModelRole. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.ModelRoleCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ----------------- | --------------- | ------- | +| `String` | Description | | +| `ModelPermission` | ModelPermission | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `NullTree` + +```csharp +public class TabularEditor.TOMWrapper.NullTree + : TabularTree, INotifyPropertyChanged + +``` + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------------- | ------- | +| `void` | OnNodesChanged(`ITabularObject` nodeItem) | | +| `void` | OnNodesInserted(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnNodesRemoved(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnStructureChanged(`ITabularNamedObject` obj = null) | | + +## `ObjectOrder` + +```csharp +public enum TabularEditor.TOMWrapper.ObjectOrder + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | ------------ | ------- | +| `0` | Alphabetical | | +| `1` | Metadata | | + +## `ObjectType` + +```csharp +public enum TabularEditor.TOMWrapper.ObjectType + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ------ | -------------------- | ------- | +| `-2` | Group | | +| `-1` | Folder | | +| `1` | Model | | +| `2` | DataSource | | +| `3` | Table | | +| `4` | Column | | +| `5` | AttributeHierarchy | | +| `6` | Partition | | +| `7` | Relationship | | +| `8` | Measure | | +| `9` | Hierarchy | | +| `10` | Level | | +| `11` | Annotation | | +| `12` | KPI | | +| `13` | Culture | | +| `14` | ObjectTranslation | | +| `15` | LinguisticMetadata | | +| `29` | Perspective | | +| `30` | PerspectiveTable | | +| `31` | PerspectiveColumn | | +| `32` | PerspectiveHierarchy | | +| `33` | PerspectiveMeasure | | +| `34` | Role | | +| `35` | RoleMembership | | +| `36` | TablePermission | | +| `1000` | Database | | + +## `Partition` + +Base class declaration for Partition + +```csharp +public class TabularEditor.TOMWrapper.Partition + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDynamicPropertyObject, IErrorMessageObject, ITabularTableObject, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | ---------------------- | ------------------------------------------------------------------------ | +| `DataSource` | DataSource | | +| `DataViewType` | DataView | Gets or sets the DataView of the Partition. | +| `String` | Description | Gets or sets the Description of the Partition. | +| `String` | ErrorMessage | Gets or sets the ErrorMessage of the Partition. | +| `String` | Expression | | +| `Partition` | MetadataObject | | +| `ModeType` | Mode | Gets or sets the Mode of the Partition. | +| `String` | Name | | +| `String` | Query | | +| `DateTime` | RefreshedTime | | +| `String` | Source | | +| `PartitionSourceType` | SourceType | Gets or sets the SourceType of the Partition. | +| `ObjectState` | State | Gets or sets the State of the Partition. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Partition. | + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------ | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `PartitionCollection` + +Collection class for Partition. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.PartitionCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------------- | ----------- | ------- | +| `DataViewType` | DataView | | +| `String` | Description | | +| `ModeType` | Mode | | +| `Table` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `Perspective` + +Base class declaration for Perspective + +```csharp +public class TabularEditor.TOMWrapper.Perspective + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | -------------------------------------------------------------------------- | +| `String` | Description | Gets or sets the Description of the Perspective. | +| `Perspective` | MetadataObject | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Perspective. | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------------------------ | ------- | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `void` | Delete() | | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `PerspectiveCollection` + +Collection class for Perspective. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------- | ----------- | ------- | +| `String` | Description | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `PerspectiveColumnIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveColumnIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------- | ------ | ------- | +| `Column` | Column | | + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------- | ------- | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveHierarchyIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveHierarchyIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ----------- | --------- | ------- | +| `Hierarchy` | Hierarchy | | + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------- | ------- | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveIndexer` + +```csharp +public abstract class TabularEditor.TOMWrapper.PerspectiveIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Fields + +| Type | Name | Summary | +| -------------------- | ------------- | ------- | +| `TabularNamedObject` | TabularObject | | + +Properties + +| Type | Name | Summary | +| ---------------------------------- | -------------- | ------- | +| `Boolean` | Item | | +| `Boolean` | Item | | +| `IEnumerable` | Keys | | +| `Dictionary` | PerspectiveMap | | +| `String` | Summary | | + +Methods + +| Type | Name | Summary | +| ----------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `void` | All() | Includes the object in all perspectives. | +| `Dictionary` | Copy() | | +| `void` | CopyFrom(`PerspectiveIndexer` source) | | +| `void` | CopyFrom(`IDictionary` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | None() | | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveMeasureIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveMeasureIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ------- | ------- | +| `Measure` | Measure | | + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------- | ------- | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveTableIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveTableIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ----- | ------- | +| `Boolean` | Item | | +| `Table` | Table | | + +Methods + +| Type | Name | Summary | +| ------------------ | ---------------------------------------------------------------------------------- | ------- | +| `PerspectiveTable` | EnsurePTExists(`Perspective` perspective) | | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `ProviderDataSource` + +Base class declaration for ProviderDataSource + +```csharp +public class TabularEditor.TOMWrapper.ProviderDataSource + : DataSource, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | ----------------- | ----------------------------------------------------------------------------- | +| `String` | Account | Gets or sets the Account of the ProviderDataSource. | +| `String` | ConnectionString | Gets or sets the ConnectionString of the ProviderDataSource. | +| `ImpersonationMode` | ImpersonationMode | Gets or sets the ImpersonationMode of the ProviderDataSource. | +| `DatasourceIsolation` | Isolation | Gets or sets the Isolation of the ProviderDataSource. | +| `Boolean` | IsPowerBIMashup | | +| `String` | Location | | +| `Int32` | MaxConnections | Gets or sets the MaxConnections of the ProviderDataSource. | +| `ProviderDataSource` | MetadataObject | | +| `String` | MQuery | | +| `String` | Name | | +| `String` | Password | Gets or sets the Password of the ProviderDataSource. | +| `String` | Provider | Gets or sets the Provider of the ProviderDataSource. | +| `String` | SourceID | | +| `Int32` | Timeout | Gets or sets the Timeout of the ProviderDataSource. | + +Methods + +| Type | Name | Summary | +| --------- | --------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `Boolean` | Editable(`String` propertyName) | | +| `void` | Init() | | + +## `Relationship` + +Base class declaration for Relationship + +```csharp +public abstract class TabularEditor.TOMWrapper.Relationship + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------ | -------------------------- | -------------------------------------------------------------------------------- | +| `CrossFilteringBehavior` | CrossFilteringBehavior | Gets or sets the CrossFilteringBehavior of the Relationship. | +| `Table` | FromTable | Gets or sets the FromTable of the Relationship. | +| `Boolean` | IsActive | Gets or sets the IsActive of the Relationship. | +| `DateTimeRelationshipBehavior` | JoinOnDateBehavior | Gets or sets the JoinOnDateBehavior of the Relationship. | +| `Relationship` | MetadataObject | | +| `Boolean` | RelyOnReferentialIntegrity | Gets or sets the RelyOnReferentialIntegrity of the Relationship. | +| `SecurityFilteringBehavior` | SecurityFilteringBehavior | Gets or sets the SecurityFilteringBehavior of the Relationship. | +| `ObjectState` | State | Gets or sets the State of the Relationship. | +| `Table` | ToTable | Gets or sets the ToTable of the Relationship. | +| `RelationshipType` | Type | Gets or sets the Type of the Relationship. | + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------ | ------- | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `RelationshipCollection` + +Collection class for Relationship. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.RelationshipCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------ | -------------------------- | ------- | +| `CrossFilteringBehavior` | CrossFilteringBehavior | | +| `Boolean` | IsActive | | +| `DateTimeRelationshipBehavior` | JoinOnDateBehavior | | +| `Model` | Parent | | +| `Boolean` | RelyOnReferentialIntegrity | | +| `SecurityFilteringBehavior` | SecurityFilteringBehavior | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `RelationshipCollection2` + +```csharp +public class TabularEditor.TOMWrapper.RelationshipCollection2 + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------ | -------------------------- | ------- | +| `CrossFilteringBehavior` | CrossFilteringBehavior | | +| `Boolean` | IsActive | | +| `DateTimeRelationshipBehavior` | JoinOnDateBehavior | | +| `Model` | Parent | | +| `Boolean` | RelyOnReferentialIntegrity | | +| `SecurityFilteringBehavior` | SecurityFilteringBehavior | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `RoleRLSIndexer` + +The RoleRLSIndexer is used to browse all filters across all tables in the model, for one specific role. This is in contrast to the TableRLSIndexer, which browses the filters across all roles in the model, for one specific table. + +```csharp +public class TabularEditor.TOMWrapper.RoleRLSIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Fields + +| Type | Name | Summary | +| ----------- | ---- | ------- | +| `ModelRole` | Role | | + +Properties + +| Type | Name | Summary | +| --------------------------- | ------- | ------- | +| `String` | Item | | +| `String` | Item | | +| `IEnumerable` | Keys | | +| `Dictionary` | RLSMap | | +| `String` | Summary | | + +Methods + +| Type | Name | Summary | +| --------------------- | ------------------------------------------------------------------- | ------- | +| `void` | Clear() | | +| `void` | CopyFrom(`RoleRLSIndexer` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | Refresh() | | +| `void` | SetRLS(`Table` table, `String` filterExpression) | | + +## `SerializeOptions` + +```csharp +public class TabularEditor.TOMWrapper.SerializeOptions + +``` + +Fields + +| Type | Name | Summary | +| ----------------- | ------------------------ | ------- | +| `Boolean` | IgnoreInferredObjects | | +| `Boolean` | IgnoreInferredProperties | | +| `Boolean` | IgnoreTimestamps | | +| `HashSet` | Levels | | +| `Boolean` | PrefixFilenames | | +| `Boolean` | SplitMultilineStrings | | + +Static Properties + +| Type | Name | Summary | +| ------------------ | ------- | ------- | +| `SerializeOptions` | Default | | + +## `SingleColumnRelationship` + +Base class declaration for SingleColumnRelationship + +```csharp +public class TabularEditor.TOMWrapper.SingleColumnRelationship + : Relationship, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | --------------- | --------------------------------------------------------------------------------- | +| `RelationshipEndCardinality` | FromCardinality | Gets or sets the FromCardinality of the SingleColumnRelationship. | +| `Column` | FromColumn | Gets or sets the FromColumn of the SingleColumnRelationship. | +| `SingleColumnRelationship` | MetadataObject | | +| `String` | Name | | +| `RelationshipEndCardinality` | ToCardinality | Gets or sets the ToCardinality of the SingleColumnRelationship. | +| `Column` | ToColumn | Gets or sets the ToColumn of the SingleColumnRelationship. | + +Methods + +| Type | Name | Summary | +| --------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `void` | Delete() | | +| `Boolean` | Editable(`String` propertyName) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `String` | ToString() | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `Table` + +Base class declaration for Table + +```csharp +public class TabularEditor.TOMWrapper.Table + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IHideableObject, IDescriptionObject, IAnnotationObject, ITabularObjectContainer, IDetailObjectContainer, ITabularPerspectiveObject, IDaxObject, IDynamicPropertyObject, IErrorMessageObject + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | ---------------------- | -------------------------------------------------------------------- | +| `IEnumerable` | AllLevels | | +| `ColumnCollection` | Columns | | +| `String` | DataCategory | Gets or sets the DataCategory of the Table. | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | +| `String` | Description | Gets or sets the Description of the Table. | +| `String` | ErrorMessage | | +| `HierarchyCollection` | Hierarchies | | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Table. | +| `MeasureCollection` | Measures | | +| `Table` | MetadataObject | | +| `String` | Name | | +| `Table` | ParentTable | | +| `PartitionCollection` | Partitions | | +| `TableRLSIndexer` | RowLevelSecurity | | +| `String` | Source | | +| `PartitionSourceType` | SourceType | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Table. | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `CalculatedColumn` | AddCalculatedColumn(`String` name = null, `String` expression = null, `String` displayFolder = null) | | +| `DataColumn` | AddDataColumn(`String` name = null, `String` sourceColumn = null, `String` displayFolder = null) | | +| `Hierarchy` | AddHierarchy(`String` name = null, `String` displayFolder = null, `Column[]` levels) | | +| `Hierarchy` | AddHierarchy(`String` name, `String` displayFolder = null, `String[]` levels) | | +| `Measure` | AddMeasure(`String` name = null, `String` expression = null, `String` displayFolder = null) | | +| `Boolean` | Browsable(`String` propertyName) | | +| `void` | CheckChildrenErrors() | | +| `void` | Children_CollectionChanged(`Object` sender, `NotifyCollectionChangedEventArgs` e) | | +| `TabularNamedObject` | Clone(`String` newName = null, `Boolean` includeTranslations = False) | | +| `void` | Delete() | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `IEnumerable` | GetChildren() | Returns all columns, measures and hierarchies inside this table. | +| `IEnumerable` | GetChildrenByFolders(`Boolean` recursive) | | +| `void` | Init() | | +| `void` | InitRLSIndexer() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +Static Fields + +| Type | Name | Summary | +| -------- | --------------------- | ------- | +| `Char[]` | InvalidTableNameChars | | + +## `TableCollection` + +Collection class for Table. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.TableCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable
, IList
, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ------------ | ------- | +| `String` | DataCategory | | +| `String` | Description | | +| `Boolean` | IsHidden | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `TableExtension` + +```csharp +public static class TabularEditor.TOMWrapper.TableExtension + +``` + +Static Methods + +| Type | Name | Summary | +| --------------------- | ---------------------------------------------------- | ------- | +| `PartitionSourceType` | GetSourceType(this `Table` table) | | + +## `TableRLSIndexer` + +The TableRLSIndexer is used to browse all filters defined on one specific table, across all roles in the model. This is in contrast to the RoleRLSIndexer, which browses the filters across all tables for one specific role. + +```csharp +public class TabularEditor.TOMWrapper.TableRLSIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Fields + +| Type | Name | Summary | +| ------- | ----- | ------- | +| `Table` | Table | | + +Properties + +| Type | Name | Summary | +| ------------------------------- | ------- | ------- | +| `String` | Item | | +| `String` | Item | | +| `IEnumerable` | Keys | | +| `Dictionary` | RLSMap | | +| `String` | Summary | | + +Methods + +| Type | Name | Summary | +| --------------------- | ---------------------------------------------------------------------- | ------- | +| `void` | Clear() | | +| `void` | CopyFrom(`TableRLSIndexer` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | Refresh() | | +| `void` | SetRLS(`ModelRole` role, `String` filterExpression) | | + +## `TabularCollectionHelper` + +```csharp +public static class TabularEditor.TOMWrapper.TabularCollectionHelper + +``` + +Static Methods + +| Type | Name | Summary | +| ------ | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `void` | InPerspective(this `IEnumerable
` tables, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` columns, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` hierarchies, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` measures, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable
` tables, `Perspective` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` columns, `Perspective` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` hierarchies, `Perspective` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` measures, `Perspective` perspective, `Boolean` value) | | +| `void` | SetDisplayFolder(this `IEnumerable` measures, `String` displayFolder) | | + +## `TabularCommonActions` + +Provides convenient methods for common actions on a Tabular Model, that often involve changing multiple objects at once. For example, these methods may be used to easily perform UI drag and drop operations that will change hierarchy levels, display folders, etc. + +```csharp +public class TabularEditor.TOMWrapper.TabularCommonActions + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | ------- | ------- | +| `TabularModelHandler` | Handler | | + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `void` | AddColumnsToHierarchy(`IEnumerable` columns, `Hierarchy` hierarchy, `Int32` firstOrdinal = -1) | | +| `Level` | AddColumnToHierarchy(`Column` column, `Hierarchy` hierarchy, `Int32` ordinal = -1) | | +| `void` | MoveObjects(`IEnumerable` objects, `Table` newTable, `Culture` culture) | | +| `String` | NewColumnName(`String` prefix, `Table` table) | | +| `String` | NewMeasureName(`String` prefix) | | +| `void` | ReorderLevels(`IEnumerable` levels, `Int32` firstOrdinal) | | +| `void` | SetContainer(`IEnumerable` objects, `IDetailObjectContainer` newContainer, `Culture` culture) | | + +## `TabularConnection` + +```csharp +public static class TabularEditor.TOMWrapper.TabularConnection + +``` + +Static Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------------- | ------- | +| `String` | GetConnectionString(`String` serverName) | | +| `String` | GetConnectionString(`String` serverName, `String` userName, `String` password) | | + +## `TabularCultureHelper` + +```csharp +public static class TabularEditor.TOMWrapper.TabularCultureHelper + +``` + +Static Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | ImportTranslations(`String` culturesJson, `Model` Model, `Boolean` overwriteExisting, `Boolean` haltOnError) | | + +## `TabularDeployer` + +```csharp +public class TabularEditor.TOMWrapper.TabularDeployer + +``` + +Static Methods + +| Type | Name | Summary | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | Deploy(`Database` db, `String` targetConnectionString, `String` targetDatabaseName) | Deploys the specified database to the specified target server and database ID, using the specified options. Returns a list of DAX errors (if any) on objects inside the database, in case the deployment was succesful. | +| `DeploymentResult` | Deploy(`Database` db, `String` targetConnectionString, `String` targetDatabaseID, `DeploymentOptions` options) | Deploys the specified database to the specified target server and database ID, using the specified options. Returns a list of DAX errors (if any) on objects inside the database, in case the deployment was succesful. | +| `String` | GetTMSL(`Database` db, `Server` server, `String` targetDatabaseID, `DeploymentOptions` options) | | +| `void` | SaveModelMetadataBackup(`String` connectionString, `String` targetDatabaseID, `String` backupFilePath) | | +| `void` | WriteZip(`String` fileName, `String` content) | | + +## `TabularModelHandler` + +```csharp +public class TabularEditor.TOMWrapper.TabularModelHandler + : IDisposable + +``` + +Fields + +| Type | Name | Summary | +| ---------------------------------------------- | ------------------ | ------- | +| `Dictionary` | WrapperCollections | | +| `Dictionary` | WrapperLookup | | + +Properties + +| Type | Name | Summary | +| ------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `TabularCommonActions` | Actions | | +| `Boolean` | AutoFixup | Specifies whether object name changes (tables, column, measures) should result in automatic DAX expression updates to reflect the changed names. When set to true, all expressions in the model are parsed, to build a dependency tree. | +| `Database` | Database | | +| `Boolean` | DelayBuildDependencyTree | | +| `IList>` | Errors | | +| `Boolean` | HasUnsavedChanges | | +| `Boolean` | IsConnected | | +| `Model` | Model | | +| `String` | Status | | +| `TabularTree` | Tree | | +| `UndoManager` | UndoManager | | +| `Int64` | Version | | + +Methods + +| Type | Name | Summary | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `IDetailObject` | Add(`AddObjectType` objectType, `IDetailObjectContainer` container) | | +| `void` | BeginUpdate(`String` undoName) | | +| `void` | BuildDependencyTree(`IExpressionObject` expressionObj) | | +| `void` | BuildDependencyTree() | | +| `ConflictInfo` | CheckConflicts() | | +| `IList` | DeserializeObjects(`String` json) | | +| `void` | Dispose() | | +| `void` | DoFixup(`IDaxObject` obj, `String` newName) | Changes all references to object "obj", to reflect "newName" | +| `Int32` | EndUpdate(`Boolean` undoable = True, `Boolean` rollback = False) | | +| `Int32` | EndUpdateAll(`Boolean` rollback = False) | | +| `Model` | GetModel() | | +| `Boolean` | ImportTranslations(`String` culturesJson, `Boolean` overwriteExisting, `Boolean` ignoreInvalid) | Applys translation from a JSON string. | +| `void` | SaveDB() | Saves the changes to the database. It is the users responsibility to check if changes were made to the database since it was loaded to the TOMWrapper. You can use Handler.CheckConflicts() for this purpose. | +| `void` | SaveFile(`String` fileName, `SerializeOptions` options) | | +| `void` | SaveToFolder(`String` path, `SerializeOptions` options) | | +| `String` | ScriptCreateOrReplace() | Scripts the entire database | +| `String` | ScriptCreateOrReplace(`TabularNamedObject` obj) | Scripts the entire database | +| `String` | ScriptTranslations(`IEnumerable` translations) | | +| `String` | SerializeObjects(`IEnumerable` objects) | | +| `void` | UpdateFolders(`Table` table) | | +| `void` | UpdateLevels(`Hierarchy` hierarchy) | | +| `void` | UpdateObject(`ITabularObject` obj) | | +| `void` | UpdateTables() | | + +Static Fields + +| Type | Name | Summary | +| -------- | ------------------------------------------- | ------- | +| `String` | PROP_ERRORS | | +| `String` | PROP_HASUNSAVEDCHANGES | | +| `String` | PROP_ISCONNECTED | | +| `String` | PROP_STATUS | | + +Static Properties + +| Type | Name | Summary | +| --------------------- | --------- | ------- | +| `TabularModelHandler` | Singleton | | + +Static Methods + +| Type | Name | Summary | +| ----------------------------------------------- | ------------------------------------------------------------ | ------- | +| `List>` | CheckErrors(`Database` database) | | +| `List>` | CheckProcessingState(`Database` database) | | + +## `TabularNamedObject` + +A TabularObject is a wrapper for the Microsoft.AnalysisServices.Tabular.NamedMetadataObject class. This wrapper is used for all objects that are to be viewable and editable in the Tabular Editor. The same base class is used for all kinds of objects in a Tabular Model. This base class provides method for editing the (localized) name and description. + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularNamedObject + : TabularObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | --------------- | -------------------------------------------------------------- | +| `Int32` | MetadataIndex | | +| `NamedMetadataObject` | MetadataObject | | +| `String` | Name | | +| `TranslationIndexer` | TranslatedNames | Collection of localized names for this object. | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `Int32` | CompareTo(`Object` obj) | | +| `void` | Delete() | | +| `void` | Init() | | +| `void` | Undelete(`ITabularObjectCollection` collection) | Hacky workaround needed to undo a delete operations. Derived classes must take care to update any objects "owned" by the object in question. For example, a Measure must take care of updating the wrapper for its KPI (if any). | + +## `TabularObject` + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularObject + : ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging + +``` + +Fields + +| Type | Name | Summary | +| -------------------------- | ---------- | ------- | +| `ITabularObjectCollection` | Collection | | +| `TabularModelHandler` | Handler | | + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------------ | ------- | +| `MetadataObject` | MetadataObject | | +| `Model` | Model | | +| `ObjectType` | ObjectType | | +| `String` | ObjectTypeName | | +| `TranslationIndexer` | TranslatedDescriptions | | +| `TranslationIndexer` | TranslatedDisplayFolders | | + +Events + +| Type | Name | Summary | +| ------------------------------ | ---------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | +| `PropertyChangingEventHandler` | PropertyChanging | | + +Methods + +| Type | Name | Summary | +| --------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | Init() | Derived members should override this method to instantiate child objects | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | Called before a property is changed on an object. Derived classes can control how the change is handled. Throw ArgumentException within this method, to display an error message in the UI. | +| `Boolean` | SetField(`T&` field, `T` value, `String` propertyName = null) | | + +## `TabularObjectCollection` + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularObjectCollection + : IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------------------------------------- | ------------------------ | ------- | +| `String` | CollectionName | | +| `Int32` | Count | | +| `TabularModelHandler` | Handler | | +| `Boolean` | IsFixedSize | | +| `Boolean` | IsReadOnly | | +| `Boolean` | IsSynchronized | | +| `T` | Item | | +| `T` | Item | | +| `IEnumerable` | Keys | | +| `NamedMetadataObjectCollection` | MetadataObjectCollection | | +| `String` | Summary | | +| `Object` | SyncRoot | | + +Events + +| Type | Name | Summary | +| ------------------------------------- | ----------------- | ------- | +| `NotifyCollectionChangedEventHandler` | CollectionChanged | | + +Methods + +| Type | Name | Summary | +| -------------------------- | ---------------------------------------------------------- | ------- | +| `void` | Add(`T` item) | | +| `void` | Add(`TabularNamedObject` item) | | +| `Int32` | Add(`Object` value) | | +| `void` | Clear() | | +| `Boolean` | Contains(`T` item) | | +| `Boolean` | Contains(`Object` value) | | +| `Boolean` | Contains(`String` name) | | +| `void` | CopyTo(`T[]` array, `Int32` arrayIndex) | | +| `void` | CopyTo(`Array` array, `Int32` index) | | +| `void` | ForEach(`Action` action) | | +| `ITabularObjectCollection` | GetCurrentCollection() | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `Int32` | IndexOf(`TabularNamedObject` obj) | | +| `Int32` | IndexOf(`T` item) | | +| `Int32` | IndexOf(`Object` value) | | +| `void` | Insert(`Int32` index, `T` item) | | +| `void` | Insert(`Int32` index, `Object` value) | | +| `void` | Refresh() | | +| `void` | Remove(`TabularNamedObject` item) | | +| `Boolean` | Remove(`T` item) | | +| `void` | Remove(`Object` value) | | +| `void` | RemoveAt(`Int32` index) | | + +## `TabularObjectComparer` + +```csharp +public class TabularEditor.TOMWrapper.TabularObjectComparer + : IComparer, IComparer + +``` + +Properties + +| Type | Name | Summary | +| ------------- | ----- | ------- | +| `ObjectOrder` | Order | | + +Methods + +| Type | Name | Summary | +| ------- | ---------------------------------------------------------------------------- | ------- | +| `Int32` | Compare(`Object` x, `Object` y) | | +| `Int32` | Compare(`ITabularNamedObject` x, `ITabularNamedObject` y) | | + +## `TabularObjectHelper` + +```csharp +public static class TabularEditor.TOMWrapper.TabularObjectHelper + +``` + +Static Methods + +| Type | Name | Summary | +| --------- | ----------------------------------------------------------------------------------------------- | ------- | +| `String` | GetLinqPath(this `TabularNamedObject` obj) | | +| `String` | GetName(this `ITabularNamedObject` obj, `Culture` culture) | | +| `String` | GetObjectPath(this `MetadataObject` obj) | | +| `String` | GetObjectPath(this `TabularObject` obj) | | +| `String` | GetTypeName(this `ObjectType` objType, `Boolean` plural = False) | | +| `String` | GetTypeName(this `ITabularObject` obj, `Boolean` plural = False) | | +| `Boolean` | SetName(this `ITabularNamedObject` obj, `String` newName, `Culture` culture) | | +| `String` | SplitCamelCase(this `String` str) | | + +## `TabularTree` + +The TabularLogicalModel controls the relation between TabularObjects for display in the TreeViewAdv control. Each individual TabularObject does not know or care about its logical relation to other objects (for example, through DisplayFolders in a specific culture). TabularObjects only care about their physical relations which are inherited from the Tabular Object Model directly (i.e., a measure belongs to a table, etc.). + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularTree + : INotifyPropertyChanged + +``` + +Fields + +| Type | Name | Summary | +| ---------------------------- | ---------- | ------- | +| `Dictionary` | FolderTree | | + +Properties + +| Type | Name | Summary | +| --------------------- | ----------- | ------- | +| `Culture` | Culture | | +| `String` | Filter | | +| `TabularModelHandler` | Handler | | +| `Model` | Model | | +| `LogicalTreeOptions` | Options | | +| `Perspective` | Perspective | | +| `Int32` | UpdateLocks | | + +Events + +| Type | Name | Summary | +| ----------------------------- | --------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | + +Methods + +| Type | Name | Summary | +| ---------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | BeginUpdate() | | +| `void` | EndUpdate() | | +| `IEnumerable` | GetChildren(`ITabularObjectContainer` tabularObject) | This method encapsulates the logic of how the tree representation of the tabular model should be structured | +| `Func` | GetFolderMutation(`Object` source, `Object` destination) | | +| `Func` | GetFolderMutation(`String` oldPath, `String` newPath) | | +| `void` | ModifyDisplayFolder(`Table` table, `String` oldPath, `String` newPath, `Culture` culture) | Updates the DisplayFolder property of all tabular objects within one table. Objects residing in subfolders to the updated path, will also be updated. | +| `void` | OnNodesChanged(`ITabularObject` nodeItem) | | +| `void` | OnNodesInserted(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnNodesInserted(`ITabularObject` parent, `IEnumerable` children) | | +| `void` | OnNodesRemoved(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnNodesRemoved(`ITabularObject` parent, `IEnumerable` children) | | +| `void` | OnStructureChanged(`ITabularNamedObject` obj = null) | | +| `void` | SetCulture(`String` cultureName) | | +| `void` | SetPerspective(`String` perspectiveName) | | +| `void` | UpdateFolder(`Folder` folder, `String` oldFullPath = null) | | +| `Boolean` | VisibleInTree(`ITabularNamedObject` tabularObject) | | + +## `TranslationIndexer` + +```csharp +public class TabularEditor.TOMWrapper.TranslationIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | --------------- | ------- | +| `String` | DefaultValue | | +| `String` | Item | | +| `String` | Item | | +| `IEnumerable` | Keys | | +| `String` | Summary | | +| `Int32` | TranslatedCount | | + +Methods + +| Type | Name | Summary | +| ---------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | Clear() | Clears all translated values for the object. | +| `Boolean` | Contains(`Culture` culture) | | +| `Dictionary` | Copy() | | +| `void` | CopyFrom(`TranslationIndexer` translations, `Func` mutator = null) | | +| `void` | CopyFrom(`IDictionary` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | Refresh() | | +| `void` | Reset() | Resets the translations of the object. Caption translations are removed, making the object appear with the base name in all locales. Display Folder and Description translations are set to the untranslated value of the object. | +| `void` | SetAll(`String` value) | | + + diff --git a/content/localization/de/Training-Webinar-for-Tabular-Editor_de.md b/content/localization/de/Training-Webinar-for-Tabular-Editor_de.md new file mode 100644 index 00000000..ac0ee77c --- /dev/null +++ b/content/localization/de/Training-Webinar-for-Tabular-Editor_de.md @@ -0,0 +1,30 @@ +# Video Tutorials + +In collaboration with [PowerBI.Tips](https://powerbi.tips/about/) Daniel Otykier conducts 4 hours of training related to the Tabular Editor Program. Watch the following videos below to learn more about this tool and see how to use it in your everyday job. + +Webinar Topics + +- Introduction to Tabular Editor +- Using Scripting +- Reviewing your data model with the Best Practice Analyzer +- Deploying your model with Azure DevOps + +## Introduction to Tabular Editor + +[![Intro to Tabular Editor](http://img.youtube.com/vi/c-jZMzsvKnM/0.jpg)](http://www.youtube.com/watch?v=c-jZMzsvKnM "Intro To Tabular Editor") + +## Using Scripting + +[![Intro to Tabular Editor](http://img.youtube.com/vi/EHs5r3XCkO8/0.jpg)](http://www.youtube.com/watch?v=EHs5r3XCkO8 "Intro To Tabular Editor") + +## Best Practice Analyzer + +[![Intro to Tabular Editor](http://img.youtube.com/vi/5WnN0NG2nBk/0.jpg)](http://www.youtube.com/watch?v=5WnN0NG2nBk "Intro To Tabular Editor") + +## Deploying with DevOps + +[![Intro to Tabular Editor](http://img.youtube.com/vi/fzZgXe3MjhI/0.jpg)](http://www.youtube.com/watch?v=fzZgXe3MjhI "Intro To Tabular Editor") + +Special thanks to PowerBI.Tips for setting up these free webinars. +Visit PowerBI.tips on YouTube - https://www.youtube.com/powerbitips +Visit PowerBI.tips - https://powerbi.tips diff --git a/content/localization/de/Useful-script-snippets_de.md b/content/localization/de/Useful-script-snippets_de.md new file mode 100644 index 00000000..b694854e --- /dev/null +++ b/content/localization/de/Useful-script-snippets_de.md @@ -0,0 +1,988 @@ +--- +uid: useful-script-snippets +title: Useful script snippets +author: Daniel Otykier +--- + +# Useful Script Snippets + +Here's a collection of small script snippets to get you started using the [Advanced Scripting functionality](/Advanced-Scripting) of Tabular Editor. Many of these scripts are useful to save as [Custom Actions](/Custom-Actions), so that you can easily reuse them from the context menu.' + +Also, make sure to check out our script library @csharp-script-library, for some more real-life examples of what you can do with the scripting capabilities of Tabular Editor. + +*** + +## Create measures from columns + +```csharp +// Creates a SUM measure for every currently selected column and hide the column. +foreach(var c in Selected.Columns) +{ + var newMeasure = c.Table.AddMeasure( + "Sum of " + c.Name, // Name + "SUM(" + c.DaxObjectFullName + ")", // DAX expression + c.DisplayFolder // Display Folder + ); + + // Set the format string on the new measure: + newMeasure.FormatString = "0.00"; + + // Provide some documentation: + newMeasure.Description = "This measure is the sum of column " + c.DaxObjectFullName; + + // Hide the base column: + c.IsHidden = true; +} +``` + +This snippet uses the `
.AddMeasure(, , )` function to create a new measure on the table. We use the `DaxObjectFullName` property to get the fully qualified name of the column for use in the DAX expression: `'TableName'[ColumnName]`. + +*** + +## Generate Time Intelligence measures + +First, create custom actions for individual Time Intelligence aggregations. For example: + +```csharp +// Creates a TOTALYTD measure for every selected measure. +foreach(var m in Selected.Measures) { + m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.DisplayFolder // Display Folder + ); +} +``` + +Here, we use the `DaxObjectName` property, to generate an unqualified reference for use in the DAX expression, as this is a measure: `[MeasureName]`. Save this as a Custom Action called "Time Intelligence\Create YTD measure" that applies to measures. Create similar actions for MTD, LY, and whatever else you need. Then, create the following as a new action: + +```csharp +// Invoke all Time Intelligence Custom Actions: +CustomAction(@"Time Intelligence\Create YTD measure"); +CustomAction(@"Time Intelligence\Create MTD measure"); +CustomAction(@"Time Intelligence\Create LY measure"); +``` + +This illustrates how you can execute one (or more) Custom Actions from within another action (beware of circular references - that will cause Tabular Editor to crash). Save this as a new Custom Action "Time Intelligence\All of the above", and you will have an easy way to generate all your Time Intelligence measures with a single click: + +![image](https://user-images.githubusercontent.com/8976200/36632257-5565c8ca-197c-11e8-8498-82667b6e1049.png) + +Of course, you may also put all your time intelligence calculations into a single script such as the following: + +```csharp +var dateColumn = "'Date'[Date]"; + +// Creates time intelligence measures for every selected measure: +foreach(var m in Selected.Measures) { + // Year-to-date: + m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Previous year: + m.Table.AddMeasure( + m.Name + " PY", // Name + "CALCULATE(" + m.DaxObjectName + ", SAMEPERIODLASTYEAR(" + dateColumn + "))", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Year-over-year + m.Table.AddMeasure( + m.Name + " YoY", // Name + m.DaxObjectName + " - [" + m.Name + " PY]", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Year-over-year %: + m.Table.AddMeasure( + m.Name + " YoY%", // Name + "DIVIDE([" + m.Name + " YoY], [" + m.Name + " PY])", // DAX expression + m.DisplayFolder // Display Folder + ).FormatString = "0.0 %"; // Set format string as percentage + + // Quarter-to-date: + m.Table.AddMeasure( + m.Name + " QTD", // Name + "TOTALQTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Month-to-date: + m.Table.AddMeasure( + m.Name + " MTD", // Name + "TOTALMTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.DisplayFolder // Display Folder + ); +} +``` + +### Including additional properties + +If you want to set additional properties on the newly created measure, the above script can be modified like so: + +```csharp +// Creates a TOTALYTD measure for every selected measure. +foreach(var m in Selected.Measures) { + var newMeasure = m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.DisplayFolder // Display Folder + ); + newMeasure.FormatString = m.FormatString; // Copy format string from original measure + foreach(var c in Model.Cultures) { + newMeasure.TranslatedNames[c] = m.TranslatedNames[c] + " YTD"; // Copy translated names for every culture + newMeasure.TranslatedDisplayFolders[c] = m.TranslatedDisplayFolders[c]; // Copy translated display folders + } +} +``` + +*** + +## Setting default translations + +Sometimes it is useful to have default translations applied to all (visible) objects. In this case, a default translation is just the original name/description/display folder of an object. One of the advantages of this, is that all translation objects will be included when exporting translations in the JSON format, i.e. for use with [SSAS Tabular Translator](https://www.sqlbi.com/tools/ssas-tabular-translator/). + +The script below will loop through all cultures in the model, and for every visible object, that doesn't already have a translation, it will assign the default values: + +```csharp +// Apply default translations to all (visible) translatable objects, across all cultures in the model: +foreach(var culture in Model.Cultures) +{ + ApplyDefaultTranslation(Model, culture); + foreach(var perspective in Model.Perspectives) + ApplyDefaultTranslation(perspective, culture); + foreach(var table in Model.Tables.Where(t => t.IsVisible)) + ApplyDefaultTranslation(table, culture); + foreach(var measure in Model.AllMeasures.Where(m => m.IsVisible)) + ApplyDefaultTranslation(measure, culture); + foreach(var column in Model.AllColumns.Where(c => c.IsVisible)) + ApplyDefaultTranslation(column, culture); + foreach(var hierarchy in Model.AllHierarchies.Where(h => h.IsVisible)) + ApplyDefaultTranslation(hierarchy, culture); + foreach(var level in Model.AllLevels.Where(l => l.Hierarchy.IsVisible)) + ApplyDefaultTranslation(level, culture); +} + +void ApplyDefaultTranslation(ITranslatableObject obj, Culture culture) +{ + // Only apply the default translation when a translation does not already exist: + if(string.IsNullOrEmpty(obj.TranslatedNames[culture])) + { + // Default name translation: + obj.TranslatedNames[culture] = obj.Name; + + // Default description translation: + var dObj = obj as IDescriptionObject; + if(dObj != null && string.IsNullOrEmpty(obj.TranslatedDescriptions[culture]) + && !string.IsNullOrEmpty(dObj.Description)) + { + obj.TranslatedDescriptions[culture] = dObj.Description; + } + + // Default display folder translation: + var fObj = obj as IFolderObject; + if(fObj != null && string.IsNullOrEmpty(fObj.TranslatedDisplayFolders[culture]) + && !string.IsNullOrEmpty(fObj.DisplayFolder)) + { + fObj.TranslatedDisplayFolders[culture] = fObj.DisplayFolder; + } + } +} +``` + +*** + +## Handling perspectives + +Measures, columns, hierarchies and tables all expose the `InPerspective` property, which holds a True/False value for every perspective in the model, that indicates if the given object is a member of that perspective or not. So for example: + +```csharp +foreach(var measure in Selected.Measures) +{ + measure.InPerspective["Inventory"] = true; + measure.InPerspective["Reseller Operation"] = false; +} +``` + +The script above ensures that all selected measures are visible in the "Inventory" perspective and hidden in the "Reseller Operation" perspective. + +In addition to getting/setting the membership in an individual perspective, the `InPerspective` property also supports the following methods: + +- `<>.InPerspective.None()` - removes the object from all perspectives. +- `<>.InPerspective.All()` - includes the object in all perspectives. +- `<>.CopyFrom(string[] perspectives)` - includes the object in all specified perspectives (array of string containing names of the perspectives). +- `<>.CopyFrom(perspectiveIndexer perspectives)` - copies perspective inclusions from another `InPerspective` property. + +The latter may be used to copy perspective memberships from one object to another. For example, say have a base measure [Reseller Total Sales], and you want to make sure that all currently selected measures are visible in the same perspectives as this base measure. The following script does the trick: + +```csharp +var baseMeasure = Model.Tables["Reseller Sales"].Measures["Reseller Total Sales"]; + +foreach(var measure in Selected.Measures) +{ + /* Uncomment the line below, if you want 'measure' to be hidden + from perspectives that 'baseMeasure' is hidden in: */ + // measure.InPerspective.None(); + + measure.InPerspective.CopyFrom(baseMeasure.InPerspective); +} +``` + +This technique can be used also when generating new objects from code. For example, if we want to ensure that auto-generated Time Intelligence measures are only visible in the same perspectives as their base measure, we can extend the script from the previous section as: + +```csharp +// Creates a TOTALYTD measure for every selected measure. +foreach(var m in Selected.Measures) { + var newMeasure = m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.DisplayFolder // Display Folder + ); + newMeasure.InPerspective.CopyFrom(m.InPerspective); // Apply perspectives from the base measure +} +``` + +*** + +## Generating partitions + +If you need to provide custom partitioning for a table, C# scripting can help you quickly generate many partitions. The basic idea is to add an annotation to your table, containing the SQL or M query to use as a template for each partition. The script will then swap in filter parameters as needed. For example, using SQL partitions, we could add an annotation named `PartitionTemplateSQL` and set its value to `SELECT * FROM fact_ResellerSales WHERE CalendarID BETWEEN {0} AND {1}`. The `{0}` and `{1}` placeholders will be replaced by our script, when generating the final partitions. In this case, `CalendarID` is an integer, but in general, it is your job to ensure that the resulting string is a valid SQL (or M) query. + +![](https://user-images.githubusercontent.com/8976200/70135273-07c6fa00-168a-11ea-84f6-90f0b3498ed8.png) + +The example here generates one partition per month. Select a table that has the `PartitionTemplateSQL` annotation assigned, then run the script. + +```csharp +var firstPartition = new DateTime(2018,1,1); // First partition date +var lastPartition = new DateTime(2020,12,1); // Last partition date + +var templateSql = Selected.Table.GetAnnotation("PartitionTemplateSQL"); +if(string.IsNullOrEmpty(templateSql)) throw new Exception("No partition template!"); + +var currentPartition = firstPartition; +while(currentPartition <= lastPartition) +{ + // Calculate the from and to CalendarID's (integer values) based on the currentPartition date: + var calendarIdFrom = currentPartition.ToString("yyyyMMdd"); + var calendarIdTo = currentPartition.AddMonths(1).AddDays(-1).ToString("yyyyMMdd"); + + // Determine a unique name for the partition - since we're partitioning at a monthly level, we just use yyyyMM: + var partitionName = Selected.Table.Name + "_" + currentPartition.ToString("yyyyMM"); + + // Swap in the placeholder values in the partition template SQL: + var partitionQuery = string.Format(templateSql, calendarIdFrom, calendarIdTo); + + // Create the partition (use .AddMPartition if you used an M query template instead of SQL): + Selected.Table.AddPartition(partitionName, partitionQuery); + + // Increment to next month (change this to .AddDays, .AddYears, etc. if you need more or fewer partitions): + currentPartition = currentPartition.AddMonths(1); +} +``` + +*** + +## Export object properties to a file + +For some workflows, it may be useful to edit multiple object properties in bulk using Excel. Use the following snippet to export a standard set of properties to a .TSV file, which can then be subsequently imported (see below). + +```csharp +// Export properties for the currently selected objects: +var tsv = ExportProperties(Selected); +SaveFile("Exported Properties 1.tsv", tsv); +``` + +The resulting .TSV file looks like this, when opened in Excel: +![image](https://user-images.githubusercontent.com/8976200/36632472-e8e96ef6-197e-11e8-8285-6816b09ad036.png) +The contents of the first column (Object) is a reference to the object. If the contents of this column is changed, subsequent import of the properties might not work correctly. To change the name of an object, only change the value in the second column (Name). + +By default, the file is saved to the same folder as TabularEditor.exe is located. By default, only the following properties are exported (where applicable, depending on the type of object exported): + +- Name +- Description +- SourceColumn +- Expression +- FormatString +- DataType + +To export different properties, supply a comma-separated list of property names to be exported as the 2nd argument to `ExportProperties`: + +```csharp +// Export the names and Detail Rows Expressions for all measures on the currently selected table: +var tsv = ExportProperties(Selected.Table.Measures, "Name,DetailRowsExpression"); +SaveFile("Exported Properties 2.tsv", tsv); +``` + +The available property names can be found in the [TOM API documentation](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.aspx). These are mostly identical to the names shown in the Tabular Editor property grid in CamelCase and with spaces removed (with a few exceptions, for example, the "Hidden" property is called `IsHidden` in the TOM API). + +To import properties, use the following snippet: + +```csharp +// Imports and applies the properties in the specified file: +var tsv = ReadFile("Exported Properties 1.tsv"); +ImportProperties(tsv); +``` + +### Exporting indexed properties + +As of Tabular Editor 2.11.0, the `ExportProperties` and `ImportProperties` methods support indexed properties. Indexed properties are properties that take a key in addition to the property name. One example is `myMeasure.TranslatedNames`. This property represents the collection of all strings applied as name translations for `myMeasure`. In C#, you can access the translated caption of a specific culture using the indexing operator: `myMeasure.TranslatedNames["da-DK"]`. + +Long story short, you can now export all translations, perspective information, annotations, extended properties, row-level- and object-level security information on objects in your Tabular model. + +For example, the following script will produce a TSV file of all model measures and information about which perspectives each is visible in: + +```csharp +var tsv = ExportProperties(Model.AllMeasures, "Name,InPerspective"); +SaveFile(@"c:\Project\MeasurePerspectives.tsv", tsv); +``` + +The TSV file looks like this, when opened in Excel: + +![image](https://user-images.githubusercontent.com/8976200/85208532-956dec80-b331-11ea-8568-32dbd4cc5516.png) + +And just as shown above, you can make changes in Excel, hit save, and then load the updated values back into Tabular Editor using `ImportProperties`. + +If you want to list only a specific or a few specific perspectives, you can specify those in the 2nd argument in the call to `ExportProperties`: + +```csharp +var tsv = ExportProperties(Model.AllMeasures, "Name,InPerspective[Inventory]"); +SaveFile(@"c:\Project\MeasurePerspectiveInventory.tsv", tsv); +``` + +Similarly, for translations, annotations, etc. For example, if you wanted to see all danish translations applied to tables, columns, hierarchies, levells and measures: + +```csharp +// Construct a list of objects: +var objects = new List(); +objects.AddRange(Model.Tables); +objects.AddRange(Model.AllColumns); +objects.AddRange(Model.AllHierarchies); +objects.AddRange(Model.AllLevels); +objects.AddRange(Model.AllMeasures); + +var tsv = ExportProperties(objects, "Name,TranslatedNames[da-DK],TranslatedDescriptions[da-DK],TranslatedDisplayFolders[da-DK]"); +SaveFile(@"c:\Project\ObjectTranslations.tsv", tsv); +``` + +*** + +## Generating documentation + +The `ExportProperties` method shown above, can also be used if you want to document all or parts of your model. The following snippet will extract a set of properties from all visible measures or columns in a Tabular Model, and save it as a TSV file: + +```csharp +// Construct a list of all visible columns and measures: +var objects = Model.AllMeasures.Where(m => !m.IsHidden && !m.Table.IsHidden).Cast() + .Concat(Model.AllColumns.Where(c => !c.IsHidden && !c.Table.IsHidden)); + +// Get their properties in TSV format (tabulator-separated): +var tsv = ExportProperties(objects,"Name,ObjectType,Parent,Description,FormatString,DataType,Expression"); + +// (Optional) Output to screen (can then be copy-pasted into Excel): +// tsv.Output(); + +// ...or save the TSV to a file: +SaveFile("documentation.tsv", tsv); +``` + +*** + +## Generating measures from a file + +The above techniques of exporting/importing properties, is useful if you want to edit object properties in bulk of _existing_ objects in your model. What if you want to import a list of measures that do not already exist? + +Let's say you have a TSV (tab-separated values) file that contains Names, Descriptions and DAX Expressions of measures you'd like to import into an existing Tabular Model. You can use the following script to read in the file, split it out into rows and columns, and generate the measures. The script also assigns a special annotation to each measure, so that it can delete measures that were previously created using the same script. + +```csharp +var targetTable = Model.Tables["Program"]; // Name of the table that should hold the measures +var measureMetadata = ReadFile(@"c:\Test\MyMeasures.tsv"); // c:\Test\MyMeasures.tsv is a tab-separated file with a header row and 3 columns: Name, Description, Expression + +// Delete all measures from the target table that have an "AUTOGEN" annotation with the value "1": +foreach(var m in targetTable.Measures.Where(m => m.GetAnnotation("AUTOGEN") == "1").ToList()) +{ + m.Delete(); +} + +// Split the file into rows by CR and LF characters: +var tsvRows = measureMetadata.Split(new[] {'\r','\n'},StringSplitOptions.RemoveEmptyEntries); + +// Loop through all rows but skip the first one: +foreach(var row in tsvRows.Skip(1)) +{ + var tsvColumns = row.Split('\t'); // Assume file uses tabs as column separator + var name = tsvColumns[0]; // 1st column contains measure name + var description = tsvColumns[1]; // 2nd column contains measure description + var expression = tsvColumns[2]; // 3rd column contains measure expression + + // This assumes that the model does not already contain a measure with the same name (if it does, the new measure will get a numeric suffix): + var measure = targetTable.AddMeasure(name); + measure.Description = description; + measure.Expression = expression; + measure.SetAnnotation("AUTOGEN", "1"); // Set a special annotation on the measure, so we can find it and delete it the next time the script is executed. +} +``` + +If you need to automate this process, save the above script into a file and use the [Tabular Editor CLI](/Command-line-Options) as follows: + +```powershell +start /wait TabularEditor.exe "" -S "" -B "" +``` + +for example: + +```powershell +start /wait TabularEditor.exe "c:\Projects\AdventureWorks\Model.bim" -S "c:\Projects\AutogenMeasures.cs" -B "c:\Projects\AdventureWorks\Build\Model.bim" +``` + +...or, if you prefer to run the script against an already deployed database: + +```powershell +start /wait TabularEditor.exe "localhost" "AdventureWorks" -S "c:\Projects\AutogenMeasures.cs" -D "localhost" "AdventureWorks" -O +``` + +*** + +## Creating Data Columns from Partition Source metadata + +**Note:** If you're using version 2.7.2 or newer, make sure to try the new "Import Table..." feature. + +If a table uses a Query partition based on an OLE DB provider data source, we can automatically refresh the column metadata of that table by executing the following snippet: + +```csharp +Model.Tables["Reseller Sales"].RefreshDataColumns(); +``` + +This is useful when adding new tables to a model, to avoid having to create every Data Column on the table manually. The snippet above assumes that the partition source can be accessed locally, using the existing connection string of the Partition Source for the 'Reseller Sales' table. The snippet above will extract the schema from the partition query, and add a Data Column to the table for every column in the source query. + +If you need to supply a different connection string for this operation, you can do that in the snippet as well: + +```csharp +var source = Model.DataSources["DWH"] as ProviderDataSource; +var oldConnectionString = source.ConnectionString; +source.ConnectionString = "..."; // Enter the connection string you want to use for metadata refresh +Model.Tables["Reseller Sales"].RefreshDataColumns(); +source.ConnectionString = oldConnectionString; +``` + +This assumes that the partitions of the 'Reseller Sales' table is using a Provider Data Source with the name "DWH". + +*** + +## Format DAX expressions + +Please see [FormatDax](/FormatDax) for more information. + +```csharp +// Works in Tabular Editor version 2.13.0 or newer: +Selected.Measures.FormatDax(); +``` + +Alternate syntax: + +```csharp +// Works in Tabular Editor version 2.13.0 or newer: +foreach(var m in Selected.Measures) + m.FormatDax(); +``` + +*** + +## Generate list of source columns for a table + +The following script outputs a nicely formatted list of source columns for the currently selected table. This may be useful if you want to replace partition queries that use `SELECT *` with explicit columns. + +```csharp +string.Join(",\r\n", + Selected.Table.DataColumns + .OrderBy(c => c.SourceColumn) + .Select(c => "[" + c.SourceColumn + "]") + ).Output(); +``` + +*** + +## Auto-creating relationships + +If you're consistently using a certain set of naming conventions within your team, you'll quickly find that scripts can be even more powerful. + +The following script, when executed on one or more fact tables, will automatically create relationships to all relevant dimension tables, based on column names. The script will search for fact table columns having the name pattern `xxxyyyKey` where the xxx is an optional qualifier for role-playing use, and the yyy is the dimension table name. On the dimension table, a column named `yyyKey` must exist and have the same data type as the column on the fact table. For example, a column named "ProductKey" will be related to the "ProductKey" column on the Product table. You can specify a different column name suffix to use in place of "Key". + +If a relationship already exists between the fact and dimension table, the script will create the new relationship as inactive. + +```csharp +var keySuffix = "Key"; + +// Loop through all currently selected tables (assumed to be fact tables): +foreach(var fact in Selected.Tables) +{ + // Loop through all SK columns on the current table: + foreach(var factColumn in fact.Columns.Where(c => c.Name.EndsWith(keySuffix))) + { + // Find the dimension table corresponding to the current SK column: + var dim = Model.Tables.FirstOrDefault(t => factColumn.Name.EndsWith(t.Name + keySuffix)); + if(dim != null) + { + // Find the key column on the dimension table: + var dimColumn = dim.Columns.FirstOrDefault(c => factColumn.Name.EndsWith(c.Name)); + if(dimColumn != null) + { + // Check whether a relationship already exists between the two columns: + if(!Model.Relationships.Any(r => r.FromColumn == factColumn && r.ToColumn == dimColumn)) + { + // If relationships already exists between the two tables, new relationships will be created as inactive: + var makeInactive = Model.Relationships.Any(r => r.FromTable == fact && r.ToTable == dim); + + // Add the new relationship: + var rel = Model.AddRelationship(); + rel.FromColumn = factColumn; + rel.ToColumn = dimColumn; + factColumn.IsHidden = true; + if(makeInactive) rel.IsActive = false; + } + } + } + } +} +``` + +*** + +## Create DumpFilters measure + +Inspired by [this article](https://www.sqlbi.com/articles/displaying-filter-context-in-power-bi-tooltips/), here's a script that will create a [DumpFilters] measure on the currently selected table: + +```csharp +var dax = "VAR MaxFilters = 3 RETURN "; +var dumpFilterDax = @"IF ( + ISFILTERED ( {0} ), + VAR ___f = FILTERS ( {0} ) + VAR ___r = COUNTROWS ( ___f ) + VAR ___t = TOPN ( MaxFilters, ___f, {0} ) + VAR ___d = CONCATENATEX ( ___t, {0}, "", "" ) + VAR ___x = ""{0} = "" & ___d + & IF(___r > MaxFilters, "", ... ["" & ___r & "" items selected]"") & "" "" + RETURN ___x & UNICHAR(13) & UNICHAR(10) +)"; + +// Loop through all columns of the model to construct the complete DAX expression: +bool first = true; +foreach(var column in Model.AllColumns) +{ + if(!first) dax += " & "; + dax += string.Format(dumpFilterDax, column.DaxObjectFullName); + if(first) first = false; +} + +// Add the measure to the currently selected table: +Selected.Table.AddMeasure("DumpFilters", dax); +``` + +*** + +## CamelCase to Proper Case + +A common naming scheme for columns and tables on a relation database, is CamelCase. That is, names do not contain any spaces and individual words start with a capital letter. In a Tabular model, tables and columns that are not hidden, will be visible to business users, and so it would often be preferable to use a "prettier" naming scheme. The following script will convert CamelCased names to Proper Case. Sequences of uppercase letters are kept as-is (acronyms). For example, the script will convert the following: + +- `CustomerWorkZipcode` to `Customer Work Zipcode` +- `CustomerAccountID` to `Customer Account ID` +- `NSASecurityID` to `NSA Security ID` + +I highly recommend saving this script as a Custom Action that applies to all object types (except Relationships, KPIs, Table Permissions and Translations, as these do not have an editable "Name" property): + +```csharp +foreach(var obj in Selected.OfType()) { + var oldName = obj.Name; + var newName = new System.Text.StringBuilder(); + for(int i = 0; i < oldName.Length; i++) { + // First letter should always be capitalized: + if(i == 0) newName.Append(Char.ToUpper(oldName[i])); + + // A sequence of two uppercase letters followed by a lowercase letter should have a space inserted + // after the first letter: + else if(i + 2 < oldName.Length && char.IsLower(oldName[i + 2]) && char.IsUpper(oldName[i + 1]) && char.IsUpper(oldName[i])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + + // All other sequences of a lowercase letter followed by an uppercase letter, should have a space + // inserted after the first letter: + else if(i + 1 < oldName.Length && char.IsLower(oldName[i]) && char.IsUpper(oldName[i+1])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + else + { + newName.Append(oldName[i]); + } + } + obj.Name = newName.ToString(); +} +``` + +*** + +## Exporting dependencies between tables and measures + +Let's say you have a large, complex model, and you want to know which measures are potentially affected by changes to the underlying data. + +The following script loops through all the measures of your model, and for each measure, it outputs a list of tables that measure depends on - both directly and indirectly. The list is outputted as a Tab-separated file. + +```csharp +string tsv = "Measure\tDependsOnTable"; // TSV file header row + +// Loop through all measures: +foreach(var m in Model.AllMeasures) { + + // Get a list of ALL objects referenced by this measure (both directly and indirectly through other measures): + var allReferences = m.DependsOn.Deep(); + + // Filter the previous list of references to table references only. For column references, let's get th + // table that each column belongs to. Finally, keep only distinct tables: + var allTableReferences = allReferences.OfType
() + .Concat(allReferences.OfType().Select(c => c.Table)).Distinct(); + + // Output TSV rows - one for each table reference: + foreach(var t in allTableReferences) + tsv += string.Format("\r\n{0}\t{1}", m.Name, t.Name); +} + +tsv.Output(); +// SaveFile("c:\\MyProjects\\SSAS\\MeasureTableDependencies.tsv", tsv); // Uncomment this line to save output to a file +``` + +*** + +## Setting up Aggregations (Power BI Dataset only) + +As of [Tabular Editor 2.11.3](https://github.com/TabularEditor/TabularEditor/releases/tag/2.11.3), you can now set the `AlternateOf` property on a column, enabling you to define aggregation tables on your model. This feature is enabled for Power BI Datasets (Compatibility Level 1460 or higher) through the Power BI Service XMLA endpoint. + +Select a range of columns and run the following script to initiate the `AlternateOf` property on them: + +```csharp +foreach(var col in Selected.Columns) col.AddAlternateOf(); +``` + +Work your way through the columns one by one, to map them to the base column and set the summarization accordingly (Sum/Min/Max/GroupBy). Alternatively, if you want to automate this process, and your aggregation table columns have identical names as the base table columns, you can use the following script, which will map the columns for you: + +```csharp +// Select two tables in the tree (ctrl+click). The aggregation table is assumed to be the one with fewest columns. +// This script will set up the AlternateOf property on all columns on the aggregation table. Agg table columns must +// have the same name as the base table columns for this script to work. +var aggTable = Selected.Tables.OrderBy(t => t.Columns.Count).First(); +var baseTable = Selected.Tables.OrderByDescending(t => t.Columns.Count).First(); + +foreach(var col in aggTable.Columns) +{ + // The script will set the summarization type to "Group By", unless the column uses data type decimal/double: + var summarization = SummarizationType.GroupBy; + if(col.DataType == DataType.Double || col.DataType == DataType.Decimal) + summarization = SummarizationType.Sum; + + col.AddAlternateOf(baseTable.Columns[col.Name], summarization); +} +``` + +After running the script, you should see that the `AlternateOf` property has been assigned on all columns on your agg table (see screenshot below). Keep in mind, that the base table partition must use DirectQuery for aggregations to work. + +![image](https://user-images.githubusercontent.com/8976200/85851134-6ed70800-b7ae-11ea-82eb-37fcaa2ca9c4.png) + +*** + +## Querying Analysis Services + +As of version [2.12.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.12.1), Tabular Editor now provides a number of helper methods for executing DAX queries and evaluating DAX expressions against your model. These methods work only when model metadata have been loaded directly from an instance of Analysis Services, such as when using the "File > Open > From DB..." option, or when using the Power BI external tools integration of Tabular Editor. + +The following methods are available: + +| Method | Description | +| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void ExecuteCommand(string tmslOrXmla, bool isXmla = false)` | This methods passes the specified TMSL or XMLA script to the connected instance of Analysis Services. This is useful when you want to refresh data in a table on the AS instance. Note that if you use this method to perform metadata changes to your model, your local model metadata will become out-of-sync with the metadata on the AS instance, and you may receive a version conflict warning the next time you try to save the model metadata. Set the `isXmla` parameter to `true` if sending an XMLA script. | +| `IDataReader ExecuteReader(string dax)` | Executes the specified DAX _query_ against the connected AS database and returns the resulting [AmoDataReader](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.amodatareader?view=analysisservices-dotnet) object. A DAX query contains one or more [`EVALUATE`](https://dax.guide/EVALUATE) statements. Note that you can not have multiple open data readers at once. Tabular Editor will automatically close them in case you forget to explicitly close or dispose the reader. | +| `DataSet ExecuteDax(string dax)` | Executes the specified DAX _query_ against the connected AS database and returns a [DataSet](https://docs.microsoft.com/en-us/dotnet/api/system.data.dataset?view=netframework-4.6) object containing the data returned from the query. A DAX query contains one or more [`EVALUATE`](https://dax.guide/EVALUATE) statements. The resulting DataSet object contains one DataTable for each `EVALUATE` statement. Returning very large data tables is not recommended as they may cause out-of-memory or other stability errors. | +| `object EvaluateDax(string dax)` | Executes the specified DAX _expression_ against the connected AS database and returns an object representing the result. If the DAX expression is scalar, an object of the relevant type is returned (string, long, decimal, double, DateTime). If the DAX expression is table-valued, a [DataTable](https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable?view=netframework-4.6) is returned. | + +The methods are scoped to the `Model.Database` object, but they can also be executed directly without any prefix. + +Darren Gosbell presents an interesting use-case of generating data-driven measures using the `ExecuteDax` method [here](https://darren.gosbell.com/2020/08/the-best-way-to-generate-data-driven-measures-in-power-bi-using-tabular-editor/). + +Another option is to create a reusable script for refreshing a table. For example, to perform a recalculation, use this: + +```csharp +var type = "calculate"; +var database = Model.Database.Name; +var table = Selected.Table.Name; +var tmsl = "{ \"refresh\": { \"type\": \"%type%\", \"objects\": [ { \"database\": \"%db%\", \"table\": \"%table%\" } ] } }" + .Replace("%type%", type) + .Replace("%db%", database) + .Replace("%table%", table); + +ExecuteCommand(tmsl); +``` + +### Clearing the Analysis Services engine cache + +As of Tabular Editor 2.16.6 or Tabular Editor 3.2.3, you can use the following syntax to send raw XMLA commands to Analysis Services. The example below shows how this can be used to clear the AS engine cache: + +```csharp +var clearCacheXmla = string.Format(@" + + {0} + +", Model.Database.ID); + +ExecuteCommand(clearCacheXmla, isXmla: true); +``` + +### Visualize query results + +You can also use the `Output` helper method to visualize the result of a DAX expression returned from `EvaluateDax` directly: + +```csharp +EvaluateDax("1 + 2").Output(); // An integer +EvaluateDax("\"Hello from AS\"").Output(); // A string +EvaluateDax("{ (1, 2, 3) }").Output(); // A table +``` + +![image](https://user-images.githubusercontent.com/8976200/91638299-bbd59580-ea0e-11ea-882b-55bff73c30fb.png) + +...or, if you want to return the value of the currently selected measure: + +```csharp +EvaluateDax(Selected.Measure.DaxObjectFullName).Output(); +``` + +![image](https://user-images.githubusercontent.com/8976200/91638367-6f3e8a00-ea0f-11ea-90cd-7d2e4cff6e31.png) + +And here's a more advanced example that allows you to select and evaluate multiple measures at once: + +```csharp +var dax = "ROW(" + string.Join(",", Selected.Measures.Select(m => "\"" + m.Name + "\", " + m.DaxObjectFullName).ToArray()) + ")"; +EvaluateDax(dax).Output(); +``` + +![image](https://user-images.githubusercontent.com/8976200/91638356-546c1580-ea0f-11ea-8302-3e40829e00dd.png) + +If you're really advanced, you could use SUMMARIZECOLUMNS or some other DAX function to visualize the selected measure sliced by some column: + +```csharp +var dax = "SUMMARIZECOLUMNS('Product'[Color], " + string.Join(",", Selected.Measures.Select(m => "\"" + m.Name + "\", " + m.DaxObjectFullName).ToArray()) + ")"; +EvaluateDax(dax).Output(); +``` + +![image](https://user-images.githubusercontent.com/8976200/91638389-9b5a0b00-ea0f-11ea-819f-d3eee3ddfa71.png) + +Remember you can save these scripts as Custom Actions by clicking the "+" icon just above the script editor. This way, you get an easily reusable collection of DAX queries that you can execute and visualize directly from inside the Tabular Editor context menu: + +![image](https://user-images.githubusercontent.com/8976200/91638790-305e0380-ea12-11ea-9d84-313f4388496f.png) + +### Exporting data + +You can use the following script to evaluate a DAX query and stream the results to a file (the script uses a tab-separated file format): + +```csharp +using System.IO; + +// This script evaluates a DAX query and writes the results to file using a tab-separated format: + +var dax = "EVALUATE 'Customer'"; +var file = @"c:\temp\file.csv"; +var columnSeparator = "\t"; + +using(var daxReader = ExecuteReader(dax)) +using(var fileWriter = new StreamWriter(file)) +{ + // Write column headers: + fileWriter.WriteLine(string.Join(columnSeparator, Enumerable.Range(0, daxReader.FieldCount - 1).Select(f => daxReader.GetName(f)))); + + while(daxReader.Read()) + { + var rowValues = new object[daxReader.FieldCount]; + daxReader.GetValues(rowValues); + var row = string.Join(columnSeparator, rowValues.Select(v => v == null ? "" : v.ToString())); + fileWriter.WriteLine(row); + } +} +``` + +If you come up with some other interesting uses of these methods, please consider sharing them in the [community scripts repository](https://github.com/TabularEditor/Scripts). Thanks! + +*** + +## Replace Power Query server and database names + +Power BI Dataset that import data from SQL Server-based datasources, often contain M expressions that look like the following. Tabular Editor does unfortunately not have any mechanism for "parsing" such an expression, but if we wanted to replace the server and database names in this expression with something else, without knowing the original values, we can exploit the fact that the values are enclosed in double quotes: + +```M +let + Source = Sql.Databases("devsql.database.windows.net"), + AdventureWorksDW2017 = Source{[Name="AdventureWorks"]}[Data], + dbo_DimProduct = AdventureWorksDW2017{[Schema="dbo",Item="DimProduct"]}[Data] +in + dbo_DimProduct +``` + +The following script will replace the first occurrence of a value in double quotes with a server name, and the second occurrence of a value in double quotes with a database name. Both replacement values are read from environment variables: + +```csharp +// This script is used to replace the server and database names across +// all power query partitions, with the ones provided through environment +// variables: +var server = "\"" + Environment.GetEnvironmentVariable("SQLServerName") + "\""; +var database = "\"" + Environment.GetEnvironmentVariable("SQLDatabaseName") + "\""; + +// This function will extract all quoted values from the M expression, returning a list of strings +// with the values extracted (in order), but ignoring any quoted values where a hashtag (#) precedes +// the quotation mark: +var split = new Func>(m => { + var result = new List(); + var i = 0; + foreach(var s in m.Split('"')) { + if(s.EndsWith("#") && i % 2 == 0) i = -2; + if(i >= 0 && i % 2 == 1) result.Add(s); + i++; + } + return result; +}); +var GetServer = new Func(m => split(m)[0]); // Server name is usually the 1st encountered string +var GetDatabase = new Func(m => split(m)[1]); // Database name is usually the 2nd encountered string + +// Loop through all partitions on the model, replacing the server and database names from the partitions +// with the ones specified in environment variables: +foreach(var p in Model.AllPartitions.OfType()) +{ + if (p.Expression.Contains("Source = Sql.Database")) + { + var oldServer = "\"" + GetServer(p.Expression) + "\""; + var oldDatabase = "\"" + GetDatabase(p.Expression) + "\""; + p.Expression = p.Expression.Replace(oldServer, server).Replace(oldDatabase, database); + } +} +``` + +*** + +## Replace Power Query data sources and partitions with Legacy + +If you are working with a Power BI-based model that uses Power Query (M) expressions for partitions against a SQL Server-based data source, you will unfortunately not be able to use Tabular Editor 2's Data Import wizard or perform a schema check (i.e. comparing imported columns with columns in the data source). + +To solve this issue, you can run the following script on your model, to replace the power query partitions with corresponding native SQL query partitions, and to create a legacy (provider) data source on the model, which will work with Tabular Editor 2's Import Data wizard: + +There are two versions of the script: The first one uses the MSOLEDBSQL provider for the created legacy data source, and hardcoded credentials. This is useful for local development. The second one uses the SQLNCLI provider, which is available on Microsoft-hosted build agents on Azure DevOps, and reads credentials and server/database names from environment variables, making the script useful for integration in Azure Pipeliens. + +MSOLEDBSQL version, which reads connection information from M partitions and prompts for user name and password through Azure AD: + +```csharp +#r "Microsoft.VisualBasic" + +// This script replaces all Power Query partitions on this model with a +// legacy partition using the provided connection string with INTERACTIVE +// AAD authentication. The script assumes that all Power Query partitions +// load data from the same SQL Server-based data source. + +// Provide the following information: +var authMode = "ActiveDirectoryInteractive"; +var userId = Microsoft.VisualBasic.Interaction.InputBox("Type your AAD user name", "User name", "name@domain.com", 0, 0); +if(userId == "") return; +var password = ""; // Leave blank when using ActiveDirectoryInteractive authentication + +// This function will extract all quoted values from the M expression, returning a list of strings +// with the values extracted (in order), but ignoring any quoted values where a hashtag (#) precedes +// the quotation mark: +var split = new Func>(m => { + var result = new List(); + var i = 0; + foreach(var s in m.Split('"')) { + if(s.EndsWith("#") && i % 2 == 0) i = -2; + if(i >= 0 && i % 2 == 1) result.Add(s); + i++; + } + return result; +}); +var GetServer = new Func(m => split(m)[0]); // Server name is usually the 1st encountered string +var GetDatabase = new Func(m => split(m)[1]); // Database name is usually the 2nd encountered string +var GetSchema = new Func(m => split(m)[2]); // Schema name is usually the 3rd encountered string +var GetTable = new Func(m => split(m)[3]); // Table name is usually the 4th encountered string + +var server = GetServer(Model.AllPartitions.OfType().First().Expression); +var database = GetDatabase(Model.AllPartitions.OfType().First().Expression); + +// Add a legacy data source to the model: +var ds = Model.AddDataSource("AzureSQL"); +ds.Provider = "System.Data.OleDb"; +ds.ConnectionString = string.Format( + "Provider=MSOLEDBSQL;Data Source={0};Initial Catalog={1};Authentication={2};User ID={3};Password={4}", + server, + database, + authMode, + userId, + password); + +// Remove Power Query partitions from all tables and replace them with a single Legacy partition: +foreach(var t in Model.Tables.Where(t => t.Partitions.OfType().Any())) +{ + var mPartitions = t.Partitions.OfType(); + if(!mPartitions.Any()) continue; + var schema = GetSchema(mPartitions.First().Expression); + var table = GetTable(mPartitions.First().Expression); + t.AddPartition(t.Name, string.Format("SELECT * FROM [{0}].[{1}]", schema, table)); + foreach(var p in mPartitions.ToList()) p.Delete(); +} +``` + +SQLNCLI version reading connection info from environment variables: + +```csharp +// This script replaces all Power Query partitions on this model with a +// legacy partition, reading the SQL server name, database name, user name +// and password from corresponding environment variables. The script assumes +// that all Power Query partitions load data from the same SQL Server-based +// data source. + +var server = Environment.GetEnvironmentVariable("SQLServerName"); +var database = Environment.GetEnvironmentVariable("SQLDatabaseName"); +var userId = Environment.GetEnvironmentVariable("SQLUserName"); +var password = Environment.GetEnvironmentVariable("SQLUserPassword"); + +// This function will extract all quoted values from the M expression, returning a list of strings +// with the values extracted (in order), but ignoring any quoted values where a hashtag (#) precedes +// the quotation mark: +var split = new Func>(m => { + var result = new List(); + var i = 0; + foreach(var s in m.Split('"')) { + if(s.EndsWith("#") && i % 2 == 0) i = -2; + if(i >= 0 && i % 2 == 1) result.Add(s); + i++; + } + return result; +}); +var GetServer = new Func(m => split(m)[0]); // Server name is usually the 1st encountered string +var GetDatabase = new Func(m => split(m)[1]); // Database name is usually the 2nd encountered string +var GetSchema = new Func(m => split(m)[2]); // Schema name is usually the 3rd encountered string +var GetTable = new Func(m => split(m)[3]); // Table name is usually the 4th encountered string + +// Add a legacy data source to the model: +var ds = Model.AddDataSource("AzureSQL"); +ds.Provider = "System.Data.SqlClient"; +ds.ConnectionString = string.Format( + "Server={0};Initial Catalog={1};Persist Security Info=False;User ID={2};Password={3}", + server, + database, + userId, + password); + +// Remove Power Query partitions from all tables and replace them with a single Legacy partition: +foreach(var t in Model.Tables.Where(t => t.Partitions.OfType().Any())) +{ + var mPartitions = t.Partitions.OfType(); + if(!mPartitions.Any()) continue; + var schema = GetSchema(mPartitions.First().Expression); + var table = GetTable(mPartitions.First().Expression); + t.AddPartition(t.Name, string.Format("SELECT * FROM [{0}].[{1}]", schema, table)); + foreach(var p in mPartitions.ToList()) p.Delete(); +} +``` diff --git a/content/localization/de/Workspace-Database_de.md b/content/localization/de/Workspace-Database_de.md new file mode 100644 index 00000000..98c3fe27 --- /dev/null +++ b/content/localization/de/Workspace-Database_de.md @@ -0,0 +1,48 @@ +## Introducing Workspace Databases + +Tabular Editor 3.0 supports editing model metadata loaded from disk with a simultaneous connection to a database deployed to an instance of Analysis Services. We call this database the _workspace database_. Going forward, this is the recommended approach to tabular modeling within Tabular Editor. + +This makes the development workflow a lot simpler, since you only need to hit Save (Ctrl+S) once, to simultaneously save your changes to the disk **and** update the metadata in the workspace database. This also has the advantage, that any error messages returned from Analysis Services, are immediately visible in Tabular Editor upon hitting Save. In a sense, this is similar to the way SSDT / Visual Studio or Power BI Desktop does, except that you are in control of when the workspace database is updated. + +When you load a model from a Model.bim file or folder structure, you will see the following prompt: + +![image](https://user-images.githubusercontent.com/8976200/58166683-a65db180-7c8a-11e9-9df3-be9a716b3ad1.png) + +- **Yes**: Model metadata is loaded from disk and then immediately deployed to an instance of Analysis Services. Tabular Editor will then connect to the newly deployed database. The next time the same model is loaded from disk, Tabular Editor will redeploy and connect to the database automatically. +- **No**: Model metadata is loaded from disk into Tabular Editor as usual, without connecting to an instance of Analysis Services. +- **No, don't ask again**: Same as the option above, but Tabular Editor will not ask again the next time the same model is loaded. + +### Setting up a Workspace Database + +When you select the "Yes" option in the prompt shown above, you will be asked for a servername and (optional) credentials to an instance of Analysis Services. Hitting "OK" will show you a list of databases already on the instance. Tabular Editor assumes that you want to deploy a new database and provides a default name for the new database, based on your Windows username and the current date and time: + +![image](https://user-images.githubusercontent.com/8976200/58179509-a10f5f80-7ca8-11e9-9764-4cb76b9d1a8b.png) + +If you want to use and existing database as your workspace database, simply select it on the list. **Warning: If you choose an existing database, it will be overwritten with the metadata of the model loaded from disk. For this reason it is not recommended to set up workspace databases on a production instance!** + +### The User Options file (.tmuo) + +To track the workspace settings for each model in your file system, Tabular Editor 3.0 introduces a new file of type .tmuo (short for Tabular Model User Options), which will be placed next to the Model.bim or Database.json file. + +The .tmuo file is just a simple json document with the following content: + +```json +{ + "UseWorkspace": true, + "WorkspaceConnection": "Data Provider=MSOLAP;Data Source=localhost", + "WorkspaceDatabase": "AdventureWorks_WS_Feature123" +} +``` + +When loading model metadata from disk, Tabular Editor looks for the presence of a .tmuo file within the same directory as the loaded model file. The name of the .tmuo file must follow the pattern: + +``` +..tmuo +``` + +The reason that the file contains a username, is to prevent multiple developers from inadvertently overwriting each others workspace databases in parallel development workflows. If the file is present and the "UseWorkspace" flag in the file is set to "true", Tabular Editor will perform the following steps when loading a model from disk: + +1. Deploy the model metadata to the workspace database (overwriting existing metadata), using the server- and database name specified in the .tmuo file. +2. Connect to the newly deployed database in "workspace mode". + +When in "workspace mode", Tabular Editor simultaneously saves your model to disk and updates the workspace database, whenever you hit Save (ctrl+s). This lets you rapidly test new code and see error messages provided by Analysis Services, without having to manually deploy the database or invoking File > Save As... or File > Save to Folder... whenever you want to persist model metadata to disk. diff --git a/content/localization/de/as-cicd_de.md b/content/localization/de/as-cicd_de.md new file mode 100644 index 00000000..a6353f13 --- /dev/null +++ b/content/localization/de/as-cicd_de.md @@ -0,0 +1,10 @@ +--- +uid: as-cicd +title: Analysis Services CI/CD with Azure DevOps and Tabular Editor +author: Daniel Otykier +updated: 2021-10-04 +--- + +# Analysis Services CI/CD with Azure DevOps and Tabular Editor + +(WIP) \ No newline at end of file diff --git a/content/localization/de/beta-16_6_de.md b/content/localization/de/beta-16_6_de.md new file mode 100644 index 00000000..56989f3e --- /dev/null +++ b/content/localization/de/beta-16_6_de.md @@ -0,0 +1,95 @@ +# Tabular Editor 3 BETA-16.6 Release Notes + +- Download [Tabular Editor 3 BETA-16.6](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-16.6.x86.msi) +- Download [Tabular Editor 3 BETA-16.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-16.6.x64.msi) + +## Updates in BETA-16.6: + +- Fixed an issue with the "Group By Columns" collection editor's Add-button. +- Changed the default Compatibility Level for new Power BI Datasets to 1560. +- Allow creation of new table-level objects (measures, columns, hierarchies) when the currently selected object is a table-level object itself. + +## Updates in BETA-16.5: + +- Installer should now correctly register Tabular Editor 3 as an external tool for Power BI Desktop +- Added the "-nosplash" CLI option, which is used when Power BI Desktop launches Tabular Editor 3, as the splash screen could sometimes cause Tabular Editor 3 to become "hidden" behind Power BI Desktop. After upgrading Tabular Editor 3, make sure you restart Power BI Desktop. +- Download links now uses our Azure CDN which is where we will host Tabular Editor 3 binaries going forward. The following URLs always point to the latest version of Tabular Editor 3: + - https://cdn.tabulareditor.com/files/latest/TabularEditor.3.x86.msi + - https://cdn.tabulareditor.com/files/latest/TabularEditor.3.x64.msi + +## Updates in BETA-16.4: + +A rather big list of bug fixes and minor improvements incoming: + +### General improvements: + +- Name of .pbix file is now used as the database name when saving a .pbix model as a .bim/folder structure. +- Added x64 support (both x64 and x86 builds are targeting "Any CPU", but the latter has the "Prefer32Bits" flag set) +- Installer has been updated. It's now using WiX, which ensures that the registry and local app data folder are neatly cleaned when the product is uninstalled. In addition, it looks better :-) +- Macro recorder now supports recording of most (all?) model changes that can be done through the UI +- Added support for multi-column scalar predicates, which is a new DAX syntax that was added recently. Tabular Editor tries to guess which version of Analysis Services is used based on the model metadata, but since this is not always possible (e.g. when working offline), you can override how Tabular Editor treats multi-column scalar predicate table filter expressions under Tools > Preferences > DAX Editor > General > Semantic Engine Features). +- Updated TOM to version 19.18.0. + +### Usability improvements: + +- Increased the "hitbox" of the expand/collapse arrow in TOM Explorer increased (see [this comment](https://github.com/TabularEditor3/PublicPreview/issues/81#issuecomment-789637586)) +- Double-clicking the icon next to an object in the TOM Explorer now brings the DAX Expression Editor into view. + +### Bug fixes: + +- Fixed DAX semantic analyzer issue, which would cause "ghost" error messages in certain expressions +- Fixed issue #75 +- Fixed issue #77 +- Fixed issue #84 +- Fixed a number of crashes based on telemetry. @**Everyone**: Keep sending those error reports when an exception occurs, and please provide descriptions - they are invaluable when trying to figure out what went wrong! Thanks! + +## Updates in BETA-16.3: + +- "Custom Actions" have been renamed to "Macros". + - There's a new window that lets you manage all macros currently defined. Edit an existing macro by doubleclicking on an item. + - Once a C# script is saved as a macro, the document will update the macro on subsequent saves (Ctrl+S). Use File > Save As... if you need to save the script as a file. + - Macros can have identical names. They are distinguished internally using an auto-assigned ID. + - Fixed an issue that prevented a macro from being saved +- The Window menu now also contains a "New" submenu, containing the same menu items as "File > New" +- Inactive toolbars and menus are now hidden by default, to reduce UI cluttering (can be changed in Tools > Preferences > User Interface). +- Fixed a DAX parser bug that caused `GENERATESERIES` to provide a table with a wrongly-named column, possibly related to #61 +- Fix for issue #74 (EndBatch() called before BeginBatch() crash) +- Added warning and refresh of local TOM tree upon save to DB, if changes were made to the deployed model metadata outside of Tabular Editor + +## Updates in BETA-16.2: + +- Table Preview can now auto-refresh similar to DAX queries/pivot grids (see issue #73) +- Fixed a bug that would prevent Table Preview from showing a calculated table that had not been refreshed +- DAX script support for creating calculated columns and calculated tables +- DAX scripts can now be partially executed (see issue #69). 4 buttons should light up on the "DAX Script" toolbar, when editing a DAX script. These buttons have the following shortcuts: + - `F5` will apply the full script. + - `Shift+F5` will apply the full script and also sync the connected database. + - `F8` will apply only the current selection. + - `Shift+F8` will apply the current selection and sync the connected database. +- Added a watermark to the diagram view to guide users on how to add tables to the diagram (see issue #76) +- Background Best Practice Analysis should no longer freeze the UI (see issue #79) +- Toolbar buttons/context menu options for ignoring rules/objects on the Best Practice Analyzer view, should now work correctly +- The "please wait" form should no longer overlap any dialogs being spawned from a C# script +- Various bug fixes (possibly related to issue #74) + +## Updates in BETA-16.1: + +- Measures now use a "calculator" icon, to better align the experience with Power BI Desktop. Calculation Item icons have also been changed slightly, so that they are distinguishable from measures. +- Key columns are now shown in **bold** +- Added "Define Measure" and "Inline Measure" refactoring options +- Improved auto-complete behaviour around DEFINE / EVALUATE statements of DAX queries. For example, autocomplete can now also suggest measures, columns and tables defined inside the query. +- Auto-complete now also suggests measures for the Name parameter of functions such as SUMMARIZECOLUMNS, ADDCOLUMNS, etc., completing both the Name and the Expression parameter at once: + ![autocomplete names](https://user-images.githubusercontent.com/8976200/107629428-66aada80-6c62-11eb-91e4-d5528947840a.gif) +- Revisited #42. +- Deployment Wizard now stores deployment preferences (destination + options) to the .tmuo file sitting next to the Model.bim or Database.json file on disk. This makes it easier to perform deployments when switching between different models, if each model is always deployed to the same destination. +- Updated TOM to 19.16.3. Should fix issue #63. +- Fixed issue #64. +- Fixed a bug with model files appearing in the "Recent Files" menu. + +## Updates in BETA-16.0: + +- Deployment Wizard updated. Also fixes issue #42 and #43. +- Support for DEFINE COLUMN and TABLE syntax in DAX queries +- The File menu now has a "Recent Files" and a "Recent Tabular Models" submenu. The former holds references to the 10 most recent DAX scripts, model diagrams, DAX queries and C# scripts that were saved/opened. The latter holds references to the 10 most recent model files (bim / pbit / folder). +- Fixed #67 +- Fixed #66 diff --git a/content/localization/de/beta-17_4_de.md b/content/localization/de/beta-17_4_de.md new file mode 100644 index 00000000..092c1eec --- /dev/null +++ b/content/localization/de/beta-17_4_de.md @@ -0,0 +1,66 @@ +# Tabular Editor 3 BETA-17.4 Release Notes + +- Download [Tabular Editor 3 BETA-17.4](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-17.4.x86.msi) +- Download [Tabular Editor 3 BETA-17.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-17.4.x64.msi) + +## Updates in BETA-17.4: + +- Fix issue with DAX semantic analyzer reporting false circular dependencies in some situations. +- DAX editors now shows keyboard shortcuts in right-click context menu +- Peek Definition editor can now be closed by pressing ESC while the cursor is inside the Peek Definition editor. Also, AutoComplete/Calltips should no longer show up within the editor, since it is read-only by design. +- Allow specifying an AlternateOf BaseColumn property when using the "Count" summarization. +- Improved support for connection strings that point to Power BI service dataset. + +## Updates in BETA-17.3: + +- Tables can now be dragged into the Diagram View (see #15) +- Inline/Define measures in DAX script mode now work as expected (see #91) +- VertiPaq Analyzer should now correctly pick up data model changes made outside of Tabular Editor when collecting statistics +- VertiPaq Analyzer data can now be accessed through scripts (see #90): There's a new global script method, `CollectVertiPaqAnalyzerStats();`, as well as two new extension methods for Tables and Columns: `.GetCardinality()` and `.GetTotalSize()`. +- Multiple improvements to the AutoComplete feature. For example, when typing code between square brackets (see #92) +- Circular dependencies between query-scoped objects in a DAX query or scripted objects in a DAX script, should no longer cause a crash +- Added a new DAX Auto Formatting option to control whether extension columns are always qualified, even when the table name is blank, such as `''[MyExtColumn]`. +- Fixed a crash that would sometimes occur when double-clicking an item in the Messages View +- Fixed error messages for the ISSELECTEDMEASURE, SELECTEDMEASURE, SELECTEDMEASURENAME and SELECTEDMEASUREFORMATSTRING functions, when used outside of a calculation item or measure expression. + +## Updates in BETA-17.2: + +- Fixed an issue with VertiPaq Analyzer assembly versions. +- Added "Partitions" pane to VeritPaq Analyzer. +- Installer will no longer delete the `%LocalAppData%\TabularEditor3` folder contents, allowing users to persist settings through upgrades/uninstalls. +- Support for drag/drop of objects into DAX and C# editors (#15). +- Support for drag/drop of selected text in all code editors. Hold down CTLR while dragging to copy the selection. +- Support for the new OneWay_LeftFiltersRight and OneWay_RightFiltersLeft arguments in the DAX CROSSFILTER function. +- Upgraded TOM to 19.20.1. +- Various stability improvements. + +## Updates in BETA-17.1: + +![image](https://user-images.githubusercontent.com/8976200/112887423-762b9900-90d3-11eb-8248-d9da55fe8fe3.png) + +- Added [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/) (you may need to delete the Layout.gz file under %LocalAppData%\TabularEditor3 and/or reset to the Default window workspace if the new view doesn't appear in the UI) + - Collects statistics (column and table cardinalities and sizes) which will then show up in the TOM Explorer tooltips as well as when hovering over a column or table reference in any DAX editor. + - Import/Export statistics from/to VPAX files + - Load a model from a VPAX file +- Allow editing synonyms +- Include SortByColumn in dependency view + +## Bug fixes in BETA-17.1: + +- Fixed issue with copy/pasting cultures overwriting existing cultures + +## Updates in BETA-17.0: + +- Tabular Editor 3 now lets you edit M Expressions and Partition queries in the main expression editor (see #2) +- All 4 flavours of code editors (DAX, C#, SQL, M) can now be configured independently under Tools > Preferences > Text Editors (e.g. line numbers, indentation guides, whitespace, etc.) +- Code editors now supports multi-paste (#87). You can toggle this feature off under Tools > Preferences > Text Editors > General. + +## Bug fixes in BETA-17.0: + +- Macro recorder now generates proper code to reference the original object, when an objects name is changed. +- The ALT key will no longer shift focus to the menu bar (this was interfering with block-selections in text editors). Instead, you can use F10 to switch the focus. ALT+letter key combinations can still be used to navigate menus. +- Tabular Editor 3 now properly deals with the LineageTag property, for example when copying a measure within a Power BI Desktop model +- Macros can now use the FormatDax method. +- Various TOMWrapper bugfixes ported from Tabular Editor 2. +- Fixed property grid behavior for read-only items (they are now grayed-out in the property grid). +- Added right-click options on certain properties in the property grid (for example to add/remove AlternateOf objects, KPIs and more). diff --git a/content/localization/de/beta-18_1_de.md b/content/localization/de/beta-18_1_de.md new file mode 100644 index 00000000..f9e62d3d --- /dev/null +++ b/content/localization/de/beta-18_1_de.md @@ -0,0 +1,38 @@ +# Tabular Editor 3 BETA-18.1 Release Notes + +- Download [Tabular Editor 3 BETA-18.1](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.1.x86.msi) +- Download [Tabular Editor 3 BETA-18.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.1.x64.msi) + +## New features in this release: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in this release: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor3/PublicPreview/blob/master/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/de/beta-18_2_de.md b/content/localization/de/beta-18_2_de.md new file mode 100644 index 00000000..f012c218 --- /dev/null +++ b/content/localization/de/beta-18_2_de.md @@ -0,0 +1,42 @@ +# Tabular Editor 3 BETA-18.2 Release Notes + +- Download [Tabular Editor 3 BETA-18.2](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.2.x86.msi) +- Download [Tabular Editor 3 BETA-18.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.2.x64.msi) + +## Bugfixes in BETA-18.2: + +- The DAX parser now correctly recognizes object names containing double quotes (see issue #22). + +## New features in BETA-18.1: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in BETA-18.1: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor3/PublicPreview/blob/master/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/de/beta-18_3_de.md b/content/localization/de/beta-18_3_de.md new file mode 100644 index 00000000..9eb4de06 --- /dev/null +++ b/content/localization/de/beta-18_3_de.md @@ -0,0 +1,48 @@ +# Tabular Editor 3 BETA-18.3 Release Notes + +- Download [Tabular Editor 3 BETA-18.3](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.3.x86.msi) +- Download [Tabular Editor 3 BETA-18.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.3.x64.msi) + +## Bugfixes in BETA-18.3: + +- Improved semantic analyzer performance on large models (regression in BETA-18.x) +- Queuing a data refresh operation should no longer freeze the UI +- Keyboard buttons (left/right arrows and F2 for rename) may now again be used to navigate the Tabular Explorer tree + +## Bugfixes in BETA-18.2: + +- The DAX parser now correctly recognizes object names containing double quotes (see issue #22). + +## New features in BETA-18.1: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in BETA-18.1: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor/TabularEditor3/blob/master/media/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/de/beta-18_4_de.md b/content/localization/de/beta-18_4_de.md new file mode 100644 index 00000000..ddbca1c0 --- /dev/null +++ b/content/localization/de/beta-18_4_de.md @@ -0,0 +1,59 @@ +# Tabular Editor 3 BETA-18.4 Release Notes + +- Download [Tabular Editor 3 BETA-18.4](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.4.x86.msi) +- Download [Tabular Editor 3 BETA-18.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.4.x64.msi) + +## New features in BETA-18.4: + +- Tabular Editor 3 will now store (encrypted) credentials for data sources in the personal .tmuo file. This is ideal when using a workspace database, as you can then specify a set of credentials different from those defined in the Model.bim file. If you're using version control, make sure to ignore the .tmuo extension. Even though the credentials in the file are encrypted with the Windows user key, the idea is that each developer can have their own .tmuo file containing credentials and preferences that apply only for them, and therefore this file should not be included in version control. +- Tabular Editor 3 now prompts for credentials that are going to be overwritten during a deployment operation, so you no longer have to set the credentials through another tool after deployment. Please note that Power Query data sources will always have their credentials wiped during a deployment operation, so credentials for these types of data sources must be entered upon every deployment. +- Upon creating a new model, you will now have the option to connect to a workspace database immediately (recommended). + +## Bugfixes in BETA-18.4: + +- Fixed an issue with keyboard shortcuts and certain actions (Undo/Redo, etc.) not always being enabled when switching the focus between different editors. +- Find/replace dialog now has a minimum size to avoid scrollbars. + +## Bugfixes in BETA-18.3: + +- Improved semantic analyzer performance on large models (regression in BETA-18.x) +- Queuing a data refresh operation should no longer freeze the UI +- Keyboard buttons (left/right arrows and F2 for rename) may now again be used to navigate the Tabular Explorer tree + +## Bugfixes in BETA-18.2: + +- The DAX parser now correctly recognizes object names containing double quotes (see issue #22). + +## New features in BETA-18.1: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in BETA-18.1: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor/TabularEditor3/blob/master/media/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/de/beta-18_5_de.md b/content/localization/de/beta-18_5_de.md new file mode 100644 index 00000000..a322b59a --- /dev/null +++ b/content/localization/de/beta-18_5_de.md @@ -0,0 +1,20 @@ +- Download [Tabular Editor 3 BETA-18.5](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.5.x86.msi) +- Download [Tabular Editor 3 BETA-18.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.5.x64.msi) +- [All releases](https://docs.tabulareditor.com/projects/te3/en/latest/downloads.html) + +## New features in BETA-18.5: + +- The Search dialog (CTRL+F) now supports searching the entire model. When this option is selected in the dropdown, another dropdown appears that lets you choose which object properties to search. There are also options for regular expressions, backslash expressions and also [Dynamic LINQ search, similar to Tabular Editor 2.x](https://docs.tabulareditor.com/Advanced-Filtering-of-the-Explorer-Tree.html) (Dynamic LINQ can also be enabled by entering `:` as the first character in the "Find what" field). Search results are displayed in a separate window, and double-clicking on an item in the search results window will take you directly to that item, highlighting the relevant property in the property grid: + +![image](https://user-images.githubusercontent.com/30911111/119983803-edd94f80-bfc0-11eb-91cb-aee084e0c83d.png) + +- Added support for DAX date literal syntax `dt"2021-05-27"` +- Updated TOM to version 19.21.0 + +## Bugfixes and minor updates in BETA-18.5: + +- Added multiline string editor for table SourceExpressions +- Ensure relationship names are not regenerated when cutting and pasting +- Added BPA support for the `it` keyword in FixExpressions, see https://github.com/TabularEditor/TabularEditor/issues/846 +- Improved behavior of Find/Replace window when switching between documents/UI elements +- Fixed a bug with the precedence order of the NOT keyword, see https://github.com/TabularEditor/TabularEditor3/issues/5. diff --git a/content/localization/de/boosting-productivity-te3_de.md b/content/localization/de/boosting-productivity-te3_de.md new file mode 100644 index 00000000..4a7bce6c --- /dev/null +++ b/content/localization/de/boosting-productivity-te3_de.md @@ -0,0 +1,26 @@ +--- +uid: boosting-productivity-te3 +title: Boosting productivity with Tabular Editor 3 +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Boosting productivity with Tabular Editor 3 + +
+ +This section contains a number of articles that will let you quickly become familiar with Tabular Editor 3 and its main features, with an emphasis on how to get stuff done in the most productive way possible. + +Below is an overview of the articles and what you will learn in each: + +- @importing-tables-data-modeling: This article describes how to import tables, upate table schemas and visualize and edit relationships. +- @refresh-preview-query: This article describes how to schedule refresh operations, how to preview table data, how to view summarized data using Pivot Grids, how to create and execute DAX queries and how to use Tabular Editor 3's integrated version of [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/). +- @creating-and-testing-dax: This article introduces Tabular Editor 3's powerful DAX editor and demonstrates how to quickly add and edit DAX calculations to your model such as measures, calculated columns and calculated tables. +- @dax-script-introduction: This article demonstrates how to use the DAX scripting feature, to write, maintain and test complex business logic across multiple measures, by combining their definition in a single DAX script. +- @bpa: This article provides more details on the Best Practice Analyzer, and how to set up customizable Best Practice rules to improve the code quality of your models. +- @cs-scripts-and-macros: This article introduces the concepts of C# scripts in Tabular Editor 3, the script recorder and how to save scripts as reusable macros that can be integrated into the UI. +- @personalizing-te3: This article takes you through the wide range of configuration options and preferences available in Tabular Editor 3, to tweak the tool to your needs. + +# Next steps + +- @downloads \ No newline at end of file diff --git a/content/localization/de/bpa-view_de.md b/content/localization/de/bpa-view_de.md new file mode 100644 index 00000000..d9937aa6 --- /dev/null +++ b/content/localization/de/bpa-view_de.md @@ -0,0 +1,13 @@ +--- +uid: bpa-view +title: Best Practice Analyzer view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +[!include[using-bpa](~/content/common/using-bpa.md)] diff --git a/content/localization/de/bpa_de.md b/content/localization/de/bpa_de.md new file mode 100644 index 00000000..19d64d45 --- /dev/null +++ b/content/localization/de/bpa_de.md @@ -0,0 +1,116 @@ +--- +uid: bpa +title: Improve code quality with the Best Practice Analyzer +author: Daniel Otykier +updated: 2021-11-02 +--- + +# Improve code quality with the Best Practice Analyzer + +By now, you are probably already aware that the Tabular Object Model (TOM) is a relatively complex data structure, with many different types of objects and properties. It is not always clear what the best values to assign to these properties are, and many times it depends on specific use cases or model designs. Tabular Editor's **Best Practice Analyzer** continuously scans the TOM for violations of best practice rules that you can define. This helps you verify that object properties are always set to their ideal values. + +Things you can check with the Best Practice Analyzer: + +- **DAX Expressions** Create rules that warn you when certain DAX functions or constructs are used. +- **Formatting** Create rules that remind you to specify format strings, descriptions, etc. +- **Naming conventions** Create rules that check whether certain types of objects (e.g. key columns, hidden columns, etc.) follow certain name patterns. +- **Performance** Create rules that check various performance-related aspects of your model, for example to encourage reducing the number of calculated columns, etc. + +The Best Practice Analyzer has access to the full metadata of the model, and can also access VertiPaq Analyzer statistics for more advanced scenarios. + +> [!NOTE] +> Tabular Editor does not ship with any rules out-of-the-box. You will have to define your own rules initially, or use a set of standard rules such as [those recommended by the Power BI CAT Team](https://powerbi.microsoft.com/en-ca/blog/best-practice-rules-to-improve-your-models-performance/). + +# Managing Best Practice Rules + +In order to add, remove or modify rules applying to your model, use the "Tools > Manage BPA Rules..." menu option. + +![Bpa Manager](~/content/assets/images/bpa-manager.png) + +This UI contains two lists: The top list represents the **collections** of rules that are currently loaded. Selecting a collection in this list, will display all the rules that are defined within this collection in the bottom list. When a model is loaded, you will see the following three rule collections: + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%LocalAppData%\TabularEditor3\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +If the same rule (by ID) is located in more than one collection, the order of precedence is from top to bottom, meaning a rule defined within the model takes precedence over a rule, with the same ID, defined on the local machine. This allows you to override existing rules, for example to take model specific conventions into account. + +At the top of the list, you'll see a special collection called **(Effective rules)**. Selecting this collection will show you the list of rules that actually apply to the currently loaded model, respecting the precedence of rules with identical ID's, as mentioned above. The lower list will indicate which collection a rule belongs to. Also, you will notice that a rule will have its name striked out, if a rule with a similar ID exists in a collection of higher precedence: + +![Rule Overrides](~/content/assets/images/rule-overrides.png) + +## Adding additional collections + +Rule collections can be added to a specific model. If you have a rules file located on a network share, you can include that file as a rule collection in the current model. If you have write access to the location of the file, you'll also be able to add/modify/remove rules from the file. Rule collections that are added this way take precedence over rules that are defined within the model. If you add multiple such collections, you can shift them up and down to control their mutual precedence. + +Click the "Add..." button to add a new rule collection to the model. This provides the following options: + +![Add Best Practice rule collection](~/content/assets/images/add-rule-file.png) + +- **Create new Rule File**: This will create a new, empty, .json file at a specified location, which you can subsequently add rules to. When choosing the file, notice that there is an option for using relative file paths. This is useful when you want to store the rule file in the same code repository as the current model. However, please be aware that a relative rule file reference only works, when the model has been loaded from disk (since there is no working directory when loading a model from an instance of Analysis Services). +- **Include local Rule File**: Use this option if you already have a .json file containing rules, that you want to include in your model. Again, you have the option of using relative file paths, which may be beneficial if the file is located close to the model metadata. If the file is located on a network share (or generally, on a drive different than where the currently loaded model metadata resides), you can only include it using an absolute path. +- **Include Rule File from URL**: This option lets you specify an HTTP/HTTPS URL, that should return a valid set of rules (in json format). This is useful if you want to include rules from an online source, for example the [standard BPA rules](https://raw.githubusercontent.com/TabularEditor/BestPracticeRules/master/BPARules-standard.json) from the [BestPracticeRules GitHub site](https://github.com/TabularEditor/BestPracticeRules). Note that rule collections added from online sources will be read-only. + +## Modifying rules within a collection + +The lower part of the screen will let you add, edit, clone and delete rules within the currently selected collection, provided you have write access to the location where the collection is stored. Moreover, the "Move to..." button allows you to move or copy the selected rule to another collection, making it easy to manage multiple collections of rules. + +## Adding rules + +To add a new rule to a collection, click on the **New rule...** button. This brings up the Best Practice Rule editor (see screenshot below). + +![Bpa Rule Editor](~/content/assets/images/bpa-rule-editor.png) + +When creating a new rule, you must specify the following details: + +- **Name**: The name of the rule, which will be displayed to users of Tabular Editor +- **ID**: An internal ID of the rule. Must be unique within a rule collection. If multiple rules have identical IDs across different collections, only the rule within the collection of the highest precedence is applied. +- **Severity**: The severity is not used within Tabular Editor's UI, but when running a Best Practice Analysis through [Tabular Editor's command line interface](xref:command-line-options), the number determines how "severe" a rule violation is. + - 1 = Information only + - 2 = Warning + - 3 (or above) = Error +- **Category**: This is used for logically grouping rules together to make management of rules easier. +- **Description** (optional): Can be used to provide a description of what the rule is intended for. Will be shown in the Best Practice Analyzer view as a tooltip. You may use the following placeholder values within the description field, to provide a more contextual message: + - `%object%` returns a fully qualified DAX reference (if applicable) to the current object + - `%objectname%` returns only the name of the current object + - `%objecttype%` returns the type of the current object +- **Applies to**: Select the type of object(s) to which the rule should apply. +- **Expression**: Type a [Dynamic LINQ](https://dynamic-linq.net/expression-language) search expression which should evaluate to `true` for those objects (among the object types selected in the **Applies to** dropdown) that violate the rule. The Dynamic LINQ expression can access the TOM properties available on the selected object types, as well as a wide range of standard .NET methods and properties. +- **Minimum compatibility level**: Some TOM properties are not available at all compatibility levels. If you are creating generic rules, use this dropdown to specify the minimum compatibility level of the models to which the rule should apply. + +When a rule is saved to a rule collection on disk, all of the above properties are stored in a JSON format. You can add/edit/delete rules by editing the JSON file as well, which also allows you to specify the `FixExpression` property on a rule. This is a string that is used to generate a [C# script](xref:cs-scripts-and-macros) which will be applied to the model in order to fix the rule violation. + +# Using the Best Practice Analyzer view + +Tabular Editor displays the best practice rule violations within the **Best Practice Analyzer view**. You can also see the number of rule violations in the status bar at the bottom of the main window. To bring the view into focus, use the **View > Best Practice Analyzer** menu option or blick on the "# BP issues" button in the status bar. + +![Best Practice Analyzer View](~/content/assets/images/best-practice-analyzer-view.png) + +The **Best Practice Analyzer view** shows a list of all rules that have objects in violation. Below each rule is a list of the violating objects. You can double-click on an object in the list, to navigate to that object in the **TOM Explorer**. + +![Item options](~/content/assets/images/bpa-options.png) + +When right-clicking on an object, you are presented with a number of options as shown above. These are: + +- **Go to object**: This is identical to double-clicking on an object, in order to navigate to that object in the **TOM Explorer**. +- **Ignore object**: This adds an annotation on the object, instructing the Best Practice Analyzer to ignore this particular rule on that object. Ignored rules are specified using their ID. +- **Generate fix script**: This option is available only if a rule has the `FixExpression` property specified. When choosing this option, Tabular Editor creates a new C# script based on the `FixExpression` of the selected rule(s). +- **Apply fix**: This option is available only if a rule has the `FixExpression` property specified. When choosing this option, Tabular Editor executes the `FixExpression` of the selected rule(s) in order to automatically fix the rule violation. + +> [!NOTE] +> You can multi-select objects in the Best Practice Analyzer view, by holding down the Shift or Ctrl keys. + +The options shown above are also available as toolbar buttons at the top of the **Best Practice Analyzer view**. In addition, there are buttons available for expanding/collapsing all items, showing ignored rules/objects and for performing a manual refresh (which is needed when background scans are disabled, see below). + +# Disabling the Best Practice Analyzer + +In some cases, you may want to disable the Best Practice Analyzer background scan. For example, when you have rules that take a relatively long time to evaluate, or when you are working with very large models. + +The background scan can be disabled under **Tools > Preferences > Features > Best Practice Analyzer** by unchecking the **Scan for Best Practice violations in the background**. + +Note that you can still manually perform a scan using the **Refresh** button of the **Best Practice Analyzer view**, as mentioned above, even when background scans are disabled. + +# Next steps + +- @cs-scripts-and-macros +- @personalizing-te3 \ No newline at end of file diff --git a/content/localization/de/calendars_de.md b/content/localization/de/calendars_de.md new file mode 100644 index 00000000..76acb477 --- /dev/null +++ b/content/localization/de/calendars_de.md @@ -0,0 +1,53 @@ +--- +uid: calendars +title: Calendars (Enhanced Time Intelligence) +author: Daniel Otykier +updated: 2025-09-15 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Calendars (Enhanced Time Intelligence) + +The September 2025 release of Power BI Desktop introduced a new Public Preview feature called "Enhanced Time Intelligence". This feature lets you define custom calendars in your semantic model, and it also introduces 8 new DAX functions that work with these calendars, enabling week-based time intelligence calculations that were difficult to perform previously. + +Tabular Editor 3 has support for Calendars and the new DAX functions since version 3.23.0. + +## Defining a Calendar + +![Creating a calendar](~/content/assets/images/calendar-create.png) + +1. Right-click on a table in your model (typically a Date table) and select **Create > Calendar...**. +2. Give your calendar a name, e.g. "Fiscal" + +Once calendars are added to a table, they will be shown in the TOM Explorer under the **Calendars** node: + +![Calendar in TOM Explorer](~/content/assets/images/calendar-tom-explorer.png) + +Before you can use a calendar in your DAX calculations, you need to configure it by specifying which columns in the table represent the different calendar attributes. You can do this by right-clicking on the calendar in the TOM Explorer, then choosing the **Edit Column Mappings...** option: + +![Editing calendar column mappings](~/content/assets/images/edit-calendar-mappings.png) + +For each calendar, you can add one or more so-called **Column Associations**. Each such association maps a column from the table, to a specific **Time Unit** (e.g. Year, Month, Week, etc.). You can also add additional associated columns for each mapping, which are typically used for columns that represent the same time unit, but in a different format. For example, you might have a "Month" column that contains the month number (1-12), and a "Month Name" column that contains the month name ("January", "February", etc.). Both of these columns can be associated with the "MonthOfYear" time unit. + +![Calendar column associations](~/content/assets/images/calendar-example.png) + +## Using Calendars in DAX + +Once you've defined a calendar and mapped its columns, you can start using it in your DAX calculations. Calendars work with all DAX functions that accept a date column as input (such as [`TOTALYTD`](https://dax.guide/totalytd), [`CLOSINGBALANCEMONTH`](https://dax.guide/closingbalancemonth) and [`DATEADD`](https://dax.guide/dateadd)). + +Moreover, 8 new DAX functions for week-based time intelligence have been introduced. These exclusively work with calendars: + +- [`CLOSINGBALANCEWEEK`](https://dax.guide/closingbalanceweek) +- [`OPENINGBALANCEWEEK`](https://dax.guide/openingbalanceweek) +- [`STARTOFWEEK`](https://dax.guide/startofweek) +- [`ENDOFWEEK`](https://dax.guide/endofweek) +- [`NEXTWEEK`](https://dax.guide/nextweek) +- [`PREVIOUSWEEK`](https://dax.guide/previousweek) +- [`DATESWTD`](https://dax.guide/dateswtd) +- [`TOTALWTD`](https://dax.guide/totalwtd) + +Click the links above to learn more about each function. \ No newline at end of file diff --git a/content/localization/de/code-actions_de.md b/content/localization/de/code-actions_de.md new file mode 100644 index 00000000..d285158e --- /dev/null +++ b/content/localization/de/code-actions_de.md @@ -0,0 +1,133 @@ +--- +uid: code-actions +title: Code Actions +author: Daniel Otykier +updated: 2024-10-30 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Code Actions + +Tabular Editor 3.18.0 introduces a new feature called **Code Actions**. This feature is enabled by default but can be disabled in the **Tools > Preferences** dialog under **Text Editors > DAX Editor > Code Actions**. + +Code Actions is a productivity feature that discretely provides suggestions for improving your DAX code. You can apply the suggestions with a single click. Code Actions also provides easy access to common code refactoring operations. + +Code Actions are separated into three different categories: + +1. **Improvements**: These are recommended suggestions for improving your DAX code in terms of: + - Following best practices + - Avoiding common pitfalls and anti-patterns + - Avoiding obsolete or deprecated DAX features + - Writing better, more performant DAX code +2. **Readability**: These are suggestions for making your DAX code more readable by... + - Simplifying complex expressions, when possible + - Remove redundant or unnecessary code + - Applying consistent formatting and naming conventions +3. **Rewrites**: These are suggestions for refactoring your DAX code. They are not necessarily improvements but are often useful for larger code refactorings. Examples are: + - Convert DAX "syntax sugar" to more verbose but more explicit code + - Rename all occurrences of a variable or an extension column + - Format code + +## How to use Code Actions + +A new command and corresponding toolbar/menu buttons have been added, **Show Code Actions**, with a default keyboard shortcut of `Ctrl+.`. This command will show the applicable Code Actions at the current cursor position: + +![Code Action Invoke Menu](~/content/assets/images/code-action-invoke-menu.png) + +You can also find the applicable Code Actions through the **Refactor** submenu of the right-click context menu: + +![Code Action Refactor Submenu](~/content/assets/images/code-action-refactor-submenu.png) + +Lastly, a lightbulb or screwdriver icon is shown in the editor's left margin when the cursor is placed on a code segment with applicable actions. Clicking on the icon will also bring up the Code Actions menu: + +![Code Actions Margin](~/content/assets/images/code-action-margin.png) + +When you hover the mouse cursor over an action in the Code Actions menu, a tooltip will show more information about the action. Click the "Learn more" link, to view the knowledge-base (KB) article for the action. + +![Code Action Tooltip](~/content/assets/images/code-action-tooltip.png)] + +## Code Action indicators + +**Improvements** and **Readability** Code Actions will also be indicated visually in the code editor. This lets you quickly determine which parts of your code can be improved or made more readable. + +- **Improvements** are shown with orange dots under the first few characters of the code segment (unless that code segment already displays an orange warning squiggly). A _lightbulb_ icon will appear in the left margin when the cursor is moved over the code segment. +- **Readability** actions are shown with teal green dots under the first few characters of the code segment. When the cursor is moved over the code segment, a _screwdriver_ icon will appear in the left margin. +- **Rewrites** are not visually indicated in the code itself; however, the _screwdriver_ icon will appear in the left margin when the cursor is placed on a code segment with applicable rewrites. + +## Apply to all occurrences + +Some Code Actions can be applied to all occurrences within the current DAX expression, DAX script, or DAX query rather than just the code segment under the cursor. When this is the case, the Code Action will be shown in the Code Actions menu with " (All occurrences)" appended to the action description. Clicking on the action will apply the change to all occurrences in the document. + +In the screenshot below, for example, the **Prefix variable with '_'** action can be applied to all occurrences (i.e., all variables) in the document, not just the `totalSales` variable under the cursor: + +![Code Action All Occurrences](~/content/assets/images/code-action-all-occurrences.png) + +## List of Code Actions + +The table below lists all currently available Code Actions. You can toggle off Code Actions in the **Tools > Preferences** dialog under **Text Editors > DAX Editor > Code Actions** (a future update will let you toggle individual actions for a more customized experience). Some Code Actions also have additional configuration options, such as which prefix to use for variable names. + +### Improvements + +The Code Actions below will appear with orange dots under the first two characters of the applicable code and a lightbulb icon in the left margin when the cursor is placed on the code segment: + +| ID | Name | Description | +| ----- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DI001 | [Remove unused variable](xref:DI001) | Variables not referenced anywhere should be removed. Example:
`VAR a = 1 VAR b = 2 RETURN a` -> `VAR a = 1 RETURN a` | +| DI002 | [Remove all unused variables](xref:DI002) | Variables that are not being used (directly or indirectly through other variables) in the `RETURN` part of a variable block should be removed. Example:
`VAR a = 1 VAR b = a RETURN 123` -> `123` | +| DI003 | [Remove table name](xref:DI003) | Measure references should not include the table name, as the table name is unnecessary when referencing measures. Moreover, this practice makes measure references more easily distinguishable from column references. Example:
`Sales[Total Sales]` -> `[Total Sales]` | +| DI004 | [Add table name](xref:DI004) | Column references should include the table name to avoid ambiguities and to more easily distinguish column references from measure references. Example:
`SUM([SalesAmount])` -> `SUM(Sales[SalesAmount])` | +| DI005 | [Rewrite table filter as scalar predicate](xref:DI005) | A common anti-pattern in DAX is to filter a table inside a [`CALCULATE`](https://dax.guide/CALCULATE) filter argument when it is sufficient to filter one or more columns from that table. Example:
`CALCULATE([Total Sales], FILTER(Products, Products[Color] = "Red"))` -> `CALCULATE([Total Sales], KEEPFILTERS(Products[Color] = "Red"))`
This Code Action supports various variations of the original expression. | +| DI006 | [Split multi-column filter into multiple filters](xref:DI006) | When filtering a table on multiple columns combined using `AND` (or the equivalent `&&` operator), better performance can often be achieved by specifying multiple filters, one for each column. Example:
`CALCULATE(..., Products[Color] = "Red" && Products[Size] = "Large")` -> `CALCULATE(..., Products[Color] = "Red", Products[Size] = "Large")` | +| DI007 | [Simplify SWITCH statement](xref:DI007) | 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:
`SWITCH(TRUE(), a = 1, ..., a = 2, ...)` -> `SWITCH(a, 1, ..., 2, ...)` | +| DI008 | [Remove superfluous CALCULATE](xref:DI008) | A [`CALCULATE`](https://dax.guide/CALCULATE) function that is not necessary because it does not modify the filter context, or because an implicit context transition would happen anyway, should be removed. Examples:
`CALCULATE([Total Sales])` -> `[Total Sales]`
`AVERAGEX(Product, CALCULATE([Total Sales]))` -> `AVERAGEX(Product, [Total Sales])`

Also applies when the first argument of `CALCULATE` / `CALCULATETABLE` is a DAX variable, e.g.:
`VAR x = [Total Sales] RETURN CALCULATE(x, Product[Color] = "Red")` ->
`VAR x = [Total Sales] RETURN x` | +| DI009 | [Avoid calculate shortcut syntax](xref:DI009) | Example:
`[Total Sales](Products[Color] = "Red")` -> `CALCULATE([Total Sales], Products[Color] = "Red")` | +| DI010 | [Use MIN/MAX instead of IF](xref:DI010) | When a conditional expression is used to return the minimum or maximum of two values, it is more efficient and compact to use the [`MIN`](https://dax.guide/MIN) or [`MAX`](https://dax.guide/MAX) function. Example:
`IF(a > b, a, b)` -> `MAX(a, b)` | +| DI011 | [Use ISEMPTY instead of COUNTROWS](xref:DI011) | When checking if a table is empty, it is more efficient to use the [`ISEMPTY`](https://dax.guide/ISEMPTY) function than to count the rows of the table. Examples:
`COUNTROWS(Products) = 0` -> `ISEMPTY(Products)` | +| DI012 | [Use DIVIDE instead of division](xref:DI012) | When using an arbitrary expression in the denominator of a division, use [`DIVIDE`](https://dax.guide/DIVIDE) instead of the division operator to avoid division by zero errors. Example:
`x / y` -> `DIVIDE(x, y)` | +| DI013 | [Use division instead of DIVIDE](xref:DI013) | When the 2nd argument of [`DIVIDE`](https://dax.guide/DIVIDE) is a non-zero constant, it is more efficient to use the division operator. Example:
`DIVIDE(x, 2)` -> `x / 2` | +| DI014 | [Replace IFERROR with DIVIDE](xref:DI014) | Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IFERROR`](https://dax.guide/IFERROR) to provide an alternate result when a division has a zero denominator. Example:
`IFERROR(x / y, 0)` -> `DIVIDE(x, y, 0)` | +| DI015 | [Replace IF with DIVIDE](xref:DI015) | Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IF`](https://dax.guide/IF) to more easily check for zero or blank in the denominator. Example:
`IF(y <> 0, x / y)` -> `DIVIDE(x, y)` | + +### Readability + +The Code Actions below will appear with teal green dots under the first two characters of the applicable code and a screwdriver icon in the left margin when the cursor is placed on the code segment + +| ID | Name | Description | | | | | | | +| ----- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | ------------------------------------------------------------------------------------------------ | - | ----- | - | ------------------------------- | +| DR001 | [Convert to scalar predicate](xref:DR001) | A column filter can be written more concisely as a scalar predicate without explicitly using the [`FILTER`](https://dax.guide/FILTER) function. Examples:
`FILTER(ALL(Products[Color]), Products[Color] = "Red")` -> `Products[Color] = "Red"`
`FILTER(VALUES(Products[Color]), Products[Color] = "Red")` -> `KEEPFILTERS(Products[Color] = "Red")` | | | | | | | +| DR002 | [Use aggregator instead of iterator](xref:DR002) | Use an aggregator function instead of an iterator function when possible to simplify the code. Example:
`SUMX(Products, Products[SalesAmount])` -> `SUM(Products[SalesAmount])` | | | | | | | +| DR003 | [Use VALUES instead of SUMMARIZE](xref:DR003) | When [`SUMMARIZE`](https://dax.guide/SUMMARIZE) only specifies a single column, and that column belongs to the table specified in the first argument, the code can be more concisely written using [`VALUES`](https://dax.guide/VALUES). Example:
`SUMMARIZE(Products, Products[Color])` -> `VALUES(Products[Color])` | | | | | | | +| DR004 | [Prefix variable](xref:DR004) | Variables should use a consistent naming convention. It is recommended to use a prefix, such as an underscore. You can configure which prefix to use to match your preferred style. Example:
`VAR totalSales = SUM(Sales[SalesAmount])` -> `VAR _totalSales = SUM(Sales[SalesAmount])` | | | | | | | +| DR005 | [Prefix temporary columns](xref:DR005) | Using a consistent prefix for temporary columns is recommended to more easily distinguish them from base columns or measures. You can configure which prefix to use to match your preferred style. Example:
`ADDCOLUMNS(Product, "SalesByProd", [Sales])` -> `ADDCOLUMNS(Product, "@SalesByProd", [Sales])` | | | | | | | +| DR006 | [Move constant aggregation to variable](xref:DR006) | When an aggregation function is used inside an iterator or a scalar predicate, the aggregation produces the same result for every row of the iteration. Therefore, the aggregation could be moved to a DAX variable outside of the iteration. Example:
`CALCULATE(..., 'Date'[Date] = MAX('Date'[Date]))` ->
`VAR _maxDate = MAX('Date'[Date]) RETURN CALCULATE(..., 'Date'[Date] = _maxDate)` | | | | | | | +| DR007 | [Simplify 1-variable block](xref:DR007) | A variable block with only one variable can be simplified by moving the expression directly into the `RETURN` part of the block. This assumes the variable is only referenced once without any context modifiers. Example:
`VAR _result = [Sales] * 1.25 RETURN _result` -> `[Sales] * 1.25` | | | | | | | +| DR008 | [Simplify multi-variable block](xref:DR008) | A variable block with multiple variables where each is a simple measure reference, which is only used once in the `RETURN` section without any context modifiers, should be simplified. Example:
`VAR _sales = [Sales] VAR _cost = [Cost] RETURN _sales - _cost` -> `[Sales] - [Cost]` | | | | | | | +| DR009 | [Rewrite using DISTINCTCOUNT](xref:DR009) | Instead of using `COUNTROWS(DISTINCT(T[c])` to count the number of distinct values in a column, use the [`DISTINCTCOUNT`](https://dax.guide/DISTINCTCOUNT) function. | | | | | | | +| DR010 | [Rewrite using COALESCE](xref:DR010) | Instead of using `IF` to return the first non-blank value from a list of expressions, use the [`COALESCE`](https://dax.guide/COALESCE) function. Example:
`IF(ISBLANK([Sales]), [Sales2], [Sales])` -> `COALESCE([Sales], [Sales2])` | | | | | | | +| DR011 | [Rewrite using ISBLANK](xref:DR011) | Instead of comparing an expression with [`BLANK()`](https://dax.guide/BLANK), use the [`ISBLANK`](https://dax.guide/ISBLANK) function. Example:
`IF([Sales] = BLANK(), [Budget], [Sales])` -> `IF(ISBLANK([Sales], [Budget], [Sales])` | | | | | | | +| DR012 | [Remove unnecessary BLANK](xref:DR012) | Some DAX functions, such as [`IF`](https://dax.guide/IF) and [`SWITCH`](https://dax.guide/SWITCH) already return `BLANK()` when the condition is false, so there is no need to explicitly specify `BLANK()`. Example:
`IF(a > b, a, BLANK())` -> `IF(a > b, a)` | | | | | | | +| DR013 | [Simplify negated logic](xref:DR013) | When a logical expression is negated, it is often more readable to rewrite the expression using the negated operator. Example:
`NOT(a = b)` -> `a <> b` | | | | | | | +| DR014 | [Simplify using IN](xref:DR014) | Rewrite compound predicates (equality comparisons of the same expression that are combined using [`OR`](https://dax.guide/OR) or [\` | | `](https://dax.guide/op/or/)) with the [`IN`](https://dax.guide/IN) operator. Example:
`a = 1 | | a = 2 | | a = 100`->`a IN { 1, 2, 100 }\` | + +### Rewrites + +The Code Actions below will appear with a screwdriver icon in the left margin when the cursor is placed on the code segment. + +| ID | Name | Description | +| ----- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RW001 | [Rewrite TOTALxTD using CALCULATE](xref:RW001) | Functions such as [`TOTALMTD`](https://dax.guide/TOTALMTD), [`TOTALQTD`](https://dax.guide/TOTALQTD) and [`TOTALYTD`](https://dax.guide/TOTALYTD) can be rewritten using the [`CALCULATE`](https://dax.guide/CALCULATE) function, which is more expressive and provides greater flexibility. Example:
`TOTALYTD([Total Sales], 'Date'[Date])` -> `CALCULATE([Total Sales], DATESYTD('Date'[Date]))` | +| RW002 | [Rewrite using FILTER](xref:RW002) | A scalar predicate in a filter argument to `CALCULATE` can be rewritten using `FILTER`. This is useful, for example, when you need to add more complex filtering logic. Example:
`CALCULATE(..., Products[Color] = "Red")` -> `CALCULATE(..., FILTER(ALL(Products[Color]), Products[Color] = "Red"))` | +| RW003 | [Invert IF](xref:RW003) | To improve readability, it is sometimes useful to invert `IF` statements. Example:
`IF(a < b, "B is greater", "A is greater")` -> `IF(a > b, "A is greater", "B is greater")` | + +## Customizing Code Actions + +You can customize the behavior of Code Actions through the **Tools > Preferences** dialog under **Text Editors > DAX Editor > Code Actions**. Here, you can toggle the feature on and off and configure additional options for some Code Actions, such as the prefix to use for variable names and extension columns. + +We plan to add more configuration options to this screen in future versions, such as an option to toggle individual Code Actions on and off. Stay tuned! + +![Code Actions Preferences](~/content/assets/images/code-actions-preferences.png) + diff --git a/content/localization/de/common-features_de.md b/content/localization/de/common-features_de.md new file mode 100644 index 00000000..5d02a922 --- /dev/null +++ b/content/localization/de/common-features_de.md @@ -0,0 +1,5 @@ +# Common features + +A lot of Tabular Editor functionality is shared between both Tabular Editor 2.x and Tabular Editor 3.x. This section holds articles that are related to such shared functionality. + +A few minor differences exist, which are highlighted whenever they occur. For example, C# scripting is called "Advanced Scripting" in Tabular Editor 2.x, and macros are called "Custom Actions". diff --git a/content/localization/de/connecting-to-azure-databricks_de.md b/content/localization/de/connecting-to-azure-databricks_de.md new file mode 100644 index 00000000..fe2d83a4 --- /dev/null +++ b/content/localization/de/connecting-to-azure-databricks_de.md @@ -0,0 +1,205 @@ +--- +uid: connecting-to-azure-databricks +title: Connecting to Azure Databricks +author: David Bojsen +updated: 2025-08-05 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Connecting to Azure Databricks + +Tabular Editor 3 supports connecting to Azure Databricks as a data source for your semantic models. This tutorial will guide you through the process of setting up a connection to Azure Databricks and importing data from it. + +## Prerequisites + +Before you begin, ensure you have the following: + +- A valid Azure Databricks workspace +- Appropriate permissions to access the Databricks data +- Tabular Editor 3 (Desktop, Business, or Enterprise edition) + +## Authentication Methods + +When connecting to Azure Databricks, you have two main authentication methods: + +### 1. Microsoft Entra ID (formerly Azure AD) Authentication + +This is the recommended approach for connecting to Azure Databricks when your organization uses Microsoft Entra ID. This method provides seamless single sign-on and better security through managed identities. + +#### About the Tabular Editor Enterprise Application + +When you connect to Azure Databricks using Microsoft Entra ID authentication, Tabular Editor uses a registered enterprise application named "Tabular Editor 3 - User Delegated Access to Azure Databricks" with the Application (client) ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c`. + +This enterprise application requires the following API permissions: + +- **Microsoft Graph** (`00000003-0000-0000-c000-000000000000`) + - `offline_access` (Delegated) - This permission allows Tabular Editor to maintain access to the data you've given it permission to access, even when you're not actively using the application. This is needed for maintaining a persistent connection to Databricks. + - `openid` (Delegated) - Allows users to sign in to the app with their work or school accounts and allows the app to see basic user profile information. + - `profile` (Delegated) - Allows the app to see basic profile information such as name, email, picture, username. + - `User.Read` (Delegated) - Allows the app to read your profile, and to identify you when accessing the Databricks API. + +- **Azure Databricks API** (`2ff814a6-3304-4ab8-85cb-cd0e6f879c1d`) + - `user_impersonation` (Delegated) - Access Azure Databricks on behalf of the signed-in user. This allows Tabular Editor to connect to your Databricks workspace using your credentials. + +For more information about Microsoft Entra ID permissions, please refer to the [Microsoft documentation on permission types](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent) and [application consent experience](https://learn.microsoft.com/en-us/azure/active-directory/develop/application-consent-experience). + +> [!IMPORTANT] +> These permissions are required for Tabular Editor to access your Azure Databricks data securely through your Microsoft Entra ID credentials. Without these permissions, Tabular Editor cannot authenticate to your Azure Databricks workspace properly. + +#### Consent Process for Microsoft Entra ID Authentication + +When you first attempt to connect to Azure Databricks using Microsoft Entra ID authentication, you may be prompted to consent to the required permissions. The consent process depends on your organization's Microsoft Entra ID policies: + +##### User Consent + +If your organization allows user consent for applications: + +1. You will see a consent prompt from Microsoft asking for permission to allow Tabular Editor to access Azure Databricks on your behalf +2. Review the permissions being requested +3. Click **Accept** to grant consent + +> [!NOTE] +> Whether admin consent is required depends on your organization's Microsoft Entra ID policies, not necessarily the specific API permissions being requested. Many organizations allow users to consent to delegated permissions themselves, while others require administrator approval for all third-party applications regardless of permission level. + +##### Admin Consent Required + +If your organization restricts user consent (common in enterprise environments): + +1. You will receive an error message indicating that admin consent is required +2. You'll need to contact your IT department or Microsoft Entra ID administrator +3. Provide them with: + - Application Name: "Tabular Editor 3 - User Delegated Access to Azure Databricks" + - Application ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c` + - Required Permissions: Microsoft Graph (offline_access, openid, profile, User.Read) and Azure Databricks API (user_impersonation) + +Your administrator can grant organization-wide consent in one of two ways: + +**Option 1: Through the Microsoft Entra ID Admin Portal** + +1. Navigate to Microsoft Entra ID > Enterprise Applications +2. Search for "Tabular Editor 3 - User Delegated Access to Azure Databricks" +3. Select the application and go to Permissions +4. Click "Grant admin consent for [Organization]" + +**Option 2: Using the Direct Admin Consent URL** +Administrators can use the following direct link to grant consent: + +``` +https://login.microsoftonline.com/organizations/v2.0/adminconsent?client_id=ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c&scope=https://graph.microsoft.com/offline_access%20https://graph.microsoft.com/openid%20https://graph.microsoft.com/profile%20https://graph.microsoft.com/User.Read%202ff814a6-3304-4ab8-85cb-cd0e6f879c1d/user_impersonation&redirect_uri=https://tabulareditor.com +``` + +For more information about admin consent, see Microsoft's documentation on [Configure how users consent to applications](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent). + +#### Steps for Microsoft Entra ID Authentication: + +1. In Tabular Editor 3, go to **Model** > **Import tables...** +2. Select **New Source** > **Databricks** +3. In the connection dialog: + - Enter your Databricks workspace URL (format: `https://.azuredatabricks.net`) + - Select **Microsoft Entra ID** as the authentication method + - For HTTP Path, specify the path to your Databricks cluster (e.g., `/sql/1.0/warehouses/`) + +> [!NOTE] +> Your Databricks workspace URL should be in the format `https://.azuredatabricks.net` - for example, `https://westeurope.azuredatabricks.net`. + +### 2. Personal Access Token (PAT) Authentication + +If Microsoft Entra ID integration is not available or if you prefer token-based authentication, you can use a Personal Access Token. + +#### Steps for PAT Authentication: + +1. Generate a Personal Access Token in your Azure Databricks workspace: + - Go to your Databricks workspace + - Click on your user profile icon in the top-right corner + - Select **User Settings** + - Go to the **Access Tokens** tab + - Click **Generate New Token** + - Provide a name and optionally set an expiration time + - Click **Generate** and copy the token value + +2. In Tabular Editor 3, go to **Model** > **Import tables...** + +3. Select **New Source** > **Databricks** + +4. In the connection dialog: + - Enter your Databricks workspace URL + - Select **Personal Access Token** as the authentication method + - Paste your token into the Token field + - For HTTP Path, specify the path to your Databricks cluster (e.g., `/sql/1.0/warehouses/`) + +## Finding Your HTTP Path + +The HTTP Path parameter is essential for connecting to your Databricks SQL warehouse. To find this value: + +1. Go to your Databricks workspace +2. Navigate to **SQL** > **SQL Warehouses** +3. Select the SQL warehouse you want to connect to +4. Look for the **Connection Details** section +5. Copy the HTTP Path value which should be in the format: `/sql/1.0/warehouses/` + +## Importing Tables from Databricks + +Once you've configured your connection: + +1. Click **Test Connection** to verify your credentials and connection settings +2. If the connection is successful, click **Next** +3. Select whether to import specific tables/views or use a custom SQL query +4. If selecting tables/views: + - Browse through the available catalogs, schemas, and tables + - Select the tables you wish to import + - Optionally preview and filter columns +5. Review your selections and click **Import** to finalize + +## Troubleshooting Connection Issues + +If you encounter issues connecting to Azure Databricks: + +- Verify your workspace URL is correct and accessible +- Ensure your Personal Access Token hasn't expired (if using PAT authentication) +- Check that your user account has the necessary permissions in Databricks +- Verify the HTTP Path points to an active SQL warehouse +- Ensure your network allows connections to the Databricks service + +### Resolving Microsoft Entra ID Authentication Issues + +If you're using Microsoft Entra ID authentication and encounter errors: + +#### "AADSTS65001: The user or administrator has not consented to use the application" + +This error occurs when the required permissions haven't been granted: + +1. If you have sufficient privileges: + - Click the consent link in the error message + - Review and accept the permissions request + +2. If you don't have sufficient privileges: + - Contact your IT administrator + - Provide them with the application ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c` + - Request they grant organizational consent for the Tabular Editor enterprise application + +#### "AADSTS700016: Application with identifier was not found in the directory" + +This may occur if your organization uses a restricted application policy: + +1. Contact your Microsoft Entra ID administrator +2. Request that they add the Tabular Editor enterprise application (ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c`) to your organization's allowed application list + +> [!TIP] +> In some organizations, IT departments may require a formal request or security review before approving new enterprise applications. Be prepared to explain that this application is used by Tabular Editor 3 to securely connect to Azure Databricks resources using the organization's existing Microsoft Entra ID authentication infrastructure. + +## Using Update Table Schema with Databricks + +After importing tables from Azure Databricks, you can use Tabular Editor's **Update Table Schema** feature to keep your model in sync with changes in the Databricks tables. + +To update the schema: + +1. Right-click on the imported table in the TOM Explorer +2. Select **Update Table Schema** +3. Review any detected changes and apply them as needed + +For complex queries or if you encounter issues with schema detection, consider enabling the **Use Analysis Services for change detection** option under **Tools** > **Preferences** > **Schema Compare** as described in the [Updating Table Schema](xref:importing-tables#updating-table-schema-through-analysis-services) documentation. + diff --git a/content/localization/de/creating-and-testing-dax_de.md b/content/localization/de/creating-and-testing-dax_de.md new file mode 100644 index 00000000..4a1d8a0e --- /dev/null +++ b/content/localization/de/creating-and-testing-dax_de.md @@ -0,0 +1,131 @@ +--- +uid: creating-and-testing-dax +title: Adding measures and other calculated objects +author: Daniel Otykier +updated: 2021-10-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Adding measures and other calculated objects + +Ever since Tabular Editor 2.x got released in early 2017, the ability to quickly modify DAX expressions across measures has always been the most popular feature of the tool. Combined with back and forward navigation, copy/paste operations, DAX dependency visualisation and undo/redo support, the tool has always been the preferred option for anyone working with large and complex data models, where the ability to quickly make multiple smaller changes is crucial. + +The only complaint in this regard, by users of Tabular Editor 2.x, was the lack of DAX code assist features (sometimes called "IntelliSense"). Especially when you are not a 100% proficient with DAX (and very few people are!), having the DAX code editor assist you in remembering syntax, function parameters, etc. is incredibly helpful. + +This has all been addressed with the new DAX code editor used by Tabular Editor 3. + +![Editing a complex DAX expression](~/content/assets/images/dax-editor-screenshot.png) + +The remainder of this article describes how to create measures and other calculated objects, and how to modify the DAX expressions on these objects. To learn more about the many features of the DAX code editor, see . + +# Adding measures + +Once you have [imported some tables](xref:importing-tables-data-modeling#importing-new-tables) to your model and [created relationships between them](xref:importing-tables-data-modeling#modifying-relationships-using-the-diagram), it is time to add some explicit measures containing your business logic. + +> [!TIP] +> Technically, you are not required to add explicit measures to your model before visualizing data in a Power BI report. However, it is a best practice to always do so, as MDX-based client tools (such as Excel and Tabular Editor 3's Pivot Grid) requires explicit measures. In addition, [Calculation Groups](https://docs.microsoft.com/en-us/analysis-services/tabular-models/calculation-groups?view=asallproducts-allversions) only apply to explicit measures. + +To add a new measure using Tabular Editor, right-click on the table in which you want to add the measure, then choose **Create > Measure** (ALT+1). + +![Adding New Measure](~/content/assets/images/adding-new-measure.png) + +When a new measure is added, the name of that measure will be editable. Hit ENTER when you have provided a name for the measure. You can always edit the name later in the **Properties** view or by pressing F2 while the measure is selected in the **TOM Explorer**. + +The **Expression Editor** view is used to provide the DAX expression for the measure. As you enter the code, notice how the DAX editor provides code suggestions and even underlines syntax or semantic errors. + +![Add Measure Edit Dax](~/content/assets/images/add-measure-edit-dax.png) + +The dropdown box at the top left corner of the **Expression Editor** is used to switch between different DAX properties of the currently selected object. For example, in newer versions of Analysis Services, measures have an `Expression` property as well as a [`Detail Rows Expression`](https://www.sqlbi.com/articles/controlling-drillthrough-in-excel-pivottables-connected-to-power-bi-or-analysis-services/). Other types of objects can have different properties that contain DAX code. For example, [KPIs](https://docs.microsoft.com/en-us/analysis-services/tabular-models/kpis-ssas-tabular?view=asallproducts-allversions) have three different DAX properties. To add a KPI in Tabular Editor, right-click on a measure and choose **Create > KPI**. + +![Editing Kpis](~/content/assets/images/editing-kpis.png) + +If you want your measure to be hidden, simply right-click and choose the **Make invisible** (CTRL+I) option. Likewise, you can unhide a measure by choosing the **Make visible** (CTRL+U) option. + +## Other measure properties + +In addition to the `Name`, `Expression` and `Hidden` properties, you can use the **Properties** view to review and edit the value of all properties of the currently selected object(s) in the **TOM Explorer**. For measures, this is where you can set the `Format String`, for example. For more information, see [Properties view](xref:properties-view). + +# Adding calculated columns + +To add a calculated column, right-click on the table on which you want to add the column, and choose **Create > Calculated Column** (ALT+2). Give the column a name and edit its DAX expression using the **Expression Editor**, similar to how we did for measures above. + +> [!IMPORTANT] +> This option is not available by default when connected to a Power BI Desktop model. This is because of the [limitations of Power BI Desktop support for external tools](xref:desktop-limitations). Click the link to learn more. + +> [!NOTE] +> When the DAX expression of a calculated column has been changed, the table in which the column resides has to be refreshed before the column can be used in a report. See for more information. + +# Adding calculated tables + +To add a calculated table, right-click on the model or on the "Tables" folder, and choose **Create > Calculated Table** (ALT+6). Give the table a name and edit its DAX expression using the **Expression Editor**, similar to how we did for measures above. Notice that the columns on the table changes automatically, when you make a change to the DAX expression. This can cause cascading effects, if other DAX expressions reference the table, or if columns are used in a hierarchy. + +> [!IMPORTANT] +> This option is not available by default when connected to a Power BI Desktop model. This is because of the [limitations of Power BI Desktop support for external tools](xref:desktop-limitations). Click the link to learn more. + +> [!NOTE] +> When the DAX expression of a calculated table has been changed, the table has to be refreshed before it can be used in a report. See for more information. + +# Adding calculation groups + +To add a [calculation group](https://docs.microsoft.com/en-us/analysis-services/tabular-models/calculation-groups?view=asallproducts-allversions), right-click on the model or on the "Tables" folder, and choose **Create > Calculation Group** (ALT+7). Give the Calculation Group a name. Also consider a different name for the default **Name** column. + +> [!IMPORTANT] +> This option is only available on models at compatibility level 1500 or higher. + +To add calculation items, right-click on the newly created calculation group and choose **Create > Calculation Item**. Give the Calculation Item a name and edit its DAX expression using the **Expression Editor** similar to how we did for measures above. + +You can arrange the display order of Calculation Items by dragging them around in the TOM Explorer, or by setting the `Ordinal` property within the **Properties** view. + +> [!NOTE] +> When Calculation Items are added, renamed or removed from a Calculation Group, the Calculation Group has to be refreshed before it can be used in a report. See for more information. + +# Common modeling operations + +## Copy / paste + +All objects in the TOM Explorer can be copied and pasted with Tabular Editor. You can even copy and paste between different instances of Tabular Editor, and even between Tabular Editor 2.x and Tabular Editor 3. You can use the familiar keyboard shortcuts: + +- **Edit > Copy** (CTRL+C) +- **Edit > Cut** (CTRL+X) +- **Edit > Paste** (CTRL+V) + +> [!TIP] +> If you want to replace one table with another, retaining all existing relationships to/from that table, copy a table to the clipboard, then select the table you wish to replace in the TOM Explorer and paste. You will be prompted whether you want to replace the selected table with the one in the clipboard. + +## Undo / redo + +Whenever a change is made to an object or property in Tabular Editor, the complete history of changes is tracked, allowing you to undo every change made. You can use the familiar keyboard shortcuts: + +- **Edit > Undo** (CTRL+Z) +- **Edit > Redo** (CTRL+Y) + +> [!NOTE] +> All text editors in Tabular Editor 3 have their own undo/redo history, so if the cursor is currently within a text editor, the keyboard shortcuts will undo/redo the typing within that editor. You can use the options in the **Edit** menu to perform an undo/redo at the model level, or deactivate the current text editor by clicking on another element in the user interface (such as the TOM Explorer). + +# Navigation + +While the cursor is over an object reference in the DAX editor, right-click and choose **Go to definition** (F12) to quickly jump to that object. Of course, you can also navigate between objects using the TOM Explorer. + +You can use the arrow buttons in the top right corner of the **Expression Editor** to jump quickly back and forth between objects visited. + +## DAX Dependencies + +To view DAX dependencies between objects, select an object in the **TOM Explorer**, then right-click and choose **Show dependencies** (SHIFT+F12). This will open a window that displays the dependencies (in both directions) of the selected object. Double-click on an object in this window to quickly navigate to that object. + +![Dax Dependencies And Tom Explorer](~/content/assets/images/dax-dependencies-and-tom-explorer.png) + +# Display folders + +Once your model starts to gain a considerable number of measures, a good practice is to organize them using Display Folders. In Tabular Editor, to create a Display Folder, either edit the `Display Folder` property through the **Properties** view, or alternatively, right-click on the measure(s), and select the **Create > Display Folder** option. + +You can also cut/copy/paste or drag and drop objects between display folders. + +# Next steps + +- @dax-script-introduction +- @bpa +- @cs-scripts-and-macros \ No newline at end of file diff --git a/content/localization/de/creating-macros_de.md b/content/localization/de/creating-macros_de.md new file mode 100644 index 00000000..010be8a1 --- /dev/null +++ b/content/localization/de/creating-macros_de.md @@ -0,0 +1,66 @@ +--- +uid: creating-macros +title: Creating macros +author: Morten Lønskov +updated: 2023-12-07 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Creating macros + +Macros are C# scripts that have been saved in Tabular Editor to be easily reused across semantic models. +Saving a script as a Macro will allow that macro to be used when right clicking on the objects in the TOM Explorer making it simple to apply the script to your model. + +## Creating a Macro + +The first step in creating a Macro is to create and test a C# script. + +> [!TIP] +> ne easy way to get started with C# scripting is to use the built in record function that lets you record the actions you take in the TOM Explorer. +> his way you can see how to interact with the different model objects and create reusable scripts. +> nother way is to reuse existing scripts such as those in our [script library](xref:csharp-script-library). +> n this tutorial we use the script [Format Numeric Measures](xref:script-format-numeric-measures) to showcase the Macro functionality. + +Once the script works according requirements the script can be saved using the toolbar button "Save as Macro" which will open the "Save Macro" window. + +![Macro Create infobox](~/content/assets/images/features/macros/macro_tutorial_create_infobox.png) + +The "Save Macro" window allows three options: + +1. Macro Name: Give the Macro a name and use backslash "\" to create folder path for the macro (See below) +2. Provide a tooltip for the Macro to remember what it does in detail +3. Select a context where the Macro should be available. + +![Macro Save infobox](~/content/assets/images/features/macros/macro_tutorial_save_window.png) + +In the above example the Macro will be saved in a folder called Formatting\Beginner and the script is called "Format Numeric Measures". It will be saved in the context of measures. + +### Macro Context + +Macros are saved in a "valid context" that determines which objects in the model the script can be applied to. + +This Macro can then be used when Right Clicking on a measure in the TOM Explorer. The context given while saving the Macro determines which objects will show the Macro when right clicking on that object. + +Tabular Editor will suggest a context based on the script that is being saved. + +![Macro Menu Shortcut](~/content/assets/images/features/macros/macro_tutorial_menu_shortcut.png) + +## Edit a Macro + +A macro can be opened by double clicking it in the Macro pane and after editing the C# script saved using _Ctrl + S_ or the Edit Macro button. + +![Macro Edit Infobox](~/content/assets/images/features/macros/macro_tutorial_edit_infobox.png) + +## Macro JSON file + +Macros are stored in the %LocalAppFolder%/TabularEditor3 as a JSON file called MacroActions.json. For more information on file types in Tabular Editor please see [Supported File Types](xref:supported-files#macroactionsjson) + +## Macro file example + +An example of a MacroActions.JSON file can be found here. It contains several of the C# scripts from our script library: [Download example MacroActions File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/MacroActions.json) + + diff --git a/content/localization/de/cs-scripts-and-macros_de.md b/content/localization/de/cs-scripts-and-macros_de.md new file mode 100644 index 00000000..35d5f195 --- /dev/null +++ b/content/localization/de/cs-scripts-and-macros_de.md @@ -0,0 +1,150 @@ +--- +uid: cs-scripts-and-macros +title: Introduction to C# scripts and macros +author: Daniel Otykier +updated: 2021-11-03 +--- + +# Introduction to C# scripts and macros + +Any software that claims to improve your productivity should provide some means of **automating user interactions**. In Tabular Editor, you can write C# scripts for exactly this purpose. With C# scripts in Tabular Editor, you can, for example: + +- Automate creation of TOM objects such as measures, tables, calculation items +- Interact with the currently selected object(s) in the TOM Explorer +- Automatically assign properties to multiple objects +- Import and export metadata in various formats, for auditing or documentation purposes + +If a script modifies your model metadata, you will be able to view the modifications immediately in the TOM Explorer and the Properties view. Moreover, you can **undo script changes**, effectively rolling back the model metadata to the point before the script was executed. If a script fails execution, the changes are automatically rolled back by default. + +Tabular Editor 3 includes a simple **script recorder** which helps you learn the syntax used, by incrementally adding lines of script code as you make changes to your model. + +A script can be saved as a standalone file (`.csx` file extension), which can be shared among Tabular Editor users. In addition, a script can be stored as a reusable **macro**, which integrates the script more closely with Tabular Editors user interface. + +# Creating a script + +To create a new C# script, use the **File > New > C# Script** menu option. Note that this option is available even when no model is loaded in Tabular Editor. + +For your first script, enter the following code: + +```csharp +Info("Hello world!"); +``` + +Hit F5 to run the code. + +![Your very first script](~/content/assets/images/first-script.png) + +If you made a mistake while typing the code, any syntax errors will be shown in the **Messages view**. + +- To save the script as a file, simply hit **File > Save** (Ctrl+S). +- To open a script from a file, use the **File > Open > File...** (Ctrl+O) option. The Open File dialog will look for files with the `.cs` or `.csx` extensions by default. + +# Using the script recorder + +While a C# script is in focus, you can start the script recorder in Tabular Editor by using the **C# Script > Record script** menu option. While the script is recording, any change you make to your model metadata will cause additional lines of code to be added to the script. Note that you cannot edit the script manually until you stop the recording. + +![Csharp Script Recorder](~/content/assets/images/csharp-script-recorder.png) + +# Accessing model metadata + +In order to access specific objects within the currently loaded model, you need to use the C# syntax for navigating through the Tabular Object Model (TOM) hierarchy. The root of this hierarchy is the `Model` object. + +The script below outputs the name of the currently loaded model. If no model is loaded, a warning is displayed. + +```csharp +if(Model != null) + Info("The name of the current model is: " + Model.Name); +else + Warning("No model is currently loaded!"); +``` + +The `Model` object is a wrapper of the [Microsoft.AnalysisServices.Tabular.Model](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) class, exposing a subset of its properties, with some additional methods and properties for convenience. + +To access a specific measure, you will need to know the name of that measure as well as the name of the table the measure resides in: + +```csharp +var myMeasure = Model.Tables["Internet Sales"].Measures["Internet Total Sales"]; +myMeasure.Description = "The formula for this measure is: " + myMeasure.Expression; +``` + +Line 1 in the script above locates the "Internet Total Sales" measure on the "Internet Sales" table, then stores a reference to that measure in the `myMeasure` variable. + +Line 2 in the script sets the description of the measure, based on a hardcoded string and the (DAX) expression of the measure. + +Tabular Editor can auto-generate the code that references a specific object, by dragging and dropping the object from the TOM Explorer into the C# script view. + +![Generate an object reference by dragging](~/content/assets/images/generate-csharp-code.gif) + +Most TOM objects (tables, columns, measures, etc.) in Tabular Editor, exposes the same set of properties that are available when using the AMO/TOM client libraries directly. For this reason, you can refer to [Microsoft's AMO/TOM documentation](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular?view=analysisservices-dotnet), to learn which properties are available. For example, [here](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.measure?view=analysisservices-dotnet#properties) is the documentation for available measure properties. + +# Accessing current TOM Explorer selection + +To make scripts reusable, it is rarely enough to be able to reference objects in the model directly by name, as shown above. Instead, it is useful to refer to whichever object(s) is currently selected in Tabular Editor's **TOM Explorer view**. This is possible through the use of the `Selected` object. + +```csharp +Info("You have currently selected: " + Selected.Measures.Count + " measure(s)."); +``` + +The `Selected` object by itself is a collection of all objects currently selected, including objects within selected display folders. In addition, the `Selected` object contains multiple properties that makes it easy to refer to specific object types, such as the `.Measures` property shown in the example above. In general, these properties exist in both a plural (`.Measures`) and a singular (`.Measure`) form. The former is a collection that you can iterate through, and which will be empty if the current selection does not contain any objects of that type, where as the latter is a reference to the currently selected object, if and only if exactly one of that type of object is selected. + +The @useful-script-snippets article contains many examples of scripts that use the `Selected` object to perform various tasks. + +# Interacting with the user + +In the examples above, we used the `Info(...)` and `Warning(...)` global methods to show a message to the user in various flavors. Tabular Editor provides a number of these global methods as well as extension methods for showing and collecting information, and for various other common tasks. The most commonly used are listed below: + +- `void Output(object value)` - halts script execution and displays detailed information about the provided object. When the provided object is a TOM object or a collection of TOM objects, a detailed view of all properties are shown. +- `void SaveFile(string filePath, string content)` - convenient way to save text data to a file. +- `string ReadFile(string filePath)` - convenient way to load text data from a file. +- `string ExportProperties(IEnumerable objects, string properties = "...")` - convenient way to export a set of properties from multiple objects as a TSV string. +- `void ImportProperties(string tsvData)` - convenient way to load properties into multiple objects from a TSV string. +- `string ConvertDax(dax, useSemicolons)` - converts a DAX expression between US/UK and non-US/UK locales. If `useSemicolons` is true (default) the `dax` string is converted from the native US/UK format to non-US/UK. That is, commas (list separators) will be converted to semicolons and periods (decimal separators) will be converted to commas. Vice versa if `useSemicolons` is set to false. +- `void FormatDax(IEnumerable objects, bool shortFormat, bool? skipSpace)` - formats DAX expressions on all objects in the provided collection +- `void FormatDax(IDaxDependantObject obj)` - queues an object for DAX expression formatting when script execution is complete, or when the `CallDaxFormatter` method is called. +- `void CallDaxFormatter(bool shortFormat, bool? skipSpace)` - formats all DAX expressions on objects enqueued so far +- `void Info(string message)` - Displays an informational message. +- `void Warning(string message)` - Displays a warning message. +- `void Error(string message)` - Displays an error message. +- `measure SelectMeasure(Measure preselect = null, string label = "...")` - Displays a list of all measures and �prompts the user to select one. +- `T SelectObject(this IEnumerable objects, T preselect = null, string label = "...") where T: TabularNamedObject` - Displays a list of the provided objects, prompting the user to select one, and returns that object (or null if the cancel button was pressed). +- `IList SelectObjects(this IEnumerable objects, IEnumerable preselect = null, string label = "...") where T: TabularNamedObject` - Displays a list of the provided objects, prompting the user to select any number of objects and returns the list of objects selected (or null if the cancel button was pressed). + +# Saving a script as a macro + +Scripts that you use often can be saved as reusabe macros, which are always available when you launch Tabular Editor. Moreover, macros are automatically integrated in the context menu of the **TOM Explorer view** and you can even use the **Tools > Customize...** option to add macros to existing or custom menus and toolbars. + +To save a script as a macro, use the **C# Script > Save as Macro...** option. + +![Save New Macro](~/content/assets/images/save-new-macro.png) + +Provide a name for your macro. You can use backslashes to organize macros into folders, i.e. a name such as "My Macros\Test" will create a "My Macros" submenu in the context menu of the TOM Explorer, and within this submenu there will be a "Test" menu option that invokes the script. + +You may also provide an optional tooltip which will be displayed when hovering over the menu option created by the macro. + +You should also specify the macro context, which specifies the type(s) of objects that needs to be selected in order for the macro to be available in the context menu. + +Lastly, you can specify a C# expression which should evaluate to true/false (typically based on the `Selected` or `Model` objects) under **Macro enabled condition (advanced)**. This lets you control more granularly whether the macro should be enabled or not, based on the current selection. For example, you could use the following expression: + +```csharp +Selected.Measures.Count == 1 +``` + +to enable your macro only when exactly 1 measure is selected. + +# Managing macros + +You can view all previously saved macros in the **Macros view**. To bring this view into focus, use the **View > Macros** menu option. This view allows you to: + +- **Rename a macro** (simply put the cursor into the **Name** column and type the new name) +- **Delete a macro.** Select it and click the red "X" button above the list of macros. +- **Edit a macro.** Double-click the macro in the list (double-click on the "Id" column of the list). This will open the macro in a new C# script view, where you can make code changes. Hit Ctrl+S to save the code changes. If you need to edit other macro properties (tooltip, macro context, etc.), use the **C# Script > Edit Macro...** menu option. + +# Next steps + +- @personalizing-te3 +- @boosting-productivity-te3 + +# Further reading + +- @csharp-scripts +- @useful-script-snippets \ No newline at end of file diff --git a/content/localization/de/csharp-script-Template_de.md b/content/localization/de/csharp-script-Template_de.md new file mode 100644 index 00000000..d5f24a8a --- /dev/null +++ b/content/localization/de/csharp-script-Template_de.md @@ -0,0 +1,40 @@ +--- +uid: csharp-script-template +title: +author: +updated: yyyy-mm-dd +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Title + +## Script Purpose + +

+ +> [!NOTE] +> This script does not work when connected to a Power BI Desktop model, due to the limitations of Power BI Desktop External tools: [External Tool Limitations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). You can still experiment with the script by enabling unsupported modeling operations under "File > Preferences" (TE2) or "Tools > Preferences" (TE3) + +

+ +## Script + +### Script Title + +```csharp +// Scripts Goes here +``` + +### Explanation + +## Example Output + +
+Image description + \ No newline at end of file diff --git a/content/localization/de/csharp-script-library-advanced_de.md b/content/localization/de/csharp-script-library-advanced_de.md new file mode 100644 index 00000000..1bfd33d4 --- /dev/null +++ b/content/localization/de/csharp-script-library-advanced_de.md @@ -0,0 +1,30 @@ +--- +uid: script-library-advanced +title: Advanced C# Scripts +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# C# Script Library: Advanced Scripts + +These are more advanced scripts with sophisticated functionalities requiring a more advanced understanding of the C# language and TOM. They are more difficult to modify and thus recommended only once you have become comfortable with the foundations of C# Scripting in Tabular Editor. + +
+
+ +|
Script Name
| Purpose | Use-case | +| ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Count Model Objects](xref:script-count-things) | Counts all the different objects by type in a model. | When you need an overview of the model contents or want to count objects by type. | +| [Output Object Details in a Grid](xref:script-output-things) | Outputs object details in a grid view. | When you need to output object details in a grid view for inspection. | +| [Create Date Table](xref:script-create-date-table) | Creates a formatted Date table based on selected Date columns in the model. | When you need to create a new date table based on a template. | +| [Create M Parameter (Auto-Replace)](xref:script-create-and-replace-parameter) | Creates a new M Parameter and automatically adds it to M Partitions. | When you want to replace strings in multiple partitions (i.e. connection strings) with a dynamic M Parameter. | +| [Format Power Query](xref:script-format-power-query) | Formats the Power Query of a selected M Partition by using the powerqueryformatter.com API. | When you have complex Power Query and need to make it more readable for reading or making changes. | +| [Implement Incremental Refresh](xref:script-implement-incremental-refresh) | Configures Incremental Refresh automatically using parameters from a UI dialogue box. | When you need to implement incremental refresh but aren't comfortable with the configuration in the table settings. | +| [Remove Measures with Errors](xref:script-remove-measures-with-error) | Creates a new M Parameter and automatically adds it to M Partitions. | When you want to replace strings in multiple partitions (i.e. connection strings) with a dynamic M Parameter. | +| [Find & Replace in Selected Measures](xref:script-find-replace) | Searches for a substring in the DAX of selected measures, replacing with another substring. | When you need to quickly find/replace values in multiple DAX measures (i.e. `CALCULATE` filter or broken object references). | +| [Databricks Semantic Model Set-up](xref:script-databricks-semantic-model-set-up) | Friendly name tables and columns and set column best practices | When your Databricks object names need making more user friendly. | +| [Create Databricks Relationships](xref:script-create-databricks-relationships) | Create relationships based on primary and foreign key definitions in Databricks Unity Catalog | When you want to re-use Databricks relationship definitions that have already been defined in Unity Catalog. | +| [Add Databricks Metadata Descriptions](xref:script-add-databricks-metadata-descriptions) | Update table and column descriptions based on Databricks Unity Catalog | When you want to re-use Databricks table and column comments that have already been defined in Unity Catalog. | \ No newline at end of file diff --git a/content/localization/de/csharp-script-library-beginner_de.md b/content/localization/de/csharp-script-library-beginner_de.md new file mode 100644 index 00000000..d566b8ea --- /dev/null +++ b/content/localization/de/csharp-script-library-beginner_de.md @@ -0,0 +1,29 @@ +--- +uid: script-library-beginner +title: Beginner C# Scripts +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# C# Script Library: Beginner Scripts + +These are more basic scripts that are easy to understand or modify. They have a defined scope and limited complexity; you don't need a reasonable knowledge of the C# language to use, understand and modify these scripts. They are thus a good place to start when beginning to author C# Scripts in Tabular Editor. + +
+
+ +|
Script Name
| Purpose | Use-case | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [Count Table Rows](xref:script-count-rows) | Evaluates a COUNTROWS ( 'Table' ) of a selected table. | When you want to check how many rows are in a table, or if it's been loaded. | +| [Create Sum Measures from Columns](xref:script-create-sum-measures-from-columns) | Create SUM ( 'Table'[Column] ) measures from any selected column. | When you have many columns in a new table / model and must make many measures at once. | +| [Create Measure Table](xref:script-create-measure-table) | Create a measure table | When you want to create an empty table to use as an organizing measure table | +| [Create Table Groups](xref:script-create-table-groups) | Organize the model into Table Groups | When you want to have an automatic organization of your tables using the table group feature of Tabular Editor 3 | +| [Create M Parameter](xref:script-create-m-parameter) | Create a new M Parameter in 'Shared Expressions' | When you want to create a parameter to use in other Power Query queries (M Partitions / Shared Expressions). | +| [Edit Hidden Partitions](xref:script-edit-hidden-partitions) | Reveals the properties of hidden partitions in Calc. Groups & Calc. Tables | When you need to see or edit the TOM properties of these hidden partitions. | +| [Format Numeric Measures](xref:script-format-numeric-measures) | Formats the chosen measures | When you want to quickly apply a format string to the currently selected measures | +| [Show Data Source Dependencies](xref:script-show-data-source-dependencies) | Shows dependencies for data sources | For explicit (legacy) data sources it can be hard to know exactly where they are used. This script shows you which partition reference the chosen data source | +| [Create Field Parameters](xref:create-field-parameter) | Quickly create a field parameter table | Choose the objects that should be in the field parameter and the script will take care of the rest | +| [Display Unique Column Values](xref:script-display-unique-column-values) | Display unique values in a column | When you want to see the unique values in the currently selected column | \ No newline at end of file diff --git a/content/localization/de/csharp-script-library_de.md b/content/localization/de/csharp-script-library_de.md new file mode 100644 index 00000000..81dfa18a --- /dev/null +++ b/content/localization/de/csharp-script-library_de.md @@ -0,0 +1,41 @@ +--- +uid: csharp-script-library +title: C# Script Library +author: Morten Lønskov +updated: 2023-02-23 +--- + +# C# Script Library + +![C# Script Library](~/content/assets/images/Cscripts/script-library-header.png) + +--- + +This section contains official Tabular Editor scripts that have been verified and validated by the Tabular Editor team. These scripts are used in demos, conferences and documentation by the Tabular Editor team, and are maintained here for your convenience. Use of these scripts are still your own responsibility. + +There are also other resources online with C# Scripts that are maintained by the community such as PowerBI.tips excellent repository: [PowerBI.Tips C# Script Repository](https://github.com/PowerBI-tips/TabularEditor-Scripts) and Michael Kovalsky's excellent blog [ElegantBI](https://www.elegantbi.com/) and [Repository for Tabular Scripts](https://github.com/m-kovalsky/Tabular) + +## Tabular Editor Versions + +The top of each article denotes script compatability in TE2.x (Tabular Editor 2) and/or TE3.x (Tabular Editor 3) + +### Scripting with Tabular Editor as a Power BI External Tool + +

+ +> [!NOTE] +> Some scripts does not work when connected to a Power BI Desktop model, due to the limitations of Power BI Desktop External tools: [External Tool Limitations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). You can still experiment with the script by enabling unsupported modeling operations under preferences.

+ +### [Tabular Editor 2 Preferences](#tab/TE2Preferences) + +"File > Preferences" +![Edit Hidden Partitions](~/content/assets/images/te2-file-menu.png) + +### [Tabular Editor 3 Preferences](#tab/TE3Preferences) + +"Tools > Preferences" +![Edit Hidden Partitions](~/content/assets/images/tools-menu.png) + + + + diff --git a/content/localization/de/csharp-scripts_de.md b/content/localization/de/csharp-scripts_de.md new file mode 100644 index 00000000..6e113ddb --- /dev/null +++ b/content/localization/de/csharp-scripts_de.md @@ -0,0 +1,275 @@ +--- +uid: csharp-scripts +title: C# Scripts +author: Daniel Otykier +updated: 2025-08-27 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# C# Scripts + +This is an introduction to the C# Scripting capabilities of Tabular Editor 3. Information in this document is subject to change. Also, make sure to check out our script library @csharp-script-library, for some more real-life examples of what you can do with the scripting capabilities of Tabular Editor. + +## Why C# scripting? + +The goal of the UI of Tabular Editor is to make it easy to perform most tasks commonly needed when building Tabular Models. For example, changing the Display Folder of multiple measures at once is just a matter of selecting the objects in the explorer tree and then dragging and dropping them around. The right-click context menu of the explorer tree provides a convenient way to perform many of these tasks, such as adding/removing objects from perspectives, renaming multiple objects, etc. + +There may be many other common workflow tasks, which are not as easily performed through the UI however. For this reason, Tabular Editor offers C# scripting, which lets advanced users write a script using C# syntax, to more directly manipulate the objects in the loaded Tabular Model. + +## Code Assist + +The C# script editor supports Roslyn-powered completion and call tips and from Tabular Editor 3.23.0, completion supports substring and capital-letters acronym matching. + +## Objects + +The [scripting API](xref:api-index) provides access to two top-level objects, `Model` and `Selected`. The former contains methods and properties that allow you to manipulate all objects in the Tabular Model, whereas the latter exposes only objects that are currently selected in the explorer tree. + +The `Model` object is a wrapper of the [Microsoft.AnalysisServices.Tabular.Model](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) class, exposing a subset of it’s properties, with some additional methods and properties for easier operations on translations, perspectives and object collections. The same applies to any descendant objects, such as Table, Measure, Column, etc. which all have corresponding wrapper objects. Please see for a complete listing of objects, properties and methods in the Tabular Editor wrapper library. + +The main advantage of working through this wrapper is, that all changes will be undoable from the Tabular Editor UI. Simply press CTRL+Z after executing a script, and you will see that all changes made by the script are immediately undone. Furthermore, the wrapper provides convenient methods that turn many common tasks into simple one-liners. We will provide some examples below. It is assumed that the reader is already somewhat familiar with C# and LINQ, as these aspects of Tabular Editors scripting capabilities will not be covered here. Users unfamiliar with C# and LINQ should still be able to follow the examples given below. + +## Setting object properties + +If you want to change a property of one object in particular, obviously the easiest way to do so would be directly through the UI. But as an example, let us see how we could achieve the same thing through scripting. + +Say you want to change the Format String of your [Sales Amount] measure in the 'FactInternetSales' table. If you locate the measure in the explorer tree, you can simply drag it onto the script editor. Tabular Editor will then generate the following code, which represents this particular measure in the Tabular Object Model: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"] +``` + +Adding an extra dot (.) after the right-most bracket, should make the autocomplete menu pop up, showing you which properties and methods exist on this particular measure. Simply choose "FormatString" in the menu, or write the first few letters and hit Tab. Then, enter an equal sign followed by "0.0%". Let us also change the Display Folder of this measure. Your final code should look like this: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"].FormatString = "0.0%"; +Model.Tables["FactInternetSales"].Measures["Sales Amount"].DisplayFolder = "New Folder"; +``` + +**Note:** Remember to put the semicolon (;) at the end of each line. This is a requirement of C#. If you forget it, you will get a syntax error message when trying to execute the script. + +Hit F5 or the "Play" button above the script editor to execute the script. Immediately, you should see the measure moving around in the explorer tree, reflecting the changed Display Folder. If you examine the measure in the Property Grid, you should also see that the Format String property has changed accordingly. + +### Working with multiple objects at once + +Many objects in the object model, are actually collections of multiple objects. For example, each Table object has a Measures collection. The wrapper exposes a series of convenient properties and methods on these collections, to make it easy to set the same property on multiple objects at once. This is described in detail below. Additionally, you may use all the standard LINQ extension methods to filter and browse the objects of a collection. + +Below is a few examples of the most commonly used LINQ extension methods: + +- `Collection.First([predicate])` Returns the first object in the collection satisfying the optional [predicate] condition. +- `Collection.Any([predicate])` Returns true if the collection contains any objects (optionally satisfying the [predicate] condition). +- `Collection.Where(predicate)` Returns a collection that is the original collection filtered by the predicate condition. +- `Collection.Select(map)` Projects each object in the collection into another object according to the specified map. +- `Collection.ForEach(action)` Performs the specified action on each element in the collection. + +In the above examples, `predicate` is a lambda expression that takes a single object as input, and returns a boolean value as output. For example, if `Collection` is a collection of measures, a typical `predicate` could look like: + +`m => m.Name.Contains("Reseller")` + +This predicate would return true only if the Name of the measure contains the character string "Reseller". Wrap the expression in curly braces and use the `return` keyword, if you need more advanced logic: + +```csharp +.Where(obj => { + if(obj is Column) { + return false; + } + return obj.Name.Contains("test"); +}) +``` + +Going back to the examples above, `map` is a lambda expression that takes a single object as input, and returns any single object as output. `action` is a lambda expression that takes a single object as input, but does not return any value. + +## Working with the **Model** object + +To quickly reference any object in the currently loaded Tabular Model, you can drag and drop the object from the explorer tree and into the C# script editor: + +![Dragging and dropping an object into the C# script editor](~/content/assets/images/drag-object-to-script.gif) + +Please refer to the [TOM documentation](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) for an overview of which properties exist on the Model and its descendant objects. Additionally, refer to for a complete listing of the properties and methods exposed by the wrapper object. + +## Working with the **Selected** object + +Being able to explicitly refer to any object in the Tabular Model is great for some workflows, but sometimes you want to cherry pick objects from the explorer tree, and then execute a script against only the selected objects. This is where the `Selected` object comes in handy. + +The `Selected` object provides a range of properties that make it easy to identify what is currently selected, as well as limiting the selection to objects of a particular type. When browsing with Display Folders, and one or more folders are selected in the explorer tree, all their child items are considered to be selected as well. +For single selections, use the singular name for the type of object you want to access. For example, + +`Selected.Hierarchy` + +refers to the currently selected hierarchy in the tree, provided that one and only one hierarchy is selected. Use the plural type name, in case you want to work with multiselections: + +`Selected.Hierarchies` + +All properties that exist on the singular object, also exist on its plural form, with a few exceptions. This means that you can set the value of these properties for multiple objects at once, with just one line of code and without using the LINQ extension methods mentioned above. For example, say you wanted to move all currently selected measures into a new Display Folder called "Test": + +`Selected.Measures.DisplayFolder = "Test";` + +If no measures are currently selected in the tree, the above code does nothing, and no error is raised. Otherwise, the DisplayFolder property will be set to "Test" on all selected measures (even measures residing within folders, as the `Selected` object also includes objects in selected folders). If you use the singular form `Measure` instead of `Measures`, you will get an error unless the current selection contains exactly one measure. + +Although we cannot set the Name property of multiple objects at once, we still have some options available. If we just want to replace all occurrences of some character string with another, we can use the provided "Rename" method, like so: + +```csharp +Selected.Measures + .Rename("Amount", "Value"); +``` + +This would replace any occurence of the word "Amount" with the word "Value" in the names of all currently selected measures. +Alternatively, we may use the LINQ ForEach()-method, as described above, to include more advanced logic: + +```csharp +Selected.Measures + .ForEach(m => if(m.Name.Contains("Reseller")) m.Name += " DEPRECATED"); +``` + +This example will append the text " DEPRECATED" to the names of all selected measures where the names contain the word "Reseller". Alternatively, we could use the LINQ extension method `Where()` to filter the collection before applying the `ForEach()` operation, which would yield exactly the same result: + +```csharp +Selected.Measures + .Where(m => m.Name.Contains("Reseller")) + .ForEach(m => m.Name += " DEPRECATED"); +``` + +## Helper methods + +Tabular Editor provides a set of special helper methods to make certain script tasks easier to achieve. Note that some of these may be invoked as extension methods. For example, `object.Output();` and `Output(object);` are equivalent. + +- `void Output(object value)` - halts script execution and displays information about the provided object. When the script is running as part of a command line execution, this will write a string representation of the object to the console. +- `void SaveFile(string filePath, string content)` - convenient way to save text data to a file. +- `string ReadFile(string filePath)` - convenient way to load text data from a file. +- `string ExportProperties(IEnumerable objects, string properties)` - convenient way to export a set of properties from multiple objects as a TSV string. +- `void ImportProperties(string tsvData)` - convenient way to load properties into multiple objects from a TSV string. +- `void CustomAction(string name)` - invoke a macro by name. +- `void CustomAction(this IEnumerable objects, string name)` - invoke a macro on the specified objects. +- `string ConvertDax(string dax, bool useSemicolons)` - converts a DAX expression between US/UK and non-US/UK locales. If `useSemicolons` is true (default) the `dax` string is converted from the native US/UK format to non-US/UK. That is, commas (list separators) will be converted to semicolons and periods (decimal separators) will be converted to commas. Vice versa if `useSemicolons` is set to false. +- `void FormatDax(this IEnumerable objects, bool shortFormat, bool? skipSpace)` - formats DAX expressions on all objects in the provided collection +- `void FormatDax(this IDaxDependantObject obj)` - queues an object for DAX expression formatting when script execution is complete, or when the `CallDaxFormatter` method is called. +- `void CallDaxFormatter(bool shortFormat, bool? skipSpace)` - formats all DAX expressions on objects enqueued so far +- `void Info(string)` - Writes an informational message to the console (only when the script is executed as part of a command line execution). +- `void Warning(string)` - Writes a warning message to the console (only when the script is executed as part of a command line execution). +- `void Error(string)` - Writes an error message to the console (only when the script is executed as part of a command line execution). +- `T SelectObject(this IEnumerable objects, T preselect = null, string label = "Select object") where T: TabularNamedObject` - Displays a dialog to the user prompting to select one of the objects specified. If the user cancels the dialog, this method returns null. +- `void CollectVertiPaqAnalyzerStats()` - If Tabular Editor is connected to an instance of Analysis Services, this runs the VertiPaq Analyzer statistics collector. +- `long GetCardinality(this Column column)` - If VertiPaq Analyzer statistics are available for the current model, this method returns the cardinality of the specified column. + +For a full list of available helper methods and their syntax, view @script-helper-methods. + +### Debugging scripts + +As mentioned above, you can use the `Output(object);` method to pause script execution, and open a dialog box with information about the passed object. You can also use this method as an extension method, invoking it as `object.Output();`. The script is resumed when the dialog is closed. + +The dialog will appear in one of four different ways, depending on the kind of object being output: + +- Singular objects (such as strings, ints and DateTimes, except any object that derives from TabularNamedObject) will be displayed as a simple message dialog, by invoking the `.ToString()` method on the object: + +![C-sharp Output](~/content/assets/images/c-sharp-script-output-function.png) + +- Singular TabularNamedObjects (such as Tables, Measures or any other TOM NamedMetadataObject available in Tabular Editor) will be shown in a Property Grid, similar to when an object has been selected in the Tree Explorer. Properties on the object may be edited in the grid, but note that if an error is encountered at a later point in the script execution, the edit will be automatically undone, if "Auto-Rollback" is enabled: + +![C-sharp Output](~/content/assets/images/c-sharp-script-auto-rollback.png) + +- Any IEnumerable of objects (except TabularNamedObjects) will be displayed in a list, where each list item shows the `.ToString()` value and type of the object in the IEnumerable: + +![C-sharp Output](~/content/assets/images/c-sharp-script-output-to-string-function.png) + +- Any IEnumerable of TabularNamedObjects will cause the dialog to display a list of the objects on the left, and a Property Grid on the right. The Property Grid will be populated from whatever object is selected in the list, and properties may be edited just as when a single TabularNamedObject is being output: + +![C-sharp Output](~/content/assets/images/c-sharp-script-output-function-enumerated.png) + +You can tick the "Don't show more outputs" checkbox at the lower left-hand corner, to prevent the script from halting on any further `.Output()` invocations. + +## .NET references + +You can use the `using` keyword to shorten class names, etc. just like in regular C# source code. In addition, you can include external assemblies by using the syntax `#r ""` similar to .csx scripts used in Azure Functions. + +For example, the following script will now work as expected: + +```csharp +// Assembly references must be at the very top of the file: +#r "System.IO.Compression" + +// Using keywords must come before any other statements: +using System.IO.Compression; +using System.IO; + +var xyz = 123; + +// Using statements still work the way they're supposed to: +using(var data = new MemoryStream()) +using(var zip = new ZipArchive(data, ZipArchiveMode.Create)) +{ + // ... +} +``` + +By default, Tabular Editor applies the following `using` keyword (even though they are not specified in the script), to make common tasks easier: + +```csharp +using System; +using System.Linq; +using System.Collections.Generic; +using Newtonsoft.Json; +using TabularEditor.TOMWrapper; +using TabularEditor.TOMWrapper.Utils; +using TabularEditor.UI; +``` + +In addition, the following .NET Framework assemblies are loaded by default: + +- System.Dll +- System.Core.Dll +- System.Data.Dll +- System.Windows.Forms.Dll +- Microsoft.Csharp.Dll +- Newtonsoft.Json.Dll +- TomWrapper.Dll +- TabularEditor.Exe +- Microsoft.AnalysisServices.Tabular.Dll + +## Compatibility + +The scripting APIs for Tabular Editor 2 and Tabular Editor 3 are mostly compatible, however, there are cases where you want to conditionally compile code depending on which version you're using. For this, you can use preprocessor directives, which were introduced in Tabular Editor 3.10.0. + +```csharp +#if TE3 + // This code will only be compiled when the script is running in TE3 (version 3.10.0 or newer). + Info("Hello from TE3!"); +#else + // This code will be compiled in all other cases. + Info("Hello from TE2!"); +#endif +``` + +If you need to know the exact version of Tabular Editor at script runtime, you can inspect the assembly version: + +```csharp +var currentVersion = typeof(Model).Assembly.GetName().Version; +Info(currentVersion.ToString()); +``` + +The public product version (for example, "2.20.2" or "3.10.1") can be found using this code: + +```csharp +using System.Diagnostics; + +var productVersion = FileVersionInfo.GetVersionInfo(Selected.GetType().Assembly.Location).ProductVersion; +productVersion.Output(); // productVersion is a string ("2.20.2" or "3.10.1", for example) +``` + +If you just want the major version number (as an integer), use: + +```csharp +var majorVersion = Selected.GetType().Assembly.GetName().Version.Major; +majorVersion.Output(); // majorVersion is an integer (2 or 3) +``` + +## Known issues and limitations + +- Certain script operations may cause the Tabular Editor 3 application to crash or become unresponsive, due to the way scripts are executed. For example, a script with an infinite loop (`while(true) {}`) will cause the application to hang. If this happens, you will have to end the Tabular Editor process through the Windows Task Manager. + +If you intend to save the script as a [macro](xref:creating-macros), please be aware of the following limitations: + +- If the script body contains local methods with access modifiers (`public`, `static`, etc.), the script cannot be saved as a macro. Remove the access modifiers, or move the method into a class instead. +- Macros currently do not support the `await` keyword, if used in the script body. If your script body calls into asynchronous methods, you should use `MyAsyncMethod.Wait()` or `MyAsyncMethod.Result` instead of `await MyAsyncMethod()`. It is fine to use `await` in `async` methods that are defined elsewhere in the script. \ No newline at end of file diff --git a/content/localization/de/data-refresh-view_de.md b/content/localization/de/data-refresh-view_de.md new file mode 100644 index 00000000..11ff997b --- /dev/null +++ b/content/localization/de/data-refresh-view_de.md @@ -0,0 +1,26 @@ +--- +uid: data-refresh-view +title: Data Refresh view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + partial: TE3 Desktop Edition includes this feature, however refreshing tables through External Tools is not currently supported by Microsoft and may cause issues in Power BI Desktop. + - edition: Business + - edition: Enterprise +--- + +# Data Refresh View + +The Data Refresh view allows you to investigate in detail how your data is being refreshed on the server. +A new active refresh will appear when a new refresh is triggered through the TOM Explorer. + +
+ Data Refresh View
Figure 1: Data Refresh View in Tabular Editor. New refresh can be started by right-clicking a table and selecting refresh
+
+ +A new refresh will run in the background so that you can continue to build your dataset, and Tabular Editor will let you know if the refresh fails with a pop up. + +> [!WARNING] +> If you are using TE as an External Tool to Power BI and have activated _Allow Unsupported modeling operations_ do _NOT_ start a refresh as this is prone to corrupt your .pbix file. diff --git a/content/localization/de/data-security-about_de.md b/content/localization/de/data-security-about_de.md new file mode 100644 index 00000000..c1a0ac12 --- /dev/null +++ b/content/localization/de/data-security-about_de.md @@ -0,0 +1,395 @@ +--- +uid: data-security-about +title: What is Data Security? +author: Kurt Buhler +updated: 2023-03-02 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# What is Data Security? + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-visual-abstract.png) + +--- + +Published datasets can be configured with Data Security using [Row-Level Security (RLS)](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls) (for Tables) or [Object-Level Security (OLS)](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-ols?tabs=table) (for Tables & Columns). **The purpose of Data Security is to ensure users only see and use data they are permitted to, both in published reports and when making their own, self-service data solutions.** To do this, users are assigned to **Roles** which have **RLS** or **OLS** rules configured, which **filter (RLS)** or **restrict (OLS)** queries generated by reports & client tools like Power BI Desktop or Excel. + +While [not obligatory](https://learn.microsoft.com/en-us/power-bi/guidance/rls-guidance#when-to-avoid-using-rls), [Data Security is a common feature of a robust, secure & compliant enterprise BI solution](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-report-consumer-planning#enforce-data-security-based-on-consumer-identity). This series is a functional introduction to Data Security, as it pertains to tabular modeling & Tabular Editor. + +_Both RLS & OLS can be easily configured, modified and tested from within Tabular Editor._ + +--- + +- **About Data Security and RLS/OLS (This Article):** A functional overview of RLS & OLS. +- [**Modify/Setup an RLS Configuration:**](data-security-setup-rls.md) How to configure RLS in a dataset. +- [**Modify/Setup an OLS Configuration:**](data-security-setup-ols.md) How to configure OLS in a dataset. +- [**Testing RLS/OLS with Impersonation:**](data-security-testing.md) How to easily validate Data Security with Tabular Editor. + +
+
WHY CONFIGURE ROW- OR OBJECT-LEVEL SECURITY?
+ Configuring RLS or OLS can be benificial for your model & reporting: +
  • Reduce risk and improve governance by ensuring users only see data they have access to. +
  • Configure dynamic RLS with central role tables for consistency and lightweight maintenance. +
  • Have granular control over what data and objects can be queried. +
  • + +--- + +### How Does it Work? + +Data Security works at the level of the model. It is configured following the below steps: + +#### 1. **Create Roles:** + +_Roles_ are groups of users who have the same permission / data security logic. _Users_ in this case are identified by their email, or the email of an [Azure AD Security Group](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-tenant-level-planning#integration-with-azure-ad). Examples of roles: + +- Users in the same region, team or department (_EMEA_, _UA Sales Team_). +- Users with the same role, function or access clearance (_Key Account Managers_, _SC Clearance_). +- Groups defined by other business logic or arbitrary rules (_Externals_, _Build Users_). + +
    + Data Security Create Role
    Figure 1: In Tabular Editor, Roles are one of the top-level object types (like Tables, Relationships, etc).
    +
    + +> [!IMPORTANT] +> After creating a new Role in Tabular Editor, you must first set the `Model Permission` property to `Read`. + +#### 2. **Specify Rules:** + +_Rules_ are applied for each role to one or more objects, depending on the security type: + +- _RLS Table Permissions:_ DAX table expressions -- return each row evaluating `True`. These permissions traverse relationships; **the design of the model is imperative to good RLS rules.** + +
    + Data Security Create Role
    Figure 2: In Tabular Editor, Table Permissions for RLS are visible under the role. New table permissions can be created by right-clicking a Role and selecting 'Add Table Partition...'
    +
    + +
    + Data Security Create Role
    Figure 3: Table Permission DAX is visible in the Expression Editor when selecting a Table Permission.
    +
    + +- _OLS Object Permissions:_ These permissions apply to the primary objects as well as all downstream dependents. + - `Read` (Can see / query) + - `None` (Cannot see / query) + - `Default` (No policy configured; equivalent to `Read`) + +
    + Data Security Create Role
    Figure 4: In Tabular Editor, object permissions are accessible in the 'Properties' window, under the 'Translations, Perspectives, Security' heading.
    +
    + +#### 3. **Assign Users to Roles:** + +Once configured in the dataset, users must be added to their respective roles. + +- _Power BI:_ Roles are assigned either via Tabular Editor or the **Power BI/Fabric service**, [in the dataset settings from the Workspace](https://learn.microsoft.com/en-us/fabric/security/service-admin-row-level-security#manage-security-on-your-model). +- _SSAS / AAS:_ Roles are assigned via the Role object, by right-clicking and selecting "Edit Members..." +- _Power BI Embedded:_ You must [generate an embed token](https://learn.microsoft.com/en-us/power-bi/developer/embedded/cloud-rls#generate-an-embed-token). + +You can assign and remove users/groups from roles through Tabular Editor the following way: + +1. Right-Click the **Role**, select **Edit members**... + +
    + Data Security Create Role
    Figure 7:Users can be assigned to roles by right-clicking a Role and selecting 'Edit members...'.
    +
    + +2. Click the **dropdown button** on the 'Add Windows AD Member' button and choose **Azure AD Member**: + +
    + Data Security Create Role
    Figure 8: For AAS/SSAS models, users can be added via the 'Edit members...' dialog box.
    +
    + +3. Specify the Azure AD user identity (typically, the user e-mail address) as the **Member Name** property. +4. Click **OK**. +5. **Save** the model. + +> [!IMPORTANT] +> If your organisation is using on-premises Active Directory with SQL Server Analysis Services, you will need to use the **Windows AD Member** option instead of **Azure AD Member**. + +> [!NOTE] +> It is [recommended](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-tenant-level-planning#strategy-for-using-groups) to manage Data Security and Access with [Azure Active Directory Groups](https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/how-to-manage-groups).
    Using this approach is preferred you can centralize management of security & user segmentation. + +#### 4. **Provision Users Access to the Dataset:** + +_Power BI:_ Users must be given dataset access according to the [usage scenario](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-usage-scenario-overview). + +- _App Audience:_ Users / their Azure AD Groups are added to the appropriate [App Audience](https://data-goblins.com/power-bi/app-audiences). +- _Workspace Viewer:_ Users / their Azure AD Groups are added as [Workspace Viewers](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-workspaces-workspace-level-planning#workspace-access) +- _Dataset Readers:_ Users / their Azure AD Groups are given [Dataset-specific permissions](https://learn.microsoft.com/en-us/power-bi/connect-data/service-datasets-manage-access-permissions) via a Dataset or dependent item (i.e. Report). + +> [!WARNING] +> Users given [Admin, Member or Contributor Workspace Roles](https://learn.microsoft.com/en-us/power-bi/collaborate-share/service-roles-new-workspaces#workspace-roles) have **_write permissions_** to a dataset. As such, Data Security like RLS and OLS will not filter or block data for users with these roles.

    +> **_If a user is an Admin, Member or Contributor, they will be able to see all the data_**.

    +> As much as is reasonable, try to distribute and manage permissions via Power BI Apps. + +#### 5. **Validating Security:** + +RLS and OLS can only be tested with impersonation once user groups have been added & granted access. Validate security via: + +- _Tabular Editor:_ Using [User Impersonation](data-security-testing.md). +- _Power BI Service:_ In the [Dataset Security settings](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls#validating-the-role-within-the-power-bi-service). + +
    + Data Security Create Role
    Figure 5: The easiest way to test Data Security is via Impersonation with Tabular Editor. The 'Impersonation' option is possible from any data querying feature (DAX Queries, Pivot Grid, Preview Data).
    +
    + +> [!NOTE] +> To validate data security with impersonation, the below factors must be all true: +> +> - The user must be assigned a role. +> - The user must have read permissions to the dataset. +> - The user must have **build permissions** to the dataset. + +
    + Data Security Create Role
    Figure 6: A demonstration of RLS testing in Tabular Editor using impersonation. Shown is testing with (A) Data Preview, (B) DAX Queries and (C) Pivot Grid.
    +
    + +> [!IMPORTANT] +> Testing Data Security with Impersonation using Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. TE3 Desktop Licenses cannot benefit from this feature. This is because roles are assigned in the Power BI Service. + +--- + +### How Does it Look? + +Depending on how you have designed and configured Data Security, the experience may differ for users. +Below are common examples for common scenarios of RLS and/or OLS implementation in a dataset + +_Click a tab to see the example and get an explanation of each:_ + +--- + +# [None](#tab/nodatasecurity) + +**Without security, everyone with access to the dataset can see all the data.** + +The only restriction is whether they have access to the reports / datasets. + +![No security](~/content/assets/images/data-security/data-security-no-security.png) + +_In the example, both Jack & Janet can see all of the data._ + +# [Static RLS](#tab/staticrls) + +**With RLS configured, data is filtered to only rows the user are allowed to see.** This is done according to the _Table Permissions_ configured in the model for that Table & Role. These Table Permissions are DAX Table Expressions configured for a specific model table. Rows that evaluate `True` are returned; rows that return `False` are filtered out due to RLS. + +The most simple Table Permissions are _Static_: + +```dax +// Table Permission for 'Regions' table and 'CTG' role +'Regions'[Territory] = "Central Transit Gate" +``` + +![Configuration of static RLS](~/content/assets/images/data-security/data-security-static-rls.png) + +_In the example:_ + +1. _Jack can see only rows for which 'Region'[Territory] = "Central Transit Gate", since they belong to the 'CTG' Role._ +2. _Executives, whom are permitted to see all the data, are added to a role with no Table Permissions._ +3. _Tommy, a user who can access the dataset but belongs to no Role, will not see any data. All visuals and queries will return a 'grey box of death'._ + +_It is necessary to create roles when using Data Security even when there are users like Executives, who have unrestricted data access._ + +# [Dynamic RLS](#tab/dynamicrls) + +**With RLS configured, data is filtered to only rows the user are allowed to see.** +This is done according to the _Table Permissions_ configured in the model for that Table & Role. + +These Table Permissions are DAX Table Expressions configured for a specific model table. +Rows that evaluate `True` are returned; rows that return `False` are filtered out due to RLS. + +**_Dynamic_ RLS relies on the `USERPRINCIPALNAME()` or `USERNAME()` functions to compare them to a security table.** +The security table will then return logic that applies the table filter to that or another table in the model. + +This is referred to as _Dynamic_ RLS as the result will change depending on the user; the `USERPRINCIPALNAME()`. +Below is an example of a Dynamic RLS Table permission: + +```dax +// Table Permission for 'Regions' table and 'Territory Directors' role. + +// Get Current User +VAR _CurrentUser = +SELECTCOLUMNS ( + FILTER ( + 'Employees', + 'Employees'[Employee Email] = USERPRINCIPALNAME () + ), + "@Name", 'Employees'[Employee Name] +) +RETURN +'Regions'[Territory Directors] IN _CurrentUser +``` + +The above table permission gets the Employee Name alias from the 'Employees' table, which is applied without a relationship to the 'Regions' table. +The result for any user added to this role is that they will only see data where: + +1. Their e-mail is in the 'Employees'[Employee Email] column +2. Their alias in 'Employees'[Employee Name] matches one in 'Regions'[Territory Directors] + +![Dynamic RLS Configuration](~/content/assets/images/data-security/data-security-dynamic-rls.png) + +_In the example, each Territory Director only sees the Territories for which they are responsible:_ + +1. _Jack sees "Central Transit Gate" and "Io"._ +2. _Janet sees "Arcadia III"._ +3. _Elisa sees all data, as the Execs role has no Table Permissions set._ + +_Dynamic RLS is the most common way to secure an Enterprise Dataset. It usually requires configuration & maintenance of a central **Security Table** used across all Enterprise datasets._ + +# [RLS (Multiple Roles)](#tab/multipleroles) + +**When a user is assigned to multiple roles, each of which have different Table Permissions, they will see data permitted by either role.** Users will see data where at least one Table Permission DAX expression evaluates to `True` for model table rows; it takes the logical `or`. + +This is dangerous if it's not expected; some developers may anticipate the intersection to be taken; to only show rows where **both** Table Permissions return `True`. This will only happen if Table Permissions are configured for multiple tables in the model; **within a Role**, the intersection is taken for all Table Permissions in the model. + +![RLS Roles combine table permissions using a logical OR](~/content/assets/images/data-security/data-security-combining-rls-roles.png) + +_In the example:_ + +1. _Jack is assigned to the roles 'CTG' and 'FTL'. They will see any rows where 'Products'[Type] = "FTL" **OR** where 'Regions'[Territory] = "Central Transit Gate". This is likely not the expected behavior; the developer likely intends to produce the result of the 'CTG/FTL' role, which returns only rows where both are true._ +2. _Elijah has the 'FTL' role, and will only see rows where 'Products'[Type] = "FTL". +3. _Abdullah has the 'CTG/FTL' role, and will only see rows where **BOTH** 'Products'[Type] = "FTL" **AND** 'Regions'[Territory] = "Central Transit Gate"._ + +_Situations like this illustrate the importance of designing clear Data Security configuration during model design, ensuring it aligns with organizational policies and existing Data Security / Access Management practices._ + +# [OLS](#tab/ols) + +**With OLS configured as `None`, queries are prevented from being evaluated; they return an error.** This is an important distinction from RLS; RLS filters data, but OLS prevents evaluation. If the OLS permission is set to `Read`, there is no effect. This is done according to the OLS Permission Level of the Column or Table, and **affects all downstream dependents** like Relationships and Measures. + +![OLS configured for the Cost column](~/content/assets/images/data-security/data-security-ols.png) + +_In the example, the column 'Territory Sales'[Cost] has an OLS Permission of `None` for the role 'Sales'. The reason is because of the below requirement:_ + +`'Sales' users are allowed to see Sales data, but not Cost or Margin data.` + +_This means that a user belonging to the 'Sales' role like Jack will not be able to see:_ + +1. _Any query or visual referring directly to the 'Territory Sales'[Cost] column_ +2. _Any DAX measure or calculation item referring directly to the 'Territory Sales'[Cost] column, like [Margin %]_ +3. _Any DAX measure or calculation item referring _indirectly_ (downstream) to the 'Territory Sales'[Cost] column._ +4. _Any object that has a column with a relationship with 'Territory Sales'[Cost]_ + +_The result of 1-4 will be an **error** in query evaluation. A Power BI visual will return a **grey box of death**._ + +> [!WARNING] +> __Business users will often perceive expected OLS results as being a 'broken' report, visual, or query. __
    If using OLS and users are expected to confront these evaluations, try the following:
    +> +> 1. Educate users about the security. +> 2. Try to handle the error and return a more meaningful message. +> 3. In Build scenarios, consider hiding the object. +> 4. A further optimization to be tested is setting `IsPrivate` to `True` or `IsAvailableInMDX` to `False`. + +# [RLS+OLS (Single Role)](#tab/rlsols) + +With both RLS & OLS configured, there are two possible outcomes: + +1. **The user has _one role_ with RLS & OLS:** The security will work as expected, presuming it is configured correctly. +2. **The user has _multiple roles_ where RLS & OLS are configured, separately:** The role combination is unsupported and the user will get an error. + +Because of #2, if you expect to use both RLS & OLS, this must be carefully considered during model design. + +An example of #1 is below: + +![Combining OLS and RLS in the same role produces the expected outcome](~/content/assets/images/data-security/data-security-ols-and-rls-functional.png) + +_In the example:_ + +1. _Jack, who has been assigned the 'CTG' Role:_ + - _Can only see data for "Central Transit Gate" due to the RLS Table Permission on 'Regions'._ + - _Can only see Sales data; they can't see [Margin %]. This is due to the OLS Object Permission `None` on 'Territory Sales'[Cost], which affects the dependent measure [Margin %]_ +2. _Elisa, who has been assigned the 'Execs' Role, can see all the data. There has been no RLS Table Permission or OLS Object Permission (set to `Default`) configured for 'Execs'._ +3. _Tommy, who has not been assigned a Role, cannot see any data._ + +> [!WARNING] +> Scenarios combining RLS & OLS are not rare.
    Scenarios using them correctly are.
    Ensure that if you have a requirement for RLS & OLS together, carefully consider it during model design. + +# [❌ RLS+OLS (Combine Roles)](#tab/rlsolscombined) + +With both RLS & OLS configured, there are two possible outcomes: + +1. **The user has _one role_ with RLS & OLS:** The security will work as expected, assuming it is configured correctly. +2. **The user has _multiple roles_ where RLS & OLS are configured, separately:** The role combination is unsupported and the user will get an error. + +Because of #2, if you expect to use both RLS & OLS, this must be carefully considered during model design. + +An example of #2 is below: + +![❌ Combining OLS and RLS across roles will produce an error](~/content/assets/images/data-security/data-security-ols-and-rls-dysfunctional.png) + +_In the above example:_ + +1. _Jack, who has been assigned the 'Read Users' Role:_ + - _Can only see data for "Central Transit Gate" due to the RLS Table Permission on 'Regions'._ + - _Can only see Sales data; they can't see [Margin %]. This is due to the OLS Object Permission `None` on 'Territory Sales'[Cost], which affects the dependent measure [Margin %]_ +2. _Janet, who has been assigned both the 'Read Users' and 'Build Users' Role:_ + - _Cannot see any data. The combination of RLS / OLS permissions across Roles are invalid._ + +_Users granted Build Permissions to the dataset are added to the Build Azure AD Security group, which is set for the 'Build Users' role. Build users can see tables not in existing reports, so `None` OLS permission is configured for the 'Employees' table. This produces a combination where RLS and OLS permissions cannot be reconciled, resulting in an error._ + +> [!WARNING] +> Scenarios combining RLS & OLS are not rare.
    Scenarios using them correctly are.
    Ensure that if you have a requirement for RLS & OLS together, carefully consider it during model design. + +# [❌ No Roles](#tab/role) + +**No user will be able to read any data until they are added to the role**, so long as Data Security is configured in the dataset. + +![No Access or No Role](~/content/assets/images/data-security/data-security-no-role.png) + +> [!NOTE] +> Don't forget to give users access to the dataset AND add them to the security role. + +# [❌ No Access](#tab/access) + +**If a user is added to a security role, this will not automatically grant them read access to the dataset.** They will still not be able to access any dataset or reports. + +![No Access or No Role](~/content/assets/images/data-security/data-security-no-access.png) + +> [!NOTE] +> Don't forget to give users access to the dataset AND add them to the security role. + +> [!WARNING] +> **It is a best practice to avoid distribution via Workspace Roles, where feasible.**
    If necessary, ensure that the **Principle of Least Permissions** is applied : users should have the minimum access necessary to do what they need. + +# [❌ Access Via Workspace Roles](#tab/workspace) + +**If a user is given access to a dataset via the Admin, Member or Contributor roles, they will be able to view all data, irrespective of the data security configuration and their assigned roles.** This is a common mistake in scaling or self-service Power BI ecosystems, resulting in data leaks and non-compliance. + +![Problems with ](~/content/assets/images/data-security/data-security-workspace-roles.png) + +> [!WARNING] +> **It is a best practice to avoid distribution via Workspace Roles, where feasible.**
    If necessary, ensure that the **Principle of Least Permissions** is applied : users should have the minimum access necessary to do what they need. + +--- + +--- + +### Hard Limitations + +Some reporting or data modeling features will not work with RLS or OLS configuration. Examples are: + +1. [RLS Limitations](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls#considerations-and-limitations) + - Service Principles added to RLS Roles + - Testing with Direct Query models using SSO + - [Publish-to-Web in Power BI](https://learn.microsoft.com/en-us/power-bi/guidance/rls-guidance#when-to-avoid-using-rls) + +2. [OLS Limitations](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-ols?tabs=table#considerations-and-limitations) + - Combining separate RLS roles & OLS roles (discussed above) + - Q&A features + - Quick Insights + - Smart Narrative + - Excel Data Types gallery + +--- + +### Further Reading & References + +For additional, detailed reading about Data Security, see the below references: + +1. [Power BI Security Whitepaper](https://learn.microsoft.com/en-us/power-bi/guidance/whitepaper-powerbi-security) +2. [Power BI Docs - Security](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-power-bi-security) +3. [Analysis Services Docs - Object-Level Security](https://learn.microsoft.com/en-us/analysis-services/tabular-models/object-level-security?view=asallproducts-allversions) +4. [Power BI Implementation Planning - Security](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-report-consumer-planning) +5. [(Related) Power BI Implementation Planning - Information Protection & Data Loss Prevention (DLP)](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-info-protection-data-loss-prevention-overview) \ No newline at end of file diff --git a/content/localization/de/data-security-setup-ols_de.md b/content/localization/de/data-security-setup-ols_de.md new file mode 100644 index 00000000..365fc8f9 --- /dev/null +++ b/content/localization/de/data-security-setup-ols_de.md @@ -0,0 +1,103 @@ +--- +uid: data-security-setup-ols +title: Setup or Modify OLS +author: Kurt Buhler +updated: 2023-03-02 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Setup or Modify Object-Level Security (OLS) + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-configure-ols-visual-abstract.png) + +--- + +**OLS is changed by adjusting the Roles or Object Permissions defined for Tables or Columns.** Object Permissions are TOM Properties visible with the `Object Level Security` property that can be either `Default` (no OLS; functionally similar to `Read`), `Read`, or `None`. OLS differs from RLS in that it does not filter data, but prevents execution of the object **and all dependents.** This means any relationship or measure that references the object where `Object Level Security` is set to `None` will return an error upon evaluation. + +--- + +- [**About Data Security and RLS/OLS:**](data-security-about.md) A functional overview of RLS & OLS. +- [**Modify/Setup an RLS Configuration:**](data-security-setup-rls.md) How to configure RLS in a dataset. +- **Modify/Setup an OLS Configuration (This Article):** How to configure OLS in a dataset. +- [**Testing RLS/OLS with Impersonation:**](data-security-testing.md) How to easily validate Data Security with Tabular Editor. + +--- + +## Configuring OLS in Tabular Editor 3 + +_Below is an overview of common changes one might make to existing OLS. Additionally, strategies for configuring OLS for atypical objects (Measures, Calculation Groups) are described, below:_ + +--- + +### 1. Remove a Role + +To remove a Role from the model, you can simply delete the Role object with `Del` or by right-clicking and selecting 'Delete'. + +
    + Data Security Create Role
    Figure 1: Deleting a Role in the model.
    +
    + +> [!NOTE] +> All users assigned to this role will no longer be able to see model data, so long as at least one other Role exists. + +--- + +### 2. Add a New Role + +To add a Role to the model: + +1. **Right-Click the 'Roles' Object Type:** This will open the dialogue to let you create a new Role. +2. **Select 'Create' > 'Role':** Name the new role. + +
    + Data Security Create Role
    Figure 2: Creating a new Role in the model.
    +
    + +3. **Set the `Model Permission` Property to `Read`:** This is necessary for Power BI datasets. + +
    + Data Security Create Role
    Figure 3: Setting the Model Permission property is necessary for Power BI.
    +
    + +4. **Set Permissions:** Set RLS Table Permissions and/or OLS Object Permissions, as described, below. + +--- + +### 3. Remove OLS + +To remove OLS from the model, all Columns and Tables must have their `Object Level Security` property configured to `Default` for all roles. To remove Data Security from the model, all Roles must be deleted. + +
    + Data Security Create Role
    Figure 4: The Object-Level Security property can be found in the Properties pane when selecting a Column or Table. The property does not exist for Measures, Relationships and other Object Types.
    +
    + +> [!NOTE] +> Once all roles are deleted, all users will be able to see all data so long as they have _Read_ permissions on the dataset. + +--- + +### 4. Setup or Change OLS + +Setup or Modification of OLS is trivial for Columns and Table. You just have to select the object and navigate to the `Object Level Security` property, using the dropdown to change the property to the desired value. + +
    + Data Security Create Role
    Figure 4: The Object-Level Security property can be changed with an adjacent drop-down, allowing selection of Default, None or Read.
    +
    + +--- + +### 5. Combine OLS with RLS + +Successfully combining RLS with OLS requires designing a model and Data Security / Access Management strategy that align. Since RLS and OLS cannot combine across roles, this means if you plan on implementing both RLS and OLS, users are limited to a single role. + +--- + +### 6. Configure OLS for Measures + +Natively, OLS works only on Columns, Tables and their dependents; there is no `Object-Level Security` property for measures. However, since OLS also applies to dependents, it is possible to design OLS that works on measures via disconnected tables or calculation groups. To do this, the measure DAX has to be altered to evaluate a column or calculation group configured with RLS. If the `Object-Level Security` property of that object is `None`, then the Measure will not evaluate. + +See also [this article by SQLBI](https://www.sqlbi.com/articles/hiding-measures-by-using-object-level-security-in-power-bi/) which explains this approach in detail. \ No newline at end of file diff --git a/content/localization/de/data-security-setup-rls_de.md b/content/localization/de/data-security-setup-rls_de.md new file mode 100644 index 00000000..7b55b9bf --- /dev/null +++ b/content/localization/de/data-security-setup-rls_de.md @@ -0,0 +1,181 @@ +--- +uid: data-security-setup-rls +title: Setup or Modify RLS +author: Kurt Buhler +updated: 2023-03-14 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Configure Row-Level Security (RLS) + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-configure-rls-visual-abstract.png) + +--- + +**RLS is changed by adjusting the Roles or Table Permissions defined for Tables.** This DAX _Filter Expression_ can be viewed in the Expression Editor window when selecting a Table Permission within a particular role. This Filter Expression is the most important piece of the RLS configuration that determines what data is seen by a user. + +--- + +- [**About Data Security and RLS/OLS:**](data-security-about.md) A functional overview of RLS & OLS. +- **Modify/Setup an RLS Configuration (This Article):** How to configure RLS in a dataset. +- [**Modify/Setup an OLS Configuration:**](data-security-setup-ols.md) How to configure OLS in a dataset. +- [**Testing RLS/OLS with Impersonation:**](data-security-testing.md) How to easily validate Data Security with Tabular Editor. + +--- + +## Configuring RLS in Tabular Editor 3 + +_Below is an overview of common changes one might make to existing RLS:_ + +--- + +### 1. Remove a Role + +To remove a Role from the model, you can simply delete the Role object with `Del` or by right-clicking and selecting 'Delete'. + +
    + Data Security Create Role
    Figure 1: Deleting a Role in the model.
    +
    + +> [!NOTE] +> All users assigned to this role will no longer be able to see model data, so long as at least one other Role exists. + +--- + +### 2. Add a New Role + +To add a Role to the model: + +1. **Right-Click the 'Roles' Object Type:** This will open the dialogue to let you create a new Role. +2. **Select 'Create' > 'Role':** Name the new role. + +
    + Data Security Create Role
    Figure 2: Creating a new Role in the model.
    +
    + +3. **Set the `Model Permission` Property to `Read`:** This is necessary for any members of the role to be able to access the dataset at all. + +
    + Data Security Create Role
    Figure 3: Setting the Model Permission property is necessary.
    +
    + +4. **Set Permissions:** Set RLS Table Permissions and/or OLS Object Permissions, as described, below. + +--- + +### 3. Remove RLS + +To remove RLS from the model, all Table Permissions must be deleted. To remove Data Security from the model, all Roles must be deleted. + +> [!NOTE] +> Once all roles are deleted, all users will be able to see all data so long as they have _Read_ permissions on the dataset. + +--- + +### 4. Modify a Table Permission + +To modify an existing Table Permission for a specific role: + +1. **Expand the Role:** This will reveal the Table Permissions. +2. **Select the Table Permission:** This will reveal the DAX for the Filter Permission in the Expression Editor. + +
    + Data Security Create Role
    Figure 4: The DAX Filter Expression is visible in the Expression Editor when selecting a Table Permission.
    +
    + +3. **Adjust the Filter Expression / RLS Table Permissions:** It is recommended that you test / validate the DAX before using it: + +- Copy the Filter Expression to a new DAX Query window under an `EVALUATE` statement. +- Add it as the Expression of an `ADDCOLUMNS` statement iterating over Table, or part of the table. +- Execute it and observe the results. +- Replace `USERNAME()` or `USERPRINCIPALNAME()` in dynamic RLS with a known value from the Security Table. +- Re-run the DAX Query and validate that the results appear as expected. Repeat until satisfied. + +
    + Data Security Validation
    Figure 5: An example of how RLS can be validated from the DAX query window by using the Filter Expression inside of an Iterator over the Table (or part of the table, like the user alias). In this example, the original RLS Filter Expression in the Table Permission has been modified (Yellow) where an explicit User Principal Name in the dataset is added instead, to test (Green). The RLS code is executed inside of the ADDCOLUMNS iterator over a relevant part of the table. The checkmark indicates any row that evaluates to TRUE. The test demonstrates that the RLS is - for this UPN - working as expected, since Gal Aehad is the only user returning TRUE when their UPN is given.
    +
    + +```dax +EVALUATE + +// Create a table to test your RLS +ADDCOLUMNS ( + VALUES ( 'Regions'[Territory Directors] ), + "@RLS-Validation", + + // RLS Code + VAR _CurrentUser = + SELECTCOLUMNS ( + FILTER ( + 'Employees', + 'Employees'[Employee Email] + + // Replace USERPRINCIPALNAME() with a user email to test + = "gal.aehad@spaceparts.co" // USERPRINCIPALNAME () + ), + "@Name", 'Employees'[Employee Name] + ) + RETURN + 'Regions'[Territory Directors] IN _CurrentUser + +) + +// Order from TRUE() to FALSE() +// Where it is TRUE() the data will be visible +ORDER BY [@RLS-Validation] DESC +``` + +--- + +### 5. Add a New Table Permission to a Role + +To add a new table permission: + +1. **Right-Click the Role:** Select 'Add table permission...' + +
    + Data Security Create Role
    Figure 6: In Tabular Editor, Table Permissions for RLS are visible under the role. New table permissions can be created by right-clicking a Role and selecting 'Add Table Partition...'
    +
    + +2. **Select the Table and press 'OK':** Select the table for which you want to create the permission. +3. **Write the Filter Expression / RLS Table Permissions:** Write the DAX for the filter expression. As above, you want to validate this filter expression (See **Figure 5**): + +- Copy the Filter Expression to a new DAX Query window under an `EVALUATE` statement. +- Add it as the Expression of an `ADDCOLUMNS` statement iterating over Table, or part of the table. +- Execute it and observe the results. +- Replace `USERNAME()` or `USERPRINCIPALNAME()` in dynamic RLS with a known value from the Security Table. +- Re-run the DAX Query and validate that the results appear as expected. Repeat until satisfied. + +--- + +### 6. Assign or Remove Users from a Role + +You can assign and remove users/groups from roles through Tabular Editor. + +1. Right-Click the **Role**, select **Edit members**... + +
    + Data Security Create Role
    Figure 7:Users can be assigned to roles by right-clicking a Role and selecting 'Edit members...'.
    +
    + +2. Click the **dropdown button** on the 'Add Windows AD Member' button and choose **Azure AD Member**: + +
    + Data Security Create Role
    Figure 8: For AAS/SSAS models, users can be added via the 'Edit members...' dialog box.
    +
    + +3. Specify the Azure AD user identity (typically, the user e-mail address) as the **Member Name** property. +4. Click **OK**. +5. **Save** the model. + +> [!IMPORTANT] +> If your organisation is using on-premises Active Directory with SQL Server Analysis Services, you will need to use the **Windows AD Member** option instead of **Azure AD Member**. + +> [!NOTE] +> Once a Power BI dataset has been published to the Power BI Service, you can also manage role members through the [Dataset Security settings](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls#manage-security-on-your-model). Alternatively, you can manage role members through [SQL Server Management Studio](https://learn.microsoft.com/en-us/analysis-services/tabular-models/manage-roles-by-using-ssms-ssas-tabular?view=asallproducts-allversions) (this applies to AAS/SSAS models in addition to Power BI dataset). + +--- diff --git a/content/localization/de/data-security-testing_de.md b/content/localization/de/data-security-testing_de.md new file mode 100644 index 00000000..da2cf8ab --- /dev/null +++ b/content/localization/de/data-security-testing_de.md @@ -0,0 +1,79 @@ +--- +uid: data-security-testing +title: Testing RLS/OLS +author: Kurt Buhler +updated: 2023-03-02 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Testing Data Security with Impersonation + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-testing-visual-abstract.png) + +--- + +**DAX Queries**, **Pivot Grid**, or **Preview Data** enable testing of Data Security in Tabular Editor. It is recommended to _always_ test Data Security with any changes to configuration, to mitigate risk of incorrect RLS/OLS implementation and the consequences thereof. + +> [!IMPORTANT] +> Testing Data Security with Impersonation using Tabular Editor 3 is limited to datasets hosted in an Analysis Services instance or the Power BI Service. Tabular Editor 3 Desktop Licenses cannot benefit from this feature. + +--- + +- [**About Data Security and RLS/OLS:**](data-security-about.md) A functional overview of RLS & OLS. +- [**Modify/Setup an RLS Configuration:**](data-security-setup-rls.md) How to configure RLS in a dataset. +- [**Modify/Setup an OLS Configuration:**](data-security-setup-ols.md) How to configure OLS in a dataset. +- **Testing RLS/OLS with Impersonation (This Article):** How to easily validate Data Security with Tabular Editor. + +--- + +## Testing with Impersonation + +**Data Security can be easily tested using _Impersonation_ in Tabular Editor 3.** Impersonation is a feature that lets you view a query result as a model Role or User. It is similar to the _'View As Role...'_ feature in the Power BI service, with two key differences: + +1. The End-User being impersonated requires **dataset Build permissions** in addition to Role assignment & Dataset Read access. +2. Any query can be executed within Tabular Editor 3; it is not limited to available report visuals, as in the Power BI Service. + +This is valuable, as it lets the developer run defined tests to see how the result would be viewed by any end-user with Build permissions. This helps ensure that even for complex queries and DAX expressions, the Data Security works as expected, and users only see what they should see. + +> [!IMPORTANT] +> Ensure that Build permissions are not provisioned by providing end-users Workspace Roles (Contributor, Member, Admin), as these roles have **Write** permissions to the dataset and thus bypass Data Security; the testing will appear to not work, even if it's configured correctly. + +
    + Data Security Create Role
    Figure 1: A demonstration of RLS testing in Tabular Editor using impersonation. Shown is testing with (A) Data Preview, (B) DAX Queries and (C) Pivot Grid.
    +
    + +--- + +## How to Test with Impersonation + +To test with impersonation, follow the below steps: + +1. **Ensure that the Dataset Configuration & Access is correct:** + End-users being impersonated... + +- _...have been assigned to the appropriate **Roles**._ +- _...have been provisioned **Dataset Read Access**._ +- _...have been provisioned **Dataset Build Access**. (Power BI)_ +- _...**are not** Workspace Contributors, Members or Admins (Power BI)_. + +2. **Create a new DAX Query, Pivot Grid or Preview Data window:** + +- It's recommended that you start with _Preview Data_ to observe the effect on model tables +- Thereafter, perform a second validation with a _DAX Query_. This is because DAX Queries can be saved for documentation and later reference, if a change occurs in the model requiring re-testing. + +3. **Select 'Impersonation' and enter the User e-mail**: If you have implemented _Static RLS_, you can test the role, instead. + +4. **Explore the data to validate that the results appear as expected:** (according to the Security Rules). + +### Tips for Testing + +1. **Test more than one user:** It's recommended you test at least 3-10 different users per Role. You can also automate the testing to iterate through each UPN in the Security Table (i.e. using C# Scripting and Macros). + +2. **Test each Role & Table Permission:** Since each Table Permission represents a different DAX Filter Expression, they all have to be tested, separately. Ensure that each Role is tested, and that each test includes the relevant tables with configured Filter Expressions. For example, if a Role consists of table expressions on the 'Customers' and 'Products' table, ensure your query includes attributes from both tables for validation purposes. + +3. **Test many Queries/Measures:** Try to find complex queries to test, particularly those which might be problematic in the context of Data Security. For example, if calculations require comparing to a total, unfiltered average (i.e. % of total) and it's expected that _that total_ is not filtered in RLS, the developer may need to re-think the Data Security implementation as a function of the model. \ No newline at end of file diff --git a/content/localization/de/dax-debugger_de.md b/content/localization/de/dax-debugger_de.md new file mode 100644 index 00000000..1e568783 --- /dev/null +++ b/content/localization/de/dax-debugger_de.md @@ -0,0 +1,218 @@ +--- +uid: dax-debugger +title: DAX debugger +author: Daniel Otykier +updated: 2022-01-19 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX debugger + +> [!NOTE] +> The DAX debugger was introduced in version 3.2.0. Information in this article is subject to change as we add more capabilities to the debugger. + + + +It is no secret that DAX is a relatively complex language which is difficult to master. Most data model developers have probably experienced a situation, where the DAX code did not return the expected result. In this situation, it is helpful to break down the code, variable by variable and function call by function call, to better understand what is going on. + +Until now, this "breakdown" of the code was a tedious and time consuming task, which often involved capturing DAX queries executed by client tools, in order to break them down and execute smaller pieces of the queries in [DAX Studio](https://daxstudio.org/) or [SQL Server Management Studio](https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15). + +Tabular Editor 3 introduces the concept of the **DAX debugger**, which is a tool that makes the process of stepping into the DAX code of your model, much, much easier. At a conceptual level, the debugger is similar to traditional IDE debuggers, such as the one found in Visual Studio when developing C# applications. + +## Prerequisites + +The DAX debugger analyses the DAX code in your model and generates suitable DAX queries for evaluating sub expressions, row contexts, etc., allowing you to step through the code in an interactive fashion. + +In order for this to work, Tabular Editor 3 must operate in **connected** or **workspace mode**, such as when loading model metadata directly from Power BI Desktop or any other instance of Analysis Services. + +# Getting started + +While Tabular Editor 3 is connected to an instance of Analysis Services, the debugger can be started in one of two different ways: + +- Through a Pivot Grid +- Through a DAX query + +Once the debugger is started, you are presented with a number of new views that provide contextual information about the code being debugged, as well as a DAX script view that highlights the portion of code currently debugged. + +> [!TIP] +> Before starting a debugging session, consider formatting your DAX code to make the code easier to read. + +# Debugging through a Pivot Grid + +1. Create a new Pivot Grid (**File > New > Pivot Grid**) +2. Add the measure you wish to debug to the Pivot Grid. You can either: + +- Drag a measure from the TOM Explorer, or +- Right-click on a measure in the TOM Explorer and choose **Add to pivot grid**, or +- Select the measure from the Pivot Grid field list (**Pivot Grid > Show fields**) + +3. (Optional) Add one or more columns to the Pivot Grid in the Filter area, Columns area or Row area. +4. Right-click on the value cell within the Pivot Grid and choose **Debug this value**. + +![Debug From Pivot](~/content/assets/images/debug-from-pivot.png) + +# Debugging through a DAX Query + +1. Create a new DAX query (**File > New > DAX Query**). +2. Type in or paste the DAX query. This should typically be a query made up of a `SUMMARIZECOLUMNS` call with one or more (explicit) measures, such as the one generated by visuals in Power BI. + +> [!TIP] +> You can use the [Performance Analyzer](https://docs.microsoft.com/en-us/power-bi/create-reports/desktop-performance-analyzer) in Power BI Desktop to capture the query generated by visuals. + +3. Hit F5 to execute the query within Tabular Editor 3. Locate the value you want to debug, right-click the cell and choose **Debug**. + +![Debug From Query](~/content/assets/images/debug-from-query.png) + +# Debug views + +The debugger provides the following views (if they are hidden, they can be accessed through the **Debug > Windows** menu). + +- Locals +- Watch +- Evaluation Context +- Call Tree + +## Locals + +This view lists the columns, measures and variables within the current scope of execution and displays their values. It also displays the value of the current subexpression being debugged. Values in this list are updated automatically when stepping to a different subexpression, or when the evaluation context is changed. **Local values are always evaluated at the currently selected item of the call tree**. + +![Locals](~/content/assets/images/locals.png) + +You can inspect a locals value by clicking on the magnifying glass button within the **Value** column. This will bring up a popup dialog showing the value in more details. This is especially useful if the inspected value is a table. + +![Inspect locals value](~/content/assets/images/inspect-locals.png) + +If you prefer to inspect the locals value in a separate DAX query window, you can toggle off the **Use popup inspector** option under **Tools > Preferences > DAX Debugger > Locals**. + +![Dax Debugger Settings](~/content/assets/images/dax-debugger-settings.png) + +## Watch + +This view allows you to enter any DAX expression, which will be calculated within the current evaluation context. You can enter scalar as well as table expressions and you can use all DAX functions available and refer to variables within the current evaluation scope. Watch values are automatically updated when stepping to a different subexpression, or when the evaluation context is changed. **Watch values are always evaluated at the scope of the currently selected item in the evaluation context stack**. + +![Watch](~/content/assets/images/watch.png) + +To quickly add a variable, measure or subexpression to the Watch view, simply highlight a portion of code and drag it into the Watch view. You can also place the cursor over the expression you want to add, then right-click and choose **Watch this expression**: + +![Quick Add To Watch](~/content/assets/images/quick-add-to-watch.png) + +To add, duplicate or delete Watch expressions, use the right-click context menu of the Watch view: + +![Watch Context Menu](~/content/assets/images/watch-context-menu.png) + +The **Generate query** option is identical to the magnifying glass button within the **Value** column, highlighted in the screenshot below. By clicking this, the debugger will open a new DAX query document, that defines the context of the calculation as well as the calculation itself, allowing you to inspect the results in more details. This is particularly useful when the watch expression is a table expression, as shown below: + +![Inspect Watch](~/content/assets/images/inspect-watch.png) + +> [!TIP] +> What's the difference between the **Locals** view and the **Watch** view? +> +> - **Locals** shows the values of columns, measures, variables and other relevant sub-expressions, within the current scope of execution, including the value of the currently selected subexpression in the call tree. +> - **Watch** allows you to enter any DAX expression, which will be calculated within the current evaluation context. + +## Evaluation Context + +This view provides information about the DAX evaluation context of the current subexpression. For example, a `CALCULATE` expression might perform a context transition or add a filter to the evaluation context, or a `SUMX` iterator might add a row context. + +![Evaluation Context](~/content/assets/images/evaluation-context.png) + +You can double-click on an item in the Evaluation Context stack, to bring the focus to that item. This will cause all **Watch** expressions to be reevaluated in the new context (that is, all contexts from the bottom of the stack up to and including the currently focused item). This is illustrated in the animation below. Notice also how you can inspect the value of individual columns in the active row context by paging through rows within any active iterations: + +![Call Tree](~/content/assets/images/navigating-evaluation-context.gif) + +You can also toggle individual filters from the outer filter context (for example, grouping columns on the [`SUMMARIZECOLUMNS`](https://dax.guide/summarizecolumns) call that generated the query or filters specified in a Pivot Grid). This is illustrated in the animation below. Filters toggled this way will apply to both Watch and Locals. + +![Call Tree](~/content/assets/images/toggle-filters.gif) + +Lastly, you can browse the first 1000 rows of any iterator, setting the current row context to a specific row within those first 1000, by clicking on the Zoom button within the **Row** column. + +![Browse Row Contexts](~/content/assets/images/browse-row-contexts.png) + +## Call Tree + +This view provides an outline of the entire calculation and lets you easily navigate between subexpressions by double-clicking (you can also use shortcut keys for navigation). The tree also provides information about context transitions, iterations and row contexts. Branches of code that will not be executed (for example in an `IF` or `SWITCH` call, or when an iterator is empty) are striked out. + +![Call Tree](~/content/assets/images/call-tree.png) + +As you navigate between items in the call tree, the debug DAX script will highlight the code corresponding to the call tree item, while also indicating (with a gray background) the path taken to reach the highlighted code, as shown below: + +![Call Tree](~/content/assets/images/navigating-call-tree.gif) + +Notice how the values in the **Locals** view are updated as the tree is navigated. You can also navigate to a subexpression by placing the cursor over the expression, right-click and choose the **Step into selection** option (Ctrl+B). + +![Step into selection](~/content/assets/images/debugger-step-into-selection.png) + +## Scalar predicates + +Scalar predicates used in filter arguments of the [`CALCULATE`](https://dax.guide/calculate) or [`CALCULATETABLE`](https://dax.guide/calculatetable) functions are handled in a special way, in the **Locals** view. + +For example, the following measure uses a scalar predicate, to display only the sales made in USA or Canada. + +```dax +CALCULATE( + [Total Sales], + Geography[Country Region Code] = "US" || Geography[Country Region Code] = "CA" +) +``` + +At first glance, the expression on line 3 looks like it would return a scalar value (true/false). However, in DAX, filters are tables. In reality, the scalar predicate is converted to a table expression using the [`FILTER`](https://dax.guide/filter) function, as shown below: + +```dax +CALCULATE( + [Total Sales], + FILTER( + ALL(Geography[Country Region Code]), + Geography[Country Region Code] = "US" || Geography[Country Region Code] = "CA" + ) +) +``` + +The `FILTER` function is an iterator that iterates over the table `ALL(Geography[Country Region Code])`, that is - all the unique values of the "Country Region Code" column in the "Geography" table. Iterators generate a filter context for every row in the iteration. The scalar predicate is then evaluated in each such row context. In the case of the `FILTER` function, only the rows for which the predicate evaluates to `TRUE` are kept. In this example, the `FILTER` function would output a table with 1 column ("Country Region Code"), and 2 rows ("US" and "CA"). + +When debugging a scalar predicate, the **Locals** view will show two special items, **(Current expression)** and **(Filter expression)**. These are described below: + +![Debug Scalar Predicates](~/content/assets/images/debug-scalar-predicates.png) + +In the above screenshot: + +1. This is the scalar predicate currently being debugged. Even though this sub-expression looks like one that should return a scalar value (true/false), in reality, it returns a table. +2. **(Current expression)**: This is the _scalar_ value of the predicate, when evaluated within the current _row context_ generated by the `FILTER` function as described above. In the screenshot, the scalar value evaluates to `False`, because the value of [Country Region Code] in the current row context is "AU", as can be seen in the **Watch** view, (4). We can use the **Evaluation Context** view (5), to scroll through the rows of the iteration one by one. +3. **(Filter expression)**: This is the _table_ expression generated by the `FILTER` function, as described above. In the screenshot, this is a 1x2 table containing the values "US" and "CA". Clicking the magnifying glass button will open a popup that displays the table values in a grid. +4. We can use the **Watch** window to evaluate any DAX expression within the current evaluation context. In this case, since we have an active row context, we can directly refer to columns in the row context, such as `Geography[Country Region Code]`. We can see that the current value of this column is "AU", which is why the scalar predicate (2) evaluates to `False`. +5. We can use the **Evaluation Context** view to scroll through the rows of the iteration, one by one. This will update the values in the **Locals** view, as well as the **Watch** view, to reflect the values in the current row context. + +## Keyboard shortcuts + +Use the following keyboard shortcuts to quickly navigate the call tree: + +- **Step in (F11)** - steps into the first child of the current item in the call tree. If there are no more children, jumps to the next sibling. +- **Step out (Shift-F11)** - steps out to the parent of the current item in the call tree. +- **Step over (F10)** - jumps to the next function parameter, the next subexpression of an arithmetic operation, or steps into the current function call (if it is a non-trivial function). +- **Step back (Shift-F10)** - jumps to the previous function parameter, the previous subexpression of an arithmetic operation, or steps out to the parent of the current item if there are no parameters or subexpressions before the current item. +- **Step into selection (Ctrl-B)** - jumps to the expression under the cursor. If multiple paths lead to the same expression (for example, when a measure is referenced by multiple measures and these measures), a dialog will prompt you to choose the path. +- **Next row (F9)** - shifts the row context of the innermost iteration to the next row of the iterator. +- **Previous row (Shift-F9)** - shifts the row context of the innermost iteration to the previous row of the iterator. + +# Limitations and known issues + +The DAX debugger currently has the following limitations: + +- **UDFs:** User-defined functions (UDFs) are not currently supported. If a UDF is encountered in the code being debugged, the debugger may behave unexpectedly. +- Only a subset of DAX table expressions are supported when debugging a DAX query (for example, queries that rely on [SUMMARIZECOLUMNS](https://dax.guide/summarizecolumns) can be debugged, while other table functions are currently not supported). Queries that have been generated by Power BI (which can be captured through the Power BI Desktop Performance Analyzer) are generally supported. +- Queries that contain implicit measures or query-scoped calculations are currently not supported. +- When browsing the first 1000 rows of an iterator that arises out of a filtered table expression, the selected row in the browse window may not always correspond to the current row context in the evaluation context stack (type `CALCULATETABLE('
    ')` in the **Watch** window to inspect the current row context). +- The debugger currently only allows debugging DAX expressions on measures. +- [Visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview) cannot be debugged as they are defined using query-scoped columns. The debugger does not currently support query-scoped objects. +- If a measure is modified by a calculation item in the filter context, partial results shown in the Watch / Locals view of the debugger may be incorrect. + +If you encounter an issue with the debugger, other than those listed above, please post it to our [issue tracker](https://github.com/TabularEditor/TabularEditor3/issues) on the TE3 Community Support GitHub site. + +# Roadmap + +We plan to add many additional features to the DAX debugger over time, to address the issues above, and to make the tool even more capable. As always, feedback is more than welcome. Please use the [Discussions area](https://github.com/TabularEditor/TabularEditor3/discussion) for feature requests and general discussions. + +**Happy debugging!** diff --git a/content/localization/de/dax-editor_de.md b/content/localization/de/dax-editor_de.md new file mode 100644 index 00000000..3f3a0565 --- /dev/null +++ b/content/localization/de/dax-editor_de.md @@ -0,0 +1,70 @@ +--- +uid: dax-editor +title: DAX Editor +author: Daniel Otykier +updated: 2023-02-03 +--- + +# DAX Editor + +The **DAX Editor** is the centerpiece of Tabular Editor 3. + +It comes in three different _flavours_: + +- **Expression Editor** Used for making quick changes to singular DAX expressions on objects in the TOM Explorer. +- **DAX Query** (Connected feature) Used for writing DAX queries in order to retrieve data from the connected instance of Analysis Services / Power BI. +- **DAX Script** Used for viewing and editing DAX expressions and basic properties across multiple objects in a single document. + +All three flavours support the same operations in terms of [keyboard shortcuts](xref:shortcuts#dax-code), syntax highlighting, code assist, etc. + +## Code Assist features + +The main enabler of productivity in Tabular Editor 3's DAX Editor, is its **Parameter Info** and **Auto-Complete** features. Collectively, these are known as **Code Assist** features (other vendors use the term "IntelliSense"). + +**Parameter Info** provides details about the DAX function and its parameter at the position of the cursor. The information is displayed in a tooltip above the cursor. Hit [Esc] to close the tooltip and [Ctrl+Shift+Space] to display it. + +**Auto-Complete** provides context-sensitive suggestions as you type, in a dropdown box. You can use the keyboard to navigate the items in the dropdown and hitting [Enter] or [Tab] will insert the selected item into your code. You can hit [Esc] to close the dropdown and [Ctrl+Space] to open it. + +These features can also be invoked through the context menu of the editor. + +DAX calltips update as you cycle syntax alternatives using the Up/Down arrows. + +![Dax Code Assist](~/content/assets/images/dax-code-assist.png) + +Most aspects of code assist can be configured under [**Tools > Preferences > Text Editors > DAX Editor > Code Assist**](xref:preferences#dax-editor--code-assist). + +## Peek Definition + +While the cursor is over an object reference such as a variable or a measure reference, hit [Alt+F12] to display an inline editor with the definition of that object, below the cursor. This is useful when you want to see the DAX code of a referenced object without leaving the current position in the document. + +![Peek Definition](~/content/assets/images/peek-definition.png) + +Use the Esc key to close the Peek Definition panel again. + +## Go To Definition + +Instead of peeking, we can also jump straight to the location where the referenced object is defined. To do this, hit [F12]. If the referenced object is not defined within the current document, this operation will jump over to that object in the TOM Explorer. If needed, you can navigate back using [Alt+Left Arrow]. + +# Define Measure + +For DAX scripts and DAX queries, it is sometimes useful to include the definition of a measure that is referenced elsewhere in the code. The **Define Measure** feature lets you do that when the cursor is over a measure reference. You may also choose the **Define Measure with Dependencies** option if you want to include all downstream measure references as well. + +![Define Measure With Deps](~/content/assets/images/define-measure-with-deps.png) + +# Inline Measure + +If you want to bring the definition of a measure into the current document, the **Inline Measure** feature lets you do just that. When a row context is surronding the original measure reference, Tabular Editor automatically surrounds the measure expression with [`CALCULATE`](https://dax.guide/calculate) (which is implicit in measure references). + +# Format DAX + +The DAX Editor in Tabular Editor 3 automatically formats your code as you type, i.e. fixing casing of functions and object references, adding proper indentation and spaces between parentheses, etc. All of this can be configured under [**Tools > Preferences > Text Editors > DAX Editor > Auto Formatting**](xref:preferences#dax-editor--auto-formatting). + +However, sometimes it is necessary to format the entire document. This can be done by hitting [F6] or [Shift+F6] if you prefer more frequent line breaks. For DAX Queries, you may also use [Alt+F6] to reformat the code to always add commas at the front of a line, which is useful when debugging. + +# Refactoring + +If you want to change the name of a variable or extension column, you can use the **Refactor** option (Ctrl+R) while the cursor is located on the variable or extension column reference. This will select all instances of that object, allowing you to rename it everywhere at once. + +# Configurable keyboard shortcuts + +The DAX Editor and code editors in general are highly configurable and support a lot of additional commands for quickly and productively editing code. You can view all of these commands, as well as modify and assign keyboard shortcuts under **Tools > Preferences > Tabular Editor > Keyboard**. \ No newline at end of file diff --git a/content/localization/de/dax-optimizer-integration_de.md b/content/localization/de/dax-optimizer-integration_de.md new file mode 100644 index 00000000..db7431c9 --- /dev/null +++ b/content/localization/de/dax-optimizer-integration_de.md @@ -0,0 +1,123 @@ +--- +uid: dax-optimizer-integration +title: DAX Optimizer Integration +author: Daniel Otykier +updated: 2024-10-30 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX Optimizer Integration + +> [!NOTE] +> Tabular Editor 3 **Enterprise Edition** users are eligible for free DAX Optimizer access. [Learn more](https://blog.tabulareditor.com/2024/10/31/free-dax-optimizer-access-in-tabular-editor-3/) + +Tabular Editor 3.18.0 introduces **DAX Optimizer** as an integrated experience. [DAX Optimizer](https://daxoptimizer.com) is a service that helps you optimize your SSAS/Azure AS tabular models and Power BI/Fabric semantic models. The tool combines [VertiPaq Analyzer statistics](https://www.sqlbi.com/tools/vertipaq-analyzer/) with a static analysis of your DAX code, thus providing a prioritized list of recommendations, to help you quickly identify potential performance bottlenecks. + +> [!IMPORTANT] +> DAX Optimizer is a paid third-party service. In order to use the **DAX Optimizer** feature in Tabular Editor 3, you will need an [account for DAX Optimizer](https://www.daxoptimizer.com/free-tour/). + +## Video introduction + +Watch Marco Russo from [SQLBI](https://www.sqlbi.com) introduce the DAX Optimizer integration in Tabular Editor 3: + + + +## Getting started + +To access this feature, go to the **View** menu and choose **DAX Optimizer**. + +![Dax Optimizer](~/content/assets/images/dax-optimizer-view-menu.png) + +You will be presented with a new view similar to the figure below: + +![Dax Optimizer View](~/content/assets/images/dax-optimizer-view.png) + +To connect Tabular Editor 3 to the DAX Optimizer service, click **Connect...** through the **Options** menu. You will be prompted to enter your Tabular Tools (DAX Optimizer) credentials. + +If you wish to **disconnect** or **connect using a different account**, go to the **Options** menu again, and choose the **Reconnect...** option. Cancelling the dialog will disconnect the current session. + +If you want Tabular Editor 3 to automatically connect the next time the application is launched, you can check the **Connect automatically** option within the **Options** menu. If you have a DAX Optimizer account with workspaces in multiple regions, you can also choose which region to connect to through the **Options** menu. + +Lastly, the **Options** menu also lets you switch to a different account in [group scenarios](https://docs.daxoptimizer.com/how-to-guides/managing-groups). + +## Browsing workspaces and models + +Once connected, the dropdowns at the top of the view will be populated with your existing workspaces, models and model versions. Make your selections from left to right (i.e. choose the **Workspace** first, then the **Model**, then the **Version**). The view will display a summary of the currently selected model version, with information such as model size, number of tables, number of measures, etc. + +![Model Overview](~/content/assets/images/model-overview.png) + +> [!NOTE] +> Tabular Editor 3 lets you upload VPAX files in order to create new models or model versions in the DAX Optimizer service. If, however, you need to create or manage workspaces, move or share models, etc. you will need to do this through the [DAX Optimizer web interface](https://app.daxoptimizer.com). + +If a model version has not yet been analyzed, you will have an option to start the analysis. Note that, depending on your account plan, you may have a limited number of "runs" available. + +Once the analysis is complete, you will be presented with a summary showing the number of issues detected. The information shown is similar to what you would see in the DAX Optimizer web interface. + +Go to the **Issues** or **Measures** tab to view detailed results. Use the column headers to sort and filter the results. + +![Dax Optimizer Issues](~/content/assets/images/dax-optimizer-issues.png) + +## Navigating issues and measures + +When you double-click on an issue or measure in the detailed view shown above, you will be taken to the **DAX Optimizer Results** view, where the original DAX expression of the measure is shown, along with highlights of the problematic areas. The list on the left side of the screen lets you toggle which issues to highlight. Moreover, you can mark issues as **Fixed** or **Ignored** using the checkboxes within the list. + +![Dax Optimizer Results](~/content/assets/images/dax-optimizer-results.png) + +Click on the **Find in TOM Explorer...** button in the top-right area of the view, to navigate to the corresponding measure in the currently loaded model. + +Tick the **Track TOM Explorer** checkbox to keep the TOM Explorer in sync with the currently selected measure in the DAX Optimizer Results view. + +When you click on a measure reference in the DAX code panel within the **DAX Optimizer Results** view, the view will navigate to that measure. You can then use the **Back** (Alt+Left) and **Forward** (Alt+Right) buttons to navigate back and forth between the measures you have visited. + +## Upload models and model versions + +To upload VPAX statistics to DAX Optimizer, make sure Tabular Editor is currently connected to an instance of Analysis Services (SSAS, Azure AS, Power BI Desktop or Power BI/Fabric XMLA endpoint). Then, select the workspace in the top-left dropdown on the **DAX Optimizer** view. Click on **Upload...** within the **Options** menu. + +You will be presented with a dialog similar to the one shown below: + +![Upload Vpax](~/content/assets/images/upload-vpax.png) + +Here, you can choose whether the VPAX should be uploaded as a new model within the workspace, or whether the VPAX contains updated statistics for an existing model. + +- For a **new model**, you must supply a name and choose whether or not the VPAX should be [obfuscated](https://www.sqlbi.com/blog/marco/2024/03/15/vpax-obfuscator-a-library-to-obfuscate-vpax-files/) (see below for more details on obfuscation). You must also choose which [contract](https://docs.daxoptimizer.com/glossary/contract) the model should be uploaded under. This impacts the number and frequency of DAX Optimizer [_runs_](https://docs.daxoptimizer.com/glossary/run) you can subsequently perform on the model. +- For a **new model version**, you must select the existing model to update. + +Once you click the **OK** button, the VPAX file will be uploaded to DAX Optimizer, and you will be able to start analyzing the model. + +> [!NOTE] +> If no VertiPaq Analyzer statistics are available in Tabular Editor 3, these statistics will be collected for the current model before the VPAX file is uploaded. We will also automatically re-collect statistics if the last statistics collection is older than or equal to the statistics of the last VPAX file upload, for the specific model. + +### Obfuscation + +By default, VPAX files uploaded using Tabular Editor 3 will be obfuscated. In the **Upload Model** you may toggle obfuscation on/off for new model uploads. Subsequent model version uploads will be obfuscated or not depending on the first version upload. You can also export an obfuscated VPAX file locally without uploading to DAX Optimizer through the **VertiPaq Analyzer** view. In this case, a dictionary file is generated and stored on your local machine, next to the exported .ovpax file. This dictionary file is used to deobfuscate the contents of the .ovpax file. + +When obfuscated VPAX data is uploaded to the DAX Optimizer service through the **DAX Optimizer** view, Tabular Editor automatically keeps track of obfuscation dictionaries by storing them in the `%LocalAppData%\TabularEditor3\DaxOptimizer` folder on your local machine. As such, when browsing models using the **DAX Optimizer** feature in Tabular Editor 3, models are automatically deobfuscated if a suitable dictionary is found in this folder, providing a more seemless experience when using obfuscation. + +If the dictionary is not found, you will have an option to manually specify a dictionary file. + +![Obfuscated Model](~/content/assets/images/obfuscated-model.png) + +If no dictionary file is provided, you will only be able to browse the obfuscated model and DAX Optimizer results, meaning you will not be able to view the original DAX expressions or navigate to the corresponding measures in the TOM Explorer. + +[Learn more about DAX Optimizer obfuscation](https://docs.daxoptimizer.com/how-to-guides/obfuscating-files). + +> [!TIP] +> If you want to browse an obfuscated model through the DAX Optimizer web interface, you can specify a dictionary from the `%LocalAppData%\TabularEditor3\DaxOptimizer` location. The DAX Optimizer web interface performs the deobfuscation on the client side, so your dictionary is never uploaded to the DAX Optimizer service. + +### Analyze a model + +Once a VPAX file has been uploaded, please allow a few seconds for the file to be "verified" by the DAX Optimizer service. Once verified, you can perform a DAX Optimizer "run" by checking the "You agree to **consume 1 run** to analyze this model." checkbox, and then clicking the **Analyze** button in the **DAX Optimizer** view: + +![Dax Optimizer Analyze](~/content/assets/images/dax-optimizer-analyze.png) + +The analysis will take a few minutes to complete, depending on the size of the model and the number of measures. Once the analysis is complete, you will be presented with a summary of the issues detected. + +## Known issues and limitations + +The following are known issues and limitations with the **DAX Optimizer** feature, which we expect to address in future releases: + +- The **DAX Optimizer** view does not display how many "runs" are left on any given contract. As a workaround, sign in to https://app.daxoptimizer.com and click the "lightning" icon in the top-right corner, to view how many "runs" you have left per contract. \ No newline at end of file diff --git a/content/localization/de/dax-query_de.md b/content/localization/de/dax-query_de.md new file mode 100644 index 00000000..c229d881 --- /dev/null +++ b/content/localization/de/dax-query_de.md @@ -0,0 +1,123 @@ +--- +uid: dax-query +title: DAX Queries +author: Morten Lønskov +updated: 2025-08-27 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX Queries + +Tabular Editor has a built-in DAX query window to write and execute DAX queries against the semantic model. + +A widespread use case for DAX queries is the DAX query produced by the [Power BI Performance Analyzer](https://www.sqlbi.com/articles/introducing-the-power-bi-performance-analyzer/), where it is possible to copy the query of each visual for troubleshooting, debugging, or detailed performance analysis. + +The window can be opened while connected to a semantic model using either the **File > New > DAX Query** menu or the toolbar shortcut. + +![Dax Query New](~/content/assets/images/features/dax_query_window/create_new_dax_query.png) + +The built-in context-aware DAX Editor ensures that only the two valid DAX keywords are available when starting a new query: DEFINE or EVALUATE (Press Ctrl+Space to verify for yourself) + +## DAX Query Options + +The DAX query window has five different query options. + +![Dax Query Toolbar](~/content/assets/images/features/dax_query_window/dax_query_toolbar.png) + +1. **Execute (F5)**: If there is a selection, it executes the selected DAX; otherwise, it executes the full query in the DAX Query editor. +2. **Execute full query**: It executes the full query in the DAX Query editor +3. **Execute Selection (Shift+F5)**: If there is a selection, it executes it. Otherwise, it executes the EVALUATE statement where the cursor is currently located. +4. **Stop**: This button cancels the current query execution. +5. **Auto Execute Query**: It allows for keeping track of the connected semantic model and updating the query results whenever something changes in the model. This can be useful for understanding e.g. how the result of a measure changes if modified. +6. **Keep sorting and filtering**: It allows users to control how sorting and filtering are preserved in the result grid(s) when executing queries. There are three preferences available: + - **Never**: Sorting and filtering reset each time the query runs. + - **When query is modified**: Sorting and filtering reset only when the query structure changes. + - **Always**: Sorting and filtering persist as long as columns remain in the new query. + +The default values of "Auto Execute Query" and "Keep Sorting and Filtering" preferences can be set up in the Preferences dialog: **Tools > Preferences... > Data browsing > DAX Query** > Basic. + +### Adding or Updating Measures, Columns and Tables with DAX Queries + +Tabular Editor (3.12.0 and higher) has the ability to add or change measures directly through the DAX Query window. + +From Tabular Editor 3.23.0, Apply and Apply selection also process DEFINE COLUMN and DEFINE TABLE statements. Tabular Editor will create the corresponding calculated columns/tables in your model, or update their expressions if they already exist. + +There are four options for applying DAX Query defined measures, columns and tables to the model: + +![Dax Query Apply Measure](~/content/assets/images/features/dax_query_window/dax_query_apply_measure.png) + +The "Apply" option syncs the DAX expression for all measures, columns or tables explicitly defined in the query to the definition of the object. Any measures, columns or tables that do not already exist are created. + +"Apply Measures & Sync" applies the DAX expression to the definition of the measures, columns or tables and saves the model. + +The "Apply Selection" and "Apply Selection & Sync" will only apply the measures, columns or tables within the current selection of the query editor. + +Unlike the [DAX Script feature](xrefid:dax-scripts), only the expression property of a measure can be updated this way, as the DAX query syntax does not support specifying other properties, such as Description, Display Folder, etc. + +The "Apply" option has also been added to the right-click context menu. + +![Dax Query Apple Right Click](~/content/assets/images/features/dax_query_window/dax_query_apply_measure_right_click.png) + +The shortcuts for these commands are: + +- Apply (F7) +- Apply Measures & Sync (Shift+F7) +- Apply Selection (F8) +- Apply Selection and Synch (Shift F7) + +## DAX Query Example + +A DAX query always returns a table of results, and the simplest form of DAX query to create is one that evaluates a table within the model. + +```DAX +EVALUATE +Products +``` + +![Dax Query Evaluate Table](~/content/assets/images/features/dax_query_window/evaluate_table.png) + +It is also possible to return the value of a measure, but a table constructor {} is required around the measure name to turn the scalar value into a 1x1 table. + +```DAX +EVALUATE +{ [Invoice Lines] } +``` + +![Dax Query Evaluate Measure](~/content/assets/images/features/dax_query_window/evaluate_measure.png) + +### Multiple EVALUATE statements + +It is perfectly possible to have multiple EVALUATE statements inside the same DAX query. This query type is most often encountered with Power BI Performance Analyzer queries. + +Both tables are returned in the below statement but as separate row tabs in the result pane. + +```DAX +EVALUATE +Products + +EVALUATE +Customers +``` + +![Dax Query Evaluate Multiple Tables](~/content/assets/images/features/dax_query_window/multiple_evaluate_table.png) + +## Debugging DAX Query + +DAX queries are one of the two places where it is possible to run the [DAX Debugger](xrefid:dax-debugger), the other being the Pivot Grid. + +The DAX debugger unlocks the ability to understand how the DAX works inside a single cell. To start the debugger simply right click on the desired cell and choose 'Debug cell', which will start the debugger in the context of the chosen cell. + +![Dax Query Debugger](~/content/assets/images/features/dax_query_window/dax_query_open_dax_debugger.gif) + +## Export DAX Query results + +Tabular Editor 3, beginning from version 3.16.0, introduces the new capability of exporting the results of a DAX Query to either CSV or Excel. After running the DAX Query, a button activates in the toolbar, enabling users to save the results locally in CSV or Excel format. + +> [!TIP] +> To Export more than 1001 rows choose "click to get all rows" after running the DAX Query + +![Dax Query Export Data](~/content/assets/images/features/dax_query_window/dax_query_export_data.png) diff --git a/content/localization/de/dax-script-introduction_de.md b/content/localization/de/dax-script-introduction_de.md new file mode 100644 index 00000000..2ec06bdb --- /dev/null +++ b/content/localization/de/dax-script-introduction_de.md @@ -0,0 +1,210 @@ +--- +uid: dax-script-introduction +title: Using the DAX Scripting feature +author: Daniel Otykier +updated: 2021-10-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Using the DAX Scripting feature + +In the [previous article](xref:creating-and-testing-dax), you learned how to add and edit calculated objects such as measures, calculated columns, etc. in your model. + +As your model grows in complexity, you may reach a point in which it starts to become cumbersome to navigate the TOM Explorer or jump back and forth between measures, when authoring and maintaining business logic. It is not uncommon to have long chains of dependencies between measures, and so for that reason, it is sometimes useful to collect all the DAX code making up the business logic, in a single document. + +This is exactly the purpose of the new **DAX script** feature introduced in Tabular Editor 3. + +To use this feature, locate the objects for which you would like to generate a single document, in the TOM Explorer. Multi-select the objects, then right-click and choose **Script DAX**. A new document is created, containing the DAX expressions and basic properties of all the selected objects. You can also generate a DAX script for all objects within a table or all objects within the model, by choosing the table or model object respectively. + +![Dax Script](~/content/assets/images/dax-script.png) + +Editing objects through a DAX script is slightly different than editing through the **Expression Editor**. With the latter, changes are applied immediately when you navigate to a different object. In a DAX script, however, changes are not applied until you explicitly do so by using the **Script > Apply** (F5) option. If you are connected to an instance of Analysis Services, you can use the **Script > Apply & Sync** (SHIFT+F5) option to simultaneously apply the changes and save the updated model metadata to Analysis Services. + +## Working with DAX script files + +DAX scripts can be saved as text files, using the `.te3daxs` file extension. To save a DAX script as a file, simply use the **File > Save** (Ctrl+S) option. To open a DAX script from a text file, use the **File > Open > File...** (Ctrl+O) option. + +> [!NOTE] +> DAX scripts are not model specific, but since DAX expressions may point to measures, columns and tables defined in the model, there are no guarantees that any DAX script can be applied to any model. DAX scripts are mostly useful for working with several DAX objects within a single document, in the context of a specific data model. + +## DAX script editor + +The DAX script editor has all the capabilities of the DAX editor used elsewhere in Tabular Editor 3. Specifically, auto-complete, auto-formatting, calltips, etc. + +In addition, to easily manage large DAX scripts, two dropdowns are displayed at the top of the DAX script view. The dropdown on the left allows you to jump between objects defined in the script, where as the dropdown on the right allows you to jump between properties on the current object. + +![Dax Script Navigation](~/content/assets/images/dax-script-navigation.png) + +## Define measures + +If you want to include the definition of a measure that is referenced in the script, but not already defined in the script, you can do so by right-clicking on a measure reference, and choose the "Define Measure" or "Define Measure with dependencies" option. + +![Define Measure With Deps](~/content/assets/images/define-measure-with-deps.png) + +## Shortcuts + +To apply the script to the model, use the following shortcuts: + +- **F5**: Apply the entire script to the local model metadata +- **Shift+F5**: Apply the entire script to the local model metadata, then save the model metadata back to the source +- **F8**: Apply the currently selected part of the script to the local model metadata +- **Shift+F8**: Apply the currently selected part of the script to the local model metadata, then save the model metadata back to the source + +## DAX objects supported + +Tabular Editor 3 supports editing the following types of objects using a DAX script: + +- Measures (including KPIs) +- Calculated columns +- Calculated tables +- Calculation groups (including calculation items) + +# DAX script syntax + +The syntax for DAX scripts is the following: + +```dax +: +MEASURE 'Table name'[Measure name] = + [] + +COLUMN 'Table name'[Column name] = + [] + +TABLE 'Table name' = + [
    ] + +CALCULATIONGROUP 'Table name'[Column name] + [] + CALCULATIONITEM "Item 1" = + [] + CALCULATIONITEM "Item 2" = + [] + ... + +: + DetailRows = + DisplayFolder = "string" + FormatString = "string" + Description = "string" + Visible = TRUE/FALSE + KpiStatusExpression = + KpiStatusDescription = "string" + KpiStatusGraphic = "string" + KpiTrendExpression = + KpiTrendDescription = "string" + KpiTrendGraphic = "string" + KpiTargetExpression = + KpiTargetDescription = "string" + KpiTargetFormatString = "string" + +: + DisplayFolder = "string" + FormatString = "string" + Description = "string" + Visible = TRUE / FALSE + Datatype = BOOLEAN / DOUBLE / INTEGER / DATETIME / CURRENCY / STRING + +
    : + Description = "string" + Visible = TRUE / FALSE + DetailRows = + +: + Description = "string" + Visible = TRUE / FALSE + Precedence = + + + Description = "string" + Ordinal = + FormatString = +``` + +## Example 1: Measure + +As an example, the script below defines the `[Internet Total Sales]` measure on the `'Internet Sales'` table. In addition to the DAX expression of the measure, the script also includes the measure description and format string. + +```dax +---------------------------------- +-- Measure: [Internet Total Sales] +---------------------------------- +MEASURE 'Internet Sales'[Internet Total Sales] = SUM('Internet Sales'[Sales Amount]) + Description = "Returns the sum of all Internet Sales" + FormatString = "\$#,0.00;(\$#,0.00);\$#,0.00" +``` + +## Example 2: Measure with status and target KPI + +The DAX script below defines the `[Internet Current Quarter Sales Performance]` measure, which includes a KPI that has a status and a target expression. The status KPI uses the "Shapes" graphic. + +```dax +-------------------------------------------------------- +-- Measure: [Internet Current Quarter Sales Performance] +-------------------------------------------------------- +MEASURE 'Internet Sales'[Internet Current Quarter Sales Performance] = + IFERROR( + [Internet Current Quarter Sales] / [Internet Previous Quarter Sales Proportion to QTD], + BLANK() + ) + , KpiStatusExpression = + VAR x = [Internet Current Quarter Sales Performance] + RETURN + IF( + ISBLANK( x ), + BLANK(), + IF(x < 1, -1, IF(x < 1.07, 0, 1)) + ) + , KpiStatusGraphic = "Shapes" + , KpiTargetExpression = 1.1 +``` + +## Example 3: Calculation group + +The DAX script below defines the `'Time Intelligence'` calculation group with the `[Period]` column. The calculation group contains 6 calculation items that performs various time calculations. Notice how the `"YoY %"` item applies a different format string. + +```dax +----------------------------------------- +-- Calculation Group: 'Time Intelligence' +----------------------------------------- +CALCULATIONGROUP 'Time Intelligence'[Period] + Description = "Use this table to perform time calculations" + + CALCULATIONITEM "Current" = SELECTEDMEASURE() + Ordinal = 0 + + CALCULATIONITEM "MTD" = TOTALMTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 1 + + CALCULATIONITEM "YTD" = TOTALYTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 2 + + CALCULATIONITEM "PY" = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 3 + + CALCULATIONITEM "YoY" = + SELECTEDMEASURE() + - CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 4 + + CALCULATIONITEM "YoY %" = + VAR lastYear = + CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + RETURN + DIVIDE( + SELECTEDMEASURE() - lastYear, + lastYear + ) + FormatString = "Percent" + Ordinal = 5 +``` + +# Next steps + +- @bpa +- @cs-scripts-and-macros +- @personalizing-te3 \ No newline at end of file diff --git a/content/localization/de/dax-scripts_de.md b/content/localization/de/dax-scripts_de.md new file mode 100644 index 00000000..38f6ccbe --- /dev/null +++ b/content/localization/de/dax-scripts_de.md @@ -0,0 +1,237 @@ +--- +uid: dax-scripts +title: DAX Scripts +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX Scripts + +**DAX Script** allow you to view and edit DAX expressions and basic properties for multiple objects, in a single document. This is useful, for example, when complex business logic is spread out across multiple measures. + +You can script the DAX code for any TOM explorer object that has DAX expressions. + +To use this feature, locate the objects for which you would like to generate a single document, in the TOM Explorer. Multi-select the objects, then right-click and choose **Script DAX**. A new document is created, containing the DAX expressions and basic properties of all the selected objects. You can also generate a DAX script for all objects within a table or all objects within the model, by choosing the table or model object respectively. + +![Dax Script](~/content/assets/images/dax-script.png) + +Editing objects through a DAX script is slightly different than editing through the **Expression Editor**. With the latter, changes are applied immediately when you navigate to a different object. In a DAX script, however, changes are not applied until you explicitly do so by using the **Script > Apply** (F5) option. If you are connected to an instance of Analysis Services, you can use the **Script > Apply & Sync** (SHIFT+F5) option to simultaneously apply the changes and save the updated model metadata to Analysis Services. + +You can undo/redo changes made by a DAX script using the usual keyboard shortcuts (Ctrl+Z / Ctrl+Y). + +## Multiple DAX scripts + +You can create as many DAX scripts as you want, if you prefer to have multiple document windows open instead of a single one. This way, you can use the usual IDE features to place the documents side by side, on different monitors, etc. Be aware, that the code within DAX script windows is not updated automatically when changes are made to the object expression/properties in the TOM. So in other words, if you have two or more DAX scripts containing the definition of the same object(s), then the last script to be applied (F5), will always override any changes made through other DAX scripts, or directly through the **Properties View**. + +## Working with DAX script files + +DAX scripts can be saved as text files, using the `.te3daxs` file extension. To save a DAX script as a file, simply use the **File > Save** (Ctrl+S) option. To open a DAX script from a text file, use the **File > Open > File...** (Ctrl+O) option. + +> [!NOTE] +> DAX scripts are not model specific, but since DAX expressions may point to measures, columns and tables defined in the model, there are no guarantees that any DAX script can be applied to any model. DAX scripts are mostly useful for working with several DAX objects within a single document, in the context of a specific data model. + +## DAX script editor + +The DAX script editor has all the capabilities of the DAX editor used elsewhere in Tabular Editor 3. Specifically, auto-complete, auto-formatting, calltips, etc. + +In addition, to easily manage large DAX scripts, two dropdowns are displayed at the top of the DAX script view. The dropdown on the left allows you to jump between objects defined in the script, where as the dropdown on the right allows you to jump between properties on the current object. + +![Dax Script Navigation](~/content/assets/images/dax-script-navigation.png) + +## Define measures + +If you want to include the definition of a measure that is referenced in the script, but not already defined in the script, you can do so by right-clicking on a measure reference, and choose the "Define Measure" or "Define Measure with dependencies" option. + +![Define Measure With Deps](~/content/assets/images/define-measure-with-deps.png) + +## Shortcuts + +To apply the script to the model, use the following shortcuts: + +- **F5**: Apply the entire script to the local model metadata +- **Shift+F5**: Apply the entire script to the local model metadata, then save the model metadata back to the source +- **F8**: Apply the currently selected part of the script to the local model metadata +- **Shift+F8**: Apply the currently selected part of the script to the local model metadata, then save the model metadata back to the source + +## DAX objects supported + +Tabular Editor 3 supports editing the following types of objects using a DAX script: + +- Measures (including KPIs) +- Calculated columns +- Calculated tables +- Calculation groups (including calculation items) + +# DAX script syntax + +The syntax for DAX scripts is the following: + +```dax +: +MEASURE 'Table name'[Measure name] [= []] + [] + +COLUMN 'Table name'[Column name] [= []] + [] + +TABLE 'Table name' [= []] + [
    ] + +CALCULATIONGROUP 'Table name'[Column name] + [] + CALCULATIONITEM "Item 1" [= []] + [] + CALCULATIONITEM "Item 2" [= []] + [] + ... + +: + DetailRows = [] + DisplayFolder = ["string"] + FormatString = ["string" / ] + Description = ["string"] + Visible = TRUE/FALSE + KpiStatusExpression = [] + KpiStatusDescription = ["string"] + KpiStatusGraphic = ["string"] + KpiTrendExpression = [] + KpiTrendDescription = ["string"] + KpiTrendGraphic = ["string"] + KpiTargetExpression = [] + KpiTargetDescription = ["string"] + KpiTargetFormatString = ["string"] + +: + DisplayFolder = ["string"] + FormatString = ["string"] + Description = ["string"] + Visible = TRUE / FALSE + Datatype = BOOLEAN / DOUBLE / INTEGER / DATETIME / CURRENCY / STRING + +
    : + Description = ["string"] + Visible = TRUE / FALSE + DetailRows = [] + +: + Description = ["string"] + Visible = TRUE / FALSE + Precedence = + + + Description = ["string"] + Ordinal = + FormatString = [] +``` + +> [!TIP] +> Users of TMDL will undoubtedly have noticed that some similarities exist between the syntax of DAX scripts and the syntax of TMDL. In fact, TMDL was inspired by DAX scripts. However, to keep things simple, DAX scripts intentionally supports only objects that have one or more DAX expressions associated with them. Moreover, the DAX script syntax is designed to be compatible with the `DEFINE` section of a DAX query (provided the DAX script does not specify any object properties). TMDL, on the other hand, is used to define the entire model metadata, and is not limited to DAX objects. However, blocks of TMDL code cannot be readily used in a DAX query as the syntax for defining object names in TMDL, is not valid in DAX. + +## Example 1: Measure + +As an example, the script below defines the `[Internet Total Sales]` measure on the `'Internet Sales'` table. In addition to the DAX expression of the measure, the script also includes the measure description and format string. + +```dax +---------------------------------- +-- Measure: [Internet Total Sales] +---------------------------------- +MEASURE 'Internet Sales'[Internet Total Sales] = SUM('Internet Sales'[Sales Amount]) + Description = "Returns the sum of all Internet Sales" + FormatString = "\$#,0.00;(\$#,0.00);\$#,0.00" +``` + +## Example 2: Measure with status and target KPI + +The DAX script below defines the `[Internet Current Quarter Sales Performance]` measure, which includes a KPI that has a status and a target expression. The status KPI uses the "Shapes" graphic. + +```dax +-------------------------------------------------------- +-- Measure: [Internet Current Quarter Sales Performance] +-------------------------------------------------------- +MEASURE 'Internet Sales'[Internet Current Quarter Sales Performance] = + IFERROR( + [Internet Current Quarter Sales] / [Internet Previous Quarter Sales Proportion to QTD], + BLANK() + ) + , KpiStatusExpression = + VAR x = [Internet Current Quarter Sales Performance] + RETURN + IF( + ISBLANK( x ), + BLANK(), + IF(x < 1, -1, IF(x < 1.07, 0, 1)) + ) + , KpiStatusGraphic = "Shapes" + , KpiTargetExpression = 1.1 +``` + +## Example 3: Calculation group + +The DAX script below defines the `'Time Intelligence'` calculation group with the `[Period]` column. The calculation group contains 6 calculation items that performs various time calculations. Notice how the `"YoY %"` item applies a different format string. + +```dax +----------------------------------------- +-- Calculation Group: 'Time Intelligence' +----------------------------------------- +CALCULATIONGROUP 'Time Intelligence'[Period] + Description = "Use this table to perform time calculations" + + CALCULATIONITEM "Current" = SELECTEDMEASURE() + Ordinal = 0 + + CALCULATIONITEM "MTD" = TOTALMTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 1 + + CALCULATIONITEM "YTD" = TOTALYTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 2 + + CALCULATIONITEM "PY" = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 3 + + CALCULATIONITEM "YoY" = + SELECTEDMEASURE() + - CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 4 + + CALCULATIONITEM "YoY %" = + VAR lastYear = + CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + RETURN + DIVIDE( + SELECTEDMEASURE() - lastYear, + lastYear + ) + FormatString = "Percent" + Ordinal = 5 +``` + +# Unspecified or empty expressions / properties + +As of Tabular Editor 3.16.0, it is possible to specify empty expressions and property values in DAX scripts, or omit object expressions entirely. + +For example, the following script will create a measure with an empty DAX expression, an empty format string and no Display Folder. If the measure already exists, it will be updated to have an empty DAX expression, an empty format string and no Display Folder. + +```dax +MEASURE 'Internet Sales'[Internet Total Sales] = + , Description = "TODO: Ask business how this should be implemented and formatted." + , FormatString = + , DisplayFolder = +``` + +Note that the `,` (comma) before properties following an empty expression is mandatory. Commas are optional when the preceding expression is non-empty. + +If you want to keep the existing DAX expression on a measure, you can omit the `=` sign after the object name: + +```dax +MEASURE 'Internet Sales'[Internet Total Sales] + DisplayFolder = "Totals" +``` + +The example above will update the `[Internet Total Sales]` measure to have the specified `DisplayFolder`, but will keep the existing DAX expression. All other properties on the object, such as `Description` and `FormatString`, will remain unchanged. + +These new features make it easier to write scripts that only update specific properties of an object, without having to specify the entire object definition. This way, scripts can more easily be reused across different models. diff --git a/content/localization/de/deployment_de.md b/content/localization/de/deployment_de.md new file mode 100644 index 00000000..56b10992 --- /dev/null +++ b/content/localization/de/deployment_de.md @@ -0,0 +1,69 @@ +--- +uid: deployment +title: Model deployment +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Model deployment + +Tabular Editor 3 (Business and Enterprise Edition) can take a copy of the currently loaded semantic model metadata, and deploy it to an Analysis Services instance, or the Power BI / Fabric XMLA endpoint. + +To perform a deployment, launch the **Deployment Wizard** through the **Model > Deploy...** menu option. + +> [NOTE] +> Tabular Editor 3 Business Edition has certain [limitations](xref:editions) regarding what type of Analysis Services instance, or Power BI / Fabric workspace is supported for XMLA connectivity. This applies to deployment as well. + +## Deployment options + +After selecting the destination server and database to deploy, you are presented with a list of **Deployment options**, as shown in the screenshot below. + +![Deployment Options](images/deployment-options.png) + +These are: + +- **Deploy Model Structure**: This indicates that the model metadata will be deployed. Unchecking this prevents you from performing the deployment (the option exists for historic reasons). +- **Deploy Data Sources**: For models that use _explicit_ data sources, this option indicates whether any such data sources will be included in the deployment. Unchecking this option may be useful, if one or more properties on a data source has been modified, and you do not intend to deploy these modifications. For example, if you are deploying model metadata from a Development environment to a Test environment, you may want to retain any connection strings, etc. on the destination environment as-is. Note that this option is typically not enabled for Power BI / Fabric semantic models, because such models use _implicit_ data sources, where credentials are managed by the Power BI service, and connection details are stored in the M queries on partitions or shared expressions in the model. +- **Deploy Table Partitions**: This option indicates whether table partitions should be deployed. In some cases, the destination database may contain partitions that are not present in the model metadata. Unchecking this option will prevent the deployment from modifying any existing partitions on the destination server. If this option is checked, Tabular Editor will synchronize the partitions on the destination server with the model metadata. If any partitions are present on the destination server, but not in the model metadata, they will be removed (including the data contained in them). + - **Deploy partitions governed by Incremental Refresh Policies**: When the **Deploy Table Partitions** option is enabled, you will have an option to avoid deploying partitions that are governed by Incremental Refresh Policies. This is useful when you have a model with partitions that created automatically by the [Incremental Refresh Policy](xref:incremental-refresh-about), and you want to deploy all partitions except those governed by the policy. +- **Deploy Model Roles**: This option indicates whether roles defined in the model should be deployed. Unchecking this option will retain existing roles on the model as-is. If you are deploying changes to tables or columns in the model, you may have to revisit [RLS or OLS settings](xref:data-security-about), to ensure that they are still valid. + - **Deploy Model Role Members**: This option indicates whether role members should be deployed. It is common to manage role members directly on the server, rather than in the model metadata. Unchecking this option will prevent the deployment from modifying any existing role members on the destination server. + +## Deployment script + +During deployment, Tabular Editor generates a [CreateOrReplace TMSL script](https://learn.microsoft.com/en-us/analysis-services/tmsl/createorreplace-command-tmsl?view=asallproducts-allversions), which is then executed against the Analysis Services engine. The CreateOrReplace script contains all the metadata required to recreate the model, including tables, columns, measures, relationships, perspectives, translations, etc. If the model does not already exist on the target server, it will be created. If the model already exists, existing objects will be replaced with the new metadata specified in the script. + +If any of the options on the **Deployment options** page were deselected, Tabular Editor will use the original metadata definition of those objects in the generated TMSL script, thus retaining their definitions as-is on the server. + +The last page of the deployment wizard lets you export the generated script, so you can review the changes before executing them. + +## Deployment impact + +> [WARNING] +> This type of deployment is a **metadata-only deployment**. Depending on the types of changes made to the model, imported data could be lost during deployment. In this case, you may need to execute a refresh operation once the deployment is complete. + +As a rule of thumb, the following changes can be made to the model without requiring a subsequent data refresh: + +- Adding/editing/removing measures and KPIs, including their DAX expressions. +- Editing properties such as FormatString, Description, DisplayFolder, etc. +- Adding/editing/removing metadata translations, perspectives, OLS and RLS roles. + +The following changes may require a **Calculate refresh**, before the objects can be queried: + +- Adding/editing calculated column, calculated tables and calculation groups +- Adding/editing relationships +- Adding/editing hierarchies +- Removing columns/tables + +The following changes may require a **Full refresh**: + +- Adding/editing partitions, tables and columns + +> [WARNING] +> Because of the potential impact of deploying a semantic model this way, we recommend not using this option to perform a deployment against a production environment. It is better to set up a [CI/CD pipeline for deploying models to production environments](https://blog.tabulareditor.com/category/ci-cd/). diff --git a/content/localization/de/desktop-limitations_de.md b/content/localization/de/desktop-limitations_de.md new file mode 100644 index 00000000..9569dfbf --- /dev/null +++ b/content/localization/de/desktop-limitations_de.md @@ -0,0 +1,17 @@ +--- +uid: desktop-limitations-te3 +title: Power BI Desktop limitations +author: Morten Lønskov +updated: 2023-08-21 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +[!include[Desktop limitations](~/content/common/desktop-limitations.md)] + +# Next steps + +- [Editing a Power BI dataset through the XMLA endpoint](xref:powerbi-xmla) diff --git a/content/localization/de/diagram-view_de.md b/content/localization/de/diagram-view_de.md new file mode 100644 index 00000000..0f0c9288 --- /dev/null +++ b/content/localization/de/diagram-view_de.md @@ -0,0 +1,109 @@ +--- +uid: diagram-view +title: Diagram View +author: Morten Lønskov +updated: 2025-04-24 +--- + +# Diagram View + +The **Diagram View** in Tabular Editor 3 is a visual representation of the semantic model. It provides an intuitive layout for viewing tables, their columns, and the relationships between them. It is particularly helpful for understanding the schema at a glance, creating relationships, and presenting models to stakeholders. A diagram can be saved as a stand alone file. See for more information. + +> [!NOTE] +> We recommend creating multiple smaller diagrams over few large diagrams. When a diagram contains more than 20 or so tables, it quickly becomes overwhelming and difficult to understand. + +After loading a model in Tabular Editor 3, choose the **File > New > Diagram** menu option to create a new diagram or open a new diagram in the main toolbar and drag and drop a table from the TOM Explorer to the diagram window. + +## Using the diagram view + +## Adding tables + +Add initial tables to the diagram in any of the following ways: + +- (Multi-)select tables in the TOM Explorer, then right-click and choose **Add to diagram**. +- (Multi-)select tables in the TOM Explorer, then drag the tables over to the diagram +- Use the **Diagram > Add tables...** menu option, and (multi-)select the tables you want to add through the dialog box. + ![Diagram Add Tables](~/content/assets/images/diagram-add-tables.png) + + To add additional tables to the diagram, use the technique above again, or right-click on an existing table in the diagram and choose one of the following options: + + - **Add tables that filter this table**: Adds all tables to the diagram which may, directly or indirectly through other tables, filter the currently selected table. Useful when starting from a fact table. + - **Add all related tables**: Adds all tables to the diagram which are directly related to the currently selected table. Useful when starting from a dimension table. + ![Add Related Tables](~/content/assets/images/add-related-tables.png) + + Before proceeding, rearrange and resize the tables in the diagram to suit your preferences, or use the **Diagram > Auto-arrange** feature to have Tabular Editor 3 lay out the tables automatically. + +## Modifying relationships using the diagram + +To add a new relationship between two tables, locate the column on the fact table (many-side) of the relationship, and drag that column over to the corresponding column on the dimension table (one-side). Confirm the settings for the relationship and hit **OK**. + +![Create Relationship](~/content/assets/images/create-relationship.png) + +To edit an existing relationship, right-click on it and choose **Edit relationship**. The right-click menu also contains shortcuts for reversing or deleting a relationship, as shown on the screenshot below. + +![Edit Relationship Diagram](~/content/assets/images/edit-relationship-diagram.png) + +> [!NOTE] +> You can also create relationships without using a diagram, through the TOM Explorer. Locate the column from which the relationship should start (many-side / fact-table side), right-click and choose **Create > Relationship from**. Specify the destination column in the Create Relationship dialog that appears on the screen. + +## Saving a diagram + +To save a diagram, simply use the **File > Save** (CTRL+S) option. Tabular Editor 3 will prompt you to save the diagram if you close the document or the application while the diagram has unsaved changes. + +> [!TIP] +> The same diagram file can be loaded for different data models. Diagrams reference tables by their names. Any tables not present in the model upon diagram load are simply removed from the diagram. + +> [!NOTE] +> Every time you add or modify a relationship, you will have to run a "calculate" refresh on the data model, before the relationships can be used when querying the model. + +## Diagram Features + +### Context Menu for Table Actions + +Right-clicking anywhere in the Diagram View opens a context menu that provides quick access to several options: + +![Diagram Context Menu](~/content/assets/images/diagram-context-menu.png) + +- **Add tables...**: Opens a dialog to manually add additional tables to the diagram. +- **Add tables that filter this table**: Automatically brings in related tables that filter the current one. +- **Add all related tables**: Loads all tables that share relationships with the selected table. +- **Fit to page**: Adjusts the diagram zoom to fit all visible tables. +- **Auto-Arrange**: Automatically arrange tables into a star schema +- **Remove from diagram**: Hides the selected table from the current view. + +### Relationship Indicators + +Relationships between tables are illustrated using directional arrows: + +- `1 - *`: Indicates a one-to-many relationship. +- `* - *`: Indicates a many-to-many relationship. +- `➝`: Indicates a single direction relationship, with the arrow defining the filter direction of the relationship. +- `⟷`: Indicates a bi-directional cross-filtering relationship. + +These visual markers allow for quick assessment of filter directionality and cardinality. + +### Column Display Toggle + +A **chevron toggle** is available in the top-right corner of each table, by clicking it you will toggle between the following options: + +![Diagram Chevron Toggle](~/content/assets/images/diagram-chevron-toggle.png) + +- **All Columns**: Displays all columns. +- **Key Columns Only**: Displays only primary and foreign keys. +- **No Columns**: Hides all columns, showing only the table header. + +The toggle helps reduce clutter, especially in complex models with many columns, making it easier to focus on relationships. + +### Column Data Type Icons + +Each column in the diagram is accompanied by an icon representing its data type: + +- Text Icon for string/text values +- Integer Icon for integer numbers +- Double Icon for double / floating-point decimal numbers +- Currency Icon for currency / fixed-point decimal numbers +- Binary Icon for binary values +- Boolean Icon for boolean (true/false) values +- Date Icon for date/time values + +This quick visual reference supports quick data validation and helps understand the data structures. \ No newline at end of file diff --git a/content/localization/de/direct-lake-guidance_de.md b/content/localization/de/direct-lake-guidance_de.md new file mode 100644 index 00000000..0e3c9a80 --- /dev/null +++ b/content/localization/de/direct-lake-guidance_de.md @@ -0,0 +1,191 @@ +--- +uid: direct-lake-guidance +title: Direct Lake Guidance +author: Daniel Otykier +updated: 2024-06-18 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + none: x + - edition: Enterprise +--- + +# Direct Lake Guidance + +With the release of Tabular Editor 3.22.0, we have added support for Direct Lake on OneLake in addition to Direct Lake on SQL. This article provides a short overview of the differences between these two modes, and how they compare to other storage modes available in Power BI semantic models. + +## Storage mode overview + +The following table summarizes the storage modes available in Power BI semantic models: + +| Storage Mode | Description | Recommended Use Cases | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Import | Data is imported into the semantic model and stored in the model's in-memory cache (VertiPaq). | When you need fast query performance and can afford to refresh the data periodically. | +| DirectQuery | Data is queried directly from the source at query time, without being imported into the model. Supports various sources, such as SQL, KQL and even other semantic models. | When you need real-time data access or when the data volume is too large to fit in memory. | +| Dual | A hybrid mode where the engine can choose between returning the imported data or delegating to DirectQuery, depending on the query context. | When your model contains a mix of DirectQuery and Import tables (for example when using aggregations), and you have tables that are related to both. | +| Direct Lake on OneLake | Utilizes the Delta Parquet story format to quickly swap the data into semantic model memory when needed. | When your data is already available as tables or materialized views in a Fabric Warehouse or Lakehouse. | +| Direct Lake on SQL | Older version of Direct Lake which utilizes the SQL Analytics Endpoint of Fabric Warehouses or Lakehouses. | Not recommended for new development (use Direct Lake on OneLake instead). | + +> [!NOTE] +> It is also possible to create tables that contain a mix of partitions in **Import** and **DirectQuery** mode (also known as "hybrid tables"). This is commonly done on large fact tables that require incremental refresh while some data is queried directly from the source. See [this article](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla) for more information. + +## Direct Lake on OneLake vs. Direct Lake on SQL + +[Direct Lake on OneLake](https://learn.microsoft.com/en-us/fabric/fundamentals/direct-lake-overview#key-concepts-and-terminology) was introduced in March 2025 as an alternative to Direct Lake on SQL. With Direct Lake on OneLake, there is no dependency on the SQL endpoint and no fallback to DirectQuery mode. This also means that the [usual restrictions that apply to DirectQuery models](https://learn.microsoft.com/en-us/power-bi/connect-data/desktop-directquery-about#modeling-limitations) do not apply to Direct Lake on OneLake models. + +However, as with Direct Lake on SQL, there are still some [limitations that _do_ apply](https://learn.microsoft.com/en-us/fabric/fundamentals/direct-lake-overview#considerations-and-limitations). The most important limitations are listed below. See the link for a full list of limitations: + +- Calculated columns on Direct Lake tables cannot reference columns that are sourced from OneLake. +- Calculated tables on Direct Lake models cannot refer columns on Direct Lake tables that are sourced from OneLake. + +One possible workaround for the above limitation, is to create a **composite model** by combining Direct Lake tables with Import tables. This is allowed with Direct Lake on OneLake, but not with Direct Lake on SQL. In this case, you would typically use Import mode for smaller dimension tables, where you may need to add custom groupings, which calculated columns are ideal for, while keeping the larger fact tables in Direct Lake mode. + +Alternatively, ensure that your source contains the columns it needs. If you add columns through a view, please note that the view must be materialized in the Fabric Warehouse or Lakehouse, as Direct Lake on OneLake does not support non-materialized views. + +## Collation + +When using **Direct Lake on OneLake**, the collation of the model is the same as for an Import model, which is case-insensitive by default. + +For a **Direct Lake on SQL** model, the collation is case-insensitive for queries that do not fallback to DirectQuery. If the query does fallback, the collation depends on the collation of the source. For a Fabric Warehouse, the collation might be case-sensitive, in which case you should specify a [case-sensitive collation on the model](https://data-goblins.com/power-bi/case-specific). + +> [!NOTE] +> You cannot change the collation of a model once the metadata has been deployed to Analysis Services / Power BI. As such, if you plan to use Direct Lake on SQL with a case-sensitive Fabric Warehouse, you must set the collation on the model metadata before it's deployed: +> +> 1. Create a new model in Tabular Editor 3 (File > New > Model...) +> 2. Uncheck "Use workspace database" +> 3. Set the **Collation** property on the model to `Latin1_General_100_BIN2_UTF8` +> 4. Save the model (Ctrl+S). +> 5. Now, open the model from the file you just saved. When prompted to connect to a workspace database, choose "Yes". +> +> With this approach, the model metadata gets deployed with the correct collation from the start, and you can then add tables in Direct Lake on SQL mode without running into collation issues. + +## Table Import Wizard + +To add Direct Lake tables using Tabular Editor 3's Table Import Wizard, choose **Microsoft Fabric Lakehouse**, **Microsoft Fabric Warehouse**, **Microsoft Fabric SQL Database** or **Microsoft Fabric Mirrored Database** as the source: + +![Import Table Wizard Fabric](../../assets/images/import-table-wizard-fabric.png) + +After signing in, you will be presented with a list of all available Fabric Lakehouses/Warehouses in workspaces you have access to. Select the one you want to connect to and hit **OK**: + +![Import Table Wizard Select Lakehouse](../../assets/images/import-table-wizard-select-lakehouse.png) + +Unless you want to specify a custom SQL query, or configure the tables for DirectQuery mode, simply hit **Next** to select the tables from a list of tables/views in the source: + +![Import Table Wizard Select Vs Custom Query](../../assets/images/import-table-wizard-select-vs-custom-query.png) + +Select the tables/views you wish to import. Note that **non-materialized views** are not supported in Direct Lake on OneLake mode. Attempting to add such a view to the model will result in an error upon saving the model metadata. + +![Import Table Wizard Select Objects](../../assets/images/import-table-wizard-select-objects.png) + +On the last page, choose which mode you want the table partition to be configured with: + +![Table Import Wizard Partition Mode](../../assets/images/table-import-wizard-partition-mode.png) + +The choices are: + +- Direct Lake on OneLake +- Direct Lake on SQL +- Import (M) + +> [!NOTE] +> If you're working on a model that already contains tables, one or more of the choices mentioned above may not be available, if the model does not support combining tables in different storage modes. For example, if the model contains a table in Direct Lake on SQL mode, you cannot add tables in other modes. + +## Power Query (M) expressions + +This section contains a more technical description on how the TOM objects and properties need to be configured, in case you want to manually set up tables for Direct Lake mode without using the Table Import Wizard. + +### Direct Lake on OneLake + +To manually set up a table for **Direct Lake on OneLake** mode, you need to do the following: + +1. **Create Shared Expression**: Direct Lake tables use "Entity" partitions, which much reference a Shared Expression in the model. Start out by creating this shared expression, if you don't have it already. Name it `DatabaseQuery`: + +![Create Shared Expression](../../assets/images/create-shared-expression.png) + +2. **Configure Shared Expression**: Set the **Kind** property of the expression you created in step 1 to "M", and set the _Expression_\* property to the following M query, replacing the IDs in the URL for your Fabric workspace and Lakehouse/Warehouse: + +```m +let + Source = AzureStorage.DataLake("https://onelake.dfs.fabric.microsoft.com//", [HierarchicalNavigation=true]) +in + Source +``` + +3. **Create Table and Entity Partition**: Create a new table in the model (Alt+5), then expand the table partitions in the TOM Explorer, and create new _Entity Partition_: + +![Create Entity Partition](../../assets/images/create-entity-partition.png) + +Delete the regular import partition that was automatically created when you created the table. + +4. **Configure Entity Partition**: Set the following properties on the Entity Partition: + +| Property | Value | +| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Name | (Recommended) Set to the same name as the table | +| Entity Name | (Required) Set to the name of the table in the Lakehouse/Warehouse | +| Expression Source | (Required) Set to the Shared Expression you created in step 1, typically `DatabaseQuery` | +| Mode | (Required) `DirectLake` | +| Schema Name | (Optional) Set to the schema name in the Lakehouse/Warehouse, if applicable. If not set, the default schema will be used. | + +The final result should look like this: + +![Configure Entity Partition](../../assets/images/configure-entity-partition.png) + +5. **Update column metadata**: At this stage, you should be able to use Tabular Editor's **Update Table Schema** feature to update the column metadata for the table. This will automatically retrieve the column names and data types from the Lakehouse/Warehouse: + +![Update Table Schema Entity](../../assets/images/update-table-schema-entity.png) + +Alternatively, manually add Data Columns to the table (Alt+4) and specify the `Name`, `Data Type`, `Source Column` and any other relevant properties for each column. + +> [!NOTE] +> When a Direct Lake table is added to the model, it needs to be manually "refreshed" after the first metadata deployment. Otherwise, the table will not contain any data when queried. This refresh only needs to be performed once. Tabular Editor 3 will automatically refresh the table when the model metadata is saved, if the **Auto-refresh when saving new tables** under **Tools > Preferences > Model Deployment > Data Refresh**. + +### Direct Lake on SQL + +To manually set up a table for **Direct Lake on SQL** mode, follow the steps in the section above for Direct Lake on OneLake, but use the following M query in the Shared Expression instead: + +```m +let + database = Sql.Database("", "") +in + database +``` + +Replace `` with the connection string of the [SQL Analytics Endpoint of the Fabric Warehouse](https://learn.microsoft.com/en-us/fabric/data-warehouse/query-warehouse) or [Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-analytics-endpoint), and `` with the name of the Warehouse or Lakehouse. + +### Import from Lakehouse / Warehouse + +If you want to configure a table for **Import** mode while sourcing data from a Fabric Lakehouse or Warehouse, the steps are as follows: + +1. **Create table**: Create a new table in the model (Alt+5), then expand the table partitions in the TOM Explorer. By default, you should see a single partition of type "Import" created automatically: + +![M Import Partition](../../assets/images/m-import-partition.png) + +2. **Configure Import Partition**: Set the following M query on the Import Partition: + +```m +let + Source = Sql.Database("",""), + Data = Source{[Schema="",Item="
    "]}[Data] +in + Data +``` + +Replace `` with the connection string of the [SQL Analytics Endpoint of the Fabric Warehouse](https://learn.microsoft.com/en-us/fabric/data-warehouse/query-warehouse) or [Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-analytics-endpoint), and `` with the name of the Warehouse or Lakehouse. + +Replace `` with the schema name in the Warehouse/Lakehouse, and `
    ` with the name of the table or view you want to import. Note that tables in Import Mode can use non-materialized views as the data source, since the data is queried through the SQL endpoint during refresh operations. + +3. **Update column metadata**: Use Tabular Editor's **Update Table Schema** feature to update the column metadata for the table. This will automatically retrieve the column names and data types from the Lakehouse/Warehouse. Alternatively, create Data Columns manually (Alt+4) and specify the `Name`, `Data Type`, `Source Column` and any other relevant properties for each column. + +## Converting between storage modes + +It is straightforward to convert between Direct Lake on SQL and Direct Lake on OneLake using the information in this article, because you only need to modify the M query of the Shared Expression referenced by the Direct Lake partitions. + +If you want to convert from Import to Direct Lake it's slightly more complicated because of the different partition types involved. + +To make things easier, we have prepared a set of C# scripts that can help you convert between different storage modes: + +- [Convert Direct Lake on SQL to Direct Lake on OneLake](xref:script-convert-dlsql-to-dlol) +- [Convert Import to Direct Lake on OneLake](xref:script-convert-import-to-dlol) \ No newline at end of file diff --git a/content/localization/de/direct-lake-sql-model_de.md b/content/localization/de/direct-lake-sql-model_de.md new file mode 100644 index 00000000..ddb192d8 --- /dev/null +++ b/content/localization/de/direct-lake-sql-model_de.md @@ -0,0 +1,141 @@ +--- +uid: direct-lake-sql-model +title: Direct Lake on SQL Semantic Models +author: Morten Lønskov +updated: 2024-08-22 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Desktop + none: x + - edition: Business + none: x + - edition: Enterprise +--- + +# Direct Lake Semantic Models + +Direct Lake on SQL semantic models connect directly to data sources stored in [OneLake in Fabric](https://learn.microsoft.com/en-us/fabric/onelake/onelake-overview) through the SQL Endpoint. + +> [!IMPORTANT] +> As of [Tabular Editor 3.22.0](~/content/te3/other/release-notes/3_22_0.md), Tabular Editor 3 supports Direct Lake on OneLake, which is recommended in most scenarios. See our [Direct Lake guidance](xref:direct-lake-guidance) article for more information. + +Tabular Editor 3 can create and connect to this type of model. For a tutorial on this please refer to our blog article: [Direct Lake semantic models: How to use them with Tabular Editor](https://blog.tabulareditor.com/2023/09/26/fabric-direct-lake-with-tabular-editor-part-2-creation/). +Tabular Editor 3 can create direct lake semantic models with both the Lakehouse and Datawarehouse SQL Endpoint. + +Tabular Editor 2 can connect to Direct Lake semantic models, but does not have any built in functionality to create new tables or direct lake semantic models. This needs to be done manually or with a C# script. + +
    +
    Direct Lake limitations
    + There are several limitations to the changes that can be made to a Direct Lake model: Direct Lake Known Issues and Limitations We recommend this article by SQLBI for a initial overview of choosing between Direct Lake and Import mode. +
    + +## Creating a Direct Lake on SQL model in Tabular Editor 3 + +Creating a Direct Lake on SQL model in Tabular Editor 3 (3.15.0 or higher) has to be specified when the model is created in the _New Model_ dialog box, by using the Direct Lake checkbox. + +![Direct Lake New Model](~/content/assets/images/common/DirectLakeNewModelDialog.png) + +Using the checkbox ensures that Direct Lake specific properties and annotations are set, as well as limits the import of tables to Direct Lake supported sources. + +> [!NOTE] +> Direct Lake on SQL models currently use a collation that is different from regular Power BI import semantic models. This may lead to different results when querying the model, or when referencing object names in DAX code. +> For more information please see this blog post by Kurt Buhler: [Case-sensitive models in Power BI: consequences & considerations](https://data-goblins.com/power-bi/case-specific) + +> [!IMPORTANT] +> As of [Tabular Editor 3.22.0](~/content/te3/other/release-notes/3_22_0.md), the Direct Lake checkbox has been removed from the New Model dialog. You must [manually set the collation on your model to match that of your Fabric Warehouse](xref:direct-lake-guidance#collation) if using Direct Lake on SQL. + +## Framing New Models and Table Imports + +Tabular Editor 3 (3.15.0 or higher) automatically frames (refreshes) the model on first deployment. This is to ensure that Direct Lake mode is activated - otherwise the model would automatically fall back to DirectQuery. + +Additionally, on import of new tables Tabular Editor 3 (3.15.0 or higher) frames (refreshes) the model when it is saved the next time. This preference is located under **Tools > Preferences > Model Deployment > Data Refresh**. + +## Identifying a Direct Lake model + +The top title bar of Tabular Editor shows which type of model is open in that instance of Tabular Editor. Additionally, the TOM Explorer displays the type and mode of every table (Import, DirectQuery, Dual or Direct Lake). If a model contains a mix of table modes, the title bar will show "Hybrid". Currently, it is not possible for a Direct Lake on SQL model to contain tables in Import, DirectQuery or Dual mode. + +## Converting a Direct Lake model to Import Mode + +The below C# script converts and existing model into 'Import Mode'. This can be useful if the data latency requirements of your model does not require Direct Lake or you want to avoid the limitations of a Direct Lake model but have already started building one inside Fabric. + +Running the script is possible when Tabular Editor is connected to a semantic model through the XMLA endpoint. However, saving changes directly back to the Power BI/Fabric workspace is not supported by Microsoft. To circumvent this, the recommended approach is to use the "Model > Deploy..." option. This allows for the deployment of the newly converted model as a new entity in a workspace. + +> [!NOTE] +> After deploying the newly converted Import-mode model, you will need to specify the credentials for accessing the Lakehouse to refresh data into the model. + +### C# Script to convert Direct Lake model to Import Mode + +```csharp +// ********************************************************************************** +// Convert Direct Lake-mode model to Import-mode +// --------------------------------------------- +// +// When this script is executed on a semantic model, it will: +// +// - Loop through all tables. Any table that contains exactly 1 partition, which +// is in Direct Lake mode, will have its partition replaced by an equivalent +// Import-mode partition. +// - Set the collation of the model to null (default) +// +// Remarks: +// +// - The Import-mode partitions will use the SQL endpoint of the Lakehouse. +// - The script assumes that the Shared Expression which specifies the SQL endpoint +// is called "DatabaseQuery". +// - Because TE2 does not expose the "SchemaName" property on EntityPartition +// objects, we have to use reflection to access the underlying TOM objects. +// +// Compatibility: +// TE2.x, TE3.x +// ********************************************************************************** + +using System.Reflection; + +const string mImportTemplate = +@"let + Source = DatabaseQuery, + Data = Source{{[Schema=""{0}"",Item=""{1}""]}}[Data] +in + Data"; + +foreach(var table in Model.Tables) +{ + // Direct Lake-mode tables only have 1 partition... + if(table.Partitions.Count != 1) continue; + + // ...which should be in "DirectLake" mode: + var partition = table.Partitions[0]; + if(partition.Mode != ModeType.DirectLake) continue; + + // Tabular Editor unfortunately doesn't expose the SchemaName property of EntityPartitionSources, + // so we'll have to use reflection to access the underlying TOM object. + var pMetadataObjct = typeof(Partition).GetProperty("MetadataObject", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + var tomPartition = pMetadataObjct.GetValue(partition) as Microsoft.AnalysisServices.Tabular.Partition; + var tomPartitionSource = tomPartition.Source as Microsoft.AnalysisServices.Tabular.EntityPartitionSource; + + // Table does not have an EntityPartitionSource, meaning it is not a Direct Lake table + // (shouldn't happen, since we already checked for DirectLake mode above...) + if(tomPartitionSource == null) continue; + + var schemaName = tomPartitionSource.SchemaName; + var tableName = tomPartitionSource.EntityName; + + // Rename the original (Direct Lake) partition (as we can't have two partitions with the same name): + var partitionName = partition.Name; + partition.Name += "_old"; + + // Add the new (Import) partition: + table.AddMPartition(partitionName, string.Format(mImportTemplate, schemaName, tableName)); + + // Delete the old (Direct Lake) partition): + partition.Delete(); +} + +// Update model collation: +Model.Collation = null; +Model.DefaultMode = ModeType.Import; +Model.RemoveAnnotation("TabularEditor_DirectLake"); +``` \ No newline at end of file diff --git a/content/localization/de/direct-query-over-as_de.md b/content/localization/de/direct-query-over-as_de.md new file mode 100644 index 00000000..78ea07ec --- /dev/null +++ b/content/localization/de/direct-query-over-as_de.md @@ -0,0 +1,57 @@ +--- +uid: dq-over-as-limitations +title: Direct Query over Analysis Services +author: Morten Lønskov +updated: 2025-07-14 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +## Overview + +Tabular Editor 3 can **connect** to composite models that leverage **DirectQuery over Analysis Services (DQ‑over‑AS)**, but full modeling support is **not yet available**. Most authoring tasks work as expected; however, operations that rely on synchronising metadata with the remote semantic model—such as _Update table schema_—are currently limited. + +> [!IMPORTANT] +> Until full DQ‑over‑AS support ships, model metadata edited in Tabular Editor 3 **is not automatically kept in sync** with the source dataset. You must apply one of the work‑arounds listed below whenever columns or measures are added to the underlying Analysis Services model. + +## Current limitations + +| Feature | Status in TE3 | Notes | +| --------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------- | +| **Update table schema** | ❌ Not supported | Attempting to run **Model > Update table schema** on a DQ‑over‑AS table has no effect. | +| **Measure synchronisation** | ❌ Not supported | Measures created in the source dataset do not appear automatically in the composite model. | + +## Work‑arounds + +### 1. Manually add missing columns + +1. In **TOM Explorer**, select the table that requires the new column. +2. Choose **Add > Data Column**. +3. In the _Properties_ window, set: + + - **SourceColumnName** – _exactly_ match the **Name** of the column in the remote table. + - **SourceLineageTag** – copy the **LineageTag** value from the source column. +4. Save and deploy the model. + +> [!NOTE] +> Column names and lineage tags must match _character‑for‑character_. Any mismatch will cause deployment errors. + +### 2. Use the “Import tables from remote model” C# script + +Daniel Otykier’s article on LinkedIn provides a [ready‑made C# automation script](https://www.linkedin.com/pulse/composite-models-tabular-editor-daniel-otykier/) that: + +1. Temporarily imports full copies of tables from the remote model. +2. Lets you copy columns (and other metadata) into existing tables. +3. Deletes the temporary tables after the copy is complete. + +This approach is faster when several tables require updates. + +### 3. One‑click macro to pull new measures + +[rem-bou's](https://github.com/rem-bou) GitHub repository contains an advanced macro that scans the source dataset for measures that are **missing** in the composite model and adds them automatically: [Create-Update DQ over AS model connection](https://github.com/rem-bou/TabularEditor-Scripts/blob/main/Advanced/One-Click%20Macros/Create-Update%20DQ%20over%20AS%20model%20connection.csx) diff --git a/content/localization/de/downloads_de.md b/content/localization/de/downloads_de.md new file mode 100644 index 00000000..029a77ab --- /dev/null +++ b/content/localization/de/downloads_de.md @@ -0,0 +1,71 @@ +--- +uid: downloads +title: All downloads +author: Daniel Otykier +updated: 2025-09-15 +--- + +# Tabular Editor 3 Downloads + +This page provides download and installation instructions for Tabular Editor 3. + +## Latest version + +Tabular Editor 3.23.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.23.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.23.1 (ARM64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) + +Read the [latest release notes](release-notes/3_23_1.md). + +> [!NOTE] +> As of Tabular Editor 3.23.0, we now provide native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) builds. 32-bit (x86) builds have been discontinued. + +## Installation Instructions + +1. Download the .exe installer file. +2. Run the .exe installer. The installation wizard will guide you through the installation. +3. For instructions on how to activate the product or change a license key, see our [getting started guide](xref:getting-started). + +It is not necessary to remove previous installations when upgrading to a newer version of Tabular Editor 3. + +## History + +- 2025-09-15 **Tabular Editor 3.23.1** (_[Release notes](release-notes/3_23_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) +- 2025-08-28 **Tabular Editor 3.23.0** (_[Release notes](release-notes/3_23_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) +- 2025-06-28 **Tabular Editor 3.22.1** (_[Release notes](release-notes/3_22_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) +- 2025-06-19 **Tabular Editor 3.22.0** (_[Release notes](release-notes/3_22_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) +- 2025-04-25 **Tabular Editor 3.21.0** (_[Release notes](release-notes/3_21_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) +- 2025-04-11 **Tabular Editor 3.20.1** (_[Release notes](release-notes/3_20_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) +- 2025-02-21 **Tabular Editor 3.20.0** (_[Release notes](release-notes/3_20_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) + +For earlier builds, see the [full release history](release-history.md). diff --git a/content/localization/de/editions_de.md b/content/localization/de/editions_de.md new file mode 100644 index 00000000..8d352c2f --- /dev/null +++ b/content/localization/de/editions_de.md @@ -0,0 +1,130 @@ +--- +uid: editions +title: Compare editions +author: Søren Toft Joensen +updated: 2025-02-07 +--- + +# Tabular Editor 3 Editions + +This document provides an overview and comparison of the different editions of Tabular Editor 3. + +> [!NOTE] +> Tabular Editor 3 licenses are **per developer**. In other words, only the persons who use the Tabular Editor 3 product will need a license. + +## Supported Data Modeling Scenarios + +The main difference between the various editions of Tabular Editor 3, is which types of tabular data modeling scenarios they support. To understand this difference, consider that Analysis Services (Tabular) exists in a number of different "flavors": + +- Power BI Desktop (make sure you you understand the [limitations](xref:desktop-limitations)) +- Power BI Premium through the XMLA Endpoint (Premium Per User, **Premium Capacity [A, EM or P SKUs]**, **Fabric Capacity [F SKUs]**) +- SQL Server (2016+) Analysis Services (Editions: Developer, Standard, **Enterprise**) +- Azure Analysis Services (Tiers: Developer, Basic, **Standard**) + +We consider the **highlighted** flavors of Analysis Services to be Enterprise-Tier, and as such, these may only be used with Tabular Editor 3 Enterprise Edition. + +> [!IMPORTANT] +> Tabular Editor only allows editing data models using Compatibility Level 1200 or higher. This is the default on any instance of Analysis Services starting from SQL Server 2016. For the same reason, Tabular Editor does not support Excel PowerPivot, as this uses an earlier Compatibility Level. + +Please refer to the matrix below for the full overview of supported scenarios: + +| Scenario / Edition | Desktop | Business | Enterprise | +| --------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------- | +| External Tool for Power BI Desktop | | | | +| Load/save model metadata to disk\*\* | | \* | | +| Workspace Mode\*\*\* | | \* | | +| Power BI Premium Per User | | | | +| SQL Server Developer Edition | | \* | | +| SQL Server Standard Edition | | | | +| SQL Server Enterprise Edition | | | | +| Azure AS Developer Tier | | \* | | +| Azure AS Basic Tier | | | | +| Azure AS Standard Tier | | | | +| Power BI Premium Capacity (P SKUs) | | | | +| Power BI Embedded Capacity (A/EM SKUs) | | | | +| Fabric Capacity (F SKUs) | | | | + +\***Note:** Enterprise Edition is required if the Analysis Services data model contains perspectives or tables with multiple partitions (does not apply to Power BI Desktop or Power BI Premium Per User models). + +\*\***Note:** Supported file formats are: **.pbip** (Power BI Project) **.pbit** (Power BI Template), **.bim** (Analysis Services model metadata), **.vpax** (VertiPaq Analyzer) and **database.json** (Tabular Editor folder structure). + +\*\*\***Note:** Workspace Mode allows Tabular Editor 3 to simultaneously save model metadata to disk and synchronize a database on any of the editions of Analysis Services or Power BI supported by the Tabular Editor 3 edition purchased. + +## Modeling Restrictions + +We restrict a few data modeling operations inside Tabular Editor 3 as well, corresponding to the restrictions on certain Microsoft service tiers (Azure Analysis Services _Basic Tier_, SQL Server Analysis Services _Standard Edition_, and Power BI _Premium-Per-User_). + +Specifically, [Azure AS Basic Tier and SQL Server Standard Edition does not support perspectives, multiple partitions or DirectQuery](https://azure.microsoft.com/en-us/pricing/details/analysis-services/), and as such, SSAS/Azure AS models using these features require TE3 Enterprise Edition. + +Similarly, [Power BI Premium-Per-User workspaces do not support Direct Lake datasets](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#prerequisites), which is why Power BI models using this feature also requires TE3 Enterprise Edition. + +| Model type | Feature | Business | Enterprise | +| --------------- | ------------------- | ------------------------------------------------------- | ------------------------------------------------------- | +| Azure AS / SSAS | Perspectives | | | +| Azure AS / SSAS | Multiple partitions | | | +| Azure AS / SSAS | DirectQuery\* | | | +| Azure AS / SSAS | Direct Lake | N/A | N/A | +| Power BI | Perspectives | | | +| Power BI | Multiple partitions | | | +| Power BI | DirectQuery | | | +| Power BI | Direct Lake | | | + +\***Note:** Analysis Services on SQL Server Standard Edition pre-2019 does not support DirectQuery. Nor does Azure AS Basic Tier. [Learn more](https://learn.microsoft.com/en-us/analysis-services/analysis-services-features-by-edition?view=asallproducts-allversions#tabular-models). + +If you attemp to open a model that uses one or more of the restricted features listed above, while on a TE3 Business Edition license, you will see the error message below: + +![This edition of Tabular Editor 3 does not support Enterprise-tier semantic models](https://github.com/TabularEditor/TabularEditorDocs/assets/8976200/7ef69593-ea4b-4a16-a8df-543f5c31ac65) + +There are no other feature differences between the Tabular Editor 3 editions, than the ones listed above. + +> [!NOTE] +> Please keep in mind that Power BI Desktop [currently does not support all Data modeling operations](xref:desktop-limitations). For this reason, Tabular Editor 3 by default blocks operations that are not supported by Power BI Desktop. However, this restriction can be removed under Tools > Preferences > Power BI. + +> [!IMPORTANT] +> Tabular Editor can only be used as an external tool for Power BI Desktop when the Power BI report (.pbix, .pbip or .pbit) file contains a data model (Import, DirectQuery or Composite). **Reports using Live connection are not supported** since these reports do not contain a data model. [More information](xref:desktop-limitations). + +## Personal vs. Transferable licenses + +Our Desktop Edition and Business Edition uses a **personal** licensing model. This means, that a user receives their own personal License Key, which can not be shared or transferred to other users. When a user no longer requires the product, their subscription should be cancelled to avoid recurring payments. + +Our Enterprise Edition uses a **transferable** licensing model. The license administrator receives a single License Key, which is then valid for a number of named users up to the quantity purchased. Users are identified by their e-mail address, which is entered the first time a user activates an installation of Tabular Editor 3. The first time a user activates a Tabular Editor 3 installation using the license key, they are "locked-in" to that license for 30 days. After the 30 day lock-in period, a user can be removed from the license at any time, freeing up the license slot for another user. License administrators can view and manage users through our [self-service portal](https://tabulareditor.com/my-account). You may also contact support for assistance. + +## Multiple installations + +Each Tabular Editor 3 user is allowed to install the tool on multiple machines depending on the type of license held: + +| | Desktop | Business | Enterprise | +| -------------------------- | ------- | -------- | ---------- | +| Simultaneous installations | 1 | 2 | 3 | + +> [!NOTE] +> Sharing a single license among multiple users is against our [licensing terms](https://tabulareditor.com/license-terms). + +You can deactivate an existing installation at any time from within the tool itself, by choosing the "Change license key..." option under "Help > About Tabular Editor". You can also deactivate an installation through our [self-service portal](https://tabulareditor.com/sign-in) by navigating to the "Licenses" tab. + +If you need more simultaneous installations of Tabular Editor 3 than listed above, please contact [licensing@tabulareditor.com](mailto:licensing@tabulareditor.com). + +## Enterprise Edition Volume Discounts + +Our Enterprise Edition is priced in tiers, according to the following table (similar discount rates apply to monthly commitment): + +| Tier | Yearly price per seat | +| ------------------ | --------------------------- | +| First 5 seats | $950.00 USD | +| Next 6-10 seats | $900.00 USD | +| Next 11-20 seats | $850.00 USD | +| Next 21-50 seats | $800.00 USD | +| Seats 51 and above | $750.00 USD | + +As an example, if you need 12 seats, the price breaks down as follow: + +```text +Seats 1-5: 5 x 950.00 = $ 4,750.00 +Seats 6-10: 5 x 900.00 = $ 4,500.00 +Seats 11-12: 2 x 850.00 = $ 1,700.00 +-------------------------------------- +Total $ 10,950.00 +====================================== +``` + +If you require more than 100 seats, please contact sales for a quote. diff --git a/content/localization/de/find-replace_de.md b/content/localization/de/find-replace_de.md new file mode 100644 index 00000000..f0868fa1 --- /dev/null +++ b/content/localization/de/find-replace_de.md @@ -0,0 +1,53 @@ +--- +uid: find-replace +title: Find/Replace +author: Morten Lønskov +updated: 2023-03-22 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Find + +In Tabular Editor, you can use the advanced Find functionality to search for specific expressions throughout your open documents and dataset. The Find dialog box is accessible through the keyboard shortcut Ctrl+F. + +
    + Find Dialog Box
    Figure 1: Find window in Tabular Editor. Ctrl+F opens the dialog box
    +
    + +To perform a search, define the expression you want to search for, and use the Options to determine if certain criteria should be met. For example, you can choose whether the case should match between your find expression and the found text or use regular expressions to search with. + +## Look in + +Additionally, you can specify where to Look in, different areas of your Tabular Editor instance, to limit or expand the scope of your search. The Look in options include: + +
    + Find and Replace Dialog Box
    Figure 2: Find/Replace window in Tabular Editor. Ctrl+F opens the dialog box
    +
    + +- _Selection_: Search within the selection in the current open document (Cannot search through your dataset) +- _Current document_: Search through the entire document that you currently have open (Cannot search through your dataset) +- _All open documents_: Searches all open documents (Cannot search through your dataset) +- _Entire model_: Searches the TOM Explorer for matches in your dataset. + - Allows for searching within the individual parts of your dataset such as Names, Expressions, Annotations etc. + - You can also search using Dynamic LINQ in this mode to, for example, find all columns that do not have summarize set to none. + +> [!TIP] +> You can also use the search field in the TOM Explorer to search your dataset instead of the Find dialog + +## Replace + +The Replace dialog allows you in the same way as Find to search for an expression and then replace it with a different expression. + +The Replace dialog does not require anything in the _Replace with_ field, but leaving it empty will replace your searched for expression with an empty expression. +You have the same options as in the Find dialog to determine search criteria, but the _Look in_ functionality is only for documents, i.e. you cannot search and replace within your dataset objects. + +
    + Replace Dialog Box
    Figure 3: Replace window in Tabular Editor. Ctrl+F opens the dialog box
    +
    + +> [!TIP] +> If you are trying to rename variables in a DAX statement (Expression or Script), Ctrl+R will let you refactor a selected variable \ No newline at end of file diff --git a/content/localization/de/gdpr-delete_de.md b/content/localization/de/gdpr-delete_de.md new file mode 100644 index 00000000..2e69f7af --- /dev/null +++ b/content/localization/de/gdpr-delete_de.md @@ -0,0 +1,3 @@ +# User Data Deletion + +In order to request a complete data deletion of all user records, please send an e-mail to gdpr@tabulareditor.com. diff --git a/content/localization/de/general-introduction_de.md b/content/localization/de/general-introduction_de.md new file mode 100644 index 00000000..9f4af82e --- /dev/null +++ b/content/localization/de/general-introduction_de.md @@ -0,0 +1,115 @@ +--- +uid: general-introduction +title: General introduction and architecture +author: Daniel Otykier +updated: 2021-09-30 +--- + +# General introduction and architecture + +Tabular Editor is a Windows desktop application for developing tabular models. Specifically, the tool lets you edit the Tabular Object Model (TOM) metadata. The tool can load the TOM metadata from a file or from an existing Analysis Services database, and it can also deploy updated TOM metadata to Analysis Services. + +> [!NOTE] +> We use the term **tabular model** to represent both Analysis Services Tabular models as well as Power BI datasets, since Analysis Services Tabular is the data model engine used by Power BI. Similarly, when we use term **Analysis Services**, we mean "any instance of Analysis Services", which could be SQL Server Analysis Services, Power BI Desktop or the Power BI Service XMLA Endpoint. + +## Tabular Object Model (TOM) metadata + +A data model is made up by a number of tables. Each table has one or more columns, and a table may also contain measures and hierarchies. Typically, the data model also defines relationships between tables, data sources containing connection details and table partitions containing data source expressions (SQL or M queries) for loading data, etc. All of this information is collectively called the **model metadata**, and it is stored in a JSON based format known as the **Tabular Object Model (TOM)**. + +- When a tabular model is created using Visual Studio, the JSON representing the TOM metadata is stored in a file called **Model.bim**. +- When a data model is created using Power BI Desktop, the TOM metadata is embedded within the .pbix or .pbit file (since this file format also contains a lot of other details, such as definitions of visuals, bookmarks, etc., which is not related to the data model itself). + +Using a client library called [AMO/TOM](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions), Tabular Editor is able to load and save metadata to and from this JSON based format. In addition, the client library allows Tabular Editor to connect directly to any instance of Analysis Services, in order to obtain the model metadata from an existing database. This is illustrated in the figure below. + +![Architecture](~/content/assets/images/architecture.png) + +> [!NOTE] +> In the paragraph above, we used the term **database** to represent a model that has been deployed to Analysis Services. Within the Power BI Service the term **dataset** is used to represent the same thing, namely a tabular model. + +Tabular Editor can load model metadata from the following sources: + +- [1] Model.bim files +- [2] Database.json files (see @parallel-development for more information) +- [3] .pbit files (Power BI Template) +- [4] A database on SQL Server Analysis Services (Tabular) +- [5] A database on Azure Analysis Services +- [6] A dataset in a Power BI Premium\* Workspace +- [7] A Power BI Desktop report in Import/DirectQuery mode + +\*Power BI Premium/Embedded Capacity or Power BI Premium-Per-User is required in order to enable the [XMLA Endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools). The XMLA Endpoint must be enabled for any third party tool to connect to Power BI datasets. + +> [!IMPORTANT] +> Tabular Editor 2.x supports all sources 1-7 above. Tabular Editor 3 supports only some sources depending on which [edition of Tabular Editor 3](xref:editions) you are using. + +Once the model metadata has been loaded in Tabular Editor, the user is free to add/edit/remove **objects** and change **object properties**. Modifications are not saved back to the source until the user explicitly saves the model, either by choosing **File > Save** or by hitting CTRL+S. If the model metadata was loaded from a file source (sources 1-3 above), that file will then be updated. If the model metadata was loaded from Analysis Services (sources 4-7 above), then the changes are saved back to Analysis Services. Note that certain changes may cause objects to enter a state where they can no longer be queried by end-users. For example, if you add a column to a table, you will need to [refresh the table](xref:refresh-preview-query#refreshing-data) before users can query the contents of that table or any measures that dependent on the table. + +> [!WARNING] +> Certain limitations apply when saving model metadata changes back to Power BI Desktop (source 7 above). See @desktop-limitations for more information. + +### TOM objects and properties + +The TOM metadata is made up of **objects** and **properties**. + +Examples of TOM **objects**: + +- Data Sources +- Tables +- Partitions +- Measures +- KPIs +- Columns +- Model Roles + +Examples of TOM **object properties**: + +- `Name` (text) +- `Display Folder` (text) +- `Description` (text) +- `Hidden` (true/false) +- `Summarize By` (one of: None, Sum, Min, Max, ...) + +Most properties are simple values (text, true/false, one-of-selections aka. enums), but properties can also reference other objects (for example, the `Sort By Column` property should reference a column). Properties can also be arrays of objects, such as the `Members` property on the Model Role object. + +Tabular Editor generally uses the same name for objects and properties as those defind in the [Microsoft.AnalysisServices.Tabular namespace](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular?view=analysisservices-dotnet). If you want to learn more about specific TOM objects or properties, always consult the namespace documentation. For example, to learn what the "Summarize By" column property does, first locate the "Column" class in Microsoft's documentation, then expand "Properties" and scroll to "SummarizeBy". You should then get to [this article](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.column.summarizeby?view=analysisservices-dotnet). + +![SummarizeBy on Microsoft's docs](~/content/assets/images/asdocs-summarizyby.png) + +### Editing property values + +Both versions of Tabular Editor display the object model metadata in a hierarchical view known as the **TOM Explorer** view, which roughly corresponds to the hierarchical structure of the JSON metadata: + +![TOM Explorer](~/content/assets/images/tom-explorer.png) + +In general, Tabular Editor lets you modify object properties by first selecting an object in the TOM Explorer (you can select multiple objects at once by holding down SHIFT or CTRL), and then simply editing the property value within the **Properties view** (see screenshot below). + +![Properties View](~/content/assets/images/properties-view.png) + +Tabular Editor does not perform explicit validation of modified property values, except for some basic rules (for example, object names cannot be empty, measure names have to be unique, etc.). It is your responsibility as a tabular model developer to know which properties to set and what values to use. + +If you make a mistake while editing property values, you can always press CTRL+Z (Edit > Undo) to roll back the last property change. + +## Architecture + +As hinted above, Tabular Editor has two different modes of operation: Metadata from file (aka. **file mode**) and metadata from Analysis Services (aka. **connected mode**). In addition, Tabular Editor 3 introduces a hybrid approach called [**workspace mode**](xref:workspace-mode). + +Before proceeding, it is important to understand the differences between these modes: + +- In **file mode**, Tabular Editor loads and saves all model metadata from and to a file on disk. In this mode, Tabular Editor cannot interact with model **data** (that is, table previews, DAX queries, Pivot Grids, and data refresh operations are not enabled). This mode can be used entirely offline, even when no instance of Analysis Services is available. The supported file formats for model metadata are: + - Model.bim (same format used by Visual Studio) + - Database.json (folder structure only used by Tabular Editor) + - .pbit (Power BI Template) +- In **connected mode**, Tabular Editor loads and saves model metadata from and to Analysis Services. In this mode, it is possible to interact with model **data** using Tabular Editor 3 (table previews, DAX queries, Pivot Grids and data refresh). This mode requires connectivity to an instance of Analysis Services. +- In **workspace mode**, Tabular Editor 3 loads model metadata from a file on disk AND deploys the metadata to Analysis Services. On subsequent saves (CTRL+S), updates are saved both to disk and to the connected instance of Analysis Services. It is possible to interact with model **data** similar to **connected mode**. + +### Metadata synchronization + +One of the major benefits of Tabular Editor over the standard tools (Visual Studio, Power BI Desktop), is that model metadata is only saved upon request. In other words, you can make multiple changes to objects and properties without having to wait for any Analysis Services instance to become synchronized between each change. The synchronization of the Analysis Services database is an operation that may take several seconds to complete, depending on the size and complexity of the data model. In Power BI Desktop, this synchronization happens every time the notorious "Working on it" spinner appears on the screen. In Tabular Editor, this only happens when you explicitly save your changes (CTRL+S). + +The downside is, of course, that you have to remember to explicitly save your changes, before you can test the impact of any metadata modifications that were made. + +## Next steps + +- @installation-activation-basic +- @migrate-from-vs +- @migrate-from-desktop +- @migrate-from-te2 \ No newline at end of file diff --git a/content/localization/de/getting-started_de.md b/content/localization/de/getting-started_de.md new file mode 100644 index 00000000..fa3ecebf --- /dev/null +++ b/content/localization/de/getting-started_de.md @@ -0,0 +1,138 @@ +--- +uid: getting-started +title: Getting Started +author: Morten Lønskov +updated: 2025-09-23 +--- + +# Getting Started + +## Installation + +Download the latest version of Tabular Editor 3 from our [downloads page](xref:downloads). + +## Prerequisites + +None. + +## System requirements + +- **Operating system:** Windows 10, Windows 11, Windows Server 2016, Windows Server 2019 or newer +- **Architecture:** x64, ARM64 (native from 3.23.0) +- **.NET Runtime:** [.NET Desktop Runtime 8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) + +See the .NET supported OS policy for current Windows versions supported by each runtime. + +## Activating your installation + +Tabular Editor 3 is commercial software. Visit our [home page](https://tabulareditor.com) for pricing details and purchase options. If you haven't previously used Tabular Editor 3 you are eligible to a free 30-day trial. + +The first time you launch Tabular Editor 3 on a new machine, you are prompted to activate the product. + +![Product activation](~/content/assets/images/product-activation.png) + +### Activating using an existing license key + +Once you purchase a license for Tabular Editor 3, you should receive an e-mail with a 25-character string which is your license key. When prompted, enter the license key and hit "Next >" to activate the product. + +![Enter License Key](~/content/assets/images/enter-license-key.png) + +> [!NOTE] +> For multi-user license types, you will need to enter your e-mail address in addition to the license key. Tabular Editor 3 will prompt you to do so, if the license key you enter represents a multi-user license. + +Note that Tabular Editor 3 installations are activated **per user**. In other words, if multiple users share the same machine, each user will have to activate the product on their Windows user profile. + +### Requesting a trial license + +If you haven't used Tabular Editor 3 before, you are eligible to a free 30-day trial. When choosing this option, you will be prompted for an e-mail address. We use the e-mail address to validate whether or not you have an existing activation of Tabular Editor 3. + +> [!NOTE] +> Tabular Editor ApS will not sent unsolicited e-mails or forward your e-mail address to third parties, when signing up for a 30-day trial license. View our @privacy-policy for more information. + +### Changing a license key + +When Tabular Editor 3 is activated, you may change your license key in the Help menu by choosing "About Tabular Editor". + +![About Te3](~/content/assets/images/about-te3.png) + +In the dialog, select "Change license key". Note that this option is only available if no model is loaded in Tabular Editor. If you already loaded a model you can close it under File > Close model. Once you click "Change license key", Tabular Editor will prompt you whether you want to remove the current license: + +![image](https://user-images.githubusercontent.com/8976200/146754154-e691810b-342d-4311-8278-33da240d8d08.png) + +By accepting this, the current license is removed, and you will have to re-enter a license key to use the product. + +> [!IMPORTANT] +> Once a license key is removed, as described above, the product will not be usable by the current user on that machine until a new license key is entered. + +#### Registry details + +Tabular Editor 3 uses the Windows Registry to store activation details. + +To view the current license key assigned to the machine, run the following command in the Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG QUERY "HKCU\Software\Kapacity\Tabular Editor 3" /v LicenseKey +``` + +You can also use `regedit.exe` (Windows Registry Editor) and navigate to `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` to view and modify the **LicenseKey** and **User** values. + +A system administrator may also proactively assign Tabular Editor 3 licenses to a machine by specifying the **LicenseKey** and **User** values under each user’s `SOFTWARE\Kapacity\Tabular Editor 3` registry key. + +![Registry Editor](~/content/assets/images/registry-editor.png) + +### Changing a license key through the registry + +If, for any reason, you are unable to change the license key using the procedure outlined above, you can always reset the license assigned to Tabular Editor 3 by using the Registry Editor: + +1. Close all instances of Tabular Editor 3. +2. Open the Registry Editor in Windows (Start > Run > regedit.msc). +3. Locate `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` (see screenshot above). +4. Delete all values within this key. +5. Close the Registry Editor and restart Tabular Editor 3. + +Alternatively, run the following command in a Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG DELETE "HKCU\Software\Kapacity\Tabular Editor 3" /va +``` + +The next time you launch Tabular Editor 3, you will be prompted for a license key, just as when the tool was first installed on the machine. + +### Silent installation and license pre-provisioning + +You can deploy Tabular Editor silently and pre-provision the license through the Windows Registry. + +1. **Install silently** (no UI, no reboot): + ```powershell + msiexec /i TabularEditor..x64.Net8.msi /qn /norestart /l*v C:\Temp\TE3_install.log + ``` + +You may also use `/package` instead of `/i`. Replace `` with the actual version string. Use the ARM64 MSI if applicable. + +For details on available MSI command-line options, please refer to the official Microsoft documentation: +[Microsoft Standard Installer command-line options - Win32 apps | Microsoft Learn](https://learn.microsoft.com/windows/win32/msi/command-line-options) + +2. **Write the license to the Registry** **before the first launch** of the application: + + ```bat + REM Per-user license key (HKCU) + REG ADD "HKCU\Software\Kapacity\Tabular Editor 3" /v LicenseKey /t REG_SZ /d YOUR-25-CHAR-KEY /f + ``` + + If you are using an **Enterprise Edition** license key, also set the licensed user’s e‑mail: + + ```bat + REG ADD "HKCU\Software\Kapacity\Tabular Editor 3" /v User /t REG_SZ /d user@example.com /f + ``` + +**Notes** + +- The installer does **not** accept a license parameter; licensing is handled via the Registry entries above. +- Keys are stored under **HKCU** (per-user). Ensure the commands run in the context of the target user (e.g., via logon script or similar) so the values are written to the correct profile. +- For additional keys and values, see the [Registry details](#registry-details). + +## Next steps + +- [Overview of Tabular Editor 3's user interface](xref:user-interface) +- [What's new in Tabular Editor 3](whats-new.md) +- [Tabular Editor 3 Onboarding Guide](xref:onboarding-te3) \ No newline at end of file diff --git a/content/localization/de/import-tables.partial_de.md b/content/localization/de/import-tables.partial_de.md new file mode 100644 index 00000000..c0497727 --- /dev/null +++ b/content/localization/de/import-tables.partial_de.md @@ -0,0 +1,143 @@ +Tabular Editor 3 includes a **Table Import Wizard** that helps you create a data source in your model and import tables/views from relational data sources such as a SQL Server database. + +![Import Tables Wizard](~/content/assets/images/import-tables-wizard.png) + +## Types of TOM Data Sources + +Depending on your version of Analysis Services, there are different ways of defining data sources within the model metadata: + +- **Provider (aka. Legacy)**: Available in every version of Analysis Services and every compatibility level. Supports a limited range of sources, primarily relational through OLE DB/ODBC drivers. Partitions are usually defined using a SQL statement, which is executed natively against the source. Credentials are managed in the Provider Data Source object in the Tabular Object Model and stored and encrypted server-side. +- **Structured (aka. Power Query)**: Available since SQL Server 2017 (compatibility level 1400+). Supports a wider range of data sources than Legacy providers. Partitions are usually defined using M (Power Query) expressions. Credentials are managed in the Structured Data Source object in the Tabular Object Model and need to be specified upon every deployment to Analysis Services. +- **Implicit data sources**: Exclusively used by Power BI semantic models. No explicit Data Source object is created in the model. Instead, the M (Power Query) expression implicitly defines the data source. Credentials are not stored in the Tabular Object Model, but are managed by Power BI Desktop or the Power BI Service. + +> [!NOTE] +> The Table Import Wizard and Update Table Schema feature of Tabular Editor 2.x only supports Legacy data sources with SQL partitions. In other words, there is no support for Power Query partitions. For this reason, Legacy data sources are usually recommended, as they provide the highest level of interoperability between the developer tools. + +## Importing new tables + +When importing tables (Model menu > Import tables...), Tabular Editor presents you with the options mentioned above (for creating a new data source), as well as a list of data sources already present in the model. Avoid creating new data sources if the tables you want to import are available in one of the data sources already specified in the model. + +> [!TIP] +> A Semantic Model is generally regarded as an in-memory optimized semantic cache of a relational data warehouse. For this reason, a model should ideally only contain a single data source, which would point to a SQL-based data warehouse or data mart. + +## Creating a new data source + +If you need to create a new data source, Tabular Editor provides you with a list of supported data sources: + +![Create New Source](~/content/assets/images/create-new-source.png) + +Note that Analysis Services and Power BI in particular supports a much wider range of data sources, however the sources listed in the screenshot above are the ones that Tabular Editor is able to connect for the purpose of automatically importing table metadata (that is, column names and data types). For data sources not on this list, Tabular Editor 3 can still [update table schema by utilising Analysis Services](#updating-table-schema-through-analysis-services). + +Currently, the following data sources are natively supported by Tabular Editor 3: + +- SQL Server databases +- Azure SQL databases +- Azure Synapse Analytics (SQL pool and Serverless SQL pool) +- Oracle +- ODBC +- OLE DB +- Snowflake\* +- Power BI Dataflow\* +- Databricks\* +- Fabric Lakehouse\* +- Fabric Warehouse\* +- Fabric SQL Database\* +- Fabric Mirrored Database\* + +\*=These data sources are only supported as implicit data sources in Power BI data models. They are not available in SSAS / Azure AS. + +> [!TIP] +> For more info about connecting to Azure Databricks, please see [Connecting to Azure Databricks](xref:connecting-to-azure-databricks). + +After choosing one of the data sources on the list, Tabular Editor displays a connection details dialog, allowing you to specify server addresses, credentials, etc., specific to the data source you want to create. The settings that you specify should be those that Tabular Editor should use for establishing a local connection to the source. These settings are saved in your @user-options. + +![Sql Auth](~/content/assets/images/sql-auth.png) + +If you want Analysis Services to use different credentials when connecting, you can specify that by editing the data source properties of the Tabular Object Model after importing the tables. + +## Choosing objects to import + +Once your data source has been defined, you get the option of choosing tables/views from a list, or specifying a native query to be executed against the source. + +![Source Options](~/content/assets/images/source-options.png) + +If you select the first option, Tabular Editor will connect to the source and display a list of tables and views that you can preview on the next page: + +![Choose Source Objects](~/content/assets/images/choose-source-objects.png) + +You can import multiple tables/views at once by checking them on the left side. For each table/view, you may deselect/select columns to import. + +> [!TIP] +> If you are in control of the source, we recommend always creating a view on top of the tables you wish to import. In the view, make sure to correct any names, spellings, etc., to be used in the Semantic Model, and get rid of any columns not needed by the Semantic Model (system columns, timestamps, etc.). +> +> Then, in the model, import all columns from this view (basically generating a `SELECT * FROM ...` statement). This makes maintenance easier, as you only need to run a Schema Update in Tabular Editor to determine if anything was changed in the source. + +![Advanced Import](~/content/assets/images/advanced-import.png) + +If you change the preview mode to "Schema only" using the dropdown in the top left corner, it is possible to change the imported data type and column name for every source column. This may be useful for example if your source using floating-point values, but you want the data to be imported as fixed-decimal. + +![Confirm Selection](~/content/assets/images/confirm-selection.png) + +On the last page, confirm your selection and choose which type of partitions to create. For provider data sources, the default type of partition to be created is `SQL`, whereas for structured data sources, it is `M`. + +![Confirm Selection Direct Lake](~/content/assets/images/confirm-selection-direct-lake.png) + +For Fabric data sources the last page has a drop-down which lets you choose if you want your selection to be created as Direct Lake or Import mode. + +At this point, you should see your tables imported with all columns, data types, and source column mappings applied: + +![Import Complete](~/content/assets/images/import-complete.png) + +# Updating table schema + +If columns are added/changed in the source, or if you recently modified a partition expression or query, you can use Tabular Editor's **Update table schema** feature to update the column metadata in your model. + +![Update Table Schema](~/content/assets/images/update-table-schema.png) + +This menu item can be invoked at the model level, as well as on a collection of tables or even individual table partitions. + +When using this option, Tabular Editor will connect to all the relevant data sources (prompting for credentials as needed), in order to determine if new columns need to be added or existing column modified or removed. + +> [!IMPORTANT] +> If a column that was previously imported to your Semantic Model has been removed or renamed in the source, you must update the table schema in your Semantic Model. Otherwise, data refresh operations may fail. + +![Schema Compare Dialog](~/content/assets/images/schema-compare-dialog.png) + +In the screenshot above, Tabular Editor detected a few new columns, a single data type change, and two columns that were renamed in the source. Note that detection of a column rename only works for simple changes. In other cases, a name change usually results in Tabular Editor detecting a column removal and a column addition, which is the case for the `Tax Amount` column below, which seems to have been renamed to `TaxAmt` in the source. + +To avoid breaking existing DAX formulas that rely on the `[Tax Amount]` column, you can hold down the Ctrl button and click on the two rows in the Schema Change dialog, then right-click in order to combine the column removal and column addition into a single SourceColumn update operation: + +![Combine Sourcecolumn Update](~/content/assets/images/combine-sourcecolumn-update.png) + +If you do not want the name change to be propagated to the imported column (but only want to update the SourceColumn property to reflect the changed name in the data source), you can deselect the `Name` update operation in the dropdown: + +![Deselect Name](~/content/assets/images/deselect-name.png) + +## Updating table schema through Analysis Services + +By default, Tabular Editor 3 attempts to connect directly to the data source for the purposes of updating the imported table schema. Naturally, this only works when the data source is supported by Tabular Editor 3. If you need to update the schema of a table imported from a data source that is not supported by Tabular Editor 3, you can enable the **Use Analysis Services for change detection** option under **Tools > Preferences > Schema Compare**. This also applies when the M expression of a partition or shared expression is too complex for Tabular Editor 3's built-in schema detection feature. For example, the built-in schema detection does not support certain M functions. + +![Update Table Schema Through As](~/content/assets/images/update-table-schema-through-as.png) + +When this option is enabled and Tabular Editor 3 is connected to Analysis Services or the Power BI XMLA endpoint, you can update the schema of tables imported from **any** data source supported by Analysis Services or Power BI. + +> [!NOTE] +> The **Use Analysis Services for change detection** option only works while Tabular Editor 3 is connected to Analysis Services or the Power BI XMLA endpoint. For this reason, we recommend that developers always use the [Workspace Mode](xref:workspace-mode) when developing models. + +When the **Use Analysis Services for change detection** option is enabled, Tabular Editor 3 will use the following technique when a schema update is requested: + +1. A new transaction is created against the connected Analysis Services instance +2. A new temporary table is added to the model. This table uses a Power Query partition expression that returns the schema of the original expression, for which a schema update was requested. This is done using the [`Table.Schema` M function](https://docs.microsoft.com/en-us/powerquery-m/table-schema). +3. The temporary table is refreshed by Analysis Services. Analysis Services takes care of connecting to the data source in order to retrieve the updated schema. +4. Tabular Editor 3 queries the content of the temporary table to obtain the schema metadata. +5. The transaction is rolled back, leaving the Analysis Services database or Power BI Semantic Model in the original state it was in before step 1. +6. Tabular Editor 3 displays the "Apply Schema Changes" dialog as shown above, in case there are any schema changes. + +Using this technique, Tabular Editor 3 makes it possible to import and update tables from data sources that are otherwise not supported, regardless of the complexity and function usage of the M queries behind the tables. + +> [!NOTE] +> If your M expressions combine data from multiple sources, such as through the M [`Table.NestedJoin`](https://learn.microsoft.com/en-us/powerquery-m/table-nestedjoin) function, you may need to change the [**Privacy Level**](https://powerbi.microsoft.com/en-us/blog/privacy-levels-for-cloud-data-sources/) from "Private" to "Organizational" on the Semantic Model in the Power BI service. Otherwise, you may see an error indicating that ` references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.`. This error may also occur even if **Use Analysis Services for change detection** is not enabled, as Tabular Editor 3 will automatically fall back to this detection mechanism when the M expression is too complex for Tabular Editor 3's built-in schema detection. + +### Importing new tables through Analysis Services + +In order to import a table from a data source otherwise not suported, you can simply copy an existing table from that data source, modify the M expression on the partition query of the copied table, then save your changes to the workspace database and update the table schema as described above. diff --git a/content/localization/de/importing-tables-data-modeling_de.md b/content/localization/de/importing-tables-data-modeling_de.md new file mode 100644 index 00000000..4529882d --- /dev/null +++ b/content/localization/de/importing-tables-data-modeling_de.md @@ -0,0 +1,74 @@ +--- +uid: importing-tables-data-modeling +title: Importing tables and data modeling +author: Daniel Otykier +updated: 2021-10-08 +applies_to: + editions: + - edition: Desktop + partial: TE3 Desktop Edition includes this feature. External tools adding/editing tables, columns and relationships against a Power BI Desktop model is not supported by Microsoft, however. + - edition: Business + - edition: Enterprise +--- + +# Importing tables and data modeling + +This article describes how to use the [Table Import Wizard](#table-import-wizard) of Tabular Editor 3, to add new tables to the model. There is also a section on how to [update the table schema](#updating-table-schema) of an existing table. Lastly, we cover how to use the [diagram tool](#working-with-diagrams) to define and edit relationships between tables. + +## Table Import Wizard + +[!include[importing-tables1](~/content/te3/import-tables.partial.md)] + +# Working with diagrams + +In Tabular Editor 3, **diagrams** are documents that can be used to visualize and edit the relationships between tables in the model. You can create as many diagrams as you want to visualize certain areas of your model. A diagram can be saved as a stand alone file. See for more information. + +> [!NOTE] +> We recommend creating multiple smaller diagrams over few large diagrams. When a diagram contains more than 20 or so tables, it quickly becomes overwhelming and difficult to understand. + +After loading a model in Tabular Editor 3, choose the **File > New > Diagram** menu option to create a new diagram. + +## Adding tables + +Add initial tables to the diagram in any of the following ways: + +- (Multi-)select tables in the TOM Explorer, then right-click and choose **Add to diagram**. +- (Multi-)select tables in the TOM Explorer, then drag the tables over to the diagram +- Use the **Diagram > Add tables...** menu option, and (multi-)select the tables you want to add through the dialog box. + ![Diagram Add Tables](~/content/assets/images/diagram-add-tables.png) + +To add additional tables to the diagram, use the technique above again, or right-click on an existing table in the diagram and choose one of the following options: + +- **Add tables that filter this table**: Adds all tables to the diagram which may, directly or indirectly through other tables, filter the currently selected table. Useful when starting from a fact table. +- **Add all related tables**: Adds all tables to the diagram which are directly related to the currently selected table. Useful when starting from a dimension table. + ![Add Related Tables](~/content/assets/images/add-related-tables.png) + +Before proceeding, rearrange and resize the tables in the diagram to suit your preferences, or use the **Diagram > Auto-arrange** feature to have Tabular Editor 3 lay out the tables automatically. + +## Modifying relationships using the diagram + +To add a new relationship between two tables, locate the column on the fact table (many-side) of the relationship, and drag that column over to the corresponding column on the dimension table (one-side). Confirm the settings for the relationship and hit **OK**. + +![Create Relationship](~/content/assets/images/create-relationship.png) + +To edit an existing relationship, right-click on it and choose **Edit relationship**. The right-click menu also contains shortcuts for reversing or deleting a relationship, as shown on the screenshot below. + +![Edit Relationship Diagram](~/content/assets/images/edit-relationship-diagram.png) + +> [!NOTE] +> You can also create relationships without using a diagram, through the TOM Explorer. Locate the column from which the relationship should start (many-side / fact-table side), right-click and choose **Create > Relationship from**. Specify the destination column in the Create Relationship dialog that appears on the screen. + +## Saving a diagram + +To save a diagram, simply use the **File > Save** (CTRL+S) option. Tabular Editor 3 will prompt you to save the diagram if you close the document or the application while the diagram has unsaved changes. + +> [!TIP] +> The same diagram file can be loaded for different data models. Diagrams reference tables by their names. Any tables not present in the model upon diagram load are simply removed from the diagram. + +> [!NOTE] +> Every time you add or modify a relationship, you will have to run a "calculate" refresh on the data model, before the relationships can be used when querying the model. + +# Next steps + +- @refresh-preview-query +- @creating-and-testing-dax \ No newline at end of file diff --git a/content/localization/de/importing-tables-from-excel_de.md b/content/localization/de/importing-tables-from-excel_de.md new file mode 100644 index 00000000..7d339d97 --- /dev/null +++ b/content/localization/de/importing-tables-from-excel_de.md @@ -0,0 +1,63 @@ +--- +uid: importing-tables-from-excel +title: Importing Tables from Excel +author: Daniel Otykier +updated: 2021-11-10 +--- + +# Importing Tables from Excel + +If you need to add Excel worksheets as tables to your tabular model, this is possible with Tabular Editor 2.x and the Excel ODBC driver. + +# Prerequisites + +Tabular Editor 2.x is a 32 bit application, and most people usually have the 64 bit version of Office installed (which includes a 64-bit Excel ODBC driver). Unfortunately, Tabular Editor 2.x can't use the 64-bit driver, and simply downloading and attempting to install the 32-bit driver, will give you an error if you already have a 64-bit version of Office installed. However, it is possible to install the 32 bit Excel ODBC driver next to the 64-bit Office, by using this workaround: + +1. Download the 32-bit version of the driver from here: https://www.microsoft.com/en-us/download/details.aspx?id=54920 +2. Unzip the AccessDatabaseEngine.exe file +3. Inside, you will find the aceredist.msi file, which should be executed through the command line with the /passive switch: + + ```shell + aceredist.msi /passive + ``` + +4. Confirm the installation by looking in the ODBC Data Sources (32-bit) configuration (Windows start button, search for "ODBC", platform should say "32/64 bit", as in the screenshot below): + ![Excel Odbc 32 64](~/content/assets/images/excel-odbc-32-64.png) + +# Setting up an ODBC data source + +After making sure you have the 32-bit ODBC Excel driver installed, as described above, adding a table from an Excel file with Tabular Editor 2.x requires the following steps: + +1. In Tabular Editor, right-click on the model, choose "Import tables…", click "Next" +2. In the Connection Properties dialog, click "Change…". Select the "Microsoft ODBC Data Source" option and click "OK". +3. Select "Use connection string" and hit "Build…". Choose "Excel Files" and hit "OK". + ![Odbc Connection Properties Excel](~/content/assets/images/odbc-connection-properties-excel.png) +4. Locate the Excel file you want to load tables from and hit "OK". That should generate a connection string that looks something like this: + + ```connectionstring + Dsn=Excel Files;dbq=C:\Users\DanielOtykier\Documents\A Beer Dataset Calculation.xlsx;defaultdir=C:\Users\DanielOtykier\Documents;driverid=1046;maxbuffersize=2048;pagetimeout=5 + ``` + +5. After hitting "OK", Tabular Editor should display the list of worksheets and data areas in the Excel file. Unfortunately, the Import Table Wizard can’t preview the data currently, because it generates an invalid SQL statement: + ![Import Tables Excel](~/content/assets/images/import-tables-excel.png) +6. You can, however, still put a checkmark on the table you want to import. Hit "Import" when done, ignore the error message. +7. On the newly added table, locate the partition and modify the SQL to remove the empty bracket and the dot in front of the worksheet name. Apply the change (Hit F5). + ![Fix Partition Expressions Excel](~/content/assets/images/fix-partition-expressions-excel.png) +8. Then, right-click on the partition and choose "Refresh Table Metadata…". Tabular Editor now reads the column metadata from the Excel file through the ODBC driver: + ![Refresh Metadata Excel](~/content/assets/images/refresh-metadata-excel.png) +9. (Optional) If you don’t want to use ODBC for refreshing data into the table, you need to swap out the partition to use an M-based expression that loads the same worksheet data. To do this, add a new Power Query partition to the table (right-click on "Partitions" then choose "New Partition (Power Query")). Delete the legacy partition. Then, set the M expression of the new partition to the following: + + ```M + let + Source = Excel.Workbook(File.Contents(""), null, true), + Customer_Sheet = Source{[Item="",Kind="Sheet"]}[Data], + #"Promoted Headers" = Table.PromoteHeaders(Customer_Sheet, [PromoteAllScalars=true]) + in + #"Promoted Headers" + ``` + +Replace the `` and `` placeholders with their actual values. + +# Conclusion + +Importing tables from Excel files is possible with Tabular Editor 2.x, but it requires the use of the ODBC Excel driver as shown above, which adds some complexity to the process. \ No newline at end of file diff --git a/content/localization/de/importing-tables_de.md b/content/localization/de/importing-tables_de.md new file mode 100644 index 00000000..36873244 --- /dev/null +++ b/content/localization/de/importing-tables_de.md @@ -0,0 +1,15 @@ +--- +uid: importing-tables +title: Importing Tables +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Importing Tables + +[!include[importing-tables](~/content/te3/import-tables.partial.md)] \ No newline at end of file diff --git a/content/localization/de/incremental-refresh-about_de.md b/content/localization/de/incremental-refresh-about_de.md new file mode 100644 index 00000000..0d131c62 --- /dev/null +++ b/content/localization/de/incremental-refresh-about_de.md @@ -0,0 +1,350 @@ +--- +uid: incremental-refresh-about +title: What is a Refresh Policy? +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# What is a Refresh Policy? + +![Incremental Refresh Visual Abstract](~/content/assets/images/incremental-refresh-header.png) + +--- + +Datasets hosted in the Power BI service can have [Incremental Refresh](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview) configured for one or more data tables. **The purpose of Incremental Refresh is to achieve faster, more efficient refreshes by only retrieving recent/changing data, _incrementally refreshing_ the table.** To do this, the table is automatically divided into partitions, such that only recent or changing data is refreshed ("hot" partitions) or even retrieved in real-time (["Direct Query" partitions in "Hybrid Tables"](https://learn.microsoft.com/en-us/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables)) while older, static data is archived ("cold" partitions). + +_Incremental refresh can be easily configured and modified from within Tabular Editor._ + +> [!NOTE] +> Configuring incremental refresh can be beneficial for your data model: +> +> - Reduce refresh time & resource consumption +> - Experience shorter and more dependable scheduled refreshes + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +### How does it work? + +To create the partitions, Power BI uses the `RangeStart` and `RangeEnd` _datetime_ parameters in Power Query. These parameters are used in a filter step of the table partition M Expression, filtering a table datetime column. Columns that are of date, string or integer types can still be filtered while maintaining query folding using functions that convert `RangeStart`, `RangeEnd` or the date column to the appropriate data type. For more information about this, see [here](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#supported-data-sources) + +An example is given below. Incremental Refresh is applied to a table _'Orders'_ upon the _[Order Date]_ column: + +# [Filter Step Only](#tab/filterstep) + +```M +// The filter step should ideally be able to fold back to the data source +// No steps before this should break query folding +#"Incremental Refresh Filter Step" = + Table.SelectRows( + Navigation, + each + [OrderDate] >= #"RangeStart" and + [OrderDate] < #"RangeEnd" + ) +``` + +# [Full M Expression](#tab/fullexp) + +```M +let + // The data source should ideally support Query Folding + Source = Sql.Database(#"ServerParameter", #"DatabaseParameter"), + + Navigation = + Source{ + [ Schema="DW_fact", Item="Internet Sales" ] + } [Data], + + // The filter step should ideally be able to fold back to the data source + // No steps before this should break query folding + #"Incremental Refresh Filter Step" = + Table.SelectRows( + Navigation, + each + [OrderDate] >= #"RangeStart" and + [OrderDate] < #"RangeEnd" + ) +in + #"Incremental Refresh Filter Step" +``` + +# [RangeStart](#tab/rangestart) + +```M +// It does not matter what the initial value is for the RangeStart parameter +// The parameter must be of data type "datetime" +#datetime(2022, 12, 01, 0, 0, 0) + meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ] +``` + +# [RangeEnd](#tab/rangend) + +```M +// It does not matter what the initial value is for the RangeEnd parameter +// The parameter must be of data type "datetime" +#datetime(2022, 12, 31, 0, 0, 0) + meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ] +``` + +*** + +> [!WARNING] +> Incremental refresh is designed for data sources that support [Power Query query folding](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#:~:text=Incremental%20refresh%20is%20designed%20for%20data%20sources%20that%20support%20query%20folding). Ideally, [query folding shouldn't be broken](https://learn.microsoft.com/en-us/power-query/step-folding-indicators) before the filter step is applied. +> There's no explicit requirement for the final query to fold, except when implementing [Hybrid Tables](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#:~:text=However%2C%20if%20the%20incremental%20refresh%20policy%20includes%20getting%20real%2Dtime%20data%20with%20DirectQuery%2C%20non%2Dfolding%20transformations%20can%27t%20be%20used.). + +--- + +### What is a Refresh Policy? + +A _Refresh Policy_ determines how the data is partitioned, and which of these Policy Range Partitions will be updated upon refresh. It consists of a set of table TOM properties which can be setup or changed. + +> [!WARNING] +> **Power BI Desktop limitations:** Configuring incremental refresh when connected to a local Power BI Desktop model is not supported. To configure incremental refresh for a local Power BI Desktop model, use the Power BI Desktop user interface. + +--- + +### Refresh Policy properties + +Properties of Incremental Refresh + +Four different kinds of properties make up a basic Refresh Policy: + +1. **Incremental window** **properties**: The period window wherein data is _kept up-to-date_. +2. **Rolling window** **properties**: The period window wherein data is _archived_. +3. **Source expressions**: Define table schema and Power Query transformations of the table. +4. **Mode**: Whether `Import` or `Hybrid` tables are used. + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-policy-windows.png) + +--- + +#### Comparing to Power BI Desktop + +In Power BI Desktop, these properties are named differently. Below is an overview of how the properties match the Power BI Desktop user interface. + +![Incremental Refresh Policy Windows Properties](~/content/assets/images/incremental-refresh-window-properties.png) + +--- + +#### Advanced Properties + +Depending on the configured properties, Incremental Refresh may function differently. Below is an overview of the different Incremental Refresh configurations: + +# [Standard (Import)](#tab/import) + +In the standard configuration of Incremental Refresh, all partitions are imported in-memory. Partitions in the rolling window are archived, while those in the incremental window are refreshed. + +# [Hybrid](#tab/hybrid) + +In the **_[hybrid](https://learn.microsoft.com/en-us/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables)_** configuration of Incremental Refresh, the latest policy range partition in the incremental window is queried in real time using DirectQuery. + +This is configured with the Mode property when set to Hybrid. + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-mode-pbi-match.png) + +# [Only Refresh Complete Periods](#tab/completeperiods) + +In this configuration, the policy range will not include the current period in the rolling window. + +In the standard configuration of Incremental Refresh, the current period is always in the incremental window. This might not be the desired behavior, as the data will change with each refresh. If the users do not expect to see partial data for a partial day, you can configure 'Only Refresh Complete Periods'. + +This is configured with the IncrementalPeriodsOffset property. In the above example, a value of -1 for an IncrementalGranularity of Day will exclude the current date from the incremental window and thus the data scope; only complete days will be refreshed. + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-period-offset-pbi-match.png) + +# [Detect Data Changes](#tab/datachanges) + +In this configuration, not all records are refreshed in the incremental window. Instead, records are only refreshed if they change. Detect data changes can further optimize refresh performance when using incremental refresh. To identify data changes you use a _Polling Expression_. A Polling Expression is a separate property that expects a valid M Expression to identify a maximum date from a list of dates. + +Typically, you use the Polling Expression on a DateTime column of a table to identify the latest date. If any records match that date, they'll be refreshed. A common example is using a column like [LastUpdateDt] to label records that were updated or added with the current DateTime value. Any records that have values equal to the latest [LastUpdateDt] are refreshed. + +> [!NOTE] +> Records in archived partitions are _not_ refreshed. + +An example of a valid `Polling Expression` property is below. You can use this as a template when configuring _Detect Data Changes_ in your model from Tabular Editor: + +```M +// Retrieves the maximum value of the column [LastUpdateDt] +let + #"maxDateOfLastUpdate" = + List.max( + Orders[LastUpdateDt] + ), + + accountForNu11 = + if #"maxDateOfLastUpdate" = null + then #datetime(1901, 01, 01, 00, 00, 00) + else #"maxDateOfLastUpdate" +in + accountForNu11 +``` + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-detect-changes-pbi-match.png) + +*** + +#### Overview of all properties + +_Below is an overview of the TOM Properties in a data model used to configure Incremental Refresh:_ + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . +
    Property NamePower BI Desktop EquivalentDescriptionExpected Value
    EnableRefreshPolicyIncrementally refresh this tableWhether a refresh policy is enabled for the table.

    In Tabular Editor, other Refresh Policy properties will only be visible if this value is set to True.
    True or False.
    IncrementalGranularityIncremental Refresh PeriodThe granularity of the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    Day, Month, Quarter or Year. Must be smaller than or equal to the IncrementalGranularity.
    IncrementalPeriodsNumber of Incremental Refresh PeriodsThe number of periods for the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    An integer of the number of IncrementalGranularity periods. Must define a total period smaller than the RollingWindowPeriods
    IncrementalPeriodsOffsetOnly refresh complete daysThe offset to be applied to IncrementalPeriods.

    Example for:
    IncrementalPeriodsOffset=-1;
    IncrementalPeriods = 30;
    IncrementalGranularity = Day:
    "Only refresh data in the last 30 days, from the day before refresh date.
    An integer of the number of IncrementalGranularity periods to shift the Incremental window.
    ModeGet the latest data in real time with DirectQuerySpecifies whether Incremental Refresh is configured with only import partitions or also a DirectQuery partition, to result in a "Hybrid Table".Import or Hybrid.
    PolicyTypeN/ASpecifies the type of refresh policy.Can only contain a single value: Basic.
    PollingExpression
    (Optional)
    Detect Data ChangesThe M Expression used to detect changes in a specific column such as LastUpdateDate

    In Tabular Editor, the Polling Expression can be viewed and modified from the Expression Editor window by selecting it from the dropdown menu in the top-left.
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Property NamePower BI Desktop EquivalentDescriptionExpected Value
    EnableRefreshPolicyIncrementally refresh this tableWhether a refresh policy is enabled for the table.

    In Tabular Editor, other Refresh Policy properties will only be visible if this value is set to True.
    True or False.
    IncrementalGranularityIncremental Refresh PeriodThe granularity of the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    Day, Month, Quarter or Year. Must be smaller than or equal to the IncrementalGranularity.
    IncrementalPeriodsNumber of Incremental Refresh PeriodsThe number of periods for the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    An integer of the number of IncrementalGranularity periods. Must define a total period smaller than the RollingWindowPeriods
    IncrementalPeriodsOffsetOnly refresh complete daysThe offset to be applied to IncrementalPeriods.

    Example for:
    IncrementalPeriodsOffset=-1;
    IncrementalPeriods = 30;
    IncrementalGranularity = Day:
    "Only refresh data in the last 30 days, from the day before refresh date.
    An integer of the number of IncrementalGranularity periods to shift the Incremental window.
    ModeGet the latest data in real time with DirectQuerySpecifies whether Incremental Refresh is configured with only import partitions or also a DirectQuery partition, to result in a "Hybrid Table".Import or Hybrid.
    PolicyTypeN/ASpecifies the type of refresh policy.Can only contain a single value: Basic.
    PollingExpression
    (Optional)
    Detect Data ChangesThe M Expression used to detect changes in a specific column such as LastUpdateDate

    In Tabular Editor, the Polling Expression can be viewed and modified from the Expression Editor window by selecting it from the dropdown menu in the top-left.
    A valid M Expression that returns a scalar value of the latest date in a column. All records in incremental window hot partitions containing that value for the column will be refreshed.

    Records in archived partitions are not refreshed.
    RollingWindowGranularityArchive Data PeriodThe granularity of the rolling window.

    Example:
    "Archive data starting 3 years before refresh date."
    Day, Month, Quarter or Year. Must be larger than or equal to the IncrementalGranularity.
    RollingWindowPeriodsNumber of Archive Data PeriodsThe number of periods for the rolling window.

    Example:
    "Archive data starting 3 years before refresh date."
    An integer of the number of RollingWindowGranularity periods. Must define a total period larger than the IncrementalPeriods
    SourceExpressionPower Query Source ExpressionThe M Expression for the table data source. This is where the original table M Expression is, and where any existing Power Query transformations would be modified.

    In Tabular Editor, the Source Expression can be viewed and modified from the Expression Editor by selecting it from the dropdown menu in the top-left.
    A valid M Expression containing a filter step appropriately using RangeStart and RangeEnd.
    + \ No newline at end of file diff --git a/content/localization/de/incremental-refresh-modify_de.md b/content/localization/de/incremental-refresh-modify_de.md new file mode 100644 index 00000000..18fa34a6 --- /dev/null +++ b/content/localization/de/incremental-refresh-modify_de.md @@ -0,0 +1,199 @@ +--- +uid: incremental-refresh-modify +title: Modify an Existing Refresh Policy +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Modifying Incremental Refresh + +![Incremental Refresh Visual Abstract](~/content/assets/images/incremental-refresh-modify-a-refresh-policy.png) + +--- + +**Incremental Refresh is changed by adjusting the Refresh Policy properties.** Depending on what you want to change, you will adjust a different property. A full overview of these properties is [here](xref:incremental-refresh-about#overview-of-all-properties). + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +## Change Incremental Refresh + +Below is a general description of how you modify an existing Refresh Policy: + +1. **Connect:** Connect to the model. + +2. **Select the Table:** Select the table already configured for Incremental Refresh. + +3. **Find 'Refresh Policy' properties:** In the _Properties_ window, go to the _Refresh Policy_ section. + + Properties of Incremental Refresh + +4. **Change the property:** Change the **Property** specified in the below sections, depending on what you want to change. For an overview of all Refresh Policy properties and what they do, see [here](xref:incremental-refresh-about#overview-of-all-properties). + +5. **Apply Changes:** Deploy the model changes. + +6. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. + + Apply Refresh Policy + +7. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + + Refresh All Partitions + +--- + +Below is an overview of common changes one might make to an existing Refresh Policy: + +### Extend or Reduce the Window for Archived Data + +**Purpose:** Add or reduce the amount of data in the model. + +**Property:** _RollingWindowPeriods_. Increase to extend the window (more data); decrease to reduce the window (less data). + +**Note:** You can also change the _RollingWindowGranularity_ to make a more fine-grain selection, i.e. from 3 Years to 36 Months. + +

    + +--- + +

    + +### Extend or Reduce the Window for Refreshed Data + +**Purpose:** Add or reduce the amount of data being refreshed in a scheduled refresh operation. + +**Property:** _IncrementalWindowPeriods_. Increase to extend the window (more data); decrease to reduce the window (less data). + +**Note:** You can also change the _IncrementalWindowGranularity_ to make a more fine-grain selection, i.e. from 3 Years to 36 Months. + +

    + +--- + +

    + +### Only Refresh Complete Periods + +**Purpose:** Exclude partial (incomplete) periods from the Rolling Window + +**Property:** _IncrementalWindowPeriodsOffset_. Set the value to `-1` to offset the period by 1, excluding the current period. + +**Note:** You can further offset this window to refresh i.e. only the periods behind the most recent complete period. + +

    + +--- + +

    + +### Change Incremental Refresh Mode + +**Purpose:** To change from `Import` to `Hybrid` tables, or vice-versa. + +**Property:** _Mode_ + +**Note:** Follow the below process to change Incremental Refresh Mode: + +1. Change _Mode_ to the desired value `Import` or `Hybrid` +2. Right-click the table and select _Apply Refresh Policy_ +3. Deploy the model changes +4. Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +> [!NOTE] +> It is recommended to check that the Rolling Window is appropriately set for the selected _Mode_. When switching from `Import` to `Hybrid` Mode, the latest Policy Range Partition will become the DirectQuery partition. You may wish to opt for a more fine-grain window, to limit the amount of data queried with DirectQuery. + +

    + +--- + +

    + +### Configure 'Detect Data Changes' + +**Purpose:** To configure that archived data will refresh if the value of a date column (i.e. _LastUpdate_) changes. + +**Property:** _PollingExpression_. Add a valid M Expression which returns a maximum date value for a column. All records containing that date will be refreshed, irrespective of their partition. + +**Note:** Follow the below process to configure 'Detect Data Changes': + +1. When the table is selected, in the _Expression Editor_ window, select _Polling Expression_ from the top-left dropdown +2. Copy in the below M Expression, replacing _LastUpdate_ with your desired column name. + +```M +// Retrieves the maximum value of the column [LastUpdate] +// Replace LastUpdate with your own column name +// The data will refresh for any records where the value in this column +// equals the maximum value in the column across the entire table +let + #"maxLastUpdate" = + List.Max( + // Replace the below with your column and table name + Orders[LastUpdate] + ), + + accountForNu11 = + if #"maxLastUpdate" = null + then #datetime(1901, 01, 01, 00, 00, 00) + else #"maxLastUpdate" +in + accountForNu11 +``` + +3. Right-click the table and select _Apply Refresh Policy_ +4. Deploy the model changes +5. Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +> [!WARNING] +> Any records will update if the value equals the maximum value in the column. It does not necessarily update explicitly because the value has changed, or if the value equals the refresh date. + +

    + +--- + +

    + +### Applying refresh policies with `EffectiveDate` + +If you want to generate partitions while overriding the current date (for purposes of generating different rolling window ranges), you can use a small script in Tabular Editor to apply the refresh policy with the [EffectiveDate](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#optional-parameters) parameter. + +With the incremental refresh table selected, run the following script in Tabular Editor's _'New C# Script'_ pane instead of applying the refresh policy by right-clicking the table. + +```csharp +// Todo: replace with your effective date +var effectiveDate = new DateTime(2020, 1, 1); +Selected.Table.ApplyRefreshPolicy(effectiveDate); +``` + +

    + +Effective Date + +

    + +--- + +

    + +### Disabling Incremental Refresh + +**Purpose:** To disable a refresh policy because it is not needed or the use-case no longer fits. + +**Property:** _EnableRefreshPolicy_ + +**Note:** To disable Incremental Refresh, follow the below steps: + +1. **Copy the _Source Expression_:** With the table selected, in the _Expression Editor_ window, select _Source Expression_ from the top-left dropdown. Copy the _Source Expression_ to a separate text editor window. +2. **Disable the Refresh Policy:** Change _EnableRefreshPolicy_ to `False` +3. **Remove all Policy Range partitions:** Select and delete all of the Policy Range partitions +4. **Create a new M Partition:** Right-click the table and select _Create > New Partition_. Set the partition _kind_ property to `M`. +5. **Paste the _Source Expression_:** Copy the _Source Expression_ from **Step 6** into the _Expression Editor_ as the _M Expression_ when selecting the new partition. +6. **Apply Changes:** Deploy the model changes. +7. **Refresh the Table:** Select and right-click the table. Select _Refresh > Full refresh (table)_. You can right-click the table and select _'Preview data'_ to see the result. diff --git a/content/localization/de/incremental-refresh-schema_de.md b/content/localization/de/incremental-refresh-schema_de.md new file mode 100644 index 00000000..f0863a30 --- /dev/null +++ b/content/localization/de/incremental-refresh-schema_de.md @@ -0,0 +1,138 @@ +--- +uid: incremental-refresh-schema +title: Add or Remove Columns in a Table that uses Incremental Refresh +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Modifying Incremental Refresh Table Schemas + +![Incremental Refresh Workspace Mode Visual Abstract](~/content/assets/images/incremental-refresh-update-schema-header.png) + +--- + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +**When adding or removing columns from a table configured with Incremental Refresh, you must update the table schema.** Generally, this follows the same protocol as updating table schemas for single-partition tables. Tabular Editor can detect and update the schema for you, automatically: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. + + Update Table Schema + +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. + + Apply Refresh Policy + +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + + Refresh All Partitions + +--- + +### Schema Update Considerations with Incremental Refresh + +- For Incremental Refresh, the main consideration is that **all partitions must be refreshed**.
    To do this, **select and right-click all partitions. Select _Refresh > Full refresh (partition)_**. + +- A second consideration is **the _Source Expression_ and _Polling Expression_ may need to be updated to reflect schema changes**. Not updating these M Expressions may result in refresh errors. Examples: + - `Table.TransformColumnTypes` step refers to a column that will be removed in the updated schema. + - `Table.SelectColumns` step lists columns to be kept; the new column is not added to this list. + +
    +
    CHECK M EXPRESSIONS BEFORE UPDATING THE TABLE SCHEMA
    +

    If schema changes arise from the Data Source, you may still need to apply changes to your Power Query Source Expression or Polling Expression. It is recommended that you carefully check these expressions before using 'Update table schema...'

    +
    + +--- + +### Removing Columns + +Depending on where the column is removed, you may follow a slightly different protocol: + +# [Supported Data Source](#tab/removingfromsource) + +For columns removed in the **data source** (i.e. removed from the view accessed by Power BI), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Power Query](#tab/removingfrompq) + +For columns removed via **Power Query** (i.e. using `Table.RemoveColumns`), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Unsupported Data Source](#tab/removingfromunsupportedsource) + +If you are **unable to automatically update the table schema** using _'Update table schema...'_ from the table context menu, follow the below steps. These steps are the same for both columns removed in the data source or in Power Query. + +1. **Select the Source Expression:** With the table selected, in the _Expression Editor_ window, select _Source Expression_ from the top-left dropdown. +2. **Update the Power Query Expressions:** Check and remove any named references to the removed column, if applicable. If the column is being excluded via Power Query, you can make the appropriate changes, here. +3. **Manually update the schema:** Delete the data column object from the table. +4. **Apply changes:** Deploy the model changes. +5. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +6. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +*** + +
    +
    DELETED COLUMN OBJECTS MAY STILL BE QUERIED
    +

    Deleting column objects from the model does not prevent them from being queried if they still exist in the source and are not removed in the Native Query or Source Expression. Columns queried but not used can have a negative impact on refresh time and resource usage. It is recommended that you remove columns from both metadata and either data sources (i.e. views) or in the Source Expression.

    +
    + +--- + +### Adding Columns + +Depending on where the column is added, you may follow a slightly different protocol: + +# [Supported Data Source](#tab/addingfromsource) + +For columns removed in the **data source** (i.e. added to the view accessed by Power BI), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Power Query](#tab/addingfrompq) + +For columns removed via **Power Query** (i.e. using `Table.AddColumns`), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Unsupported Data Source](#tab/addingfromunsupportedsource) + +If you are **unable to automatically update the table schema** using _'Update table schema...'_ from the table context menu, follow the below steps. These steps are the same for both columns removed in the data source or in Power Query. + +1. **Select the Source Expression:** With the table selected, in the _Expression Editor_ window, select _Source Expression_ from the top-left dropdown. +2. **Update the Power Query Expressions:** Check and remove any named references to the removed column, if applicable. If the column is being excluded via Power Query, you can make the appropriate changes, here. +3. **Manually update the schema:** Right-click the table and select _Create > Data column_. Name the column appropriately. +4. **Configure the new column:** Set the column's `data type` property, appropriately. Set the `Source Column` property such that it matches the source. Any additional properties can also be configured (i.e. `Format String`, `SummarizeBy`, `Data Category`...) and the column can be added to the appropriate display folder. +5. **Apply changes:** Deploy the model changes. +6. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +7. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +*** \ No newline at end of file diff --git a/content/localization/de/incremental-refresh-setup_de.md b/content/localization/de/incremental-refresh-setup_de.md new file mode 100644 index 00000000..e24832f2 --- /dev/null +++ b/content/localization/de/incremental-refresh-setup_de.md @@ -0,0 +1,259 @@ +--- +uid: incremental-refresh-setup +title: Set Up a New Refresh Policy +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Setting up Incremental Refresh + +![Incremental Refresh Setup Visual Abstract](~/content/assets/images/incremental-refresh-setup-refresh-policy.png) + +--- + +To set up Incremental Refresh, you must configure a new Refresh Policy for the table. This is easily done by configuring the Refresh Policy properties once _EnableRefreshPolicy_ is set to `True`: + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. +> For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +### Configure a New Refresh Policy + +1. **Connect to the model:** Connect to the Power BI XMLA endpoint of your workspace, and open the dataset upon which you want to configure Incremental Refresh. +2. **Create the `RangeStart` and `RangeEnd` Parameters:** Incremental refresh requires the `RangeStart` and `RangeEnd` parameters to be created ([more information](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-configure#create-parameters)). Add two new Shared Expressions in Tabular Editor: + +Apply Refresh Policy + +3. **Configure the `RangeStart` and `RangeEnd` Parameters:** Name them `RangeStart` and `RangeEnd` respectively, set their `Kind` property to "M" and set their expression to the following (the actual date/time value you specify doesn't matter, as it will be set by Power BI Service when starting the data refresh): + +```M +#datetime(2021, 6, 9, 0, 0, 0) + meta + [ + IsParameterQuery=true, + Type="DateTime", + IsParameterQueryRequired=true + ] +``` + +Apply Refresh Policy + +4. **Copy Partition M Code**: Navigate to the table for which you want to configure incremental refresh. Fold it out and select your partition containing your Power Query M Expression. Copy your code to Notepad, you will need it in step 6. + +5. **Enable the Table Refresh Policy:** In the _'Properties'_ window, set the `EnableRefreshPolicy` property on the table to `True`: + +Apply Refresh Policy + +6. **Configure the Table Refresh:** Next, select the table for which you want to configure incremental refresh. In the **Expression Editor** window, Select **'Source Expression'** from the dropdown, insert your Power Query M Expression from step 4 and alter the Power Query M Expression such that there is a filter step on the date column for which you will enable incremental refresh. + + _An example of one such valid filter step is below:_ + +```M +// The filter step must be able to fold back to the data source +// No steps before this should break query folding +#"Incremental Refresh Filter Step" = + Table.SelectRows( + Navigation, + each + [OrderDate] >= #"RangeStart" and + [OrderDate] < #"RangeEnd" + ) +``` + +Columns that are of date, string or integer types can still be filtered while maintaining query folding using functions that convert `RangeStart` or `RangeEnd` to the appropriate data type. For more information about this, see [here](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#supported-data-sources) + +7. **Configure Refresh Policy:** Configure the remaining properties according to the incremental refresh policy you need. Remember to specify an M expression for the `SourceExpression` property (this is the expression that will be added to partitions created by the incremental refresh policy, which should use the `RangeStart` and `RangeEnd` parameters to filter the data in the source). The = operator should only be applied to either RangeStart or RangeEnd, but not both, as data may be duplicated. + + - **Source Expression:** The M Expression that be added to partitions created by the Refresh Policy. + - **IncrementalWindowGranularity:** The granularity of the incremental (refresh) window. + - **IncrementalWindowPeriods:** # periods (of granularity specified above) wherein data should be refreshed. + - **IncrementalWindowPeriodsOffset:** Set to `-1` to set _'Only Refresh Complete Periods'_ + - **RollingWindowGranularity:** The granularity of the rolling (archive) window. + - **RollingWindowPeriods:** # periods (of granularity specified above) wherein data should be archived. + - **Mode:** Whether it is standard `Import` Refresh Policy or `Hybrid`, where the last partition is DirectQuery. + - **PollingExpression:** A valid M Expression configured to detect data changes. For more information about _Polling Expression_ or other Refresh Policy properties, see [here](xref:incremental-refresh-about#overview-of-all-properties). +8. **Apply Model Changes:** Save your model (Ctrl+S). +9. **Apply Refresh Policy:** Right-click on the table and choose "Apply Refresh Policy". + +Apply Refresh Policy + +**That's it!** At this point, you should see that the Power BI service has automatically generated the partitions on your table, based on the policy you specified. All that's left is to refresh all the partitions. + +Refresh All Partitions + +10. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + + Refresh All Partitions + +Finally, you can configure the scheduled refresh in Power BI Service. Power BI will automatically handle the partitioning of your table. You can always connect to the remote model to view and validate the partitions, i.e. using the VertiPaq Analyzer. + +------------- + +### Incremental Refresh with Integer Date Keys + +If your date column is Integer data type, use the below in the place of the filter Step 4, above: + +1. **Create the custom function:** Create a Shared Expression named `ConvertDatetimeToInt`: + +```M + // A custom M function which will return a DateTime value as a YYYYMMDD integer + (DateValue as datetime) => + Date.Year(DateValue) * 10000 + Date.Month(DateValue) * 100 + Date.Day(DateValue) +``` + +2. **Create the filter step:** Use the custom function to convert `RangeStart` and `RangeEnd` in-line to Integer. The filter step is otherwise identical to if the Date column would be a DateTime column: + +```M +let + // Connect to your data source + Source = + Sql.Database(#"SqlEndpoint", #"Database"), + +// Load the table data + Data = + Source{ [Schema="Factview", Item="Orders"] }[Data], + + // Make any transformations that should fold back to the data source + #"Remove Unnecessary Columns" = + Table.RemoveColumns ( + Data, + { + "DWCreatedDate", + "Net Invoice Cost" + } + ), + + // Add incremental refresh filter step + // The filter step must be able to fold back to the data source + // No steps before this should break query folding + #"Incremental Refresh" = + Table.SelectRows( + #"Remove Unnecessary Columns", + each [OrderDateKey] >= ConvertDatetimeToInt(#"RangeStart") + and [OrderDateKey] < ConvertDatetimeToInt(#"RangeEnd") + ) +in + #"Incremental Refresh" +``` + +3. **Proceed as normal with the next steps:** You can then proceed with configuring and applying the refresh policy with _'Apply refresh policy'_ and finally refreshing all partitions. Preview the data of the table after the refresh operations complete to see the result. + +------------- + +### Incremental Refresh with String Date Keys + +If your date column is of String data type, you should configure your filter step to parse the Date column without breaking query folding. This will vary depending on your source and how the date is formatted. Below is a hypothetical example for an Order Date formatted 'YYYY-MM-DD': + +```M +let + // Connect to your data source + Source = + Sql.Database(#"SqlEndpoint", #"Database"), + + // Load the table data + Data = + Source{ [Schema="Factview", Item="Orders"] }[Data], + + // Make any transformations that should fold back to the data source + #"Remove Unnecessary Columns" = + Table.RemoveColumns ( + Data, + { + "DWCreatedDate", + "Net Invoice Cost" + } + ), + + // Add incremental refresh filter step + // The filter step must be able to fold back to the data source + // No steps before this should break query folding + #"Incremental Refresh" = + Table.SelectRows( + #"Remove Unnecessary Columns", + each + + // Converts "2022-01-09" to DateTime, for example + DateTime.From( + Date.FromText( + [OrderDate], + [Format="yyyy-MM-dd"] + ) + ) >= #"RangeStart" + + and + + DateTime.From( + Date.FromText( + [OrderDate], + [Format="yyyy-MM-dd"] + ) + ) < #"RangeEnd" + ) +in + #"Incremental Refresh" +``` + +See also the documentation for the `Date.FromText` function in Power Query [here](https://learn.microsoft.com/en-us/powerquery-m/date-fromtext). Should it not be possible to convert the Date column in-line while preserving query folding, it is also possible to configure incremental refresh with a native query, as described in the section, below. + +------------- + +### Incremental Refresh with Native Queries + +If you have configured a native query, it may still be possible to configure and use incremental refresh, depending on your data source. To try this for yourself, you need to follow the following steps in the place of Step 4, above: + +1. **Author and Save the Native Query:** Write your native query in SQL Server Management Studio or Azure Data Studio. Include a placeholder `WHERE` clause which filters >= a DateTime parameter, and < another DateTime parameter. + + Refresh All Partitions + +2. **Replace the Native Query String in the Source Expression:** Copy the query and replace the existing query, which will be full of characters like (lf) (line feed), (cr) (carraige return) and (n) (new line). Doing this makes the query actually readable and editable without resorting to the Native Query user interface of Power BI Desktop. + +Refresh All Partitions + +Replace the above text in the `Query` parameter to the below, for example: + +Refresh All Partitions + +3. **Add `RangeStart` and `RangeEnd`:** Concatenate "RangeStart" and "RangeEnd" inside of the `WHERE` clause, replacing the placeholder fields and converting the parameters to date with `Date.From` and to string data types using `Date.ToText` with the `Format` option set to `"yyyy-MM-dd`. Don't forget to include single quotes `'` on either side of the concatenation. Below is an example of what the final query would look like: + +```M +// Example of a full native query that folds and works with Incremental Refresh +let + Source = Sql.Database("yoursql.database.windows.net", "YourDatabaseName", + [Query=" + +SELECT + [OrderDateKey] + ,[DueDateKey] + ,SUM([OrderQuantity]) AS 'TotalOrderQuantity' + ,SUM([SalesAmount] ) AS 'TotalSalesAmount' + ,[CustomerKey] + ,[ProductKey] +FROM [DW_fact].[Internet Sales] +WHERE + CONVERT(DATE, CONVERT(VARCHAR(8), [OrderDateKey])) + >= CONVERT(DATE, '" & Date.ToText(Date.From(#"RangeStart"), [Format="yyyy-MM-dd"]) & "') + AND + CONVERT(DATE, CONVERT(VARCHAR(8), [OrderDateKey])) + < CONVERT(DATE, '" & Date.ToText(Date.From(#"RangeEnd"), [Format="yyyy-MM-dd"]) & "') +GROUP BY + [OrderDateKey] + ,[DueDateKey] + ,[CustomerKey] + ,[ProductKey] + +"]) +in + Source +``` + +4. **Validate the new M Expression:** You can attempt to save the changes to the table M Expression prior to enabling the refresh policy, to see if you get the expected results when setting the `RangeStart` and `RangeEnd` to specific values. If so, you can proceed as normal; Power BI will be able to handle the partitioning as expected if you configured the steps in Power Query. + + It may not be necessary, but depending on the transformations in the native query, you may also try adding the parameter `[EnableFolding = True]` as described in [this article by Chris Webb](https://blog.crossjoin.co.uk/2021/02/21/query-folding-on-sql-queries-in-power-query-using-value-nativequery-and-enablefoldingtrue/). + +5. **Proceed as normal with the next steps:** You can then proceed with configuring and applying the refresh policy with _'Apply refresh policy'_ and finally refreshing all partitions. Preview the data of the table after the refresh operations complete to see the result. diff --git a/content/localization/de/incremental-refresh-workspace-mode_de.md b/content/localization/de/incremental-refresh-workspace-mode_de.md new file mode 100644 index 00000000..d04ec253 --- /dev/null +++ b/content/localization/de/incremental-refresh-workspace-mode_de.md @@ -0,0 +1,51 @@ +--- +uid: incremental-refresh-workspace-mode +title: Using Workspace Mode on a Model with Incremental Refresh +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise + versions: + - version: 2.X + - version: 3.4.2 and earlier +--- + +# Workspace mode and incremental refresh + +> [!IMPORTANT] +> This article only applies to versions 3.4.2 and earlier of Tabular Editor. +> Since the 3.5.0 update, _Workspace Mode_ will not overwrite deployed Refresh Policy partitions from scheduled refreshes. +> Refresh policy partitions will also not be serialized in source control. You can change this setting in _'Tools > Preferences... > Save-to-Folder'_. + +--- + +![Incremental Refresh Workspace Mode Visual Abstract](~/content/assets/images/incremental-refresh-workspace-mode.png) + +--- + +Incremental Refresh creates new partitions upon the first scheduled refresh in a day. As a result, any local metadata (i.e. `.bim` or `database.json`) will be out-of-sync with the remote model metadata after the refresh. As a result, **when working with a model that has tables configured with Incremental Refresh, _Workspace Mode_ is not recommended**. + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services, custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +### Workspace Mode is not Recommended + +The reason is because _Workspace Mode_ will overwrite the remote model metadata with local metadata files; any out-of-sync changes (like to Policy Range partitions) will be lost. When working with _Workspace Mode_ on these models, you would need to _Apply refresh policy_ for tables using incremental refresh before saving changes every day. + +![Workspace mode can get out of sync with local metadata.](~/content/assets/images/incremental-refresh-workspace-mode-out-of-sync.png) + +### Recommendation: Develop & Deploy from Local Metadata + +**Instead, it is recommended to develop the model from the local metadata files.** Changes can be deployed excluding partitions governed by a Refresh Policy, so there is no risk of overwriting the policies created by Power BI. A second read/refresh instance of Tabular Editor can be connected to the remote model for testing purposes. + +To deploy the model, go _Model > Deploy..._ which opens the Deployment Wizard. Here you can select whether you want to include partitions governed by Incremental Refresh policies: + +![Deploy partitions, avoiding partitions with refresh policies.](~/content/assets/images/incremental-refresh-deploy-partitions.png) + +By deploying the model without these Policy Range partitions, you are mitigating any potential impact due to out-of-sync incremental refresh partitions between the metadata and remote model. \ No newline at end of file diff --git a/content/localization/de/incremental-refresh_de.md b/content/localization/de/incremental-refresh_de.md new file mode 100644 index 00000000..549bb3c7 --- /dev/null +++ b/content/localization/de/incremental-refresh_de.md @@ -0,0 +1,90 @@ +--- +uid: incremental-refresh-policy +title: Incremental Refresh +author: Daniel Otykier +updated: 2021-02-15 +--- + +# Incremental Refresh + +Datasets hosted in the Power BI service can have [Incremental Refresh](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview) set up on one or more tables. To configure or modify Incremental Refresh on a Power BI dataset, you can either use the [XMLA endpoint of the Power BI service directly](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla), or you can use Tabular Editor connected to the XMLA endpoint, as described below: + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +## Setting up Incremental Refresh from scratch with Tabular Editor + +1. Connect to the Power BI XMLA R/W endpoint of your workspace, and open the dataset on which you want to configure Incremental Refresh. +2. Incremental refresh requires the `RangeStart` and `RangeEnd` parameters to be created ([more information](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-configure#create-parameters)), so let's start by adding two new Shared Expressions in Tabular Editor: + ![Add shared expressions](https://user-images.githubusercontent.com/8976200/121341006-8906e900-c920-11eb-97af-ee683ff40609.png) +3. Name them `RangeStart` and `RangeEnd` respectively, set their `Kind` property to "M" and set their expression to the following (the actual date/time value you specify doesn't matter, as it will be set by the PBI service when starting the data refresh): + + ```M + #datetime(2021, 6, 9, 0, 0, 0) meta [IsParameterQuery=true, Type="DateTime", IsParameterQueryRequired=true] + ``` + +![Set kind property](https://user-images.githubusercontent.com/8976200/121342389-dc2d6b80-c921-11eb-8848-b67950e55e36.png) +4. Next, select the table on which you want to enable incremental refresh +5. Set the `EnableRefreshPolicy` property on the table to "true": +![Enable Refresh Policy](https://user-images.githubusercontent.com/8976200/121339872-3842c080-c91f-11eb-8e63-a051b34fb36f.png) +6. Configure the remaining properties according to the incremental refresh policy you need. Remember to specify an M expression for the `SourceExpression` property (this is the expression that will be added to partitions created by the incremental refresh policy, which should use the `RangeStart` and `RangeEnd` parameters to filter the data in the source). The = operator should only be applied to either RangeStart or RangeEnd, but not both, as data may be duplicated. +![Configure Properties](https://user-images.githubusercontent.com/45298358/170603450-8232ad55-0b4a-4ead-b113-786a781f94ad.png) +7. Save your model (Ctrl+S). +8. Right-click on the table and choose "Apply Refresh Policy". +![Apply Refresh Policy](https://user-images.githubusercontent.com/8976200/121342947-78577280-c922-11eb-82b5-a517fbe86c3e.png) + +That's it! At this point, you should see that the Power BI service has automatically generated the partitions on your table, based on the policy you specified. + +![Generated Partitions](https://user-images.githubusercontent.com/8976200/121343417-eef47000-c922-11eb-8731-1ac4dde916ef.png) + +The next step is to refresh the data in the partitions. You can use the Power BI service for that, or you can refresh the partitions in batches using [XMLA/TMSL through SQL Server Management Studio](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla#refresh-management-with-sql-server-management-studio-ssms), or even using [Tabular Editor's scripting](https://www.elegantbi.com/post/datarefreshintabulareditor). + +### Full refresh with incremental refresh policy applied + +If you have applied a refresh policy to your table and wish to perform a full refresh, you must ensure that you set [applyRefreshPolicy to false](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla#override-incremental-refresh-behavior) in your script. This will ensure that you perform a full refresh of all the partitions in your table. +The TMSL Command would in our example look like this: + + ``` + { + "refresh": { + "type": "full", + "applyRefreshPolicy": false + "objects": [ + { + "database": "AdventureWorks", + "table": "Internet Sales" + } + ] + } + } + ``` + +## Modifying existing refresh policies + +You can also use Tabular Editor to modify existing refresh policies that has been set up using Power BI Desktop. Simply follow step 6-8 above in this case. + +## Applying refresh policies with `EffectiveDate` + +If you want to generate partitions while overriding the current date (for purposes of generating different rolling window ranges), you can use a small script in Tabular Editor to apply the refresh policy with the [EffectiveDate](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#optional-parameters) parameter. + +With the incremental refresh table selected, run the following script in Tabular Editor's "Advanced Scripting" pane, in place of step 8 above: + +```csharp +var effectiveDate = new DateTime(2020, 1, 1); // Todo: replace with your effective date +Selected.Table.ApplyRefreshPolicy(effectiveDate); +``` + +![Use scripts to apply refresh policy](https://user-images.githubusercontent.com/8976200/121344362-f9633980-c923-11eb-916c-44a35cf03a36.png) + +## Removing Incremental Refresh using Tabular Editor + +You may need to remove the incremental refresh policy from a table. + +1. Select the table in the TOM view and get the M code from the SourceExpression property and save it somewhere. +2. Change the EnableRefreshPolicy value from TRUE to FALSE. +3. Right-click on the table and create a new M partition. +4. Paste in the M code from step 1 above as the partition's expression. +5. Edit the M code to remove the step that contains the Table.SelectRows() function for the RangeStart/RangeEnd parameters. +6. Delete all of the historical partitions. They have a SourceType of "Policy Range". +7. Refresh the table (Tabular Editor 3) or in the service refresh the dataset to repopulate the table. +8. Optionally delete the RangeStart/RangeEnd shared expressions if there are no other tables in the model with an Incremental Refresh policy set. diff --git a/content/localization/de/index_de.md b/content/localization/de/index_de.md new file mode 100644 index 00000000..8d7df9b3 --- /dev/null +++ b/content/localization/de/index_de.md @@ -0,0 +1,95 @@ +--- +title: Tabular Editor 3 +author: Daniel Otykier +--- + +# Tabular Editor 3 + +This is the documentation site for Tabular Editor 3 - the ultimate productivity tool for Analysis Services and Power BI data models. + +Use the menu on the left side to navigate between topics. + +## Installation + +Download the latest version of Tabular Editor 3 from our [downloads page](xref:downloads). + +## Prerequisites + +None. + +## System requirements + +- **Operating system:** Windows 7, Windows 8, Windows 10, Windows Server 2016, Windows Server 2019 or newer +- **.NET Framework:** [4.7.2](https://dotnet.microsoft.com/download/dotnet-framework) + +## Activating your installation + +Tabular Editor 3 is commercial software. Visit our [home page](https://tabulareditor.com) for pricing details and purchase options. If you haven't previously used Tabular Editor 3 you are eligible to a free 30-day trial. + +The first time you launch Tabular Editor 3 on a new machine, you are prompted to activate the product. + +![Product activation](~/content/assets/images/product-activation.png) + +### Activating using an existing license key + +Once you purchase a license for Tabular Editor 3, you should receive an e-mail with a 25-character string which is your license key. When prompted, enter the license key and hit "Next >" to activate the product. + +![Enter License Key](~/content/assets/images/enter-license-key.png) + +> [!NOTE] +> For multi-user license types, you will need to enter your e-mail address in addition to the license key. Tabular Editor 3 will prompt you to do so, if the license key you enter represents a multi-user license. + +### Requesting a trial license + +If you haven't used Tabular Editor 3 before, you are eligible to a free 30-day trial. When choosing this option, you will be prompted for an e-mail address. We use the e-mail address to validate whether or not you have an existing activation of Tabular Editor 3. + +> [!NOTE] +> Tabular Editor ApS will not sent unsolicited e-mails or forward your e-mail address to third parties, when signing up for a 30-day trial license. View our @privacy-policy for more information. + +### Changing a license key + +When Tabular Editor 3 is activated, you may change your license key in the Help menu by choosing "About Tabular Editor". + +![About Te3](~/content/assets/images/about-te3.png) + +In the dialog, select "Change license key". Note that this option is only available if no model is loaded in Tabular Editor. IF you already loaded a model you can close it under File > Close model. + +#### Registry details + +Tabular Editor 3 uses the Windows Registry to store activation details. + +To view the current license key assigned to the machine, run the following command in the Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG QUERY "HKCU\Software\Kapacity\Tabular Editor 3" /v LicenseKey +``` + +You can also use `regedit.exe` (Windows Registry Editor) and navigate to `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` to view and modify the **LicenseKey** and **User** values. + +A system administrator may also proactively assign Tabular Editor 3 licenses to a machine by specifying the **LicenseKey** and **User** values under each user’s `SOFTWARE\Kapacity\Tabular Editor 3` registry key. + +![Registry Editor](~/content/assets/images/registry-editor.png) + +### Changing a license key through the registry + +If, for any reason, you are unable to change the license key using the procedure outlined above, you can always reset the license assigned to Tabular Editor 3 by using the Registry Editor: + +1. Close all instances of Tabular Editor 3. +2. Open the Registry Editor in Windows (Start > Run > regedit.msc). +3. Locate `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` (see screenshot above). +4. Delete all values within this key. +5. Close the Registry Editor and restart Tabular Editor 3. + +Alternatively, run the following command in a Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG DELETE "HKCU\Software\Kapacity\Tabular Editor 3" /va +``` + +The next time you launch Tabular Editor 3, you will be prompted for a license key, just as when the tool was first installed on the machine. + +## Next steps + +- [Overview of Tabular Editor 3's user interface](xref:user-interface) +- [What's new in Tabular Editor 3](whats-new.md) +- [Tabular Editor 3 Onboarding Guide](xref:onboarding-te3) \ No newline at end of file diff --git a/content/localization/de/installation_de.md b/content/localization/de/installation_de.md new file mode 100644 index 00000000..ae418cba --- /dev/null +++ b/content/localization/de/installation_de.md @@ -0,0 +1,99 @@ +--- +uid: installation-activation-basic +title: Installation, activation and basic configuration +author: Daniel Otykier +updated: 2021-09-30 +--- + +## Installation + +In order to install Tabular Editor 3, download the latest version from our [downloads page](xref:downloads). + +We recommend downloading the MSI 64-bit installer, which is suitable in most scenarios. Once downloaded, doubleclick the MSI file and go through the installation pages. + +![Install](~/content/assets/images/install.png) + +## Activating your installation + +The first time you launch Tabular Editor 3 on a new machine, you are prompted to activate the product. + +![Product activation](~/content/assets/images/product-activation.png) + +### Activating using an existing license key + +Once you purchase a license for Tabular Editor 3, you should receive an e-mail with a 25-character string which is your license key. When prompted, enter the license key and hit "Next >" to activate the product. + +![Enter License Key](~/content/assets/images/enter-license-key.png) + +> [!NOTE] +> For multi-user license types, you will need to enter your e-mail address in addition to the license key. Tabular Editor 3 will prompt you to do so, if the license key you enter represents a multi-user license. + +#### Manual Activation (No Internet) + +If you do not have access to the internet e.g., due to a proxy Tabular Editor will prompt you to do a manual activation. + +![Manual Activation Prompt](~/content/assets/images/Activation_manual_firstprompt.png) + +After entering your email, a dialog box appears with a link to an activation key. +Copy the URL and open it in a web-browser that is connected to the internet. + +The URL returns a JSON object: + +![Manual Activation JSON Object](~/content/assets/images/activation_manual_jsonobject.png) + +Copy the full JSON object and paste the full JSON object given into the dialog box. +Your manual activation dialog should end up looking like below. + +![Manual Activation Filled In](~/content/assets/images/activation_manual_dialogbox_filled.png) + +Your Tabular Editor 3 license will thereby be verified. + +### Changing a license key + +When Tabular Editor 3 is activated, you may change your license key in the Help menu by choosing "About Tabular Editor". + +![About Te3](~/content/assets/images/about-te3.png) + +In the dialog, select "Change license key". Note that this option is only available if no model is loaded in Tabular Editor. IF you already loaded a model you can close it under File > Close model. + +For more details on managing the license keys, see [Registry details](xref:getting-started#registry-details). + +## Basic configuration + +After Tabular Editor 3 is activated, we recommend spending a few minutes familiarizing yourself with the [basic interface](xref:user-interface). In addition, Tabular Editor 3 provides many different configuration options. The default settings are sufficient for most development scenarios, but there are a few important configuration options that you should always review. + +### Check for updates on start-up + +By default, whenever Tabular Editor 3 is launched, the tool will check online to see if a newer version is available. You can control how this update check is performed under **Tools > Preferences > Updates and Feedback**. + +> [!NOTE] +> We recommend always using the latest version of Tabular Editor 3. Our support team will generally assume that you are always using the latest version before submitting a bug report. + +### Opting out of telemetry collection + +Tabular Editor 3 collects anonymous usage data and telemetry, which helps us improve the product. You can opt out at any time by launching Tabular Editor 3 and navigating to **Tools > Preferences > Updates and Feedback**. Uncheck the **Help improve Tabular Editor by collecting anonymous usage data** checkbox to opt out. + +![Collect Telemetry](~/content/assets/images/collect-telemetry.png) + +### Proxy settings + +If you are on a network with limited Internet connectivity, you can specify the address, username and password of a proxy server under **Tools > Preferences > Proxy Settings**. This is required before Tabular Editor 3 can use any features that rely on outgoing web requests. Specifically, these are: + +- Update checks +- Product activation +- DAX Formatting +- Download of Best Practice Rules from external URLs + +> [!TIP] +> The proxy settings can at times interfere with authentication dialog boxes or other external prompts. +> Try to switch the proxy setting between "System" and "None", close and reopen Tabular Editor 3 to verify. + +### Other preferences + +In addition to the settings mentioned above, Tabular Editor 3 contains many other settings for controlling various application behavior, allowing you to closely tailor the tool to your needs. To learn more about other these settings, see @preferences. + +## Next steps + +- @migrate-from-vs +- @migrate-from-desktop +- @migrate-from-te2 \ No newline at end of file diff --git a/content/localization/de/locale-not-supported_de.md b/content/localization/de/locale-not-supported_de.md new file mode 100644 index 00000000..756e7db2 --- /dev/null +++ b/content/localization/de/locale-not-supported_de.md @@ -0,0 +1,59 @@ +--- +uid: locale-not-supported +title: Locale Not Supported +author: Morten Lønskov +updated: 2025-09-02 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +You may encounter the warning message: + +```plaintext +The XXXX locale is not supported +``` + +in the Tabular Editor 3 Message view. + +![Locale not supported message](~/content/assets/images/troubleshooting/locale-not-supported-message-view.png) + +This issue usually occurs when your local machine uses a **regional configuration not supported by the Analysis Services (SSAS) engine**. +In most cases, the error is triggered by another underlying issue or warning, but this message is shown as a result. + +--- + +## Scenarios and Solutions + +### 1. Connecting to a Local SSAS Instance + +If you are running SQL Server Analysis Services (SSAS) locally on your machine: + +- **Solution:** Change the **service account** used by the SSAS instance. + Updating the account often resolves unsupported locale mismatches. + +--- + +### 2. Connecting to a Remote SSAS, Azure AS, or Power BI + +When connecting to a remote instance, you have two possible solutions: + +#### Option A: Specify Locale in the Connection String + +Explicitly set a supported locale (e.g., English – 1033) by adding `LocaleIdentifier=1033` to your connection string. + +**Example (Azure AS):** + +```plaintext +Data Source=asazure://westeurope.asazure.windows.net/instance-name;LocaleIdentifier=1033 +``` + +#### Option B: Change Regional Settings on Your Machine + +Adjust your local system’s regional and language settings to match a supported locale. + +- **Recommended settings:** + - **Regional format:** English (United States) + - **Windows Display Language:** English (United States) diff --git a/content/localization/de/log4j_de.md b/content/localization/de/log4j_de.md new file mode 100644 index 00000000..d3167c24 --- /dev/null +++ b/content/localization/de/log4j_de.md @@ -0,0 +1,19 @@ +--- +uid: log4j +title: Log4j vulnerability +author: Daniel Otykier +updated: 2021-12-15 +--- + +# Log4j vulnerability + +On December 9, 2021, the [Log4j vulnerability](https://logging.apache.org/log4j/2.x/security.html) was uncovered. Naturally, IT organizations worldwide took steps to ensure that affected software was patched immediately. + +For anyone seeking information about whether Tabular Editor is affected by this vulnerability, we hereby state the following: + +> [!IMPORTANT] +> Tabular Editor 2 and Tabular Editor 3 are **not** affected by the Log4j vulnerability. + +No version of Tabular Editor is affected by this vulnerability, since the application itself is a .NET application that does not rely on any Java components. This applies to all versions of Tabular Editor 2 (current and historic major and minor updates), as well as all versions of Tabular Editor 3 (current and historic major and minor updates). + +Should you have any concerns or questions, please reach out to [sales@tabulareditor.com](mailto:sales@tabulareditor.com). \ No newline at end of file diff --git a/content/localization/de/macros-view_de.md b/content/localization/de/macros-view_de.md new file mode 100644 index 00000000..a257b090 --- /dev/null +++ b/content/localization/de/macros-view_de.md @@ -0,0 +1,39 @@ +--- +uid: macros-view +title: Macros view +author: Morten Lønskov +updated: 2023-03-22 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Macros view + +Macros are a powerful feature of Tabular Editor that allow you to automate repetitive tasks or create custom actions for your models. A macro is a script written in C# that can access and manipulate the Tabular Object Model (TOM). + +You can create, edit, run and manage macros from the Macros menu in Tabular Editor. + +> [!TIP] +> You can nest your macros in folders by prefixing your macro name in the following pattern `FolderName\MacroName` + +
    + Macro Window
    Figure 1: Macro window in Tabular Editor. Provides an overview of all your saved Macros
    +
    + +> [!NOTE] +> The macros view displays a list of all macros currently saved in your `%localappdata%\TabularEditor3\MacroActions.json` file. + +- You can delete a macro by clicking on the "X" button at the top left corner of the view. +- You can edit a macro by double-clicking on the list item. This will bring up a [C# script document](xref:csharp-scripts) containing the code that will be executed when the macro is invoked. To save your changes to the macro, click the "Edit Macro..." toolbar button (see screenshot below) or use the **C# Script > Edit Macro...** menu item. +- To create a new macro, start by creating a new [C# script](xref:csharp-scripts), then save it as a macro using the **C# Script > Save as Macro...** menu item. + +
    + Edit Macro Button
    Figure 2: When you have a Macro open you can save it back by choosing "Edit Macro..."
    +
    + +## Next steps + +- @creating-macros diff --git a/content/localization/de/messages-view_de.md b/content/localization/de/messages-view_de.md new file mode 100644 index 00000000..5d117c87 --- /dev/null +++ b/content/localization/de/messages-view_de.md @@ -0,0 +1,42 @@ +--- +uid: messages-view +title: Messages view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Messages view + +The Messages view in Tabular Editor 3 is a tool window that displays various types of messages related to the current dataset. + +> [!TIP] +> You can double-click on a message to jump to the source of the error in the model tree or script editor. + +
    + Message View
    Figure 1: Messages window in Tabular Editor. Provides an overview of all warnings and errors in your dataset
    +
    + +The Messages view will tell you the Source and the object from which the message is being generated. + +There are two types of messages displayed Errors and Warnings + +- Errors: This tab shows any errors that prevent your model from being deployed or saved. For example, if you have an invalid expression in a calculation item or a circular dependency in a relationship. +- Warnings: This tab shows any warnings that does not concur with standards but does not prevent your model from being usable. This is for example having fully qualified measure references. +- + +## Copying Messages + +The message view allows for copying out the error message using Ctrl+C. + +From Tabular Editor 3.23.0 Ctrl+C copies the selected cell by default. Use Ctrl+Shift+C (or Copy Row in right-click menu) for row-level copy. + +> [!TIP] +> Right-click a cell to choose Copy Cell / Copy Row. + +![Message View Copy](~/content/assets/images/messages-view-copy.png) + diff --git a/content/localization/de/metadata-translation-editor_de.md b/content/localization/de/metadata-translation-editor_de.md new file mode 100644 index 00000000..61bd0938 --- /dev/null +++ b/content/localization/de/metadata-translation-editor_de.md @@ -0,0 +1,35 @@ +--- +uid: metadata-translation-editor +title: Metadata Translation Editor +author: Šarūnas Jučius +updated: 2023-04-18 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Metadata Translation Editor + +The **Metadata Translation Editor** provides an overview of the translated names, descriptions and display folders of translatable objects in the model. You can launch the Metadata Translation Editor through the **View** menu. Alternatively, if you only need to edit certain translations, select them in the **TOM Explorer** (hold down CTRL or SHIFT to multi-select), then right-click and choose **Show in metadata translation editor**. + +![Metadata Translation Editor](~/content/assets/images/metadata-translation-editor.png) + +Use the input fields in the metadata translation editor to quickly add/remove or edit translations of object names, descriptions and display folder names for the corresponding language. The first three columns in the editor allow you to change the default names, descriptions and display folder names of objects. You can use Undo (Ctrl+Z) and Redo (Ctrl+Y) the usual way. + +## Metadata Translation Editor toolbar + +While the Metadata Translation Editor is active, the accompanying toolbar provides the following options: + +- ![Metadata Translation Editor New Translation](~/content/assets/images/metadata-translation-editor-add-translation.png) **New translation**: This button adds a new translation to the model. The translation will be displayed in the Metadata Translation Editor. +- ![Metadata Translation Editor Hide Members](~/content/assets/images/perspective-editor-hide-members.png) **Show/Hide hidden objects**: Enable this option if you want to see all objects in the Metadata Translation Editor, including hidden objects. +- ![Metadata Translation Editor Hide Names](~/content/assets/images/metadata-translation-editor-name.png) **Show/Hide names**: Disable this option if you don't want to see the name translation columns in Metadata Translation Editor. +- ![Metadata Translation Editor Hide Descriptions](~/content/assets/images/metadata-translation-editor-description.png) **Show/Hide descriptions**: Disable this option if you don't want to see the description translation columns in Metadata Translation Editor +- ![Metadata Translation Editor Hide Display Folders](~/content/assets/images/perspective-editor-folder.png) **Show/Hide display folders**: Disable this option if you don't want to see the display folder translation columns in Metadata Translation Editor + +## Working with many translations + +If you're working on a model with many translations, it may be impractical to display all of them at once. You can rearrange the display order of translations in the Metadata Translation Editor, by dragging the column headers around, making it easier to compare translations side-by-side. Moreover, you can add/remove translations from the editor at any time, through the right-click context menu: + +![Metadata Translation Editor Columns](~/content/assets/images/metadata-translation-editor-columns-bands.png) \ No newline at end of file diff --git a/content/localization/de/migrate-from-desktop_de.md b/content/localization/de/migrate-from-desktop_de.md new file mode 100644 index 00000000..a0c50756 --- /dev/null +++ b/content/localization/de/migrate-from-desktop_de.md @@ -0,0 +1,236 @@ +--- +uid: migrate-from-desktop +title: Migrating from Power BI Desktop +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Migrating from Power BI Desktop + +If you are already familiar with data modeling concepts in Power BI Desktop, this article is intended to help you migrate your data modeling over to Tabular Editor. Thus, we assume you have a solid understanding of concepts such as the Power Query Editor, imported vs. calculated tables, calculated columns, measures, etc. + +## Power BI and Tabular Editor + +Historically, Tabular Editor was designed as a tool for SQL Server Analysis Services (Tabular) and Azure Analysis Services developer. When Power BI first launched, there was no supported way for third party tools to access the Analysis Services instance hosting the Power BI data model, and so the only way to create and edit a Power BI dataset, was through Power BI Desktop. + +This changed in March 2020, when [Microsoft announced the read/write XMLA endpoint in Power BI Premium](https://powerbi.microsoft.com/en-us/blog/announcing-read-write-xmla-endpoints-in-power-bi-premium-public-preview/). A few months later, it even became possible to use third party tools in conjunction with Power BI Desktop, with the [announcement of the External Tools feature](https://powerbi.microsoft.com/en-us/blog/announcing-public-preview-of-external-tools-in-power-bi-desktop/). + +The availability of the XMLA endpoint in Power BI Premium allows data model developers to leverage their existing skills and tools, and it is not a secret that Microsoft is investing heavily in making [Power BI Premium a superset of Analysis Services](https://community.powerbi.com/t5/Webinars-and-Video-Gallery/Power-BI-Premium-as-a-superset-of-Analysis-Services-the-XMLA/m-p/1434121). In other words, the integration of third party tools, community as well as commercial, with Power BI is something that is here to stay. In fact, Amir Netz, CTO of Microsoft Analytics, made a [joint statement](https://powerbi.microsoft.com/en-us/blog/community-tools-for-enterprise-powerbi-and-analysisservices/) with Marco Russo, founder of SQLBI, to affirm this point. + +Here at Tabular Editor ApS, we firmly believe that Tabular Editor 3 is the best tabular data modeling tool available right now, and thanks to the integrations mentioned above, the tool is no longer reserved for SQL Server or Azure Analysis Services developers. + +Before proceeding, it is important to understand that Tabular Editor can be used in conjunction with Power BI in two very different scenarios: + +- **Scenario 1:** Tabular Editor as an External Tool for Power BI Desktop. +- **Scenario 2:** Tabular Editor with the Power BI Premium XMLA Endpoint. + +> [!IMPORTANT] +> You cannot use Tabular Editor to directly load a .pbix file. For more information, see . + +### Scenario 1: Tabular Editor as an External Tool for Power BI Desktop + +Generally, this scenario is intended for self-service analysts and Power BI Desktop users without access to Power BI Premium, to make certain data modeling operations easier (for example, adding and editing measures), and to unlock advanced modeling options not otherwise available (calculation groups, perspectives and metadata translations). + +External tools connect to the Analysis Services model hosted by Power BI Desktop. This allows the tool to make certain changes to the data model. Currently, however, not all types of data modeling operations are supported by Power BI Desktop. It is important to understand this limitation and how Tabular Editor behaves when used as an external tool for Power BI Desktop. See for more information about this. + +The typical workflow in this scenario, is the following: + +1. Open a .pbit or .pbix file in Power BI Desktop +2. Launch Tabular Editor through the External Tools ribbon +3. Switch back and forth between Tabular Editor and Power BI Desktop, depending on what type of change you need to make. For example, you can add and edit measures through Tabular Editor, but you must use Power BI Desktop if you need to add a new table to the model. +4. Whenever you make a change in Tabular Editor, use **File > Save** (CTRL+S) to write the changes back to Power BI Desktop. +5. When you are done making changes, close Tabular Editor. Then, publish or save the report as usual from within Power BI Desktop. + +> [!NOTE] +> As of October 2021, there is a bug in Power BI Desktop that sometimes prevents Desktop from automatically refreshing the field list and visuals to reflect changes made through external tools. When this happens, saving the .pbix file and reopening it, or manually refreshing a table within the model, usually causes the field list and all visuals to update correctly. + +The [modeling limitations](xref:desktop-limitations) that apply to External Tools are only relevant regarding write operations/model modifications. You can still use Tabular Editor 3's connected features to browse the data within the model through table data previews, Pivot Grids or DAX queries, as described later in this guide. + +### Scenario 2: Tabular Editor with the Power BI Premium XMLA Endpoint + +This scenario is for BI professionals in organizations that use Power BI Premium Capacity or Power BI Premium-Per-User workspaces, who intend to replace Power BI Desktop altogether for purposes of dataset development. + +Essentially, the Power BI Premium XMLA Endpoint exposes an instance of Analysis Services (Tabular). In this scenario, Tabular Editor behaves no different than it would when connected to Azure Analysis Services or SQL Server Analysis Services (Tabular). + +The typical workflow in this scenario, is the following: + +1. When first migrating to Tabular Editor, use the XMLA endpoint to open a Power BI dataset in Tabular Editor, then save the model metadata as a file (Model.bim) or folder (Database.json). See @parallel-development for more information. +2. Going forward, open the model metadata in Tabular Editor from the file or folder you saved in step 1. Optionally use [workspace mode](xref:workspace-mode). +3. Apply changes using Tabular Editor. +4. If using workspace mode, changes should be immediately visible in the Power BI service every time you hit Save (CTRL+S) in Tabular Editor. +5. If not using workspace mode or when done making changes, use Tabular Editor's **Model > Deploy...** option to publish the changes to the Power BI service. + +As the model metadata "source of truth" in this scenario, is the file or folder structure stored on disk, this scenario not only enables parallel development with version control integration, but also continuous integration/continuous deployment (CI/CD) using an automated build server such as Azure DevOps. See for more information. + +> [!WARNING] +> As soon as you apply changes to a Power BI dataset through the Power BI service XMLA endpoint, that dataset can no longer be downloaded as a .pbix file. See [Dataset connectivity with the XMLA endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#power-bi-desktop-authored-datasets) for more information. + +When using Tabular Editor to connect to the dataset through the XMLA endpoint, there are no limitations to the types of write operations/model modifications that can be made. + +The remainder of this article focuses on differences between Power BI Desktop and Tabular Editor for data model development. Some sections only apply to scenario 2, due to the [modeling limitations](xref:desktop-limitations) that apply when using Tabular Editor as an external tool for Power BI Desktop (scenario 1). + +## Tabular Editor 3 user interface + +If you are new to Tabular Editor, we recommend reading through the following resources to understand Tabular Editor 3's user interface: + +- [Getting to know Tabular Editor 3's User Interface](xref:user-interface) +- [TOM Explorer view](xref:tom-explorer-view) +- [Properties view](xref:properties-view) +- [DAX editor](xref:dax-editor) + +## Tabular Editor 3 how-tos + +What follows is a quick walkthrough of how to achieve common tasks in Tabular Editor 3. + +### How to add a measure + +To add a new measure to your model, right-click on the table in the **TOM Explorer** on which you want the new measure to reside, then choose **Create > Measure** (shortcut ALT+1). After the measure is added, you can immediately type the name of the measure. + +![Add Measure](~/content/assets/images/add-measure.png) + +### How to rename a measure + +If you need to edit the name of the measure (or any other object), simply select the measure and hit F2 (or double-click the measure name). If multiple objects are selected, you will see the Batch rename dialog, that makes it easy to rename multiple objects in one go. + +![Batch Rename](~/content/assets/images/batch-rename.png) + +> [!WARNING] +> Changing object names in the data model may cause report visuals to stop working, if the visuals relies on one or more of the objects being renamed. External tools cannot access information about Power BI visuals, so Tabular Editor is not able to warn you before an object that is used in a visual is renamed or deleted. + +### How to create a copy of a measure + +In Tabular Editor 3, you can use the familiar Cut (CTRL+X), Copy (CTRL+C) and Paste (CTRL+V) operations to quickly move around and make copies of objects. You can also drag objects between tables and display folders using the **TOM Explorer**. If you make a mistake along the way, you can use the Undo (CTRL+Z) and Redo (CTRL+Y) options (repeatedly) to navigate back and forth through the history of changes applied. + +### How to modify the DAX expression of a measure + +Locate the measure you want to modify in the **TOM Explorer** and select it. You can toggle the display of hidden objects (CTRL+6) and display folders (CTRL+5) using the toolbar buttons near the top of the TOM Explorer. You may also type the partial name of the measure in the search box, to filter the **TOM explorer**. + +Once the measure is selected, you should see the DAX expression of the measure in the **Expression Editor** and various properties such as `Description`, `Format String`, `Hidden`, etc. in the **Properties** grid. + +![Modify Measure](~/content/assets/images/modify-measure.png) + +To modify the DAX expression, simply place the cursor in the **Expression Editor** and update the DAX code. Hit F6 to automatically format the code. If you select a different object in the TOM Explorer or click the green checkmark button **Expression > Accept** (F5), the expression change is stored locally in Tabular Editor. You can also cancel the modification you made by hitting the red "X", **Expression > Cancel**. If you accidentally hit **Accept**, you can always undo the change by using the **Edit > Undo** (CTRL+Z) option. + +To save your changes back to Power BI Desktop, the Power BI XMLA endpoint, or the file on disk from which the model was loaded, hit **File > Save** (CTRL+S). + +To learn more about the capabilities of the Expression Editor, when writing DAX code, see . + +### How to visualize dependencies between measures + +While a measure is selected in the **TOM Explorer** use the **Measure > Show dependencies** (SHIFT+F12) option. This causes a new window to pop up, visualizing the dependency tree of the DAX expression for that measure. You can switch between viewing both upstream and downstream dependencies. + +![Show Dependencies](~/content/assets/images/show-dependencies.png) + +Double-clicking on an item in the dependencies view navigate to that object in the **TOM Explorer**. + +### How to change the format string of a measure + +Locate the measure you want to modify in the **TOM Explorer** and select it. You can toggle the display of hidden objects (CTRL+6) and display folders (CTRL+5) using the toolbar buttons near the top of the TOM Explorer. You may also type the partial name of the measure in the search box, to filter the **TOM explorer**. + +Once the measure is selected, locate the `Format String` property in the **Properties** grid, expand it, and set the format string properties according to your preferences. Note the dropdown button at the right of the `Format` property. You may also freely enter a format string in the `Format String` property itself. + +![Format String](~/content/assets/images/format-string.png) + +### How to modify the DAX expression of multiple measures + +Tabular Editor 3 allows you to select multiple measures in order to create a **DAX Script**, which lets you modify the DAX expression and various properties of all selected measures at once. + +To create a DAX script based on existing measures, simply select the measures in the **TOM Explorer** (hold down the CTLR key to select multiple objects or hold down the SHIFT key to select a range of objects). Then, right click and hit **Script DAX**. + +![Script Dax](~/content/assets/images/script-dax.png) + +You can add or modify properties such as `Description`, `FormatString`, `Visible`, `DetailRows` and more directly in the script. + +Hit F5 to apply the script to the data model. Note that unlike the **Expression Editor**, navigating to a different object will not automatically apply any changes made to the script. You can still use the **Edit > Undo** (CTRL+Z) option to roll back any changes applied by a DAX script. + +See @dax-script-introduction for more information. + +### How to preview data in a table + +To view the contents of a table (similar to the Data Tab in Power BI Desktop), simply right-click on a table and choose "Preview data". This will open a new tab containing a preview of the table content. You can scroll through all rows of the table, as well as apply sorting or filtering to columns. Unlike Power BI Desktop, you can open as many of these preview tabs as you like and arrange them next to each other in the user interface. The preview also works for tables in [DirectQuery mode](https://docs.microsoft.com/en-us/power-bi/connect-data/desktop-use-directquery) (although the preview will be limited to the first 100 records). + +![Preview Data](~/content/assets/images/preview-data.png) + +> [!NOTE] +> The **Preview data** feature is only available when Tabular Editor is connected to Power BI Desktop or a dataset in the Power BI XMLA endpoint. + +See @refresh-preview-query for more information. + +### How to add a calculation group + +[Calculation Groups](https://docs.microsoft.com/en-us/analysis-services/tabular-models/calculation-groups?view=asallproducts-allversions) are useful for defining and reusing a modified DAX filter context or other type of business logic across all model measures. To add a calculation group using Tabular Editor, simply use the **Model > New Calculation Group** (ALT+7) option. + +![Add Calculation Group](~/content/assets/images/add-calc-group.png) + +Give the calculation group a name, then, while the Calculation Group is selected in the **TOM Explorer**, add new Calculation Items by using the **Calculation Group Table > Create > Calculation Item** option. You can copy (CTRL+C) and paste (CTRL+V) calculation items to speed up this process for additional items. + +![Add Calc Item](~/content/assets/images/add-calc-item.png) + +### How to add a new table + +To add a new table to a model, use the **Model > Import tables...** option. Tabular Editor's [Import Table Wizard](xref:importing-tables) will guide you through the process. + +> [!NOTE] +> Tabular Editor 3 does not support every data source otherwise supported by Power BI. If your model uses a data source not supported by Tabular Editor, the easiest way to import a new table from the same source is to copy an existing table in Tabular Editor (CTRL+C / CTRL+V), and then modify the partition expression and update the table schema as shown below. For this to work, make sure that the **Tools > Preferences > Schema Compare > Use Analysis Services for change detection** option is enabled. See for more information. + +> [!IMPORTANT] +> This option is not available by default when using Tabular Editor as an external tool, since adding/editing tables through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +See @importing-tables-data-modeling for more information. + +### How to modify a Power Query expression on a table + +Power Query (M) expressions that define what is loaded into each table reside in the corresponding table's **Partition**. The partitions can be located in the **TOM Explorer**. When selecting a partition, Tabular Editor displays the M expression for that partition in the **Expression Editor**, allowing you to edit it. After editing and accepting the expression change, you can right-click on the partition in the **TOM Explorer** and choose the **Update table schema...** option in order to detect if the columns imported on the table should be changed, based on the updated Power Query expression. + +![Power Query Update Schema](~/content/assets/images/power-query-update-schema.png) + +> [!NOTE] +> Currently, Tabular Editor 3 does not perform any validation of the partition expression. For Power Query (M) expressions, this is planned for a later update of Tabular Editor 3. + +> [!IMPORTANT] +> Partition expressions are read-only by default when using Tabular Editor as an external tool, since editing partitions through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +If the Power Query expression changes gives rise to any changes on the imported table columns, a dialog that lets you review these changes will show: + +![Apply schema changes](~/content/assets/images/combine-sourcecolumn-update.png) + +### How to modify a shared Power Query expression + +Shared Expressions are M queries that are not directly used to load data into a table. For example, when you create a Power Query parameter in Power BI Desktop, the M expression for this parameter is stored as a Shared Expression. In Tabular Editor, These can be accessed through the Shared Expressions folder of the **TOM Explorer** and edited just like M queries on partitions. + +![Shared Expression](~/content/assets/images/shared-expression.png) + +> [!IMPORTANT] +> Shared expressions are read-only by default when using Tabular Editor as an external tool, since editing partitions through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +### How to add relationships between tables + +The easiest way to add relationships between two tables is to create a new diagram, add the two tables to the diagram, and then visually dragging a column from one table to another, to indicate the columns that should participate in the relationship. This is similar to how you would create a relationship in Power BI Desktop. + +1. To create a new diagram use the **File > New > Diagram** option. +2. To add tables to the diagram, either drag and drop the tables from the **TOM Explorer** or use the **Diagram > Add tables...** option. +3. Once the tables are added, locate the column on the (many-side) fact table, and drag it over to the corresponding column on the (one-side) dimension table. +4. Confirm the relationship settings and hit "OK". + +![Shared Expression](~/content/assets/images/create-relationship-through-diagram.gif) + +See [Working with diagrams](xref:importing-tables-data-modeling#working-with-diagrams) for more information. + +> [!IMPORTANT] +> Relationships cannot be modified when using Tabular Editor as an external tool, since editing relationships through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +### How to publish to the Power BI Service + +To publish or update a dataset in the Power BI Service, use the **Model > Deploy...** option and use the XMLA endpoint of the workspace, in which you want to publish the dataset. + +If you loaded the model metadata directly from the XMLA Endpoint, you only need to hit **File > Save** (CTRL+S), to update the dataset that was loaded in Tabular Editor. + +> [!NOTE] +> The **Model > Deploy...** option is **not** available in Tabular Editor 3 Desktop Edition, as this edition is only intended to be used as an External Tool for Power BI Desktop. [More information](xref:editions). + +## Next steps + +- +- @parallel-development +- @boosting-productivity-te3 +- \ No newline at end of file diff --git a/content/localization/de/migrate-from-te2_de.md b/content/localization/de/migrate-from-te2_de.md new file mode 100644 index 00000000..8dd21802 --- /dev/null +++ b/content/localization/de/migrate-from-te2_de.md @@ -0,0 +1,140 @@ +--- +uid: migrate-from-te2 +title: Migrating from Tabular Editor 2.x +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Migrating from Tabular Editor 2.x + +This article is intended for developers who already have some experience using Tabular Editor 2.x for Power BI Dataset or Analysis Services Tabular development. The article highlights similarities and important feature additions of Tabular Editor 3, to get you quickly up to speed. + +## Installation side-by-side + +Tabular Editor 3 has a different product code than Tabular Editor 2.x. This means that you can install both tools side-by-side without issues. In fact, the tools are installed into separate program folders and their settings are also kept in separate folders. In other words, the term "upgrade" or "downgrade" between Tabular Editor 2.x and Tabular Editor 3 does not apply. It is better to think of Tabular Editor 3 as an entirely different product. + +## Feature comparison + +In terms of features, Tabular Editor 3 is essentially a superset of Tabular Editor 2.x, with few exceptions. The table below compares all major features of the two tools: + +| | Tabular Editor 2.x | Tabular Editor 3 | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | --------------------------------------------------------- | +| Edit all TOM objects and properties | | | +| Batch editing and renaming | | | +| Copy/paste and drag/drop support | | | +| Undo/redo data modeling operations | | | +| Load/save model metadata to disk | | \* | +| Save-to-folder | | \* | +| [daxformatter.com](https://daxformatter.com) integration | | | +| Advanced data modeling (OLS, Perspectives, Calculation Groups, Metadata Translations, etc.) | | \* | +| Syntax highlighting and automatic formula fixup | | | +| View DAX dependencies between objects | | | +| Import Table Wizard | | | +| Deployment Wizard | | \* | +| Best Practice Analyzer | | | +| C# scripting and automation | | | +| Use as External Tool for Power BI Desktop | | | +| Connect to SSAS/Azure AS/Power BI Premium | | \* | +| Command-line interface | | _[Coming soon](xref:roadmap)_ | +| Premium, customizable user-interface with high-DPI, multi-monitor and theming support | | | +| World-class DAX editor with IntelliSenseTM-like features | | | +| Offline DAX syntax checking and column/data type inference | | | +| Improved Table Import Wizard and Table Schema Update check with Power Query support | | | +| DAX querying, table preview and Pivot Grids | | | +| Create diagrams for visualizing and editing table relationships | | | +| Execute data refresh operations in the background | | \* | +| C# macro recorder | | | +| Edit multiple DAX expressions in a single document using DAX scripting | | | +| [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/) integration | | | + +\***Note:** Limitations apply depending on which [edition](xref:editions) of Tabular Editor 3 you are using. + +## Feature differences + +Below is a summary of important feature differences. + +### User interface + +The first thing you will notice when launching Tabular Editor 3, is the new Visual Studio Shell-like interface. This interface is fully customizable, supports high-DPI, multiple monitors and even allows you to change the theming. All interface elements can be moved to different locations, so if you prefer the interface layout of Tabular Editor 2.x, immediately choose **Classic layout** from the **Window** menu. + +In general, though, interface elements that exist in Tabular Editor 2.x have the same name in Tabular Editor 3, so it should be relatively easy to navigate the new interface. A few important differences are listed below: + +- The **Advanced Scripting** tab in Tabular Editor 2.x is gone. In Tabular Editor 3, you instead create _C# Scripts_\* using the **File > New** menu. You are not limited to working on a single script at a time. In addition, **Custom actions** have been renamed to **Macros**. +- **Dynamic LINQ filtering** is not currently available within the TOM Explorer. Instead, if you want to find objects using [Dynamic LINQ](https://dynamic-linq.net/expression-language) you have to bring up the **Find and replace** dialog by pressing CTRL+F. +- If you close the **Expression Editor** you can bring it back by doubleclicking on the icon of an object in the **TOM Explorer**, or by choosing the **View > Expression Editor** menu option. +- When using the default layout in Tabular Editor 3, the **Best Practice Analyzer** will be located as a tab next to the **TOM Explorer**. Here, you will also find the new **Data Refresh** view (which lets you view the queue of background refresh operations) and the **Macros** view (which lets you manage any macros that was previously saved from C# scripts). +- Tabular Editor 3 displays all DAX syntax and semantic errors in the new **Messages View**. In the default layout, this is located at the bottom left of the interface. +- In addition, Tabular Editor 3 includes **VertiPaq Analyzer** (which you may be familiar with from [DAX Studio](https://daxstudio.org/)). +- As a final note, Tabular Editor 3 introduces the concept of **documents**, which is just a generic term for C# scripts, DAX scripts, DAX Queries, Diagrams, Data Previews and Pivot Grids. + +For more information, see . + +### New DAX editor and semantic capabilities + +Tabular Editor 3 features its very own DAX parsing engine (aka. the "semantic analyzer"), which means that the tool now understands the semantics of any DAX code in your model. This engine is also used to power our DAX editor (codename "Daxscilla"), to enable features such as syntax highligting, automatic formatting, code completion, calltips, refactoring and much more. Of course the editor is highly configurable, allowing you to tweak it to match your preferred DAX coding style. + +To learn more about the new DAX editor, see . + +In addition, the semantic analyzer continuously reports any DAX syntax or semantic errors across all objects in your model. This works even if not connected to Analysis Services and is lightning fast. The semantic analyzer also enabled Tabular Editor 3 to automatically infer data types from DAX expressions. In other words, Tabular Editor 3 automatically detects which columns would result from a calculated table expression. This is a big improvement over Tabular Editor 2.x, where you would have to manually map columns on a calculated table, or rely on Analysis Services to return the column metadata. + +### Table Import and Schema Update with Power Query support + +Another major advantage of Tabular Editor 3 over Tabular Editor 2.x is its support for structured data sources and Power Query (M) partitions. Specifically, the "Schema Update" feature now works for these types of data sources and partitions, and the Table Import Wizard can generate the necessary M code when importing new tables. + +The schema compare dialog itself also has a number of improvements, for example allowing you to easily map a column delete+column insert operation to a single column rename operation (and vice versa). There are also options for controlling how floating and decimal data types should be treated (for example, sometimes your data source may be using a floating point data type, but you may still want to import it always as a decimal type). + +To learn more, see . + +### Workspace mode + +Tabular Editor 3 introduces the concept of **workspace mode**, in which model metadata is loaded from disk (Model.bim or Database.json), and then immediately deployed to an Analysis Services instance of your choice. Whenever you hit Save (CTRL+S), the workspace database is synchronized and updated model metadata is saved back to the disk. The advantage of this approach, is that Tabular Editor is connected to Analysis Services, thus enabling the [connected features](#connected-features) listed below, while also making it easy to update the source files on disk. With Tabular Editor 2.x, you had to open a model from a database, and then remember to manually save to disk once in a while. + +This approach is ideal to enable [parallel development](xref:parallel-development) and model metadata integration with version control systems. + +For more information, see . + +### Connected features + +Tabular Editor 3 includes a number of new connected features, allowing you to use it as a client tool for Analysis Services. These features are enabled whenever Tabular Editor 3 is connected to Analysis Services, either directly or when using the [workspace mode](#workspace-mode) feature. + +The new connected features are: + +- Table data previewing +- PivotGrids +- DAX Querying +- Data refresh operations +- VertiPaq Analyzer + +### Diagrams + +One highly requested feature of Tabular Editor 2.x, was the ability to better visualize relationships between tables. With Tabular Editor 3, you can now create model diagrams. Each diagram is a simple JSON file that holds the names and coordinates of tables to be included in the diagram. Tabular Editor 3 then renders the tables and relationships and provides features for easily editing relationships, adding additional tables to the diagram based on existing relationships, etc. + +![Easily add related tables](~/content/assets/images/diagram-menu.png) + +See [Working with diagrams](xref:importing-tables-data-modeling#working-with-diagrams) for more information. + +### C# Scripts and Macro recorder + +The **Advanced Scripting** feature of Tabular Editor 2.x has carried over to Tabular Editor 3 as **C# Scripts**. One important difference in Tabular Editor 3 is that you are no longer limited to working with a single script. Instead, using the **File > New > C# Script** option, you can create and work with as many C# scripts as you need. Similar to Tabular Editor 2.x, these scripts can be saved as reusable actions that are integrated directly into the right-click context menu of the TOM Explorer. In Tabular Editor 3, we call these actions **Macros**, and you can even create your own menus and toolbars to which you can add macros. + +Most importantly, Tabular Editor 3 features a **Macro recorder** that you can use to automatically generate C# code from user interactions. + +To learn more, see @cs-scripts-and-macros. + +### DAX Scripting + +The last important feature you need to know about, when coming from Tabular Editor 2.x, is **DAX Scripting**. With this feature, you can create documents that allow you to edit the DAX expression and basic properties of several calculated objects at once. Calculated objects are measures, calculated columns, calculated tables, etc. + +This is very convenient when authoring complex business logic across several objects. By (multi)selecting objects in the TOM Explorer, right-clicking and choosing the **Script DAX** option, you get a new DAX script containing the definitions of all selected objects. The DAX script editor of course has all of the same DAX capabilities of the Expression Editor and the DAX query editor. + +When working in **connected** or **workspace** mode, DAX scripting is an incredibly powerful tool to quickly modify and test updated business logic, for example when using it in conjunction with a Pivot Grid as shown in the screenshot below. Simply hitting SHIFT+F5 causes the database to be updated based on the DAX expressions in the script, after which the Pivot Grid will immediately update. + +![Dax Scripting And Pivot](~/content/assets/images/dax-scripting-and-pivot.png) + +To learn more, see @dax-script-introduction. + +## Next steps + +- @migrate-from-vs +- @parallel-development +- @boosting-productivity-te3 diff --git a/content/localization/de/migrate-from-vs_de.md b/content/localization/de/migrate-from-vs_de.md new file mode 100644 index 00000000..c1d91379 --- /dev/null +++ b/content/localization/de/migrate-from-vs_de.md @@ -0,0 +1,211 @@ +--- +uid: migrate-from-vs +title: Migrating from Visual Studio +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Migrating from Visual Studio / SQL Server Data Tools + +This article assumes that you are familiar with Tabular model development using [Analysis Services Projects for Visual Studio](https://marketplace.visualstudio.com/items?itemName=ProBITools.MicrosoftAnalysisServicesModelingProjects) (formerly known as SQL Server Data Tools). This is common among developers using SQL Server Analysis Services (Tabular) or Azure Analysis Services. + +- If you have never used Visual Studio for Tabular model development, you can safely skip this topic. +- If you previously used Tabular Editor 2.x for Tabular model development, we recommend you skip directly to the @migrate-from-te2 article. + +## Partial migration + +Tabular Editor 3 contains features that allow you to completely migrate away from Visual Studio for tabular model development. This is in contrast to Tabular Editor 2.x, where some users still preferred using Visual Studio for things like table import, visualization of relationships and preview of data. + +However, as you familiarize yourself with Tabular Editor 3, you might still find it useful to open your tabular models in Visual Studio from time to time. This is possible at any time, since Tabular Editor 3 does not modify the **Model.bim** file format (aka. the [TOM JSON](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions)) used by Visual Studio, thus ensuring compatibility with Visual Studio. + +The only exception is, if you decide to use Tabular Editor's [Save-to-folder](xref:parallel-development#what-is-save-to-folder) feature, as this file format is not supported by Visual Studio. However, you can easily recreate a Model.bim file for use with Visual Studio, using the **File > Save As...** option in Tabular Editor. The opposite conversion can also be performed by loading a Model.bim file in Tabular Editor and then using the **File > Save to Folder...** option. + +### Automating file format conversion + +If you often face the need to convert back and forth between Tabular Editor's (database.json) folder-based format and Visual Studio's (model.bim) file format, consider writing a small Windows command script using [Tabular Editor 2.x CLI](xref:command-line-options) to automate the conversion process. + +# [Model.bim to folder](#tab/frombim) + +To convert from model.bim to database.json (folder-based format): + +```cmd +tabulareditor.exe model.bim -F database.json +``` + +# [Folder to model.bim](#tab/fromfolder) + +To convert from database.json (folder-based format) to model.bim: + +```cmd +tabulareditor.exe database.json -B model.bim +``` + +*** + +> [!NOTE] +> The command line script above assumes you have [Tabular Editor 2.x](xref:getting-started-te2) installed. The installation location of Tabular Editor 2.x should also be specified as part of your [PATH environment variable](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/path). + +## Integrated Workspace server + +When starting a new Analysis Services (Tabular) project in Visual Studio, you are prompted to choose if you want to use Visual Studio's Integrated workspace server or provide your own instance of Analysis Services. In addition, you must decide the compatibility level of the tabular model (see screenshot below). + +![VS New Project](~/content/assets/images/vs-new-project.png) + +In contrast, when creating a new model in Tabular Editor, using a workspace server is completely optional (but recommended - see [workspace mode](xref:workspace-mode)). + +Below is the dialog box shown when creating a new model in Tabular Editor 3: + +![New model dialog](~/content/assets/images/new-model.png) + +If you enable the **Use workspace database** option, Tabular Editor will prompt you for an Analysis Services instance and database name that will be used as as workspace database while working on the model. If you do not enable this option, you will be able to create and work on your model in "offline" mode, which still allows you to add tables, relationships, author DAX expressions, etc. However, you will have to deploy your offline model to an instance of Analysis Services before you can refresh, preview and query the data in the model. + +> [!IMPORTANT] +> Tabular Editor 3 does not provide a feature equivalent to the **Integrated workspace** option of Visual Studio. Essentially, the integrated workspace is an Analysis Services instance managed by Visual Studio. Since Analysis Services is proprietary software from Microsoft, we cannot ship it alongside Tabular Editor 3. Instead, if you would like to run a local instance of Analysis Services for use with Tabular Editor, we recommend that you install [SQL Server Developer Edition](https://www.microsoft.com/en-us/sql-server/sql-server-downloads). + +### Compatibility level requirements + +Tabular Editor lets you choose the following compatibility levels for creating Analysis Services databases: + +- 1200 (Azure Analysis Services / SQL Server 2016+) +- 1400 (Azure Analysis Services / SQL Server 2017+) +- 1500 (Azure Analysis Services / SQL Server 2019+) + +In addition, Tabular Editor lets you choose compatibility levels suitable for Power BI datasets that will be deployed to the Power BI service through the [XMLA endpoint](xref:powerbi-xmla). + +> [!NOTE] +> Tabular Editor does not support compatibility levels below 1200, as these do not use the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) metadata format. If you plan on migrating development from Visual Studio to Tabular Editor for a model in compatibility level 1100 or 1103, **you must upgrade the compatibility level to at least 1200** before migrating to Tabular Editor. By doing so, you will no longer be able to deploy the model to SQL Server 2014 Analysis Services. + +## Visual Studio projects + +When creating an Analysis Services (Tabular) project in Visual Studio, a number of files are created in the project folder next to the Model.bim file. These files contain project- and user-specific information which is not related to the Tabular Object Model (TOM). The screenshot below shows the files resulting from creating a new tabular project in Visual Studio. + +![VS Project File Structure](~/content/assets/images/vs-file-structure.png) + +When migrating to Tabular Editor, you only need to bring the Model.bim file, as the concept of "project" does not exist here. Instead, Tabular Editor simply loads the model metadata directly from the Model.bim file. In some cases, a file called the [Tabular Model User Options (tmuo) file](xref:user-options) is created next to the Model.bim file. This file is used by Tabular Editor to store user- and model specific settings, such as whether or not to use a workspace database, (encrypted) user credentials for data sources, etc. + +To keep the "project" directory clean, we therefore recommend to copy the Model.bim file created by Visual Studio into a new directory, before loading the file in Tabular Editor. + +![Te File Structure](~/content/assets/images/te-file-structure.png) + +If you want to use the [Save-to-folder](xref:parallel-development#what-is-save-to-folder) feature, which is recommended for parallel development and integration with version control systems, now is the time to save the model as a folder from within Tabular Editor (**File > Save To Folder...**). + +![Te Folder Structure](~/content/assets/images/te-folder-structure.png) + +## Version control + +Tabular Editor does not have any integrated version control of model metadata. However, since all model metadata is stored as simple text (JSON) files on the disk, it is straightforward to include the tabular model metadata in any type of version control system. For this reason, most Tabular Editor users prefer to still keep Visual Studio installed, in order to have access to the [Visual Studio Team Explorer](https://docs.microsoft.com/en-us/azure/devops/user-guide/work-team-explorer?view=azure-devops) or, specifically for git, the new [Git Changes window](https://docs.microsoft.com/en-us/visualstudio/version-control/git-with-visual-studio?view=vs-2019) of Visual Studio 2019. + +> [!NOTE] +> These days, it seems that [git](https://git-scm.com/) is the preferred version control system by most developers. Git integration in Tabular Editor 3 is planned for a future update. + +Once you migrate to Tabular Editor, you do not need to keep the original Tabular model project and supporting files created by Visual Studio. You can still use the Visual Studio Team Explorer or Git Changes window to look at code changes, manage version control branches, perform code check-ins, merges, etc. + +Of course, most version control systems also have their own set of tools that you can use without relying on Visual Studio. For example, git has its command line and many popular tools that integrate directly with the Windows Explorer, such as [TortoiseGit](https://tortoisegit.org/). + +### Save-to-folder and version control + +The main advantage of using the [Save-to-folder](xref:parallel-development#what-is-save-to-folder) option, is that the model metadata is broken out into multiple small files, instead of storing everything in a large JSON document. Many properties in the TOM are arrays of objects (for example tables, measures and columns). Since all such objects have explicit names, their order in the array does not matter. Sometimes it happens that the order is changed during serialization to JSON, and this causes most version control system to indicate that a change was made to the file. However, since this ordering does not have any semantic meaning, we should not bother handling merge conflicts that may arise from this type of change. + +With Save-to-folder serialization, the number of arrays used in the JSON files are greatly reduced, as objects that would otherwise be stored as arrays, are now broken out into individual files stored within a subfolder. When Tabular Editor loads the model metadata from disk, it traverses all these subfolders to ensure all objects are deserialized correctly into the TOM. + +As such, Save-to-folder serialization greatly reduces the chance that merge conflicts are ever encountered, when two or more developers make parallel changes to the same tabular model. + +## UI differences + +This section lists the most important differences between the user interfaces of Tabular Editor 3 and Visual Studio for tabular model development. If you are an avid Visual Studio user, you should feel quite comfortable with Tabular Editor 3's user interface. If you would like a more detailed walkthrough, please see . + +### Tabular Model Explorer vs. TOM Explorer + +In Visual Studio, a hierarchical overview of the model metadata can be found in the **Tabular Model Explorer**. + +![Vs Tom Explorer](~/content/assets/images/vs-tom-explorer.png) + +In Tabular Editor, this is called the **TOM Explorer** view. In Tabular Editor, all data modeling generally revolves around locating the relevant objects in the TOM Explorer and then performing certain actions by invoking the right-click context menu, by navigating to the main menu, or by editing object properties in the **Properties** view. In Tabular Editor, you can use intuitive operations such as multi-select, drag-drop, copy-paste and undo-redo for all data modeling operations. + +![Vs Tom Explorer](~/content/assets/images/tom-explorer.png) + +The TOM Explorer in Tabular Editor also has shortcut options for showing/hiding certain types of objects, hidden objects, display folders, and for quickly searching and filtering the metadata hierarchy. + +See @tom-explorer-view for more information. + +### Property Grid + +Both Visual Studio and Tabular Editor include a property grid that allows you to edit most object properties of whatever object is currently selected. Below is a comparison between the Visual Studio property grid (left) and the Tabular Editor property grid (right) for the same measure: + +![Property grid in Visual Studio and Tabular Editor](~/content/assets/images/property-grid-vs-te.png) + +The two generally work the same way, except that Tabular Editor uses property names that are closely aligned with the TOM object properties. Tabular Editor also adds a number of properties that are not found in the TOM, to make certain modeling operations easier. For example, by expanding the **Translated Names** property, you can compare and edit object name translations across all model cultures. + +### Editing DAX expressions + +In Visual Studio, you can use the formula bar or open a DAX editor window by right-clicking on a measure in the Tabular Model Explorer and choosing "Edit formula". + +Tabular Editor works quite similar, with the formula bar being replaced by the **Expression Editor** view. In addition, if you want to edit the DAX expressions for one or more objects in a standalone document, you can right-click on those objects (measures, calculated columns, calculated tables), and choose **Script DAX**. + +The DAX code editor in Tabular Editor 3 is one of the main reasons for using the tool. You can read more about it [here](xref:dax-editor). + +### Error List vs. Messages View + +In Visual Studio, DAX syntax errors are shown as warnings within the **Error List** (see screenshot below). In addition, measures that have errors are indicated with a warning triangle in the measures grid. + +![Vs Error List](~/content/assets/images/vs-error-list.png) + +In Tabular Editor, we use the Messages View to consolidate all error, warning and informational messages posted by different sources during model development. Specifically for DAX syntax errors, these are shown as errors in the Messages View, and any measures that have an error are indicated with a red dot in the TOM Explorer (see screenshot below). + +![Te Messages](~/content/assets/images/te-messages.png) + +In the screenshot above, notice how there are three different message-posting sources: + +- **Analysis Services**: When metadata changes are saved to a connected instance of Analysis Services, the server updates the TOM metadata to indicate if any objects are in an erroneous state. Specifically, the [State](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.measure.state?view=analysisservices-dotnet#Microsoft_AnalysisServices_Tabular_Measure_State) and [ErrorMessage](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.measure.errormessage?view=analysisservices-dotnet#Microsoft_AnalysisServices_Tabular_Measure_ErrorMessage) properties are updated. Tabular Editor displays these error messages in the Messages View. These messages are not shown when Tabular Editor is used offline (i.e. without a connection to Analysis Services). +- **Tabular Editor Semantic Analysis**: In addition, Tabular Editor 3 performs its own semantic analysis of all DAX expressions in the model. Any syntax or semantic errors encountered are reported here. +- **Expression Editor**: Lastly, if any documents are open in Tabular Editor 3, such as the Expression Editor, any DAX syntax or semantic errors encountered in the document are reported here. + +### Previewing table data + +In Visual Studio, tables and their content are displayed in a tabbed view once you load the Model.bim file. In Tabular Editor 3, you can preview table data by right-clicking on a table in the TOM Explorer, and chooseing **Preview Data**. This opens a new document tab that lets you scroll through all rows of the table, as well as filter and sort the columns. It even works for model using DirectQuery! + +Also, you can freely rearrange the documents, to view the content of several tables at once (see screenshot below). + +![Te3 Table Preview](~/content/assets/images/te3-table-preview.png) + +### Importing tables + +To import new tables with Tabular Editor 3, use the **Model > Import tables...** option. This launches Tabular Editor 3's Import Table Wizard, which guides you through the process of connecting to a data source and selecting tables to import. The process is relatively similar to the legacy table import in Visual Studio. + +One important difference is that Tabular Editor 3 does not include a visual Power Query Editor. You can still edit Power Query (M) expressions as text, but if your model relies heavily on complex data transformation expressed as Power Query queries, you should consider to keep using Visual Studio for purposes of editing the Power Query queries. + +> [!NOTE] +> Performing complex data transformations using Power Query is generally not recommended for enterprise data modeling, due to the increased overhead of data refresh operations. Instead, prepare your data into a star schema using other ETL tools, and store the star schema data in a relational database, such as SQL Server or Azure SQL Database. Then, import tables to your tabular model from that database. + +#### Editing partitions and updating table schema + +In Tabular Editor 3, you can update the schema of a table without forcing a table refresh. Partitions are displayed in the TOM Explorer as individual objects. Click on a partition to edit its expression (M or SQL) in the Expression Editor. + +Once a partition expression has been updated, Tabular Editor can automatically detect if the table schema resulting from the updated expression, is different from the set of columns defined in the model. To perform a schema update, right-click on the partition or table in the TOM Explorer and choose **Update table schema...**. + +For more information about table import and schema updates, see @importing-tables. + +### Visualizing relationships + +Visual Studio includes a diagram tool that lets you visualize and create relationships between tables. + +Tabular Editor 3 also includes a diagram tool, that can be accessed using **File > New > Diagram**. A new diagram document tab will be created, at which point you can add tables from the TOM Explorer by dragging and dropping, or from the **Diagram > Add tables...** menu. + +Once tables have been added to the diagram, you can create relationship between columns simply by dragging from one column to another. + +![Te3 Diagram View](~/content/assets/images/te3-diagram-view.png) + +> [!NOTE] +> For performance reasons, the diagram tool does not inspect the data of the model, nor does it validate the uniqueness or directionality of any relationships you create. It is up to you to ensure that relationships are created correctly. If a relationship has been incorrectly defined, Analysis Services will return an error state which is shown in the **Messages View**. + +### Model deployment + +Tabular Editor lets you easily deploy the model metadata to any instance of Analysis Services. You can invoke Tabular Editor's Deployment Wizard under **Model > Deploy...** or by hitting CTRL+SHIFT+D. + +For more information, see . + +## Next steps + +- @migrate-from-te2 +- @parallel-development +- @boosting-productivity-te3 \ No newline at end of file diff --git a/content/localization/de/new-as-model_de.md b/content/localization/de/new-as-model_de.md new file mode 100644 index 00000000..1108e338 --- /dev/null +++ b/content/localization/de/new-as-model_de.md @@ -0,0 +1,125 @@ +--- +uid: new-as-model +title: Create an Analysis Services Model +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Creating your first Analysis Services Model + +This page walks you through the process of creating a new Analysis Services tabular model from scratch using Tabular Editor 3. + +> [!NOTE] +> Tabular Editor 3 Business Edition is limited to [SQL Server Standard Edition](https://docs.microsoft.com/en-us/analysis-services/analysis-services-features-supported-by-the-editions-of-sql-server-2016?view=asallproducts-allversions#tabular-models) and [Azure Analysis Services Basic Tier](https://docs.microsoft.com/en-us/azure/analysis-services/analysis-services-overview#basic-tier). Note that certain modeling features are not supported at these tiers. + +##### Creating a new model + +- From the File menu, choose New > Model... or hit `CTRL+N` + +![New model](https://user-images.githubusercontent.com/8976200/116813646-02a6fc80-ab55-11eb-89b0-8909b768ce7e.png) + +- Provide a name for your model or use the default value. Then, choose the compatibility level depending on which version of Analysis Services you are targetting. Your options are the following: + - 1200 (Works with SQL Server 2016 or newer, and Azure Analysis Services) + - 1400 (Works with SQL Server 2017 or newer, and Azure Analysis Services) + - 1500 (Works with SQL Server 2019 or Azure Analysis Services) +- For the best development experience, check the "Use workspace database" option. This requires that you have an instance of Analysis Services available on which your workspace database will be deployed. This could be a local or a remote instance of SQL Server Analysis Services or it could be an instance of Azure Analysis Services. When you click OK, you will be prompted to enter the connection string for the Analysis Services instance in which you want the workspace database created. + + [Learn more about workspace databases](xref:workspace-mode). + +> [!NOTE] +> With a workspace database, you can validate Power Query (M expressions) and import table schema from Power Query expressions. You can also refresh and query data in the workspace database, making it easier to debug and test your DAX expressions. + +Once your model is created, the next step is to add a data source and some tables. + +#### Adding a data source and tables + +Before you can import data to your tabular model, you have to set up one or more data sources. Locate the TOM Explorer, right-click on the "Data Sources" folder and choose "Create". For a model that uses compatibility level 1400 or higher, we have two options: Legacy and Power Query data sources. To learn more about th differences between these two types of data sources, [consult the Microsoft Analysis Services blog](https://docs.microsoft.com/en-us/archive/blogs/analysisservices/using-legacy-data-sources-in-tabular-1400). + +![Add data source](https://user-images.githubusercontent.com/8976200/124598010-72db4280-de64-11eb-818a-e5793f061185.png) + +In this example, we will create a Power Query data source, which we will use to import a few tables from a SQL Server relational database. Once the data source is created, hit F2 to rename it and configure the data source using the Propery Grid as seen in the screenshot below: + +![Set data source properties](https://user-images.githubusercontent.com/8976200/124599856-71ab1500-de66-11eb-8ede-3a6272872734.png) + +In our example, we set the following properties: + +| Property | Value | +| ------------------ | ---------------------- | +| Name | `AdventureWorks` | +| Protocol | `tds` | +| Database | `AdventureWorksDW2017` | +| Server | `localhost` | +| AuthenticationKind | `ServiceAccount` | + +Hit Save (Ctrl+S). You will be prompted to provide a path and file name for the Model.bim file which will hold the model metadata that you have created so far. You may also save the model as a folder structure instead (File > Save to folder...), which is recommended if you plan to integrate your model metadata into a version controlled environment. If you are using a Workspace Database, Tabular Editor 3 will also synchronize the metadata to the connected instance of Analysis Services. + +Next, add a new table to the model by right-clicking on the "Tables" folder and choosing "Create > Table" (you can also hit Alt+5). Give the table a name, in our example `Internet Sales`. Expand the table, locate the partition on the table and provide the following M query as the partition expression, in order to populate the table with data: + +```M +let + Source = #"AdventureWorks", + Data = Source{[Schema="dbo",Item="FactInternetSales"]}[Data] +in + Data +``` + +This assumes that the relational SQL Server database contains a table named "FactInternetSales" within the "dbo" schema. + +![M partition expression](https://user-images.githubusercontent.com/8976200/124601212-dd41b200-de67-11eb-9720-3890d7d746ba.png) + +Next, right-click on the newly created table and choose "Update table schema...". This allows Tabular Editor to automatically populate the table columns based on the partition query. + +> [!NOTE] +> If you are not using a Workspace Database, this operation is only available in Tabular Editor version 3.1.0 or newer. + +![Schema compare](https://user-images.githubusercontent.com/8976200/124601333-0104f800-de68-11eb-94f7-654c9e8ff206.png) + +Hit "OK" to add the columns to the table. Hit Save again (Ctrl+S). If you are using a Workspace Database, you may refresh the table on the server and browse the data in the table once the refresh operation is complete. To do so, right-click the table and choose "Refresh table > Automatic (table)". Wait for the operation on the "Data Refresh" tab to complete, then right-click the table and choose "Preview" (you can do so from the TOM Explorer as well), to view the actual data within the table: + +![Data refresh](https://user-images.githubusercontent.com/8976200/124602234-f0a14d00-de68-11eb-8886-dc7e0d255f9a.png) + +If the table you imported is a dimension table, we recommend setting the "Key" property of the primary key column on the table, to "true". This makes it easier to define relationships between this and other tables, as we shall see later. + +Repeat this process for any table you wish to import to your Tabular model. You don't have to refresh the data in each table one by one - instead, you can run the refresh operation at the model level. + +#### Defining relationships + +Once you have imported a number of tables, the easiest way to define the relationships between them with Tabular Editor 3, is to create a new diagram. Choose "File > New > Diagram". Then, multi-select and drag the tables into the diagram view or right-click on the tables and choose "Add to diagram": + +![Add to diagram](https://user-images.githubusercontent.com/8976200/124602823-8a68fa00-de69-11eb-9332-09ad42c4f1b3.png) + +To create a relationship between two tables, locate the foreign key column on the fact table and "drag" that column to the primary key column on the dimension table. Hit "OK" to confirm the relationship settings in the dialog that appears. + +![Diagram view](https://user-images.githubusercontent.com/8976200/124604764-8f2ead80-de6b-11eb-88d0-c9cebbca57d0.png) + +Close the diagram view (no need to save it, as you can always reconstruct the diagram later). Hit Ctrl+S once again to save the model. Now it's time to add some business logic. If you're using a Workspace Database, now is a good time to execute a refresh (automatic or calculate) at the model level, to ensure that the supporting structures for the relationships are created on the server, thus bringing the model into a queryable state. + +#### Adding measures + +Select one of the tables in the TOM Explorer and hit Alt+1 (or choose Create > New Measure) to add a measure to that table. Give the measure a name and provide a DAX expression for the measure. + +![Add measure](https://user-images.githubusercontent.com/8976200/124605349-19771180-de6c-11eb-94be-7baf8b5e0ee9.png) + +Hit Ctrl+S to save the model metadata. + +If you're using a Workspace Database, you can now test your new measure directly inside Tabular Editor 3. The easiest way to test it is by using a Pivot Grid. Choose File > New > Pivot Grid, then drag the newly created measure from the TOM Explorer into the grid. You can also drag columns and hierarchies from the TOM Explorer into the Filter, Row or Column area of the Pivot Grid, to slice your measure by different dimension attributes: + +![Pivot Grid](https://user-images.githubusercontent.com/8976200/124605906-ae7a0a80-de6c-11eb-985d-6fd580ed81d1.png) + +If you didn't use a Workspace Database, you will have to deploy your model to an instance of Analysis Services, before you can perform data refreshes and query the model. + +#### Deploying the data model + +To deploy the model metadata to any instance of Analysis Services, click on the "Model" menu and choose "Deploy...". This brings up the Tabular Editor 3 Deployment Wizard which is similar to the Deployment Wizard of Tabular Editor 2.X. Follow the instructions on the various pages of the wizard, to deploy the model metadata to an instance of Analysis Services. You can also use the Deployment Wizard to generate a TMSL/XMLA script, that can be handed over to an Analysis Services server administrator for manual deployment. + +![Deployment](https://user-images.githubusercontent.com/8976200/124607262-f5b4cb00-de6d-11eb-8139-4f74b5ae19bf.png) + +To refresh and test the deployed database, you can use the standard management and client tools provided by Microsoft, or you can use another instance of Tabular Editor 3 (assuming you have administrative access on the instance of Analysis Services where the deployed model resides). + +The paragraph above provides a good reason for using the Workspace Database approach described above. When connected to a workspace database, you will be able to perform all development operations, including data refresh and testing of business logic within the same instance of Tabular Editor 3, without having to rely on other tools. diff --git a/content/localization/de/new-pbi-model_de.md b/content/localization/de/new-pbi-model_de.md new file mode 100644 index 00000000..0b085310 --- /dev/null +++ b/content/localization/de/new-pbi-model_de.md @@ -0,0 +1,35 @@ +--- +uid: new-pbi-model +title: Create a Power BI Semantic Model +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Creating your first Power BI semantic model + +This page walks you through the process of creating a new Power BI semantic model from scratch using Tabular Editor 3. + +> [!IMPORTANT] +> Tabular Editor 3 Business Edition is limited to [Power BI Premium Per User](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-per-user-faq). For Power BI Premium or Embedded capacity, you must upgrade to Tabular Editor 3 Enterprise Edition. In either case, the Power BI workspace in which the semantic model is to be deployed, must have its [XMLA read/write endpoint enabled](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#enable-xmla-read-write). +> +> Tabular Editor 3 Desktop Edition does not have any support for Power BI semantic models. +> +> [More information](xref:editions). + +##### Creating a new semantic model + +1. From the File menu, choose New > Model... or hit `CTRL+N` + +![New model](~/content/assets/images/new-pbi-model.png) + +- Provide a name for your model or use the default value. Then, set the compatibility level to "1609 (Power BI / Fabric)". +- For the best development experience, check the "Use workspace database" option. This requires that you have a development workspace available in Power BI, with XMLA read/write enabled. When you click OK, you will be prompted to enter the connection string for the Power BI workspace in which you want the workspace database created. + +> [!NOTE] +> With a workspace database, you can validate Power Query (M expressions) and import table schema from Power Query expressions. You can also refresh and query data in the workspace database, making it easier to debug and test your DAX expressions. diff --git a/content/localization/de/optimizing-workflow-workspace-mode_de.md b/content/localization/de/optimizing-workflow-workspace-mode_de.md new file mode 100644 index 00000000..cd7bc408 --- /dev/null +++ b/content/localization/de/optimizing-workflow-workspace-mode_de.md @@ -0,0 +1,22 @@ +--- +uid: optimizing-workflow-workspace-mode +title: Optimizing development workflow using Workspace Mode +author: Daniel Otykier +updated: 2021-10-05 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Optimizing development workflow using Workspace Mode + +[!include[workspace-mode](~/content/te3/workspace-mode.partial.md)] + +# Next steps + +- @powerbi-cicd +- @as-cicd +- @boosting-productivity-te3 \ No newline at end of file diff --git a/content/localization/de/parallel-development_de.md b/content/localization/de/parallel-development_de.md new file mode 100644 index 00000000..4ca33fa4 --- /dev/null +++ b/content/localization/de/parallel-development_de.md @@ -0,0 +1,187 @@ +--- +uid: parallel-development +title: Enabling parallel development using Git and Save to Folder +author: Daniel Otykier +updated: 2021-09-30 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Enabling parallel development using Git and Save to Folder + +
    + +This article describes the principles of parallel model development (that is, the ability for multiple developers to work in parallel on the same data model) and the role of Tabular Editor in this regard. + +# Prerequisites + +- The destination of your data model must be one of the following: + - SQL Server 2016 (or newer) Analysis Services Tabular + - Azure Analysis Services + - Power BI Premium Capacity/Power BI Premium-per-user with [XMLA read/write enabled](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#enable-xmla-read-write) +- Git repository accessible by all team members (on-premises or hosted in Azure DevOps, GitHub, etc.) + +# TOM as source code + +Parallel development has traditionally been difficult to implement on Analysis Services tabular models and Power BI datasets (in this article, we will call both types of models "tabular models" for brevity). With the introduction of the JSON-based model metadata used by the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions), integrating model metadata in version control has certainly become easier. + +The use of a text-based file format makes it possible to handle conflicting changes in a graceful way, by using various diff tools that are often included with the version control system. This type of change conflict resolution is very common in traditional software development, where all of the source code resides in a large number of small text files. For this reason, most popular version control systems are optimized for these types of files, for purposes of change detection and (automatic) conflict resolution. + +For tabular model development, the "source code" is our JSON-based TOM metadata. When developing tabular models with earlier versions of Visual Studio, the Model.bim JSON file was augmented with information about who modified what and when. This information was simply stored as additional properties on the JSON objects throughout the file. This was problematic, because not only was the information redundant (since the file itself also has metadata that describes who the last person to edit it was, and when the last edit happened), but from a version control perspective, this metadata does not hold any _semantic meaning_. In other words, if you were to remove all of the modification metadata from the file, you would still end up with a perfectly valid TOM JSON-file, that you could deploy to Analysis Services or publish to Power BI, without affecting the functionality and business logic of the model. + +Just like source code for traditional software development, we do not want this kind of information to "contaminate" our model metadata. Indeed, a version control system gives a much more detailed view of the changes that were made, who made them, when and why, so there is no reason to include it as part of the files being versioned. + +When Tabular Editor was first created, there was no option to get rid of this information from the Model.bim file created by Visual Studio, but that has luckily changed in more recent versions. However, we still need to deal with a single, monolithic file (the Model.bim file) containing all of the "source code" that defines the model. + +Power BI dataset developers have it much worse, since they do not even have access to a text-based file containing the model metadata. The best they can do is export their Power BI report as a [Power BI Template (.pbit) file](https://docs.microsoft.com/en-us/power-bi/create-reports/desktop-templates#creating-report-templates) which is basically a zip file containing the report pages, the data model definitions and the query definitions. From the perspective of a version control system, a zip file is a binary file, and binary files cannot be diff'ed, compared and merged, the same way text files can. This forces Power BI developers to use 3rd party tools or come up with elaborate scripts or processes for properly versioning their data models - especially, if they want to be able to merge parallel tracks of development within the same file. + +Tabular Editor aims to simplify this process by providing an easy way to extract only the semantically meaningful metadata from the Tabular Object Model, regardless of whether that model is an Analysis Services tabular model or a Power BI dataset. Moreover, Tabular Editor can split up this metadata into several smaller files using its Save to Folder feature. + +# What is Save to Folder? + +As mentioned above, the model metadata for a tabular model is traditionally stored in a single, monolithic JSON file, typically named **Model.bim**, which is not well suited for version control integration. Since the JSON in this file represents the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions), it turns out that there is a straight forward way to break the file down into smaller pieces: The TOM contains arrays of objects at almost all levels, such as the list of tables within a model, the list of measures within a table, the list of annotations within a measure, etc. When using Tabular Editor's **Save to Folder** feature, these arrays are simply removed from the JSON, and instead, a subfolder is generated containing one file for each object in the original array. This process can be nested. The result is a folder structure, where each folder contains a set of smaller JSON files and subfolders, which semantically contains exactly the same information as the original Model.bim file: + +![Save To Folder](~/content/assets/images/save-to-folder.png) + +The names of each of the files representing individual TOM objects are simply based on the `Name` property of the object itself. The name of the "root" file is **Database.json**, which is why we sometimes refer to the folder-based storage format as simply **Database.json**. + +## Pros of using Save to Folder + +Below are some of the advantages of storing the tabular model metadata in this folder based format: + +- **Multiple smaller files work better with many version control systems than few large files.** For example, git stores snapshots of modified files. For this reason alone, it makes sense why representing the model as multiple smaller files is better than storing it as a single, large file. +- **Avoid conflicts when arrays are reordered.** Lists of tables, measures, columns, etc., are represented as arrays in the Model.bim JSON. However, the order of objects within the array does not matter. It is not uncommon for objects to be reordered during model development, for example due to cut/paste operations, etc. With Save to Folder, array objects are stored as individual files, so the arrays are no longer change tracked, reducing the risk of merge conflicts. +- **Different developers rarely change the same file.** As long as developers work on separate parts of the data model, they will rarely make changes to the same files, reducing the risk of merge conflicts. + +## Cons of using Save to Folder + +As it stands, the only disadvantage of storing the tabular model metadata in the folder based format, is that this format is used exclusively by Tabular Editor. In other words, you can not directly load the model metadata into Visual Studio from the folder based format. Instead, you would have to temporarily convert the folder based format to the Model.bim format, which can of course be done using Tabular Editor. + +## Configuring Save to Folder + +One size rarely fits all. Tabular Editor has a few configuration options that affect how a model is serialized into the folder structure. In Tabular Editor 3, you can find the general settings under **Tools > Preferences > Save-to-folder**. Once a model is loaded in Tabular Editor, you can find the specific settings that apply to that model under **Model > Serialization options...**. The settings that apply to a specific model are stored as an annotation within the model itself, to ensure that the same settings are used regardless of which user loads and saves the model. + +![Configuring Save To Folder](~/content/assets/images/configuring-save-to-folder.png) + +### Serialization settings + +- **Use recommended settings**: (Default: checked) When this is checked, Tabular Editor uses the default settings when saving a model as a folder structure for the first time. +- **Serialize relationships on from-tables**: (Default: unchecked) When this is checked, Tabular Editor stores relationships as an annotation on the table at the "from-side" (typically the fact table) of the relationship, instead of storing them at the model level. This is useful when in the early development phase of a model, where table names are still subject to change quite often. +- **Serialize perspective membership info on objects**: (Default: unchecked) When this is checked, Tabular Editor stores information about which perspectives an object (table, column, hierarchy, measure) belongs to, as an annotation on that object, instead of storing the information at the perspective level. This is useful when object names are subject to change, but perspective names are finalised. +- **Serialize translations on translated objects**: (Default: unchecked) When this is checked, Tabular Editor stores metadata translations as an annotation on each translatable object (table, column, hierarchy, level, measure, etc.), instead of storing the translations at the culture level. This is useful when object names are subject to change. +- **Prefix file names sequentially**: (Default: unchecked) In cases where you want to retain the metadata ordering of array members (such as the order of columns in a table), you can check this to have Tabular Editor prefix the filenames with a sequential integer based on the object's index in the array. This is useful if you use the default drillthrough feature in Excel, and would like [columns to appear in a certain order in the drillthrough](https://github.com/TabularEditor/TabularEditor/issues/46#issuecomment-297932090). + +> [!NOTE] +> The main purpose of the settings described above, is to reduce the number of merge conflicts encountered during model development, by adjusting how and where certain model metadata is stored. In the early phases of model development, it is not uncommon for objects to be renamed often. If a model already has metadata translations specified, every object rename would cause at least two changes: One change on the object being renamed, and one change for every culture that defines a translation on that object. When **Serialize translations on translated objects** is checked, there would only be a change on the object being renamed, as that object also includes the translated values (since this information would be stored as an annotation). + +### Serialization depth + +The checklist allows you to specify which objects will be serialized as individual files. Note that some options (perspectives, translations, relationships) may not be available, depending on the settings specified above. + +In most cases, it is recommended to always serialize objects to the lowest level. However, there may be special cases where this level of detail is not needed. + +# Power BI and version control + +As mentioned above, integrating a Power BI report (.pbix) or Power BI template (.pbit) file in version control, does not enable parallel development or conflict resolution, due to these files using a binary file format. At the same time, we have to be aware of the current limitations of using Tabular Editor (or other third party tools) with Power BI Desktop or the Power BI XMLA endpoint respectively. + +These limitations are: + +- When using Tabular Editor as an external tool for Power BI Desktop, [not all modeling operations are supported](xref:desktop-limitations). +- Tabular Editor can extract model metadata from a .pbix file loaded in Power BI Desktop, or directly from a .pbit file on disk, but there is **no supported way to update model metadata in a .pbix or .pbit file outside of Power BI Desktop**. +- Once any changes are made to a Power BI dataset through the XMLA endpoint, [that dataset can no longer be downloaded as a .pbix file](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#power-bi-desktop-authored-datasets). + +To enable parallel development, we must be able to store the model metadata in one of the text-based (JSON) formats mentioned above (Model.bim or Database.json). There is no way to "recreate" a .pbix or .pbit file from the text-based format, so **once we decide to go this route, we will no longer be able to use Power BI Desktop for editing the data model**. Instead, we will have to rely on tools that can use the JSON-based format, which is exactly the purpose of Tabular Editor. + +> [!WARNING] +> If you do not have access to a Power BI Premium workspace (either Premium capacity or Premium-Per-User), you will not be able to publish the model metadata stored in the JSON files, since this operation requires access to the [XMLA endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools). + +> [!NOTE] +> Power BI Desktop is still needed for purpose of creating the visual part of the report. It is a [best practice to always separate reports from models](https://docs.microsoft.com/en-us/power-bi/guidance/report-separate-from-model). In case you have an existing Power BI file that contains both, [this blog post](https://powerbi.tips/2020/06/split-an-existing-power-bi-file-into-a-model-and-report/) ([video](https://www.youtube.com/watch?v=PlrtBm9YN_Q)) describes how to split it into a model file and a report file. + +# Tabular Editor and git + +Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. It is the most popular version control system right now, and it is available through multiple hosted options, such as [Azure DevOps](https://azure.microsoft.com/en-us/services/devops/repos/), [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/) and others. + +A detailed description of git is outside the scope of this article. There are, however, many resources available online if you want to learn more. We recommend the [Pro Git](https://git-scm.com/book/en/v2) book for reference. + +> [!NOTE] +> Tabular Editor 3 does not currently have any integration with git or other version control systems. To manage your git repository, commit code changes, create branches, etc., you will have to use the git command line or another tool, such as the [Visual Studio Team Explorer](https://docs.microsoft.com/en-us/azure/devops/user-guide/work-team-explorer?view=azure-devops#git-version-control-and-repository) or [TortoiseGit](https://tortoisegit.org/). + +As mentioned earlier, we recommend using Tabular Editor's [Save to Folder](#what-is-save-to-folder) option when saving model metadata to a git code repository. + +## Branching strategy + +What follows is a discussion of branching strategies to employ when developing tabular models. + +The branching strategy will dictate what the daily development workflow will be like, and in many cases, branches will tie directly into the project methods used by your team. For example, using the [agile process within Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/boards/work-items/guidance/agile-process-workflow?view=azure-devops), your backlog would consist of **Epics**, **Features**, **User Stories**, **Tasks** and **Bugs**. + +In the agile terminology, a **User Story** is a deliverable, testable piece of work. The User Story may consist of several **Tasks**, that are smaller pieces of work that need to be performed, typically by a developer, before the User Story may be delivered. In the ideal world, all User Stories have been broken down into manageable tasks, each taking only a couple of hours to complete, adding up to no more than a handful of days for the entire User Story. This would make a User Story an ideal candidate for a so-called Topic Branch, where the developer could make one or more commits for each of the tasks within the User Story. Once all tasks are done, you want to deliver the User Story to the client, at which time the topic branch is merged into a delivery branch (for example, a "Test" branch), and the code deployed to a testing environment. + +Determining a suitable branching strategy depends on many different factors. In general, Microsoft recommends the [Trunk-based Development](https://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance?view=azure-devops) ([video](https://youtu.be/t_4lLR6F_yk?t=232)) strategy, for agile and continuous delivery of small increments. The main idea is to create branches off the "Main" branch for every new feature or bugfix (see image below). Code review processes are enforced through pull requests from feature branches into Main, and using the Branch Policy feature of Azure DevOps, we can set up rules that require code to build cleanly before a pull request can be completed. + +![Trunk Based Development](~/content/assets/images/trunk-based-development.png) + +### Trunk-based Development + +However, such a strategy might not be feasible in a Business Intelligence development teams, for a number of reasons: + +- New features often require prolonged testing and validation by business users, which may take several weeks to complete. As such, you will likely need a user-faced test environment. +- BI solutions are multi-tiered, typically consisting of a Data Warehouse tier with ETL, a Master Data Management tier, a semantic layer and reports. Dependencies exist between these layers, that further complicate testing and deployment. +- The BI team may be responsible for developing and maintaining several different semantic models, serving different areas of business (Sales, Inventory, Logistics, Finance, HR, etc.), at different maturity stages and at varying development pace. +- The most important aspect of a BI solution is the data! As a BI developer, you don not have the luxury of simply checking out the code from source control, hitting F5 and having a full solution up and running in the few minutes it takes to compile the code. Your solution needs data, and that data has to be loaded, ETL'ed or processed across several layers to make it to the end user. Including data in your DevOps workflows could blow up build and deployment times from minutes to hours or even days. In some scenarios, it might not even be possible, due to ressource or economy constraints. + +There is no doubt that a BI team would benefit from a branching strategy that supports parallel development on any of the layers in the full BI solution, in a way that lets them mix and match features that are ready for testing. But especially due to the last bullet point above, we need to think carefully about how we are going to handle the data. If we add a new attribute to a dimension, for example, do we want to automatically load the dimension as part of our build and deployment pipelines? If it only takes a few minutes to load such a dimension, that would probably be fine, but what if we are adding a new column to a multi-billion row fact table? And if developers are working on new features in parallel, should each developer have their own development database, or how do we otherwise prevent them from stepping on each others toes in a shared database? + +There is no easy answer to the questions above - especially when considering all the tiers of a BI solution, and the different constellations and prefered workflows of BI teams across the planet. Also, when we dive into actual build, deployment and test automation, we are going to focus mostly on Analysis Services. The ETL- and database tiers have their own challenges from a DevOps perspective, which are outside the scope of this article. But before we move on, let us take a look at another branching strategy, and how it could potentially be adopted to BI workflows. + +### GitFlow branching and deployment environments + +The strategy described below is based on [GitFlow by Vincent Driessen](https://nvie.com/posts/a-successful-git-branching-model/). + +![Gitflow](~/content/assets/images/gitflow.png) + +Implementing a branching strategy similar to this, can help solve some of the DevOps problems typically encountered by BI teams, provided you put some thought into how the branches correlate to your deployment environments. In an ideal world, you would need at least 4 different environments to fully support GitFlow: + +- The **production** environment, which should always contain the code at the HEAD of the master branch. +- A **canary** environment, which should always contain the code at the HEAD of the develop branch. This is where you typically schedule nightly deployments and run your integration testing, to make sure that the features going into the next release to production play nicely together. +- One or more **UAT** environments where you and your business users test and validate new features. Deployment happens directly from the feature branch containing the code that needs to be tested. You will need multiple test environments if you want to test multiple new features in parallel. With some coordination effort, a single test environment is usually enough, as long as you carefully consider the dependencies between your BI tiers. +- One or more **sandbox** environments where you and your team can develop new features, without impacting any of the environments above. As with the test environment, it is usually enough to have a single, shared, sandbox environment. + +We must emphasize that there is really no "one-size-fits-all" solution to these considerations. Maybe you are not building your solution in the Cloud, and therefore do not have the scalability or flexibility to spin up new resources in seconds or minutes. Or maybe your data volumes are very large, making it impractical to replicate environments due to resource/economy/time constraints. Before moving on, also make sure to ask yourself the question of whether you truly need to support parallel development and testing. This is rarely the case for small teams with only a few stakeholders, in which case you can still benefit from CI/CD, but where GitFlow branching might be overkill. + +Even if you do need to support parallel development, you may find that multiple developers can easily share the same development or sandbox environment, without encountering too much trouble. Specifically for tabular models, though, we recommend that developers still use individual [workspace databases](xref:workspace-mode) to avoid "stepping over each others toes". + +## Common workflow + +Assuming you already have a git repository set up and aligned to your branching strategy, adding your tabular model "source code" to the repository is simply a matter of using Tabular Editor to save the metadata to a new branch in a local repository. Then, you stage and commit the new files, push your branch to the remote repository and create a pull request to get your branch merged into the main branch. + +The exact workflow depends on your branching strategy and how your git repositories have been set up. In general, the workflow would look something like this: + +1. Before starting work on a new feature, create a new feature branch in git. In a trunk-based development scenario, you would need the following git commands to checkout the main branch, get the latest version of the code, and create the feature branch from there: + ```cmd + git checkout main + git pull + git checkout -b "feature\AddTaxCalculation" + ``` +2. Open your model metadata from the local git repository in Tabular Editor. Ideally, use a [workspace database](xref:workspace-mode), to make it easier to test and debug DAX code. +3. Make the necessary changes to your model using Tabular Editor. Continuously save the changes (CTRL+S). Regularly commit code changes to git after you save, to avoid losing work and to keep a full history of all changes that were made: + ```cmd + git add . + git commit -m "Description of what was changed and why since last commit" + git push + ``` +4. If you are not using a workspace database, use Tabular Editor's **Model > Deploy...** option to deploy to a sandbox/development environment, in order to test the changes made to the model metadata. +5. When done, and all code has been committed and pushed to the remote repository, you submit a pull request in order to get your code integrated with the main branch. If a merge conflict is encountered, you will have to resolve it locally, using for example the Visual Studio Team Explorer or by simply opening the .json files in a text editor to resolve the conflicts (git inserts conflict markers to indicate which part of the code has conflicts). +6. Once all conflicts are resolved, there may be a process of code review, automated build/test execution based on branch policies, etc. to get the pull request completed. This, however, depends on your branching strategy and overall setup. + +We present more details about how to configure git branch policies, set up automated build and deployment pipelines, etc. using Azure DevOps in the following articles. Similar techniques can be used in other automated build and git hosting environments, such as TeamCity, GitHub, etc. + +# Next steps + +- @powerbi-cicd +- @as-cicd +- @optimizing-workflow-workspace-mode \ No newline at end of file diff --git a/content/localization/de/personalizing-te3_de.md b/content/localization/de/personalizing-te3_de.md new file mode 100644 index 00000000..0827d748 --- /dev/null +++ b/content/localization/de/personalizing-te3_de.md @@ -0,0 +1,252 @@ +--- +uid: personalizing-te3 +title: Personalizing and configuring Tabular Editor 3 to suit your needs +author: Daniel Otykier +updated: 2021-09-28 +--- + +# Personalizing and configuring Tabular Editor 3 to suit your needs + +Tabular Editor 3 provides a wide range of configuration options, that allow you to tweak the tool to your specific needs and preferred workflow. In this article, we will guide you through the settings that are most commonly adjusted by individual model developers. + +Most of the settings covered in this article are accessed through the **Tools > Preferences** menu option. Throughout the article, we will list individual settings in the following style, for easy reference: + +**_Name of setting_ (default value)**
    Description of setting. + +# General features + +The first page you will encounter within the **Preferences** dialog is the **Tabular Editor > Features** page (see screenshot below). Below is a short description of the features on this page, and what they are commonly used for: + +![Pref General Features](~/content/assets/images/pref-general-features.png) + +## Power BI + +These settings are mostly useful for developers who use Tabular Editor 3 as an [External Tool for Power BI Desktop](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools). + +##### _Allow unsupported modeling operations_ (disabled) + +External Tools for Power BI Desktop have some [limitations](xref:desktop-limitations). By default, Tabular Editor 3 will prevent the user from making unsupported changes to the data model. There may be some advanced modeling features which work well, even though they are not supported cf. the previous link. To unlock all Tabular Object Model objects and properties, enable this setting. + +##### _Hide auto date/time warnings_ (disabled) + +When the "Auto date/time" setting in Power BI Desktop is enabled, a number of calculated tables are created automatically. Unfortunately, these tables contain DAX code which trigger a warning message by Tabular Editor 3's built-in DAX analyzer. To hide these warnings, enable this setting. + +##### _Line break on first line of DAX_ (disabled) + +In Power BI Desktop it is common to insert a line break on the first line of a DAX expression, due to the way the formula bar displays the DAX code. If you often switch back and forth between Tabular Editor and Power BI Desktop, consider enabling this option to have Tabular Editor 3 insert the line break automatically, whenever a DAX expression is edited through the tool. + +## Metadata Synchronization + +These settings controls the behavior of Tabular Editor 3, when model metadata is loaded from a database on an instance of Analysis Services. The settings specify how Tabular Editor 3 should deal with metadata changes applied to the database from outside the application, such as when another user makes a change to the database, or when you make a change to the model through Power BI Desktop while Tabular Editor 3 is used as an external tool. + +##### _Warn when local metadata is out-of-sync with deployed model_ (enabled) + +When this is checked, Tabular Editor displays a warning message when you attempt to save changes, while another user or process has made a change to the database since the model metadata was loaded into your instance of Tabular Editor. + +##### _Track external model changes_ (enabled) + +This option is only relevant for local instances of Analysis Services (i.e. msmdsrv.exe processes running on the same machine as Tabular Editor). When checked, Tabular Editor starts a trace on Analysis Services and notifies you if external changes are made. + +##### _Refresh local Tabular Object Model metadata automatically_ (enabled) + +When the tracing mechanism as described above is enabled, this option allows Tabular Editor to automatically refresh the model metadata when an external change is detected. This is useful if you often switch back and forth between Power BI Desktop and Tabular Editor 3, as this ensures that changes made in Power BI Desktop are automatically sync'ed to Tabular Editor. + +##### _Cleanup orphaned Tabular Editor traces_ + +Normally, Tabular Editor 3 should automatically stop and remove any AS traces started due to the settings above. However, if the application was shut down prematurely, the traces may never be stopped. By clicking this button, all AS traces started by any instance of Tabular Editor, on the current instance of Analysis Services, will be removed. + +> [!NOTE] +> The cleanup button is only available when Tabular Editor is connected to an instance of Analysis Services. + +# TOM Explorer settings + +The settings below control various aspects of the TOM Explorer. You can find these settings under **Tabular Editor > TOM Explorer**: + +![Tom Explorer Settings](~/content/assets/images/tom-explorer-settings.png) + +##### _Show full branch_ (disabled) + +When filtering the TOM Explorer, by default Tabular Editor 3 shows all items in the hierarchy that matches the filter string, including their parents. If you want to see all child items as well (even though these might not match the filter string), enable this option. + +##### _Always show delete warnings_ (disabled) + +If you prefer Tabular Editor 3 to prompt you to confirm all object deletions, enable this setting. Otherwise, Tabular Editor 3 will only prompt you to confirm multi-object deletions, or deletions of objects that are referenced by other objects. + +> [!NOTE] +> All delete operations in Tabular Editor 3 can be undone by hitting CTRL+Z. + +# DAX editor general settings + +Tabular Editor 3's DAX editor is highly configurable, and it is easy to get overwhelmed by the many settings available. This section highlights the most common and important settings. Locate the general settings under **Text Editors > DAX Editor > General**: + +![Dax Editor General](~/content/assets/images/dax-editor-general.png) + +## General + +The _Line numbers_, _Code folding_, _Visible whitespace_ and _Indentation guides_ settings can be used to toggle various visual feature of the editor. In the screenshot below, all four options have been enabled: + +![Visible Whitespace](~/content/assets/images/visible-whitespace.png) + +##### _Use tabs_ (disabled) + +When this is checked, a tab character (`\t`) is inserted whenever the TAB button is hit. Otherwise, a number of spaces corresponding to the _Indent width_ setting is inserted. + +##### _Comment style_ (slashes) + +DAX supports line comments that use slashes (`//`) or hyphens (`--`). This setting determines which style of comment is used when Tabular Editor 3 generates DAX code, such as when using the DAX script feature. + +## DAX Settings + +These settings determine certain behavior of the DAX code analyzer. The _Locale_ setting is simply a matter of preference. All other settings are relevant only when Tabular Editor 3 cannot determine the version of Analysis Services used, as is the case for example when a Model.bim file is loaded directly. In this case, Tabular Editor tries to guess which version the model will be deployed to, based on the compatibility level specified in the model, but depending on the actual version of the deployment target, there may be various DAX language differences, which Tabular Editor cannot determine. If Tabular Editor reports incorrect semantic/syntax errors, you may need to tweak these settings. + +# Auto Formatting + +On the **Text Editors > DAX Editor > Auto Formatting** page, you can find a wide range of settings for controlling how your DAX code is formatted. + +![Auto Formatting Settings](~/content/assets/images/auto-formatting-settings.png) + +##### _Auto format code as you type_ (enabled) + +This option will automatically apply certain formatting rules whenever certain keystrokes occur. For example, when a parenthesis is closed, this feature will ensure that everything within the parentheses is formatted according to the other settings on this page. + +##### _Auto-format function calls_ (enabled) + +This option specifically controls whether automatic formatting of function calls (that is, spacing between arguments and parentheses), should happen when a parenthesis is closed. + +##### _Auto-indent_ (enabled) + +This option automatically indents function arguments when a line break is inserted within a function call. + +##### _Auto-brace_ (enabled) + +This option automatically inserts the closing brace or quote whenever an opening brace or quote is entered. + +##### _Wrap selection_ (enabled) + +When enabled, this option automatically wraps the current selection with the closing brace, when an opening brace is entered. + +## Formatting rules + +These settings control how DAX code whitespace is formatted, both when auto-formatting occurs, but also when code is manually formatted (using the **Format DAX** menu options). + +##### _Space after functions_ (disabled) + +# [Enabled](#tab/tab1) + +```DAX +SUM ( 'Sales'[Amount] ) +``` + +# [Disabled](#tab/tab2) + +```DAX +SUM( 'Sales'[Amount] ) +``` + +*** + +##### _Newline after functions_ (disabled) + +Applies only when a function call needs to be broken across multiple lines. + +# [Enabled](#tab/tab3) + +```DAX +SUM +( + 'Sales'[Amount] +) +``` + +# [Disabled](#tab/tab4) + +```DAX +SUM( + 'Sales'[Amount] +) +``` + +*** + +##### _Newline before operator_ (enabled) + +Applies only when a binary operation needs to be broken across multiple lines. + +# [Enabled](#tab/tab5) + +```DAX +[Internet Total Sales] + + [Reseller Total Sales] +``` + +# [Disabled](#tab/tab6) + +```DAX +[Internet Total Sales] + + [Reseller Total Sales] +``` + +*** + +##### _Pad parentheses_ (enabled) + +# [Enabled](#tab/tab7) + +```DAX +SUM( Sales[Amount] ) +``` + +# [Disabled](#tab/tab8) + +```DAX +SUM(Sales[Amount]) +``` + +*** + +##### _Long format line limit_ (120) + +The maximal number of characters to keep on a single line before an expression is broken across multiple lines, when using the **Format DAX (long lines)** option. + +##### _Short format line limit_ (60) + +The maximal number of characters to keep on a single line before an expression is broken across multiple lines, when using the **Format DAX (short lines)** option. + +> [!NOTE] +> Most settings above are only in effect when using the (default) built-in DAX formatter. + +## Casings and quotes + +In addition to formatting the DAX code whitespace, Tabular Editor 3 can also fix object references and function/keyword casings. + +##### _Fix measure/column qualifiers_ (enabled) + +When this is checked, table prefixes are automatically removed from measure references, and automatically inserted on column references. + +##### _Preferred keyword casing_ (default = UPPER) + +This setting allows you to change the casing used for keywords, such as `ORDER BY`, `VAR`, `EVALUATE`, etc. This also applies when a keyword is inserted through the auto-complete feature. + +##### _Preferred function casing_ (default = UPPER) + +This setting allows oyu to change the casing used for functions, such as `CALCULATE(...)`, `SUM(...)`, etc. This also applies when a function is inserted through the auto-complete feature. + +##### _Fix keyword/function casing_ (enabled) + +When this is checked, casing of keywords and functions is automatically corrected whenever code is auto-formatted or manually formatted. + +##### _Fix object reference casing_ (enabled) + +DAX is a case-insensitive language. When this is enabled, references to tables, columns and measures are automatically corrected such that the casing matches the physical name of the referenced objects. This fixup happens whenever code is auto-formatted or manually formatted. + +##### _Always quote tables_ (disabled) + +Referencing certain table names do not require surrounding single quotes in DAX. However, if you prefer table references to always be quoted, regardless of the table name, you can check this option. + +##### _Always prefix extension columns_ (disabled) + +Extension columns can be defined without a table name. When this is checked, the DAX editor will always add the table prefix to an extension column, even if the table name is blank. In that case, the column reference will look like `''[Extension Column]`. + +# Next steps + +- @boosting-productivity-te3 \ No newline at end of file diff --git a/content/localization/de/perspective-editor_de.md b/content/localization/de/perspective-editor_de.md new file mode 100644 index 00000000..8ba5ae03 --- /dev/null +++ b/content/localization/de/perspective-editor_de.md @@ -0,0 +1,36 @@ +--- +uid: perspective-editor +title: Perspective Editor +author: Šarūnas Jučius +updated: 2022-03-16 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Perspective Editor + +> [!NOTE] +> In order to add perspectives to models running on SSAS or Azure AS, you will need a Tabular Editor 3 Enterprise Edition license. + +The **Perspective Editor** provides a quick overview of the perspective assignment of objects in the model (tables, columns, hierarchies and measures). You can launch the Perspective Editor through the **View** menu. Alternatively, if you only need to edit certain perspectives, select them in the **TOM Explorer** (hold down CTRL or SHIFT to multi-select), then right-click and choose **Show in Perspective Editor**. + +![Perspective Editor](~/content/assets/images/perspective-editor.png) + +Use the checkboxes in the perspective editor to quickly add/remove multiple objects from a perspective. You can use Undo (Ctrl+Z) and Redo (Ctrl+Y) the usual way. Note that the changes made through the perspective editor are immediately applied to the TOM, although you will still have to save (Ctrl+S) or deploy your model for the changes to apply in Analysis Services / Power BI. + +## Perspective Editor toolbar + +While the Perspective Editor is active, the accompanying toolbar provides the following options: + +- ![Perspective Editor Add Perspective](~/content/assets/images/perspective-editor-add-perspective.png) **New perspective**: This button adds a new perspective to the model. The perspective will be displayed in the Perspective Editor. +- ![Perspective Editor Hide Members](~/content/assets/images/perspective-editor-hide-members.png) **Show/Hide hidden options**: Enable this option if you want to see all objects in the Perspective Editor, including hidden objects. +- ![Perspective Editor Folder](~/content/assets/images/perspective-editor-folder.png) **Show/Hide display folders**: Enable this toggle button if you want the Perspective Editor to group table objects (measures, hierarchies, columns) by Display Folders. + +## Working with many perspectives + +If you're working on a model with many perspectives, it may be impractical to display all of them at once. You can rearrange the display order of perspectives in the Perspective Editor, by dragging the column headers around, making it easier to compare perspectives side-by-side. Moreover, you can add/remove perspectives from the editor at any time, through the right-click context menu: + +![Perspective Editor Columns](~/content/assets/images/perspective-editor-columns.png) \ No newline at end of file diff --git a/content/localization/de/pivot-grid_de.md b/content/localization/de/pivot-grid_de.md new file mode 100644 index 00000000..419aebc4 --- /dev/null +++ b/content/localization/de/pivot-grid_de.md @@ -0,0 +1,162 @@ +--- +uid: pivot-grid +title: Pivot Grids +author: Daniel Otykier +updated: 2024-05-28 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Pivot Grids + +> [!NOTE] +> Information in this article relates to Tabular Editor 3.16.0 or newer. Please make sure you are using the latest version of Tabular Editor 3 to take advantage of the new features and improvements. + +While developing semantic models, you may often want to test that your DAX expressions return the expected values. Traditionally, this was done using client tools such as Excel or Power BI. With Tabular Editor 3, you can use **Pivot Grids** which behave much like the widely known PivotTables in Excel. The Pivot Grid lets you quickly create summarized views of the data in your model, allowing you to test the behavior of your DAX measures when filtering and slicing by various columns and hierarchies. + +![Pivot Grid Example](images/pivot-grid-example.png) + +The screenshot above shows a Pivot Grid containing two measures, `[Total Net Order Value]` and `[Net Orders]`, which is sliced horizontally by Year, filtered to 2021 and 2022, and vertically by the Product Hierarchy. Tabular Editor 3 users can use this feature to ensure that DAX expressions behind the measures are working as expected and to quickly validate the data in the model. + +By default, the Pivot Grid auto-updates every time you save changes to the semantic model (Ctrl+S). Thus, you can quickly iterate on your DAX expressions and see the results in the Pivot Grid without having to wait for the model to refresh by changing your measures, saving the model, and directly seeing the new measure definition reflected in the Pivot Grid. A good workflow is to open the Pivot Grid in a separate window while working on DAX expressions in the **Expression Editor** or using a **DAX Script**. + +> [!TIP] +> Some clarifications on terminology: +> +> - **Fields** refers to model measures, KPIs, columns and hierarchies. In other words, anything that can be dragged into the Pivot Grid. +> - **KPIs** are a special type of measure that can be created in Tabular Editor. They are displayed in the Pivot Grid just like measures, but with a special icon to indicate that they are KPIs. Each KPI can have up to 3 different values (target, trend, and status), which are displayed separately in the Pivot Grid. +> - **Columns** in the Pivot Grid (such as in the term "Column Area") should not be confused with columns in the model. In the Pivot Grid, columns are used to slice the data horizontally, while rows are used to slice the data vertically. +> - **Cells** in the Pivot Grid are the individual data points where a row and a column intersect. Each cell contains a single value, which is the result of the DAX expression of the specific measure, evaluated under the filter context produced by values in the _Row Area_ and _Column Area_, in combination with any filters applied to fields in the _Filter Area_. + +> [!NOTE] +> Developers with a multidimensional background may be more familiar with the terms _Dimensions_ and _Attributes_. In semantic models, _Dimensions_ are represented by model _tables_, and _Attributes_ are represented by model _columns_. _Hierarchies_ in a semantic model, is just a way to group columns together, such as in a calendar hierarchy: Year > Quarter > Month > Day. Such hierarchies used to be called _Attribute Hierarchies_ or _User-Defined Hierarchies_ in multidimensional models. + +## Creating a Pivot Grid + +You can create a new, empty Pivot Grid through the **File > New > New Pivot Grid** menu option. Alternatively, select one or more measures in the **TOM Explorer**, right-click or go to the **Measure** menu and select **Add to Pivot Grid**, to create a new Pivot Grid with the selected measures. + +![Create Pivot Grid From TOM Explorer](images/create-pivot-grid-from-TOM-Explorer.png) + +You can create as many Pivot Grids as you like. + +> [!IMPORTANT] +> The option to create a Pivot Grid is only available while Tabular Editor 3 is connected to an instance of Analysis Services or the Power BI / Fabric XMLA endpoint. + +## Pivot Grid layout + +The Pivot Grid is divided into 4 areas: **Filter Area**, **Column Area**, **Row Area**, and **Data Area**. You can drag fields from the **Field List** or the **TOM Explorer** into these areas to create a Pivot Grid layout. The **Data Area** area is where you place measures or KPIs, while the **Row Area** and **Column Area** are used to slice the data by hierarchies and columns. The **Filter Area** is used to filter the data based on values in columns or hierarchies. + +![Empty Pivot Grid Highlighted](images/empty-pivot-grid-highlighted.png) + +The screenshot above shows an empty Pivot Grid layout. The 4 empty boxes at the bottom of the Field List represent the 4 areas of the Pivot Grid. You can drag fields from the Field List into these listboxes to create a Pivot Grid layout. Alternatively, you can drag fields directly into the Pivot Grid. + +## Pivot Grid menu and toolbar + +By default, when a Pivot Grid is the active window in Tabular Editor 3, a **Pivot Grid** menu and toolbar are available. The menu contains the same actions as the toolbar. + +![Pivot Grid Toolbar](images/pivot-grid-toolbar.png) + +![Pivot Grid Menu](images/pivot-grid-menu.png) + +These actions are: + +- **Impersonation...**: Displays a dialog that allows you to specify a role or user to impersonate through the Pivot Grid. This is useful when you want to test the behavior of your model for different users or roles, such as when [RLS or OLS](xref:data-security-about) has been applied to the model. +- **Refresh**: Re-execute the query generated by the Pivot Grid. This is useful when auto-refresh is disabled, or if changes have been made to the model outside of Tabular Editor 3. +- **Auto Refresh**: Toggles auto-refresh on or off. When auto-refresh is enabled, the Pivot Grid will automatically refresh every time you save changes to the model, or when a [Data Refresh operation](xref:data-refresh-view) completes. +- **Clear filters**: Clears all filters from the Pivot Grid. +- **Clear**: Removes all fields from the Pivot Grid. +- **Show empty values on columns**: Toggles whether empty values should be shown in the Pivot Grid, for fields that are added to the Pivot Grids Column Area. +- **Show empty values on rows**: Toggles whether empty values should be shown in the Pivot Grid, for fields that are added to the Pivot Grids Row Area. +- **Show fields**: Display and move focus to the Field List. + +## Field List + +By default, the Field List is displayed on the right side of the Pivot Grid. The Field List contains all the fields (measures, KPIs, columns, and hierarchies) that are available in the model. You can drag fields from the Field List into the Pivot Grid to create a layout. You can also drag fields between the different areas of the Pivot Grid to rearrange the layout. + +The Field List itself can be docked to the left or right side of the Pivot Grid, above or below, it can be hidden, or it can be undocked so that it "floats" as a separate window. If you have multiple Pivot Grids open, each Pivot Grid has its own Field List. + +If you would like the Field List to not be shown by default, uncheck the **Always show field list** option under **Tools > Preferences > Data Browsing > Pivot Grid > Field List**. + +You can change the default layout of the Field List under **Tools > Preferences > Data Browsing > Pivot Grid > Field List > Layout**. You can also change the layout of any field lists, by right-clicking in an empty area of the Field List and choosing the desired layout from the context menu. + +![Field List Settings](images/field-list-settings.png) + +By default, any field you add to the Pivot Grid remains visible in the Field List. If you would like to hide fields that are added to the Pivot Grid, you can uncheck the **Keep fields visible** option under **Tools > Preferences > Data Browsing > Pivot Grid > Field List** (this behavior is similar to how Pivot Grid worked prior to Tabular Editor v. 3.16.0). + +If you are working on a large, complex model, and you are expecting measures used in the Pivot Grid to be relatively slow, you can check the **Defer Layout Update** option at the bottom of the Field List. This will prevent the Pivot Grid from updating the layout every time you add or remove a field, which can be useful, if you intend to make multiple changes to the Pivot Grid layout before updating it. Hit the **Update** button to apply the changes to the Pivot Grid. + +> [!IMPORTANT] +> Columns without an attribute hierarchy (IsAvailableIn MDX = false) cannot be used in the Pivot Grid and are not shown in the Field list. + +## Customizing Pivot Grids + +### Adding fields + +There are several ways to add a field to a Pivot Grid: + +**From the TOM Explorer:** + +- Right-click on one or more _measures_ and choose **Add to Pivot Grid**. +- Right-click on a _column_ or _hierarchy_ and choose any of the **Add to pivot**-options (choose between rows, columns, or filters). +- If a measure, column or hierarchy is already shown in the Pivot Grid, the right-click options will allow you to **Remove from Pivot Grid**. in addition, you will see options to move columns or hierarchies between the different areas of the Pivot Grid. +- All of the options above are also available through the **Measure**, **Column**, and **Hierarchy** menus (respectively), when one or more such objects are selected in the TOM Explorer. +- In addition to the above, you can also drag one or more measures, columns, or hierarchies from the TOM Explorer into the Pivot Grid areas. + +![Add hierarchy to Pivot Grid through TOM Explorer](images/add-through-tom-explorer.png) + +**From the Field List:** + +- Drag a field from the Field List into the Pivot Grid. +- Drag a field from the Field List into the area listboxes at the bottom of the Field List to add it to the Pivot Grid. +- Right-click on a field in the Field List for options to add it to the Pivot Grid. +- If a field is already showing in the Pivot Grid, the right-click context menu will also have an option to remove the field, or move it to a different area (column/hierarchy fields only). +- Double-clicking on a field will immediately add it to the Pivot Grid. Measures/KPIs are added to the Data Area, while columns and hierarchies are added to the Filter Area. + +![Add Through Field List](images/add-through-field-list.png) + +### Adjusting fields + +After fields have been added to the Pivot Grid, you can adjust the width of columns to better accommodate their content. Double-clicking on a column header separator will automatically adjust the column width to fit the content of the column. You can also drag the column header separator to manually adjust the column width. Lastly, you can use the **Best Fit** or **Set width...** context menu options by right-clicking on the column header. + +![Best Fit Columns 2](images/best-fit-columns-2.png) + +To apply a "Best Fit" or set a specific pixel width for all columns in the Pivot Grid simultaneously, right-click on the "Values" header and select the desired option from the context menu. + +By default, field headers will expand vertically to fit the content of the field name. If you would like to limit the height of field headers to one row, you can disable the **Word wrap field headers**-option under **Tools > Preferences > Pivot Grid > Field Headers**. + +To change the order of fields in the Pivot Grid, you can drag fields between the different areas of the Pivot Grid. You can also drag fields within the same area to change their order. To remove a field from the Pivot Grid, drag it back to the Field List or right-click on the field and choose **Remove from Pivot Grid** from the context menu. + +If you want measures to be displayed on rows rather than on columns, drag the "Values" field from the Column Area to the Row Area. + +### Visualization rules + +You can add visualization rules to cells in the Pivot Grids, which is useful for highlighting cells based on their values, for example in order to better spot outliers. To add visualization rules, right-click on any Data Area cell in the Pivot Grid, and choose which rules to apply from the context menu (see screenshot below). + +![Customizing Pivot Grids](images/customizing-pivot-grids.png) + +## Persisting Pivot Grid layouts + +When you close a Pivot Grid, Tabular Editor will prompt you to save the layout of the Pivot Grid. If you choose to save the layout, the next time you open the Pivot Grid, it will be restored to the same layout as when you closed it. You can also save the layout of a Pivot Grid manually by hitting (Ctrl+S) or using the **File > Save** option, while the Pivot Grid is the active window. + +The file extension used for saving Pivot Grid layouts is `.te3pivot`. This is a simple json file that specifies which model objects are shown in the Pivot Grid, and in which areas they are placed. Objects are referenced by name and lineage tag (if present), so the Pivot Grid layout can generally be restored even if the model has been modified since the layout was saved. + +> [!NOTE] +> It is possible to open a Pivot Grid layout that was created in a different model, but be aware that the fields in the layout may not exist in the model you are currently connected to. In such cases, the Pivot Grid will show a warning message, and any fields that do not exist in the model will be removed from the layout. The warning message may be toggled off under **Tools > Preferences > Data Browsing > Pivot Grid > Show warning if Pivot Grid doesn't match model**. + +## Additional features + +The Pivot Grid has a few more features that are useful to know about: + +- If you right-click on a field, you will have the option to **Go to** that field. This brings the TOM Explorer into focus, with the equivalent model object selected. For measures and calculated columns, the **Expression Editor** will be brought into focus, with the DAX expression of the measure displayed. +- If you right-click on a cell in the Pivot Grid, you can select the option to **Debug this value**. This will launch the [**DAX Debugger**](xref:dax-debugger) starting from the specific measure and filter context that produced the value in the cell. + +## Limitations and known issues + +Below is a list of known limitations and issues with Pivot Grids in Tabular Editor 3.16.0, which we are working to address in future releases: + +- Format rules (such as icon sets, data bars, etc.) are not properly persisted when saving a Pivot Grid layout as a `.te3pivot` file. +- The .te3pivot file does not currently store the state of the "Show empty values on columns" and "Show empty values on rows" options. +- If you open a .te3pivot file on a model different from the one the layout was saved from, fields that do not exist in the current model will be removed from the layout. Hitting Save (Ctrl+S) will save the layout with the removed fields removed. We may change this behavior in a future release so that the .te3pivot file is not overwritten without explicit confirmation. \ No newline at end of file diff --git a/content/localization/de/policies_de.md b/content/localization/de/policies_de.md new file mode 100644 index 00000000..c83152d3 --- /dev/null +++ b/content/localization/de/policies_de.md @@ -0,0 +1,41 @@ +--- +uid: policies +title: Policies +author: Daniel Otykier +updated: 2024-10-30 +--- + +# Policies + +Some IT organisations may wish to limit certain features of Tabular Editor. This is possible through the use of group policies, by setting certain values in the Windows registry. + +> [!NOTE] +> This functionality requires the following versions of Tabular Editor: +> +> - Tabular Editor 2 version [2.17.0](https://github.com/TabularEditor/TabularEditor/releases/tag/2.17.0) or newer +> - Tabular Editor 3 version [3.3.5](https://github.com/TabularEditor/TabularEditor3/releases/tag/3.3.5) or newer. + +Below is a listing of the policies that can be controlled. To enforce one or more of these policies, add a non-zero DWORD value to the registry key. The name of the value specifies which policy to enforce. + +**Registry key:** HKEY_CURRENT_USER\Software\Policies\Kapacity\Tabular Editor\ + +| Value | When enforced... | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DisableUpdates | Tabular Editor will not check if newer versions are available online. Moreover, users cannot manually check if new updates are available through the tool. | +| DisableCSharpScripts | Tabular Editor will not let users create and execute C# scripts. | +| DisableMacros | Tabular Editor will not let users save or run macros. Moreover, macros defined in the %LocalAppData% folder will not be loaded and compiled upon application startup. | +| DisableBpaDownload | Tabular Editor will not allow Best Practice Analyzer rules to be downloaded from the web. | +| DisableWebDaxFormatter | Tabular Editor will disable the DAX code formatter, which performs a webrequest to daxformatter.com. (TE3 will still allow formatting code through the built-in DAX formatter) | +| DisableErrorReports | **(TE3 Only)** Tabular Editor will not allow users to send error/crash reports to the Tabular Editor 3 support team. | +| DisableTelemetry | **(TE3 Only)** Tabular Editor will not collect and send anonymous usage data to the Tabular Editor 3 support team. | +| DisableDaxOptimizer | **(TE3 Only)** The DAX Optimizer integration feature will not be available | +| DisableDaxOptimizerUpload | **(TE3 Only)** Users will not be allowed to upload VPAX files through the DAX Optimizer integration feature. Implicitly enforced when `DisableDaxOptimizer` is enforced. | +| RequireDaxOptimizerObfuscation | **(TE3 Only)** Users will not be allowed to upload un-obfuscated (clear text) VPAX files through the DAX Optimizer integration feature. Implicitly enforced when `DisableDaxOptimizer` or `DisableDaxOptimizerUpload` is enforced. | + +## Disabling web communications + +If you want to ensure that Tabular Editor does not perform web requests, specify the `DisableUpdates`, `DisableBpaDownload`, `DisableWebDaxFormatter`, `DisableErrorReports`, `DisableTelemetry`, ànd `DisableDaxOptimizer` policies. + +## Disabling custom scripts + +If you want to ensure that Tabular Editor does not allow users to execute arbitrary code, specify the `DisableCSharpScripts` and `DisableMacros` policies. diff --git a/content/localization/de/powerbi-cicd_de.md b/content/localization/de/powerbi-cicd_de.md new file mode 100644 index 00000000..04266dfb --- /dev/null +++ b/content/localization/de/powerbi-cicd_de.md @@ -0,0 +1,10 @@ +--- +uid: powerbi-cicd +title: Power BI CI/CD with Azure DevOps and Tabular Editor +author: Daniel Otykier +updated: 2021-10-04 +--- + +# Power BI CI/CD with Azure DevOps and Tabular Editor + +(WIP) \ No newline at end of file diff --git a/content/localization/de/powerbi-xmla-pbix-workaround_de.md b/content/localization/de/powerbi-xmla-pbix-workaround_de.md new file mode 100644 index 00000000..7f54228c --- /dev/null +++ b/content/localization/de/powerbi-xmla-pbix-workaround_de.md @@ -0,0 +1,98 @@ +--- +uid: powerbi-xmla-pbix-workaround +title: Creating PBIX File from XMLA Endpoint. +author: Morten Lønskov +updated: 2023-10-18 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + partial: Tabular Editor 3 Business Edition only allows connecting to the XMLA endpoint of Premium-Per-User (PPU) workspaces. + - edition: Enterprise +--- + +# Downloading a Power BI dataset to a .pbix using the XMLA endpoint + +Once a change is made to a Power BI semantic model through the XMLA endpoint, it's not possible to download the model as a .pbix file from the Power BI service. + +However, with the Power BI Project file, it's possible to create a .pbix file from the remote model by following the three-step process, which is described as follows. + +![XLMA to PBIX Overview](~/content/assets/images/power-bi/create-pbix-from-xmla-overview.png) + +> [!NOTE] +> The described workaround isn't officially supported by Microsoft. There's no guarantee that it works for every model. Specifically, if you've added custom partitions or other objects [listed here](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations), Power BI Desktop may not be able to correctly open the file following this approach. See below for a script to handle incremental refresh partitions. + +## Step 1: Create and save an empty Power BI projects (.pbip) file + +The first step is to create a new Power BI report and save it as an empty Power BI Project (.pbip) file, as depicted in the following diagram. + +![Save PBIP file](~/content/assets/images/power-bi/save-pbip-file.png) + +This creates a folder structure that contains an empty _model_ file. This _model_ file contains the model metadata. You'll overwrite this metadata in the next step with the metadata of the published model that you want to save to .pbix. + +![PBIP with Model file](~/content/assets/images/power-bi/pbip-file-bim-model.png) + +Close Power BI desktop, and proceed with the next step in Tabular Editor. + +## Step 2: Open XMLA model with Tabular Editor + +With Tabular Editor open, connect to the Fabric workspace via the XMLA endpoint. Load the Power BI semantic model you want to convert to a .pbix. + +## Step 3: Save XMLA model into .pbip + +In Tabular Editor using _File > Save as..._, navigate to the Power BI Project folder. Overwrite the _model.bim_ file shown in the previous diagram. + +This will save the remote model into the Power BI Project that will now contain the model metadata. + +If the .pbip folder is configured to store the model as [TMDL](xref:tmdl) files, you will need to use the Save To Folder option in Tabular Editor instead. Then navigate to the Power BI project folder for the semantic model (ModelName.SemanticModel), open the 'definition' folder and save your model there. + +> [!NOTE] +> To enable TMDL go to **Tools > Preferences > File Formats > Save-to-folder**, and select "TMDL" in the **Serialization mode** dropdown. See [TMDL documentation for more information](xref:tmdl) + +## Step 3.1: Remove incremental refresh partitions and create new (Optional) + +Use the Convert Incremental Refresh script below to delete incremental refresh partitions and create a single partition for each table containing the expression used in the incremental refresh expression. + +## Step 4: Save to .pbix and open this file in Power BI Desktop + +![PBIP with Tables](~/content/assets/images/power-bi/pbip-includes-tables.png) + +Open the .pbip and the Power BI report will now contain the XMLA endpoint semantic model. + +Save it to a .pbix using _File > Save As..._ in Power BI Desktop. + +## Re-hydrate .pbix + +The .pbix now contains the model that was published to the Fabric workspace. When you open the .pbix, you can _re-hydrate_ the file, meaning that you load the data based on the connections specified in the model. + +## Convert Incremental Refresh partitions + +The above step 4 will fail if the semantic model has incremental refresh enabled as a Power BI desktop model cannot contain multiple partitions. +In this case the following script should be run against the model to convert incremental refresh partitions into single partitions + +```csharp +foreach (var t in Model.Tables) +{ + if(t.EnableRefreshPolicy) + { + //We will collect the SourceExpression from the Incremental Refresh Source Expression of the table + string m_expression = t.SourceExpression.ToString(); + + //We will generate a new partition name + string partition_name = t.Name + "-" + Guid.NewGuid(); + + //Now we will create a new partition + var partition = t.AddMPartition(partition_name, m_expression); + partition.Mode = ModeType.Import; + + //Next we will delete all the incremental refresh partitions of the table + foreach (var p in t.Partitions.OfType().ToList()) + { + p.Delete(); + } + } +}; +``` + +Thank you to [Micah Dail](https://twitter.com/MicahDail) for creating the script and suggesting it to be included in this document. diff --git a/content/localization/de/powerbi-xmla_de.md b/content/localization/de/powerbi-xmla_de.md new file mode 100644 index 00000000..d4bb1390 --- /dev/null +++ b/content/localization/de/powerbi-xmla_de.md @@ -0,0 +1,52 @@ +--- +uid: powerbi-xmla +title: Editing through XMLA endpoint +author: Daniel Otykier +updated: 2021-10-01 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + partial: Tabular Editor 3 Business Edition only allows connecting to the XMLA endpoint of Premium-Per-User (PPU) workspaces. + - edition: Enterprise +--- + +# Editing a Power BI dataset through the XMLA endpoint + +You can use Tabular Editor 3 to connect to a Power BI dataset published to the Power BI service through the [XMLA endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools). The XMLA endpoint is available for Power BI Premium Capacity workspaces (i.e. workspaces assigned to a Px, Ax or EMx SKU), or Power BI Premium-Per-User (PPU) workspaces. + +> [!NOTE] +> Power BI Pro licenses are not sufficient for accessing Power BI datasets in a shared workspace. Premium/Embedded capacity or Premium-Per-User Power BI licensing is required for XMLA access. + +## Prerequisites + +Tabular Editor requires the XMLA endpoint to allow both read/write access. This setting is controlled by [your capacity admin](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#enable-xmla-read-write). + +> [!IMPORTANT] +> If using Tabular Editor 3 be aware of the [license limitations](xref:editions) for connecting to the Power BI XMLA endpoint. You need at least Tabular Editor 3 Business or Enterprise Edition depending on the type of Power BI Workspace used. + +## Limitations + +When connecting to a dataset through the XMLA endpoint, all data modeling operations supported by the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) are available for editing. In other words, the [Power BI Desktop Limitations](xref:desktop-limitations) do not apply when editing a dataset through the XMLA endpoint of the Power BI Service. + +> [!WARNING] +> Once a change is made to a Power BI dataset through the XMLA endpoint, it will not be possible to download the dataset as a .pbix file. [More information](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#power-bi-desktop-authored-datasets). +> Please see [Creating PBIX File from XMLA Endoint](xref:powerbi-xmla-pbix-workaround) for a workaround + +## Workflow + +The Power BI XMLA endpoint essentially exposes an instance of Analysis Services that Tabular Editor can connect to. As such, you can treat the Power BI workspace as the Analysis Services **server** with each Power BI dataset in the workspace corresponding to an Analysis Services **database**. All of Tabular Editor's modeling and management features are available when connecting to the XMLA endpoint. If you decide to use Tabular Editor to build and maintain your Power BI datasets, you should also consider some kind of version control system for your model metadata. + +The workflow is then: + +1. Create a new data model in Tabular Editor or connect to an existing dataset through the Power BI XMLA endpoint +2. Save this model as a **Model.bim** file or use Tabular Editor's [Save to folder](xref:save-to-folder) option. +3. Whenever you want to make changes to the model, load the file/folder you saved in step 2. The first time you do this, decide whether you want to use a [workspace database](xref:workspace-mode) or not. +4. Once you are ready to publish your changes to the Power BI service, perform a deployment through Tabular Editor (**Model > Deploy...**), thus creating a new or overwriting an existing dataset in a Power BI workspace. + +## Next steps + +- @new-pbi-model +- @workspace-mode +- @importing-tables \ No newline at end of file diff --git a/content/localization/de/preferences_de.md b/content/localization/de/preferences_de.md new file mode 100644 index 00000000..006c62c8 --- /dev/null +++ b/content/localization/de/preferences_de.md @@ -0,0 +1,77 @@ +--- +uid: preferences +title: Controlling preferences +author: Daniel Otykier +updated: 2021-09-08 +--- + +# Tabular Editor 3 Preferences + +Tabular data model development processes and workflows differ greatly from organization to organization. To ensure that the tool can fit into as many of these workflows as possible, Tabular Editor 3 is highly customizable - not just in terms of the user interface's look and feel, but also on more advanced topics such as web proxies, updates and feedback, row limits, timeouts, schema compare preferences, etc. + +This article describes the Tabular Editor 3 Preferences dialogs and the settings that you can control through it. + +To access the preferences dialog, go to **Tools > Preferences**. + +> [!NOTE] +> All Tabular Editor preferences are stored for each Windows user profile, in the `%localappdata%\TabularEditor3` folder. It is possible to migrate your settings to another machine by simply copying the contents of this folder. + +## Tabular Editor > Features + +![image](https://user-images.githubusercontent.com/8976200/104600495-5ad6f300-5679-11eb-9572-af99f0895859.png) + +### Power BI + +- **Allow unsupported editing**: This option is only relevant when Tabular Editor 3 is used as an external tool for Power BI Desktop. When checked, all TOM data modeling properties are available for editing when connected to an instance of Power BI Desktop. It's generally recommended to leave this unchecked, to make sure that you do not accidentally make changes to your Power BI file, [that are not supported by Power BI Desktop](xref:desktop-limitations). + +### Metadata Synchronization + +- **Warn when local metadata is out-of-sync with deployed model**: When checked, an information bar is displayed inside Tabular Editor, whenever you have made local changes to the model that have not yet been saved to Analysis Services. For example, if you're wondering why a DAX query or a Pivot Grid does not produce the expected result, this could be due to a measure expression being changed in Tabular Editor without saving the change to Analysis Services. The bar disappears when you hit save (Ctrl+S). Uncheck this if you get tired of seeing the information bar. +- **Track external model changes**: Just like Power BI Desktop can detect when an external tool makes a change to the data model, so too can Tabular Editor. In other words, when this is checked, and another user or application makes a change to the model _on a local instance of Analysis Services_, Tabular Editor will receive a notification. + - **Refresh local Tabular Object Model metadata automatically**: Check this if you want the notification from above to actually trigger a refresh of the metadata inside Tabular Editor. + +### Best Practice Analyzer + +- **Scan for Best Practice violations in the background** If unchecked, you will have to explicitly run a Best Practice Analysis from inside the Best Practice Analyzer tool window, to view if there are any violations. If checked, the scan happens continuously on a background thread whenever changes are made. For very large models, or models with very complex Best Practice rules, this may cause issues. + +## Tabular Editor > Updates and Feedback + +![image](https://user-images.githubusercontent.com/8976200/104601469-92926a80-567a-11eb-9499-1d1c8d967c72.png) + +- **Check for updates on start-up**: Pretty self-explanatory. Update notifications will not be sent during the public preview period, and the "Check for updates" button below also does not work at the moment. +- **Help improve Tabular Editor by collecting anonymous usage data**: Data does not contain any personally identifiable information, nor any information about the structure or content of your data models. If you would still like to opt out of telemetry, uncheck this. +- **Send error reports**: In cases of crashes, Tabular Editor displays an option for sending a crash report when this is checked. Crash reports are very helpful when debugging, so please leave this checked if you don't mind! + +## Tabular Editor > Keyboard + +![image](~/content/assets/images/keyboard-mappings.png) + +## Data Browsing > Pivot Grid / DAX Query + +![image](https://user-images.githubusercontent.com/8976200/104601874-0df41c00-567b-11eb-8ba1-41a992e5664f.png) + +More configuration options will certainly follow at some point, but this setting allows you to indicate whether new Pivot Grids or DAX Query windows will automatically be refreshed, by default, when model changes are saved to Analysis Services. You can change this behavior on a per-window basis by toggling the "Auto-execute" button as seen on the screenshot below: + +![image](https://user-images.githubusercontent.com/8976200/104602109-56abd500-567b-11eb-9e8f-32ab58390449.png) + +This feature is super-useful when debugging a measure for example: Update the measure expression in one window, while having a Pivot Grid or a DAX query that uses that measure open in another window. Whenever you hit CTRL+S, the Pivot Grids or DAX Queries are automatically refreshed to immediately show the impact of the change you made. + +## DAX Editor > General + +![image](https://user-images.githubusercontent.com/8976200/104602381-a7233280-567b-11eb-8151-cf810b7cb748.png) + +Now we're starting to get to the good stuff! This page provides a number of settings for general configuration of the DAX editor. Make sure you try out the "Code folding" feature! + +- **DAX function documentation**: Use this setting to specify which URL to launch in the default web browser, whenever you hit F12 while the cursor is on a DAX function. I recommend using https://dax.guide but some people tend to like Microsoft's official documentation (which is available in the drop down). + +## DAX Editor > Auto Formatting + +![image](https://user-images.githubusercontent.com/8976200/104602767-084b0600-567c-11eb-88ea-018e3d436f68.png) + +As can be seen from the screenshot above, the new DAX Editor is **very** powerful and helps you produce beautiful, readable DAX code, as you type. Feel free to experiment with these settings to figure out what editor behavior works best for you, and don't forget to provide [feedback](https://github.com/TabularEditor3/PublicPreview/issues/new) if something does not work as you expect, or if you have any ideas for additional improvements. + +## DAX Editor > Code Assist + +![image](https://user-images.githubusercontent.com/8976200/104603313-90311000-567c-11eb-853d-6ca6e0f0ed07.png) + +On this page, you can configure the two most important Code Assist features, namely calltips (aka. "parameter info") and auto-complete. The settings mostly control under what circumstances the calltips and auto-complete box appears on the screen. However, for the auto-complete, there are a number of features for controlling which items are suggested, whether table names should always be quoted, incremental search, etc. diff --git a/content/localization/de/privacy-policy_de.md b/content/localization/de/privacy-policy_de.md new file mode 100644 index 00000000..bb3d9958 --- /dev/null +++ b/content/localization/de/privacy-policy_de.md @@ -0,0 +1,171 @@ +--- +uid: privacy-policy +title: Privacy Policy +author: Søren Toft Joensen +updated: 2021-09-08 +--- + +# Privacy Policy + +Tabular Editor ApS ("we," "our," or "us") is committed to protecting your privacy. This Privacy Policy explains how your personal information is collected, used, and disclosed by Tabular Editor ApS. + +This Privacy Policy applies to our website, and its associated subdomains (collectively, our "Service") alongside our application, Tabular Editor 3. By accessing or using our Service, you signify that you have read, understood, and agree to our collection, storage, use, and disclosure of your personal information as described in this Privacy Policy and our Terms of Service. + +#### Definitions and key terms + +To help explain things as clearly as possible in this Privacy Policy, every time any of these terms are referenced, they are defined as follows: + +- _Cookie_: small amount of data generated by a website and saved by your web browser. It is used to identify your browser, provide analytics, remember information about you such as your language preference or login information. +- _Company_: when this policy mentions "Company," "we," "us," or "our," it refers to Tabular Editor ApS, (Gærtorvet 3, 2. floor, 1799 Copenhagen V, Denmark) that is responsible for your information under this Privacy Policy. +- _Country_: where Tabular Editor ApS or the owners/founders of Tabular Editor ApS are based, in this case is Denmark +- _Customer_: refers to the company, organization or person that purchases a subscription for Tabular Editor 3. +- _Device_: any internet connected device such as a phone, tablet, computer or any other device that can be used to visit tabulareditor.com and/or use the Tabular Editor 3 product. +- _IP address_: Every device connected to the Internet is assigned a number known as an Internet protocol (IP) address. These numbers are usually assigned in geographic blocks. An IP address can often be used to identify the location from which a device is connecting to the Internet. +- _Personnel_: refers to those individuals who are employed by Tabular Editor ApS or are under contract to perform a service on behalf of one of the parties. +- _Personal Data_: any information that directly, indirectly, or in connection with other information — including a personal identification number — allows for the identification or identifiability of a natural person. +- _Service_: refers to the service provided by Tabular Editor ApS as described in the relative terms (if available) and on this platform. +- _Third-party service_: refers to advertisers, contest sponsors, promotional and marketing partners, and others who provide our content or whose products or services we think may interest you. +- _Website_: Tabular Editor ApS’ site, which can be accessed via this URL: https://tabulareditor.com. + +#### What Information Do We Collect? + +We collect the following information from you when you visit our website, register on our site, place an order, subscribe to our newsletter, respond to a survey or fill out a form: + +- Name +- Email Addresses +- Billing Addresses +- Other personal information that you may submit to us + +#### How Do We Use The Information We Collect? + +Any of the information we collect from you may be used in one of the following ways: + +- To personalize your experience (your information helps us to better respond to your individual needs). +- To improve our website (we continually strive to improve our website/app offerings based on the information and feedback we receive from you). +- To improve customer service (your information helps us to more effectively respond to your customer service requests and support needs). +- To process transactions. +- To send periodic emails. + +#### What is the legal basis for our processing of your personal data? + +Our legal bases for the processing of your personal data for the above purposes are: + +- Fulfilment of contract for the purchase of products or services (the GDPR art. 6 (1) (b)). +- Fulfilment of contract for the provision of services (the GDPR art. 6 (1) (b)). +- Our legal obligations as data controller (the GDPR art. 6 (1) (c)). +- Consent to newsletter send-out and other direct marketing (the GDPR art. 6 (1) (a)). +- Legitimate interest in being able to send out service messages (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to facilitate communications and respond to your comments questions and requests (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to send out customer satisfaction surveys (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to establish, exercise or defence legal claims (the GDPR art. 6 (1) (f) and the GDPR art. 9 (2) (f)). +- Legitimate interest in being able to collect, and administrate your data, also based on your click behaviour in relation to marketing send outs and via cookies on our website (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to personalize and improve our Services and provide tailored content or features for marketing purposes (the GDPR art. 6 (1) (f)). + +#### Do we share the information we collect with third parties? + +Data processors: + +We do not share the information that we collect with third parties, with the following exceptions: + +We may engage trusted third party service providers acting as data processors to perform functions and provide services to us, such as hosting and maintaining our servers and the website/app, database storage and management, e-mail management, storage marketing, credit card processing, customer service and fulfilling orders for products and services you may purchase through the website/app. We will likely share your personal information, and possibly some non-personal information, with these third parties to enable them to perform these services for us and for you. + +The data processors will not review, share, distribute, or reference any collected information except to the extent they are so instructed by us. All data processors have implemented security measures to protect against unauthorized access, loss, use or alteration of the information. Further, data processing agreements have been entered into with all data processors. + +Currently we use the following data processors:. + +| Name | Location | Purpose of sub-data processing | Which data? | +| ----------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| Chargebee Inc. | AWS EU Data centre in Frankfurt, Germany | Subscription management, including handling of invoicing. | E-mail addresses, name of contact person, billing address and billing information. | +| Amazon.com Inc. | As above | Hosting of the above- mentioned information on behalf of Chargebee Inc. | As above | +| Microsoft | Azure West EU Data Center, Amsterdam, Netherlands | License management | E-mail address and name of contact person/license administrator | + +Other third parties: + +We may share portions of our log file data, including IP addresses, for analytics purposes with third parties such as web analytics partners, application developers, and ad networks. If your IP address is shared, it may be used to estimate general location and other technographics such as connection speed, whether you have visited the website/app in a shared location, and type of the device used to visit the website/app. They may aggregate information about our advertising and what you see on the website/app and then provide auditing, research and reporting for us and our advertisers. + +We may also disclose personal and non-personal information about you to government or law enforcement officials or private parties as we, in our sole discretion, believe necessary or appropriate in order to respond to claims, legal process (including subpoenas), to protect our rights and interests or those of a third party, the safety of the public or any person, to prevent or stop any illegal, unethical, or legally actionable activity, or to otherwise comply with applicable court orders, laws, rules and regulations. + +#### How Do We Use Your Email Address? + +By submitting your email address on this website/app, you agree to receive emails from us. You can cancel your participation in any of these email lists at any time by clicking on the opt-out link or other unsubscribe option that is included in the respective email. We only send emails to people who have authorized us to contact them, either directly, or through a third party. We do not send unsolicited commercial emails, because we hate spam as much as you do. Email addresses submitted only through the order processing page will be used for the sole purpose of sending you information and updates pertaining to your order. If, however, you have provided the same email to us through another method, we may use it for any of the purposes stated in this Policy. + +Note: If at any time you would like to unsubscribe from receiving future emails, we include detailed unsubscribe instructions at the bottom of each email. + +#### How Long Do We Keep Your Information? + +We keep your information only so long as we need it to provide Tabular Editor 3 to you and/or fulfil the purposes described in this policy. This is also the case for anyone that we share your information with and who carries out services on our behalf. When we no longer need to use your information and there is no need for us to keep it to comply with our legal or regulatory obligations, we’ll either remove it from our systems or depersonalize it so that we can’t identify you. + +#### How Do We Protect Your Information? + +We implement a variety of security measures to maintain the safety of your personal information when you place an order or enter, submit, or access your personal information. We offer the use of a secure server. All supplied sensitive/credit information is transmitted via Secure Socket Layer (SSL) technology and then encrypted into our Payment gateway providers database only to be accessible by those authorized with special access rights to such systems, and are required to keep the information confidential. After a transaction, your private information (credit cards, social security numbers, financials, etc.) is never kept on file. We cannot, however, ensure or warrant the absolute security of any information you transmit to Tabular Editor ApS or guarantee that your information on the Service may not be accessed, disclosed, altered, or destroyed by a breach of any of our physical, technical, or managerial safeguards. + +Credit Card information is collected and processed only by our payment/subscription partner, which currently is Chargebee.com. Tabular Editor ApS does not collect or store Credit Card information. + +#### Could my information be transferred to other countries? + +Tabular Editor ApS is incorporated in Denmark. Information collected via our website, through direct interactions with you, or from use of our help services may be transferred from time to time to our offices or personnel, or to third parties within the EU/EEA. We do not transfer your information to unsecure third countries, i.e. countries outside of EU/EEA that have not been considered by the Commission to have an adequate level of data protection. + +#### Is the information collected through the Tabular Editor Service secure? + +We take precautions to protect the security of your information. We have physical, electronic, and managerial procedures to help safeguard, prevent unauthorized access, maintain data security, and correctly use your information. However, neither people nor security systems are fool proof, including encryption systems. In addition, people can commit intentional crimes, make mistakes or fail to follow policies. Therefore, while we use reasonable efforts to protect your personal information, we cannot guarantee its absolute security. If applicable law imposes any non-disclaimable duty to protect your personal information, you agree that intentional misconduct will be the standards used to measure our compliance with that duty. + +#### Can I update or correct my information and which other rights to I have? + +Customers and users of our website have the right to request the restriction of certain uses and disclosures of personally identifiable information as follows: You can contact us in order to (1) receive information about which personal data we are processing about you and for what purposes, (2) to have personal information that we are processing about you transferred to another service provider (data portability), if applicable, (3) update or correct your personally identifiable information, (4) change your preferences with respect to communications and other information you receive from us, or (5) delete the personally identifiable information maintained about you on our systems (subject to the following paragraph), by cancelling your account. + +Such updates, corrections, changes and deletions will have no effect on other information that we maintain, or information that we have provided to third parties in accordance with this Privacy Policy prior to such update, correction, change or deletion. + +To protect your privacy and security, we may take reasonable steps (such as requesting a unique password) to verify your identity before granting you profile access or making corrections. You are responsible for maintaining the secrecy of your unique password and account information at all times. + +Promptly after receiving your request, all personal information stored in databases we actively use, and other readily searchable media will be updated, corrected, changed or deleted, as appropriate, as soon as and to the extent reasonably and technically practicable. + +If you are an end user and wish to update, delete, or receive any information we have about you, you may do so by contacting at the following e-mail address: [contact@tabulareditor.com](mailto:contact@tabulareditor.com). + +You may also use this mail address to withdraw any consents to our processing of your personal data. + +#### Sale of Business + +We reserve the right to transfer information to a third party in the event of a sale, merger or other transfer of all or substantially all of the assets of Tabular Editor or any of its Corporate Affiliates (as defined herein), or that portion of Tabular Editor or any of its Corporate Affiliates to which the Service relates, or in the event that we discontinue our business or file a petition or have filed against us a petition in bankruptcy, reorganization or similar proceeding, provided that the third party agrees to adhere to the terms of this Privacy Policy. + +#### Governing Law + +This Privacy Policy is governed by the laws of Denmark without regard to its conflict of laws provision. +The laws of Denmark, excluding its conflicts of law rules, shall govern any contracts we enter with you and your use of the website/app. Your use of the website/app may also be subject to other local, state, national, or international laws. + +#### Acceptance of this Privacy Policy + +By using Tabular Editor or contacting us directly, you signify your acceptance of this Privacy Policy. If you do not agree to this Privacy Policy, you should not engage with our website, or use our services. Continued use of the website, direct engagement with us, or following the posting of changes to this Privacy Policy that do not significantly affect the use or disclosure of your personal information will mean that you accept those changes. + +We’ve updated our Privacy Policy to provide you with complete transparency into what is being set when you visit our site and how it’s being used. By using our website/app, registering an account, or making a purchase, you hereby consent to our Privacy Policy and agree to its terms. + +#### Links to Other Websites + +This Privacy Policy applies only to the Services. The Services may contain links to other websites not operated or controlled by Tabular Editor. We are not responsible for the content, accuracy or opinions expressed in such websites, and such websites are not investigated, monitored or checked for accuracy or completeness by us. Please remember that when you use a link to go from the Services to another website, our Privacy Policy is no longer in effect. Your browsing and interaction on any other website, including those that have a link on our platform, is subject to that website’s own rules and policies. Such third parties may use their own cookies or other methods to collect information about you. + +\####Cookies +tabulareditor.com uses "Cookies" to identify the areas of our website that you have visited. We use Cookies to enhance the performance and functionality of our website/app but are non-essential to their use. However, without these cookies, certain functionality like videos may become unavailable or you would be required to enter your login details every time you visit the website/app as we would not be able to remember that you had logged in previously. Most web browsers can be set to disable the use of Cookies. However, if you disable Cookies, you may not be able to access functionality on our website correctly or at all. We never place Personally Identifiable Information in Cookies. + +You should also be aware that you may also lose some saved information (e.g. saved login details, site preferences) if you block cookies on your browser. Different browsers make different controls available to you. Disabling a cookie or category of cookie does not delete the cookie from your browser, you will need to do this yourself from within your browser, you should visit your browser’s help menu for more information. + +#### Payment Details + +In respect to any credit card or other payment processing details you have provided us, we commit that this confidential information will be stored in the most secure manner possible. + +#### Kids’ Privacy + +We do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 13 without verification of parental consent, We take steps to remove that information from Our servers. + +#### Changes To Our Privacy Policy + +We may change our Service and policies, and we may need to make changes to this Privacy Policy so that they accurately reflect our Service and policies. Unless otherwise required by law, we will notify you (for example, through our Service) before we make changes to this Privacy Policy and give you an opportunity to review them before they go into effect. Then, if you continue to use the Service, you will be bound by the updated Privacy Policy. If you do not want to agree to this or any updated Privacy Policy, you can delete your account. + +#### Contact Us + +Don’t hesitate to contact us if you have any questions. + +- Via Email: contact@tabulareditor.com +- Via this Link: https://tabulareditor.com/contact + +#### Complaints + +If you wish to complain about the processing of your personal data, please contact us at [contact@tabulareditor.com](mailto:contact@tabulareditor.com). You may also contact the Data Protection Agency, Borgergade 28, 5., 1300 Copenhagen K. diff --git a/content/localization/de/properties-view_de.md b/content/localization/de/properties-view_de.md new file mode 100644 index 00000000..380903ff --- /dev/null +++ b/content/localization/de/properties-view_de.md @@ -0,0 +1,34 @@ +--- +uid: properties-view +title: Properties view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Using the Properties grid in Tabular Editor 3 + +The Properties view in Tabular Editor 3 allows you to inspect and modify the properties of any object in your tabular model. +You access the properties view by selecting an object in the TOM Explorer. You will then see a list of properties that are relevant for the selected object type, such as name, description, data type, format string, etc. +You can also access advanced properties that are not available in other tools like Visual Studio or Power BI Desktop. + +
    + Properties View
    Figure 1: Example of Properties for a table. Each object has different properties depending on its type
    +
    + +The Properties view helps you to: + +- View and modify the properties of any object in the model, such as tables, columns, measures, hierarchies, relationships, partitions, roles and perspectives. +- Filter and sort the properties by name or category using the search box and the buttons at the top of the view. +- Copy and paste property values between different objects using Ctrl+C and Ctrl+V shortcuts. +- Undo and redo property changes using Ctrl+Z and Ctrl+Y shortcuts. +- You can use keyboard shortcuts to quickly navigate and edit your properties. For example, you can press Ctrl+Up or Ctrl+Down to move between different properties; press Enter or F2 to edit a property value; press Esc to cancel editing; press Ctrl+S to save changes; + +> [!TIP] +> You can multi-select objects to see the properties they have in common and edit them in bulk. This can be useful for setting Format Strings, for example. + +The Properties view is by default in the bottom right corner, but you can also open it by pressing F4 on your keyboard. You can also dock it to any side of the main window or undock it as a separate window. diff --git a/content/localization/de/proxy-settings_de.md b/content/localization/de/proxy-settings_de.md new file mode 100644 index 00000000..13661a65 --- /dev/null +++ b/content/localization/de/proxy-settings_de.md @@ -0,0 +1,99 @@ +--- +uid: proxy-settings +title: Proxy settings +author: Daniel Otykier +updated: 2024-11-07 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Proxy settings + +Due to different proxy behavior between .NET Core (used by Tabular Editor 3) and .NET Framework (used by Tabular Editor 2 and DAX Studio), you may experience issues with connecting to external services, such as the Power BI service, when using Tabular Editor 3 behind a proxy server. + +For example, you might see the following error message when trying to connect to the Power BI service: + +![No such host is known-error](~/content/assets/images/proxy-error.png) + +Typical error messages you would see, are: + +**Title:** `Could not connect to server` + +**Message:** + +- `No such host is known. (login.microsoftonline.com:443)` +- `Unable to obtain authentication token using the credentials provided` +- `The requested address is not valid in its context. (login.microsoftonline.com:443)` + +When this happens, the first thing you should try is to change the proxy settings in Tabular Editor 3. You can find these settings under **Tools > Preferences > Proxy Settings**: + +![Proxy settings in Tabular Editor 3](~/content/assets/images/proxy-settings.png) + +In most cases, changing the **Proxy Type** from `None` to `System` will resolve the issue. This setting tells Tabular Editor 3 to use the system-wide proxy settings configured in Windows. If you are still experiencing issues, you can try setting the **Proxy Type** to `Custom` and enter the proxy server address and port manually. + +> [!IMPORTANT] +> After changing the proxy settings, you must restart Tabular Editor 3 for the changes to take effect. + +# .NET Core vs. .NET Framework proxy handling + +If the suggestion above does not solve the problem, starting with version 3.21.0 of Tabular Editor, you can try the following alternative solution: + +> [!NOTE] +> The solutions outlined below require Tabular Editor 3.21.0 or newer, because the AS configuration options are only available in the AMO/TOM client library v. [19.94.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.94.1.1). Previous versions of Tabular Editor 3 use an older version of this client library, which ignores these configuration options. + +Create a file called **AnalysisServices.AppSettings.json** and put it in the installation folder for Tabular Editor 3 (i.e. the same folder that TabularEditor3.exe resides in). Add the following content to the file: + +```json +{ + "asConfiguration": { + "authentication": { + "msalConnectivityMode": "external" + } + } +} +``` + +To turn on external MSAL proxy support for all .NET core applications on your machine, you can also set the following environment variable rather than using the AppSettings file as described above: + +| Environment variable name | Environment variable value | +| -------------------------------------------------------------------- | -------------------------- | +| MS_AS_MsalConnectivityMode | 1 | + +# Enabling diagnostics + +If you're still not able to connect after attempting the solutions outlined above, it may help to turn on advanced diagnostics logging. You can do that, either by modifying the **AnalysisServices.AppSettings.json** file to look like the following: + +```json +{ + "asConfiguration": { + "authentication": { + "msalConnectivityMode": "external" + }, + "diagnostics": { + "authenticationTrace": { + "isEnabled": true, + "traceLevel": 4, + "fileName": "" + } + } + } +} +``` + +or if using Environment Variables, by setting the following: + +| Environment variable name | Environment variable value | +| ---------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| MS_AS_AADAUTHENTICATOR_LOG | 1 | +| MS_AS_AADAUTHENTICATOR_LOGLEVEL | 4 | +| MS_AS_AADAUTHENTICATOR_LOGFILE | \ | + +`` must point to a file in a directory that exists. I.e. if you want the file to be written to `c:\temp\logs\as-auth.log`, you must ensure that the directory `c:\temp\logs` exists. + +The contents of this trace file is useful when contacting Microsoft support. + +> [!IMPORTANT] +> You must restart Tabular Editor 3 after making changes to the **AnalysisServices.AppSettings.json** file, or after modifying environment variables. \ No newline at end of file diff --git a/content/localization/de/refresh-preview-query_de.md b/content/localization/de/refresh-preview-query_de.md new file mode 100644 index 00000000..ba295b87 --- /dev/null +++ b/content/localization/de/refresh-preview-query_de.md @@ -0,0 +1,163 @@ +--- +uid: refresh-preview-query +title: Refreshing, previewing and querying data +author: Daniel Otykier +updated: 2021-09-30 +applies_to: + editions: + - edition: Desktop + partial: Refreshing tables through external tools is currently not supported by Power BI Desktop, even though Tabular Editor 3 Desktop Edition allows this operation. Querying data is fully supported. + - edition: Business + - edition: Enterprise +--- + +# Refreshing, previewing and querying data + +When Tabular Editor 3 is connected to an instance of Analysis Services, a number of additional **connected features** are available, allowing you to use Tabular Editor 3 as a client tool for Analysis Services. + +> [!NOTE] +> The phrase "connected to an instance of Analysis Services" means any one of the following: +> +> - Loading a model in [**workspace mode**](xref:workspace-mode) +> - Loading a model directly from SQL Server Analysis Services, Azure Analysis Services or the Power BI XMLA endpoint +> - Using Tabular Editor 3 as an external tool for Power BI Desktop + +In summary, these connected features are: + +- Data refresh operations +- Table data previewing +- PivotGrids +- DAX Querying +- VertiPaq Analyzer + +# Refreshing data + +Tabular Editor does not automatically trigger refresh operations in Analysis Services when changes are made to the data model. This is by design, to ensure that saving metadata changes to Analysis Services does not take too long. Potentially, a refresh operation can take a long time to complete, during which no additional metadata may be updated on the server. Of course, the drawback of this, is that you can make changes using Tabular Editor, which causes the model to enter a state where it is only partly queryable or not queryable at all. Depending on what type of data model change was made, different levels of refresh may be needed. + +In general, the following changes require a full refresh, before the mentioned object can be queried (that is, a data refresh followed by a calculate refresh): + +- Adding a new table to the model +- Adding a new column to a table + +In general, the following changes require a calculate refresh: + +- Changing the DAX expression of a calculated table or calculated column +- Adding or modifying a relationship +- Adding, renaming or removing a calculation item from a calculation group + +Notably, adding, modifying or removing measures from a model does not require any type of refresh (unless the measure is referenced by a calculated column, in which case the table in which that column resides has to be recalculated). + +To initiate a refresh using Tabular Editor, simply right click on the Table or Partition you wish to refresh, navigate to **Refresh table** or **Refresh partition**, and then choose the type of refresh you want to perform. + +![Refresh Table](~/content/assets/images/refresh-table.png) + +You may also initiate a refresh at the model level through the **Model > Refresh model** menu. Once the refresh operation starts, you will see the text "Data refresh started... View refresh queue". Click on the link or locate the **Data refresh** view through the **View > Data refresh** menu option. This will display a list of all refresh operations (both present and current), displaying the status message returned from Analysis Services including progress counters and duration, and allowing you to cancel an unintended refresh. + +![Data Refresh View2](~/content/assets/images/data-refresh-view2.png) + +While a refresh is in progress you can continue work on your data model, querying and previewing data or queueing new data refresh operations according to this article. However, you will not be able to save model changes to Analysis Services until the all data refresh operations complete. + +> [!NOTE] +> Currently, [Power BI Desktop does not support refresh operations triggered from external tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). For this reason, Tabular Editor 3 hides these options when connected to an instance of Power BI Desktop. You can override this behavior by enabling **Tools > Preferences > Allow unsupported modeling operations**. + +## Supported refresh operations + +Tabular Editor 3 supports refresh operations on different object types. The supported refresh types are shown below: + +- **Model** (Automatic, calculate, full) +- **(Imported) Table** (Automatic, calculate, data only, full) +- **Partition** (Full) +- **Calculated Table** (Calculate) +- **Calculation Group** (Calculate) + +See [Refresh Types](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#request) for more information about the types of refresh operations supported by Analysis Services / Power BI. + +# Previewing table data + +At certain points during DAX authoring and data model development, you may need to inspect the contents of your tables on a row-by-row basis. Of course, you could write a DAX query to achieve this, but Tabular Editor 3 makes that even easier by allowing you to preview table data directly. To do this, right-click on a table and choose the **Preview data** option. + +![Preview Data](~/content/assets/images/preview-data-big.png) + +You can open multiple such table previews and arrange them anyway you like in the user interface. In addition, you can sort or filter individual columns. There is no practical limit to the number of rows that can be previewed. Tabular Editor simply executes a [`TOPNSKIP`](https://dax.guide/topnskip) DAX query against the model, to return just a small number of records suitable to fill the current view. + +If one or more calculated columns are in an invalid state, those columns contain the text _(Calculation needed)_. You can recalculate the table by right-clicking on the column and choosing the **Recalculate table...** option. + +![Recalculate Table](~/content/assets/images/recalculate-table.png) + +# Pivot Grids + +After adding or editing DAX measures in a model, it is common for model developers to test these measures. Traditionally, this was typically done using client tools such as Excel or Power BI. With Tabular Editor 3, you can now use **Pivot Grids** which behave much like the famous PivotTables of Excel. The Pivot Grid lets you quickly create summarized views of the data in your model, allowing you test the behavior of your DAX measures when filtering and slicing by various columns and hierarchies. + +To create a new Pivot Grid, use the **File > New > Pivot Grid** option. From here, you can either drag measures, columns and hierarchies from the TOM Explorer into the grid, or you can use the **Pivot Grid > Show fields** menu option to display a popup list of all fields that can be dragged into the Pivot Grid (see screenshot below). + +![Show Fields Pivot](~/content/assets/images/show-fields-pivot.png) + +As fields are dragged into the Pivot Grid, Tabular Editor generates MDX queries that are sent to Analysis Services, to display the resulting data. In this regard, the behavior is very similar to Pivot Tables in Excel. You can rearrange fields in the Pivot Grid by dragging and dropping, and there are various right-click menu options available for customizing how the data is displayed. + +![Customizing Pivot Grids](~/content/assets/images/customizing-pivot-grids.png) + +The Pivot Grid is automatically refreshed when a change is made to the model or a refresh operation finishes. You can toggle this auto-refresh capability within the **Pivot Grid** menu. + +# DAX Queries + +A more direct way to query the data in your model, is to write a DAX query. Use the **File > New > DAX Query** menu option to create a new DAX query document. You can have multiple DAX query documents open at the same time. + +DAX queries can be saved and loaded to and from standalone files using the `.dax` or `.msdax` file extension. See @supported-files for more information. + +Type your DAX `EVALUATE` query into the editor and hit **Query > Execute** (F5) to send the query to Analysis Services and see the result. By default, Tabular Editor 3 limits the number of rows returned from Analysis Services to 1000, but this can be changed under **Tools > Preferences > Data Browsing > DAX Query**. If a query exceeds this limit, Tabular Editor 3 displays a shortcut that lets you retrieve all records (see screenshot below). + +![Query Rowset Limit](~/content/assets/images/query-rowset-limit.png) + +> [!WARNING] +> Displaying a large number of records in the query result window could take a while and drastically increase the memory consumed by Tabular Editor 3. + +Tabular Editor 3 uses the same DAX code editor for query editing as for defining DAX expressions on objects. As such, all the features regarding code-completion, auto-formatting, etc. are available. See @dax-editor for more information. In addition, since a DAX query has a slightly different syntax than object expressions, the DAX query editor provides a few more options for common tasks. + +For example, if you right-click on a measure reference, there is an option to **Define measure** as seen on the screenshot below. This option will add a `DEFINE MEASURE` statement at the top of your DAX query, allowing you to easily modify the DAX expression of that measure within the scope of the query. + +![Dax Query Features](~/content/assets/images/dax-query-features.png) + +In addition, a DAX query can contain multiple `EVALUATE` statements. When that is the case, Tabular Editor 3 displays the result from each such statement on a separate, numbered tab. If you only want to execute a single `EVALUATE` statement, even though your document contains multiple, you can place the cursor somewhere within the statement you want to execute, and then use the **Query > Execute selection** (SHIFT+F5) option. + +A DAX query in Tabular Editor 3 is automatically refreshed when a change is made to the model or a refresh operation finishes. You can toggle this auto-refresh capability within the **Query** menu. + +# Impersonation + +When querying the data in the model, it is sometimes useful to be able to impersonate a specific user or a combination of roles, to see what the behavior of the model from an end user perspective would be. Tabular Editor 3 allows you to impersonate a specific user or one or more roles, by clicking on the **Impersonate...** button. This applies to [Table previews](#previewing-table-data), [Pivot Grids](#pivot-grids) and [DAX queries](#dax-queries). + +> [!NOTE] +> To impersonate a user, Tabular Editor adds the [`EffectiveUserName` property](https://docs.microsoft.com/en-us/analysis-services/instances/connection-string-properties-analysis-services?view=asallproducts-allversions#effectiveusername) to the connection string, when connecting to Analysis Services. To impersonate a role, Tabular Editor adds the [`Roles` property](https://docs.microsoft.com/en-us/analysis-services/instances/connection-string-properties-analysis-services?view=asallproducts-allversions#roles) to the connection string. This only applies to the data view (i.e. the DAX query, the Pivot Grid or the Table Preview) where the impersonation is specified. + +When clicking on the **Impersonation..** button (which can also be found through the **Query**, **Pivot Grid** or **Table Preview** menu, depending on which type of data view is active), a popup allows you to specify either a user, or select one or more roles. + +![Select Impersonation](~/content/assets/images/select-impersonation.png) + +Once the impersonation is enabled, the **Impersonation..** button is checked, and the impersonation will be applied to the current data view. By clicking on the small arrow next to the **Impersonation..** button, you can view and quickly switch between the 10 most recent impersonations used. + +![Impersonation Dropdown](~/content/assets/images/impersonation-dropdown.png) + +When auto-refresh is enabled on a data view, changing the impersonation will immediately refresh the view. + +# VertiPaq Analyzer + +Tabular Editor 3 includes a version of the open-source [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/) tool, created by [SQLBI](https://sqlbi.com). VertiPaq Analyzer is useful to analyze VertiPaq storage structures for your Power BI or Tabular data model. + +With Tabular Editor 3, you can collect VertiPaq Analyzer statistics while you are connected to any instance of Analysis Services. You can also export the statistics as a [.vpax file](https://www.youtube.com/watch?v=zRa9y01Ub30), or import statistics from a .vpax file. + +To collect statistics, simply hit the **Collect stats** button in the **VertiPaq Analyzer** view. + +![Vertipaq Analyzer Collect Stats](~/content/assets/images/vertipaq-analyzer-collect-stats.png) + +Once statistics are collected, VertiPaq Analyzer displays a summary of the model size, number of tables, etc. You can find more detailed statistics on the **Tables**, **Columns**, **Relationships** and **Partitions** tabs. + +Additionally, whenever statistics have been loaded, Tabular Editor 3 will display cardinality and size information as a tooltip when hovering the mouse cursor over objects in the TOM Explorer: + +![Vertipaq Analyzer Stats in TOM Explorer](~/content/assets/images/vertipaq-analyzer-stats.png) + +...or when hovering the mouse cursor over object references in DAX expressions: + +![Vertipaq Analyzer Stats in a DAX expression](~/content/assets/images/vertipaq-analyzer-stats-dax.png) + +# Next steps + +- @creating-and-testing-dax \ No newline at end of file diff --git a/content/localization/de/release-history_de.md b/content/localization/de/release-history_de.md new file mode 100644 index 00000000..4ea941a1 --- /dev/null +++ b/content/localization/de/release-history_de.md @@ -0,0 +1,346 @@ +# Full release history + +- 2025-09-15 **Tabular Editor 3.23.1** (_[Release notes](release-notes/3_23_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) +- 2025-08-28 **Tabular Editor 3.23.0** (_[Release notes](release-notes/3_23_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) +- 2025-06-28 **Tabular Editor 3.22.1** (_[Release notes](release-notes/3_22_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) +- 2025-06-19 **Tabular Editor 3.22.0** (_[Release notes](release-notes/3_22_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) +- 2025-04-25 **Tabular Editor 3.21.0** (_[Release notes](release-notes/3_21_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) +- 2025-04-11 **Tabular Editor 3.20.1** (_[Release notes](release-notes/3_20_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) +- 2025-02-21 **Tabular Editor 3.20.0** (_[Release notes](release-notes/3_20_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) +- 2024-12-19 **Tabular Editor 3.19.0** (_[Release notes](release-notes/3_19_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.msi) +- 2024-11-14 **Tabular Editor 3.18.2** (_[Release notes](release-notes/3_18_2.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.msi) +- 2024-11-11 **Tabular Editor 3.18.1** (_[Release notes](release-notes/3_18_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.msi) +- 2024-10-31 **Tabular Editor 3.18.0** (_[Release notes](release-notes/3_18_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.msi) +- 2024-08-22 **Tabular Editor 3.17.1** (_[Release notes](release-notes/3_17_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.msi) +- 2024-08-14 **Tabular Editor 3.17.0** (_[Release notes](release-notes/3_17_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.msi) +- 2024-06-19 **Tabular Editor 3.16.2** (_[Release notes](release-notes/3_16_2.md)_) + - [TabularEditor.3.16.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x64.exe) + - [TabularEditor.3.16.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x86.exe) + - [TabularEditor.3.16.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.zip) + - [TabularEditor.3.16.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.zip) + - [TabularEditor.3.16.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.msi) + - [TabularEditor.3.16.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.msi) +- 2024-06-17 **Tabular Editor 3.16.1** (_[Release notes](release-notes/3_16_1.md)_) + - [TabularEditor.3.16.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x64.exe) + - [TabularEditor.3.16.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x86.exe) + - [TabularEditor.3.16.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.zip) + - [TabularEditor.3.16.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.zip) + - [TabularEditor.3.16.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.msi) + - [TabularEditor.3.16.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.msi) +- 2024-06-10 **Tabular Editor 3.16.0** (_[Release notes](release-notes/3_16_0.md)_) + - [TabularEditor.3.16.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x64.exe) + - [TabularEditor.3.16.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x86.exe) + - [TabularEditor.3.16.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.zip) + - [TabularEditor.3.16.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.zip) + - [TabularEditor.3.16.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.msi) + - [TabularEditor.3.16.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.msi) +- 2024-04-17 **Tabular Editor 3.15.0** (_[Release notes](release-notes/3_15_0.md)_) + - [TabularEditor.3.15.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x64.exe) + - [TabularEditor.3.15.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x86.exe) + - [TabularEditor.3.15.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.zip) + - [TabularEditor.3.15.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.zip) + - [TabularEditor.3.15.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.msi) + - [TabularEditor.3.15.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.msi) +- 2024-02-20 **Tabular Editor 3.14.0** (_[Release notes](release-notes/3_14_0.md)_) + - [TabularEditor.3.14.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x64.exe) + - [TabularEditor.3.14.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x86.exe) + - [TabularEditor.3.14.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.zip) + - [TabularEditor.3.14.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.zip) + - [TabularEditor.3.14.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.msi) + - [TabularEditor.3.14.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.msi) +- 2023-12-15 **Tabular Editor 3.13.0** (_[Release notes](release-notes/3_13_0.md)_) + - [TabularEditor.3.13.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x64.exe) + - [TabularEditor.3.13.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x86.exe) + - [TabularEditor.3.13.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.zip) + - [TabularEditor.3.13.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.zip) + - [TabularEditor.3.13.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.msi) + - [TabularEditor.3.13.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.msi) +- 2023-12-01 **Tabular Editor 3.12.1** (_[Release notes](release-notes/3_12_1.md)_) + - [TabularEditor.3.12.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x64.exe) + - [TabularEditor.3.12.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x86.exe) + - [TabularEditor.3.12.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.zip) + - [TabularEditor.3.12.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.zip) + - [TabularEditor.3.12.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.msi) + - [TabularEditor.3.12.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.msi) +- 2023-11-27 **Tabular Editor 3.12.0** (_[Release notes](release-notes/3_12_0.md)_) + - [TabularEditor.3.12.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x64.exe) + - [TabularEditor.3.12.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x86.exe) + - [TabularEditor.3.12.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.zip) + - [TabularEditor.3.12.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.zip) + - [TabularEditor.3.12.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.msi) + - [TabularEditor.3.12.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.msi) +- 2023-09-25 **Tabular Editor 3.11.0** (_[Release notes](release-notes/3_11_0.md)_) + - [TabularEditor.3.11.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x64.exe) + - [TabularEditor.3.11.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x86.exe) + - [TabularEditor.3.11.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.zip) + - [TabularEditor.3.11.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.zip) + - [TabularEditor.3.11.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.msi) + - [TabularEditor.3.11.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.msi) +- 2023-08-30 **Tabular Editor 3.10.1** (_[Release notes](release-notes/3_10_1.md)_) + - [TabularEditor.3.10.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x64.exe) + - [TabularEditor.3.10.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x86.exe) + - [TabularEditor.3.10.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.zip) + - [TabularEditor.3.10.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.zip) + - [TabularEditor.3.10.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.msi) + - [TabularEditor.3.10.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.msi) +- 2023-08-24 **Tabular Editor 3.10.0** (_[Release notes](release-notes/3_10_0.md)_) + - [TabularEditor.3.10.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x64.exe) + - [TabularEditor.3.10.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x86.exe) + - [TabularEditor.3.10.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.zip) + - [TabularEditor.3.10.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.zip) + - [TabularEditor.3.10.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.msi) + - [TabularEditor.3.10.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.msi) +- 2023-07-20 **Tabular Editor 3.9.0** (_[Release notes](release-notes/3_9_0.md)_) + - [TabularEditor.3.9.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x64.exe) + - [TabularEditor.3.9.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x86.exe) + - [TabularEditor.3.9.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.zip) + - [TabularEditor.3.9.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.zip) + - [TabularEditor.3.9.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.msi) + - [TabularEditor.3.9.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.msi) +- 2023-06-23 **Tabular Editor 3.8.0** (_[Release notes](release-notes/3_7_1.md)_) + - [TabularEditor.3.8.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x64.exe) + - [TabularEditor.3.8.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x86.exe) + - [TabularEditor.3.8.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.zip) + - [TabularEditor.3.8.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.zip) + - [TabularEditor.3.8.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.msi) + - [TabularEditor.3.8.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.msi) +- 2023-05-22 **Tabular Editor 3.7.1** (_[Release notes](release-notes/3_7_1.md)_) + - [TabularEditor.3.7.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x64.exe) + - [TabularEditor.3.7.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x86.exe) + - [TabularEditor.3.7.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.zip) + - [TabularEditor.3.7.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.zip) + - [TabularEditor.3.7.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.msi) + - [TabularEditor.3.7.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.msi) +- 2023-05-17 **Tabular Editor 3.7.0** (_[Release notes](release-notes/3_7_0.md)_) + - [TabularEditor.3.7.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x64.exe) + - [TabularEditor.3.7.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x86.exe) + - [TabularEditor.3.7.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.zip) + - [TabularEditor.3.7.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.zip) + - [TabularEditor.3.7.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.msi) + - [TabularEditor.3.7.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.msi) +- 2023-04-19 **Tabular Editor 3.6.0** (_[Release notes](release-notes/3_6_0.md)_) + - [TabularEditor.3.6.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x64.exe) + - [TabularEditor.3.6.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x86.exe) + - [TabularEditor.3.6.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.zip) + - [TabularEditor.3.6.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.zip) + - [TabularEditor.3.6.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.msi) + - [TabularEditor.3.6.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.msi) +- 2023-03-28 **Tabular Editor 3.5.1** (_[Release notes](release-notes/3_5_1.md)_) + - [TabularEditor.3.5.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x64.exe) + - [TabularEditor.3.5.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x86.exe) + - [TabularEditor.3.5.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.zip) + - [TabularEditor.3.5.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.zip) + - [TabularEditor.3.5.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.msi) + - [TabularEditor.3.5.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.msi) +- 2023-03-15 **Tabular Editor 3.5.0** (_[Release notes](release-notes/3_5_0.md)_) + - [TabularEditor.3.5.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x64.exe) + - [TabularEditor.3.5.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x86.exe) + - [TabularEditor.3.5.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.zip) + - [TabularEditor.3.5.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.zip) + - [TabularEditor.3.5.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.msi) + - [TabularEditor.3.5.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.msi) +- 2023-02-09 **Tabular Editor 3.4.2** (_[Release notes](release-notes/3_4_2.md)_): + - [TabularEditor.3.4.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x64.exe) + - [TabularEditor.3.4.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x86.exe) + - [TabularEditor.3.4.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.zip) + - [TabularEditor.3.4.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.zip) + - [TabularEditor.3.4.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.msi) + - [TabularEditor.3.4.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.msi) +- 2023-02-03 **Tabular Editor 3.4.1** (_[Release notes](release-notes/3_4_1.md)_): + - _Not recommended - use [3.4.2](release-notes/3_4_2.md) instead._ + - [TabularEditor.3.4.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x64.exe) + - [TabularEditor.3.4.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x86.exe) + - [TabularEditor.3.4.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.zip) + - [TabularEditor.3.4.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.zip) + - [TabularEditor.3.4.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.msi) + - [TabularEditor.3.4.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.msi) +- 2022-12-13 **Tabular Editor 3.4.0** (_[Release notes](release-notes/3_4_0.md)_): + - [TabularEditor.3.4.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x64.exe) + - [TabularEditor.3.4.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x86.exe) + - [TabularEditor.3.4.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.zip) + - [TabularEditor.3.4.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.zip) + - [TabularEditor.3.4.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.msi) + - [TabularEditor.3.4.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.msi) +- 2022-11-11 **Tabular Editor 3.3.6** (_[Release notes](release-notes/3_3_6.md)_): + - [TabularEditor.3.3.6.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x64.exe) + - [TabularEditor.3.3.6.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x86.exe) + - [TabularEditor.3.3.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.zip) + - [TabularEditor.3.3.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.zip) + - [TabularEditor.3.3.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.msi) + - [TabularEditor.3.3.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.msi) +- 2022-09-06 **Tabular Editor 3.3.5** (_[Release notes](release-notes/3_3_5.md)_): + - [TabularEditor.3.3.5.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x64.exe) + - [TabularEditor.3.3.5.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x86.exe) + - [TabularEditor.3.3.5.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.zip) + - [TabularEditor.3.3.5.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.zip) + - [TabularEditor.3.3.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.msi) + - [TabularEditor.3.3.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.msi) +- 2022-08-10 **Tabular Editor 3.3.4** (_[Release notes](release-notes/3_3_4.md)_): + - [TabularEditor.3.3.4.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x64.exe) + - [TabularEditor.3.3.4.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x86.exe) + - [TabularEditor.3.3.4.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.zip) + - [TabularEditor.3.3.4.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.zip) + - [TabularEditor.3.3.4.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.msi) + - [TabularEditor.3.3.4.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.msi) +- 2022-07-17 **Tabular Editor 3.3.3** (_[Release notes](release-notes/3_3_3.md)_): + - [TabularEditor.3.3.3.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x64.exe) + - [TabularEditor.3.3.3.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x86.exe) + - [TabularEditor.3.3.3.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.zip) + - [TabularEditor.3.3.3.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.zip) + - [TabularEditor.3.3.3.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.msi) + - [TabularEditor.3.3.3.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.msi) +- 2022-06-28 **Tabular Editor 3.3.2** (_[Release notes](release-notes/3_3_2.md)_): + - [TabularEditor.3.3.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x64.exe) + - [TabularEditor.3.3.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x86.exe) + - [TabularEditor.3.3.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x64.zip) + - [TabularEditor.3.3.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x86.zip) +- 2022-06-16 **Tabular Editor 3.3.0** (_[Release notes](release-notes/3_3_0.md)_): + - [TabularEditor.3.3.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.msi) + - [TabularEditor.3.3.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.msi) + - [TabularEditor.3.3.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.zip) + - [TabularEditor.3.3.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.zip) +- 2022-04-07 **Tabular Editor 3.2.3** (_[Release notes](release-notes/3_2_3.md)_): + - [TabularEditor.3.2.3.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.msi) + - [TabularEditor.3.2.3.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.msi) + - [TabularEditor.3.2.3.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.zip) + - [TabularEditor.3.2.3.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.zip) +- 2022-02-16 **Tabular Editor 3.2.2** (_[Release notes](release-notes/3_2_2.md)_): + - [TabularEditor.3.2.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.msi) + - [TabularEditor.3.2.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.msi) + - [TabularEditor.3.2.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.zip) + - [TabularEditor.3.2.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.zip) +- 2022-01-28 **Tabular Editor 3.2.1** (_[Release notes](release-notes/3_2_1.md)_): + - [TabularEditor.3.2.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.msi) + - [TabularEditor.3.2.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.msi) + - [TabularEditor.3.2.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.zip) + - [TabularEditor.3.2.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.zip) +- 2022-01-20 **Tabular Editor 3.2.0** (_[Release notes](release-notes/3_2_0.md)_): + - [TabularEditor.3.2.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.msi) + - [TabularEditor.3.2.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.msi) + - [TabularEditor.3.2.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.zip) + - [TabularEditor.3.2.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.zip) +- 2021-12-16 **Tabular Editor 3.1.7** (_[Release notes](release-notes/3_1_7.md)_): + - [TabularEditor.3.1.7.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.msi) + - [TabularEditor.3.1.7.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.msi) + - [TabularEditor.3.1.7.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.zip) + - [TabularEditor.3.1.7.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.zip) +- 2021-11-23 **Tabular Editor 3.1.6** (_[Release notes](release-notes/3_1_6.md)_): + - [TabularEditor.3.1.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.msi) + - [TabularEditor.3.1.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.msi) + - [TabularEditor.3.1.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.zip) + - [TabularEditor.3.1.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.zip) +- 2021-11-02 **Tabular Editor 3.1.5** (_[Release notes](release-notes/3_1_5.md)_): + - [TabularEditor.3.1.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.msi) + - [TabularEditor.3.1.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.msi) + - [TabularEditor.3.1.5.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.zip) + - [TabularEditor.3.1.5.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.zip) +- 2021-10-07 **Tabular Editor 3.1.4** (_[Release notes](release-notes/3_1_4.md)_): + - [TabularEditor.3.1.4.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.msi) + - [TabularEditor.3.1.4.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.msi) + - [TabularEditor.3.1.4.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.zip) + - [TabularEditor.3.1.4.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.zip) +- 2021-09-30 **Tabular Editor 3.1.3** (_[Release notes](release-notes/3_1_3.md)_): + - [TabularEditor.3.1.3.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.msi) + - [TabularEditor.3.1.3.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.msi) + - [TabularEditor.3.1.3.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.zip) + - [TabularEditor.3.1.3.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.zip) +- 2021-08-10 **Tabular Editor 3.0.10** (_[Release notes](release-notes/3_0_10.md)_): + - [TabularEditor.3.0.10.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.msi) + - [TabularEditor.3.0.10.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.msi) + - [TabularEditor.3.0.10.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.zip) + - [TabularEditor.3.0.10.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.zip) +- 2021-08-07 **Tabular Editor 3.0.9** (_[Release notes](release-notes/3_0_9.md)_): + - [TabularEditor.3.0.9.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.msi) + - [TabularEditor.3.0.9.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.msi) + - [TabularEditor.3.0.9.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.zip) + - [TabularEditor.3.0.9.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.zip) +- 2021-08-06 **Tabular Editor 3.0.8** (_[Release notes](release-notes/3_0_8.md)_): + - [TabularEditor.3.0.8.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.msi) + - [TabularEditor.3.0.8.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.msi) + - [TabularEditor.3.0.8.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.zip) + - [TabularEditor.3.0.8.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.zip) +- 2021-06-30 **Tabular Editor 3.0.7** (_[Release notes](release-notes/3_0_7.md)_): + - [TabularEditor.3.0.7.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.msi) + - [TabularEditor.3.0.7.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.msi) + - [TabularEditor.3.0.7.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.zip) + - [TabularEditor.3.0.7.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.zip) +- 2021-06-17 **Tabular Editor 3.0.6** (_[Release notes](release-notes/3_0_6.md)_): + - [TabularEditor.3.0.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.msi) + - [TabularEditor.3.0.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.msi) + - [TabularEditor.3.0.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.zip) + - [TabularEditor.3.0.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.zip) +- 2021-06-10 **Tabular Editor 3.0.5** (_[Release notes](release-notes/3_0_5.md)_): + - [TabularEditor.3.0.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x64.msi) + - [TabularEditor.3.0.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x86.msi) +- 2021-06-08 **Tabular Editor 3.0.4** (_[Release notes](release-notes/3_0_4.md)_): + - [TabularEditor.3.0.4.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x64.msi) + - [TabularEditor.3.0.4.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x86.msi) +- 2021-06-03 **Tabular Editor 3.0.2** (_[Release notes](release-notes/3_0_2.md)_): + - [TabularEditor.3.0.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x64.msi) + - [TabularEditor.3.0.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x86.msi) +- 2021-06-01 **Tabular Editor 3.0.1** (_[Release notes](release-notes/3_0_1.md)_): + - [TabularEditor.3.0.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x64.msi) + - [TabularEditor.3.0.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x86.msi) \ No newline at end of file diff --git a/content/localization/de/roadmap_de.md b/content/localization/de/roadmap_de.md new file mode 100644 index 00000000..2b4471c4 --- /dev/null +++ b/content/localization/de/roadmap_de.md @@ -0,0 +1,121 @@ +--- +uid: roadmap +title: Roadmap +author: Morten Lønskov +updated: 2024-04-23 +--- + +# Tabular Editor 3 Roadmap + +Below is an overview of major new features to be shipped with Tabular Editor 3 updates in the short- to long term: + +# [Planned 2025](#tab/Planned2025) + +- Direct Lake on One Lake support + +- Day zero support for DAX User Defined Functions + +- Support for Calendars + +- Adding more Code Actions + +- Built in Best Practice Rules + +- Built in Macros + +- Power Query (M) Auto-Formatting + +## Shipped in 2025 + +✅ New Code Actions + Knowledge Base for all Code Actions +✅ C# Editor Improvements +✅ Copy TMDL Scripts from TOM Explorer + +# [Future Features](#tab/FutureFeatures) + +## Up Next + +- Localization +- Power Query (M) Editing Enchantments +- Macro Actions improvements such as automatic application across model and preferences for which to apply. +- TOM Properties shown as TMDL and TMSL Scripts. + +## Non Planned Features + +- Standalone CLI application +- Git integration +- DAX Debugger Filter Context visualizer +- Configurable Daxscilla autocomplete code snippets +- Configurable theming for code editors (syntax highlighting colors) +- Incremental deployment (a la [ALM Toolkit](http://alm-toolkit.com/)) + +# [Shipped](#tab/shipped) + +## Shipped in 2024 + +✅ DAX Debugger Locals Enhancement + +✅ Full Direct Lake Integration + +✅ DAX Optimizer Integration (Preview) + +✅ .Net 8 migration + +✅ Pivot Grid Enhancement + +✅ DAX Query Enhancement + +✅ TMDL GA Support + +✅ Code Actions + +✅ GA of DAX Optimizer Integration + +✅ Data Refresh View Improvements + +✅ Power Query (M) Highlighting + +## Shipped in 2023 + +✅ TMDL Support as standard Save to Folder file format. (Depending on release of TMDL by Microsoft) + +✅ Import Table Wizard support for Databricks (pending availability of REST endpoint for fetching metadata/schema) + +✅ Metadata Translation Editor (view that can be opened when selecting one or more cultures, similar to the Tabular Translator tool) + +✅ Perspective Editor (view that can be opened when selecting one or more perspectives, allowing you to check/uncheck objects visible in those perspectives) + +✅ Improved Support for Oracle Databases + +✅ Import Table Wizard support for Power BI datamarts (Use Datamart SQL Endpoint) + +## Shipped in 2022 + +✅ DAX Debugger + +✅ .NET 6 migration + +✅ C# code assist (autocomplete, calltips, etc.) + +✅ Import Table Wizard support for Snowflake + +✅ Import Table Wizard support for Power BI dataflows + +✅ Configurable hotkeys + +✅ Support for DAX window functions + +✅ Git integration (private preview) + +## Shipped in 2021 + +✅ Import Table Wizard + +✅ Portable Version + +✅ Pivot Grid, Table Preview and DAX Query impersonation of a specific role or user, making it easy to test RLS/OLS + +✅ DAX Script support for calculation groups and calculation items + +✅ Offline DAX formatting + diff --git a/content/localization/de/save-to-folder_de.md b/content/localization/de/save-to-folder_de.md new file mode 100644 index 00000000..59423951 --- /dev/null +++ b/content/localization/de/save-to-folder_de.md @@ -0,0 +1,59 @@ +--- +uid: save-to-folder +title: Save to folder +author: Morten Lønskov +updated: 2023-08-08 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Save to folder + +Save to Folder allows you to store your model metadata as individual files, which can be easily managed by version control systems. Instead of having a single file (.bim or .pbix) that contains all the objects of your data model, such as tables, measures, relationships, etc., you can split them into separate files and store them in a folder. This way, you can use source control tools to track the changes, compare versions, and collaborate with other developers on your data model. + +> [!NOTE] +> ou can save your data model to a folder using two different formats: JSON or [TMDL](tmdl-common.md). + +To save your model to folder, follow these steps: + +1. Click on File > Save To Folder +2. Choose a folder where you want to save your model files. +3. Click on Save. Tabular Editor will create or update the files in the selected folder, using the JSON or TMDL format as specified in the serialization settings. +4. You can now use the files in the folder for version control, deployment, or backup purposes. + +## Serialization settings + +The serialization settings defines how the model objects are split into separate files. In these settings you can also define if you wish to use JSON or TMDL formats. + +> [!NOTE] +> SON is the default format as TMDL is currently in preview. + +### [Tabular Editor 2 Preferences](#tab/TE2Preferences) + +Serialization settings are found under File > Preferences > Serialization

    +![TE2 Preferences](~/content/assets/images/common/TE2SaveToFolderSerializationSettings.png) + +The settings shown above are those set as default when using Tabular Editor 3, but are not those that are set per default by Tabular Editor 2.X + +### [Tabular Editor 3 Preferences](#tab/TE3Preferences) + +Serialization settings are found under Tools > Preferences > File Formats +The tabs General and Save-to-folder contains settings regarding the serialization of the model.

    +![TE3 Preferences](~/content/assets/images/common/TE3SaveToFolderSerializationSettings.png) + +Tabular Editor 3 has a default setting for JSON serialization and you must actively choose a different setting in serialization mode, which is also where you change to the TMDL format. + +*** + +### Serialization Model Annotation + +Tabular Editor saves the serialization settings on your model so that they will always stay the same no matter who is working on the model. This ensures that a developer's local preferences do not overwrite model's setting and lead to a unmanageable merge in your source control. You can find these annotations in the TOM Explorer properties of the Model > Annotations > TabularEditor_SerializeOptions

    +![TE3 Preferences](~/content/assets/images/common/SaveToFolderModelAnnotation.png) + +#### Overwriting Model Serialization + +The model's annotation can be overwritten if so desired. First set up the serialization preferences inside Tabular Editor and go to File > Save to Folder. +This open up Windows Explorer and here the ticket button needs to be unselected.

    +![TE3 Preferences](~/content/assets/images/common/SaveToFolderOverwriteModelAnnotation.png) diff --git a/content/localization/de/script-add-databricks-metadata-descriptions_de.md b/content/localization/de/script-add-databricks-metadata-descriptions_de.md new file mode 100644 index 00000000..89a4c408 --- /dev/null +++ b/content/localization/de/script-add-databricks-metadata-descriptions_de.md @@ -0,0 +1,576 @@ +--- +uid: script-add-databricks-metadata-descriptions +title: Databricks-Metadatenbeschreibungen hinzufügen +author: Johnny Winter +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Databricks-Metadatenbeschreibungen hinzufügen + +## Skriptzweck + +Dieses Skript wurde als Teil der Tabular Editor x Databricks-Serie erstellt. In Unity Catalog ist es möglich, beschreibende Kommentare für Tabellen und Spalten bereitzustellen. Dieses Skript kann diese Informationen wiederverwenden, um Tabellen- und Spaltenbeschreibungen in Ihrem semantischen Modell automatisch auszufüllen.

    + +> [!NOTE] +> Dieses Skript erfordert die Installation des Simba Spark ODBC-Treibers (Download von https://www.databricks.com/spark/odbc-drivers-download) +> Bei jeder Ausführung des Skripts werden Sie aufgefordert, ein Databricks Personal Access Token einzugeben. Dies ist erforderlich, um sich bei Databricks zu authentifizieren. +> Das Skript nutzt die information_schema-Tabellen in Unity Catalog, um Beziehungsinformationen abzurufen. Daher müssen Sie möglicherweise mit Ihrem Databricks-Administrator überprüfen, ob Sie Berechtigung zum Abfragen dieser Tabellen haben.

    + +## Skript + +### Databricks-Metadatenbeschreibungen hinzufügen + +```csharp +/* + * Title: Add Databricks Metadata descriptions + * Author: Johnny Winter, greyskullanalytics.com + * + * This script, when executed, will loop through the currently selected tables and send a query to Databricks to see if each table has metadata descriptions defined in Unity Catalog. + * Where a description exists, this will be added to the semantic model description. + * Step 1: Select one or more tables in the model + * Step 2: Run this script + * Step 3: Enter your Databricks Personal Access Token when prompted + * Step 4: The script will connect to Databricks and update the table and column descriptions where they exist. + * For each table processed, a message box will display the number of descriptions updated. + * Click OK to continue to the next table. + * Notes: + * - This script requires the Simba Spark ODBC Driver to be installed (download from https://www.databricks.com/spark/odbc-drivers-download) + * - Each run of the script will prompt the user for a Databricks Personal Access Token + */ +#r "Microsoft.VisualBasic" +using System; +using System.Data.Odbc; +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using Microsoft.VisualBasic; +using sysData = System.Data; + +//code to create a masked input box for Databricks PAT token +public partial class PasswordInputForm : Form +{ + public string Password { get; private set; } + + private TextBox passwordTextBox; + private Button okButton; + private Button cancelButton; + private Label promptLabel; + + public PasswordInputForm(string prompt, string title) + { + InitializeComponent(prompt, title); + } + + private void InitializeComponent(string prompt, string title) + { + this.Text = title; + this.Size = new System.Drawing.Size(4000, 1500); + this.StartPosition = FormStartPosition.WindowsDefaultLocation; + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + + // Prompt label + promptLabel = new Label(); + promptLabel.Text = prompt; + promptLabel.Location = new System.Drawing.Point(12, 15); + promptLabel.Size = new System.Drawing.Size(360, 40); + promptLabel.AutoSize = false; + this.Controls.Add(promptLabel); + + // Password textbox + passwordTextBox = new TextBox(); + passwordTextBox.Location = new System.Drawing.Point(12, 55); + passwordTextBox.Size = new System.Drawing.Size(360, 20); + passwordTextBox.UseSystemPasswordChar = true; // This masks the input + passwordTextBox.KeyPress += (s, e) => + { + if (e.KeyChar == (char)Keys.Return) + { + OkButton_Click(null, null); + e.Handled = true; + } + }; + this.Controls.Add(passwordTextBox); + + // OK button + okButton = new Button(); + okButton.Text = "OK"; + okButton.Location = new System.Drawing.Point(216, 85); + okButton.Size = new System.Drawing.Size(150, 50); + okButton.Click += OkButton_Click; + this.Controls.Add(okButton); + + // Cancel button + cancelButton = new Button(); + cancelButton.Text = "Cancel"; + cancelButton.Location = new System.Drawing.Point(297, 85); + cancelButton.Size = new System.Drawing.Size(150, 50); + cancelButton.Click += CancelButton_Click; + this.Controls.Add(cancelButton); + + // Set default and cancel buttons + this.AcceptButton = okButton; + this.CancelButton = cancelButton; + + // Focus on textbox when form loads + this.Load += (s, e) => passwordTextBox.Focus(); + } + + private void OkButton_Click(object sender, EventArgs e) + { + Password = passwordTextBox.Text; + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void CancelButton_Click(object sender, EventArgs e) + { + Password = string.Empty; + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + public static string ShowDialog(string prompt, string title) + { + using (var form = new PasswordInputForm(prompt, title)) + { + if (form.ShowDialog() == DialogResult.OK) + return form.Password; + return string.Empty; + } + } +} + +public static class MaskedInputHelper +{ + public static string GetMaskedInput(string prompt, string title, string defaultValue = "") + { + using (var form = new Form()) + { + form.Text = title; + form.Size = new System.Drawing.Size(1000, 500); + form.StartPosition = FormStartPosition.CenterScreen; + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + + var label = new Label() + { + Left = 12, + Top = 15, + Size = new System.Drawing.Size(900, 100), + Text = prompt, + }; + var textBox = new TextBox() + { + Left = 12, + Top = 150, + Size = new System.Drawing.Size(900, 100), + UseSystemPasswordChar = true, + Text = defaultValue, + }; + var buttonOk = new Button() + { + Text = "OK", + Size = new System.Drawing.Size(150, 50), + Left = 12, + Width = 150, + Top = 200, + DialogResult = DialogResult.OK, + }; + var buttonCancel = new Button() + { + Text = "Cancel", + Size = new System.Drawing.Size(150, 50), + Left = 175, + Width = 150, + Top = 200, + DialogResult = DialogResult.Cancel, + }; + + buttonOk.Click += (sender, e) => + { + form.Close(); + }; + form.Controls.Add(label); + form.Controls.Add(textBox); + form.Controls.Add(buttonOk); + form.Controls.Add(buttonCancel); + form.AcceptButton = buttonOk; + form.CancelButton = buttonCancel; + + return form.ShowDialog() == DialogResult.OK ? textBox.Text : string.Empty; + } + } +} + +//Code to retrieve Databricks Connection information from the M Query in a table partition +public class DatabricksConnectionInfo +{ + public string ServerHostname { get; set; } + public string HttpPath { get; set; } + public string DatabaseName { get; set; } + public string SchemaName { get; set; } + public string TableName { get; set; } + + public override string ToString() + { + return $"Server: {ServerHostname}\n" + + $"HTTP Path: {HttpPath}\n" + + $"Database: {DatabaseName}\n" + + $"Schema: {SchemaName}\n" + + $"Table: {TableName}"; + } +} + +public class PowerQueryMParser +{ + public static DatabricksConnectionInfo ParseMQuery(string mQuery) + { + if (string.IsNullOrWhiteSpace(mQuery)) + throw new ArgumentException("M query cannot be null or empty"); + + var connectionInfo = new DatabricksConnectionInfo(); + + try + { + // Parse Source line to extract server hostname and HTTP path + ParseSourceLine(mQuery, connectionInfo); + + // Parse Database line to extract database name + ParseDatabaseLine(mQuery, connectionInfo); + + // Parse Schema line to extract schema name + ParseSchemaLine(mQuery, connectionInfo); + + // Parse Data line to extract table name + ParseDataLine(mQuery, connectionInfo); + + return connectionInfo; + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error parsing M query: {ex.Message}", ex); + } + } + + private static void ParseSourceLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match both: + // Source = DatabricksMultiCloud.Catalogs("hostname", "httppath", null), + // Source = Databricks.Catalogs("hostname", "httppath", null), + var sourcePattern = + @"Source\s*=\s*Databricks(?:MultiCloud)?\.Catalogs\s*\(\s*\"([^\"]+)\"\s*,\s*\"([^\"]+)\"\s*,\s*null\s*\)" + var sourceMatch = Regex.Match( + mQuery, + sourcePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!sourceMatch.Success) + throw new FormatException( + "Could not find valid Source definition in M query (supports both Databricks and DatabricksMultiCloud connectors)" + ); + + connectionInfo.ServerHostname = sourceMatch.Groups[1].Value; + connectionInfo.HttpPath = sourceMatch.Groups[2].Value; + } + + private static void ParseDatabaseLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Database = Source{[Name="databasename",Kind="Database"]}[Data], + var databasePattern = + @"Database\s*=\s*Source\s*{\s*\[\s*Name\s*=\s*\"([^\"]+)\"\s*,\s*Kind\s*=\s*\"Database\"\s*\]\s*}\s*\[\s*Data\s*\]" + var databaseMatch = Regex.Match( + mQuery, + databasePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!databaseMatch.Success) + throw new FormatException("Could not find valid Database definition in M query"); + + connectionInfo.DatabaseName = databaseMatch.Groups[1].Value; + } + + private static void ParseSchemaLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Schema = Database{[Name="schemaname",Kind="Schema"]}[Data], + var schemaPattern = + @"Schema\s*=\s*Database\s*{\s*\[\s*Name\s*=\s*\"([^\"]+)\"\s*,\s*Kind\s*=\s*\"Schema\"\s*\]\s*}\s*\[\s*Data\s*\]" + var schemaMatch = Regex.Match( + mQuery, + schemaPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!schemaMatch.Success) + throw new FormatException("Could not find valid Schema definition in M query"); + + connectionInfo.SchemaName = schemaMatch.Groups[1].Value; + } + + private static void ParseDataLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Data = Schema{[Name="tablename",Kind="Table"]}[Data] + var dataPattern = + @"Data\s*=\s*Schema\s*{\s*\[\s*Name\s*=\s*\"([^\"]+)\"\s*,\s*Kind\s*=\s*\"Table\"\s*\]\s*}\s*\[\s*Data\s*\]" + var dataMatch = Regex.Match( + mQuery, + dataPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!dataMatch.Success) + throw new FormatException("Could not find valid Data definition in M query"); + + connectionInfo.TableName = dataMatch.Groups[1].Value; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//main script + + + +//check that user has a table selected +if (Selected.Tables.Count == 0) +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox("Select one or more tables", MsgBoxStyle.Critical, "Table Required"); + return; +} + +//prompt for personal access token - required to authenticate to Databricks +string dbxPAT; +do +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + dbxPAT = MaskedInputHelper.GetMaskedInput( + "Please enter your Databricks Personal Access Token (needed to connect to the SQL Endpoint)", + "Personal Access Token" + ); + + if (string.IsNullOrEmpty(dbxPAT)) + { + return; // User cancelled + } + + if (string.IsNullOrWhiteSpace(dbxPAT)) + { + MessageBox.Show( + "Personal Access Token required", + "Personal Access Token required", + MessageBoxButtons.OK, + MessageBoxIcon.Warning + ); + } +} while (string.IsNullOrWhiteSpace(dbxPAT)); + +// toggle the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = true; + +//for each selected table, get the Databricks connection info from the partition info +foreach (var t in Selected.Tables) +{ + string mQuery = t.Partitions[t.Name].Expression; + var connectionInfo = PowerQueryMParser.ParseMQuery(mQuery); + var columnDescriptions = 0; + var tableDescriptions = 0; + // Access individual components + string serverHostname = connectionInfo.ServerHostname; + string httpPath = connectionInfo.HttpPath; + string databaseName = connectionInfo.DatabaseName; + string schemaName = connectionInfo.SchemaName; + string tableName = connectionInfo.TableName; + //set DBX connection string + var odbcConnStr = + @"DSN=Simba Spark;driver=C:\Program Files\Simba Spark ODBC Driver;host=" + + serverHostname + + ";port=443;httppath=" + + httpPath + + ";thrifttransport=2;ssl=1;authmech=3;uid=token;pwd=" + + dbxPAT; + + //test connection + OdbcConnection conn = new OdbcConnection(odbcConnStr); + try + { + conn.Open(); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Please check the following prequisites: + +- you must have the Simba Spark ODBC Driver installed +(download from https://www.databricks.com/spark/odbc-drivers-download) + +- the ODBC driver must be installed in the path C:\Program Files\Simba Spark ODBC Driver + +- check that the Databricks server name " + + serverHostname + + @" is correct + +- check that the Databricks SQL endpoint / HTTP Path " + + httpPath + + @" is correct + +- check that you have used a valid Personal Access Token", + MsgBoxStyle.Critical, + "Connection Error" + ); + return; + } + + //get table metadata + var tableQuery = + "SELECT comment FROM " + + databaseName + + ".information_schema.tables WHERE table_schema = '" + + schemaName + + "' AND table_name = '" + + tableName + + "'"; + OdbcDataAdapter td = new OdbcDataAdapter(tableQuery, conn); + var dbxTable = new sysData.DataTable(); + + try + { + td.Fill(dbxTable); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Either: + - the table " + + schemaName + + "." + + tableName + + " does not exist" + + @" + + - you do not have permissions to query this table + + - the connection timed out. Please check that the SQL Endpoint cluster is running", + MsgBoxStyle.Critical, + "Connection Error - Table Metadata" + ); + return; + } + string tableUpdate = ""; + foreach (sysData.DataRow row in dbxTable.Rows) + { + if (t.Description != row["comment"].ToString()) + { + t.Description = row["comment"].ToString(); + tableUpdate = t.Name + " table description updated."; + } + } + + //get column metadata + var columnsQuery = @"DESCRIBE " + databaseName + "." + schemaName + "." + tableName; + OdbcDataAdapter da = new OdbcDataAdapter(columnsQuery, conn); + var dbxColumns = new sysData.DataTable(); + + try + { + da.Fill(dbxColumns); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Either: + - the table " + + schemaName + + "." + + tableName + + " does not exist" + + @" + + - you do not have permissions to query this table + + - the connection timed out. Please check that the SQL Endpoint cluster is running", + MsgBoxStyle.Critical, + "Connection Error - Column Metadata" + ); + return; + } + + //update column descriptions + int counter = 0; + foreach (sysData.DataRow row in dbxColumns.Rows) + { + string sourceColumn = row["col_name"].ToString(); + if (sourceColumn.Length != 0) + { + foreach (var c in t.DataColumns) + { + if (c.SourceColumn == sourceColumn && c.Description != row["comment"].ToString()) + { + c.Description = row["comment"].ToString(); + counter = counter + 1; + } + } + } + } + string msg; + if (tableUpdate.Length > 0) + { + msg = + tableUpdate + + @" + +" + + counter + + " descriptions updated on " + + t.Name; + } + else + { + msg = counter + " descriptions updated on " + t.Name; + } + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox(msg, MsgBoxStyle.Information, "Update Metadata Descriptions"); + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = true; + conn.Close(); +} +``` + +### Erläuterung + +Das Skript verwendet WinForms, um ein Databricks Personal Access Token anzufordern, das zur Authentifizierung bei Databricks verwendet wird. Für jede ausgewählte Tabelle ruft das Skript die Databricks-Verbindungsinformationen und Schema- und Tabellennamen aus der M-Abfrage in der Partition der ausgewählten Tabelle ab. Mit Hilfe des Spark ODBC-Treibers sendet es dann eine SQL-Abfrage an Databricks, die die information_schema-Tabellen abfragt, um die in Unity Catalog definierte Tabellenbeschreibung zurückzugeben. Diese wird dann in der Tabellenbeschreibung des semantischen Modells aktualisiert. Eine zweite SQL-Abfrage mit dem DESCRIBE-Befehl wird auch an die ausgewählte Tabelle gesendet, um Spaltenbeschreibungen abzurufen. Die Ergebnisse werden durchlaufen, wobei Beschreibungen im Modell hinzugefügt werden. Nach der Ausführung des Skripts auf jeder ausgewählten Tabelle wird ein Dialogfeld angezeigt, das die Anzahl der aktualisierten Beschreibungen zeigt. + +## Beispielausgabe + +
    + Prompt for Databricks personal access token
    Abbildung 1: Das Skript fordert Sie auf, ein Databricks Personal Access Token einzugeben, damit es sich bei Databricks authentifizieren kann.
    +
    + +
    + The number of descriptions updated
    Abbildung 2: Nach der Ausführung des Skripts für jede ausgewählte Tabelle wird die Anzahl der aktualisierten Beschreibungen angezeigt.
    +
    + + + diff --git a/content/localization/de/script-convert-dlsql-to-dlol_de.md b/content/localization/de/script-convert-dlsql-to-dlol_de.md new file mode 100644 index 00000000..8981718d --- /dev/null +++ b/content/localization/de/script-convert-dlsql-to-dlol_de.md @@ -0,0 +1,154 @@ +--- +uid: script-convert-dlsql-to-dlol +title: Direct Lake auf SQL zu OneLake konvertieren +author: Daniel Otykier +updated: 2025-06-20 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Direct Lake auf SQL zu OneLake konvertieren + +## Skriptzweck + +Dieses Skript konvertiert ein Modell, das Direct Lake auf SQL (DL/SQL) verwendet, zu Direct Lake auf OneLake (DL/OL). Wie im [Artikel zur Direct Lake-Anleitung](xref:direct-lake-guidance) dargelegt, geht es einfach darum, die M-Abfrage für den freigegebenen Ausdruck, der von den Direct Lake-Partitionen im Modell verwendet wird, zu aktualisieren, um den Connector [`AzureStorage.DataLake`](https://learn.microsoft.com/en-us/powerquery-m/azurestorage-datalake) statt des Connectors [`Sql.Database`](https://learn.microsoft.com/en-us/powerquery-m/sql-database) zu verwenden. + +## Voraussetzungen + +Sie benötigen die **Workspace-ID** sowie die **Ressourcen-ID** Ihres Fabric Warehouse oder Lakehouse. Beide sind GUIDs, die Teil der URL sind, wenn Sie im Fabric-Portal zum Warehouse oder Lakehouse navigieren: + +![Lakehouse Warehouse URL](~/content/assets/images/lakehouse-warehouse-url.png) + +Im obigen Screenshot ist die **Workspace-ID** des Lakehouse blau hervorgehoben, während die **Ressourcen-ID** grün hervorgehoben ist. + +## Skript + +### Direct Lake auf SQL zu OneLake konvertieren + +```csharp +// ================================================================== +// Direct Lake auf SQL zu OneLake konvertieren +// ------------------------------------- +// +// Dieses Skript erkennt, ob das aktuelle Modell Direct Lake auf SQL +// verwendet, und empfiehlt ein Upgrade des Modells auf Direct Lake +// auf OneLake. +// +// Sie benötigen die Workspace-ID und die ID Ihres Fabric Warehouse +// oder Lakehouse (beide sind GUIDs). +// ================================================================== + +// Finden Sie den freigegebenen Ausdruck, der von EntityPartitions im Modell verwendet wird: +using System.Windows.Forms; +using System.Drawing; + +var partition = Model.AllPartitions.OfType() + .FirstOrDefault(e => e.Mode == ModeType.DirectLake && e.ExpressionSource != null); +var expressionSource = partition == null ? null : partition.ExpressionSource; + +if (expressionSource == null) +{ + Warning("Ihr Modell scheint keine Tabellen im Direct Lake-Modus zu enthalten."); + return; +} + +if (!expressionSource.Expression.Contains("Sql.Database")) +{ + Warning("Dieses Modell ist nicht für Direct Lake über SQL konfiguriert."); + return; +} + +WaitFormVisible = false; +Application.UseWaitCursor = false; +var promptDialog = new UrlNameDialog(); +if(promptDialog.ShowDialog() == DialogResult.Cancel) return; + +const string mTemplate = @"let + Source = AzureStorage.DataLake(""https://onelake.dfs.fabric.microsoft.com/%workspaceId%/%resourceId%"", [HierarchicalNavigation=true]) +in + Source"; + +expressionSource.Expression = mTemplate.Replace("%workspaceId%", promptDialog.WorkspaceId.Text).Replace("%resourceId%", promptDialog.ResourceId.Text); + +if(!string.IsNullOrEmpty(Model.Collation)) +{ + Model.Collation = null; + Info("Modell erfolgreich zu Direct Lake auf OneLake konvertiert. Sie müssen es möglicherweise als neues semantisches Modell bereitstellen, da die Modellsortierung geändert wurde."); +} +else + Info("Modell erfolgreich zu Direct Lake auf OneLake konvertiert."); + +// UI-Code unter dieser Zeile: +public class UrlNameDialog : Form +{ + public TextBox WorkspaceId { get; private set; } + public TextBox ResourceId { get; private set; } + private Button okButton; + + public UrlNameDialog() + { + Text = "Direct Lake auf SQL zu OneLake konvertieren"; + AutoSize = true; + AutoSizeMode = AutoSizeMode.GrowAndShrink; + StartPosition = FormStartPosition.CenterParent; + Padding = new Padding(20); + + var mainLayout = new TableLayoutPanel + { + ColumnCount = 1, + RowCount = 3, + Dock = DockStyle.Fill, + AutoSize = true, + AutoSizeMode = AutoSizeMode.GrowAndShrink + }; + Controls.Add(mainLayout); + + // Workspace ID + mainLayout.Controls.Add(new Label { Text = "Workspace-ID (GUID):", AutoSize = true }); + WorkspaceId = new TextBox { Width = 1000 }; + mainLayout.Controls.Add(WorkspaceId); + + // Resource ID + mainLayout.Controls.Add(new Label { Text = "Fabric Warehouse / Lakehouse-ID (GUID):", AutoSize = true, Padding = new Padding(0, 20, 0, 0) }); + ResourceId = new TextBox { Width = 1000 }; + mainLayout.Controls.Add(ResourceId); + + // Buttons + var buttonPanel = new FlowLayoutPanel + { + Padding = new Padding(0, 20, 0, 0), + FlowDirection = FlowDirection.RightToLeft, + Dock = DockStyle.Fill, + AutoSize = true + }; + + okButton = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true, Enabled = false }; + var cancelButton = new Button { Text = "Abbrechen", DialogResult = DialogResult.Cancel, AutoSize = true }; + buttonPanel.Controls.Add(okButton); + buttonPanel.Controls.Add(cancelButton); + + AcceptButton = okButton; + CancelButton = cancelButton; + mainLayout.Controls.Add(buttonPanel); + + WorkspaceId.TextChanged += Validate; + ResourceId.TextChanged += Validate; + } + + private void Validate(object sender, EventArgs e) + { + Guid g; + okButton.Enabled = Guid.TryParse(WorkspaceId.Text, out g) && Guid.TryParse(ResourceId.Text, out g); + } +} +``` + +### Erklärung + +Das Skript versucht zunächst, eine EntityPartition zu finden, die für den Direct Lake-Modus konfiguriert ist und eine Expression Source (einen Verweis auf einen freigegebenen Ausdruck) aufweist. Wenn keine solche Partition gefunden wird, zeigt es eine Warnmeldung an und wird beendet. Darüber hinaus muss der referenzierte freigegebene Ausdruck den Connector `Sql.Database` angeben, was darauf hinweist, dass das Modell derzeit Direct Lake auf SQL verwendet. + +Sobald das Skript bestätigt, dass das Modell Direct Lake auf SQL verwendet, fordert es den Benutzer auf, die **Workspace-ID** und **Ressourcen-ID** des Fabric Warehouse oder Lakehouse einzugeben. Das Skript ersetzt dann den Connector `Sql.Database` im freigegebenen Ausdruck durch den Connector `AzureStorage.DataLake` unter Verwendung der bereitgestellten IDs. + +Abschließend löscht das Skript die Sortierung des Modells, falls diese gesetzt ist, da diese Änderung eine neue Sortierung erfordert. Das Skript informiert den Benutzer dann, dass das Modell erfolgreich zu Direct Lake auf OneLake konvertiert wurde. \ No newline at end of file diff --git a/content/localization/de/script-convert-import-to-dlol_de.md b/content/localization/de/script-convert-import-to-dlol_de.md new file mode 100644 index 00000000..b80667a6 --- /dev/null +++ b/content/localization/de/script-convert-import-to-dlol_de.md @@ -0,0 +1,206 @@ +--- +uid: script-convert-import-to-dlol +title: Import in Direct Lake auf OneLake konvertieren +author: Daniel Otykier +updated: 2025-06-20 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Import in Direct Lake auf OneLake konvertieren + +## Skriptzweck + +Dieses Skript konvertiert Import-Modus-Tabellen in Direct Lake auf OneLake (DL/OL). Wie im [Direct Lake-Leitartikel](xref:direct-lake-guidance) dargelegt, müssen wir die Partition(en) in solchen Tabellen durch eine einzelne [EntityPartition](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.entitypartitionsource?view=analysisservices-dotnet) ersetzen, die den Namen und das Schema der Tabelle/materialisierten Ansicht im Fabric Lakehouse oder Warehouse angibt, während auf einen freigegebenen Ausdruck verwiesen wird, der den [`AzureStorage.DataLake`](https://learn.microsoft.com/en-us/powerquery-m/azurestorage-datalake) (OneLake)-Connector verwendet. + +## Voraussetzungen + +Sie benötigen die **Workspace-ID** sowie die **Ressourcen-ID** Ihres Fabric Warehouse oder Lakehouse. Beide sind GUIDs, die Teil der URL sind, wenn Sie im Fabric-Portal zum Warehouse oder Lakehouse navigieren: + +![Lakehouse Warehouse URL](~/content/assets/images/lakehouse-warehouse-url.png) + +Im obigen Screenshot ist die **Workspace-ID** des Lakehouse blau hervorgehoben, während die **Ressourcen-ID** grün hervorgehoben ist. + +Wenn Sie sich mit einem Fabric Warehouse oder einem Lakehouse verbinden, das Schemas unterstützt, müssen Sie auch das **Schema** der Tabelle/materialisierten Ansicht kennen, mit der Sie sich verbinden möchten. + +> [!WARNING] +> Tabellen im Import-Modus können Transformationen in ihren Partitionen definieren (ausgedrückt mit SQL oder M). Diese Transformationen gehen bei der Konvertierung in den Direct Lake auf OneLake-Modus verloren, da die Direct Lake-Partitionen eine 1:1-Zuordnung der Spalten in der Quelltabelle/materialisierten Ansicht enthalten müssen. Stellen Sie daher sicher, dass die Quelltabelle/materialisierte Ansicht denselben Namen im Fabric Warehouse oder Lakehouse hat wie im semantischen Modell, und dass die Spaltenzuordnungen korrekt sind, bevor Sie dieses Skript ausführen. + +## Skript + +### Import-Modus-Tabellen in Direct Lake auf OneLake konvertieren + +```csharp +// ================================================================== +// Import in Direct Lake auf OneLake konvertieren +// ---------------------------------------- +// +// Dieses Skript konvertiert die ausgewählten (Import-)Tabellen oder +// alle Tabellen im Modell, falls nichts ausgewählt ist, in Direct +// Lake auf OneLake-Tabellen. +// +// WARNUNG: Das Skript geht davon aus, dass Tabellen im Fabric +// Warehouse oder Lakehouse denselben Namen haben wie im semantischen +// Modell. Darüber hinaus gehen alle Transformationen (M- oder +// SQL-basiert) in den Import-Partitionen verloren, da Direct Lake +// Modus-Tabellen dieselben Spalten 1:1 wie die Quelltabelle/ +// materialisierte Ansicht enthalten müssen. +// +// Sie benötigen die Workspace-ID und die ID Ihres Fabric Warehouse +// oder Lakehouse (beide sind GUIDs). +// ================================================================== + +// Suchen Sie den freigegebenen Ausdruck, der von EntityPartitions im Modell verwendet wird: +using System.Windows.Forms; +using System.Drawing; +using System.Data; + +IEnumerable tableSource = Selected.Context.HasFlag(Context.Tables) ? (IEnumerable
    )Selected.Tables : Model.Tables; +var importTables = tableSource.Where(t => t.Partitions.All(p => + (p.SourceType == PartitionSourceType.Query || p.SourceType == PartitionSourceType.M) && + (p.Mode == ModeType.Import || (p.Mode == ModeType.Default && Model.DefaultMode == ModeType.Import)))) + .ToList(); + +WaitFormVisible = false; +Application.UseWaitCursor = false; + +if(importTables.Count == 0) +{ + Warning("Das Modell oder die Auswahl enthält keine Tabellen im Import-Modus"); + return; +} +else +{ + var result = MessageBox.Show("Die folgenden Tabellen werden konvertiert:\r\n\r\n" + string.Join("\r\n", importTables.Select(t => " - " + t.Name)) + + "\r\n\r\nFortfahren?", + "Konvertierung bestätigen?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); + if (result == DialogResult.Cancel) return; +} + +string workspaceId = string.Empty; +string resourceId = string.Empty; +var sharedExpression = Model.Expressions.FirstOrDefault(e => e.Expression.Contains("AzureStorage.DataLake")); +if(sharedExpression != null) +{ + // Extrahieren Sie vorhandene Workspace-ID und Ressourcen-ID + var ix = sharedExpression.Expression.IndexOf("onelake.dfs.fabric.microsoft.com"); + var url = sharedExpression.Expression.Substring(ix + 33, 73); + var guids = url.Split('/'); + Guid g; + if(Guid.TryParse(guids[0], out g) && Guid.TryParse(guids[1], out g)) + { + workspaceId = guids[0]; + resourceId = guids[1]; + } +} + +var promptDialog = new UrlNameDialog(workspaceId, resourceId); +if(promptDialog.ShowDialog() == DialogResult.Cancel) return; + +const string mTemplate = @"let + Source = AzureStorage.DataLake(""https://onelake.dfs.fabric.microsoft.com/%workspaceId%/%resourceId%"", [HierarchicalNavigation=true]) +in + Source"; + +if(promptDialog.WorkspaceId.Text != workspaceId || promptDialog.ResourceId.Text != resourceId) +{ + if (sharedExpression == null) sharedExpression = Model.AddExpression("DatabaseQuery"); + sharedExpression.Expression = mTemplate.Replace("%workspaceId%", promptDialog.WorkspaceId.Text).Replace("%resourceId%", promptDialog.ResourceId.Text); +} + +foreach(var table in importTables) +{ + var ep = table.AddEntityPartition(); + ep.EntityName = table.Name; + ep.ExpressionSource = sharedExpression; + ep.SchemaName = promptDialog.Schema.Text; + ep.Mode = ModeType.DirectLake; + foreach(var p in table.Partitions.ToList()) if(p != ep) p.Delete(); + ep.Name = table.Name; +} + +Info("Tabellen in Direct Lake auf OneLake-Modus konvertiert."); + +public class UrlNameDialog : Form +{ + public TextBox WorkspaceId { get; private set; } + public TextBox ResourceId { get; private set; } + public TextBox Schema { get; private set; } + private Button okButton; + + public UrlNameDialog(string workspaceId, string resourceId) + { + Text = "Direct Lake auf SQL in OneLake konvertieren"; + AutoSize = true; + AutoSizeMode = AutoSizeMode.GrowAndShrink; + StartPosition = FormStartPosition.CenterParent; + Padding = new Padding(20); + + var mainLayout = new TableLayoutPanel + { + ColumnCount = 1, + RowCount = 3, + Dock = DockStyle.Fill, + AutoSize = true, + AutoSizeMode = AutoSizeMode.GrowAndShrink + }; + Controls.Add(mainLayout); + + // Workspace ID + mainLayout.Controls.Add(new Label { Text = "Workspace-ID (GUID):", AutoSize = true }); + WorkspaceId = new TextBox { Width = 1000, Text = workspaceId }; + mainLayout.Controls.Add(WorkspaceId); + + // Resource ID + mainLayout.Controls.Add(new Label { Text = "Fabric Warehouse / Lakehouse-ID (GUID):", AutoSize = true, Padding = new Padding(0, 20, 0, 0) }); + ResourceId = new TextBox { Width = 1000, Text = resourceId }; + mainLayout.Controls.Add(ResourceId); + + // Schema + mainLayout.Controls.Add(new Label { Text = "Schema (optional):", AutoSize = true, Padding = new Padding(0, 20, 0, 0) }); + Schema = new TextBox { Width = 1000 }; + mainLayout.Controls.Add(Schema); + + + // Buttons + var buttonPanel = new FlowLayoutPanel + { + Padding = new Padding(0, 20, 0, 0), + FlowDirection = FlowDirection.RightToLeft, + Dock = DockStyle.Fill, + AutoSize = true + }; + + okButton = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true, Enabled = false }; + var cancelButton = new Button { Text = "Abbrechen", DialogResult = DialogResult.Cancel, AutoSize = true }; + buttonPanel.Controls.Add(okButton); + buttonPanel.Controls.Add(cancelButton); + + AcceptButton = okButton; + CancelButton = cancelButton; + mainLayout.Controls.Add(buttonPanel); + + WorkspaceId.TextChanged += Validate; + ResourceId.TextChanged += Validate; + this.Shown += Validate; + } + + private void Validate(object sender, EventArgs e) + { + Guid g; + okButton.Enabled = Guid.TryParse(WorkspaceId.Text, out g) && Guid.TryParse(ResourceId.Text, out g); + } +} +``` + +### Erklärung + +Das Skript bestimmt zunächst, ob alle Import-Modus-Tabellen im Modell oder nur die vom Benutzer ausgewählten konvertiert werden sollen. Es prüft dann, ob solche Tabellen vorhanden sind, und fordert den Benutzer auf, die Konvertierung zu bestätigen, bevor er fortfährt. + +Das Skript versucht dann, einen freigegebenen Ausdruck zu finden, der den `AzureStorage.DataLake`-Connector verwendet. Falls ein solcher Ausdruck vorhanden ist, extrahiert er die Workspace-ID und Ressourcen-ID aus dem Ausdruck. Wenn kein solcher Ausdruck gefunden wird, wird ein neuer erstellt. + +Der Benutzer wird dann aufgefordert, die Workspace-ID und Ressourcen-ID des Fabric Warehouse oder Lakehouse sowie einen optionalen Schemanamen einzugeben. Das Skript ersetzt den vorhandenen freigegebenen Ausdruck durch einen neuen, der die bereitgestellten IDs verwendet, falls diese geändert wurden. + +Schließlich erstellt das Skript für jede Import-Modus-Tabelle eine neue EntityPartition mit dem angegebenen Namen und Schema, die auf den freigegebenen Ausdruck verweist. Es löscht dann alle vorhandenen Partitionen in der Tabelle, die nicht die neu erstellte EntityPartition sind. \ No newline at end of file diff --git a/content/localization/de/script-count-rows_de.md b/content/localization/de/script-count-rows_de.md new file mode 100644 index 00000000..2a3ea68f --- /dev/null +++ b/content/localization/de/script-count-rows_de.md @@ -0,0 +1,54 @@ +--- +uid: script-count-rows +title: Count Table Rows +author: Kurt Buhler +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Count Rows in a Table + +## Script Purpose + +If you want to see how many rows are loaded to a table, or quickly check if the table has been loaded, at all. +This script requires connection to a remote model or connection via Workspace Mode. + +## Script + +### Count the rows in the selected table + +```csharp +// This script counts rows in a selected table and displays the result in a pop-up info box. +// It does not write any changes to this model. +// +// Use this script when you want to check whether a table was loaded or how many rows it has. +// +// Get table name +string _TableName = + Selected.Table.DaxObjectFullName; + +// Count table rows +string _dax = + "{ FORMAT( COUNTROWS (" + _TableName + "), \"#,##0\" ) }"; + +// Evaluate DAX +string _TableRows = + Convert.ToString(EvaluateDax( _dax )); + +// Return output in pop-up +Info ( "Number of rows in " + _TableName + ": " + _TableRows); +``` + +### Explanation + +This snippet goes through the model and counts the different object types, displaying them in a hierarchical "node and tree" format that is manually constructed. +You can comment out + +## Example Output + +
    + Example of the dialog pop-up that informs the user of how many rows are in the selected table upon running the script.
    Figure 1: An example of the Info box that appears to inform the user of how many rows are in the selected table, upon running this script.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-count-things_de.md b/content/localization/de/script-count-things_de.md new file mode 100644 index 00000000..849b7f26 --- /dev/null +++ b/content/localization/de/script-count-things_de.md @@ -0,0 +1,204 @@ +--- +uid: script-count-things +title: Modellobjekte zählen +author: Kurt Buhler +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Objekte im Modell zählen + +## Skriptzweck + +Wenn Sie einen Überblick über den Inhalt eines Modells und die Anzahl der Objekte erhalten möchten: + +- Wie viele Maße sind in einem Modell. +- Wie viele Spalten und berechnete Spalten sind in einem Modell. +- Wie viele Tabellen und berechnete Tabellen sind in einem Modell. +- Wie viele Beziehungen, inaktive Beziehungen usw. + +## Skript + +### Die Anzahl der Modellobjekte nach Typ zählen + +```csharp +// Dieses Skript zählt Objekte in Ihrem Modell und zeigt sie in einem Pop-up-Informationsfeld an. +// Es nimmt keine Änderungen an diesem Modell vor. +// +// Verwenden Sie dieses Skript, wenn Sie ein neues Modell öffnen und einen "Hubschrauberperspektive" auf den Inhalt benötigen. +// +// Berechnungsgruppen und Berechnungselemente zählen +int _calcgroups = 0; +int _calcitems = 0; +foreach ( var _calcgroup in Model.CalculationGroups ) +{ + _calcgroups = _calcgroups + 1; + foreach ( var _item in _calcgroup.CalculationItems ) + { + _calcitems = _calcitems + 1; + } +} + +// Partitionen und DAX-Parameter zählen +int _partitions = 0; +int _whatifparameters = 0; +int _fieldparameters = 0; +foreach ( var _table in Model.Tables ) +{ + foreach ( var _partition in _table.Partitions ) + { + string _type = Convert.ToString(_partition.SourceType); + string _exp = Convert.ToString(_partition.Expression); + if ( _type == "M" ) + { + _partitions = _partitions + 1; + } + else if ( _type == "Calculated" && _exp.Contains("NAMEOF") ) + { + _fieldparameters = _fieldparameters + 1; + } + else if ( _type == "Calculated" && _exp.Contains("GENERATESERIES") ) + { + _whatifparameters = _whatifparameters + 1; + } + + } +} + +// Durchschnittliche Messlänge +decimal _numLines = 0; +decimal _numChars = 0; +int _measures = Model.AllMeasures.Count(); +foreach ( var _measure in Model.AllMeasures ) +{ + _numLines = _numLines + _measure.Expression.Split("\n").Length; + _numChars = _numChars + _measure.Expression.Length; +} +_numLines = Math.Round(_numLines / _measures, 1); +_numChars = Math.Round(_numChars / _measures, 1); + + +// Pop-up zurückgeben +Info ( "Im Modell sehen wir die folgenden Objekte:\n\n" + + + "-----------------------------------------\n" + + "Datenobjekte\n" + + "-----------------------------------------\n" + + " ├─ PQ-Ausdrücke: " + Convert.ToString(Model.Expressions.Count()) + "\n" + + " │\n" + + " └─ Tabellen: " + Convert.ToString(Model.Tables.Count()) + "\n" + + " ├─ Tabellen mit inkrementeller Aktualisierung: " + + Convert.ToString(Model.Tables.Where( + _ir => + Convert.ToString(_ir.EnableRefreshPolicy) + == + "True").Count()) + "\n" + + + " │\n" + + " ├─ Berechnete Tabellen: " + + Convert.ToString( + Model.Tables.Where( + _tables => + Convert.ToString(_tables.Columns[0].Type) + == + "CalculatedTableColumn").Count()) + "\n" + + + " │ ├─ What-if-Parameter: " + + Convert.ToString(_whatifparameters) + "\n" + + " │ └─ Feldparameter: " + + Convert.ToString(_fieldparameters) + "\n" + + " │\n" + + " ├─ M-Partitionen: " + + Convert.ToString(_partitions) + "\n" + + " │\n" + + " └─ Gesamttabellenspalten: " + + Convert.ToString(Model.AllColumns.Count()) + "\n\n" + + + "-----------------------------------------\n" + + "DAX-Objekte\n" + + "-----------------------------------------\n" + + " ├─ Beziehungen: " + + Convert.ToString(Model.Relationships.Count()) + "\n" + + " │ ├─ Bidirektional: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.CrossFilteringBehavior) + == + "BothDirections").Count()) + "\n" + + + " │ ├─ Viele-zu-Viele: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.FromCardinality) + == + "Many" + && + Convert.ToString(_relationships.ToCardinality) + == + "Many").Count()) + "\n" + + + " │ ├─ Eins-zu-Eins: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.FromCardinality) + == + "One" + && + Convert.ToString(_relationships.ToCardinality) + == + "One").Count()) + "\n" + + + " │ └─ Inaktiv: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.IsActive) + == + "False").Count()) + "\n" + + + " │\n" + + " ├─ Berechnungsgruppen: " + + Convert.ToString(_calcgroups) + "\n" + + " │ └─ Berechnungselemente: " + + Convert.ToString(_calcitems) + "\n" + + " │\n" + + " ├─ Berechnete Spalten: " + + Convert.ToString(Model.AllColumns.Where( + _columns => + Convert.ToString(_columns.Type) + == + "Calculated").Count()) + "\n" + + + " │\n" + + " └─ Measures: " + + Convert.ToString(_measures) + "\n" + + " └─ Durchschn. DAX-Zeilen: " + + Convert.ToString(_numLines) + " Zeilen \n" + + " └─ Durchschn. DAX-Zeichen: " + + Convert.ToString(_numChars) + " Zeichen \n\n" + + + "-----------------------------------------\n" + + "Sonstige Objekte\n" + + "-----------------------------------------\n" + + " ├─ Datensicherheitsrollen: " + + Convert.ToString(Model.Roles.Count()) + "\n" + + " ├─ Explizite Datenquellen: " + + Convert.ToString(Model.DataSources.Count()) + "\n" + + " ├─ Perspektiven: " + + Convert.ToString(Model.Perspectives.Count()) + "\n" + + " └─ Übersetzungen: " + + Convert.ToString(Model.Cultures.Count())); +``` + +### Erklärung + +Dieses Snippet durchläuft das Modell und zählt die verschiedenen Objekttypen und zeigt sie in einem hierarchischen "Knoten- und Baum"-Format an, das manuell konstruiert ist. +Sie können die Teile auskommentieren, die Sie nicht benötigen. + +## Beispielausgabe + +
    + Example of the dialog pop-up that informs the user of how many rows are in the selected table upon running the script.
    Abbildung 1: Ein Beispiel der Info-Box-Ausgabe, die den Benutzer über die Anzahl der Objekte im Modell bei der Skriptausführung informiert. Wenn bestimmte Objekte nicht relevant sind, können sie vom Benutzer auskommentiert oder aus dem Skript entfernt werden, und das Skript kann erneut ausgeführt werden.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-create-and-replace-M-parameter_de.md b/content/localization/de/script-create-and-replace-M-parameter_de.md new file mode 100644 index 00000000..1fa79c53 --- /dev/null +++ b/content/localization/de/script-create-and-replace-M-parameter_de.md @@ -0,0 +1,200 @@ +--- +uid: script-create-and-replace-parameter +title: M Parameter erstellen (Automatische Ersetzung) +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 3.x +--- + +# Neuen M Parameter erstellen und zu vorhandenen M Partitionen hinzufügen + +## Skriptzweck + +Wenn Sie eine Zeichenfolge in Model M Partitionen ersetzen möchten (z. B. Verbindungszeichenfolge, Filterbedingung, Spaltenname usw.) mit einem Parameterwert.

    + +> [!NOTE] +> Dieses Skript funktioniert nur mit Parametern vom Datentyp `string`. +> Für andere Datentypen ändern Sie bitte die Variablentypen und den Parameterwert entsprechend.

    + +## Skript + +### Neuen M Parameter erstellen und zu vorhandenen M Partitionen hinzufügen + +```csharp +// Dieses Skript erstellt einen neuen M Parameter als 'Shared Expression'. +// Es findet auch den Standardwert in allen M Partitionen und ersetzt ihn durch den Namen des Parameterobjekts. +//#r "System.Drawing" + +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +// Spinfeld 'Makro wird ausgeführt' ausblenden +ScriptHelper.WaitFormVisible = false; + +// Variablen initialisieren +string _ParameterName = "New Parameter"; +string _ParameterValue = "ParameterValue"; + +// WinForms-Eingabeaufforderung zum Eingeben von Parameternamen / Wert +using (Form prompt = new Form()) +{ + Font formFont = new Font("Segoe UI", 11); + + // Eingabeaufforderung konfigurieren + prompt.AutoSize = true; + prompt.MinimumSize = new Size(380, 120); + prompt.Text = "Neuen M Parameter erstellen"; + prompt.StartPosition = FormStartPosition.CenterScreen; + + // Suchen: Bezeichnung + Label parameterNameLabel = new Label() { Text = "Namen eingeben:" }; + parameterNameLabel.Location = new Point(20, 20); + parameterNameLabel.AutoSize = true; + parameterNameLabel.Font = formFont; + + // Textfeld zur Eingabe des Substring-Texts + TextBox parameterNameBox = new TextBox(); + parameterNameBox.Width = 200; + parameterNameBox.Location = new Point(parameterNameLabel.Location.X + parameterNameLabel.Width + 20, parameterNameLabel.Location.Y - 4); + parameterNameBox.SelectedText = "Neuer Parameter"; + parameterNameBox.Font = formFont; + + // Ersetzen: Bezeichnung + Label parameterValueLabel = new Label() { Text = "Wert eingeben:" }; + parameterValueLabel.Location = new Point(parameterNameLabel.Location.X, parameterNameLabel.Location.Y + parameterNameLabel.Height + 20); + parameterValueLabel.AutoSize = true; + parameterValueLabel.Font = formFont; + + // Textfeld zur Eingabe des Substring-Texts + TextBox parameterValueBox = new TextBox() { Left = parameterValueLabel.Right + 20, Top = parameterValueLabel.Location.Y - 4, Width = parameterNameBox.Width }; + parameterValueBox.SelectedText = "Parameterwert"; + parameterValueBox.Font = formFont; + + // Schaltfläche OK + Button okButton = new Button() { Text = "Erstellen", Left = 20, Width = 75, Top = parameterValueBox.Location.Y + parameterValueBox.Height + 20 }; + okButton.MinimumSize = new Size(75, 25); + okButton.AutoSize = true; + okButton.Font = formFont; + + // Schaltfläche Abbrechen + Button cancelButton = new Button() { Text = "Abbrechen", Left = okButton.Location.X + okButton.Width + 10, Top = okButton.Location.Y }; + cancelButton.MinimumSize = new Size(75, 25); + cancelButton.AutoSize = true; + cancelButton.Font = formFont; + + // Schaltflächenaktionen + okButton.Click += (sender, e) => { _ParameterName = parameterNameBox.Text; _ParameterValue = parameterValueBox.Text; prompt.DialogResult = DialogResult.OK; }; + cancelButton.Click += (sender, e) => { prompt.DialogResult = DialogResult.Cancel; }; + + prompt.AcceptButton = okButton; + prompt.CancelButton = cancelButton; + + prompt.Controls.Add(parameterNameLabel); + prompt.Controls.Add(parameterNameBox); + prompt.Controls.Add(parameterValueLabel); + prompt.Controls.Add(parameterValueBox); + prompt.Controls.Add(okButton); + prompt.Controls.Add(cancelButton); + + // Der Benutzer hat auf OK geklickt, daher wird die Such- und Ersetzungslogik ausgeführt + if (prompt.ShowDialog() == DialogResult.OK) + { + + // Erstellt den Parameter + Model.AddExpression( + _ParameterName, + @" + """ + _ParameterValue + + @""" meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type text + ]" + ); + + + // Informiert den Benutzer, dass der Parameter erfolgreich erstellt wurde + Info ( + "Parameter erfolgreich erstellt: " + @"""" + + _ParameterName + @"""" + + "\nStandardwert: " + @"""" + + _ParameterValue + @""""); + + + // Findet den Standardwert des Parameters in M Partitionen und ersetzt ihn durch den Parameternamen + string _Find = @"""" + _ParameterValue + @""""; + string _Replace = @"#""" + _ParameterName + @""""; + + int _NrMPartitions = 0; + int _NrReplacements = 0; + var _ReplacementsList = new List(); + + foreach ( var _Tables in Model.Tables ) + { + foreach ( var _p in _Tables.Partitions ) + { + if ( _p.SourceType == PartitionSourceType.M ) + { + if ( _p.Expression != _p.Expression.Replace( _Find, _Replace ) ) + { + _p.Expression = _p.Expression.Replace( _Find, _Replace ); + + // Verfolgt, welche M Partitionen ersetzt wurden (und wie viele) + _NrReplacements = _NrReplacements + 1; + _ReplacementsList.Add( _p.Name ); + } + + // Zählt die Gesamtzahl der M Partitionen + _NrMPartitions = _NrMPartitions + 1; + } + } + } + + + // Erstellt eine Aufzählungsliste aller M Partitionen, die ersetzt wurden + string _ReplacedPartitions = " • " + String.Join("\n • ", _ReplacementsList ); + + + // Informiert + // - Ob die Such- und Ersetzung erfolgreich war + // - Wie viele M Partitionen ersetzt wurden + // - Welche M Partitionen mit der Such- und Ersetzung durchgeführt wurden + Info ( + "Erfolgreich ersetzt\n\n " + + _Find + + "\n\n mit: \n\n" + + _Replace + + "\n\n in " + + Convert.ToString(_NrReplacements) + + " von " + + Convert.ToString(_NrMPartitions) + + " M Partitionen:\n" + + _ReplacedPartitions + ); + + } + else + { + Error ( "Eingabe abgebrochen! Skript ohne Änderungen beendet."); + } +} +``` + +### Erklärung + +Dieser Codeausschnitt öffnet ein Dialogfeld, in dem der Benutzer den Parameternamen und den Wert eingeben kann, und erstellt dann den Parameter als 'Shared Expression' im Modell. +Anschließend werden alle M Partitionen nach dem Standardwert durchsucht und durch `#"ParameterName"` ersetzt. + +## Beispielausgabe + +
    + Data Security Create Role
    Abbildung 1: Das Popup-Dialogfeld, das beim Ausführen des Skripts angezeigt wird und zur Eingabe des Parameternamens und Werts auffordert.
    +
    + +
    + Data Security Create Role
    Abbildung 2: Bestätigungsdialog, der zeigt, dass der Parameter erstellt wurde und die entsprechende Wertteilzeichenfolge in allen M Partitionsausdrücken ersetzt wurde.
    Passen Sie für Parameter anderer Typen den C#-Code entsprechend an. +
    \ No newline at end of file diff --git a/content/localization/de/script-create-databricks-relationships_de.md b/content/localization/de/script-create-databricks-relationships_de.md new file mode 100644 index 00000000..5c0005a2 --- /dev/null +++ b/content/localization/de/script-create-databricks-relationships_de.md @@ -0,0 +1,610 @@ +--- +uid: script-create-databricks-relationships +title: Databricks-Beziehungen erstellen +author: Johnny Winter +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Databricks-Beziehungen erstellen + +## Zweck des Skripts + +Dieses Skript wurde als Teil der Tabular Editor x Databricks Serie erstellt. In Unity Catalog ist es möglich, Primär- und Fremdschlüsselbeziehungen zwischen Tabellen zu definieren. Dieses Skript kann diese Informationen wiederverwenden, um Beziehungen in Tabular Editor automatisch zu erkennen und zu erstellen. Beim Importieren der Beziehungen blendet das Skript auch Primär- und Fremdschlüssel aus und setzt IsAvailableInMDX auf false (mit Ausnahme von Primärschlüsseln vom Typ DateTime). Primärschlüssel werden im semantischen Modell auch als IsKey = TRUE gekennzeichnet.

    + +> [!NOTE] +> Dieses Skript erfordert die Installation des Simba Spark ODBC Treibers (Download von https://www.databricks.com/spark/odbc-drivers-download) +> Jede Ausführung des Skripts fordert den Benutzer auf, ein Databricks Personal Access Token einzugeben. Dies ist erforderlich, um sich bei Databricks zu authentifizieren. +> Das Skript nutzt die information_schema Tabellen in Unity Catalog, um Beziehungsinformationen abzurufen. Möglicherweise müssen Sie sich mit Ihrem Databricks Administrator absprechen, um sicherzustellen, dass Sie die Berechtigung zum Abfragen dieser Tabellen haben.

    + +## Skript + +### Databricks-Beziehungen erstellen + +```csharp +/* + * Title: Create Databricks Relationships + * Author: Johnny Winter, greyskullanalytics.com + * + * This script, when executed, will loop through the currently selected tables and send a query to the Databricks Information Schema tables to see if any foreign keys + * have been defined. Where foreign keys are identified, the script will create relationships between the tables in the semantic model. + * With the exception of dimension columns that are datetime type, key columns will be hidden once relationshsips are created, with primary keys marked as primary keys and IsAvailableInMDX set to false. + * Step 1: Select one or more tables in the model. These should be tables which have a foreign key relationship defined in Unity Catalog + (typically fact tables, but they could also be bridge tables or outrigger dimensions). + * Step 2: Run this script + * Step 3: Enter your Databricks Personal Access Token when prompted + * Step 4: The script will connect to Databricks and detect where foreign keys exist on the selected table. + If the relationship does not already exist in the semantic model, it will be created. + If a relationship already exists between the two tables, the new relationship will be created as inactive + For each table processed, a message box will display the number of relationships created. + * Click OK to continue to the next table. + * Notes: + * - This script requires the Simba Spark ODBC Driver to be installed (download from https://www.databricks.com/spark/odbc-drivers-download) + * - Each run of the script will prompt the user for a Databricks Personal Access Token + */ +#r "Microsoft.VisualBasic" +using System; +using System.Data.Odbc; +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using Microsoft.VisualBasic; +using sysData = System.Data; + +//code to create a masked input box for Databricks PAT token +public partial class PasswordInputForm : Form +{ + public string Password { get; private set; } + + private TextBox passwordTextBox; + private Button okButton; + private Button cancelButton; + private Label promptLabel; + + public PasswordInputForm(string prompt, string title) + { + InitializeComponent(prompt, title); + } + + private void InitializeComponent(string prompt, string title) + { + this.Text = title; + this.Size = new System.Drawing.Size(4000, 1500); + this.StartPosition = FormStartPosition.WindowsDefaultLocation; + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + + // Prompt label + promptLabel = new Label(); + promptLabel.Text = prompt; + promptLabel.Location = new System.Drawing.Point(12, 15); + promptLabel.Size = new System.Drawing.Size(360, 40); + promptLabel.AutoSize = false; + this.Controls.Add(promptLabel); + + // Password textbox + passwordTextBox = new TextBox(); + passwordTextBox.Location = new System.Drawing.Point(12, 55); + passwordTextBox.Size = new System.Drawing.Size(360, 20); + passwordTextBox.UseSystemPasswordChar = true; // This masks the input + passwordTextBox.KeyPress += (s, e) => + { + if (e.KeyChar == (char)Keys.Return) + { + OkButton_Click(null, null); + e.Handled = true; + } + }; + this.Controls.Add(passwordTextBox); + + // OK button + okButton = new Button(); + okButton.Text = "OK"; + okButton.Location = new System.Drawing.Point(216, 85); + okButton.Size = new System.Drawing.Size(150, 50); + okButton.Click += OkButton_Click; + this.Controls.Add(okButton); + + // Cancel button + cancelButton = new Button(); + cancelButton.Text = "Cancel"; + cancelButton.Location = new System.Drawing.Point(297, 85); + cancelButton.Size = new System.Drawing.Size(150, 50); + cancelButton.Click += CancelButton_Click; + this.Controls.Add(cancelButton); + + // Set default and cancel buttons + this.AcceptButton = okButton; + this.CancelButton = cancelButton; + + // Focus on textbox when form loads + this.Load += (s, e) => passwordTextBox.Focus(); + } + + private void OkButton_Click(object sender, EventArgs e) + { + Password = passwordTextBox.Text; + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void CancelButton_Click(object sender, EventArgs e) + { + Password = string.Empty; + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + public static string ShowDialog(string prompt, string title) + { + using (var form = new PasswordInputForm(prompt, title)) + { + if (form.ShowDialog() == DialogResult.OK) + return form.Password; + return string.Empty; + } + } +} + +public static class MaskedInputHelper +{ + public static string GetMaskedInput(string prompt, string title, string defaultValue = "") + { + using (var form = new Form()) + { + form.Text = title; + form.Size = new System.Drawing.Size(1000, 500); + form.StartPosition = FormStartPosition.CenterScreen; + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + + var label = new Label() + { + Left = 12, + Top = 15, + Size = new System.Drawing.Size(900, 100), + Text = prompt, + }; + var textBox = new TextBox() + { + Left = 12, + Top = 150, + Size = new System.Drawing.Size(900, 100), + UseSystemPasswordChar = true, + Text = defaultValue, + }; + var buttonOk = new Button() + { + Text = "OK", + Size = new System.Drawing.Size(150, 50), + Left = 12, + Width = 150, + Top = 200, + DialogResult = DialogResult.OK, + }; + var buttonCancel = new Button() + { + Text = "Cancel", + Size = new System.Drawing.Size(150, 50), + Left = 175, + Width = 150, + Top = 200, + DialogResult = DialogResult.Cancel, + }; + + buttonOk.Click += (sender, e) => + { + form.Close(); + }; + form.Controls.Add(label); + form.Controls.Add(textBox); + form.Controls.Add(buttonOk); + form.Controls.Add(buttonCancel); + form.AcceptButton = buttonOk; + form.CancelButton = buttonCancel; + + return form.ShowDialog() == DialogResult.OK ? textBox.Text : string.Empty; + } + } +} + +//Code to retrieve Databricks Connection information from the M Query in a table partition +public class DatabricksConnectionInfo +{ + public string ServerHostname { get; set; } + public string HttpPath { get; set; } + public string DatabaseName { get; set; } + public string SchemaName { get; set; } + public string TableName { get; set; } + + public override string ToString() + { + return $"Server: {ServerHostname}\n" + + $"HTTP Path: {HttpPath}\n" + + $"Database: {DatabaseName}\n" + + $"Schema: {SchemaName}\n" + + $"Table: {TableName}"; + } +} + +public class PowerQueryMParser +{ + public static DatabricksConnectionInfo ParseMQuery(string mQuery) + { + if (string.IsNullOrWhiteSpace(mQuery)) + throw new ArgumentException("M query cannot be null or empty"); + + var connectionInfo = new DatabricksConnectionInfo(); + + try + { + // Parse Source line to extract server hostname and HTTP path + ParseSourceLine(mQuery, connectionInfo); + + // Parse Database line to extract database name + ParseDatabaseLine(mQuery, connectionInfo); + + // Parse Schema line to extract schema name + ParseSchemaLine(mQuery, connectionInfo); + + // Parse Data line to extract table name + ParseDataLine(mQuery, connectionInfo); + + return connectionInfo; + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error parsing M query: {ex.Message}", ex); + } + } + + private static void ParseSourceLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match both: + // Source = DatabricksMultiCloud.Catalogs("hostname", "httppath", null), + // Source = Databricks.Catalogs("hostname", "httppath", null), + var sourcePattern = + @"Source\s*=\s*Databricks(?:MultiCloud)?\.Catalogs\s*\(\s*""([^""]+)""\s*,\s*""([^""]+)""\s*,\s*null\s*\)"; + var sourceMatch = Regex.Match( + mQuery, + sourcePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!sourceMatch.Success) + throw new FormatException( + "Could not find valid Source definition in M query (supports both Databricks and DatabricksMultiCloud connectors)" + ); + + connectionInfo.ServerHostname = sourceMatch.Groups[1].Value; + connectionInfo.HttpPath = sourceMatch.Groups[2].Value; + } + + private static void ParseDatabaseLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Database = Source{[Name="databasename",Kind="Database"]}[Data], + var databasePattern = + @"Database\s*=\s*Source\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Database""\s*\]\s*}\s*\[\s*Data\s*\]"; + var databaseMatch = Regex.Match( + mQuery, + databasePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!databaseMatch.Success) + throw new FormatException("Could not find valid Database definition in M query"); + + connectionInfo.DatabaseName = databaseMatch.Groups[1].Value; + } + + private static void ParseSchemaLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Schema = Database{[Name="schemaname",Kind="Schema"]}[Data], + var schemaPattern = + @"Schema\s*=\s*Database\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Schema""\s*\]\s*}\s*\[\s*Data\s*\]"; + var schemaMatch = Regex.Match( + mQuery, + schemaPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!schemaMatch.Success) + throw new FormatException("Could not find valid Schema definition in M query"); + + connectionInfo.SchemaName = schemaMatch.Groups[1].Value; + } + + private static void ParseDataLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Data = Schema{[Name="tablename",Kind="Table"]}[Data] + var dataPattern = + @"Data\s*=\s*Schema\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Table""\s*\]\s*}\s*\[\s*Data\s*\]"; + var dataMatch = Regex.Match( + mQuery, + dataPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!dataMatch.Success) + throw new FormatException("Could not find valid Data definition in M query"); + + connectionInfo.TableName = dataMatch.Groups[1].Value; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//main script + + + +//check that user has a table selected +if (Selected.Tables.Count == 0) +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox("Select one or more tables", MsgBoxStyle.Critical, "Table Required"); + return; +} + +//prompt for personal access token - required to authenticate to Databricks +string dbxPAT; +do +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + dbxPAT = MaskedInputHelper.GetMaskedInput( + "Please enter your Databricks Personal Access Token (needed to connect to the SQL Endpoint)", + "Personal Access Token" + ); + + if (string.IsNullOrEmpty(dbxPAT)) + { + return; // User cancelled + } + + if (string.IsNullOrWhiteSpace(dbxPAT)) + { + MessageBox.Show( + "Personal Access Token required", + "Personal Access Token required", + MessageBoxButtons.OK, + MessageBoxIcon.Warning + ); + } +} while (string.IsNullOrWhiteSpace(dbxPAT)); + +// toggle the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = true; + +//for each selected table, get the Databricks connection info from the partition info +foreach (var t in Selected.Tables) +{ + string mQuery = t.Partitions[t.Name].Expression; + var connectionInfo = PowerQueryMParser.ParseMQuery(mQuery); + var rels = 0; + // Access individual components + string serverHostname = connectionInfo.ServerHostname; + string httpPath = connectionInfo.HttpPath; + string databaseName = connectionInfo.DatabaseName; + string schemaName = connectionInfo.SchemaName; + string tableName = connectionInfo.TableName; + + //use this query to see if any primary/foreign key relationships have been defined in Unity Catalog + var query = + @" + SELECT + fk.table_catalog AS fk_table_catalog, + fk.table_schema AS fk_table_schema, + fk.table_name AS fk_table_name, + fk.column_name AS fk_column, + pk.table_catalog AS pk_table_catalog, + pk. table_schema AS pk_table_schema, + pk.table_name AS pk_table_name, + pk.column_name AS pk_column + FROM + " + + databaseName + + @".information_schema.key_column_usage fk + INNER JOIN " + + databaseName + + @".information_schema.referential_constraints rc + ON fk.constraint_catalog = rc.constraint_catalog + AND fk.constraint_schema = rc.constraint_schema + AND fk.constraint_name = rc.constraint_name + INNER JOIN " + + databaseName + + @".information_schema.key_column_usage pk + ON rc.unique_constraint_catalog = pk.constraint_catalog + AND rc.unique_constraint_schema = pk.constraint_schema + AND rc.unique_constraint_name = pk.constraint_name + WHERE + fk.table_schema = '" + + schemaName + + @"' + AND fk.table_name = '" + + tableName + + @"' + AND fk.position_in_unique_constraint = 1 +"; + + //set DBX connection string + var odbcConnStr = + @"DSN=Simba Spark;driver=C:\Program Files\Simba Spark ODBC Driver;host=" + + serverHostname + + ";port=443;httppath=" + + httpPath + + ";thrifttransport=2;ssl=1;authmech=3;uid=token;pwd=" + + dbxPAT; + + //test connection + OdbcConnection conn = new OdbcConnection(odbcConnStr); + try + { + conn.Open(); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Please check the following prequisites: + +- you must have the Simba Spark ODBC Driver installed +(download from https://www.databricks.com/spark/odbc-drivers-download) + +- the ODBC driver must be installed in the path C:\Program Files\Simba Spark ODBC Driver + +- check that the Databricks server name " + + serverHostname + + @" is correct + +- check that the Databricks SQL endpoint / HTTP Path " + + httpPath + + @" is correct + +- check that you have used a valid Personal Access Token", + MsgBoxStyle.Critical, + "Connection Error" + ); + return; + } + + //send query + OdbcDataAdapter da = new OdbcDataAdapter(query, conn); + var dbxRelationships = new sysData.DataTable(); + + try + { + da.Fill(dbxRelationships); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + + Either: + - the table " + + schemaName + + "." + + tableName + + " does not exist" + + @" + + - you do not have permissions to query this table + + - the connection timed out. Please check that the SQL Endpoint cluster is running", + MsgBoxStyle.Critical, + "Connection Error" + ); + return; + } + + //for every table in the model, see if it matches a row in the Databricks query + foreach (var dt in Model.Tables) + { + //get the source table information + string sourceMQuery = dt.Partitions[dt.Name].Expression; + var sourceConnectionInfo = PowerQueryMParser.ParseMQuery(sourceMQuery); + // Access individual components + string sourceSchemaName = sourceConnectionInfo.SchemaName; + string sourceTableName = sourceConnectionInfo.TableName; + + foreach (sysData.DataRow row in dbxRelationships.Rows) + { + if ( + string.Equals( + sourceSchemaName + "." + sourceTableName, + row["pk_table_schema"].ToString() + "." + row["pk_table_name"].ToString(), + StringComparison.OrdinalIgnoreCase + ) + ) + { + var dimTable = dt; + foreach (var dc in dt.DataColumns) + if (dc.SourceColumn == row["pk_column"].ToString()) + { + var dimColumn = dc; + + foreach (var fc in t.DataColumns) + if (fc.SourceColumn == row["fk_column"].ToString()) + { + var factColumn = fc; + + // Check whether a relationship already exists between the two columns: + if ( + !Model.Relationships.Any(r => + r.FromColumn == factColumn && r.ToColumn == dimColumn + ) + ) + { + // If relationships already exists between the two tables, new relationships will be created as inactive: + var makeInactive = Model.Relationships.Any(r => + r.FromTable == t && r.ToTable == dimTable + ); + + // Add the new relationship: + var rel = Model.AddRelationship(); + rel.FromColumn = factColumn; + rel.ToColumn = dimColumn; + factColumn.IsHidden = true; + factColumn.IsAvailableInMDX = false; + dimColumn.IsKey = true; + if (dc.DataType != DataType.DateTime) + { + dimColumn.IsHidden = true; + dimColumn.IsAvailableInMDX = false; + } + + if (makeInactive) + rel.IsActive = false; + rels = rels + 1; + } + } + } + } + } + } + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + rels + " relationships added to " + t.Name, + MsgBoxStyle.Information, + "Add relationships" + ); + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = true; + conn.Close(); +} +``` + +### Erklärung + +Das Skript verwendet WinForms, um einen persönlichen Databricks-Zugriffstoken zur Authentifizierung bei Databricks anzufordern. Für jede ausgewählte Tabelle ruft das Skript die Databricks-Verbindungszeichenfolgeninformationen sowie den Schema- und Tabellennamen aus der M-Abfrage in der Partition der ausgewählten Tabelle ab. Mit dem Spark ODBC-Treiber sendet es dann eine SQL-Abfrage an Databricks, die die information_schema-Tabellen abfragt, um alle in Unity Catalog definierten Fremdschlüsselbeziehungen für die Tabelle zu finden. Für jede in der SQL-Abfrage zurückgegebene Zeile sucht das Skript nach übereinstimmenden Tabellen- und Spaltennamen im Modell und erstellt ggf. eine neue Beziehung, falls noch keine vorhanden ist. Bei Rollenabspiel-Dimensionen, bei denen dieselbe Tabelle mehrere Fremdschlüssel mit Bezug zu einer einzelnen Tabelle haben könnte, wird die erste erkannte Beziehung die aktive sein, und alle nachfolgenden Beziehungen werden als inaktiv erstellt. Das Skript blendet auch Primär- und Fremdschlüssel aus und setzt IsAvailableInMDX auf false (mit Ausnahme von DateTime-Primärschlüsseln). Primärschlüssel werden auch als IsKey = TRUE im semantischen Modell gekennzeichnet. Nach der Ausführung des Skripts für jede ausgewählte Tabelle wird ein Dialogfeld angezeigt, in dem die Anzahl der neu erstellten Beziehungen angegeben ist. + +## Beispielausgabe + +
    + Table relationships before running the script
    Abbildung 1: Vor der Ausführung des Skripts sind keine Beziehungen definiert.
    +
    + +
    + Prompt for Databricks personal access token
    Abbildung 2: Das Skript fordert Sie auf, einen persönlichen Databricks-Zugriffstoken einzugeben, damit es sich bei Databricks authentifizieren kann.
    +
    + +
    + The number of new relationships created
    Abbildung 3: Nach der Ausführung des Skripts für jede ausgewählte Tabelle wird die Anzahl der neu erstellten Beziehungen angezeigt.
    +
    + +
    + Table relationships after running the script
    Abbildung 4: Tabellenbeziehungen nach Ausführung des Skripts.
    +
    + diff --git a/content/localization/de/script-create-date-table_de.md b/content/localization/de/script-create-date-table_de.md new file mode 100644 index 00000000..5adf0519 --- /dev/null +++ b/content/localization/de/script-create-date-table_de.md @@ -0,0 +1,541 @@ +--- +uid: script-create-date-table +title: Create Date Table +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create a Date Table + +## Script Purpose + +You can use this script to create a new, organized and configured date table based on 1-2 selected date columns in the model. +The first selected column should be the earliest date and the second selected column should be the latest date. Both should be selected before running the script / macro. + +This script will create the below objects in the model: + +1. A measure `[RefDate]`, which will have the latest date in the model scope; i.e. last day of sales. You can adjust this measure manually and re-process the date table to re-generate it based on a different reference date (i.e. if you want to change it to TODAY() or add a filter) +2. The `'Date'` table - The table can be configured in a separate DAX Query window and copied back into the script if you have other requirements. + - All columns will be organized in display folders + - Column properties like Sort By will be set + +This script does not yet create model relationships between the created date table and date fields in your model. + +## Script + +### Create Date Table + +```csharp +// To use this C# Script: +// +// 1. Run the script +// 2. Select the column that has the earliest date +// 3. Select the column that has the latest date + +// List of all DateTime columns in the model +var _dateColumns = Model.AllColumns.Where(c => c.DataType == DataType.DateTime ).ToList(); + +// Select the column with the earliest date in the model +try +{ + string _EarliestDate = + SelectColumn( + _dateColumns, + null, + "Select the Column with the Earliest Date:" + ).DaxObjectFullName; + + try + { + // Select the column with the latest date in the model + string _LatestDate = + SelectColumn( + _dateColumns, + null, + "Select the Column with the Latest Date:" + ).DaxObjectFullName; + + + // Create measure for reference date + var _RefDateMeasure = _dateColumns[0].Table.AddMeasure( + "RefDate", + "CALCULATE ( MAX ( " + _LatestDate + " ), REMOVEFILTERS ( ) )" + ); + + + // Formatted date table DAX + // Based on date table from https://www.sqlbi.com/topics/date-table/ + // To adjust, copy everything after the @" into a DAX query window & replace + + var _DateDaxExpression = @"-- Reference date for the latest date in the report + -- Until when the business wants to see data in reports + VAR _Refdate_Measure = [RefDate] + VAR _Today = TODAY ( ) + + -- Replace with ""Today"" if [RefDate] evaluates blank + VAR _Refdate = IF ( ISBLANK ( _Refdate_Measure ), _Today, _Refdate_Measure ) + VAR _RefYear = YEAR ( _Refdate ) + VAR _RefQuarter = _RefYear * 100 + QUARTER(_Refdate) + VAR _RefMonth = _RefYear * 100 + MONTH(_Refdate) + VAR _RefWeek_EU = _RefYear * 100 + WEEKNUM(_Refdate, 2) + + -- Earliest date in the model scope + VAR _EarliestDate = DATE ( YEAR ( MIN ( " + _EarliestDate + @" ) ) - 2, 1, 1 ) + VAR _EarliestDate_Safe = MIN ( _EarliestDate, DATE ( YEAR ( _Today ) + 1, 1, 1 ) ) + + -- Latest date in the model scope + VAR _LatestDate_Safe = DATE ( YEAR ( _Refdate ) + 2, 12, 1 ) + + ------------------------------------------ + -- Base calendar table + VAR _Base_Calendar = CALENDAR ( _EarliestDate_Safe, _LatestDate_Safe ) + ------------------------------------------ + + + + ------------------------------------------ + VAR _IntermediateResult = + ADDCOLUMNS ( _Base_Calendar, + + ------------------------------------------ + ""Calendar Year Number (ie 2021)"", --| + YEAR ([Date]), --|-- Year + --| + ""Calendar Year (ie 2021)"", --| + FORMAT ([Date], ""YYYY""), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Quarter Year (ie Q1 2021)"", --| + ""Q"" & --|-- Quarter + CONVERT(QUARTER([Date]), STRING) & --| + "" "" & --| + CONVERT(YEAR([Date]), STRING), --| + --| + ""Calendar Year Quarter (ie 202101)"", --| + YEAR([Date]) * 100 + QUARTER([Date]), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Month Year (ie Jan 21)"", --| + FORMAT ( [Date], ""MMM YY"" ), --|-- Month + --| + ""Calendar Year Month (ie 202101)"", --| + YEAR([Date]) * 100 + MONTH([Date]), --| + --| + ""Calendar Month (ie Jan)"", --| + FORMAT ( [Date], ""MMM"" ), --| + --| + ""Calendar Month # (ie 1)"", --| + MONTH ( [Date] ), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Week EU (ie WK25)"", --| + ""WK"" & WEEKNUM( [Date], 2 ), --|-- Week + --| + ""Calendar Week Number EU (ie 25)"", --| + WEEKNUM( [Date], 2 ), --| + --| + ""Calendar Year Week Number EU (ie 202125)"", --| + YEAR ( [Date] ) * 100 --| + + --| + WEEKNUM( [Date], 2 ), --| + --| + ""Calendar Week US (ie WK25)"", --| + ""WK"" & WEEKNUM( [Date], 1 ), --| + --| + ""Calendar Week Number US (ie 25)"", --| + WEEKNUM( [Date], 1 ), --| + --| + ""Calendar Year Week Number US (ie 202125)"", --| + YEAR ( [Date] ) * 100 --| + + --| + WEEKNUM( [Date], 1 ), --| + --| + ""Calendar Week ISO (ie WK25)"", --| + ""WK"" & WEEKNUM( [Date], 21 ), --| + --| + ""Calendar Week Number ISO (ie 25)"", --| + WEEKNUM( [Date], 21 ), --| + --| + ""Calendar Year Week Number ISO (ie 202125)"",--| + YEAR ( [Date] ) * 100 --| + + --| + WEEKNUM( [Date], 21 ), --| + ------------------------------------------ + + ------------------------------------------ + ""Weekday Short (i.e. Mon)"", --| + FORMAT ( [Date], ""DDD"" ), --|-- Weekday + --| + ""Weekday Name (i.e. Monday)"", --| + FORMAT ( [Date], ""DDDD"" ), --| + --| + ""Weekday Number EU (i.e. 1)"", --| + WEEKDAY ( [Date], 2 ), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Month Day (i.e. Jan 05)"", --| + FORMAT ( [Date], ""MMM DD"" ), --|-- Day + --| + ""Calendar Month Day (i.e. 0105)"", --| + MONTH([Date]) * 100 --| + + --| + DAY([Date]), --| + --| + ""YYYYMMDD"", --| + YEAR ( [Date] ) * 10000 --| + + --| + MONTH ( [Date] ) * 100 --| + + --| + DAY ( [Date] ), --| + ------------------------------------------ + + + ------------------------------------------ + ""IsDateInScope"", --| + [Date] <= _Refdate --|-- Boolean + && --| + YEAR([Date]) > YEAR(_EarliestDate), --| + --| + ""IsBeforeThisMonth"", --| + [Date] <= EOMONTH ( _Refdate, -1 ), --| + --| + ""IsLastMonth"", --| + [Date] <= EOMONTH ( _Refdate, 0 ) --| + && --| + [Date] > EOMONTH ( _Refdate, -1 ), --| + --| + ""IsYTD"", --| + MONTH([Date]) --| + <= --| + MONTH(EOMONTH ( _Refdate, 0 )), --| + --| + ""IsActualToday"", --| + [Date] = _Today, --| + --| + ""IsRefDate"", --| + [Date] = _Refdate, --| + --| + ""IsHoliday"", --| + MONTH([Date]) * 100 --| + + --| + DAY([Date]) --| + IN {0101, 0501, 1111, 1225}, --| + --| + ""IsWeekday"", --| + WEEKDAY([Date], 2) --| + IN {1, 2, 3, 4, 5}) --| + ------------------------------------------ + + VAR _Result = + + -------------------------------------------- + ADDCOLUMNS ( --| + _IntermediateResult, --|-- Boolean #2 + ""IsThisYear"", --| + [Calendar Year Number (ie 2021)] --| + = _RefYear, --| + --| + ""IsThisMonth"", --| + [Calendar Year Month (ie 202101)] --| + = _RefMonth, --| + --| + ""IsThisQuarter"", --| + [Calendar Year Quarter (ie 202101)] --| + = _RefQuarter, --| + --| + ""IsThisWeek"", --| + [Calendar Year Week Number EU (ie 202125)]--| + = _RefWeek_EU --| + ) --| + -------------------------------------------- + + RETURN + _Result"; + + // Create date table + var _date = Model.AddCalculatedTable( + "Date", + _DateDaxExpression + ); + + //-------------------------------------------------------------------------------------------// + + // Sort by... + + // Sort Weekdays + (_date.Columns["Weekday Name (i.e. Monday)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Weekday Number EU (i.e. 1)"] as CalculatedTableColumn); + (_date.Columns["Weekday Short (i.e. Mon)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Weekday Number EU (i.e. 1)"] as CalculatedTableColumn); + + // Sort Weeks + (_date.Columns["Calendar Week EU (ie WK25)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Week Number EU (ie 25)"] as CalculatedTableColumn); + (_date.Columns["Calendar Week ISO (ie WK25)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Week Number ISO (ie 25)"] as CalculatedTableColumn); + (_date.Columns["Calendar Week US (ie WK25)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Week Number US (ie 25)"] as CalculatedTableColumn); + + // Sort Months + (_date.Columns["Calendar Month (ie Jan)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Month # (ie 1)"] as CalculatedTableColumn); + (_date.Columns["Calendar Month Day (i.e. Jan 05)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Month Day (i.e. 0105)"] as CalculatedTableColumn); + (_date.Columns["Calendar Month Year (ie Jan 21)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Year Month (ie 202101)"] as CalculatedTableColumn); + + // Sort Quarters + (_date.Columns["Calendar Quarter Year (ie Q1 2021)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Year Quarter (ie 202101)"] as CalculatedTableColumn); + + // Sort Years + (_date.Columns["Calendar Year (ie 2021)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Year Number (ie 2021)"] as CalculatedTableColumn); + + + //-------------------------------------------------------------------------------------------// + + + // For all the columns in the date table: + foreach (var c in _date.Columns ) + { + c.DisplayFolder = "7. Boolean Fields"; + c.IsHidden = true; + + // Organize the date table into folders + if ( ( c.DataType == DataType.DateTime & c.Name.Contains("Date") ) ) + { + c.DisplayFolder = "6. Calendar Date"; + c.IsHidden = false; + c.IsKey = true; + } + + if ( c.Name == "YYMMDDDD" ) + { + c.DisplayFolder = "6. Calendar Date"; + c.IsHidden = true; + } + + if ( c.Name.Contains("Year") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "1. Year"; + c.IsHidden = false; + } + + if ( c.Name.Contains("Week") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "4. Week"; + c.IsHidden = true; + } + + if ( c.Name.Contains("day") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "5. Weekday / Workday\\Weekday"; + c.IsHidden = false; + } + + if ( c.Name.Contains("Month") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "3. Month"; + c.IsHidden = false; + } + + if ( c.Name.Contains("Quarter") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "2. Quarter"; + c.IsHidden = false; + } + + } + + // Mark as date table + _date.DataCategory = "Time"; + + + //-------------------------------------------------------------------------------------------// + + + // Create Workdays MTD, QTD, YTD logic + // (separate into measures & calc. column to be easier to maintain) + // + // Add calculated columns for Workdays MTD, QTD, YTD + + string _WorkdaysDax = @"VAR _Holidays = + CALCULATETABLE ( + DISTINCT ('Date'[Date]), + 'Date'[IsHoliday] <> TRUE + ) + VAR _WeekdayName = CALCULATE ( SELECTEDVALUE ( 'Date'[Weekday Short (i.e. Mon)] ) ) + VAR _WeekendDays = SWITCH ( + _WeekdayName, + ""Sat"", 2, + ""Sun"", 3, + 0 + ) + VAR _WorkdaysMTD = + CALCULATE ( + NETWORKDAYS ( + CALCULATE ( + MIN ('Date'[Date]), + ALLEXCEPT ('Date', 'Date'[Calendar Month Year (ie Jan 21)]) + ), + CALCULATE (MAX ('Date'[Date]) - _WeekendDays), + 1, + _Holidays + ) + ) + + 1 + RETURN + IF (_WorkdaysMTD < 1, 1, _WorkdaysMTD)"; + + _date.AddCalculatedColumn( + "Workdays MTD", + _WorkdaysDax, + "5. Weekday / Workday\\Workdays" + ); + + _date.AddCalculatedColumn( + "Workdays QTD", + _WorkdaysDax.Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Quarter Year (ie Q1 2021)]"), + "5. Weekday / Workday\\Workdays" + ); + + _date.AddCalculatedColumn( + "Workdays YTD", + _WorkdaysDax.Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Year (ie 2021)]"), + "5. Weekday / Workday\\Workdays" + ); + + + //-------------------------------------------------------------------------------------------// + + + // Create measures for showing how many workdays passed + _WorkdaysDax = @"CALCULATE( + MAX( 'Date'[Workdays MTD] ), + 'Date'[IsDateInScope] = TRUE + )"; + + _date.AddMeasure( + "# Workdays MTD", + _WorkdaysDax, + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays QTD", + _WorkdaysDax.Replace("MTD", "QTD"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays YTD", + _WorkdaysDax.Replace("MTD", "YTD"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + // Create measures showing how many workdays are in the selected period + + _WorkdaysDax = @"IF ( + HASONEVALUE ('Date'[Calendar Month Year (ie Jan 21)]), + CALCULATE ( + MAX ('Date'[Workdays MTD]), + VALUES ('Date'[Calendar Month Year (ie Jan 21)]) + ) + )"; + + _date.AddMeasure( + "# Workdays in Selected Month", + _WorkdaysDax, + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays in Selected Quarter", + _WorkdaysDax.Replace("MTD", "QTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Quarter Year (ie Q1 2021)]"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays in Selected Year", + _WorkdaysDax.Replace("MTD", "YTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Year (ie 2021)]"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + + // Create measures showing how many workdays passed as a % + + _WorkdaysDax = @"IF ( + HASONEVALUE ('Date'[Calendar Month Year (ie Jan 21)]), + MROUND ( + DIVIDE ([# Workdays MTD], [# Workdays in Selected Month]), + 0.01 + ) + )"; + + _date.AddMeasure( + "% Workdays MTD", + _WorkdaysDax, + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "% Workdays QTD", + _WorkdaysDax.Replace("MTD", "QTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Quarter Year (ie Q1 2021)]").Replace("Month", "Quarter"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "% Workdays YTD", + _WorkdaysDax.Replace("MTD", "YTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Year (ie 2021)]").Replace("Month", "Year"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + + //-------------------------------------------------------------------------------------------// + + + // Move the reference measure to the newly created 'Date' table. + _RefDateMeasure.Delete(); + _RefDateMeasure = Model.Tables["Date"].AddMeasure( + "RefDate", + "CALCULATE ( MAX ( " + _LatestDate + " ), REMOVEFILTERS ( ) )", + "0. Measures" + ); + + _RefDateMeasure.IsHidden = true; + + Info ( "Created a new, organized 'Date' table based on the template in the C# Script.\nThe Earliest Date is taken from " + _EarliestDate + "\nThe Latest Date is taken from " + _LatestDate ); + + } + catch + { + Error( "Latest column not selected! Ending script without making changes." ); + } +} +catch +{ + Error( "Earliest column not selected! Ending script without making changes." ); +} + +``` + +### Explanation + +This snippet takes the selected columns and creates a measure to highlight the maximum date for reporting. It then creates a formatted Date table with common columns used for reporting. The date table only contains calendar dates and not fiscal periods. + +## Example Output + +
    + Select Earliest date dialog
    Figure 1: When running the script, a dialog will appear which prompts you to select a DateTime column from the model that contains the earliest date for which you want to configure your Date table.
    +
    + +
    + Select Latest date dialog
    Figure 2: Once selecting the earliest date, a dialog will appear which prompts you to select a DateTime column from the model that contains the latest date for which you want to configure your Date table.
    +
    + +
    + Confirmation of the date table being created
    Figure 3: A confirmation dialog will inform you that the Date table was configured successfully based on the two selected dates.
    +
    + +
    + Resulting Date Table Template
    Figure 4: An example of an organized, configured date table created with a single click using this script.
    +
    diff --git a/content/localization/de/script-create-field-parameter_de.md b/content/localization/de/script-create-field-parameter_de.md new file mode 100644 index 00000000..0dc9ebdf --- /dev/null +++ b/content/localization/de/script-create-field-parameter_de.md @@ -0,0 +1,72 @@ +--- +uid: create-field-parameter +title: Create Field Parameter +author: Daniel Otykier +updated: 2024-01-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create Field Parameters in + +## Script Purpose + +If you want to create field parameters in a Power BI model using Tabular Editor or in a Direct Lake model. + +> [!TIP] +> Want to see the script in action, check out this [Guy in a Cube video](https://www.youtube.com/watch?v=Cg6zRhwF-Ro) where Patrick LeBlanc explains how to use it step by step. + +## Script + +### Select Columns or Measures to create a field parameter table + +```csharp +// Before running the script, select the measures or columns that you +// would like to use as field parameters (hold down CTRL to select multiple +// objects). Also, you may change the name of the field parameter table +// below. NOTE: If used against Power BI Desktop, you must enable unsupported +// features under File > Preferences (TE2) or Tools > Preferences (TE3). +var name = "Parameter"; + +if(Selected.Columns.Count == 0 && Selected.Measures.Count == 0) throw new Exception("No columns or measures selected!"); + +// Construct the DAX for the calculated table based on the current selection: +var objects = Selected.Columns.Any() ? Selected.Columns.Cast() : Selected.Measures; +var dax = "{\n " + string.Join(",\n ", objects.Select((c,i) => string.Format("(\"{0}\", NAMEOF('{1}'[{0}]), {2})", c.Name, c.Table.Name, i))) + "\n}"; + +// Add the calculated table to the model: +var table = Model.AddCalculatedTable(name, dax); + +// In TE2 columns are not created automatically from a DAX expression, so +// we will have to add them manually: +var te2 = table.Columns.Count == 0; +var nameColumn = te2 ? table.AddCalculatedTableColumn(name, "[Value1]") : table.Columns["Value1"] as CalculatedTableColumn; +var fieldColumn = te2 ? table.AddCalculatedTableColumn(name + " Fields", "[Value2]") : table.Columns["Value2"] as CalculatedTableColumn; +var orderColumn = te2 ? table.AddCalculatedTableColumn(name + " Order", "[Value3]") : table.Columns["Value3"] as CalculatedTableColumn; + +if(!te2) { + // Rename the columns that were added automatically in TE3: + nameColumn.IsNameInferred = false; + nameColumn.Name = name; + fieldColumn.IsNameInferred = false; + fieldColumn.Name = name + " Fields"; + orderColumn.IsNameInferred = false; + orderColumn.Name = name + " Order"; +} +// Set remaining properties for field parameters to work +// See: https://twitter.com/markbdi/status/1526558841172893696 +nameColumn.SortByColumn = orderColumn; +nameColumn.GroupByColumns.Add(fieldColumn); +fieldColumn.SortByColumn = orderColumn; +fieldColumn.SetExtendedProperty("ParameterMetadata", "{\"version\":3,\"kind\":2}", ExtendedPropertyType.Json); +fieldColumn.IsHidden = true; +orderColumn.IsHidden = true; +``` + +### Explanation + +Before running the script the user has to select the measures or columns in the TOM Explorer they wish to have in their field parameter table. +The selected objects are then inserted into a calculated table which is then configured as a field parameter table automatically. + diff --git a/content/localization/de/script-create-m-parameter_de.md b/content/localization/de/script-create-m-parameter_de.md new file mode 100644 index 00000000..0f0643b8 --- /dev/null +++ b/content/localization/de/script-create-m-parameter_de.md @@ -0,0 +1,56 @@ +--- +uid: script-create-m-parameter +title: Create M Parameter +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create M Partition + +## Script Purpose + +If you want to create a new dynamic M Parameter to use in Power Query queries (M Partitions or Shared Expressions). + +## Script + +### Create a new M Partition + +```csharp +// This script creates a new M parameter in the 'Shared Expressions' of a model. +// +// Create a new shared expression called "New Parameter" +Model.AddExpression( + "New Parameter", + @" +""Parameter Text"" meta +[ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type text +]" +); + +// Provides an output informing how to configure and use the parameter +Info ( + "Created a new Shared Expression called 'New Parameter', which is an M Parameter template." + + "\n------------------------------------------------------\n" + + "To configure:" + + "\n------------------------------------------------------\n " + + "1. Replace the text 'New Parameter' with the desired parameter value\n " + + "2. Set the data type appropriately\n " + + "3. Replace any values found in the M partitions with the parameter reference." ); +``` + +### Explanation + +This snippet creates a new M parameter in 'Shared Expressions' which you can refer to from within your M Partitions Power Query. + +## Example Output + +
    + An example of the Info box that appears to inform the user that the M Parameter was successfully created, and recommending next steps to configure / use it in the M Partitions.
    Figure 1: An example of the Info box that appears to inform the user that the M Parameter was successfully created, and recommending next steps to configure / use it in the M Partitions.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-create-measure-table_de.md b/content/localization/de/script-create-measure-table_de.md new file mode 100644 index 00000000..23ac09a5 --- /dev/null +++ b/content/localization/de/script-create-measure-table_de.md @@ -0,0 +1,26 @@ +--- +uid: script-create-measure-table +title: Create Measure Table +author: Morten Lønskov +updated: 2023-11-29 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create Measure Table + +## Script Purpose + +The scripts creates a hidden measure table containing one hidden column + +## Script + +### Create Measure Table + +```csharp +// Create a calculated table with a single column which is hidden: +var table = Model.AddCalculatedTable("Model Measures", "{0}"); +table.Columns[0].IsHidden = true; +``` \ No newline at end of file diff --git a/content/localization/de/script-create-sum-measures-from-columns_de.md b/content/localization/de/script-create-sum-measures-from-columns_de.md new file mode 100644 index 00000000..d8e4b79e --- /dev/null +++ b/content/localization/de/script-create-sum-measures-from-columns_de.md @@ -0,0 +1,51 @@ +--- +uid: script-create-sum-measures-from-columns +title: Create SUM Measure from Column +author: Morten Lønskov +updated: 2023-02-22 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create SUM Measure from Column + +## Script Purpose + +If you want to quickly create a number of measures that SUM over the columns that you select then this script with do it for you. + +## Script + +### Create measures from columns + +```csharp +// Creates a SUM measure for every currently selected column and hide the column. +foreach(var c in Selected.Columns) +{ + var newMeasure = c.Table.AddMeasure( + "Sum of " + c.Name, // Name + "SUM(" + c.DaxObjectFullName + ")", // DAX expression + c.DisplayFolder // Display Folder + ); + + // Set the format string on the new measure: + newMeasure.FormatString = "0.00"; + + // Provide some documentation: + newMeasure.Description = "This measure is the sum of column " + c.DaxObjectFullName; + + // Hide the base column: + c.IsHidden = true; +} +``` + +### Explanation + +This snippet uses the `
    .AddMeasure(, , )` function to create a new measure on the table. We use the `DaxObjectFullName` property to get the fully qualified name of the column for use in the DAX expression: `'TableName'[ColumnName]`. + +## Example Output + +
    + Example of measures created with the script
    Figure 1: An example of measures created with this script.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-create-table-groups_de.md b/content/localization/de/script-create-table-groups_de.md new file mode 100644 index 00000000..9e8527c2 --- /dev/null +++ b/content/localization/de/script-create-table-groups_de.md @@ -0,0 +1,60 @@ +--- +uid: script-create-table-groups +title: Create Table Groups +author: Morten Lønskov +updated: 2023-11-29 +applies_to: + versions: + - version: 3.x +--- + +# Create Table Groups + +## Script Purpose + +This script creates default table groups within Tabular Editor 3. + +## Script + +### Script Title + +```csharp +// Loop through all tables: +foreach(var table in Model.Tables) +{ + if (table is CalculationGroupTable) + { + table.TableGroup = "Calculation Groups"; + } + else if (!table.UsedInRelationships.Any() && table.Measures.Any(m => m.IsVisible)) + { + // Tables containing visible measures, but no relationships to other tables + table.TableGroup = "Measure Groups"; + } + else if (table.UsedInRelationships.All(r => r.FromTable == table) && table.UsedInRelationships.Any()) + { + // Tables exclusively on the "many" side of relationships: + table.TableGroup = "Facts"; + } + else if (!table.UsedInRelationships.Any() && table is CalculatedTable && !table.Measures.Any()) + { + // Tables without any relationships, that are Calculated Tables and do not have measures: + table.TableGroup = "Parameter Tables"; + } + else if (table.UsedInRelationships.Any(r => r.ToTable == table)) + { + // Tables on the "one" side of relationships: + table.TableGroup = "Dimensions"; + } + else + { + // All other tables: + table.TableGroup = "Misc"; + } +} +``` + +### Explanation + +The scripts loops through all tables in the model assigning a table group according to specific properties. + diff --git a/content/localization/de/script-databricks-semantic-model-set-up_de.md b/content/localization/de/script-databricks-semantic-model-set-up_de.md new file mode 100644 index 00000000..a18ae557 --- /dev/null +++ b/content/localization/de/script-databricks-semantic-model-set-up_de.md @@ -0,0 +1,100 @@ +--- +uid: script-databricks-semantic-model-set-up +title: Databricks Semantic Model Set-Up +author: Johnny Winter +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Databricks Semantic Model Set-Up + +## Script Purpose + +This script was created as part of the Tabular Editor x Databricks series. In Databricks Unity Catalog it is not possible to use capital letters in table names. A common way to make tables names more readable without using capital letters is to adopt snake_case. Also, whilst column names can contain spaces, it is often advised against as these can be cumbersome to work with, meaning data engineers most often use snake_case, camelCase or PascalCase. + +However, we want users of our Semantic Model to see business friendly names in our model. + +The following script will loop through all tables in the model and make sure friendly, Proper Case formatting is applied. + +Whilst doing this, it will also apply some best practice recommendations, setting default summarisation for all columns to none and also setting format strings for DateTime type fields (this script is set up to use format ‘yyyy-mm-dd' but you can alter the script at line 61 if you prefer)

    + +> [!NOTE] +> This script is not strictly for use with only Databricks – use it with any model you like, regardless of data source, but it has been built with some of the limitations of Databricks in mind.

    + +## Script + +### Databricks Semantic Model Set-Up + +```csharp +/* + * Title: Databricks Semantic Model Set-Up + * Author: Johnny Winter, greyskullanalytics.com + * + * This script, when executed, will loop through all tables and columns in the model and rename with friendly names. + * Names in snake_case, camelCase or PascalCase will all be converted to Proper Case. + * No table selections are required as all tables in the model will be processed, simply run the script. + * Whilst looping though columns it also sets default summarization to none and sets a format string for all DateTime type fields + * (currently it sets format 'yyyy-mm-dd' but you can change this on line 61 if you wish). + * + */ +using System; +using System.Globalization; + +//create script as class so it can be reused +class p { + + public static void ConvertCase(dynamic obj) + { + TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo; + //replace underscores with a space + var oldName = obj.Name.Replace("_", " "); + var newName = new System.Text.StringBuilder(); + for(int i = 0; i < oldName.Length; i++) { + // First letter should always be capitalized: + if(i == 0) newName.Append(Char.ToUpper(oldName[i])); + + // A sequence of two uppercase letters followed by a lowercase letter should have a space inserted + // after the first letter: + else if(i + 2 < oldName.Length && char.IsLower(oldName[i + 2]) && char.IsUpper(oldName[i + 1]) && char.IsUpper(oldName[i])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + + // All other sequences of a lowercase letter followed by an uppercase letter, should have a space + // inserted after the first letter: + else if(i + 1 < oldName.Length && char.IsLower(oldName[i]) && char.IsUpper(oldName[i+1])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + else + { + newName.Append(oldName[i]); + } + } + //apply Proper Case where this has not already been taken care of above + obj.Name = textInfo.ToTitleCase(newName.ToString()); + } +} + +foreach(var t in Model.Tables) { +//convert table names + p.ConvertCase(t); +//convert column names + foreach(var c in t.Columns) { + p.ConvertCase(c); + c.SummarizeBy = AggregateFunction.None; + if (c.DataType == DataType.DateTime) + {c.FormatString = "yyyy-mm-dd";} + } +} +``` + +### Explanation + +This script, when executed, will loop through all tables and columns in the model and rename with friendly names. Names in snake_case, camelCase or PascalCase will all be converted to Proper Case. No table selections are required as all tables in the model will be processed, simply run the script. Whilst looping though columns it also sets default summarization to none and sets a format string for all DateTime type fields. + diff --git a/content/localization/de/script-display-unique-column-values_de.md b/content/localization/de/script-display-unique-column-values_de.md new file mode 100644 index 00000000..48c6e743 --- /dev/null +++ b/content/localization/de/script-display-unique-column-values_de.md @@ -0,0 +1,39 @@ +--- +uid: script-display-unique-column-values +title: Distinct Column Values +author: Morten Lønskov +updated: 2024-05-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Distinct Column Values + +## Script Purpose + +Display the distinct values in a column for quick data profiling and access. +Save as a Macro on the column level to have it quickly available. + +

    + +## Script + +### Script Title + +```csharp +// Construct the DAX expression to get all distinct column values, from the selected column: +var dax = string.Format("ALL({0})", Selected.Column.DaxObjectFullName); + +// Evaluate the DAX expression against the connected model: +var result = EvaluateDax(dax); + +// Output the DataTable containing the result of the DAX expression: +Output(result); +``` + +### Explanation + +The script uses the ALL() DAX function against the selected columns and display the result in an output dialog box. + diff --git a/content/localization/de/script-edit-hidden-partitions_de.md b/content/localization/de/script-edit-hidden-partitions_de.md new file mode 100644 index 00000000..b50faf85 --- /dev/null +++ b/content/localization/de/script-edit-hidden-partitions_de.md @@ -0,0 +1,28 @@ +--- +uid: script-edit-hidden-partitions +title: Edit Hidden Partitions +author: Morten Lønskov +updated: 2023-02-21 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Edit Hidden Partitions + +## Script Purpose + +Calculated Tables, Calculation Groups and Field Parameters do not have partitions displayed in Tabular Editor. This is on purpose as these should/can not generally be edited. The partition's properties can however still be accessed and edited with below script snippet. + +## Script + +```csharp +Selected.Table.Partitions[0].Output(); +``` + +### Example Output + +
    + An example of the output box that appears, letting the user view and edit hidden partitions in the model.
    Figure 1: An example of the output box that appears, letting the user view and edit hidden partitions in the model.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-find-replace-selected-measures_de.md b/content/localization/de/script-find-replace-selected-measures_de.md new file mode 100644 index 00000000..3037f97b --- /dev/null +++ b/content/localization/de/script-find-replace-selected-measures_de.md @@ -0,0 +1,167 @@ +--- +uid: script-find-replace +title: Find/Replace Measure DAX +author: Kurt Buhler +updated: 2023-03-01 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Find & Replace Substring in Measures + +## Script Purpose + +Will find & replace a substring in the model's measures DAX expression. I.e. if you want to replace `'Customers'[Key Account]` with `'Products'[Type]` in many measures. +An input box lets the user enter the text to find and a subsequent input lets the user define the replacement text. + +## Script + +```csharp +#r "System.Drawing" + +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Replace Selected.Measures with Model.AllMeasures to scan all measures +var _measures = Model.AllMeasures; + // Optional: Replace _m.Expression with _m.Name to find & replace in names. + +// Initialize _find and _replace string variables +string _find = "Find"; +string _replace = "Replace"; + +// WinForms prompt to get Find & Replace input +using (Form prompt = new Form()) +{ + Font formFont = new Font("Segoe UI", 11); + + // Prompt config + prompt.AutoSize = true; + prompt.MinimumSize = new Size(350, 120); + prompt.Text = "Find and Replace Dialog"; + prompt.StartPosition = FormStartPosition.CenterScreen; + + // Set the AutoScaleMode property to Dpi + prompt.AutoScaleMode = AutoScaleMode.Dpi; + + // Find: label + Label findLabel = new Label() { Text = "Find:" }; + findLabel.Location = new Point(20, 20); + findLabel.Width = 80; + findLabel.Font = formFont; + + // Textbox for inputing the substring text + TextBox findBox = new TextBox(); + findBox.Width = 200; + findBox.Location = new Point(findLabel.Location.X + findLabel.Width + 20, findLabel.Location.Y - 4); + findBox.SelectedText = "Find this Text"; + findBox.Font = formFont; + + // Replace: label + Label replaceLabel = new Label() { Left = 20, Top = 60, Text = "Replace:" }; + replaceLabel.Width = 80; + replaceLabel.Font = formFont; + + // Textbox for inputting the substring text + TextBox replaceBox = new TextBox() { Left = replaceLabel.Right + 20, Top = replaceLabel.Location.Y - 4, Width = findBox.Width }; + replaceBox.SelectedText = "Replace with this Text"; + replaceBox.Font = formFont; + + // OK Button + Button okButton = new Button() { Text = "OK", Left = 20, Width = 75, Top = replaceBox.Location.Y + replaceBox.Height + 20 }; + okButton.MinimumSize = new Size(75, 25); + okButton.AutoSize = true; + okButton.Font = formFont; + + // Cancel Button + Button cancelButton = new Button() { Text = "Cancel", Left = okButton.Location.X + okButton.Width + 10, Top = okButton.Location.Y }; + cancelButton.MinimumSize = new Size(75, 25); + cancelButton.AutoSize = true; + cancelButton.Font = formFont; + + // Button actions + okButton.Click += (sender, e) => { _find = findBox.Text; _replace = replaceBox.Text; prompt.DialogResult = DialogResult.OK; }; + cancelButton.Click += (sender, e) => { prompt.DialogResult = DialogResult.Cancel; }; + + prompt.AcceptButton = okButton; + prompt.CancelButton = cancelButton; + + prompt.Controls.Add(findLabel); + prompt.Controls.Add(findBox); + prompt.Controls.Add(replaceLabel); + prompt.Controls.Add(replaceBox); + prompt.Controls.Add(okButton); + prompt.Controls.Add(cancelButton); + + // The user clicked OK, so perform the find-and-replace logic + if (prompt.ShowDialog() == DialogResult.OK) + { + + int _occurrences = 0; + var _ReplacedList = new List(); + + foreach (var _m in _measures) + { + if (_m.Expression != _m.Expression.Replace(_find, _replace)) + { + try + { + // Count number of occurrences of _find substring in the string + string _pattern = Regex.Escape(_find); + _occurrences = Regex.Matches(_m.Expression, _pattern).Count; + } + catch + { + // If it's not found there are 0 occurrences + _occurrences = 0; + } + + // Perform the Find/Replace + _m.Expression = _m.Expression.Replace(_find, _replace); + _ReplacedList.Add(_m.DaxObjectName); + } + } + + // Create a list of all the measures replaced + string _Replaced = _ReplacedList.Count > 0 + ? "\n\nMeasures with Replacements:\n • " + string.Join("\n • ", _ReplacedList) + : ""; + + // Return a success Info box pop-up + Info( + "Replaced " + + _occurrences + + " occurrences of '" + + _find + + "' with '" + + _replace + + "'" + + _Replaced); + } + else + { + Error("Find/Replace cancelled!"); + } +} + +``` + +### Explanation + +This snippet will create a pop-up dialogue with WinForms that will let you input a substring to search the selected measures and replace with a different substring. A success box dialogue will inform you that the find/replace was successful. + +### Example Output + +
    + An example of the pop-up Find/Replace dialog that allows the user to enter the sub-strings to be searched / replaced.
    Figure 1: An example of the pop-up Find/Replace dialog that allows the user to enter the sub-strings to be searched / replaced.
    +
    + +
    + An example of the info box dialog which informs the user that the Find/Replace was successful, and how many / which measures were affected by the script.
    Figure 2: An example of the info box dialog which informs the user that the Find/Replace was successful, and how many / which measures were affected by the script.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-format-numeric-measures_de.md b/content/localization/de/script-format-numeric-measures_de.md new file mode 100644 index 00000000..377eec8a --- /dev/null +++ b/content/localization/de/script-format-numeric-measures_de.md @@ -0,0 +1,48 @@ +--- +uid: script-format-numeric-measures +title: Format Numeric Measures +author: Morten Lønskov +updated: 2023-11-29 +applies_to: + versions: + - version: 3.x +--- + +# Format Numeric Measures + +## Script Purpose + +Allows you to quickly set default format strings on the measures selected. + +

    + +> [!NOTE] +> The script uses certain naming standards so you might wish to adjust it to suit yours.

    + +## Script + +### Script Title + +```csharp +// This script is meant to format all measures with a default formatstring +foreach (var ms in Selected.Measures) { +//Don't set format string on hidden measures + if (ms.IsHidden) continue; +// If the format string is empty continue. + if (!string.IsNullOrWhiteSpace(ms.FormatString)) continue; +//If the data type is int set a whole number format string + if (ms.DataType == DataType.Int64) ms.FormatString = "#,##0"; +//If the datatype is double or decimal + if (ms.DataType == DataType.Double || ms.DataType == DataType.Decimal) { + //and the name contains # or QTY then set the format string to a whole number + if (ms.Name.Contains("#") + || ms.Name.IndexOf("QTY", StringComparison.OrdinalIgnoreCase) >= 0) ms.FormatString = "#,##0"; + //otherwise set it a decimal format string. + else ms.FormatString = "#,##0.00"; + } +} +``` + +### Explanation + +The script takes each of the selected measures and loops through them to set a default format string according to various conditions. \ No newline at end of file diff --git a/content/localization/de/script-format-power-query_de.md b/content/localization/de/script-format-power-query_de.md new file mode 100644 index 00000000..d06da782 --- /dev/null +++ b/content/localization/de/script-format-power-query_de.md @@ -0,0 +1,124 @@ +--- +uid: script-format-power-query +title: Format Power Query +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 3.x +--- + +# Format Power Query + +## Script Purpose + +If you want to format complex Power Query to make it more readable and easy to change.

    + +> [!NOTE] +> This script will send your Power Query M Code to the Power Query Formatter API. +> Please ensure responsible use and compliance when using this script to format your Power Query code.

    + +## Script + +### Format Power Query + +```csharp +// This script formats the Power Query (M Code) of any selected M Partition (not Shared Expression or Source Expression). +// It will send an HTTPS POST request of the expression to the Power Query Formatter API and replace the code with the result. +// +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +// URL of the powerqueryformatter.com API +string powerqueryformatterAPI = "https://m-formatter.azurewebsites.net/api/v2"; + +// HttpClient method to initiate the API call POST method for the URL +HttpClient client = new HttpClient(); +HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, powerqueryformatterAPI); + +// Get the M Expression of the selected partition +string partitionExpression = Selected.Partition.Expression; + +// Serialize the request body as a JSON object +var requestBody = JsonConvert.SerializeObject( + new { + code = partitionExpression, + resultType = "text", + lineWidth = 40, + alignLineCommentsToPosition = true, + includeComments = true + }); + +// Set the "Content-Type" header of the request to "application/json" and the encoding to UTF-8 +var content = new StringContent(requestBody, Encoding.UTF8, "application/json"); +content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + +// Retrieve the response +var response = client.PostAsync(powerqueryformatterAPI, content).Result; + +// If the response is successful +if (response.IsSuccessStatusCode) +{ + // Get the result of the response + var result = response.Content.ReadAsStringAsync().Result; + + // Parse the response JSON object from the string + JObject data = JObject.Parse(result.ToString()); + + // Get the formatted Power Query response + string formattedPowerQuery = (string)data["result"]; + + /////////////////////////////////////////////////////////////////////// + // OPTIONAL MANUAL FORMATTING + // Manually add a new line and comment to each step + var replace = new Dictionary + { + { " //", "\n\n//" }, + { "\n #", "\n\n // Step\n #" }, + { "\n Source", "\n\n // Data Source\n Source" }, + { "\n Dataflow", "\n\n // Dataflow Connection Info\n Dataflow" }, + {"\n Data =", "\n\n // Step\n Data ="}, + {"\n Navigation =", "\n\n // Step\n Navigation ="}, + {"in\n\n // Step\n #", "in\n #"}, + {"\nin", "\n\n// Result\nin"} + }; + + // Replace the first string in the dictionary with the second + var manuallyformattedPowerQuery = replace.Aggregate( + formattedPowerQuery, + (before, after) => before.Replace(after.Key, after.Value)); + + // Replace the auto-formatted code with the manually formatted version + formattedPowerQuery = manuallyformattedPowerQuery; + //////////////////////////////////////////////////////////////////////// + + // Replace the unformatted M expression with the formatted expression + Selected.Partition.Expression = formattedPowerQuery; + + // Pop-up to inform of completion + Info("Formatted " + Selected.Partition.Name); +} + +// Otherwise return an error message +else +{ +Info( + "API call unsuccessful." + + "\nCheck that you are selecting a partition with a valid M Expression." + ); +} +``` + +### Explanation + +This snippet creates an HTTP POST request of the Power Query in the M Partition and sends it to the [Power Query Formatter](https://www.powerqueryformatter.com/). +Some manual formatting is done to make the code further readable. + +## Example Output + +
    + Format Power Query example
    Figure 1: An illustration of the script formatting Power Query code.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-helper-methods_de.md b/content/localization/de/script-helper-methods_de.md new file mode 100644 index 00000000..9001ed95 --- /dev/null +++ b/content/localization/de/script-helper-methods_de.md @@ -0,0 +1,51 @@ +--- +uid: script-helper-methods +title: C# Script Helper Methods +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + + + +# C# Script Helper Methods + +When writing C# scripts in Tabular Editor, a number of global methods (i.e. methods that can be called without prefixing a class or object name) are available. + +The full list of these can be found in the [API documentation](xref:TabularEditor.Shared.Scripting.ScriptHost#methods). + +Below is a summary of these methods. Click on a method name to browse the API documentation for that method. + +|
    Method
    | Purpose | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`CallDaxFormatter`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CallDaxFormatter_System_Nullable_System_Boolean__System_Nullable_System_Boolean__) | Format all DAX expressions on objects currently flagged for formatting. | +| [`CollectVertiPaqAnalyzerStats`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CollectVertiPaqAnalyzerStats) | Collects VertiPaq Analyzer statistics for the currently loaded model. | +| [`ConvertDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ConvertDax_System_String_System_Boolean_) | Changes the character used for decimals and list separators in a DAX expression. | +| [`CustomAction`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CustomAction_System_String_) (+2) | Invoke the custom action (aka. macro) with the given name. | +| [`Error`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Error_System_String_) | Displays an error message in a popup dialog. When the script is running in the CLI, an error message is written to the console. | +| [`EvaluateDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_EvaluateDax_System_String_) | Evaluates the specified DAX expression against the connected database and returns a data table or scalar value containing the result. | +| [`ExecuteCommand`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExecuteCommand_System_String_System_Boolean_) | Executes the specified TMSL or XMLA command. | +| [`ExecuteDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExecuteDax_System_String_) | Executes the specified DAX query. | +| [`ExecuteReader`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExecuteReader_System_String_) | Executes the specified DAX query. | +| [`ExportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExportProperties_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_ITabularNamedObject__System_String_) | Export properties of the specified set of objects to a TSV (tab-separated) string.
    Use [`ImportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ImportProperties_System_String_) to import properties from a TSV string. | +| [`FormatDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_FormatDax_TabularEditor_TOMWrapper_IDaxDependantObject_) (+2) | Flags the specified object for formatting after script execution or the next time [`CallDaxFormatter`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CallDaxFormatter_System_Nullable_System_Boolean__System_Nullable_System_Boolean__) is called. | +| [`GetObjectPath`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_GetObjectPath_TabularEditor_TOMWrapper_TabularObject_) | Returns a string representation that uniquely identifies the specified object within the model. | +| [`ImportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ImportProperties_System_String_) | Applies properties to objects based on a string representation (tab separated format) of property values to assign,
    such as obtained by [`ExportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExportProperties_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_ITabularNamedObject__System_String_) . | +| [`Info`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Info_System_String_) | Displays an informational message in a popup dialog. When the script is running in the CLI, an information message is written to the console. | +| [`LineBreakFirstChar`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_LineBreakFirstChar_System_String_System_Boolean_) | Ensures that a DAX expression starts with a line break. | +| [`Model`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Model) | The currently loaded [`Model`](xref:TabularEditor.TOMWrapper.Model) . | +| [`Output`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Output_System_Object_) | Displays detailed information about the specified object or collection of objects in a popup dialog. When executed through the UI, the user has an option to ignore additional popups. When the script is running in the CLI, the information is written to the console. | +| [`ReadFile`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ReadFile_System_String_) | Read the specified file as text | +| [`ResolveObjectPath`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ResolveObjectPath_System_String_) | Resolves an object within the model based on a string such as the one obtained by [`GetObjectPath`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_GetObjectPath_TabularEditor_TOMWrapper_TabularObject_) . | +| [`SaveFile`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SaveFile_System_String_System_String_System_Text_Encoding_) | Saves the specified text to a file | +| [`SelectColumn`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectColumn_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_Column__TabularEditor_TOMWrapper_Column_System_String_) (+1) | Displays a dialog that allows the user to select a column from the specified list of columns. | +| [`Selected`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Selected) | An object that represents the current selection in the TOM Explorer. | +| [`SelectMeasure`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectMeasure_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_Measure__TabularEditor_TOMWrapper_Measure_System_String_) (+3) | Displays a dialog that allows the user to select a measure from the specified list of measures. | +| [`SelectObject`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectObject__1_System_Collections_Generic_IEnumerable___0____0_System_String_) | Displays a dialog that allows the user to select a model object from a list of objects. | +| [`SelectObjects`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectObjects__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_IEnumerable___0__System_String_) | Displays a dialog that allows the user to select one or more model objects from a list of objects. | +| [`SelectTable`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectTable_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_Table__TabularEditor_TOMWrapper_Table_System_String_) (+2) | Displays a dialog that allows the user to select a table from the specified list of tables. | +| [`SuspendWaitForm`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SuspendWaitForm_System_Action_) (+1) | Hides the "Please wait" spinner while performing the specified action. Useful if the action displays custom dialogs / UI to the end user. | +| [`WaitFormVisible`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_WaitFormVisible) | Toggle the "Please wait" spinner on/off. Useful if you want to display custom dialogs / UI to the end user. | +| [`Warning`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Warning_System_String_) | Displays a warning message in a popup dialog. When the script is running in the CLI, a warning message is written to the console. | diff --git a/content/localization/de/script-implement-incremental-refresh_de.md b/content/localization/de/script-implement-incremental-refresh_de.md new file mode 100644 index 00000000..a4415aea --- /dev/null +++ b/content/localization/de/script-implement-incremental-refresh_de.md @@ -0,0 +1,493 @@ +--- +uid: script-implement-incremental-refresh +title: Setup Incremental Refresh +author: Kurt Buhler +updated: 2023-03-01 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Configure Incremental Refresh + +## Script Purpose + +If you want to configure Incremental Refresh for an import table based on a specific date field. +This script will work for `datetime`, `date`, or `integer` date columns for which you want to configure incremental refresh. + +To use the script, select the date column in the table for which you want to configure incremental refresh, then run the script. The script will only run if you don't already have a #"RangeStart" and #"RangeEnd" parameter, and the selected table doesn't already have a Refresh Policy configured. + +> [!NOTE] +> This script will automatically modify the M partition of the table to add the filter step. +> Be sure to check that this was done correctly. +> +> If you have many steps you must be sure to move this step to a point when it will fold to the data source. +> Make sure you adjust all the \`#"Step References" in Power Query + +> [!NOTE] +> This script uses user input to generate the refresh policy. +> Make sure you enter the correct values in the user input dialogue box. + +## Script + +### Implement Incremental Refresh for Selected Column + +```csharp +// This script will automatically generate an Incremental Refresh policy for a selected table +// It is generated based on the selected column +// It requires input from the user with a dialogue pop-up box. +// This script will automatically generate an Incremental Refresh policy for a selected table +// It is generated based on the selected column +// It requires input from the user with a dialogue pop-up box. +using System.Drawing; +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Initialize Variables +Table _Table = Model.Tables[0]; +string _MExpression = ""; +Column _Column = Model.AllColumns.ToList()[0]; +string _ColumnName = ""; +DataType _ColumnDataType = DataType.DateTime; + +try + { + // Select a Table for which you will configure Incremental Refresh. + // The Refresh Policy will be enabled and configured for this table. + _Table = + Model.Tables.Where( + + // Exclude tables that already have a refresh policy + t => + t.EnableRefreshPolicy != true && + + // Include only 'Table' objects + t.ObjectType == ObjectType.Table && + + // Exclude Calculated Tables + t.Columns[0].Type != ColumnType.CalculatedTableColumn && + + // Only include tables that have a column on the "From" side of the relationship + (Model.Relationships.Count() > 0 ? + t.Columns.Any(c => Model.Relationships.Any(r => r.FromColumn == c) ) : true) && + + // Exclude tables that don't have a DateTime or Integer column + ( + t.Columns.Any(c => c.DataType == DataType.DateTime) || + t.Columns.Any(c => c.DataType == DataType.Int64) + ) + ).SelectTable(null,"Select a Table for which you will configure Incremental Refresh:"); + + _MExpression = _Table.Partitions[0].Expression; + + try + { + // Select the column to apply the Refresh Policy. + // The M Expression will be modified using the name of this column. + _Column = + _Table.Columns.Where( + + // Include only DateTime or Int columns + c => + c.DataType == DataType.DateTime || + c.DataType == DataType.Int64 + + ).SelectColumn(null, "Select a DateTime or DateKey (Int) Column to apply the Refresh Policy."); + + _ColumnName = _Column.DaxObjectName; + _ColumnDataType = _Column.DataType; + + try + { // Test if 'RangeStart' exists + Model.Expressions.Contains(Model.Expressions["RangeStart"]); + Info ("RangeStart already exists!"); + } + catch + { + // Add RangeStart parameter + Model.AddExpression( + "RangeStart", + @" + #datetime(2023, 01, 01, 0, 0, 0) meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ]" + ); + + // Success message for adding 'RangeStart' + Info ( "Created 'RangeStart' M Parameter!" ); + } + + // Test if the RangeEnd parameter exists + try + { // Test if 'RangeEnd' exists + Model.Expressions.Contains(Model.Expressions["RangeEnd"]); + Info ("RangeEnd already exists!"); + } + catch + { + // Add RangeEnd parameter + Model.AddExpression( + "RangeEnd", + @" + #datetime(2023, 31, 01, 0, 0, 0) meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ]" + ); + + // Success message for adding 'RangeEnd' + Info ( "Created 'RangeEnd' M Parameter!" ); + + } + + // Incremental Refresh Configuration + // Input box config + Font _fontConfig = new Font("Segoe UI", 11); + + // Label for how long data should be stored + var storeDataLabel = new Label(); + storeDataLabel.Text = "Store data in the last:"; + storeDataLabel.Location = new Point(20, 20); + storeDataLabel.AutoSize = true; + storeDataLabel.Font = _fontConfig; + + // User input for how long data should be stored + var storeDataTextBox = new TextBox(); + storeDataTextBox.Location = new Point(storeDataLabel.Location.X + TextRenderer.MeasureText(storeDataLabel.Text, storeDataLabel.Font).Width + 20, storeDataLabel.Location.Y); + storeDataTextBox.Size = new Size(100, 20); + storeDataTextBox.Text = "3"; + storeDataTextBox.Font = _fontConfig; + + // User selection for how long data should be stored (granularity) + var storeDataComboBox = new ComboBox(); + storeDataComboBox.Location = new Point(storeDataTextBox.Location.X + storeDataTextBox.Width + 20, storeDataLabel.Location.Y); + storeDataComboBox.Size = new Size(100, 20); + storeDataComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + storeDataComboBox.Items.AddRange(new object[] { "days", "months", "quarters", "years" }); + storeDataComboBox.SelectedIndex = 3; + storeDataComboBox.Font = _fontConfig; + + // Label for how much data should be refreshed + var refreshDataLabel = new Label(); + refreshDataLabel.Text = "Refresh data in the last:"; + refreshDataLabel.Location = new Point(20, storeDataLabel.Location.Y + storeDataLabel.Height + 15); + refreshDataLabel.AutoSize = true; + refreshDataLabel.Font = _fontConfig; + + // User input for how much data should be refreshed + var refreshDataTextBox = new TextBox(); + refreshDataTextBox.Location = new Point(storeDataTextBox.Location.X, refreshDataLabel.Location.Y); + refreshDataTextBox.Size = new Size(100, 20); + refreshDataTextBox.Text = "30"; + refreshDataTextBox.Font = _fontConfig; + + // User selection for how much data should be refreshed (Period) + var refreshDataComboBox = new ComboBox(); + refreshDataComboBox.Location = new Point(storeDataComboBox.Location.X, refreshDataLabel.Location.Y); + refreshDataComboBox.Size = new Size(100, 20); + refreshDataComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + refreshDataComboBox.Items.AddRange(new object[] { "days", "months", "quarters", "years" }); + refreshDataComboBox.SelectedIndex = 0; + refreshDataComboBox.Font = _fontConfig; + + // User input to refresh full periods or not + var fullPeriodsCheckBox = new CheckBox(); + fullPeriodsCheckBox.Text = "Refresh only full periods"; + fullPeriodsCheckBox.Location = new Point(storeDataLabel.Location.X + 3, refreshDataLabel.Location.Y + refreshDataLabel.Height + 15); + fullPeriodsCheckBox.AutoSize = true; + fullPeriodsCheckBox.Font = _fontConfig; + + // Form OK button + var okButton = new Button(); + okButton.Text = "OK"; + okButton.Location = new Point(storeDataLabel.Location.X, fullPeriodsCheckBox.Location.Y + fullPeriodsCheckBox.Height + 15); + okButton.MinimumSize = new Size(80, 25); + okButton.AutoSize = true; + okButton.DialogResult = DialogResult.OK; + okButton.Font = _fontConfig; + + // Form cancel button + var cancelButton = new Button(); + cancelButton.Text = "Cancel"; + cancelButton.Location = new Point(okButton.Location.X + okButton.Width + 10, okButton.Location.Y); + cancelButton.MinimumSize = new Size(80, 25); + cancelButton.AutoSize = true; + cancelButton.DialogResult = DialogResult.Cancel; + cancelButton.Font = _fontConfig; + + // Adjust the Location of the storeDataLabel to align with the storeDataTextBox + storeDataLabel.Location = new Point(storeDataLabel.Location.X, storeDataLabel.Location.Y + 4); + refreshDataLabel.Location = new Point(refreshDataLabel.Location.X, refreshDataLabel.Location.Y + 4); + + // Form config + var form = new Form(); + form.Text = "Incremental Refresh configuration:"; + form.AutoSize = true; + form.MinimumSize = new Size(450, 0); + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + + // Open the dialogue in the center of the screen + form.StartPosition = FormStartPosition.CenterScreen; + + // Set the AutoScaleMode property to Dpi + form.AutoScaleMode = AutoScaleMode.Dpi; + + // Add controls to form specified above + form.Controls.Add(storeDataLabel); + form.Controls.Add(storeDataTextBox); + form.Controls.Add(storeDataComboBox); + form.Controls.Add(refreshDataLabel); + form.Controls.Add(refreshDataTextBox); + form.Controls.Add(refreshDataComboBox); + form.Controls.Add(fullPeriodsCheckBox); + form.Controls.Add(okButton); + form.Controls.Add(cancelButton); + + // Draw the form + var result = form.ShowDialog(); + + // Get the values of the user input if entered + if (result == DialogResult.OK) + { + // Enables the refresh policy + _Table.EnableRefreshPolicy = true; + + var storeDataValue = storeDataTextBox.Text; + var storeDataComboBoxValue = storeDataComboBox.SelectedItem.ToString(); + var refreshDataValue = refreshDataTextBox.Text; + var refreshDataComboBoxValue = refreshDataComboBox.SelectedItem.ToString(); + var fullPeriodsChecked = fullPeriodsCheckBox.Checked; + + // Display the input values in a message box + var message = string.Format( + "Store data in the last: {0} {1}" + + "\nRefresh data in the last: {2} {3}" + + "\nRefresh only full periods: {4}", + storeDataTextBox.Text, + storeDataComboBox.SelectedItem.ToString(), + refreshDataTextBox.Text, + refreshDataComboBox.SelectedItem.ToString(), + fullPeriodsCheckBox.Checked); + + Info(message); + + // Convert StoreDataGranularity to correct TOM Property + RefreshGranularityType StoreDataGranularity = RefreshGranularityType.Day; + switch (storeDataComboBox.SelectedItem.ToString()) + { + case "years": + StoreDataGranularity = RefreshGranularityType.Year; + break; + + case "quarters": + StoreDataGranularity = RefreshGranularityType.Quarter; + break; + + case "months": + StoreDataGranularity = RefreshGranularityType.Month; + break; + + case "days": + StoreDataGranularity = RefreshGranularityType.Day; + break; + + default: + Error("Bad selection for Incremental Granularity."); + break; + } + + + // Convert IncrementalGranularity to correct TOM Property + RefreshGranularityType IncrementalPeriodGranularity = RefreshGranularityType.Year; + switch (refreshDataComboBox.SelectedItem.ToString()) + { + case "years": + IncrementalPeriodGranularity = RefreshGranularityType.Year; + break; + + case "quarters": + IncrementalPeriodGranularity = RefreshGranularityType.Quarter; + break; + + case "months": + IncrementalPeriodGranularity = RefreshGranularityType.Month; + break; + + case "days": + IncrementalPeriodGranularity = RefreshGranularityType.Day; + break; + + default: + Error ( "Bad selection for Incremental Granularity." ); + break; + } + + // Convert RefreshCompletePeriods checkbox to correct TOM property + int RefreshCompletePeriods; + if ( fullPeriodsCheckBox.Checked == true ) + { + RefreshCompletePeriods = -1; + } + else + { + RefreshCompletePeriods = 0; + } + + // Set incremental window: period to be refreshed + _Table.IncrementalGranularity = IncrementalPeriodGranularity; + + // Default: 30 days - change # if you want + _Table.IncrementalPeriods = Convert.ToInt16(refreshDataTextBox.Text); + + // Only refresh complete days. Change to 0 if you don't want. + _Table.IncrementalPeriodsOffset = RefreshCompletePeriods; + + // Set rolling window: period to be archived + // Granularity = day, can change to month, quarter, year... + _Table.RollingWindowGranularity = StoreDataGranularity; + + // Keep data for 1 year. Includes 1 full year and current partial year + // i.e. if it is Nov 2023, keeps data from Jan 1, 2022. + // On Jan 1, 2024, it will drop 2022 automatically. + _Table.RollingWindowPeriods = Convert.ToInt16(storeDataTextBox.Text); + + // If the selected date column is an integer of type YYYYMMDD... + if ( _ColumnDataType == DataType.Int64 ) + { + // Add DateTimeToInt Function + var _DateTimeToInt = + Model.AddExpression( + "fxDateTimeToInt", + @"(x as datetime) => Date.Year(x) * 10000 + Date.Month(x) * 100 + Date.Day(x)" + ); + + _DateTimeToInt.SetAnnotation("PBI_ResultType", "Function"); + _DateTimeToInt.Kind = ExpressionKind.M; + + // Source expression obtained from the original M partition + _Table.SourceExpression = + + // Gets expression before final "in" keyword + _MExpression.Split("\nin")[0].TrimEnd() + + + // Adds comma and newline + ",\n" + + + // Adds step called "Incremental Refresh" for filtering + @" #""Incremental Refresh"" = Table.SelectRows( " + + + // Gets name of last step (after "in" keyword) + _MExpression.Split("\nin")[1].TrimStart() + + + // Adds 'each' keyword + @", each " + + + // Bases incremental refresh on current column name + _ColumnName + + + // Greater than or equal to RangeStart + @" >= fxDateTimeToInt ( #""RangeStart"" ) and " + + + // and + _ColumnName + + + // Less than RangeEnd + @" < fxDateTimeToInt ( #""RangeEnd"" ) )" + + + // re-add 'in' keyword + "\nin\n" + + + // Reference final step just added + @" #""Incremental Refresh"""; + } + + + // Otherwise treat it like a normal date/datetime column + else + { + // Source expression obtained from the original M partition + _Table.SourceExpression = + // Gets expression before final "in" keyword + _MExpression.Split("\nin")[0].TrimEnd() + + + // Adds comma and newline + ",\n" + + + // Adds step called "Incremental Refresh" for filtering + @" #""Incremental Refresh"" = Table.SelectRows( " + + + // Gets name of last step (after "in" keyword) + _MExpression.Split("\nin")[1].TrimStart() + + + // Adds 'each' keyword + @", each " + + + // Bases incremental refresh on current column name + _ColumnName + + + // Greater than or equal to RangeStart + @" >= Date.From ( #""RangeStart"" ) and " + + + // and + _ColumnName + + + // Less than RangeEnd + @" < Date.From ( #""RangeEnd"" ) )" + + + // re-add 'in' keyword + "\nin\n" + + + // Reference final step just added + @" #""Incremental Refresh"""; + } + + // Success message for Refresh Policy configuration + Info ( + "Successfully configured the Incremental Refresh policy.\n" + + "\nSelect the table and right-click on 'Apply Refresh Policy...'" + + "\nSelect & peform a 'Full Refresh' of all new policy partitons that are created." + ); + } + else if (result == DialogResult.Cancel) + { + // if the user clicks the Cancel button, close the form and exit the script + form.Close(); + Error ( "Cancelled configuration! Ending script without changes." ); + return; + } + } + catch + { + Error( "No valid column selected! Ending script without changes." ); + } + +} +catch +{ + Error( "No valid table selected! Ending script without changes." ); +} +``` + +### Explanation + +This snippet will configure incremental refresh in the selected table based on a selected date column. + +## Example Output + +
    + The prompt that helps you configure incremental refresh based on selected columns
    Figure 1: When running the script, you are prompted to select the Table you want to configure, and the DateTime or Int column the policy will be configured for. Then, the dialog in this image will appear to let you enter the Refresh Policy parameters.
    +
    + +
    + A confirmation dialog that acknowledges you have configured the refresh policy
    Figure 2: A confirmation dialog will inform you about the success of the Refresh Policy configuration, explaining it back to you in plain words.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-output-things_de.md b/content/localization/de/script-output-things_de.md new file mode 100644 index 00000000..52cb88c3 --- /dev/null +++ b/content/localization/de/script-output-things_de.md @@ -0,0 +1,68 @@ +--- +uid: script-output-things +title: Output Object Details in a Grid +author: Daniel Otykier +updated: 2024-12-13 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Output Object Details in a Grid + +## Script Purpose + +Another way to get an overview of objects in the model, and how they are configured, is to output them in a grid using the C# [`DataTable`](https://learn.microsoft.com/en-us/dotnet/api/system.data.datatable?view=net-8.0) class. This is a very flexible technique, as you can add only the information you are interested in, as columns of the `DataTable`. Moreover, when passing a `DataTable` to the `Output()` method, Tabular Editor will automatically display it in a grid view, which is very convenient for inspecting the data. + +## Script + +### Show measure complexity details + +```csharp +// This script displays a grid with details about each measure in the model. +using System.Data; + +var result = new DataTable(); +result.Columns.Add("Name"); +result.Columns.Add("Table"); +result.Columns.Add("Expression token count", typeof(int)); +result.Columns.Add("Expression line count", typeof(int)); +result.Columns.Add("Description line count", typeof(int)); +result.Columns.Add("Format String"); + +foreach(var m in Model.AllMeasures) +{ + var row = new object[] + { + m.DaxObjectName, // Name + m.Table.Name, // Table + m.Tokenize().Count, // Token count + m.Expression.Split(new []{'\n'}, StringSplitOptions.RemoveEmptyEntries).Length, + m.Description.Split(new []{'\n'}, StringSplitOptions.RemoveEmptyEntries).Length, + m.FormatStringExpression ?? m.FormatString + }; + result.Rows.Add(row); +} + +Output(result); +``` + +### Explanation + +This snippet first configures a `DataTable` object with the columns we want to display in the grid. We explicitly specify the `typeof(int)` for some of the columns, to ensure that sorting works correctly. We then iterate over all measures in the model, and for each measure, we create a new row in the `DataTable` with the desired information. Finally, we pass the `DataTable` to the `Output()` method, which will display the grid. + +The columns displayed are: + +- **Name**: The name of the measure. +- **Table**: The name of the table the measure belongs to. +- **Expression token count**: The number of tokens in the measure expression. This is a rough measure of DAX complexity. +- **Expression line count**: The number of lines in the measure expression, not counting empty lines. +- **Description line count**: The number of lines in the measure description, not counting empty lines. +- **Format String**: The measure's format string expresssion or format string, if any. + +## Example Output + +
    + Example of the dialog pop-up that displays the grid.
    Figure 1: Example of the dialog pop-up that displays the grid. Both Tabular Editor 2 and Tabular Editor 3 will let you sort the grid columns as well as copy the output to the clipboard. However, Tabular Editor 3 also has additional features for grouping, filtering, and searching within the grid.
    +
    \ No newline at end of file diff --git a/content/localization/de/script-remove-measures-with-error_de.md b/content/localization/de/script-remove-measures-with-error_de.md new file mode 100644 index 00000000..8fe9c842 --- /dev/null +++ b/content/localization/de/script-remove-measures-with-error_de.md @@ -0,0 +1,126 @@ +--- +uid: script-remove-measures-with-error +title: View/Remove Measures with Errors +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 3.x +--- + +# View/Remove Measures with Errors + +## Script Purpose + +If you want to see all the measures that have errors and have the option to delete them from the model, saving a back-up .tsv of the deleted measures to a selected directory (in case you want to re-add them, later). + +## Script + +### View & Remove Measures with Errors + +```csharp +// This script scans the model and shows all measures with errors, giving the option to remove them. +// +// .GetCachedSemantics(...) method is only available in TE3 +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Get all the measures that have errors +var measuresWithError = Model.AllMeasures.Where(m => m.GetCachedSemantics(ExpressionProperty.Expression).HasError).ToList(); +//Prior to Tabular Editor 3.12.0 the GetSemantics method must be used. +//var measuresWithError = Model.AllMeasures.Where(m => m.GetSemantics(ExpressionProperty.Expression).HasError).ToList(); + +// If no measures with errors, end script with error. +if ( measuresWithError.Count == 0 ) +{ +Info ( "No measures with errors! 👍" ); +} + +// Handle erroneous measures +else +{ + +// View the list of measures with an error +measuresWithError.Output(); + +// From the list, you can select 1 or more measures to delete +var _ToDelete = SelectObjects(measuresWithError, measuresWithError, "Select measures to delete.\nYou will be able to export a back-up, later."); + + // Delete the selected measures + try + { + foreach ( var _m in _ToDelete ) + { + _m.Delete(); + } + + Info ( + "Deleted " + + Convert.ToString(_ToDelete.Count()) + + " measures with errors." + ); + + // Create an instance of the FolderBrowserDialog class + FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); + + // Set the title of the dialog box + folderBrowserDialog.Description = "Select a directory to output a backup of the deleted measures."; + + // Set the root folder of the dialog box + folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer; + + // Show the dialog box and get the result + DialogResult result = folderBrowserDialog.ShowDialog(); + + // Check if the user clicked the OK button and get the selected path + if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(folderBrowserDialog.SelectedPath)) + { + // Get the output path as a string + string _outputPath = folderBrowserDialog.SelectedPath; + + // Get the properties of the deleted measures + var _backup = ExportProperties( _ToDelete ); + + // Save a backup of the deleted measures + SaveFile( _outputPath + "/DeletedMeasures-" + Model.Name + DateTime.Today.ToString("-yyyy-MM-dd") + ".tsv", _backup); + + Info ( + "Exported a backup of " + + Convert.ToString(_ToDelete.Count()) + + " Measures to " + + _outputPath + ); + } + } + catch + // Display an info box if no measure was selected + { + Info ( "No measure selected." ); + } +} + +``` + +### Explanation + +This snippet gets all the measures that have errors according to the Tabular Editor Semantic Analysis. It then will display them in an output box where you can manually browse them or make changes. Thereafter, measures can be selected for removal. The removed measures can be saved as a back-up .tsv file in case you want to import them, later. + +## Example Output + +
    + An output dialog that lets the user view and edit any measures with errors in Tabular Editor
    Figure 1: An output dialog allows you to view and also edit any measures that currently have 'errors' according to the analysis services semantic analysis.
    +
    + +
    + A selection dialog that lets the user select measures to delete
    Figure 2: Measures with errors can be selected for deletion.
    +
    + +
    + A confirmation dialog that informs the user the deletion was successful
    Figure 3: A confirmation dialog will inform you deletion of the measures was successful.
    +
    + +
    + A dialog that lets the user select a directory to save a .tsv back-up of the deleted measure metadata
    Figure 4: An optional .tsv backup of the measure properties and definitions can be saved to a local directory, in case they need to be re-added, later.
    +
    diff --git a/content/localization/de/script-show-data-source-dependencies_de.md b/content/localization/de/script-show-data-source-dependencies_de.md new file mode 100644 index 00000000..41a4491b --- /dev/null +++ b/content/localization/de/script-show-data-source-dependencies_de.md @@ -0,0 +1,59 @@ +--- +uid: script-show-data-source-dependencies +title: Show Data Source Dependencies +author: David Bojsen +updated: 2023-09-12 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Show Data Source Dependencies + +## Script Purpose + +The script outputs the tables that reference the selected explicit (legacy) data source. This will make it easier to determine where a selected data source is used. + +## Script + +### Show Data Source Dependencies + +```csharp +//The script outputs the tables that reference the selected explicit (legacy) data source. +if (Model.DataSources.Count == 0) +{ + Info("This model doesn't contain any data sources, it is either empty or using implicit datasources"); + return; +} +// Checks that a data source is selected +DataSource selectedDatasource = null; + +if (Selected.DataSources.Count == 1) + selectedDatasource = Selected.DataSource; +else + selectedDatasource = SelectObject(Model.DataSources, null, "Select which datasource to see dependencies for"); + +// Legacy sources +var legacyTables = Model.Tables.Where(t => t.Source == selectedDatasource.Name).ToList(); + +// M sources +var mTables = Model.Tables.Where(t => t.Partitions.Any(p => p.Expression.Contains($"= #\"{selectedDatasource.Name}\","))).ToList(); + +// join arrays +var allTables = legacyTables.Union(mTables).OrderBy(t => t.Name); + +// Present result +var tableString = string.Join("\r\n", allTables.Select(t => t.Name)); +Info($"Datasource {selectedDatasource.Name} is referenced from the following tables:\r\n" + tableString); +``` + +### Explanation + +This snippet takes the selected data source and goes through the model to collect the partitions where that data source is used. + +## Example Output + +
    + Example of the dialog pop-up that informs the user which tables use the selected data source
    Figure 1: Example of the dialog pop-up that informs the user which tables use the selected data source.
    +
    \ No newline at end of file diff --git a/content/localization/de/security-privacy_de.md b/content/localization/de/security-privacy_de.md new file mode 100644 index 00000000..c62d5f4d --- /dev/null +++ b/content/localization/de/security-privacy_de.md @@ -0,0 +1,86 @@ +--- +uid: security-privacy +title: Security overview +author: Daniel Otykier +updated: 2024-10-30 +--- + +# Tabular Editor 3 Security and Privacy + +This document describes the security and privacy considerations of Tabular Editor 3 and its use. In the following, the phrase "Tabular Editor" can mean both the commercial tool Tabular Editor 3, as well as the open-source tool Tabular Editor 2.X. Whenever something considers only one of the tools, we will use their explicit names "Tabular Editor 3" or "Tabular Editor 2.X". + +## Microsoft advice on third-party tools such as Tabular Editor + +Microsoft supports the use of community third-party tools as communicated here: [Community and third-party tools for developing enterprise-level Power BI and Analysis Services models](https://powerbi.microsoft.com/en-us/blog/community-tools-for-enterprise-powerbi-and-analysisservices) + +Microsoft's Power BI implementation planning documentation specifically includes Tabular Editor in advanced data modeling scenarios and enterprise development: [Power BI usage scenarios: Advanced data model management](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-usage-scenario-advanced-data-model-management#tabular-editor) + +## Trust Center + +At Tabular Editor, we are committed to transparency and strong security practices. Visit our [Trust Center](https://trust.tabulareditor.com/) to find details about our SOC 2 audit report, key policy documents, license terms, and our approach to infrastructure and organizational security. You’ll also find information about our sub-processors and how we work to keep your data safe. + +## Metadata and Data Privacy + +Tabular Editor is primarily an offline tool, meaning that all data and metadata reside locally in the client machine on which Tabular Editor is installed, and all user interactions are performed locally as well. An Internet connection is not required to run and use Tabular Editor. + +That being said, there are scenarios in which Tabular Editor connects to remote services for various purposes. These are described in the following: + +### Analysis Services XMLA Protocol + +All communication with Analysis Services instances or Power BI Premium workspaces happens through the use of the [Microsoft Analysis Management Objects (AMO)](https://docs.microsoft.com/en-us/analysis-services/amo/developing-with-analysis-management-objects-amo?view=asallproducts-allversions) client libraries, or more specifically, the [Tabular Object Model (TOM) extension for AMO](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions). These client libraries are provided by Microsoft for redistribution in 3rd party applications such as Tabular Editor. For licensing details, please refer to the [AMO EULA](https://go.microsoft.com/fwlink/?linkid=852989). + +When Tabular Editor connects to an instance of Analysis Services (local network or cloud) or a Power BI Premium workspace (cloud), this connection is performed through the client libraries mentioned above. By design, the AMO library handles the authentication and authorization of the user. Only users with administrative privileges on the Analysis Services instance or Power BI Premium workspace, are allowed to connect. This is no different than when using Microsoft tools such as SQL Server Management Studio or SQL Server Data Tools (which use the same client libraries for connectivity). + +### Tabular Object Model metadata + +Once the AMO/TOM client library establishes connection, Tabular Editor will request the full Tabular Object Model (TOM) metadata for the specific Analysis Services database or Power BI dataset that the user wants to connect to. The AMO/TOM client library then serves this metadata to the client application (Tabular Editor) in a programmatic approach, allowing the application to apply metadata changes, such as renaming an object, adding a description, modifying a DAX expression, etc. In addition, the AMO/TOM client library provides methods for serializing the TOM metadata into a JSON-based format. Tabular Editor uses this technique to allow users to save the model metadata as a local JSON file, for purposes of version control of the data model structure. **Note: The JSON file produced this way contains no actual data records. The file contains only model metadata, that is, information about the structure of the model in terms of tables, columns, measures, DAX expressions, etc.** While model metadata is generally not considered confidential information, it is the responsibility of the user of Tabular Editor to handle any file produced this way with the required confidentiality (i.e. not sharing the file with 3rd parties, etc.). + +**Tabular Editor does not collect, publish, share, transfer or otherwise make public any model metadata obtained through the AMO/TOM client library unless the user specifically initiates an action to do so** (for example by saving the model metadata JSON file to a shared network location, or deploying the model metadata to another instance of Analysis Services or Power BI workspace). + +### Model data content + +In the following, "model data" refers to the actual data records stored within the Analysis Services database or Power BI dataset. Depending on the source database or dataset, it is very likely that the model data is confidential. + +Because of the requirement for a user to have administrative privileges on the instance of Analysis Services or Power BI workspace that they are connecting to, the user will, by definition, also have access to all data content of the Analysis Services database or Power BI dataset. Tabular Editor only allows retrieval of data through the AMO client library mentioned above. Tabular Editor 3 provides features for browsing and querying model data. Regardless of which technique is used to access the data **Tabular Editor only stores retrieved data in local memory. Tabular Editor does not collect, publish, share, transfer or otherwise make public any model data obtained through the tool**. If a user chooses to copy or export query results obtained through Tabular Editor, it is their responsibility to treat the copied or exported data according to the confidentiality of the data. This is no different than a user connecting to the Analysis Services database or Power BI dataset using client tools such as Excel or Power BI, in which case they will also have the option to copy query results. + +### Web requests + +Tabular Editor may perform requests to online resources (web URLs) only in the following cases: + +- **License activation\*.** When Tabular Editor 3 is first launched, and at periodic intervals thereafter, the tool may perform a request to our licensing service. This request contains encrypted information about the license key entered by the user, the e-mail address of the user (if provided), the local machine name and a one-way encoded hash identifying the current installation. No other data is transmitted in this request. The purpose of this request, is to activate and validate the license key used by the installation, enforce trial limitations, as well as allowing the user to manage their installations of Tabular Editor 3 through our licensing service. +- **Upgrade checks\*.** Each time Tabular Editor 3 is launched, it may perform a request to our application service, in order to determine if a newer version of Tabular Editor 3 is available. This request does not contain any data. +- **Usage telemetry\*.** By default, Tabular Editor 3 collects and transmits anonymous usage data as users interact with the tool. This data includes information about which UI objects a user interacts with and the timing of each. It also contains high-level information about the Tabular data model being edited through the tool. This information only relates to high-level properties like compatibility level and mode, number of tables, type of server (Analysis Services vs. Power BI vs. Power BI Desktop), etc. **No personally identifyable data is collected this way**, neither do we collect any information about names of objects or DAX expressions in the Tabular Object Model itself. A user may opt out of sending telemetry data to us at any point. +- **Error reports\*.** When an unexpected error occurs, we transmit the stack trace and (anonymized) error message, along with an optional description provided by the user. If a user opts out of sending telemetry data, error reports will also not be sent. +- **Using the DAX formatter.** (Tabular Editor 2.x only) A DAX expression may be formatted by clicking a button in Tabular Editor. In this case, the DAX expression (and nothing else) is sent to the www.daxformatter.com webservice. The first time a user clicks this button, an explicit warning message is shown, asking them to confirm their intent. Tabular Editor 3 does not perform web requests when formatting DAX code. +- **DAX Optimizer**. If a user has a [Tabular Tools account](https://tabulartools.com) with a [DAX Optimizer](https://daxoptimizer.com) subscription, they will be able to browse their DAX Optimizer workspace, view issues and suggestions, and upload new VPAX files directly from within Tabular Editor 3. VPAX files contains model metadata and statistics, but no actual model _data_. The DAX Optimizer Integration feature in Tabular Editor 3 causes various requests to one or more of the below endpoints (depending on authentication type and region specified when the Tabular Tools account was created).
    + For more information, please consult the [DAX Optimizer documentation](https://docs.daxoptimizer.com/legal/data-processing).
    + Endpoints used: + - https://account.tabulartools.com + - https://licensing.api.daxoptimizer.com/api + - https://australiaeast.api.daxoptimizer.com/api + - https://eastus.api.daxoptimizer.com/api + - https://westeurope.api.daxoptimizer.com/api +- **Importing Best Practice Rules.** Tabular Editor has a feature that allows a user to specify an URL from which to retrieve a list of Best Practice rules in a JSON based format. This type of request only downloads the JSON data from the URL - no data is transmitted to the URL. +- **Using C# scripts.** Tabular Editor allows users to write and execute code written in C#, for purposes of automation. Such a script may potentially connect to online resources, using C# language features and the .NET runtime. The user is always responsible for ensuring that executed code does not cause any unintended sharing of data. Tabular Editor ApS cannot be held liable for any damages, losses or leaks caused by the use of the C# scripting feature in general. Tabular Editor will never execute C# scripts without the explicit action of the user. + +\***Any information we obtain through the license activation service, the usage telemetry or the error reports, is kept confidential. We will not share, publish or distribute the data collected in any way, shape or form.** + +**Firewall allowlist / acceptlist** +To allow traffic to the above mentioned web requests, you'll have to whitelist: + +- License activation / upgrade checks: **https://api.tabulareditor.com** +- Usage telemetry / Error reports: **https://\*.in.applicationinsights.azure.com** +- DAX Formatter (Tabular Editor 2.x only): **https://www.daxformatter.com** +- Import Best Practice Rules / C# Scripts: Depends on the context +- DAX Optimizer: Endpoints listed above. + +> [!NOTE] +> A system administrator may enforce certain [policies](xref:policies), which can be used to disable some or all of the features shown on the list above. + +## Application Security + +Tabular Editor does not require any elevated privileges on the Windows machine in which it is installed, neither does it access any restricted resources on the machine. One exception from this rule, is if using the Tabular Editor installer file (.msi), in which case the executable and support files required by the tool, are by default copied to the `Program Files` folder, which typically requires elevated permission. Both the Tabular Editor binary files as well as the installer file, have been signed with a code signing certificate issued to Kapacity A/S, which is your guarantee that the code has not been tampered with by any 3rd party. + +When the application is executing, all access to external resources are performed through the AMO/TOM client library or the web requests mentioned above. + +The C# script feature allows Tabular Editor to execute arbitrary C# code within the .NET runtime. Such code is only compiled and executed on the explicit request of the user. C# scripts may also be saved as "macros", which makes it easier for the user to manage and execute multiple different scripts. The code is stored to the users own `%localappdata%` folder, ensuring that only they or a local machine administrator, can access the scripts. The user is always responsible for ensuring that executed code does not cause any unintended sideeffects. Under no circumstance can Tabular Editor ApS be held liable for any damages, losses or leaks caused by the use of the C# scripting or custom actions/macros features. diff --git a/content/localization/de/semantic-model-types_de.md b/content/localization/de/semantic-model-types_de.md new file mode 100644 index 00000000..d9059226 --- /dev/null +++ b/content/localization/de/semantic-model-types_de.md @@ -0,0 +1,71 @@ +--- +uid: semantic-model-types +title: Power BI Semantic model Types +author: Morten Lønskov +updated: 2025-06-19 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Semantic Model Types + +Tabular Editor can work with several different model types. Below is an overview of which model types work with Tabular Editor and the capabilities that can be used with each model type. + +|Model Type|Import|Direct Query|Direct Lake on OneLake|Direct Lake on SQL|.pbix|.pbip| +\|---|---|---|---|---| +|Connect in Tabular Editor|✔️|✔️|✔️|✔️|✔️| +|Create new model|✔️|✔️|✔️|✔️|✔️|✔️| +|Write Measures|✔️|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Tables|✔️|✔️|✔️[1](#DirectLake)|✔️[1](#DirectLake)|✔️|✔️| +|Create & Edit Partitions|✔️|✔️|✔️[1](#DirectLake)|✔️[1](#DirectLake)|✔️|✔️| +|Create & Edit Columns|✔️|✔️|✔️[1](#DirectLake)|✔️[1](#DirectLake)|✔️|✔️| +|Create & Edit Calculated Tables|✔️|✔️|✔️[2](#DirectLakeCalculated)|✔️|✔️|✔️| +|Create & Edit Calculated Columns|✔️|✔️|✔️[2](#DirectLakeCalculated)|✔️|✔️|✔️| +|Create & Edit Calculation Groups|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Relationships|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Roles|✔️|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Perspectives|✔️|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Translations|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Best Practice Analyzer|✔️|✔️|✔️|✔️|✔️| +|Edit All TOM properties|✔️|✔️|✔️|✔️|✔️|✔️| +|Create Diagrams[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Preview Data[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Pivot Grids[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use DAX Queries[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use DAX Debugger[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Vertipac Analyzer[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Process Model and Tables[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Delete Objects|✔️|✔️|✔️|✔️| + +**Legend:** + +- ✔️: Supported +- ❌: Unsupported + +1 - The table partition must be an Entity Partition to work correctly and Direct Lake models can only have one partition. 2 - Calculated Tables and Columns cannot refer to Direct Lake on OneLake tables or columns. + +3 - Tabular Editor 3 features only. Operations performed through the XMLA endpoint requires a Business or Enterprise license. [More information](xref:editions). + +> [!NOTE] +> The June 2025 Release of Power BI Desktop all modeling limitations for third party tools where lifted. Prior to that various modeling operations where not supported. See [Power BI Desktop Limitations](xref:desktop-limitations) + +> [!TIP] +> For further details on restrictions on Direct Lake models refer to Microsoft's [Direct Lake documentation](https://learn.microsoft.com/en-us/fabric/fundamentals/direct-lake-overview) + +## Unsupported Semantic Model types + +The following semantic model types are unsupported, as they don't support XMLA write operations. + +- Reports based on a live connection to an Azure Analysis Services or SQL Server Analysis Services model. +- Reports based on a live connection to a Power BI dataset. +- Models with Push data. +- Models stored in Power BI My Workspace. +- Models stored in Power BI Pro Workspace. +- Direct Lake Default Semantic Models. (It is possible to connect to a default dataset, but it is not possible to change it through the XMLA endpoint) +- Excel workbook Semantic Models. \ No newline at end of file diff --git a/content/localization/de/shortcuts_de.md b/content/localization/de/shortcuts_de.md new file mode 100644 index 00000000..ab73de05 --- /dev/null +++ b/content/localization/de/shortcuts_de.md @@ -0,0 +1,158 @@ +--- +uid: shortcuts +title: Keyboard shortcuts +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Keyboard shortcuts + +## General + +| Command | Shortcut | +| -------------------------- | ------------ | +| New model | Ctrl+N | +| Open file | Ctrl+O | +| Load model from a database | Ctrl+Shift+O | +| Save current item | Ctrl+S | +| Save all | Ctrl+Shift+S | +| Exit | Alt+F4 | +| Deployment wizard | Ctrl+Shift+D | + +## Edit + +| Command | Shortcut | +| ---------- | -------- | +| Select All | Ctrl+A | +| Copy | Ctrl+C | +| Cut | Ctrl+X | +| Paste | Ctrl+V | +| Undo | Ctrl+Z | +| Redo | Ctrl+Y | +| Find | Ctrl+F | +| Replace | Ctrl+H | + +## Data modelling + +| Command | Shortcut | +| ------------------------------- | --------- | +| Properties | F4 | +| Edit object name / batch rename | F2 | +| Batch rename children | Shift+F2 | +| View dependencies | Shift+F12 | +| Make invisible | Ctrl+I | +| Make visible | Ctrl+U | +| Create measure | Alt+1 | +| Create calculated column | Alt+2 | +| Create hierarchy | Alt+3 | +| Create data column | Alt+4 | +| Create table | Alt+5 | +| Create calculated table | Alt+6 | +| Create calculation group | Alt+7 | +| Accept expression change | F5 | + +## TOM Explorer + +| Command | Shortcut | +| ----------------------------------------------- | ----------------------------- | +| Navigate up or down | Up / Down arrow | +| Expand / collapse current node | Right / Left arrow | +| Expand / collapse current node and all subnodes | Ctrl+Right / Left arrow | +| Expand / collapse entire tree | Ctrl+Shift+Right / Left arrow | +| Toggle measures | Ctrl+1 | +| Toggle columns | Ctrl+2 | +| Toggle hierarchies | Ctrl+3 | +| Toggle partitions | Ctrl+4 | +| Toggle display folders | Ctrl+5 | +| Toggle hidden objects | Ctrl+6 | +| Toggle info columns | Ctrl+7 | +| Navigate back | Alt+Left arrow | +| Navigate forward | Alt+Right arrow | + +## Text/code editing (general) + +| Command | Shortcut | +| --------------- | -------------- | +| Cut line | Ctrl+L | +| Delete line | Ctrl+Shift+L | +| Copy line | Ctrl+Shift+T | +| Transpose lines | Ctrl+T | +| Duplicate line | Ctrl+D | +| Lowercase line | Ctrl+U | +| Uppercase line | Ctrl+Shift+U | +| Move lines up | Alt+Up arrow | +| Move lines down | Alt+Down arrow | + +## DAX code + +| Command | Shortcut | +| ------------------------------------------- | -------------------------------------- | +| Go to definition | F12 | +| Peek definition | Alt+F12] | +| Refactor | Ctrl+R | +| Show auto-complete | Ctrl+Space | +| Show calltip | Ctrl+Shift+Space | +| Format DAX | F6 | +| Format DAX (Short lines) | Ctrl+F6 | +| Comment lines | Ctrl+K | +| Uncomment lines | Ctrl+U | +| Toggle comments | Ctrl+/ | +| Collapse all foldable regions | Ctrl+Alt+[ | +| Expand all foldable regions | Ctrl+Alt+] | +| Toggle all foldable regions state | Ctrl+Alt+; | +| Collapse foldable region | Ctrl+Shift+[ | +| Expand foldable region | Ctrl+Shift+] | +| Toggle foldable region state | Ctrl+Shift+; | +| Delete reference or words | Ctrl+Backspace or Ctrl+Delete | +| Expand Selection | Ctrl+Shift+E | + +## DAX Query + +| Command | Shortcut | +| ----------------- | -------- | +| Execute query | F5 | +| Execute selection | Shift+F5 | + +## DAX Script + +| Command | Shortcut | +| ------------------------------ | -------- | +| Apply script | F5 | +| Apply selection | F8 | +| Apply script and save model | Shift+F5 | +| Apply selection and save model | Shift+F8 | + +## DAX Debugger + +| Command | Shortcut | +| ------------------------------------------------------- | --------- | +| Step over | F10 | +| Step back | Shift+F10 | +| Step in | F11 | +| Step out | Shift+F11 | +| Next row (innermost row context) | F9 | +| Previous row (innermost row context) | Shift+F9 | + +## C# Script + +| Command | Shortcut | +| ---------- | -------- | +| Run script | F5 | + +# Customizing Shortcuts + +Tabular Editor 3 allows for the customization of shortcuts by rebinding existing or adding new shortcuts. + +Setting shortcuts can be done through **Tools -> Preferences -> Keyboard** and locating the command that should have a shortcut binding and setting the binding in the menu. +Shortcuts can be set for many different parts of Tabular Editor 3 including [Macros](xref:creating-macros) to have C# scripts available at the fingertips. + +![Dax Script](~/content/assets/images/SetShortcuts.png) + +1. Keyboard Menu in Preferences +2. Find command that should have a shortcut +3. Set shortcut by holding desired shortcuts key and use "Assign Shortcut" \ No newline at end of file diff --git a/content/localization/de/supported-files_de.md b/content/localization/de/supported-files_de.md new file mode 100644 index 00000000..6fbb4f93 --- /dev/null +++ b/content/localization/de/supported-files_de.md @@ -0,0 +1,233 @@ +--- +uid: supported-files +title: Supported file types +author: Morten Lønskov +updated: 2023-10-17 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Supported file types + +Tabular Editor 3 uses a number of different file formats and document types, some of which are not used by Analysis Services or Power BI. This article provides an overview and a description of each of these file types. + +![Supported File Types](~/content/assets/images/file-types/te3-supported-file-types.png) + +Example files are available for each several file type, based on the [learn.tabulareditor.com](https://tabulareditor.com/learn) course 2 Business Case. + +## Dataset file types + +Tabular Editor supports four file types for semantic models: .bim, Power BI files (.pbit and.pbip), .json and .tmdl. Each file type has different features and limitations, which are explained below. + +> [!NOTE] +> Since **Tabular Editor 3 Desktop Edition** is only intended to be used as an External Tool for Power BI Desktop, this edition does not allow loading and saving semantic model files. You may however still use Tabular Editor 2.x for this purpose. See to learn more about the difference between the Tabular Editor 3 editions. + +### [Tabular Model Files (.bim)](#tab/BIM) + +A .bim file is a single file consisting of nested JSON that is known as TMSL. + +It's the original format for a semantic model that Microsoft supports. + +However, it has a large drawback: as it's a single large file, it's difficult to track changes and use good team development practices such as git source control. + +#### .bim file in a folder + +![Supported File Types BIM](~/content/assets/images/file-types/te3-supported-file-bim.png) + +[Download example .bim file ](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/bim-file-example.bim) + +### [Power BI](#tab/PowerBI) + +Tabular Editor can handle two types of Power BI storage formats: + +- Power BI Template files (.pbit) +- Power BI Project folders (.pbip) + +#### Power BI Project folders (.pbip ) _(Preview)_ + +Power BI Project folders were introduced in June 2023 and is available in Power BI Desktop as a preview feature (also known as "Developer Mode"). The storage format is an alternative way to store the contents of a .pbix file, in a format that is more friendly to version control and 3rd party reading/editing of the content. + +> [!WARNING] +> Just like a .pbix file, a Power BI Project folder may contain model **data** in addition to **metadata**, so the folder should be treated as sensitive in the same way as a .pbix file should be. + +At the root of the Power BI Project folders sits a .pbip file. The file is essentially a pointer to a Power BI report definition file, which may then in turn point to a Power BI dataset, either locally in the same folder structure (stored as a model.bim file), or a dataset published to the Power BI service (in this case, the report is said to be in _Live connect_ mode). If a dataset (model.bim file) is present in the Power BI Project folder, Tabular Editor will be able to load this model metadata when opening the .pbip file. + +To learn more about Power BI Project folders, please read [this official blog post from Microsoft](https://powerbi.microsoft.com/en-us/blog/deep-dive-into-power-bi-desktop-developer-mode-preview/). + +> [!IMPORTANT] +> Power BI Project file is the recommended format when using Power BI with Tabular Editor, as it supports the [widest range of modeling operations](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview#model-authoring). Making other types of changes to the model metadata than those listed, may cause your model to become unloadable in Power BI Desktop, and in this case, Microsoft Support will not be able to help you. + +#### Power BI Template file (.pbit) + +Power BI Template files are similar to .pbix files, with the exception that they do not contain any model **data** - only model **metadata**. As such, this model metadata can be opened and edited in Tabular Editor. + +> [!WARNING] +> Even though it's technically possible to load and save model metadata to and from a .pbit file, this approach is unsupported by Power BI Desktop. Tabular Editor will show a warning and block changes by default. Use Power BI Project folders instead, if you intend to make changes to your Power BI model through Tabular Editor. + +### [Tabular Model Folder (.json)](#tab/JSON) + +Tabular Editor allows you to save your dataset objects as separate JSON files, which is a custom serialization format. + +This format preserves the structure and properties of your objects, such as tables, columns, measures, and relationships. + +This format has been supported in Tabular Editor from the early days and is a proven, though by Microsoft unsupported, method for storing your dataset objects as individual files. Thereby enabling developers to track changes in source control and collaborate on building semantic models. + +There is full compatibility between Tabular Editor 2 and 3 with regards to the the JSON file structure. + +In order to save a semantic model to JSON you must use the 'Save to Folder' option when saving the first time. Subsequent saves to a model loaded from a JSON structured model maintains the setting. it's always possible to convert a model that is in JSON to a .bim file using 'File > Save As' + +![Supported File Types JSON](~/content/assets/images/file-types/te3-supported-file-json.png) + +1. The overall model has a database json and each TOM headline has its own folder +2. In tables, each table exist in its own folder +3. An individual table as a TableName json file with folders for measures, columns and partitions +4. The measures on the table each have their own json file. + +The depth of which json objects that will be created are handled by the serialization settings. + +A single JSON file for a measure contains all the properties of that measure: + +![Supported File Types JSON File](~/content/assets/images/file-types/te3-supported-file-json-measure.png) + +For more information on Save to Folder and serialization settings please refer to: [Save to Folder](xref:save-to-folder) + +[Download example JSON Folder Structure](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/json-model-example.zip) + +### [TMDL](#tab/TMDL) + +TMDL stands for Tabular Model Definition Language and it's a new format for defining and managing datasets in a human readable format using YAML like syntax. + +Microsoft introduced TMDL as a preview feature in April 2023, aiming to provide a unified and consistent way of working with datasets across different platforms and tools. + +TMDL is designed to support dataset source control, enabling users to track changes, collaborate, and automate workflows with semantic models. + +> [!Note] +> TMDL is in preview, which means that it's not fully stable and may have some limitations or issues. + +![Supported File Types TMDL](~/content/assets/images/file-types/te3-supported-file-tmdl.png) + +1. The overall serialization is on the top object level from the TOM +2. Each table is a single file +3. The TMDL file consist of a YAML like indentation with each column and measure inside the file. + +For further reading please see: [TMDL](xref:tmdl) + +[Download example TMDL Folder Structure](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/tmdl-model-example.zip) + +*** + +## Tabular Editor Supporting files + +Supporting files are files which are not used by Analysis Services or Power BI. Instead, these files all support different kinds of development workflow in Tabular Editor 3 and other tools. + +All supporting files can be saved individually using either Ctrl+S or 'File > Save' while having the corresponding document or window open and focused. + +### Diagram file (.te3diag) + +A .te3diag file is a file format that stores the diagram of a model created with TE3. + +These file can be useful for documenting the model structure and logic for other developers who work on the same project. A .te3diag file can be saved in the same folder as the model file for easy access and reference. + +Diagram files are actually JSON that is stored in a Tabular Editor 3 extension. + +[Download example Diagram File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/te3-diagram.te3diag) + +### DAX query files (.dax or .msdax) + +DAX queries are expressions that can be used to manipulate and analyze data in semantic models. A DAX file is a text file that contains one or more DAX queries. + +You can save a DAX file in Tabular Editor 3 and use it later to run the queries again. You can also open a DAX file in other tools that support DAX, such as [DAX Studio](https://daxstudio.org). + +[Download example DAX File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/dax-query-example.dax) + +These files can only be opened while Tabular Editor 3 is connected to an instance of Analysis Services or the Power BI / Fabric XMLA endpoint. + +### Pivot Grid layouts (.te3pivot) + +These files contain the layout of a Pivot Grid in Tabular Editor 3. They are simple JSON files specifying which fields (measures, columns, hierarchies) are displayed in the Pivot Grid, and how they are arranged. + +These files can only be opened while Tabular Editor 3 is connected to an instance of Analysis Services or the Power BI / Fabric XMLA endpoint. + +### DAX Scripts (.te3daxs) + +These files are saved DAX scripts (not queries) which are used in Tabular Editor to manipulate many DAX objects at once. For example, modifying multiple measures in a semantic model. + +### C# Scripts (.csx) + +Creating and editing C# Scripts is one of Tabular Editor's biggest productivity features. + +These scripts can be saved as files with the .csc extension and loaded into Tabular Editor as well as saved as Macros. A [MacroActions.json local setting file](xref:supported-files#macroactionsjson) is maintained by Tabular Editor. + +This way, scripts can be reused without having to write them from scratch every time. The [script library](xref:csharp-script-library) is a good place investigate and reuse various examples of scripts as they demonstrate different features and functionalities of C#. + +[Download example C# Script File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/create-sum-measures-csharp.csx) + +### Vertipaq Analyzer Files (.vpax) + +With Tabular Editor, you can export and import .vpax files using the Vertipaq Analyzer feature. A .vpax file is a compressed file that contains information about the size and structure of your semantic model, but not the actual data. + +You can use this file to analyze and optimize your model performance, without exposing sensitive data. For example, you can use the [DAX optimizer](https://www.daxoptimizer.com/) tool to get suggestions on how to improve your DAX formulas based on the .vpax file. + +[Download example DAX Script File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/dax-script-example.te3daxs) + +Unlike other supporting file types creating a .vpax file is done within the Vertipaq Analyzer window using the 'Import' and 'Export' buttons. + +![VPAX](~/content/assets/images/file-types/te3-supported-file-vpax.png) + +[Download example VPAX file](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/vpaq-example.vpax) + +> [!WARNING] +> If your model metadata is confidential, a .vpax file should also be considered confidential and only shared with that in mind. If you are concerned about protecting IP, Tabular Editor 3 has an option to obfuscate VPAX files. + +#### Obfuscation + +If you need to hand off the VPAX file to a 3rd party, such as a consultant or a tool vendor, you can obfuscate the file to hide the model metadata. This is done by selecting the 'Obfuscated Export...' option under the drop-down button next to the 'Export' button in the Vertipaq Analyzer window. + +An obfuscated VPAX file uses the .ovpax file extension. + +![Export obfuscated VPAX](~/content/assets/images/obfuscated-vpax.png) + +For more documentation on Vertipaq Analyzer please see: [sqlbi Vertipaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer) and [sqlbi Docs: Vertipaq Analyzer](https://docs.sqlbi.com/vertipaq-analyzer/) + +For more information about obfuscation of VPAX files, please see: [VPAX Obfuscator](https://www.sqlbi.com/blog/marco/2024/03/15/vpax-obfuscator-a-library-to-obfuscate-vpax-files/) + +## Local Setting Files + +Tabular Editor maintains several local files in the "%localappdata%\TabularEditor3" folder. These files are functionally relevant for Tabular Editor 3 and are useful to know. + +It can be helpful to share these files across a team so that all developers have the same Macros and BPA rules. + +> [!TIP] +> A windows native way of syncing a version controlled file into the "%localappdata%\TabularEditor3" folder is to use [SymLink](https://www.howtogeek.com/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/). +> +> Store the required files in Git or OneDrive and create a Symlink to the "%localappdata%\TabularEditor3" folder, but be aware that this could end up with synchronization issues, if multiple users update the same file version. +> However, this is not supported by Tabular Editor directly, so implement it at your own discretion. + +### MacroActions.json + +This file stores all the macros that you have created or imported. It can be useful to share this file with your colleagues or backup it in a version control system and can also be configured to sync with a remote repository that contains macros (See tip above). + +This file contains the index of each macro that is used in the software. If you need to change the order or the name of any macro, you can edit this file manually with a text editor. However, be careful not to introduce any errors or inconsistencies in the file thereby corrupting so make sure to create a backup. + +[Download example MacroActions File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/MacroActions.json) + +### BPARules.json + +The file contains the [Best Practice Analyzer rules](xref:using-bpa) and fix expressions. The only place to add and edit fix expressions is inside this JSON file. +It is recommended to store the PBA rule file in version control, which also enables the possibility of running the BPA rules against the semantic model before deployment. + +You can download the official Microsoft BPA rules here: [PBA Rules](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json) + +### RecentServers.json + +Contains all the servers a user has been connected to. It can be advisable to edit it manually to 'forget' past servers no longer relevant. + +### Layouts.json + +The Layouts file is automatically generated by Tabular Editor when starting the application. It contains all information to how Tabular Editor 3's UI layout is configured. + +> [!TIP] +> Deleting this file will reset Tabular Editor's layout. If the Tabular Editor layout does not behave as expected a good first step is to backup this file somewhere else, delete the original and restart Tabular Editor 3. diff --git a/content/localization/de/table-groups_de.md b/content/localization/de/table-groups_de.md new file mode 100644 index 00000000..5e2814e7 --- /dev/null +++ b/content/localization/de/table-groups_de.md @@ -0,0 +1,81 @@ +--- +uid: table-groups +title: Table Groups +author: Daniel Otykier +updated: 2023-03-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Table Groups + +Table Groups is a new feature, available in Tabular Editor 3 starting from [version 3.5.0](xref:release-3-5-0). The feature lets you quickly organise tables into folders, making it easier than ever to manage and navigate large, complex models, in Tabular Editor 3's [TOM Explorer](xref:tom-explorer-view). + +![Table groups](~/content/assets/images/user-interface/table-groups.png) + +You can set up Table Groups either by right-clicking on a table and choosing the **Create > Table group** menu option, or by specifying a name for the Table Group in the **Properties View**, while selecting one or more tables. + +Tables can be moved around between Table Groups by dragging and dropping in the TOM Explorer. Note that, unlike Display Folders for measures, columns and hierarchies, Table Groups cannot be nested. + +Right-clicking on a Table Group in the TOM Explorer, gives you the same context menu options, as if you had selected the table(s) within that Table Group. + +> [!NOTE] +> Table Groups is a Tabular Editor-exclusive feature. Client tools (such as Excel, Power BI Desktop, etc.) will not observe Table Groups, as the [CSDL format](https://learn.microsoft.com/en-us/ef/ef6/modeling/designer/advanced/edmx/csdl-spec), which specifies the conceptual schema of the data model, does not support Table Groups. + +## Metadata and scripting + +Tabular Editor uses an annotation on each table, to specify which Table Group that table belongs to. The name of the annotation is `TabularEditor_TableGroup`. However, when scripting changes to the model using C# scripts, you can modify the Table Group directly through the new `Table.TableGroup` (string) property. + +Below is an example of a C# script, that loops through all tables of a model, organizing them into Table Groups based on their type and usage: + +```csharp +// Loop through all tables: +foreach(var table in Model.Tables) +{ + if (table is CalculationGroupTable) + { + table.TableGroup = "Calculation Groups"; + } + else if (!table.UsedInRelationships.Any() && table.Measures.Any(m => m.IsVisible)) + { + // Tables containing visible measures, but no relationships to other tables + table.TableGroup = "Measure Groups"; + } + else if (table.UsedInRelationships.All(r => r.FromTable == table) && table.UsedInRelationships.Any()) + { + // Tables exclusively on the "many" side of relationships: + table.TableGroup = "Facts"; + } + else if (!table.UsedInRelationships.Any() && table is CalculatedTable && !table.Measures.Any()) + { + // Tables without any relationships, that are Calculated Tables and do not have measures: + table.TableGroup = "Parameter Tables"; + } + else if (table.UsedInRelationships.Any(r => r.ToTable == table)) + { + // Tables on the "one" side of relationships: + table.TableGroup = "Dimensions"; + } + else + { + // All other tables: + table.TableGroup = "Misc"; + } +} +``` + +## Hiding Table Groups + +If you prefer to always see the full, ungrouped list of tables in the TOM Explorer, but you're collaborating with others on a model containing table group annotations, you can still disable table groups altogether, for your Tabular Editor 3 installation. This is done through the **Tools > Preferences** dialog. Navigate to the **TOM Explorer** page, then uncheck **Use table groups** under **Display and filtering**: + +![Table Groups Disable](~/content/assets/images/table-groups-disable.png) + +> [!NOTE] +> Even though you have disabled table groups as described above, tables in your model may still have the `TabularEditor_TableGroup` annotation assigned. If you wish to clear all such annotations from the model, you can use the following C# script: +> +> ```csharp +> foreach(var table in Model.Tables) table.TableGroup = null; +> ``` \ No newline at end of file diff --git a/content/localization/de/te3-eula_de.md b/content/localization/de/te3-eula_de.md new file mode 100644 index 00000000..e24eb96e --- /dev/null +++ b/content/localization/de/te3-eula_de.md @@ -0,0 +1,10 @@ +--- +uid: te3-eula +title: Standard License Terms +author: Søren Toft Joensen +updated: 2021-07-10 +--- + +# Tabular Editor 3 Standard License Terms + +The latest version of our license terms is always available on https://tabulareditor.com/license-terms diff --git a/content/localization/de/third-party-notices_de.md b/content/localization/de/third-party-notices_de.md new file mode 100644 index 00000000..db486bd1 --- /dev/null +++ b/content/localization/de/third-party-notices_de.md @@ -0,0 +1,902 @@ +--- +uid: third-party-notices +title: Third Party Notices +author: Daniel Otykier +updated: 2021-06-01 +--- + +# Tabular Editor 3 Third Party Notices + +This product incorporates third party components from the projects +listed below. The original copyright notices and the licenses under +which Tabular Editor ApS received such third party components are set +forth below for informational purposes. Tabular Editor ApS licenses +these third party components to you under the Tabular Editor 3 software +licensing terms; however, any third party components received under +open source licenses that require such components to remain under their +original license are provided to you by Tabular Editor ApS under their +original license. Tabular Editor ApS reserves all other rights not +expressly granted herein, whether by implication, estoppel or +otherwise. + +For third party components licensed under open source licenses with +source code availability obligations, you may obtain the source code +from us, if and as required under the relevant open source licenses, +by sending an e-mail to licensing@tabulareditor.com. Please write +"Third party open source code" in the subject line. We may also make +a copy of the source code available at: + +https://github.com/TabularEditor/TabularEditor3. + +----------------------------------------------------------------- + +## License for Lexilla, Scintilla, and SciTE + +Copyright 1998-2021 by Neil Hodgson neilh@scintilla.org + +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. + +NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. + +----------------------------------------------------------------- + +## License for Scintilla.NET + +The MIT License (MIT) + +Copyright (c) 2017, Jacob Slusser, https://github.com/jacobslusser + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for ANTLR + +The "BSD 3-clause license" +Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +\===== + +MIT License for codepointat.js from https://git.io/codepointat +MIT License for fromcodepoint.js from https://git.io/vDW1m + +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------------------------------------------------------------- + +## License for Newtonsoft.Json + +The MIT License (MIT) + +Copyright (c) 2007 James Newton-King + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +----------------------------------------------------------------- + +## License for Dax.Formatter + +MIT License + +Copyright (c) SQLBI Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Roslyn + +https://github.com/dotnet/roslyn/blob/main/License.txt + +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Windows-API-CodePack-NET + +https://github.com/Wagnerp/Windows-API-CodePack-NET/blob/main/LICENSE + +MIT License + +Copyright (c) 2009 - 2010 Microsoft Corporation, then modifications by Jacob Slusser 2014, Peter William Wagner 2017 - 2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Tulpep.ActiveDirectoryObjectPicker + +https://github.com/Tulpep/Active-Directory-Object-Picker/blob/master/LICENSE + +Microsoft Public License (MS-PL) + +The initial project was originally created by Armand du Plessis +in 2004 and now is extended and maintained by Tulpep. + +This license governs use of the accompanying software. If you use the software, you +accept this license. If you do not accept the license, do not use the software. + +1. Definitions + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the + same meaning here as under U.S. copyright law. + A "contribution" is the original software, or any additions or changes to the software. + A "contributor" is any person that distributes its contribution under this license. + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions + and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free + copyright license to reproduce its contribution, prepare derivative works of its contribution, and + distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and + limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free + license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or + otherwise dispose of its contribution in the software or derivative works of the contribution + in the software. + +3. Conditions and Limitations + (A) No Trademark License- This license does not grant you rights to use any contributors' name, + logo, or trademarks. + (B) If you bring a patent claim against any contributor over patents that you claim are infringed + by the software, your patent license from such contributor to the software ends automatically. + (C) If you distribute any portion of the software, you must retain all copyright, patent, + trademark, and attribution notices that are present in the software. + (D) If you distribute any portion of the software in source code form, you may do so only + under this license by including a complete copy of this license with your distribution. If + you distribute any portion of the software in compiled or object code form, you may only do + so under a license that complies with this license. + (E) The software is licensed "as-is." You bear the risk of using it. The contributors give + no express warranties, guarantees or conditions. You may have additional consumer rights + under your local laws which this license cannot change. To the extent permitted under your + local laws, the contributors exclude the implied warranties of merchantability, fitness for + a particular purpose and non-infringement. + +----------------------------------------------------------------- + +## License for dotNetCore.Data.OracleClient + +https://github.com/ericmend/oracleClientCore-2.0/blob/master/LICENSE + +MIT License + +Copyright (c) 2018 Eric Azevedo Mendonça + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Ninject + +https://github.com/ninject/Ninject?tab=License-1-ov-file#readme + +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you +accept this license. If you do not accept the license, do not use the software. + +1. Definitions + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the + same meaning here as under U.S. copyright law. + A "contribution" is the original software, or any additions or changes to the software. + A "contributor" is any person that distributes its contribution under this license. + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and + limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free + copyright license to reproduce its contribution, prepare derivative works of its contribution, + and distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations + in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under + its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose + of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, + or trademarks. + (B) If you bring a patent claim against any contributor over patents that you claim are infringed by + the software, your patent license from such contributor to the software ends automatically. + (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, + and attribution notices that are present in the software. + (D) If you distribute any portion of the software in source code form, you may do so only under this + license by including a complete copy of this license with your distribution. If you distribute + any portion of the software in compiled or object code form, you may only do so under a license + that complies with this license. + (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express + warranties, guarantees or conditions. You may have additional consumer rights under your local laws + which this license cannot change. To the extent permitted under your local laws, the contributors + exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + +----------------------------------------------------------------- + +## License for Snowflake.Data + + ``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + ``` + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2017 Snowflake Computing Inc. All right reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + ``` + http://www.apache.org/licenses/LICENSE-2.0 + ``` + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------- + +## License for Dynamic-LINQ.net + + ``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + ``` + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [2016] [Stef Heyenrath] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + ``` + http://www.apache.org/licenses/LICENSE-2.0 + ``` + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------- + +## License for VertiPaq-Analyzer + +MIT License + +Copyright (c) 2019 SQLBI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for CliWrap + +MIT License + +Copyright (c) 2017-2024 Oleksii Holub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for TOMWrapper (Tabular Editor Open Source version) + +MIT License + +Copyright (c) 2016 otykier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Microsoft.ApplicationInsights client libraries + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of Microsoft.ApplicationInsights (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +MICROSOFT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------------------------------------------------------------- + +## License for MICROSOFT ANALYSIS MANAGEMENT OBJECTS (AMO) + +Please view the updated EULA at: https://go.microsoft.com/fwlink/?linkid=852989 + +----------------------------------------------------------------- + +## License for DevExpress WinForms Controls + +End-User License Agreement + +Please view the updated EULA at: https://www.devexpress.com/Support/EULAs/winforms-controls.xml \ No newline at end of file diff --git a/content/localization/de/tmdl-common_de.md b/content/localization/de/tmdl-common_de.md new file mode 100644 index 00000000..2848a76a --- /dev/null +++ b/content/localization/de/tmdl-common_de.md @@ -0,0 +1,12 @@ +--- +uid: tmdl-common +title: Tabular Model Definition Language (TMDL) +author: Daniel Otykier +updated: 2023-05-22 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +[!include[tmdl](~/content/te3/features/tmdl.md)] \ No newline at end of file diff --git a/content/localization/de/tmdl_de.md b/content/localization/de/tmdl_de.md new file mode 100644 index 00000000..3c889417 --- /dev/null +++ b/content/localization/de/tmdl_de.md @@ -0,0 +1,36 @@ +--- +uid: tmdl +title: Tabular Model Definition Language (TMDL) +author: Daniel Otykier +updated: 2023-05-22 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Tabular Model Definition Language (TMDL) + +**TMDL** is a model metadata file format [announced by Microsoft in April 2023](https://powerbi.microsoft.com/en-ie/blog/announcing-public-preview-of-the-tabular-model-definition-language-tmdl/). It aims to provide a human-readable, text-based alternative to the JSON-based model.bim file format. TMDL is inspired by YAML, and as such, is easy to read and write, with minimal use of string quotes and escape characters. It also serializes a model as several smaller files in a folder structure, and is therefore also better suited for version control integration. + +## Enabling TMDL in Tabular Editor 3 + +To enable TMDL in Tabular Editor 3, go to **Tools > Preferences > File Formats > Save-to-folder**, and select "TMDL" in the **Serialization mode** dropdown. The legacy "save-to-folder" functionality will continue to exist side by side with TMDL, but is not a Microsoft supported format. + +After doing so, Tabular Editor 3 will use the TMDL format when saving a model as a folder (**File > Save to folder...**). + +> [!NOTE] +> When you load a model from a legacy Tabular Editor folder structure, it will still get saved into that same format when using **File > Save** (Ctrl+S). Only when you explicitly use the **File > Save to folder...** command, will the model be saved in the new TMDL format. + +## New models + +When saving a new model for the first time, Tabular Editor (since v. 3.7.0), will now provide an option for saving the model as TMDL, even when the default serialization mode is not set to TMDL, as described in the previous section. + +![New Model Tmdl](~/content/assets/images/new-model-tmdl.png) + +# Next steps + +- [TMDL overview (Microsoft Learn)](https://learn.microsoft.com/en-us/analysis-services/tmdl/tmdl-overview). +- [Get started with TMDL (Microsoft Learn)](https://learn.microsoft.com/en-us/analysis-services/tmdl/tmdl-how-to) diff --git a/content/localization/de/toc_de.md b/content/localization/de/toc_de.md new file mode 100644 index 00000000..8a871b16 --- /dev/null +++ b/content/localization/de/toc_de.md @@ -0,0 +1,147 @@ +# Introduction + +## @getting-started + +## @whats-new + +## @editions + +## @desktop-limitations-te3 + +## Power BI XMLA Endpoint + +### @powerbi-xmla + +### @powerbi-xmla-pbix-workaround + +## @proxy-settings + +# Documentation + +## User interface + +### @user-interface + +### @tom-explorer-view + +### @bpa-view + +### @messages-view + +### @data-refresh-view + +### @macros-view + +### @find-replace + +## Features + +### @csharp-scripts + +### @dax-debugger + +### @dax-editor + +### @dax-optimizer-integration + +### @dax-scripts + +### @dax-query + +### @diagram-view + +### @metadata-translation-editor + +### @perspective-editor + +### @pivot-grid + +### @table-groups + +### @code-actions + +## Files formats + +### @supported-files + +### @tmdl + +## @preferences + +## @shortcuts + +## @user-options + +## @security-privacy + +# Tutorials and walkthroughs + +## Connect to a Model + +### @workspace-mode + +## Create a New Model + +### @new-as-model + +### @new-pbi-model + +### @direct-lake-guidance + +## Adding Tables & Data Sources + +### @importing-tables + +### @connecting-to-azure-databricks + +## Configuring Data Security + +### @data-security-about + +### @data-security-setup-rls + +### @data-security-setup-ols + +### @data-security-testing + +## Incremental Refresh + +### @incremental-refresh-about + +### @incremental-refresh-modify + +### @incremental-refresh-setup + +### @incremental-refresh-schema + +### @incremental-refresh-workspace-mode + +## Advanced Modelling + +### @udfs + +### @calendars + +## Automation with C# Scripting + +### @creating-macros + +### @csharp-script-library + +# Troubleshooting + +## @locale-not-supported + +# Other resources + +## @downloads + +## @roadmap + +# Legal + +## @te3-eula + +## @third-party-notices + +## @privacy-policy diff --git a/content/localization/de/tom-explorer-view_de.md b/content/localization/de/tom-explorer-view_de.md new file mode 100644 index 00000000..a3741022 --- /dev/null +++ b/content/localization/de/tom-explorer-view_de.md @@ -0,0 +1,132 @@ +--- +uid: tom-explorer-view +title: TOM Explorer view +author: Morten Lønskov +updated: 2023-02-21 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Using the TOM Explorer in Tabular Editor 3 + +The TOM Explorer is your main window for interacting with the objects of your data mode. Objects such has tables, columns, measures, security groups etc. are all displayed in a hierarchical structure. A Tabular data model is represented by the so called [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) and it is the metadata of your TOM that is displayed in the TOM Explorer. + +The TOM Explorer consists of two main areas, firstly the data model objects and secondly the menu bar that allows for filtering and changing what is presented in the main window. + +![Tom Explorer](~/content/assets/images/user-interface/TOMExplorer.png) + +

    + +## Data Model Objects + +You can fold out objects in the TOM Explorer to see their children and follow the hierarchy of objects downwards. And if you right click on any object you will be given a list of options to interact with that specific object. As you can see below there are several options that you can use with a table. It is with this menu that you for example can easily refresh your tables and see the status of that refresh in the @data-refresh-view + +![Tom Explorer Interaction](~/content/assets/images/user-interface/TomExplorerRightClick.png) + +The right click menu has the following items some of which can be expanded for more actions. The menu depends on the object type chosen (Table, partition, measure, column etc.) and the list below is not exhaustive for all types of objects but contains those most used. + +### Options in Right-click menu + +- **Update table schema...**: + Checks for structural changes in the external data source and updates the table’s schema accordingly. This is useful when columns have been added, renamed, or removed in the source. + +- **Script DAX**: + Generates a DAX script for the selected table and its objects. Opens a new script editor window where you can review or edit DAX definitions collectively. + +- **Preview data**: + Opens the data preview pane displaying a sample of the data loaded into the selected table. Useful for validation or debugging. Only exists when right clicking tables. + +- **Refresh**: + Expands to a selection of possible refresh operation for the selected table. This is available only if the model is connected to live model either stand alone or in workspace mode. This option is only available on tables and partitions. + +- **Create**: + Expands to a submenu allowing the creation of new measures, columns, hierarchies, display folders or calculation items under the selected object. The available options depends on the object type selected. + +- **Move to group**: + Allows you to organize the table into a Table group within the TOM Explorer for easier model navigation. This option is only available for tables. + +- **Make invisible**: + Marks the object as not visible in client tools. The table remains part of the model but is hidden from report authors. Alternative use the shortcut `Ctrl+I` to hide the object. + +- **Shown in perspectives**: + Enables or disables the table’s inclusion in one or more perspectives. Perspectives limit what end-users can see in tools like Power BI. + +- **Batch rename**: When selecting more than one object you can batch rename those objects using string replacement or regex. The shortcut for batch rename is `F2`. + +- **Batch rename children...**: + Enables bulk renaming of all child objects under the table or display folder using regex or string replacement rules. Can also be accessed with the shortcut `Shift+F2`. + +- **Duplicate**: + Creates a copy of the selected table, including all its columns, measures, and partitions. Also exists for all other objects in the TOM Explorer. + +- **Mark as date table...**: + Marks the table as a date table, enabling time intelligence features. Requires that the table contains a valid date column. + +- **Show dependencies**: + Visualizes dependencies between the selected table and other model objects. Can also be accessed via shortcut `Shift+F12`. + +- **Export script**: + Exports the selected object as a TMSL or TMDL script for use in deployment or source control. + +- **Macro Menus**: + Macros can be placed into folders and run against the selected object. In the example above the user has a Modelling and Analysis folder for Macro scripts on table objects. + +- **Cut / Copy / Paste / Delete**: + Standard clipboard operations. Use these to move, duplicate, or remove model objects. + +- **Properties**: + Opens the Properties pane for the selected object. Shortcut: `Alt+Enter`. Used to inspect and edit metadata, expressions, formatting, and visibility settings. + +> [!IMPORTANT] +> In Tabular Editor 3 Desktop Edition some options are disabled and greyed-out. This is due to the limitations of using Tabular Editor has an external tool. For more information see @desktop-limitations + +### Show Info Columns + +The TOM Explorer allows for toggling on additional info columns about the data model objects. This can be done with the short cut `CTRL+7` +These extra info also exists in the property window, but allow for a quick view of the Object Type, Format String, Data Type, Expression and Description. +![Tom Explorer Show Hide Coloumns](~/content/assets/images/user-interface/TOMExplorerInfoColumns.png) + +## TOM Explorer Toolbar + +The toolbar allow you to show and hide different types of objects, toggling perspectives and languages ans well as searching for specific objects in the data model. +![Tom Explorer Toolbar](~/content/assets/images/user-interface/TOMExplorerToolbar.png) + +1. **Show/Hide Measures** + Toggle the visibility of measures within tables. + **Shortcut:** `Ctrl+1` + +2. **Show/Hide Columns** + Toggle the visibility of columns within tables. + **Shortcut:** `Ctrl+2` + +3. **Show/Hide Hierarchies** + Toggle whether hierarchies are shown in the TOM Explorer. + **Shortcut:** `Ctrl+3` + +4. **Show/Hide Partitions** + Controls whether partitions are visible for tables. + **Shortcut:** `Ctrl+4` + +5. **Show/Hide Display Folders** + Enables or disables the display of folder organization within tables. + **Shortcut:** `Ctrl+5` + +6. **Show/Hide Hidden Objects** + Toggles whether hidden objects are shown. + **Shortcut:** `Ctrl+6` + +7. **Show/Hide Info Columns** + Shows or hides metadata columns, such as data types or object status. + **Shortcut:** `Ctrl+7` + +8. **Perspective Selector** + Drop-down to choose a specific perspective. Only objects in the selected perspective will be shown in the TOM Explorer. + +9. **Language Selector** + Allows switching between different languages for model metadata localization. + +10. **Search Bar** + Provides real-time filtering and navigation within the TOM Explorer. Type to search across all visible model objects. diff --git a/content/localization/de/udfs_de.md b/content/localization/de/udfs_de.md new file mode 100644 index 00000000..9f4d771b --- /dev/null +++ b/content/localization/de/udfs_de.md @@ -0,0 +1,296 @@ +--- +uid: udfs +title: DAX User-Defined Functions +author: Daniel Otykier +updated: 2025-09-15 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX User-Defined Functions + +DAX User-Defined Functions (UDFs) is a new capability of semantic models introduced in Power BI Desktop with the September 2025 update. + +The feature lets you create reusable DAX functions that you can invoke from within any DAX expression of your model, even other functions. This powerful feature helps you maintain consistency, reduce code duplication, and create more maintainable DAX expressions. + +Tabular Editor 3 supports UDFs starting from version 3.23.0, although we recommend using [3.23.1](xref:release-3-23-1) (or newer) to benefit from various bug fixes and improvements. + +Für eine ausführlichere Einführung in UDFs in Tabular Editor 3 lesen Sie [diesen Blogbeitrag](https://tabulareditor.com/blog/how-to-get-started-using-udfs-in-tabular-editor-3). + +## Understanding UDFs + +UDFs can be thought of as custom DAX functions that you define once and can use throughout your model. You define which parameters the function accepts, which can be both scalar- or table-valued, or even references to objects, and then you provide the DAX expression that uses those parameters to compute a result, which can also be scalar- or table-valued. + +To learn more about how DAX UDFs work, we recommend [this article by SQLBI](https://www.sqlbi.com/articles/introducing-user-defined-functions-in-dax/). + +## Prerequisites + +Before you can create and use UDFs in Tabular Editor 3, ensure that: + +- Your model compatibility level is **1702 or higher** + +## Creating Your First UDF + +### Step 1: Set Up the Model + +First, verify your model's compatibility level is appropriate for UDFs: + +1. Open your model in Tabular Editor 3 +2. Select the root node ("Model") in the **TOM Explorer** +3. In the **Properties** panel, expand the **Database** property, then check that the **Compatibility Level** is set to **1702** or higher +4. If needed, update the compatibility level and save your model + +![Setting Compatibility Level](~/content/assets/images/udfs-cl1702.png) + +### Step 2: Add a New Function + +1. In the **TOM Explorer**, locate the **Functions** folder under your model +2. Right-click on the **Functions** folder +3. Select **Create > User-Defined Function** +4. Give your function a descriptive name (spaces and special characters are not allowed; underscores and periods are permitted) + +![Creating a UDF](~/content/assets/images/new-udf.png) + +You can also add a UDFs through the **Model > Add User-Defined Function** menu option. + +Alternatively, you can create UDFs directly from the **DEFINE** section of a DAX query, by hitting F7 (Apply) or using the **Query > Apply** menu option. If your query contains multiple query-scoped definitions, you can also select just a subset of them and hit F8 (Apply Selection). + +![Creating a UDF from DAX Query](~/content/assets/images/udf-from-query.png) + +### Step 3: Define Your Function + +In the **Expression Editor**, define your function using proper UDF syntax. + +Here's a basic example that adds two numbers together: + +```dax +// Adds two numbers together +( + x, // The first number + y // The second number +) +=> x + y +``` + +> [!TIP] +> Use the **"Use correct UDF syntax"** code action in the Expression Editor if you need help with the proper syntax structure. + +## UDF Syntax and Structure + +### Basic Syntax + +UDFs follow this general structure: + +```dax +FUNCTION FunctionName = + // Optional comment describing the function + ( + parameter1, // Parameter description + parameter2, // Parameter description + // ... more parameters + ) + => expression_using_parameters +``` + +### Parameter Evaluation Mode + +A key aspect of UDFs is that parameters can be defined in one of two modes, **pass-by-value** and **pass-by-reference**. By default, and unless you specify otherwise, a parameter will by **pass-by-value**. This essentially means that the parameter behaves just like a DAX variable (i.e. one that is defined using the `VAR` keyword) inside the UDF expression. In other words, when the UDF is called, the parameter values are "copied" into the function and any reference to that parameter inside the function will always return the same value. + +In contrast, **pass-by-reference** parameters behave more like measures. That is, the result of evaluating the parameter _inside the function_ may differ depending on the evaluation context. + +To specify the evaluation mode, include a parameter specification after the parameter name, separated by a colon (`:`). The specification can be either `VAL` or `EXPR` for "pass-by-value" and "pass-by-reference", respectively. As mentioned above, "pass-by-value" is the default, so `VAL` is implicit if not specified. For example: + +```dax +( + x: VAL, // Pass-by-value parameter - the DAX expression is evaluated once when the function is called, and the result is "copied" into the function + y: EXPR // Pass-by-reference parameter - can be any DAX expression which will observe whatever context the parameter is later referenced under +) +=> +ROW( + "x", x, + "x modified", CALCULATE(x, Product[Color] = "Red"), + "y", y, + "y modified", CALCULATE(y, Product[Color] = "Red") +) +``` + +Calling the above function with a measure reference for each parameter, e.g. `MyFunction([Some Measure], [Some Measure])`, will yield different results for the `y` parameter depending on the current filter context, as shown in the screenshot below: + +![Pass-by-value vs Pass-by-reference](~/content/assets/images/udf-pass-by-ref.png) + +In addition to specifying the evaluation mode, you can also constrain the parameter type by specifying a data type before the evaluation mode, e.g. `x: INT64 VAL` or `y: TABLE EXPR`. + +These type specifications are optional, but if specified they will perform an implicit type conversion on arguments passed to the function, and will also affect the autocomplete suggestions in Tabular Editor 3 when writing DAX code that calls the function. + +Check the [Microsoft specification for UDFs](https://learn.microsoft.com/en-us/dax/best-practices/dax-user-defined-functions) for the complete list of available constraints. + +## Using UDFs in Your Model + +### In Object Expressions + +Once you've created a UDF, you can use it in any DAX expression throughout your model. Tabular Editor 3's autocomplete will suggest your UDFs as you type. + +### In DAX Scripts + +UDFs are also available when working with DAX Scripts: + +```dax +-- Function: MyFuncRenamed +FUNCTION MyFuncRenamed = + // Adds two numbers together + ( + x: INT64, // The first number + y: INT64 // The second number + ) + => x + y + +-- Measure: [New Measure] +MEASURE 'Date'[New Measure] = MyFuncRenamed(1,2) +``` + +### In DAX Queries + +Tabular Editor 3 adds powerful new features for working with UDFs in DAX queries. We already mentioned above how you can "apply" a UDF from the **DEFINE** section of a DAX query, to have it become a permanent part of your model. In addition, if using a UDF inside a DAX query, you can right-click on the function invocation and choose **Define Function** to automatically generate the function definition in the **DEFINE** section of your query: + +![Define Function from Query](~/content/assets/images/udf-define.png) + +As can be seen from the screen above, the following options are available when right-clicking on a UDF invocation: + +- **Peek Definition** (Alt+F12): Opens a nested, read-only editor below the current cursor position, showing you the function definition +- **Go To Definition** (F12): Navigates to the function definition in the **Functions** folder of your model, or, if the function is defined in the current query or script, to the function definition inside the editor +- **Inline Function**: Replaces the function invocation with the actual function definition, substituting parameters with the actual arguments passed to the function +- **Define Function** (DAX scripts or DAX queries only): Generates the function definition in the **DEFINE** section of your query, if it doesn't already exist there +- **Define Function with dependencies** (DAX scripts or DAX queries only): Similar to the above, but also generates definitions for any other UDFs that the function depends on + +## Advanced Features + +### Formula Fixup + +When you rename a UDF, Tabular Editor 3 automatically updates all references throughout your model, just like with measures and other objects. + +### Peek Definition + +The **Peek Definition** feature works with UDFs, allowing you to quickly view the function's implementation without navigating away from your current context. + +![Peek Definition for UDFs](~/content/assets/images/udf-peek-definition.png) + +### Dependencies View + +UDFs appear in the **DAX Dependencies** (Shift+F12) view, showing both: + +- **Objects that depend on the function**: Which measures, columns, etc. use the UDF +- **Objects the function depends on**: Which measures, columns, etc. the UDF references + +## Best Practices + +### Naming Conventions + +- Use descriptive names that clearly indicate the function's purpose +- Consider prefixing UDFs with your organization's initials (e.g., `ACME.CalculateDiscount`) +- Avoid generic names that might conflict with future DAX functions + +### Documentation + +- Always include comments describing what the function does +- Document each parameter's purpose and expected data type +- Include usage examples in your comments + +```dax +// Calculates the percentage change between two values +// Usage: PercentChange(100, 110) returns 0.10 (10% increase) +( + oldValue: DOUBLE, // The original value + newValue: DOUBLE // The new value to compare against +) +=> DIVIDE(newValue - oldValue, oldValue) +``` + +Tabular Editor 3 automatically picks up any comments and displays them appropriately in autocomplete suggestions and tooltips. + +![UDF Autocomplete with Comments](~/content/assets/images/udf-comment-tooltips.png) + +## Common Use Cases + +### Mathematical Operations + +```dax +// Calculate compound interest +( + principal: DOUBLE, + rate: DOUBLE, + periods: INT64 +) +=> principal * POWER(1 + rate, periods) +``` + +### String Manipulation + +```dax +// Format a full name from first and last name components +( + firstName: STRING, + lastName: STRING +) +=> TRIM(firstName) & " " & TRIM(lastName) +``` + +### Date Calculations + +```dax +// Get the fiscal year based on a date (fiscal year starts July 1) +( + inputDate: DATETIME +) +=> IF(MONTH(inputDate) >= 7, YEAR(inputDate) + 1, YEAR(inputDate)) +``` + +### Business Logic + +```dax +// Apply tiered discount based on quantity +( + quantity: INT64 +) +=> SWITCH( + TRUE(), + quantity >= 100, 0.15, + quantity >= 50, 0.10, + quantity >= 25, 0.05, + 0 +) +``` + +## Troubleshooting + +### Common Issues + +**Function not appearing in autocomplete** + +- Verify the function was saved successfully +- Check that there are no syntax errors in the function definition +- Ensure you're using the function in a compatible context + +**Parameter constraint errors** + +- Review the parameter types you've specified +- Make sure you're passing compatible values to the function +- Check the Microsoft documentation for supported constraint types + +**Function not working after deployment** + +- Verify your target environment supports UDFs (compatibility level 1702+). As of September 16th, 2025, the Power BI Service does not yet support UDFs, nor does Azure Analysis Services or SQL Server Analysis Services. + +## Limitations + +- UDFs are currently a preview feature and may have limitations in certain deployment scenarios +- Not all Power BI environments support UDFs (requires specific builds) +- UDFs cannot be recursive (call themselves) +- UDFs do not support optional parameters, parameters with default values, or parameter overloading +- While Power BI supports visual calculation expressions in UDFs, our DAX parser currently does not, which may cause Tabular Editor 3 to show false error messages, when using visual calculation-specific functions (such as [`RUNNINGSUM`](https://dax.guide/runningsum)) in UDFs. + +--- + +UDFs in Tabular Editor 3 provide a powerful way to create reusable, maintainable DAX code. By following these guidelines and best practices, you can build a library of functions that will improve your model's consistency and reduce development time. \ No newline at end of file diff --git a/content/localization/de/user-interface_de.md b/content/localization/de/user-interface_de.md new file mode 100644 index 00000000..245edc82 --- /dev/null +++ b/content/localization/de/user-interface_de.md @@ -0,0 +1,229 @@ +--- +uid: user-interface +title: Basic user interface +author: Daniel Otykier +updated: 2021-09-08 +--- + +# Getting to know Tabular Editor 3's User Interface + +This article describes the user interface of Tabular Editor 3. + +## Basic user interface elements + +The first time you launch Tabular Editor 3 and load a Semantic Model, you will be presented with an interface, as shown in the screenshot below. + +![Basic user interface](~/content/assets/images/basic-ui.png) + +1. **Title bar**: This shows the name or the currently loaded file and Analysis Services database or Power BI dataset if connected. +2. **Menu bar**: The menu bar provides access to all of the various features of Tabular Editor 3. See [Menus](#menus) for a detailed walkthrough of all menu items. +3. **Toolbars**: The toolbars provide quick access to the most commonly used features. All features accessible through the toolbar can also be accessed through the menus. You may customize the toolbars and their buttons under **Tools > Customize...** +4. **TOM Explorer view**: A hierarchical view of your data model, with all objects available . of the metadata from the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) metadata that represents your data model. The toggle buttons at the top allow you to filter which objects are displayed. The search box allows you to filter objects by names. +5. **Expression Editor**: The expression editor provides a quick way to edit any DAX, SQL or M expressions of the currently selected object in the TOM Explorer. If you close the expression editor, you can bring it back up by double-clicking on an object in the TOM Explorer. The dropdown at the top allows you to switch between different expression properties, in case the currently selected object has more than one such property (for example, KPIs have Target Expressions, Status Expressions and Trend Expressions, which are 3 different DAX expressions belonging to the same KPI object). +6. **Properties view**: A detailed view of all TOM properties available on the currently selected object(s) in the TOM Explorer. Most properties can be edited through the grid, even when multiple objects are selected. Some properties (such as "Format String", "Connection String", "Role Members") have popup dialogs or collection editors that can be brought up by clicking on the ellipsis button within the property value cell. +7. **Messages view**: Tabular Editor 3 continuously analyzes the DAX expressions on your model for semantic errors. Any such errors are outputted here. In addition, messages shown in this view, can originate from C# scripts or from error messages reported by Analysis Services. +8. **Status bar**: The status bar provides various contextual information about the current selection, Best Practice Analyzer findings, etc. + +There are a number of additional views available, serving various purposes. More information in the [View menu](#view) section. + +# Customizing the user interface + +All UI elements may be resized and/or rearranged to fit your needs. You can even drag individual views out of the main view, thus splitting up an instance of Tabular Editor 3 across multiple monitors. Tabular Editor 3 will save the customization when the application is closed, and reload it automatically upon next launch. + +### Choosing a different layout + +To reset the application to the default layout, choose the **Window > Default layout** option. Users of Tabular Editor 2.x may prefer the **Window > Classic layout** option which places the TOM Explorer on the left side of the screen, and the Properties view below the Expression Editor. + +Use the \*\*Window > Capture current layout..." option to save a customized layout such that it will become available as a new layout option within the Window menu, allowing you to quickly switch back and forth between different layouts. Use the **Window > Manage layouts...** option to bring up a list of all available layouts, allowing you to rename, save, delete layouts, etc. When saving a layout to disk, the result is an .xml file which you can share with other users of Tabular Editor 3. + +![Manage Layouts](~/content/assets/images/manage-layouts.png) + +### Changing themes and palettes + +The visual appearance of Tabular Editor 3 can be changed by choosing a different theme and/or palette. Tabular Editor 3 ships with five different themes (sometimes called "skins"), available through the **Window > Themes** menu: + +- Basic and Bezier (vector based, works well on high-DPI displays) +- Blue, Dark and Light (raster based, not recommended for high-DIP Displays) + +For the vector based themes (Basic and Bezier), use the **Window > Palette** menu item to change the colors used by the theme. + +![Palettes](~/content/assets/images/palettes.png) + +# Menus + +The following section describes the menus in Tabular Editor 3 in more details. + +We use the term **Active document** in the following section, to mean that the cursor is placed within a document such as the Expression Editor or the "DAX Script 1" tab in the screenshot below. Some keyboard shortcuts and menu items behave differently depending on whether there is an active document or not, and what type of document is active. + +> [!NOTE] +> Menus and toolbars are locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option + +![Active Document](~/content/assets/images/active-document.png) + +## File + +The **File** menu primarily contains menu items for dealing with loading and saving model metadata and supporting files and documents. + +![File Menu](~/content/assets/images/file-menu.png) + +- **New**: Opens a submenu that allows you to create a new blank data model (Ctrl+N), or create various [supporting files](xref:supported-files#supported-file-types) such as a new DAX Query or DAX Script (text files) or a data model diagram (JSON file). Supporting files (with the exception of C# scripts), can be created only when a model is already loaded in Tabular Editor. + + ![File Menu New](~/content/assets/images/file-menu-new.png) + +> [!IMPORTANT] +> The **New > Model...** option is not available in Tabular Editor 3 Desktop Edition, as this edition may only be used as an External Tool for Poewr BI Desktop. [More information](xref:editions). + +- **Open**: Opens a submenu with options for loading a data model from various sources, as well as on option for loading any other type of file. The submenu items are: + + ![File Menu Open](~/content/assets/images/file-menu-open.png) + + - **Model from file...** Open model metadata from a file such as a .bim or .pbit file. + - **Model from DB...** Specify Analysis Services or Power BI XMLA connection details, or connect to a local instance of Analysis Services (such as Visual Studio's Integrated Workspace server or Power BI Desktop), in order to load model metadata from a tabular model that has already been deployed. + - **Model from folder...** Open model metadata from a folder structure which was previously saved using any version of Tabular Editor. + - **File...** displays a dialog that lets you open any type of file supported by Tabular Editor 3, based on the file name extension. See [Supported file types](xref:supported-files) for more information. + + ![Supported File Types](~/content/assets/images/supported-file-types.png) + +> [!IMPORTANT] +> In Tabular Editor 3 Desktop Edition the **Open > Model from file...** and **Open > Model from folder...** options are not available and the **Open > File...** dialog only allows opening [supporting files](xref:supported-files#supported-file-types), not files containing metadata. + +- **Revert**: This option lets you reload the model metadata from the source, discarding any changes that are made in Tabular Editor, which have not yet been saved. This option is useful when Tabular Editor 3 is used as an External Tool for Power BI Desktop, and a change is made in Power BI Desktop while Tabular Editor 3 is connected. By choosing **Revert**, Tabular Editor 3 can reload the model metadata from Power BI Desktop without having to reconnect. +- **Close**: This closes the active document (for example a DAX Query, a C# script or a data model diagram). If the document has unsaved changes, Tabular Editor will prompt you to save the changes before closing. +- **Close model**: This unloads the currently loaded model metadata from Tabular Editor. If you made changes to the metadata, Tabular Editor will prompt you to save the changes before closing. +- **Save**: This saves the active document back to the source file. If no document is active, this saves the model metadata back to the source, which could be a Model.bim file, a Database.json (folder structure) or a connected instance of Analysis Services (including Power BI Desktop) or the Power BI XMLA endpoint. +- **Save as...** This allows you to save the active document as a new file. If no document is active, this allows you to save the model metadata as a new file, using the .bim (JSON-based) file. +- **Save to folder...** This allows you to save the model metadata as a [folder structure](xref:save-to-folder). +- **Save all**: Saves all unsaved documents and model metadata at once. +- **Recent files**: Displays a list of recently used supporting files allowing you to quickly reopen them. +- **Recent tabular models**: Displays a list of recently used model metadata files or folders, allowing you to quickly reload model metadata from one of these. + +> [!IMPORTANT] +> In Tabular Editor 3 Desktop Edition the **Save to folder** and **Recent tabular models** options are disabled. In addition, the **Save as** option is only enabled for [supporting files](xref:supported-files#supported-file-types). + +- **Exit**: Shuts down the Tabular Editor 3 application. You are prompted to save any unsaved files or model metadata before the application is shut down. + +## Edit + +The **Edit** menu contains standard Windows application menu items for editing a document or making changes to the currently loaded model metadata. + +![Edit Menu](~/content/assets/images/edit-menu.png) + +- **Undo**: This option undoes the last change made to the model metadata. When there is no active document, the familiar CTRL+Z shortcut maps to this option. +- **Redo**: This option undoes the last undo against the model metadata. When there is no active document, the familiar CTRL+Y shortcut maps to this option. +- **Undo typing**: Undoes the last text change in the currently active document. When there is no active document, this option is not available. +- **Redo typing**: Undoes the last undo within the currently active document. When there is no active document, this option is not available. +- **Find**: Displays the "Find and replace" dialog with the "Find" tab selected. [More information](xref:find-replace#find). +- **Replace**: Displays the "Find and replace" dialog with the "Replace" tab selected. [More information](xref:find-replace#replace). +- **Cut / Copy / Paste**: These are the familiar Windows editing operations. If there is an active document, then these apply to the text selection within that document. Otherwise, these options may be used to manipulate objects in the TOM Explorer. For example, you can duplicate multiple measures by holding down the SHIFT or CTRL key while selecting the measures in the TOM Explorer, then hitting CTRL+C followed by CTRL+V. +- **Delete**: Deletes the selected text in the active document, or the currently selected object(s) in the TOM Explorer if there is no active document. + +> [!NOTE] +> Tabular Editor generally only prompts for object deletion when multiple objects are selected, or when there are dependencies to the object(s) being deleted. Object deletion can be undone by using the **Undo** option (CTRL+Z). + +- **Select all**: Selects all text in the currently active document, or all objects belonging to the same parent within the TOM Explorer. +- **Code assist**: This option is available when editing DAX code. It provides a shortcut to various code assist features relevant for editing DAX code. See [DAX editor](xref:dax-editor#code-assist-features) for more information. + +## View + +The **View** menu lets you navigate between the different views of the Tabular Editor 3 UI. If a view has been hidden, click on the view title in this menu will unhide the view and bring it into focus. Note that documents are not shown in the View menu. To navigate between documents, use the [Window menu](#window). + +![View Menu](~/content/assets/images/view-menu.png) + +- **TOM Explorer**: The TOM Explorer presents a hierarchical view of the entire [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) of the currently loaded model metadata. See @tom-explorer-view for more information. +- **Best Practice Analyzer**: The Best Practice Analyzer helps improve the quality of your model by letting you specify rules for best practice validation. See @bpa-view for more information. +- **Messages**: The Messages view displays errors, warnings and informational messages from various sources, such as the Tabular Editor 3 Semantic Analyzer. See @messages-view for more information. +- **Data Refresh**: The Data Refresh view allows you to track data refresh operations that are running in the background. See @data-refresh-view for more information. +- **Macros**: The Macros view allows you to manage any macros you have created. Macros can be created from @csharp-scripts. See @creating-macros for more information. +- **VertiPaq Analyzer**: The VertiPaq Analyzer view allows you to collect, import and export detailed statistics about the data in your model, to help improve and debug DAX performance. VertiPaq Analyzer is created and maintained by [Marco Russo](https://twitter.com/marcorus) of [SQLBI](https://sqlbi.com) under MIT license. More information on the [GitHub project page](https://github.com/sql-bi/VertiPaq-Analyzer). +- **Expression Editor**: This is the "quick editor" that lets you edit DAX, M or SQL expressions on whichever object is currently selected in the TOM Explorer. See @dax-editor for more information. + +## Model + +The **Model** menu displays actions that can be performed at the level of the Model object (the root object of the TOM Explorer). + +![View Menu](~/content/assets/images/model-menu.png) + +- **Deploy...**: Launches the Tabular Editor Deployment wizard. For more information, see @deployment. + +> [!IMPORTANT] +> The **Deploy** option is not available in Tabular Editor 3 Desktop Edition. For more information see @editions. + +- **Import tables...** Launches the Tabular Editor 3 Import Table Wizard. For more information, see @importing-tables. +- **Update table schema...** Detects schema changes in the data source(s) for the currently selected table(s) or partition(s) compared to the currently imported columns. See @importing-tables#updating-table-schema for more information. +- **Script DAX**: Generates a DAX script for the currently selected object(s) (or all DAX objects in the model, if nothing is selected). See @dax-scripts for more information. +- **Refresh model**: When Tabular Editor is connected to an instance of Analysis Services, this submenu contains options for starting a background refresh operation at the model level. The submenu has the options below. For more information, see [Refresh command (TMSL)](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#request). + - **Automatic (model)**: Analysis Services determines which objects to refresh (only objects that are not in the "Ready" state). + - **Full refresh (model)**: Analysis Services performs a full refresh of the model. + - **Calculate (model)**: Analysis Services performs a re-calculation of all calculated tables, calculated columns, calculation groups and relationships. No data is read from the data sources. +- **Create [object type]**: The remaining shortcuts in the **Model** menu lets you create new types of model child objects (tables, data sources, perspectives, etc.). + +## Tools + +The **Tools** menu contains options for controlling Tabular Editor 3 preferences and customizations. + +![View Menu](~/content/assets/images/tools-menu.png) + +- **Customize...** Launches the Tabular Editor 3 User Interface Layout customization dialog, which lets you create new toolbars, rearrange and edit menus and toolbar buttons, etc. +- **Preferences...** Launches the Tabular Editor 3 Preferences dialog, which is a central hub for managing all other aspects of Tabular Editor and its features, such as update checks, proxy settings, query row limits, request timeouts, etc. See @preferences for more information. + +## Window + +The **Window** menu provides shortcuts for managing and navigating between the various views and documents (collectively known as _windows_) of the application. It also has menu items for controlling the theming and color palettes as described [above](#changing-themes-and-palettes). + +![View Menu](~/content/assets/images/window-menu.png) + +- **New...** this submenu provides a shortcut for creating new [supporting files](xref:supported-files#supported-file-types). The options here are identical to those under **File > New**. + +- **Float** undocks the current view or document into a floating window. + +- **Pin tab** pins a tab. When a tab is pinned, it is shown at the left-most side of the document tabs, and when right-clicking on the tabs, shortcuts are available for closing only unpinned tabs. + + ![View Menu](~/content/assets/images/tab-context-menu.png) + +- **New Horizontal/Vertical Tab Group**: This option lets you divide the main document area into multiple sections (aka. "tab groups), in order to have multiple documents displayed simultaneously side-by-side or top-by-bottom. + +- **Close All Documents**: Closes all document tabs. You are prompted to save unsaved changes, if any. + +- **Reset Window Layout**: Resets all customization applied to the main document area. + +- **1..N [document]**: The first 10 open documents are listed here, allowing you to navigate between them. You can also use the CTLR+Tab shortcut to quickly switch between open documents and views, such as shown in the screenshot below: + + ![View Menu](~/content/assets/images/ctrl-tab.png) + +- **Windows...**: Opens a dialog listing ALL open documents, allowing you to switch between them or close them individually. + + ![View Menu](~/content/assets/images/windows-manager.png) + +- **Capture current layout** / **Manage layouts...** / **Default layout** / **Classic layout**: These menu items were discussed [earlier in this article](#choosing-a-different-layout). + +- **Theme** / **Default palette**: These menu items were discussed [earlier in this article](#changing-themes-and-palettes). + +## Help + +The **Help** menu provides shortcuts for online resources and more. + +![View Menu](~/content/assets/images/help-menu.png) + +- **Getting Started**: This menu item links to [this article](xref:getting-started). +- **Tabular Editor 3 Docs**: This menu item links to [docs.tabulareditor.com](https://docs.tabulareditor.com/te3). +- **Community Support**: This menu item links to our [public community support site](https://github.com/TabularEditor/TabularEditor3). +- **Dedicated Support**: This menu item lets you send an e-mail directly to our dedicated support hotline. + +> [!NOTE] +> Dedicated support is reserved for Tabular Editor 3 Enterprise Edition customers. All other customers should reach out on the [public community support site](https://github.com/TabularEditor/TabularEditor3) for any technical issues, questions or other product-specific questions. + +- **About Tabular Editor**: Launches a dialog that shows detailed information about the version of Tabular Editor being used as well installation and licensing details. The dialog also lets you change your license key. + +## Dynamic menus (context dependent) + +In addition to the menus mentioned above, other menus may appear at certain times, depending on which UI element currently has focus and which object is currently selected in the TOM Explorer. For example, if you select a Table-object, a **Table** menu will appear, holding the same context-specific shortcut items as when you right-click on that object in the TOM Explorer. + +If you switch the input focus between different types of documents (i.e. DAX queries, Pivot Grids, diagrams, etc.), you should also see a menu representing the type of document currently in focus. That menu will hold items relevant for the current document. For example, when a diagram currently has focus, there will be a **Diagram** menu which has an item for adding tables to the diagram, among others. + +You can change the behavior of these dynamic menus under **Tools > Preferences > User interface**. + +# Next steps + +- [Using the TOM Explorer in Tabular Editor 3](xref:tom-explorer-view) +- @supported-files +- @preferences \ No newline at end of file diff --git a/content/localization/de/user-options_de.md b/content/localization/de/user-options_de.md new file mode 100644 index 00000000..d0cb0f6a --- /dev/null +++ b/content/localization/de/user-options_de.md @@ -0,0 +1,63 @@ +--- +uid: user-options +title: User options (.tmuo) file +author: Daniel Otykier +updated: 2021-09-27 +--- + +# Tabular Model User Options (.tmuo) File + +Tabular Editor 3 introduces a new JSON based file, to store developer- and model-specific preferences. This file is called the **Tabular Model User Options** file and uses the **.tmuo** file extension. + +When you open a Model.bim or Database.json file in Tabular Editor 3, the file will be created using the name of the file you loaded and your Windows user name. For example, if a user opens a file called `AdventureWorks.bim`, the user options file will be saved as `AdventureWorks..tmuo`, where `` is the Windows user name of the current user. Tabular Editor searches for a file with such a name every time a model is loaded from disk. + +> [!IMPORTANT] +> The **.tmuo** file contains user-specific preferences, and as such it should not be included in a shared version control environment. If you're using Git for version control, make sure to include the `.tmuo` extension in your `.gitignore` file. + +## File content + +Below is an example of the file content: + +```json +{ + "UseWorkspace": true, + "WorkspaceConnection": "provider=MSOLAP;data source=localhost", + "WorkspaceDatabase": "WorkspaceDB_DanielOtykier_20210904_222118", + "DataSourceOverrides": { + "SQLDW": { + "ConnectionString": { + "Encryption": "UserKey", + "EncryptedString": "..." + }, + "PrivacySetting": "NA" + } + }, + "TableImportSettings": { + "SQLDW": { + "ServerType": "Sql", + "UserId": "sqladmin", + "Password": { + "Encryption": "UserKey", + "EncryptedString": "..." + }, + "Server": "localhost", + "Database": "AdventureWorksDW2019", + "Authentication": 0 + } + } +} +``` + +In this example, the JSON properties shown have the following meaning: + +- `UseWorkspace`: Indicates whether Tabular Editor should connect to a workspace database upon loading the model. The workspace database will be overwritten with the metadata of the loaded file/folder structure. When this value is not present, Tabular Editor will prompt the user for whether they want to use a workspace database or not, upon model load. +- `WorkspaceConnection`: Server name of the Analysis Services instance or Power BI XMLA Endpoint to which the workspace database will be deployed. +- `WorkspaceDatabase`: Name of the workspace database to deploy. This should ideally be unique for each developer and model. +- `DataSourceOverrides`: This structure may be used to specify alternative data source properties and credentials which will be used every time the workspace database is deployed. This is useful if the Model.bim file contains data source connection details that you want to override for your workspace database, such as when you want Analysis Services to refresh data from a different source than what is specified in the Model.bim file. +- `TableImportSettings`: This structure is used whenever Tabular Editor's [Import Table or Schema Update](xref:importing-tables) feature is used. The credentials and settings specified here, are used by Tabular Editor when establishing a connection to the source for purposes of browsing available tables/views and updating the imported table schema, when changes have been made to the source. + +All credentials and connection strings in the .tmuo file are encrypted with the Windows User Key. In other words, a .tmuo file containing encrypted data cannot be shared between multiple users. + +## Next steps + +- @workspace-mode \ No newline at end of file diff --git a/content/localization/de/using-bpa-sample-rules-expressions_de.md b/content/localization/de/using-bpa-sample-rules-expressions_de.md new file mode 100644 index 00000000..56191f11 --- /dev/null +++ b/content/localization/de/using-bpa-sample-rules-expressions_de.md @@ -0,0 +1,118 @@ +--- +uid: using-bpa-sample-rules-expressions +title: BPA Sample Rules Expression +author: Morten Lønskov +updated: 2023-02-21 +--- + +# Rule Expression Samples + +In this section, you'll see some examples of Dynamic LINQ expressions that can be used to define rules. The expression that is entered in the Rule Expression Editor, will be evaluated whenever focus leaves the textbox, and any syntax errors will be shown on top of the screen: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380170/9f01634e-29af-11e7-952e-e10a1f28df32.png) + +Your rule expressions may access any public properties on the objects in the TOM. If you try to access a property that does not exist on that type of object, an error will also be shown: + +![image](https://cloud.githubusercontent.com/assets/8976200/25381302/798bab98-29b3-11e7-931e-789e5286fc45.png) + +"Expression" does not exist on the "Column" object, but if we switch the dropdown to "Calculated Columns", the statement above works fine: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380451/87b160da-29b0-11e7-8e2e-c4e47593007d.png) + +Dynamic LINQ supports all the standard arithmetic, logical and comparison operators, and using the "."-notation, you can access subproperties and -methods of all objects. + +``` +String.IsNullOrWhitespace(Expression) and not Name.StartsWith("Dummy") +``` + +The above statement, applied to Calculated Columns, Calculated Tables or Measures, flags those that have an empty DAX expression unless the object's name starts with the text "Dummy". + +Using LINQ, we can also work with collections of objects. The following expression, applied to tables, will find those that have more than 10 columns which are not organized in Display Folders: + +``` +Columns.Count(DisplayFolder = "") > 10 +``` + +Whenever we use a LINQ method to iterate over a collection, the expression used as an argument to the LINQ method is evaluated on the items in the collection. Indeed, DisplayFolder is a property on columns that does not exist at the Table level. + +Here, we see this rule in action on the Adventure Works tabular model. Note how the "Reseller" table shows up as being in violation, while the "Reseller Sales" does not show up (columns in the latter have been organized in Display Folders): + +![image](https://cloud.githubusercontent.com/assets/8976200/25380809/d9d1c3a4-29b1-11e7-839e-29450ad39c8a.png) + +To refer to the parent object inside a LINQ method, use the special "outerIt" syntax. This rule, applied to tables, will find those that contain columns whose name does not start with the table name: + +``` +Columns.Any(not Name.StartsWith(outerIt.Name)) +``` + +It would probably make more sense to apply this rule to Columns directly, in which case it should be written as: + +``` +not Name.StartsWith(Table.Name) +``` + +To compare against enumeration properties, simply pass the enumerated value as a string. This rule, will find all columns whose name end with the word "Key" or "ID", but where the SummarizeBy property has not been set to "None": + +``` +(Name.EndsWith("Key") or Name.EndsWith("ID")) and SummarizeBy <> "None" +``` + +## Finding unused objects + +When building Tabular Models it is important to avoid high-cardinality columns at all costs. Typical culprits are system timestamps, technical keys, etc. that have been imported to the model by mistake. In general, we should make sure that the model only contains columns that are actually needed. Wouldn't it be nice if the Best Practice Analyzer could tell us which columns are likely not needed at all? + +The following rule will report columns that: + +- ...are hidden (or whose parent table is hidden) +- ...are not referenced by any DAX expressions (considers all DAX expressions in the model - even drillthrough and RLS filter expressions) +- ...do not participate in any relationships +- ...are not used as the "Sort By"-column of any other column +- ...are not used as levels of a hierarchy. + +The Dynamic LINQ expression for this BPA rule is: + +``` +(IsHidden or Table.IsHidden) +and ReferencedBy.Count = 0 +and (not UsedInRelationships.Any()) +and (not UsedInSortBy.Any()) +and (not UsedInHierarchies.Any()) +``` + +The same technique can be used to find unused measures. It's a little simpler, since measures can't participate in relationships, etc. So instead, let's spice things up a bit, by also considering whether any downstream objects that reference a given measure, are visible or not. That is, if measure [A] is referenced by measure [B], and both measure [A] and [B] are hidden, and no other DAX expressions refer to these two measures, we should let the developer know that it is safe to remove both of them: + +``` +(IsHidden or Table.IsHidden) +and not ReferencedBy.AllMeasures.Any(not IsHidden) +and not ReferencedBy.AllColumns.Any(not IsHidden) +and not ReferencedBy.AllTables.Any(not IsHidden) +and not ReferencedBy.Roles.Any() +``` + +## Fixing objects + +In some cases, it is possible to automatically fix the issues on objects satisfying the criteria of a rule. For example when it's just a matter of setting a simple property on the object. Take a closer look at the JSON behind the following rule: + +```json +{ + "ID": "FKCOLUMNS_HIDDEN", + "Name": "Hide foreign key columns", + "Category": null, + "Description": "Columns used on the Many side of a relationship should be hidden.", + "Severity": 1, + "Scope": "Column", + "Expression": "Model.Relationships.Any(FromColumn = outerIt) and not IsHidden and not Table.IsHidden", + "FixExpression": "IsHidden = true", + "Compatibility": [ + 1200, + 1400 + ], + "IsValid": false +} +``` + +This rule finds all columns that are used in a relationship (on the "Many"/"From" side), but where the column or its parent table are not hidden. It is recommended that such columns are never shown, as users should filter data using the related (dimension) table instead. So the fix in this case, would be to set the columns IsHidden property to true, which is exactly what the "FixExpression" string above does. To see this in action, right-click any objects that violate the rule, and choose "Generate Fix Script". This puts a small script into the clipboard, which can be pasted into the Advanced Script Editor, from where you can easily review the code and execute it: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298489/9035bab6-26f5-11e7-8134-8502daaf4132.png) + +Remember that you can always undo (CTRL+Z) changes done to a model after script execution. diff --git a/content/localization/de/using-bpa_de.md b/content/localization/de/using-bpa_de.md new file mode 100644 index 00000000..23a76481 --- /dev/null +++ b/content/localization/de/using-bpa_de.md @@ -0,0 +1,104 @@ +--- +uid: using-bpa +title: Using the Best Practice Analyzer +author: Morten Lønskov +updated: 2023-02-09 +--- + +# Best Practice Analyzer + +The Best Practice Analyzer (BPA) lets you define rules on the metadata of your model, to encourage certain conventions and best practices while developing your Power BI or Analysis Services Model. + +## PBA Overview + +The BPA overview shows you all the rules defined in your model that are currently being broken: + +![BPA Overview](~/content/assets/images/common/BPAOverview.png) + +And you will always be able to see in the main UI how many rules you are currently being broken. + +![BPA Overview Line](~/content/assets/images/common/PBAOverviewMenuLine.png) + +Clicking the link (or pressing F10), brings up the full BPA window. + +> [!NOTE]> If you are more into a video walk through then PowerBI.tips has a video with our own Daniel Otykier showing the Best Practice Analyzer in detail here: +> > [!Video https://www.youtube.com/embed/5WnN0NG2nBk] + +### Functionality + +Whenever a change is made to the model, the Best Practice Analyzer scans your model for issues in the background. You can disable this feature under File > Preferences. + +The BPA Window in both TE2 and TE3 allows you to dock the window on one side of your desktop, while keeping the main window in the other side, allowing you to work with your model while you can see BPA issues. + +The Best Practice Analyzer window continuously lists all the **effective rules** on your model as well as the objects that are in violation of each rule. Right-clicking anywhere inside the list or using the toolbar buttons at the top of the window, let's you perform the following actions: + +- **Manage rules...**: This opens the Manage Rules UI, which we will cover below. This UI can also be accessed through the "Tools > Manage BPA Rules..." menu of the main UI. +- **Go to object...**: Choosing this option or double-clicking on an object in the list, takes you to the same object in the main UI. +- **Ignore item/items**: Selecting one or more objects in the list and choosing this option, will apply an annotation to the chosen objects indicating that the Best Practice Analyzer should ignore the objects going forward. If you ignored an object by mistake, toggle the "Show ignored" button at the top of the screen. This will let you unignore an object that was previously ignored. +- **Ignore rule**: If you've selected one or more rules in the list, this option will put an annotation at the model level that indicates, that the selected rule should always be ignored. Again, by toggling the "Show ignored" button, you can unignore rules as well. +- **Generate fix script**: Rules that have an easy fix (meaning the issue can be resolved simply by setting a single property on the object), will have this option enabled. By clicking, you will get a C# script copied into your clipboard. This script can then be subsequently pasted into the [Advanced Scripting](/Advanced-Scripting) area of Tabular Editor, where you can review it before executing it to apply the fix. +- **Apply fix**: This option is also available for rules than have an easy fix, as mentioned above. Instead of copying the script to the clipboard, it will be executed immediately. + +## Managing Best Practice Rules + +If you need to add, remove or modify the rules applying to your model, there's a specific UI for that. You can bring it up by clicking the top-left button on the Best Practice Analyzer window, or by using the "Tools > Manage BPA Rules..." menu item in the main window. + +![BPA Manage Rules](~/content/assets/images/common/BPAOverviewManageRules.png) + +The Manage BPA rules window contains two lists: The top list represents the **collections** of rules that are currently loaded. Selecting a collection in this list, will display all the rules that are defined within this collection in the bottom list. + +![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUp.png) + +### Rule Collections + +By default, three rule collections will show up: + +### [Tabular Editor 3](#tab/TE3Rules) + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%AppData%\..\Local\TabularEditor3\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor3\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +### [Tabular Editor 2](#tab/TE2Rules) + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%AppData%\..\Local\TabularEditor\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +*** + +#### Rule Precedence + +If the same rule (by ID) is located in more than one collection, the order of precedence is from top to bottom, meaning a rule defined within the model takes precedence over a rule, with the same ID, defined on the local machine. This allows you to override existing rules, for example to take model specific conventions into account. + +##### Effective Rules + +At the top of the list, you'll see a special collection called **(Effective rules)**. Selecting this collection will show you the list of rules that actually apply to the currently loaded model, respecting the precedence of rules with identical ID's, as mentioned above. The lower list will indicate which collection a rule belongs to. Also, you will notice that a rule will have its name striked out, if a rule with a similar ID exists in a collection of higher precedence: + +![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUpHigherPrecedence.png) + +#### Adding additional collections + +Tabular Editor provides the possibility of including rules from other sources on a model. If, for example, you have a rules file located on a network share, you can now include that file as a rule collection in the current model. If you have write access to the location of the file, you'll also be able to add/modify/remove rules from the file. Rule collections that are added this way take precedence over rules that are defined within the model. If you add multiple such collections, you can shift them up and down to control their mutual precedence. + +Click the "Add..." button to add a new rule collection to the model. This provides the following options: + +![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUpCreateNewRuleFile.png) + +- **Create new Rule File**: This will create a new, empty, .json file at the specified location, which you can subsequently add rules to. When choosing the file, notice that there is an option for using relative file paths. This is useful when you want to store the rule file in the same code repository as the current model. However, please be aware that a relative rule file reference only works, when the model has been loaded from disk (since there is no working directory when loading a model from an instance of Analysis Services). +- **Include local Rule File**: Use this option if you already have a .json file containing rules, that you want to include in your model. Again, you have the option of using relative file paths, which may be beneficial if the file is located close to the model metadata. If the file is located on a network share (or generally, on a drive different than where the currently loaded model metadata resides), you can only include it using an absolute path. +- **Include Rule File from URL**: This option lets you specify an HTTP/HTTPS URL, that should return a valid rule definition (json). This is useful if you want to include rules from an online source, for example the [Microsoft standard BPA rules](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json) from the [BestPracticeRules GitHub site](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules). Note that rule collections added from online sources will be read-only. + +#### Modifying rules within a collection + +The lower part of the screen will let you add, edit, clone and delete rules within the currently selected collection, provided you have write access to the location where the collection is stored. Also, the "Move to..." button allows you to move or copy the selected rule to another collection, making it easy to manage multiple collections of rules. Please see our article with [samples of rule expressions ](/common/using-bpa-sample-rules-expressions.md) for more information on how to use that. + +#### Rule Description Placeholders + +You can use placeholder values within the Best Practice Rule's description. This provides more customizable descriptions that will appear as tooltips in the Best Practice UI: + +- `%object%` returns a fully qualified DAX reference (if applicable) to the current object +- `%objectname%` returns only the name of the current object +- `%objecttype%` returns the type of the current object + +![BPA Manage Rules UI](~/content/assets/images/common/BPAOverviewRuleDescriptionPlaceHolders.png) diff --git a/content/localization/de/whats-new_de.md b/content/localization/de/whats-new_de.md new file mode 100644 index 00000000..d38185c5 --- /dev/null +++ b/content/localization/de/whats-new_de.md @@ -0,0 +1,15 @@ +--- +uid: whats-new +title: What's new +author: Morten Lønskov +updated: 2023-10-11 +--- + + + + diff --git a/content/localization/de/workspace-mode.partial_de.md b/content/localization/de/workspace-mode.partial_de.md new file mode 100644 index 00000000..a32bed81 --- /dev/null +++ b/content/localization/de/workspace-mode.partial_de.md @@ -0,0 +1,91 @@ +Tabular Editor 3 introduces the concept of **workspace mode** when creating a new model inside the tool, or when loading a Model.bim or Database.json file of an existing model. + +Using workspace mode, Tabular Editor will synchronize your model metadata changes to a **workspace database**, whenever you hit Save (Ctrl+S), while also saving the metadata changes to the file(s) on disk. + +Ideally, each model developer should use their own workspace database to avoid conflicts while developing. + +> [!WARNING] +> Do not enable Git integration on the Fabric workspace that you use to host your Tabular Editor workspace databases. This is to avoid Git conflicts as you develop the model, since Tabular Editor makes changes to the workspace database through the XMLA endpoint, and these changes will not be in sync with any underlying Git branch. + +> [!NOTE] +> For models at compatibility level 1200, 1400 or 1500, we recommend using a local instance of Analysis Services to host the workspace database, such as the one included with [SQL Server Developer Edition 2019](https://www.microsoft.com/en-us/sql-server/sql-server-downloads). + +# Creating a new model + +When you create a new model in Tabular Editor, the "Use workspace database" option is checked by default: + +![New Model](~/content/assets/images/new-model.png) + +Leaving this checked, you will be prompted to connect to an instance of Analysis Services after hitting "OK". This is the instance of Analysis Services to which your workspace database will be deployed. + +> [!IMPORTANT] +> If you plan to deploy your workspace database to the Power BI Service XMLA endpoint, make sure you choose Compatibility Level 1609 (Power BI / Fabric) in the dialog above. + +After entering the Analysis Services server details and (optional) credentials, you are shown a list of all databases currently reciding on the server (or for a Power BI workspace, the list of datasets deployed to the workspace): + +![Select Workspace Database](~/content/assets/images/select-workspace-database.png) + +Tabular Editor suggests a new unique name for your workspace database, based on your Windows user name and the current date and time, but you are free to change this to a more meaningful name. + +After hitting OK, your new model is created and the workspace database is deployed and connected. At this point, hit save (Ctrl+S) to save your model as a Model.bim file. You may also choose the File > Save to Folder... menu item if you intend to store the model metadata in a version control system such as Git. + +![Save New To Folder](~/content/assets/images/save-new-to-folder.png) + +At this point, you are ready to define data sources and add new tables to your model. Every time you subsequently hit Save (Ctrl+S), the workspace database is updated with the changes, and the file/folder you chose previously will be updated as well. + +Information about the workspace database tied to this model is stored in a Tabular Model User Options (.tmuo) file next to the model metadata file. See @user-options for more information. + +# Opening a Model.bim or Database.json file + +If you open an existing Model.bim or Database.json file, Tabular Editor 3 will prompt you whether you want to initiate a workspace database for that file. + +![Connect To Workspace database](~/content/assets/images/connect-to-wsdb.png) + +Your options are: + +- **Yes**: Connect to an instance of Analysis Services and choose an existing workspace database or create a new one. The next time you load the same Model.bim or Database.json file, Tabular Editor will connect to the same workspace database. Tabular Editor will perform a deployment of the Model.bim or Database.json file onto the selected workspace database. +- **No**: Tabular Editor will load the metadata in the file offline with no connectivity to Analysis Services. +- **Don't ask again**: Same as above, but Tabular Editor will no longer ask you to connect to a workspace database the next time you open the same Model.bim or Database.json file. +- **Cancel**: The file is not loaded at all. + +Information about whether to connect to a workspace database for a given model, and which workspace server and database to use is stored in the [Tabular Model User Options (.tmuo) file](xref:user-options). + +> [!WARNING] +> When choosing a workspace database, Tabular Editor 3 will deploy the loaded model metadata onto that workspace database. For this reason, you should never use a production database as your workspace database. Moreover, we recommend using a separate Analysis Services instance/Power BI workspace for your workspace databases. + +# Advantages of workspace mode + +The main advantage of workspace mode, is that it allows Tabular Editor to stay connected to an instance of Analysis Services. In other words, Tabular Editor 3's new [connected features](xref:migrate-from-te2#connected-features) are enabled. But even if you choose not to use these features, it is much easier to synchronize an instance of Analysis Services for purposes of testing your changes. All you have to do is hit Save (CTRL+S). This is similar to when Tabular Editor opens model metadata directly from an instance of Analysis Services, but with workspace mode, the model metadata is simultaneously saved to disk. + +> [!NOTE] +> When a refresh operation is in progress, Tabular Editor cannot synchronize the Analysis Services instance (refresh operations block other write operations). However, hitting Save (CTRL+S) while such an operation is under way will still save the model metadata to disk, while using workspace mode. + +# Disable Workspace Mode for a Model + +If you prefer to _disable workspace mode_ and edit a model file entirely offline, choose one of the methods below. + +## Permanently disable Workspace Mode + +1. Locate the model’s `.tmuo` workspace file (it sits next to your `.bim`, `.tmdl`, or `.json` file) in your File Explorer. + +2. Do **either** of the following: + - **Delete** the `.tmuo` file, **or** + - Open it in a text editor and set: + + ```json + { + "UseWorkspaceDatabase": false + } + ``` + +3. Open the model from the `.bim`, `.tmdl`, or `.json` file as usual. + +Tabular Editor will now stay offline every time you load this model. + +## Disable Workspace Mode for the current session only + +1. In the **Open Semantic Model** dialog, check **Load without workspace database**. + +![Load without Workspace database](~/content/assets/images/load-without-wsdb.png) + +The model loads offline for this session; next time you open it, Workspace Mode is re-enabled unless you repeat these steps. diff --git a/content/localization/de/workspace-mode_de.md b/content/localization/de/workspace-mode_de.md new file mode 100644 index 00000000..00250f63 --- /dev/null +++ b/content/localization/de/workspace-mode_de.md @@ -0,0 +1,16 @@ +--- +uid: workspace-mode +title: Workspace Mode +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# (Walkthrough) Workspace Mode + +[!include[workspace-mode](~/content/te3/workspace-mode.partial.md)] \ No newline at end of file diff --git a/content/localization/de/xmla-as-connectivity_de.md b/content/localization/de/xmla-as-connectivity_de.md new file mode 100644 index 00000000..748fa175 --- /dev/null +++ b/content/localization/de/xmla-as-connectivity_de.md @@ -0,0 +1,189 @@ +--- +uid: xmla-as-connectivity +title: XMLA / Analysis Services connectivity +author: Daniel Otykier +updated: 2024-05-01 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Business + - edition: Enterprise +--- + +# XMLA / Analysis Services connectivity + +Tabular Editor uses the [AMO client library](https://learn.microsoft.com/en-us/analysis-services/amo/developing-with-analysis-management-objects-amo?view=asallproducts-allversions) to connect to the Power BI / Fabric XMLA endpoint or instances of SQL Server or Azure Analysis Services (Tabular). Authentication and authorization is handled by the AMO client library, which means that Tabular Editor does not store any credentials or tokens. Moreover, users will need sufficient permissions to connect to the XMLA endpoint or Analysis Services instance. In most cases, the user must be a member of the Analysis Services server administrator role or have administrative permissions in the Power BI workspace. + +In the following article, we will use the term "semantic model server" to mean the service accessed through the Power BI / Fabric XMLA endpoint or any instance of SQL Server Analysis Services Tabular (SSAS) or Azure Analysis Services (AAS). + +## Connection dialog + +To connect to the semantic model server, go to **File** > **Open** > **Model from DB...**, or press **Ctrl+Shift+O**. + +This will open the **Load Semantic Model from Database** dialog, where you can specify the server name, an XMLA connection string or pick a local SSAS instance from a dropdown. Moreover, you can specify the type of authentication to use. + +> [!NOTE] +> In Tabular Editor 2.x, the **Advanced Options** (for specifying read/write mode and a custom status bar color) are not available. + +![Connect Dialog](~/content/assets/images/connect-dialog.png) + +## Select database + +After you click "OK", Tabular Editor will connect to the semantic model server and retrieve a list of databases that you have access to. Select the database you want to work with, and click "OK". + +## Advanced Connection String Properties + +In all versions of Tabular Editor, you can specify an OLAP connection string in the **Server** textbox, rather than just the server name. + +A typical OLAP connection string looks like this: + +``` +Provider=MSOLAP;Data Source=servername;Initial Catalog=databasename;Integrated Security=SSPI; +``` + +> [!NOTE] +> If the `Initial Catalog` property is specified in the connection string, the **Select Database** dialog will not be shown, and Tabular Editor will connect directly to the specified database. + +OLAP connection strings support many properties in addition to the ones shown above. For a full list of properties, see the [Microsoft documentation](https://learn.microsoft.com/en-us/analysis-services/instances/connection-string-properties-analysis-services?view=asallproducts-allversions). + +In addition to the properties listed in the documentation, AMO connection strings also supports the following properties: + +### Locale Identifier + +You can specify the language to use for the connection by setting the `Locale Identifier` property. The value is a number that corresponds to a specific language. For example, `1033` corresponds to English (United States). + +``` +Provider=MSOLAP;Data Source=servername;Initial Catalog=databasename;Integrated Security=SSPI;Locale Identifier=1033; +``` + +This is useful if you want error messages and other server messages to be in a specific language. If the `Locale Identifier` property is not specified, the language of the client operating system is used. + +Most Analysis Services instances support several languages. See [this page for a full list of locale identifiers (LCID)](https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-fulltext-languages-transact-sql?view=sql-server-ver16). + +## Fabric/Power BI XMLA Settings + +Two admin settings must be switched on to enable the XMLA endpoint in Fabric/Power BI. + +### Enable Tennant XMLA Endpoint + +In the Fabric/Power BI admin portal, the integration setting "Allow XMLA endpoints and Analyze in Excel with on-premises semantic models" must be enabled + +At the tenant level, the setting may be restricted to only certain users. If the setting is restricted in your organization, ensure all required users are allowed to use the XMLA endpoint at the tenant level. + +![Tennant Admin Setting](~/content/assets/images/common/XMLASettings/TennantAdminSetting.png) + +### Enable XMLA Read Write on Capacity + +To use the XMLA endpoint, the workspace that hosts a semantic model must be assigned to a capacity (FSku or Power BI Premium Per User), and the capacity must have XMLA ["Read Write" enabled in the capacity settings.](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#enable-xmla-read-write) + +![Tennant Admin Setting](~/content/assets/images/common/XMLASettings/CapacityAdminSetting.png) + +Read Write is enabled in the Admin Portal by navigating to + +1. Capacity Settings +2. Choosing the type of capacity +3. Selecting the relevant Capacity +4. Navigating to Power BI Workloads and scrolling down to find the XMLA Endpoint setting choosing "Read Write" + +### Workspace Level User Rights + +To edit models using the XMLA endpoint the user's account needs to have access to the workspace as either **Contributor**, **Member** or **Admin**. In the workspace choose 'Manage Access' and add the user account or a Entra ID group that the user belongs to with the required role. For more information on roles in workspaces please see Microsoft's Documentation: [Roles in Workspaces](https://learn.microsoft.com/en-us/fabric/fundamentals/roles-workspaces) + +### Read/Write on Semantic Model + +Ensure that the user's account has Write permission to the semantic model. This can be required even if the user is an admin on the workspace as mentioned above. + +To check that your account has the necessary permissions start by locating the model in the Fabric/Power BI workspace and first click on the hamburger symbol (3 vertical dots) and go to the "Manage permissions" page. + +![Manage Permissions on Semantic Model](~/content/assets/images/common/XMLASettings/ManagePermissionsonSemanticModel.png) + +Validate or give the user's account or the Entra ID group that they belong to either **Workspace Admin**, **Workspace Contributor**, or **Write permission** on the semantic model. For example, in the screenshot below, only the 3 users highlighted in Blue would be able to access the model through Tabular Editor: + +![User Permissions on Semantic Model](~/content/assets/images/common/XMLASettings/UserPermissionsonSemanticModel.png) + +### Set workspace to large semantic models + +To ensure the best experience while editing models using the XMLA endpoint the workspace should have its semantic storage format set to **Large Semantic model storage format**. Go to 'Workspace Settings' in the top right corner of the Fabric/Power BI workspace. First navigate to the 'License info', secondly validate if the storage format is set to large and if not choose 'Edit' to change the storage format. + +![Large Semantic Model Storage Format](~/content/assets/images/common/XMLASettings/LargeSemanticModelStorageFormat.png) + +## Additional Fabric/Power BI settings. + +### Disable Package Refresh + +If another user, other than the semantic model's owner, needs to edit the model through the XMLA endpoint, the security admin setting in Fabric/Power BI called "Block republish and disable package refresh" must be disabled. + +![Tennant Admin Setting](~/content/assets/images/common/XMLASettings/DisablePackageRefresh.png) + +## Unsupported model types + +Several types of models do not support XMLA connections, [listed below](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#unsupported-semantic-models). + +The following semantic models aren't accessible by using the XMLA endpoint. These semantic models won't appear under the workspace in Tabular Editor or any other tool. + +- Semantic models based on a live connection to an Azure Analysis Services or SQL Server Analysis Services model. +- Semantic models based on a live connection to a Power BI semantic model in another workspace. +- Semantic models with Push data by using the REST API. +- Semantic models in My Workspace. +- Excel workbook semantic models + +In Fabric, the default semantic model of a lakehouse or warehouse can be opened/connected to in Tabular Editor, but [not edited](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#considerations-and-limitations). Moreover, some operations that require read access to certain [DMVs](https://learn.microsoft.com/en-us/analysis-services/instances/use-dynamic-management-views-dmvs-to-monitor-analysis-services?view=asallproducts-allversions), such as collecting VertiPaq Analyzer statistics, may not be supported on default semantic models. + +## Troubleshooting XMLA connections + +### Testing a simple connection + +These steps show how to most reliably connect to a Fabric/Power BI semantic model from Tabular Editor. + +1. Connecting to a semantic model in Fabric is through the 'File' > 'Open' > 'Model from DB' (default shortcut Ctrl+Shift+O) + +2. You'll be presented with a dialogue (see below), and you need to put the Power BI connection string into the text box labeled 'Server'. Leave the rest of the options as configured in the screenshot (these are defaults). The connection string is in the form shown below. You can find this connection string in the Service (more details here in this [Microsoft doc in the sections 'Connecting to a Premium Workspace' and 'To get the workspace connection URL'](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#connecting-to-a-premium-workspace) + +![Load Model From Database](~/content/assets/images/common/XMLASettings/LoadModelFromDatabase.png) + +Please copy and paste the connection string directly from the workspace rather than copying from somewhere/someone else or modifying it in any way. + +3. Depending on your machine (if your Windows login is linked to Entra ID or your identity provider) you may be prompted to log in. It's important that the account you use is the one with permission to the workspace. If your organization has multiple tenants or if you have multiple logins, this might not match your Windows login. You should use the exact credential that is shown in the Fabric web UI for your user. + +![Authenticate to FabricPowerBI](~/content/assets/images/common/XMLASettings/AuthenticateToFabricPowerBI.png) + +4. After successful authentication, you'll be presented with a 'Choose database' dialog. Select one and click 'Ok'. + +![Choose Database](~/content/assets/images/common/XMLASettings/ChooseDatabase.png) + +### Set Authentication Type to Microsoft Entra ID + +In some cases the 'Integrated' security option could be different from the user account that should be used for authenticating against the Fabric/Power BI service. The next step to take is to choose the **Microsoft Entra MFA** option in the open model dialog box. + +![Microsoft Entra MFA](~/content/assets/images/common/XMLASettings/LoadModelFromDatabaseMicrosoftEntraID.png) + +Choosing the 'Microsoft Entra MFA' option forces the multifactor authentication and allows for choosing the specific account that is needed to connect to the workspace. + +### Multiple tenants + +If you've double-checked the user name and connection string as above and are still having issues, the next thing to check is whether adding the tenant GUID to the connection string helps. This might be an issue if you belong to multiple tenants. + +The tenant ID can be found directly in Power BI by clicking the top-right question mark and selecting 'About Power BI'. The tenant ID is shown as part of the 'Tenant URL'. Be careful, as the text box is typically too small to display the whole thing in the window in Power BI. Double-click on the URL shown, which will highlight the entire thing, that you can copy and paste. + +The whole URL is not the tenant ID. The tenant ID is the GUID at the end of the string, after "ctid=". So in the screenshot below, my tenant ID starts with "ddec", but yours will be different. Once you have the tenant ID, you can change the connection string that you used above: replace the part of the path that says "myorg" with your tenant ID. + +An example is below. Your tenant ID and your workspace name will be different than those shown. + +- Old: `powerbi://api.powerbi.com/v1.0/myorg/WorkspaceName` +- New: `powerbi://api.powerbi.com/v1.0/eeds65sv-kl25-4d12-990a-770ca3eb6226/WorkspaceName` + +You can also use the tenant name (e.g. `fabrikam.com`) as shown in [this article](https://learn.microsoft.com/en-us/fabric/enterprise/powerbi/service-premium-connect-tools#connecting-to-a-premium-workspace). + +Then, attempt connecting precisely as the instructions in the [Testing a simple connection section](#testing-a-simple-connection) + +### Duplicate names + +There can be issues connecting to a model if the workspace name is a duplicate of another workspace or if the model name is a duplicate name of another model. + +If there are duplicate names, please refer to Microsoft's documentation in the sections ["Duplicate workspace names" and "Duplicate semantic model name"](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#duplicate-workspace-names) to learn how to modify the connection string to address these issues + +### Proxy handling + +Another common cause of connectivity issues is proxies. For more information about this, please review [this article](xref:proxy-settings). diff --git a/content/localization/zh/3_0_10_zh.md b/content/localization/zh/3_0_10_zh.md new file mode 100644 index 00000000..a3d2bdcb --- /dev/null +++ b/content/localization/zh/3_0_10_zh.md @@ -0,0 +1,50 @@ +# Tabular Editor 3.0.10 + +- Download [Tabular Editor 3.0.10 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.10](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.10 + +- Updated AMO/TOM to version [19.22.5](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Allow incremental search in "Select Item" dialogs, such as when adding tables to a diagram,see issue [#167](https://github.com/TabularEditor/TabularEditor3/issues/167). + +## Bugfixes in 3.0.10 + +- Fixed an issue with TOM Explorer losing current selection when trying to drag an object into a text editor +- Fixed an issue with the semantic analyzer causing false "A single value for column ... cannot be determined" errors, when a DAX expression somewhere in the model used ALLEXCEPT, see [#140](https://github.com/TabularEditor/TabularEditor3/issues/140). +- Macro recorder now works for calculation item expressions, format string expressions, measure detail rows expressions, and more, see [#143](https://github.com/TabularEditor/TabularEditor3/issues/143). +- Added the `Model.AddCalculationGroupTable()` method for C# script purposes. This also fixes issue [#144](https://github.com/TabularEditor/TabularEditor3/issues/144). +- DAX Script should no longer add extra indentation, see [#165](https://github.com/TabularEditor/TabularEditor3/issues/165). +- Fixed Pivot Grid connectivity issues, see [#166](https://github.com/TabularEditor/TabularEditor3/issues/166). +- Fixed issue with VertiPaq Analyzer data types, see [#169](https://github.com/TabularEditor/TabularEditor3/issues/169). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/zh/3_0_1_zh.md b/content/localization/zh/3_0_1_zh.md new file mode 100644 index 00000000..434caaaa --- /dev/null +++ b/content/localization/zh/3_0_1_zh.md @@ -0,0 +1,53 @@ +# Tabular Editor 3.0.1 + +- Download [Tabular Editor 3.0.1](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x86.msi) +- Download [Tabular Editor 3.0.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +## Known issues + +- Table Import Wizard didn't make it to this release. It will be available in 3.0.3 which is coming out very soon. As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## New features in 3.0.1: + +(The list below compares Tabular Editor 3.0.1 with the previous beta release) + +- Updated [EULA](https://tabulareditor.com/tabular-editor-software-license-agreement_ver-1-0/) and added [ThirdPartyNotices.txt](https://github.com/TabularEditor/TabularEditor3/blob/master/ThirdPartyNotices.txt) to installer. +- Schema Compare now also works with Provider (Legacy) Data Sources and Query partitions +- The first time you use the "Format DAX" button, Tabular Editor will ask for your consent to send DAX code to the www.daxformatter.com web service (an upcoming version of Tabular Editor 3 will feature offline DAX code formatting, making this consent obsolete). +- Improved some text strings on the Activation Wizard, and allow entering a new license key if the current license has expired. +- Added Connection String editor to property grid +- Added preferences for globally ignoring certain types of schema differences under Tools > Preferences > Schema Compare. + +## Bugfixes in 3.0.1: + +- Fixed issue [#5](https://github.com/TabularEditor/TabularEditor3/issues/5) +- Fixed issue [#6](https://github.com/TabularEditor/TabularEditor3/issues/6) +- Fixed issue [#7](https://github.com/TabularEditor/TabularEditor3/issues/7) +- Fixed issue [#8](https://github.com/TabularEditor/TabularEditor3/issues/8) +- Fixed issue [#9](https://github.com/TabularEditor/TabularEditor3/issues/9) +- Fixed issue [#13](https://github.com/TabularEditor/TabularEditor3/issues/13) +- Fixed a mapping issue with Update Table Schema (PQ type `decimal.type` now maps to Tabular type `Decimal` instead of `Double`). diff --git a/content/localization/zh/3_0_2_zh.md b/content/localization/zh/3_0_2_zh.md new file mode 100644 index 00000000..c20c3f38 --- /dev/null +++ b/content/localization/zh/3_0_2_zh.md @@ -0,0 +1,51 @@ +# Tabular Editor 3.0.2 + +- Download [Tabular Editor 3.0.2](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x86.msi) +- Download [Tabular Editor 3.0.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +## Known issues + +- Table Import Wizard didn't make it to this release. It will be available in 3.0.3 which is coming out very soon. As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## New features in 3.0.2: + +- You can now change your license key from the Help > About Tabular Editor dialog (option available only when no model is currently loaded). +- Added a "Revert" button in the main toolbar and File menu (you may need to restore the Default workspace to see it). When clicked, this button reloads the TOM from the connected source (Power BI model or Analysis Services database). It can be used to manually synchronize changes between the two, if the automatic option is disabled under Tools > Preferences. + +## Bugfixes in 3.0.2: + +- DAX Editor support for the TEXT / INTEGER keywords in the PATHITEM / PATHITEMREVERSE DAX functions. +- DAX Editor preferences are now persisted between sessions (see [#23](https://github.com/TabularEditor/TabularEditor3/issues/23)) +- Various DAX Editor autocomplete / calltip improvements. +- Fixed issue [#14](https://github.com/TabularEditor/TabularEditor3/issues/14) (object errors not shown in TOM Explorer) +- Support for KMeansClustering DAX extension function. +- Fixed bug with DAX Parser reporting errors on comparing a value with BLANK() in the SWITCH function. +- A few minor visual updates +- Fixed a crash that would occur when trying to execute a DAX script that edits/adds objects that are unsupported on a Power BI Desktop file (for example, [we cannot yet add calculated tables or calculated columns through external tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools)) +- DetailRowsExpressions are now editable on measures when connected to a Power BI Desktop file. +- Fixed a bug with SciLexer.dll that caused a crash immediately upon startup in some cases. +- Column names in the DAX query are now shown as-is (no adding of spaces before capital letters diff --git a/content/localization/zh/3_0_3_zh.md b/content/localization/zh/3_0_3_zh.md new file mode 100644 index 00000000..8c973acb --- /dev/null +++ b/content/localization/zh/3_0_3_zh.md @@ -0,0 +1,51 @@ +# Tabular Editor 3.0.3 + +- Download [Tabular Editor 3.0.3](https://cdn.tabulareditor.com/files/TabularEditor.3.0.3.x86.msi) +- Download [Tabular Editor 3.0.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.3.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## New features in 3.0.3: + +- Right-clicking on an item in the Processing View now lets you requeue that item or, if the item represents a single table, opens a data preview of that table. + +## Bugfixes in 3.0.3: + +- When the semantic analyzer detects an error on a calculated column/calculated table, it no longer modifies the columns on that table (this was previously causing relationships to be dropped in some circumstances) +- Fixed an issue with enabled-state of certain controls on the Find/Replace dialog +- Several bugfixes based on telemetry and error reports, such as: + - Copy/pasting columns with lineage tags now works + - Pasting a table over an existing one when the table is renamed no longer causes a crash + - "Revert" button now reconnects to AS before refresing the local TOM, instead of causing a crash + - Right-clicking in the property grid while it is empty no longer causes a crash + - And many, many others... +- Fixed MRUs not being properly saved for the "Server" dropdown +- Fixed several issues with the Workspace Mode not properly loading data source override values from the User Options file. See [#28](https://github.com/TabularEditor/TabularEditor3/issues/28). +- Fixed and improved several "phantom" DAX semantic errors (support for ROLLUPADDISSUBTOTAL, COUNTROWS with 0 arguments, etc.) +- Improved autocomplete / calltips for several DAX functions (TOPN, TOPNPERLEVEL, interval parameter for DATEADD/DATESINPERIOD/PARALLELPERIOD), after RETURN keyword, etc. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/zh/3_0_4_zh.md b/content/localization/zh/3_0_4_zh.md new file mode 100644 index 00000000..a5109c95 --- /dev/null +++ b/content/localization/zh/3_0_4_zh.md @@ -0,0 +1,55 @@ +# Tabular Editor 3.0.4 + +- Download [Tabular Editor 3.0.4](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x86.msi) +- Download [Tabular Editor 3.0.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Bugfixes in 3.0.4: + +- Refreshing the Best Practice Analyzer no longer causes a crash + +## New features in 3.0.3: + +- Right-clicking on an item in the Processing View now lets you requeue that item or, if the item represents a single table, opens a data preview of that table. + +## Bugfixes in 3.0.3: + +- When the semantic analyzer detects an error on a calculated column/calculated table, it no longer modifies the columns on that table (this was previously causing relationships to be dropped in some circumstances) +- Fixed an issue with enabled-state of certain controls on the Find/Replace dialog +- Several bugfixes based on telemetry and error reports, such as: + - Copy/pasting columns with lineage tags now works + - Pasting a table over an existing one when the table is renamed no longer causes a crash + - "Revert" button now reconnects to AS before refresing the local TOM, instead of causing a crash + - Right-clicking in the property grid while it is empty no longer causes a crash + - And many, many others... +- Fixed MRUs not being properly saved for the "Server" dropdown +- Fixed several issues with the Workspace Mode not properly loading data source override values from the User Options file. See [#28](https://github.com/TabularEditor/TabularEditor3/issues/28). +- Fixed and improved several "phantom" DAX semantic errors (support for ROLLUPADDISSUBTOTAL, COUNTROWS with 0 arguments, etc.) +- Improved autocomplete / calltips for several DAX functions (TOPN, TOPNPERLEVEL, interval parameter for DATEADD/DATESINPERIOD/PARALLELPERIOD), after RETURN keyword, etc. + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/zh/3_0_5_zh.md b/content/localization/zh/3_0_5_zh.md new file mode 100644 index 00000000..60c2bf50 --- /dev/null +++ b/content/localization/zh/3_0_5_zh.md @@ -0,0 +1,45 @@ +# Tabular Editor 3.0.5 + +- Download [Tabular Editor 3.0.5](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x86.msi) +- Download [Tabular Editor 3.0.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x64.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.5: + +- Diagram view now looks much better (in both light and dark themes), and relationship routes are updated while tables are dragged around on the canvas. + +## Bugfixes in 3.0.5: + +- Expression Editor, if hidden, doesn't automatically pop up when selecting a diagram item / TOM explorer item. Instead, double-click on the item in the TOM Explorer or bring it back using the View menu (see issue [#43](https://github.com/TabularEditor/TabularEditor3/issues/43). +- DAX parser should no longer report circular dependencies when there are none (see issue [#63](https://github.com/TabularEditor/TabularEditor3/issues/63) and [#64](https://github.com/TabularEditor/TabularEditor3/issues/64)) +- Fixed an issue with DAX parser determination of SourceColumn values on CalculatedTableColumns, which could cause columns to be deleted (and by extension, relationships) upon model load. +- DAX parser now shows an error if certain keywords are used as DAX variables (which is not allowed). See issue [#58](https://github.com/TabularEditor/TabularEditor3/issues/58). +- Hitting ':' when starting a search, now immediately switches to "Entire Model" and Dynamic LINQ mode. +- Dynamic LINQ now also search partitions and calculation group items, see issue [#70](https://github.com/TabularEditor/TabularEditor3/issues/70). + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- \*Schedule data refreshes +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI diff --git a/content/localization/zh/3_0_6_zh.md b/content/localization/zh/3_0_6_zh.md new file mode 100644 index 00000000..99868dec --- /dev/null +++ b/content/localization/zh/3_0_6_zh.md @@ -0,0 +1,36 @@ +# Tabular Editor 3.0.6 + +- Download [Tabular Editor 3.0.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.6](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.6: + +- Support for consultancy licenses. [More details](https://tabulareditor.com/consultancy-edition/). +- DAX queries now display row counts and timings (see issue [#10](https://github.com/TabularEditor/TabularEditor3/issues/10)) +- DAX queries are now limited to 1000 rows by default, to prevent timeouts/memory issues. This limit can be changed in Tools > Preferences > Data Browsing > DAX Query. +- Columns in the DAX query results can now be sorted and filtered (local sorting/filtering only). See issue [#60](https://github.com/TabularEditor/TabularEditor3/issues/60) +- Data from grids (DAX query results, Table Preview, etc.) can now be copied to the clipboard +- When copying a DAX expression the syntax highlighting is now preserved on the clipboard. See issue [#80](https://github.com/TabularEditor/TabularEditor3/issues/80). +- When adding a calculated table through a C# script expression, the semantic analyzer now immediately adds the calculated table columns to the table based on the DAX expression (instead of after script execution). +- Updated TOM client library to v. 19.22.0.1 +- Portable versions (.zip) now available. Remember that you have to [manually register Tabular Editor 3 with Power BI Desktop](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#registering-external-tools) if using the portable version. + +## Bugfixes in 3.0.6: + +- Can now use the `EvaluateDax`, `ExecuteCommand`, `SelectTable`, `SelectMeasure` etc. methods in C# scripts (similar to Tabular Editor 2.x), see [#44](https://github.com/TabularEditor/TabularEditor3/issues/44). +- The `CustomAction` C# script method now works properly, see [#79](https://github.com/TabularEditor/TabularEditor3/issues/79). +- Better reestablishing of connections to AS (should see fewer "connection lost" crashes) +- Best Practice Analyzer can now be instantiated through a C# script: `new TabularEditor.Shared.BPA.Analyzer();` - this is different than in Tabular Editor 2.x in which the Analyzer class resided in a different namespace. See issue [#45](https://github.com/TabularEditor/TabularEditor3/issues/45) +- Copy operations are now supported when folders are selected, see [#84](https://github.com/TabularEditor/TabularEditor3/issues/84) +- Improved filtering of date columns in the Table Preview, see [#77](https://github.com/TabularEditor/TabularEditor3/issues/77) +- Fixed a bug where semantic engine feature overrides were not in effect, see [#62](https://github.com/TabularEditor/TabularEditor3/issues/62). diff --git a/content/localization/zh/3_0_7_zh.md b/content/localization/zh/3_0_7_zh.md new file mode 100644 index 00000000..e3edd498 --- /dev/null +++ b/content/localization/zh/3_0_7_zh.md @@ -0,0 +1,32 @@ +# Tabular Editor 3.0.7 + +- Download [Tabular Editor 3.0.7 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.7](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.7 + +- Allow using a custom compiler for C# scripts, see issue [#97](https://github.com/TabularEditor/TabularEditor3/issues/97) +- Auto date/time column warnings can now be hidden (under Tools > Preferences > Tabular Editor > Hide auto/date time warnings). See issue [#99](https://github.com/TabularEditor/TabularEditor3/issues/99) + +## Bugfixes in 3.0.7 + +- "Standard Edition" has been renamed to "Business Edition" +- Fixed an issue with the semantic analyzer which would sometimes cause stack overflow exceptions and crash the tool (see issue [#95](https://github.com/TabularEditor/TabularEditor3/issues/95)). +- Fixed an issue with the semantic analyzer which would sometimes report non-existing circular dependency errors. +- Semantic analyzer now supports the SUBSTITUTEWITHINDEX DAX function +- Fixed an issue with some of the JOIN DAX functions (NATURALINNERJOIN, etc.) which would sometimes return the wrong set of columns (see issue [#103](https://github.com/TabularEditor/TabularEditor3/issues/103)) +- Autocomplete now only shows relevant columns/tables in RELATED and RELATEDTABLE (see issue [#112](https://github.com/TabularEditor/TabularEditor3/issues/112)) +- Autocomplete now works with ORDER BY (see issue [#53](https://github.com/TabularEditor/TabularEditor3/issues/53)) +- Editor now longer disappears when creating a folder, copy/pasting a single object, etc. (see issue [#90](https://github.com/TabularEditor/TabularEditor3/issues/90)) +- All relevant context menu items should now show for calculation groups (including refresh options), see issue [#100](https://github.com/TabularEditor/TabularEditor3/issues/100) +- Fixed an issue with DAX queries now returning any results when an ORDER BY statement was added to the query, see issue [#108](https://github.com/TabularEditor/TabularEditor3/issues/108) diff --git a/content/localization/zh/3_0_8_zh.md b/content/localization/zh/3_0_8_zh.md new file mode 100644 index 00000000..be62156c --- /dev/null +++ b/content/localization/zh/3_0_8_zh.md @@ -0,0 +1,59 @@ +# Tabular Editor 3.0.8 + +- Download [Tabular Editor 3.0.8 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.8](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Improvements in 3.0.8 + +- Added option for executing only selected EVALUATE statements in DAX queries (shortcut Shift+F5), see issue [#47](https://github.com/TabularEditor/TabularEditor3/issues/47). +- Allow using shortcut Ctrl+/ to comment/uncomment code, see issue [#46](https://github.com/TabularEditor/TabularEditor3/issues/46). You can also change the comment style (-- or //) under Tools > Preferences > DAX Editor > General. +- DAX Script will now also script measure KPIs, calculated columns and calculated tables in the current selection. We also add comments to make the code more readable (this can be disabled under Tools > Preferences > DAX Scripting). +- There is now an option to automatically add a line break character at the beginning of all DAX expressions, when working against a Power BI model. This makes the code look better in the Power BI Desktop formula bar. This can be disabled under Tools > Preferences >, see issue [#26](https://github.com/TabularEditor/TabularEditor3/issues/26). +- When adding Windows AD Role Members, the Directory Object Picker dialog now appears, see issue [#152](https://github.com/TabularEditor/TabularEditor3/issues/152). +- The "Add Deployment Metadata" option is now available under Tools > Preferences > Model Deployment. +- Pivot Grid improvements: + - You can now drag TOM Explorer objects into all areas of the Pivot Grid, see [#49](https://github.com/TabularEditor/TabularEditor3/issues/49). + - Added TOM Explorer context menu option for adding measures, columns and hierarchies directly to a Pivot Grid. + - Added "Show field" button in Pivot Grid, to display all available fields on the connected database. + - Added a "Go to object" right-click menu option in the Pivot Grid. +- Relationship errors (ambiguous paths, invalid state, etc.) are now detected and indicated in the TOM Explorer + +## Bugfixes in 3.0.8 + +- Changed color of the "Execute query" exclamation mark from red to green. +- Fixed a crash when reversing relationships through the Diagram View +- Fixed an issue with the Relationship Editor where changes are not correctly saved +- Fixed a crash which would occur when TE3 is launched from PBI Desktop while an instance of SSAS is running on the local machine. +- Fixed a bug that prevented creation of new models with a workspace database on Power BI XMLA endpoint. +- Fixed a bug where code selection was cleared after using the Comment action. +- Deployment Wizard now remembers the last server used. +- DAX Script calculated column expressions should no longer give false semantic error messages about missing row context. +- Fixed a bug preventing Business Edition license holders to use the Visual Studio Integrated Workspace server. +- Fixed "successful" typo. +- Fixed an issue with auto formatter sometimes duplicating code when entering a right-parenthesis. +- Added "Save Model.bim backup" option in UI, see issue [#37](https://github.com/TabularEditor/TabularEditor3/issues/37). +- Perspective selection should no longer get "stuck", see issue [#52](https://github.com/TabularEditor/TabularEditor3/issues/52). +- Property grid now properly displays date formatting examples, see issue [#86](https://github.com/TabularEditor/TabularEditor3/issues/86). +- Fixed highlight color when searching, see issue [#98](https://github.com/TabularEditor/TabularEditor3/issues/98). +- "Find All" now works as expected, see issue [#107](https://github.com/TabularEditor/TabularEditor3/issues/107). +- Calculation Item that causes measure data types to decay to Variant is now correctly picked up, see issue [#111](https://github.com/TabularEditor/TabularEditor3/issues/111). +- Fixed false semantic error when using EARLIER in a filter, see issue [#118](https://github.com/TabularEditor/TabularEditor3/issues/118). +- Fixed false semantic error when using KEEPFILTERS, see issue [#122](https://github.com/TabularEditor/TabularEditor3/issues/122). +- Blank (or comment only) Detail Rows Expression no longer causes an error indication, see issue [#127](https://github.com/TabularEditor/TabularEditor3/issues/127). +- Fixed multiple credential prompts, see issue [#131](https://github.com/TabularEditor/TabularEditor3/issues/131). +- Fix vpax import issue, see issue [#133](https://github.com/TabularEditor/TabularEditor3/issues/133). +- Fixed property grid behavior when selecting a display folder, see issue [#134](https://github.com/TabularEditor/TabularEditor3/issues/134). +- Diagram no longer deletes table when hitting "Delete" (remove from diagram instead), see issue [#139 ](https://github.com/TabularEditor/TabularEditor3/issues/139). +- Pivot Grid should now handle date fields correctly, see issue [#142](https://github.com/TabularEditor/TabularEditor3/issues/142). +- Copying a calculation group will no longer create measures with duplicated names, and the precedence number will also be changed to ensure uniqueness, see issue [#155](https://github.com/TabularEditor/TabularEditor3/issues/155) and [#156](https://github.com/TabularEditor/TabularEditor3/issues/156). +- Uncomment Code button now works for lines that have indentation, see [#159](https://github.com/TabularEditor/TabularEditor3/issues/159). diff --git a/content/localization/zh/3_0_9_zh.md b/content/localization/zh/3_0_9_zh.md new file mode 100644 index 00000000..02494fd5 --- /dev/null +++ b/content/localization/zh/3_0_9_zh.md @@ -0,0 +1,63 @@ +# Tabular Editor 3.0.9 + +- Download [Tabular Editor 3.0.9 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.0.9](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## Known issues + +- Table Import Wizard didn't make it to this release due to some high-priority bugs that had to be fixed. It will be available ASAP! As a work around, simply create a new table and specify the partition query (SQL or M). Then, right-click the table and choose "Update Table Schema..." to import columns. +- See [roadmap](https://github.com/TabularEditor/TabularEditor3/issues/12) for more information. + +## Bugfixes in 3.0.9 + +- Included a missing DLL which would otherwise cause a crash when trying to add role members. + +## Improvements in 3.0.8 + +- Added option for executing only selected EVALUATE statements in DAX queries (shortcut Shift+F5), see issue [#47](https://github.com/TabularEditor/TabularEditor3/issues/47). +- Allow using shortcut Ctrl+/ to comment/uncomment code, see issue [#46](https://github.com/TabularEditor/TabularEditor3/issues/46). You can also change the comment style (-- or //) under Tools > Preferences > DAX Editor > General. +- DAX Script will now also script measure KPIs, calculated columns and calculated tables in the current selection. We also add comments to make the code more readable (this can be disabled under Tools > Preferences > DAX Scripting). +- There is now an option to automatically add a line break character at the beginning of all DAX expressions, when working against a Power BI model. This makes the code look better in the Power BI Desktop formula bar. This can be disabled under Tools > Preferences >, see issue [#26](https://github.com/TabularEditor/TabularEditor3/issues/26). +- When adding Windows AD Role Members, the Directory Object Picker dialog now appears, see issue [#152](https://github.com/TabularEditor/TabularEditor3/issues/152). +- The "Add Deployment Metadata" option is now available under Tools > Preferences > Model Deployment. +- Pivot Grid improvements: + - You can now drag TOM Explorer objects into all areas of the Pivot Grid, see [#49](https://github.com/TabularEditor/TabularEditor3/issues/49). + - Added TOM Explorer context menu option for adding measures, columns and hierarchies directly to a Pivot Grid. + - Added "Show field" button in Pivot Grid, to display all available fields on the connected database. + - Added a "Go to object" right-click menu option in the Pivot Grid. +- Relationship errors (ambiguous paths, invalid state, etc.) are now detected and indicated in the TOM Explorer + +## Bugfixes in 3.0.8 + +- Changed color of the "Execute query" exclamation mark from red to green. +- Fixed a crash when reversing relationships through the Diagram View +- Fixed an issue with the Relationship Editor where changes are not correctly saved +- Fixed a crash which would occur when TE3 is launched from PBI Desktop while an instance of SSAS is running on the local machine. +- Fixed a bug that prevented creation of new models with a workspace database on Power BI XMLA endpoint. +- Fixed a bug where code selection was cleared after using the Comment action. +- Deployment Wizard now remembers the last server used. +- DAX Script calculated column expressions should no longer give false semantic error messages about missing row context. +- Fixed a bug preventing Business Edition license holders to use the Visual Studio Integrated Workspace server. +- Fixed "successful" typo. +- Fixed an issue with auto formatter sometimes duplicating code when entering a right-parenthesis. +- Added "Save Model.bim backup" option in UI, see issue [#37](https://github.com/TabularEditor/TabularEditor3/issues/37). +- Perspective selection should no longer get "stuck", see issue [#52](https://github.com/TabularEditor/TabularEditor3/issues/52). +- Property grid now properly displays date formatting examples, see issue [#86](https://github.com/TabularEditor/TabularEditor3/issues/86). +- Fixed highlight color when searching, see issue [#98](https://github.com/TabularEditor/TabularEditor3/issues/98). +- "Find All" now works as expected, see issue [#107](https://github.com/TabularEditor/TabularEditor3/issues/107). +- Calculation Item that causes measure data types to decay to Variant is now correctly picked up, see issue [#111](https://github.com/TabularEditor/TabularEditor3/issues/111). +- Fixed false semantic error when using EARLIER in a filter, see issue [#118](https://github.com/TabularEditor/TabularEditor3/issues/118). +- Fixed false semantic error when using KEEPFILTERS, see issue [#122](https://github.com/TabularEditor/TabularEditor3/issues/122). +- Blank (or comment only) Detail Rows Expression no longer causes an error indication, see issue [#127](https://github.com/TabularEditor/TabularEditor3/issues/127). +- Fixed multiple credential prompts, see issue [#131](https://github.com/TabularEditor/TabularEditor3/issues/131). +- Fix vpax import issue, see issue [#133](https://github.com/TabularEditor/TabularEditor3/issues/133). +- Fixed property grid behavior when selecting a display folder, see issue [#134](https://github.com/TabularEditor/TabularEditor3/issues/134). +- Diagram no longer deletes table when hitting "Delete" (remove from diagram instead), see issue [#139 ](https://github.com/TabularEditor/TabularEditor3/issues/139). +- Pivot Grid should now handle date fields correctly, see issue [#142](https://github.com/TabularEditor/TabularEditor3/issues/142). +- Copying a calculation group will no longer create measures with duplicated names, and the precedence number will also be changed to ensure uniqueness, see issue [#155](https://github.com/TabularEditor/TabularEditor3/issues/155) and [#156](https://github.com/TabularEditor/TabularEditor3/issues/156). +- Uncomment Code button now works for lines that have indentation, see [#159](https://github.com/TabularEditor/TabularEditor3/issues/159). diff --git a/content/localization/zh/3_10_0_zh.md b/content/localization/zh/3_10_0_zh.md new file mode 100644 index 00000000..06fda77e --- /dev/null +++ b/content/localization/zh/3_10_0_zh.md @@ -0,0 +1,98 @@ +--- +uid: release-3-10-0 +--- + +# Tabular Editor 3.10.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.10.0 downloads: + +- Download [Tabular Editor 3.10.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.10.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.10.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x64.exe) | `478827F7C7096DA96C93CCA2F2232062E8B01E80AA4B698B9F9381C1DA35750B` | +| [TabularEditor.3.10.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.msi) | `4C07502FAB83777D00E8350430B8AA4C34AA0D5A7A134D3224E31C4D856D9156` | +| [TabularEditor.3.10.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.zip) | `8E8B34B768811B814F8254F11BA454EA7D5008F12E0599A9B0F4E159AC6830D0` | +| [TabularEditor.3.10.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x86.exe) | `E7F0D6DA19741C9DB0F75007FCA2302B0B12EF9AFD574F124B969EDC4A301B42` | +| [TabularEditor.3.10.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.msi) | `4D1E832080D763A83EDD0E930204EA86B0D7B946D46CB26593E7BDEE22967C86` | +| [TabularEditor.3.10.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.zip) | `8212D1E12E543AFDB50B0DEA592F9324E4F8F22D63CA067436A0DC3EEF024112` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.10.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/08/23/tabular-editor-3-august-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor now supports adding tables to [Direct Lake datasets](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview) through the Import Table Wizard. Moreover, you can update the schema of existing tables the usual way. Tabular Editor utilises the [SQL endpoint of your Fabric Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-endpoint) to obtain the table schemas. We've also published a [blog post on DirectLake, if you want to learn more](https://blog.tabulareditor.com/2023/08/23/fabric-direct-lake-dataset/). + +> [!NOTE] +> This version of Tabular Editor will let you import tables / update table schemas on models that already have a Direct Lake connection. The Import Table Wizard does not yet support creating a new Direct Lake connection on an empty model. This will be added in a future release. + +> [!WARNING] +> Once you make any changes to a Direct Lake dataset through the XMLA endpoint, you will [no longer be able to open that dataset in the Web Modelling feature of Fabric](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#enable-xmla-read-write:~:text=Direct%20Lake%20datasets%20created%20or%20modified%20by%20using%20XMLA%2Dbased%20tools%20cannot%20be%20opened%20in%20the%20Web%20modelling%20feature.). + +- C# scripts now support [preprocessor directives](xref:csharp-scripts#compatibility) to determine which version of Tabular Editor you're using. This allows you to write scripts that are compatible with both Tabular Editor 2 and Tabular Editor 3. + +## Improvements in 3.10.0 + +- We're now using using the latest version of [AMO/TOM](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/). This update adds support for Binary XML, which should help speed up XMLA operations. More details in this [Microsoft blog post](https://powerbi.microsoft.com/en-us/blog/improving-the-communication-performance-of-xmla-based-tools/). +- We also updated [TMDL to preview-3](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.65.12.3-TmdlPreview), which includes a number of bugfixes. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +- When cloning objects, we now add the suffix "-Copy" instead of " Copy", to reduce the risk of leaving trailing blanks in object names, see [#940](https://github.com/TabularEditor/TabularEditor3/issues/940). +- The auto-complete popup now automatically adjusts its width to fit the widest item inside of it. See [#965](https://github.com/TabularEditor/TabularEditor3/issues/965). +- When a backup .bim file is saved for a Power BI Desktop model, we now use the name of the .pbix file, instead of the database GUID, see [#958](https://github.com/TabularEditor/TabularEditor3/issues/958). +- Table Preview performance improvements. + +## Bugfixes in 3.10.0 + +- Fixed a bug that prevented Synonyms (linguistic metadata) to be persisted, when using Save to Folder. +- Fixed a bug where the backup .bim file had an incorrect timstamp, see [#967](https://github.com/TabularEditor/TabularEditor3/issues/967). +- Fixed a bug that prevented the user from cancelling the deployment when the backup save fails for any reason. +- Find Panel on Table Preview should now generate valid DAX search expressions behind the scenes, see [#955](https://github.com/TabularEditor/TabularEditor3/issues/955). +- Fixed an issue that caused the "Go to definition (F12)" action to be disabled when the caret was placed on a DAX function, see [#962](https://github.com/TabularEditor/TabularEditor3/issues/962). +- Fixed a bug that prevented loading models from .vpax files in some cases. +- The height of the "result count" panel in DAX queries should now automatically adjust to fit its content. +- The Properties grid now correctly displays multi-line expressions that happen to start with one or more line breaks, just like when editing the expression inside the grid. +- Fixed a bug that could cause Pivot Grid to get stuck in an infinite error-message loop, when columns that were added to the Pivot Grid were deleted from the remote model. +- Fixed a bug where macros added to the menu bar, would stop working after a restart of Tabular Editor. +- Fixed a bug where attempting to perform a Schema Update on multiple tables originating from the same source table, would fail for all except one. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_10_1_zh.md b/content/localization/zh/3_10_1_zh.md new file mode 100644 index 00000000..73af292a --- /dev/null +++ b/content/localization/zh/3_10_1_zh.md @@ -0,0 +1,102 @@ +--- +uid: release-3-10-1 +--- + +# Tabular Editor 3.10.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.10.1 downloads: + +- Download [Tabular Editor 3.10.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.10.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.10.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x64.exe) | `67734FC61247C18E63F29AA4B18D73F05971D688B691F4DBD8246EB15052D999` | +| [TabularEditor.3.10.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.msi) | `3A1967110B8649D06E821F36744199302258B05AD9479F8DE688BEFDAE794E6F` | +| [TabularEditor.3.10.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.zip) | `689ED9836950660B32BB9C29BC91B44B7EA339B8B128E57E2A5A4FCF824B2A04` | +| [TabularEditor.3.10.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x86.exe) | `D7F75E8DDC6F08AE513977AB191F93BC876C94C1555C03CFDD340C3A53CD8F5B` | +| [TabularEditor.3.10.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.msi) | `59CCB76191C3A8A23093CB744B3D9681F5057318EAF4919183182D8557209C9B` | +| [TabularEditor.3.10.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.zip) | `5EDF7A7C37BB5F8F2C78593CA7324B50A6F28DD38334085844478AD44266B8DE` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.10.1 + +- Fixed a bug that caused a crash whenever the user attempted to type a DAX expression in the DAX Debugger's Watch Expression window. + +## New in 3.10.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/08/23/tabular-editor-3-august-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor now supports adding tables to [Direct Lake datasets](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview) through the Import Table Wizard. Moreover, you can update the schema of existing tables the usual way. Tabular Editor utilises the [SQL endpoint of your Fabric Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-endpoint) to obtain the table schemas. We've also published a [blog post on DirectLake, if you want to learn more](https://blog.tabulareditor.com/2023/08/23/fabric-direct-lake-dataset/). + +> [!NOTE] +> This version of Tabular Editor will let you import tables / update table schemas on models that already have a Direct Lake connection. The Import Table Wizard does not yet support creating a new Direct Lake connection on an empty model. This will be added in a future release. + +> [!WARNING] +> Once you make any changes to a Direct Lake dataset through the XMLA endpoint, you will [no longer be able to open that dataset in the Web Modelling feature of Fabric](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#enable-xmla-read-write:~:text=Direct%20Lake%20datasets%20created%20or%20modified%20by%20using%20XMLA%2Dbased%20tools%20cannot%20be%20opened%20in%20the%20Web%20modelling%20feature.). + +- C# scripts now support [preprocessor directives](xref:csharp-scripts#compatibility) to determine which version of Tabular Editor you're using. This allows you to write scripts that are compatible with both Tabular Editor 2 and Tabular Editor 3. + +## Improvements in 3.10.0 + +- We're now using using the latest version of [AMO/TOM](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/). This update adds support for Binary XML, which should help speed up XMLA operations. More details in this [Microsoft blog post](https://powerbi.microsoft.com/en-us/blog/improving-the-communication-performance-of-xmla-based-tools/). +- We also updated [TMDL to preview-3](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.65.12.3-TmdlPreview), which includes a number of bugfixes. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +- When cloning objects, we now add the suffix "-Copy" instead of " Copy", to reduce the risk of leaving trailing blanks in object names, see [#940](https://github.com/TabularEditor/TabularEditor3/issues/940). +- The auto-complete popup now automatically adjusts its width to fit the widest item inside of it. See [#965](https://github.com/TabularEditor/TabularEditor3/issues/965). +- When a backup .bim file is saved for a Power BI Desktop model, we now use the name of the .pbix file, instead of the database GUID, see [#958](https://github.com/TabularEditor/TabularEditor3/issues/958). +- Table Preview performance improvements. + +## Bugfixes in 3.10.0 + +- Fixed a bug that prevented Synonyms (linguistic metadata) to be persisted, when using Save to Folder. +- Fixed a bug where the backup .bim file had an incorrect timstamp, see [#967](https://github.com/TabularEditor/TabularEditor3/issues/967). +- Fixed a bug that prevented the user from cancelling the deployment when the backup save fails for any reason. +- Find Panel on Table Preview should now generate valid DAX search expressions behind the scenes, see [#955](https://github.com/TabularEditor/TabularEditor3/issues/955). +- Fixed an issue that caused the "Go to definition (F12)" action to be disabled when the caret was placed on a DAX function, see [#962](https://github.com/TabularEditor/TabularEditor3/issues/962). +- Fixed a bug that prevented loading models from .vpax files in some cases. +- The height of the "result count" panel in DAX queries should now automatically adjust to fit its content. +- The Properties grid now correctly displays multi-line expressions that happen to start with one or more line breaks, just like when editing the expression inside the grid. +- Fixed a bug that could cause Pivot Grid to get stuck in an infinite error-message loop, when columns that were added to the Pivot Grid were deleted from the remote model. +- Fixed a bug where macros added to the menu bar, would stop working after a restart of Tabular Editor. +- Fixed a bug where attempting to perform a Schema Update on multiple tables originating from the same source table, would fail for all except one. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_11_0_zh.md b/content/localization/zh/3_11_0_zh.md new file mode 100644 index 00000000..582cd62b --- /dev/null +++ b/content/localization/zh/3_11_0_zh.md @@ -0,0 +1,86 @@ +--- +uid: release-3-11-0 +--- + +# Tabular Editor 3.11.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.11.0 downloads: + +- Download [Tabular Editor 3.11.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.11.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.11.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x64.exe) | `4E65D74F7535F7B5543AA592B2558DA20AA85958D8623558B75E65053BC50D6C` | +| [TabularEditor.3.11.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.msi) | `C334EDD03701D05F25255CE83375C72E0ACEE7866914D382CAC7E0A83B59FD46` | +| [TabularEditor.3.11.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.zip) | `06BA6B064CF193AD435F19999F6F71E54225C6B9BF733C944C8D7DE1834C8BD7` | +| [TabularEditor.3.11.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x86.exe) | `27275F6B65C4B63AE2FC96648BDA74D9A4F860D725DB1188DA7283DF63F5D504` | +| [TabularEditor.3.11.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.msi) | `D654E4A7BF27EAB5C87D1A8A60F1B8BCD6978AED6BF6C47C420B3F22579ACEAE` | +| [TabularEditor.3.11.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.zip) | `3D907626CDCA1DFD9D5CE3A474FFE8574267512C109FC7611A8A3BB020B4B8C9` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.11.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/09/25/september-release-tabular-editor-3-11-0/) to get a brief overview of the most important updates in this release. + +- As noted in [last months' release notes](xref:release-3-10-1), Tabular Editor did not let you create a [Direct Lake dataset](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview) from scratch. This is now possible! The only prerequisite is that the model does not already have any tables or explicit data sources defined, and that its Compatibility Mode is set to PowerBI. Check out our [blog post on DirectLake, if you want to learn more](https://blog.tabulareditor.com/2023/08/23/fabric-direct-lake-dataset/). + +> [!WARNING] +> Once you make any changes to a Direct Lake dataset through the XMLA endpoint, you will [no longer be able to open that dataset in the Web Modelling feature of Fabric](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#enable-xmla-read-write:~:text=Direct%20Lake%20datasets%20created%20or%20modified%20by%20using%20XMLA%2Dbased%20tools%20cannot%20be%20opened%20in%20the%20Web%20modelling%20feature.). + +## Improvements in 3.11.0 + +- We're now using using the latest version of [AMO/TOM](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) and [TMDL](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64), which includes a number of bugfixes and stability improvements. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +- Our DAX parser and autocomplete now supports the newly added 3rd parameter to [`MINX`](https://dax.guide/minx)/[`MAXX`](https://dax.guide/maxx). Moreover, we now also provide suggestions for the [`MATCHBY`](https://dax.guide/matchby) function, which can be used as an optional parameter of window functions. +- The Native Query option of the Table Import Wizard is now available when importing from Databricks, provided a catalog has been specified. + +## Bugfixes in 3.11.0 + +- The list of reserved table names in DAX has been updated using the `$system.discover_keywords` DMV. The consequence is that our built-in DAX formatter now correctly applies quotes on certain table names, which are also reserved words. For example, a reference to a table named `status` will now always be quoted. See [#991](https://github.com/TabularEditor/TabularEditor3/issues/991). +- Autocomplete now suggests proper keywords for the _<Skip>_ parameter of DAX window functions such as [`RANK`](https://dax.guide), etc. +- Batch Rename now works for folders, see [#797](https://github.com/TabularEditor/TabularEditor3/issues/797). +- Fixed some issues regarding custom layouts, see [#711](https://github.com/TabularEditor/TabularEditor3/issues/711). Also fixed an issue where customizations to the built-in menus, were not properly persisted. +- Fixed a bug in the Deployment Wizard, when the model contains an incremental refresh table with no partitions. In this case, the deployment wizard UI did not allow the user to skip partition deployment of this table which would cause an invalid TMSL to be generated generated (one with no partitions for the table in question). +- Fixed a bug, where running a DAX query with no whitespace between [`EVALUATE`](https://dax.guide) and the following expression would cause an error. +- Fixed numerous issues with the DAX debugger. See [#954](https://github.com/TabularEditor/TabularEditor3/issues/954), [#971](https://github.com/TabularEditor/TabularEditor3/issues/971) and [#984](https://github.com/TabularEditor/TabularEditor3/issues/984). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_12_0_zh.md b/content/localization/zh/3_12_0_zh.md new file mode 100644 index 00000000..4363cf27 --- /dev/null +++ b/content/localization/zh/3_12_0_zh.md @@ -0,0 +1,97 @@ +--- +uid: release-3-12-0 +--- + +# Tabular Editor 3.12.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.12.0 downloads: + +- Download [Tabular Editor 3.12.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.12.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.12.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x64.exe) | `EF139EA10FF8D7376B36C505778F4030BF5FE5D4B4976DA6EBA4E594C857CAA4` | +| [TabularEditor.3.12.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.msi) | `12691A728D51D9CA27AEB5D99B8C8C5BC820633AFD1521DDE5AA7CFC7B5C1798` | +| [TabularEditor.3.12.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.zip) | `852F233CEA4724DA492ADD66FB5D1DF5BB6722D08BC04AC35AB37B71255C520F` | +| [TabularEditor.3.12.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x86.exe) | `83CD723B477421834AA640C01887AFC530366E321263E8929D3D12FB77713BB8` | +| [TabularEditor.3.12.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.msi) | `772C7BBA32F5603D51CD16DFB71E0D9CF56D33F34C3FB2E6B99FFDAB018A8CD5` | +| [TabularEditor.3.12.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.zip) | `94CA188CCCF73FC11CCF1862BE68C69475EE7EDAB9C4C03F5DEA25693BF4AE7D` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.12.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/11/27/tabular-editor-3-november-2023-release) to get a brief overview of the most important updates in this release. + +- Tabular Editor now displays a "What's New" page when the application is updated. The page informs you of new Tabular Editor features, along with community updates and other relevant news for Tabular Editor users. If the page is hidden, you can access it from the **Help > What's New**. You can disable this feature by unchecking **Tools > Preferences > Updates and Feedback > Show "What's New" page on startup**. +- When prototyping new measures, it is quite common to specify them within the `DEFINE` block of a DAX query. In this update, we've added an easy way to create/update model measures based on measures defined within the DAX query. On the toolbar, through the **Query** menu, and through the right-click context menu of the DAX query editor, you will see 4 new options light up, which work very similarly to the "Apply" actions in [DAX Scripts](https://docs.tabulareditor.com/te3/features/dax-scripts.html#shortcuts), with the exception that only a measures' name and expression is applied (since it's not possible to specify other properties like Description, Display Folder, etc. through a DAX query). More details in the [blog post](https://blog.tabulareditor.com). +- Please be aware that we're now using a new certificate to sign the binaries, in case your IT organization needs to expclitly approve 3rd party code certificates. The new certificate is issued by [GlobalSign GCC](https://www.globalsign.com/en) and the certificate is issued directly to [Tabular Editor ApS](https://tabulareditor.com/contact). + +## Improvements in 3.12.0 + +- We have hidden the special RowNumber column from the various VertiPaq Analyzer views, to align with other tools (DAX Studio, DAX Optimizer, etc.). +- AMO/TOM has been updated to [19.69.6.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64), meaning Tabular Editor 3 now supports the latest data modelling features. For example, we now support the `Model.DirectLakeBehavior` property, letting you control whether DirectQuery fallback on Direct Lake models should occur or not. +- TMDL has also been updated to the [latest version](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.69.6.2-TmdlPreview). + +> [!NOTE] +> **TMDL is still in preview and should not be used in production.** We're aware of a deserialization issue in AMO/TOM 19.69.6.2, when a table has an incremental refresh policy applied. This will be fixed in the next release of AMO/TOM. + +- You can now create BPA rules that inspect DAX tokens returned from the [`IDaxDependantObject.Tokenize()`](https://docs.tabulareditor.com/api/TabularEditor.TOMWrapper.Utils.DaxDependencyHelper.html#TabularEditor_TOMWrapper_Utils_DaxDependencyHelper_Tokenize_TabularEditor_TOMWrapper_IDaxDependantObject_) method, the same way as in TE2. +- We now show a warning in the DAX editor, when a variable is declared but never used. See [#934](https://github.com/TabularEditor/TabularEditor3/issues/934). Such variables should generally be removed to keep your DAX tidy. +- When importing tables or updating table schema from a T-SQL source, where the partition references a Stored Procedure, we now provide an option to execute the Stored Procedure, in cases where the resulting schema cannot be statically determined. This can happen, for example, when the stored procedure uses temp tables. The user is always prompted with an option to cancel the operation, before the stored procedure is executed. +- Tabular Editor now allows importing tables from Snowflake using Native Query, see [#949](https://github.com/TabularEditor/TabularEditor3/issues/949). **Note:** For this option to be available, you must specify a database name in the Snowflake connection dialog. +- You can now refresh individual tables or partitions in Direct Lake mode (this operation is also known as ["framing"](https://github.com/TabularEditor/TabularEditor3/issues/999)). +- Adding tables to a model in Direct Lake mode, will no longer prompt you for the type of partition to create (defaulting to an Entity Partition in Direct Lake mode). + +## Bugfixes in 3.12.0 + +- Fixed an issue where the **Rename Variable** context menu option would not always be available, see [#692](https://github.com/TabularEditor/TabularEditor3/issues/692). +- Fixed an issue where username/passwords were not properly persisted for ODBC data connections. Tabular Editor will now prompt if the ODBC credentials are missing. +- Fixed an issue where a Snowflake DSI ODBC connection string was not generated correctly, see [#993](https://github.com/TabularEditor/TabularEditor3/issues/993). +- When Tabular Editor generates T-SQL during table import/schema updates, we no longer use the `IIF` keyword, since this is not supported on Azure Synapse (dedicated SQL pools), see [#1007](https://github.com/TabularEditor/TabularEditor3/issues/1007). +- When Tabular Editor generates the deployment TMSL script, we now automatically add a dummy partition to tables governed by incremental refresh, in case no partitions have been defined (otherwise, deployment would fail). +- The Best Practice Analyzer should now gracefully handle BPA rules where the rule expression itself has an error (just like TE2). +- Fixed an issue where the **Last accessed** column of VertiPaq Analyzer did not show correct info. +- Fixed a minor glitch with VertiPaq Analyzer buttons not indicating correct state. +- Emojis in the DAX editor should no longer cause random crashes, although auto-complete, auto-formatting, etc. will still not work. +- Fixed an issue where setting the OLS Column Permission to "None" would cause the TOM Explorer to lock up. +- Fixed a glitch in the "Save as Macro" dialog, which could cause a crash in some cases. +- M partitions containing a comment on the last line should no longer produce an error when performing a schema update through Analysis Services/Power BI, see [#1167](https://github.com/TabularEditor/TabularEditor3/issues/1167). +- The auto-complete popup should now have a suitable width on its first appearance, see [#1152](https://github.com/TabularEditor/TabularEditor3/issues/1152). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_12_1_zh.md b/content/localization/zh/3_12_1_zh.md new file mode 100644 index 00000000..eaa28e59 --- /dev/null +++ b/content/localization/zh/3_12_1_zh.md @@ -0,0 +1,103 @@ +--- +uid: release-2-12-1 +--- + +# Tabular Editor 3.12.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.12.1 downloads: + +- Download [Tabular Editor 3.12.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.12.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.12.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x64.exe) | `3FEFFC80E6C1C369A35A84624C8AD239A2EA1FDD8DCC5C64517F196302FE9BC4` | +| [TabularEditor.3.12.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.msi) | `BA514787D6602B40B2A281586B8FBD82CA10C877AAB83DCD1D863C8E9E673C63` | +| [TabularEditor.3.12.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.zip) | `1EB42BC752460726DADCBC130EC7E44FA69156542AD3119717245B17E5D139A4` | +| [TabularEditor.3.12.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x86.exe) | `AB68ECA42B80AD9D140E82970E76192BF4C68925A5E0906744EE607A5F9AB5CB` | +| [TabularEditor.3.12.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.msi) | `6D38264E8127CC66959306AE135C7CBAE1B56C1D92D9F291037CF8E1D9750A41` | +| [TabularEditor.3.12.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.zip) | `DA748A8B653A75F8E652EE055E0E47C320640CFCDE9D9140E278DE683EE8DF14` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.12.1 + +- Fixed an issue that caused a crash in the DAX Editor, when typing out new measure definitions in the query, see [#1183](https://github.com/TabularEditor/TabularEditor3/issues/1183). + +*** + +## New in 3.12.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +- Tabular Editor now displays a "What's New" page when the application is updated. The page informs you of new Tabular Editor features, along with community updates and other relevant news for Tabular Editor users. If the page is hidden, you can access it from the **Help > What's New**. You can disable this feature by unchecking **Tools > Preferences > Updates and Feedback > Show "What's New" page on startup**. +- When prototyping new measures, it is quite common to specify them within the `DEFINE` block of a DAX query. In this update, we've added an easy way to create/update model measures based on measures defined within the DAX query. On the toolbar, through the **Query** menu, and through the right-click context menu of the DAX query editor, you will see 4 new options light up, which work very similarly to the "Apply" actions in [DAX Scripts](https://docs.tabulareditor.com/te3/features/dax-scripts.html#shortcuts), with the exception that only a measures' name and expression is applied (since it's not possible to specify other properties like Description, Display Folder, etc. through a DAX query). More details in the [blog post](https://blog.tabulareditor.com). +- Please be aware that we're now using a new certificate to sign the binaries, in case your IT organization needs to expclitly approve 3rd party code certificates. The new certificate is issued by [GlobalSign GCC](https://www.globalsign.com/en) and the certificate is issued directly to [Tabular Editor ApS](https://tabulareditor.com/contact). + +## Improvements in 3.12.0 + +- We have hidden the special RowNumber column from the various VertiPaq Analyzer views, to align with other tools (DAX Studio, DAX Optimizer, etc.). +- AMO/TOM has been updated to [19.69.6.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64), meaning Tabular Editor 3 now supports the latest data modelling features. For example, we now support the `Model.DirectLakeBehavior` property, letting you control whether DirectQuery fallback on Direct Lake models should occur or not. +- TMDL has also been updated to the [latest version](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.69.6.2-TmdlPreview). + +> [!NOTE] +> **TMDL is still in preview and should not be used in production.** We're aware of a deserialization issue in AMO/TOM 19.69.6.2, when a table has an incremental refresh policy applied. This will be fixed in the next release of AMO/TOM. + +- You can now create BPA rules that inspect DAX tokens returned from the [`IDaxDependantObject.Tokenize()`](https://docs.tabulareditor.com/api/TabularEditor.TOMWrapper.Utils.DaxDependencyHelper.html#TabularEditor_TOMWrapper_Utils_DaxDependencyHelper_Tokenize_TabularEditor_TOMWrapper_IDaxDependantObject_) method, the same way as in TE2. +- We now show a warning in the DAX editor, when a variable is declared but never used. See [#934](https://github.com/TabularEditor/TabularEditor3/issues/934). Such variables should generally be removed to keep your DAX tidy. +- When importing tables or updating table schema from a T-SQL source, where the partition references a Stored Procedure, we now provide an option to execute the Stored Procedure, in cases where the resulting schema cannot be statically determined. This can happen, for example, when the stored procedure uses temp tables. The user is always prompted with an option to cancel the operation, before the stored procedure is executed. +- Tabular Editor now allows importing tables from Snowflake using Native Query, see [#949](https://github.com/TabularEditor/TabularEditor3/issues/949). **Note:** For this option to be available, you must specify a database name in the Snowflake connection dialog. +- You can now refresh individual tables or partitions in Direct Lake mode (this operation is also known as ["framing"](https://github.com/TabularEditor/TabularEditor3/issues/999)). +- Adding tables to a model in Direct Lake mode, will no longer prompt you for the type of partition to create (defaulting to an Entity Partition in Direct Lake mode). + +## Bugfixes in 3.12.0 + +- Fixed an issue where the **Rename Variable** context menu option would not always be available, see [#692](https://github.com/TabularEditor/TabularEditor3/issues/692). +- Fixed an issue where username/passwords were not properly persisted for ODBC data connections. Tabular Editor will now prompt if the ODBC credentials are missing. +- Fixed an issue where a Snowflake DSI ODBC connection string was not generated correctly, see [#993](https://github.com/TabularEditor/TabularEditor3/issues/993). +- When Tabular Editor generates T-SQL during table import/schema updates, we no longer use the `IIF` keyword, since this is not supported on Azure Synapse (dedicated SQL pools), see [#1007](https://github.com/TabularEditor/TabularEditor3/issues/1007). +- When Tabular Editor generates the deployment TMSL script, we now automatically add a dummy partition to tables governed by incremental refresh, in case no partitions have been defined (otherwise, deployment would fail). +- The Best Practice Analyzer should now gracefully handle BPA rules where the rule expression itself has an error (just like TE2). +- Fixed an issue where the **Last accessed** column of VertiPaq Analyzer did not show correct info. +- Fixed a minor glitch with VertiPaq Analyzer buttons not indicating correct state. +- Emojis in the DAX editor should no longer cause random crashes, although auto-complete, auto-formatting, etc. will still not work. +- Fixed an issue where setting the OLS Column Permission to "None" would cause the TOM Explorer to lock up. +- Fixed a glitch in the "Save as Macro" dialog, which could cause a crash in some cases. +- M partitions containing a comment on the last line should no longer produce an error when performing a schema update through Analysis Services/Power BI, see [#1167](https://github.com/TabularEditor/TabularEditor3/issues/1167). +- The auto-complete popup should now have a suitable width on its first appearance, see [#1152](https://github.com/TabularEditor/TabularEditor3/issues/1152). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_13_0_zh.md b/content/localization/zh/3_13_0_zh.md new file mode 100644 index 00000000..b6f64ef0 --- /dev/null +++ b/content/localization/zh/3_13_0_zh.md @@ -0,0 +1,88 @@ +--- +uid: release-3-13-0 +--- + +# Tabular Editor 3.13.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.13.0 downloads: + +- Download [Tabular Editor 3.13.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.13.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.13.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x64.exe) | `7C22DC330D8F1F83C30FB4F84E6A038C1F4E08128BEA293E0559D6C5C2F80671` | +| [TabularEditor.3.13.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.msi) | `582DA8393AE8C51CA0DAC5B6980534957AAF2E729B5E0ECDB2ED943181A5860D` | +| [TabularEditor.3.13.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.zip) | `F7B0CCB25B3CEA478F921AF7C0FDA6979910D17F8BAF321E23986C800978811F` | +| [TabularEditor.3.13.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x86.exe) | `B851EE5B994F69B8BB0D806FA8147D2196D17D395D8D1601CC338E8D343526B1` | +| [TabularEditor.3.13.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.msi) | `30B15436DD7FB1BA8B9FFBEFBAB366A70B3EB21422ACEFE442EFF464E6E7E361` | +| [TabularEditor.3.13.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.zip) | `CED68ECC4821B9A21AB022AD61AB693A1FD4988F8C6D66BEC1B08E941295C7B3` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.13.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/12/15/tabular-editor-3-december-2023-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.13.0 + +- Unused variable warnings are now only shown when the variable declaration block is complete, and only the variable name itself is highlighted. Moreover, there is a new option where you can toggle off these warnings under **Tools > Preferences > DAX Editor > Code Assist**. +- VertiPaq Analyzer in TE3 now uses the same default settings as in DAX Studio. You can also configure the "Read statistics from DirectQuery tables" option now, under **Tools > Preferences > VertiPaq Analyzer**. +- We've made a small change to how the Refresh Policy on a table appears in the **Properties** view, to better align with [TOM](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.table.refreshpolicy?view=analysisservices-dotnet). This change also lets you add annotations/extended properties to Refresh Policies, which previously wasn't possible. C# scripts can still use the Refresh Policy properties directly on the `Table` object, but we recommend updating scripts to access these properties through the `Table.RefreshPolicy` object instead. +- When selecting a table or column in the TOM Explorer, we now highlight (with **bold** font) any relationships the object is involved in, see [#865](https://github.com/TabularEditor/TabularEditor3/issues/865). This feature can be disabled under **Tools > Preferences > TOM Explorer**. +- We now display the main storage mode (Import, DirectQuery, Direct Lake, etc.) of the model, in the title bar. +- In addition to tables, it is now possible to view relationships starting from a specific column in the "Dependencies" view. Right-click on a column and choose "Show dependencies", then choose the "Show relationships starting from this column" option, see [this comment](https://github.com/TabularEditor/TabularEditor3/issues/865#issuecomment-1490782086). +- We now show a warning in the **Messages** view when objects are in an unprocessed state. This applies to both tables, columns and partitions. It also solves [#1153](https://github.com/TabularEditor/TabularEditor3/issues/1153). +- We now show a warning in the **Messages** view when a column uses a sort-by-column that has `IsAvailableInMDX` set to **false** (as this would otherwise produce an error when the model is saved/deployed). See [#868](https://github.com/TabularEditor/TabularEditor3/issues/868). +- We've updated AMO/TOM to use the latest version [19.72.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). This library also includes an updated version of TMDL, which should fix a deserialization issue, when a table has incremental refresh policy applied. +- When serializing a model using TMDL, we now also output a `database.tmdl` file, which contains metadata at the database level (name, compatibility mode, compatibility level, etc.), which should improve the overall TMDL experience. + +> [!NOTE] +> **TMDL is still in preview and should not be used in production, as you may be impacted by breaking changes between updates.** +> If you encounter any issues opening a model that was saved as TMDL with an earlier version of Tabular Editor, a possible fix is to open the model from TMDL using the same earlier version of Tabular Editor, save it as a Model.bim file, and then use the latest version of Tabular Editor to open the Model.bim file and save it back to the TMDL format. + +## Bugfixes in 3.13.0 + +- Fixed an issue where undo'ing (Ctrl+Z) the removal of a Refresh Policy from a table, would not restore the configuration of that Refresh Policy. +- Fixed an issue where the DAX editor auto-complete would suggest incorrect items for window function parameters, when the window function was used as a filter argument for [`CALCULATE`](https://dax.guide/calculate/) or [`CALCULATETABLE`](https://dax.guide/calculatetable/). +- Fixed a bug that prevented adding/removing levels to hierarchies, when connected to an instance of Power BI Desktop, even though this is a [supported modeling operation](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). +- Fixed an issue where the "Calculate" refresh option did not appear for regular tables. +- Fixed an issue where evaluating only the current selection of a DAX Query would not work, if a line comment was directly above the first `EVALUATE` statement in the selection, see [#912](https://github.com/TabularEditor/TabularEditor3/issues/912). +- Tabular Editor should now let you "Open from folder", when the folder contains ".tmdl" files (previous versions of TMDL used the ".tmd" extension). See [#1175](https://github.com/TabularEditor/TabularEditor3/issues/1175). +- The logic for determining if a table is a "Date Table" was a bit too restrictive, which could cause false circular dependency errors in some cases, or incorrect display of overridden filter contexts in the DAX debugger (due to the implicit filter removal associated with date tables). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_14_0_zh.md b/content/localization/zh/3_14_0_zh.md new file mode 100644 index 00000000..21f08807 --- /dev/null +++ b/content/localization/zh/3_14_0_zh.md @@ -0,0 +1,92 @@ +--- +uid: release-3-14-0 +--- + +# Tabular Editor 3.14.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.14.0 downloads: + +- Download [Tabular Editor 3.14.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.14.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.14.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x64.exe) | `E648B9F735D50B1F253FE6A5EA2FC036810F2C66525609C92D1463219A2EF9C1` | +| [TabularEditor.3.14.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.msi) | `0E3703B392FD8D586687BD31CA870BCB602CFAAAA355343C5229DD69AA54E105` | +| [TabularEditor.3.14.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.zip) | `26A700AF5F2A70107F96A3FDA2A7D66072C2FCD047BF541724A4FFB5B77DEC4A` | +| [TabularEditor.3.14.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x86.exe) | `69EECC729C418707E3472EFC58CD4D68D4B45C82540F9321C22CBA3C7D0D5357` | +| [TabularEditor.3.14.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.msi) | `13F064F0253C05B62F0319FE8C846F913386C31B2ED1103324CD0A52CDD2F353` | +| [TabularEditor.3.14.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.zip) | `2DAFAB4FFC17F42B27313791819A09E5905D65991F9971621BCC636C6422D5F6` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.14.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/02/20/tabular-editor-3-february-2024-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.14.0 + +- Calculated columns now show the "_fx_" glyph in the Table Preview, so they are easier to distinguish from non-calculated columns. +- The DAX query row limiter will now be disabled if a DAX query uses [`TOPN`](https://dax.guide/TOPN) or [`START AT`](https://dax.guide/st/start-at/), to avoid interfering with the returned results. +- The DAX auto-complete feature now supports any scalar expression in the [`ORDER BY`](https://dax.guide/st/order-by/) clause of a DAX query, and will also no longer suggest columns that are already specified earlier in the [`ORDER BY`](https://dax.guide/st/order-by/) clause. +- When importing/updating tables in a Direct Lake model, we now add the same annotations to tables and columns as if the model was created through the Power BI web modelling, ensuring that cross workspace models can refresh without issues, among other things. +- Support for [DAX `INFO` functions](https://powerbi.microsoft.com/en-us/blog/dax-query-view-introduces-new-info-dax-functions/) in editor auto-complete. These functions are only suggested in a DAX query, as they cannot be used in calculated items (e.g., columns, tables) or measures in a model. +- Updated TOM to [19.76.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64) which includes the latest version of TMDL (Preview-9). +- With TMDL Preview-9, we now have a set of new options available, for configuring how the TMDL is serialized. You can find these options under **Tools > Preferences > Save-to-folder** (for any models that were previously saved as TMDL, you can change these settings under **Model > Serialization options**): + +> [!IMPORTANT] +> TMDL is still a preview feature, meaning breaking changes could be introduced between new releases. If you face any issues deserializing a model after upgrading Tabular Editor, rollback to the latest version of Tabular Editor, then temporarily save the model as a regular .bim file, before serializing it to TMDL again using the latest version of Tabular Editor. + +![TMDL serialization settings](https://docs.tabulareditor.com/images/tmdl-options.png) + +> [!NOTE] +> We do not currently have any options available for customizing which objects get serialized as individual files, when using TMDL. If you would like to see this feature, [please let us know](https://github.com/TabularEditor/TabularEditor3/discussions/1198#discussioncomment-8382137)! + +## Bugfixes in 3.14.0 + +- Fixed an issue with Find/Replace unexpectedly searching/performing replaces outside of the current selection. +- Fixed an issue where the DAX autocomplete would not suggest a column after a binary operator, if that column was already used previously in the same filter expression, see [#1156](https://github.com/TabularEditor/TabularEditor3/issues/1156). +- Fixed an issue where unpinning the **Properties View** would cause all layout settings to be reset upon reopening TE3. +- The DAX Semantic Analyzer now properly handles [`ORDER BY`](https://dax.guide/st/order-by/) and [`START AT`](https://dax.guide/st/start-at/) expressions in DAX queries. Moreover, auto-complete works correctly within these clauses, and the automatic row limiter no longer generates invalid DAX when [`START AT`](https://dax.guide/st/start-at/) is present. See [#1182](https://github.com/TabularEditor/TabularEditor3/issues/1182). Lastly, the built-in DAX formatter should no longer crash when formatting a query containing [`START AT`](https://dax.guide/st/start-at/). +- Fixed a bug where the Data Preview grid seemed to support sorting by more than column. In reality, only the first column selected for sorting is effective, since the [`TOPNSKIP`](https://dax.guide/topnskip) function used to query the table does not support sorting on more than column. +- Fixed a bug that would cause documents to get "stuck" when restoring a layout through the **Window** menu. +- Fixed a bug that prevented certain types of errors to be shown in the **TOM Explorer** and the **Messages** view, see [1217](https://github.com/TabularEditor/TabularEditor3/issues/1217). +- Fixed a bug that could cause the application to hang during activation. +- Fixed an issue with extended properties on perspectives not being serialized when using (legacy) "Save to folder", see [#1165](https://github.com/TabularEditor/TabularEditor/issues/1165). +- Entering a '.' (dot) should no longer close the DAX auto-complete popup window when filtering DAX functions that have a dot in their name. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_15_0_zh.md b/content/localization/zh/3_15_0_zh.md new file mode 100644 index 00000000..37452176 --- /dev/null +++ b/content/localization/zh/3_15_0_zh.md @@ -0,0 +1,97 @@ +--- +uid: release-3-15-0 +--- + +# Tabular Editor 3.15.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.15.0 downloads: + +- Download [Tabular Editor 3.15.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.15.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.15.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x64.exe) | `5E90A3990E015F719CD92B53B54738F26FEEA7826D465E81E815427C9070144F` | +| [TabularEditor.3.15.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.msi) | `A9925DC6E5D5D6AA1A73EBF0F1B385588DD8D4F68A8E950573344FB587ECCFCA` | +| [TabularEditor.3.15.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.zip) | `6CFA5AB78783F406EE511D73F646931A582FD51AEAC31E4AD065240453C7F13E` | +| [TabularEditor.3.15.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x86.exe) | `B8BBA2AFD6AB6277A465E680A3EAA85310BF27D24B23F7CC1B604F92E2D61A29` | +| [TabularEditor.3.15.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.msi) | `2F61FF655EFD4658D16AB69A0CA5BCB6282C4A01B2E355CF9E2EF52A4AF233C4` | +| [TabularEditor.3.15.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.zip) | `A8868D4BBB9D6A5B034B9292CBC395A639A03A7C163AF1EF8A9CA1DBE8F4EA0F` | + +*** + +### Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +## New in 3.15.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/04/24/tabular-editor-3-april-2024-release/) to get a brief overview of the most important updates in this release. + +- We have a new **Preview** feature this month: **DAX Optimizer integration**. If you have a DAX Optimizer account, you can connect to your workspaces, upload VPAX files, and view [DAX Optimizer](https://daxoptimizer.com) results directly in Tabular Editor. [More information](https://docs.tabulareditor.com/te3/features/dax-optimizer-integration). +- We now support adding [Data Coverage Definition expressions](https://learn.microsoft.com/en-us/analysis-services/tom/table-partitions?view=asallproducts-allversions#define-the-data-coverage-of-the-directquery-partition) to partitions in DirectQuery mode. +- Tabular Editor will now add a `__TEdtr` annotation to your model when metadata is saved to disk (either as Model.bim, Database.json or TMDL). This annotation is used by Microsoft for analytics about Tabular Editor usage for semantic models published to a Power BI or Fabric workspace. This annotation may also be required for certain features to work correctly in Power BI / Fabric, when a model was edited using Tabular Editor. +- The **New Model** dialog now has a **Direct Lake** checkbox\*, which will configure the model to use the new Direct Lake storage mode in Fabric. [More information](https://docs.tabulareditor.com/common/Datasets/direct-lake-dataset.html). Moreover, you can now explicitly choose the _Compatibility Mode_ when entering the _Compatibility Level_ manually. +- You can now export [obfuscated VPAX files](https://www.sqlbi.com/blog/marco/2024/03/15/vpax-obfuscator-a-library-to-obfuscate-vpax-files/) using Tabular Editor. This can be helpful when your metadata (object names and DAX expressions) are confidential, but you want to share the VPAX file with a person or service for optimization purposes. Find this option in the **VertiPaq Analyzer** view, on the dropdown next to the **Export** button. + +## Improvements in 3.15.0 + +- We've updated [AMO/TOM to 19.79.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). In this update, a bug that could sometimes cause overlapping policy range partitions to be generated, when invoking the "Apply Refresh Policy" option, has been fixed. +- Default _Compatibility Level_ for new Power BI / Fabric models set to 1605. +- When a Direct Lake model is initially deployed, we now perform an automatic refresh, which is a prerequisite to avoid DirectQuery fallback. Moreover, there is a new option (which is enabled by default), to also perform an automatic refresh whenever a Direct Lake model is saved, when new tables have been added. This preference is located under **Tools > Preferences > Model Deployment > Data Refresh**. +- Add new sorting option when scripting DAX items: when enabling "Sort scripted items alphabetically", all DAX items in the script will be sorted alphabetically by name. +- Add six new editor commands and default keyboard shortcuts to interact with foldable code regions in DAX editors: + - `Editor.Dax.CollapseAllFolds`: collapse/close all foldable regions in the document. Default shortcut: **Ctrl+Alt+[** + - `Editor.Dax.ExpandAllFolds`: expand/open all foldable regions in the document. Default shortcut: **Ctrl+Alt+]** + - `Editor.Dax.ToggleAllFolds`: toggle the state of all foldable regions between expanded and collapsed; this ensures that all folds end up in the same state. Default shortcut: **Ctrl+Alt+;** + - `Editor.Dax.CollapseFold`: collapse/close the foldable region that the cursor is currently positioned in. Default shortcut: **Ctrl+Shift+[** + - `Editor.Dax.ExpandFold`: expand/open the foldable region that the cursor is currently positioned in. Default shortcut: **Ctrl+Shift+]** + - `Editor.Dax.ToggleFold`: toggle the state of the foldable region that the cursor is in between the open and close states. Default shortcut: **Ctrl+Shift+;** +- The DAX editor now lets you delete individual words inside table/column/measure references when using **Ctrl+Backspace** or **Ctrl+Delete**. To delete the full reference, place the cursor at the beginning or end of the reference and use the same shortcuts. +- "database.tmdl" files are now also shown in the **Open Model from File** dialog, in addition to "model.tmdl" files. It doesn't matter which file is opened - Tabular Editor loads the full model metadata from both files in any case. +- When collecting VertiPaq Analyzer statistics for a Direct Lake model, only resident columns are queried by default. This considerable reduces the time it takes to collect statistics for large models. You can still choose to include non-resident columns by changing the **Statistics for Direct Lake models** setting under **Tools > Preferences > VertiPaq Analyzer**. +- Add preferences to control Currency formatting under **'Tools' > 'Preferences' > 'TOM Explorer' > 'Localization'**: previously, currency was hard coded to use a US Dollar symbol ($) at the beginning of the format string. Now, you can select either a standard formatting style from a searchable dropdown, or define your own custom symbol and positioning. + +## Bugfixes in 3.15.0 + +- Fixed an issue where customized keyboard shortcuts for "Editor.Dax.FormatLong" and "Editor.Dax.FormatShort" didn't work. +- Fixed a bug where macros would not be fully loaded, unless the macro definitions in the MacroActions.json file were ordered by macro ID, see [#1151](https://github.com/TabularEditor/TabularEditor3/issues/1151). +- If a table preview fails in the Import Table Wizard, it should now be possible to continue previewing other tables. +- Table previews in the Import Table Wizard, should now work correctly for Fabric Lakehouse SQL endpoints. +- When saving a model as TMDL, the default encoding is now UTF8 without Byte-Order-Marks (BOM), which should be compatible with Power BI Desktop. +- Fixed a bug where URL tooltips on the **What's New** page would linger on the screen. +- The built-in DAX formatter should no longer replace KPI references with their base measure reference. +- Fixed a bug where the "Ignore incremental refresh partitions" and "Ignore lineage tags" serialization settings were not being properly saved. + +\*=Direct Lake models require Fabric workspaces. As such, they are only accessible for Tabular Editor 3 Enterprise Edition customers. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +--- + diff --git a/content/localization/zh/3_16_0_zh.md b/content/localization/zh/3_16_0_zh.md new file mode 100644 index 00000000..7b3c4fba --- /dev/null +++ b/content/localization/zh/3_16_0_zh.md @@ -0,0 +1,99 @@ +--- +uid: release-3-16-0 +--- + +# Tabular Editor 3.16.0 + +## [**Downloads**](#tab/downloads) + +Tabular Editor 3.16.0 downloads: + +- Download [Tabular Editor 3.16.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.16.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.16.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x64.exe) | `95DADC45A7B6B242D1497A34F5B09ACEBE822E2315DEE9E2A4EDFC95B43FDE0F` | +| [TabularEditor.3.16.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.msi) | `BEF1D9CF4F60C09646F3FB4A355FBDC4DF4BA1920481A7AFF3584DBC0314ED6E` | +| [TabularEditor.3.16.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.zip) | `D3CE2DE02C9D68F67746344EAB05F2E5FDD7BB5CC238D0B2132CE5CCB61C729E` | +| [TabularEditor.3.16.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x86.exe) | `AC3CE7829E709A80332679A2FE63F9A5F929F7B235893BCBEE6A561BFA01EC7D` | +| [TabularEditor.3.16.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.msi) | `FF1D1475E129A0C2BFD2F06586428C3922C66CD00278149BDA9DB15167892C70` | +| [TabularEditor.3.16.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.zip) | `B78E689FAF6372FE84A05A97E9B48949F9C4E9CC58EC0C534BEC067627D304D6` | + +*** + +## Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +## New in 3.16.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/06/13/tabular-editor-3-july-2024-release/) to get a brief overview of the most important updates in this release. + +We have substantially overhauled how **Pivot Grids** work in this release. Some highlights include: + +- Pivot Grid layouts can now be saved and loaded to/from files! A new file format, `.te3pivot` is used to store a JSON representation of the Pivot Grid layout. +- Hidden objects (measures, columns, hierarchies) can now be used in a Pivot Grid, and object renames should no longer cause the Pivot Grid to lose its layout or clear any filters. +- A new and improved Pivot Grid **Field List**, which is now shown by default, and provides a more familiar experience when adding fields to the Pivot Grid. + +Head on over to the [Pivot Grid documentation](https://docs.tabulareditor.com/te3/features/pivot-grid.html) to learn more about these changes. + +## Improvements in 3.16.0 + +- Reduced the number of redundant error messages that are shown, when DAX expression contain syntax/semantic errors. +- DAX scripts now support unspecified/empty expressions. This allows you to specify a DAX script that does not modify existing expressions on objects, or a script that explicitly sets an expression to be empty. +- You can now export DAX query results to CSV/Excel. Look for the **Export data** and **Export data (all results)** options under the **Query** menu. +- When exporting VertiPaq Analyzer statistics, we now suggest a default name for the VPAX file based on the database name. +- We changed the default keyboard shortcuts for `Editor.Dax.CollapseAllFolds`, `Editor.Dax.ExpandAllFolds` and `Editor.Dax.ToggleAllFolds` from **Ctrl+Alt+(key)** to **Ctrl+Shift+(key)**. This is to avoid conflicts with certain characters that require the **AltGr** key (which is equivalent to **Ctrl+Alt**) to be typed on non-US keyboards. The **Ctrl+Shift+(key)** shortcuts were previously used by `Editor.Dax.CollapseFold`, `Editor.Dax.ExpandFold` and `Editor.Dax.ToggleFold`. Their defaults have been changed to **Ctrl+(key)**. +- Updated [AMO/TOM to 19.80.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Menus and toolbars are now locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option. +- Our DAX semantic analyzer now supports the `WITH VISUAL SHAPE` syntax used in DAX queries that contain [visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview). Note that debugging such queries is not yet supported (as only measures can be debugged, and visual calculations are not measures). +- Show a warning when debugging a Pivot Grid cell value or DAX query that includes calculation items in the filter context (which the TE3 debugger currently doesn't support). + +## Bugfixes in 3.16.0 + +- Pressing control-key combinations that do not have any keybinding assigned, should no longer cause special control chars to be inserted in code editors. +- Macros that have been modified and saved, should no longer execute multiple times when invoked through the UI. +- The `.Output()` method should now show the output dialog on subsequent macro executions, even when the **Don't show more outputs** option was checked on a previous execution. +- Unquoted table name references that also happen to be DAX keywords (such as `Currency`), will no longer be treated as keywords during auto-formatting (i.e. they will not be capitalized). Moreover, certain object properties in DAX scripts can now also be empty. View the updated [DAX Scripts documentation](https://docs.tabulareditor.com/te3/features/dax-scripts.html) for more information. +- Errors during DAX script execution are now handled gracefully, and the changes made by the script before the error was encountered, are automatically rolled back. +- Fixed a bug where macro buttons assigned to custom toolbars did not persist after restarting the application. +- Fixed a bug that would cause Tabular Editor to crash when using the `ForEach(IEnumerable, Action)` extension method in a C# script. +- Fixed bugs regarding removing/resetting shortcut keys, which did not work correctly for some commands. +- Fixed a bug where the Save button would remain disabled after a refresh operation finishes. +- Fixed a bug where certain actions could cause the **TOM Explorer** to lock up and not behave correctly until the application was restarted. +- Fixed a bug where deleting an object in the **TOM Explorer** would cause the selection to jump to the **Model** node, rather than the closest parent node of the deleted object. +- Fixed several bugs related to Pivot Grids. +- The semantic analyzer should no longer produce false errors when comparing against `BLANK()` in expressions such as `"string value" IN { BLANK() }`. +- Fixed a bug where changing serialization settings did not persist when a model was loaded from a TMDL folder. See [#1285](https://github.com/TabularEditor/TabularEditor3/issues/1285). +- When sorting a column in the Table Preview, where the column has `IsAvailableInMDX = false` (that is, no attribute hierarchies have been created for the column), we will now use `TOPN` queries to preview the data, since `TOPNSKIP` doesn't support sorting by columns with no attribute hierarchies. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_16_1_zh.md b/content/localization/zh/3_16_1_zh.md new file mode 100644 index 00000000..60258642 --- /dev/null +++ b/content/localization/zh/3_16_1_zh.md @@ -0,0 +1,109 @@ +--- +uid: release-3-16-1 +--- + +# Tabular Editor 3.16.1 + +## [**Downloads**](#tab/downloads) + +Tabular Editor 3.16.1 downloads: + +- Download [Tabular Editor 3.16.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.16.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.16.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x64.exe) | `4B15F2DA8097C7E57A31683B395EAF0BBC9E8ACAC7AF29A2B5018863421C4DBC` | +| [TabularEditor.3.16.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.msi) | `0B9D8C2007227C8242EF96137096C7D968DEE1FABEABC0D6F2E42BBE4C9FEEF3` | +| [TabularEditor.3.16.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.zip) | `12701D66A239697901A26682B040C01053FBBB18784EA67038366ACBC47DF75B` | +| [TabularEditor.3.16.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x86.exe) | `8828CD47EFA8BFFF9B02684D448238B153D57FE573B048A6A629309147672326` | +| [TabularEditor.3.16.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.msi) | `5C005602A10F0C56BE12ABB4DD77F55E9D59C87D826585C9E4DB93A3C6192E91` | +| [TabularEditor.3.16.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.zip) | `CCC8C425C9E604A9A52998143C0BFFC72D6492FD03F65922E1D8B5C60279F254` | + +*** + +## Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +## Bugfixes in 3.16.1 + +- Fixed a bug that prevented saved diagram files (.te3diag) from being opened correctly, see [#1313](https://github.com/TabularEditor/TabularEditor3/issues/1313) + +## Improvements in 3.16.1 + +- DAX query results now use the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. + +*** + +## New in 3.16.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +We have substantially overhauled how **Pivot Grids** work in this release. Some highlights include: + +- Pivot Grid layouts can now be saved and loaded to/from files! A new file format, `.te3pivot` is used to store a JSON representation of the Pivot Grid layout. +- Hidden objects (measures, columns, hierarchies) can now be used in a Pivot Grid, and object renames should no longer cause the Pivot Grid to lose its layout or clear any filters. +- A new and improved Pivot Grid **Field List**, which is now shown by default, and provides a more familiar experience when adding fields to the Pivot Grid. + +Head on over to the [Pivot Grid documentation](https://docs.tabulareditor.com/te3/features/pivot-grid.html) to learn more about these changes. + +## Improvements in 3.16.0 + +- Reduced the number of useless/redundant error messages that are shown, when DAX expression contain syntax/semantic errors. +- DAX scripts now support unspecified/empty expressions. This allows you to specify a DAX script that does not modify existing expressions on objects, or a script that explicitly sets an expression to be empty. +- You can now export DAX query results to CSV/Excel. Look for the **Export data** and **Export data (all results)** options under the **Query** menu. +- When exporting VertiPaq Analyzer statistics, we now suggest a default name for the VPAX file based on the database name. +- We changed the default keyboard shortcuts for `Editor.Dax.CollapseAllFolds`, `Editor.Dax.ExpandAllFolds` and `Editor.Dax.ToggleAllFolds` from **Ctrl+Alt+(key)** to **Ctrl+Shift+(key)**. This is to avoid conflicts with certain characters that require the **AltGr** key (which is equivalent to **Ctrl+Alt**) to be typed on non-US keyboards. The **Ctrl+Shift+(key)** shortcuts were previously used by `Editor.Dax.CollapseFold`, `Editor.Dax.ExpandFold` and `Editor.Dax.ToggleFold`. Their defaults have been changed to **Ctrl+(key)**. +- Updated [AMO/TOM to 19.80.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Menus and toolbars are now locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option. +- Our DAX semantic analyzer now supports the `WITH VISUAL SHAPE` syntax used in DAX queries that contain [visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview). Note that debugging such queries is not yet supported (as only measures can be debugged, and visual calculations are not measures). +- Show a warning when debugging a Pivot Grid cell value or DAX query that includes calculation items in the filter context (which the TE3 debugger currently doesn't support). + +## Bugfixes in 3.16.0 + +- Pressing control-key combinations that do not have any keybinding assigned, should no longer cause special control chars to be inserted in code editors. +- Macros that have been modified and saved, should no longer execute multiple times when invoked through the UI. +- The `.Output()` method should now show the output dialog on subsequent macro executions, even when the **Don't show more outputs** option was checked on a previous execution. +- Unquoted table name references that also happen to be DAX keywords (such as `Currency`), will no longer be treated as keywords during auto-formatting (i.e. they will not be capitalized). Moreover, certain object properties in DAX scripts can now also be empty. View the updated [DAX Scripts documentation](https://docs.tabulareditor.com/te3/features/dax-scripts.html) for more information. +- Errors during DAX script execution are now handled gracefully, and the changes made by the script before the error was encountered, are automatically rolled back. +- Fixed a bug where macro buttons assigned to custom toolbars did not persist after restarting the application. +- Fixed a bug that would cause Tabular Editor to crash when using the `ForEach(IEnumerable, Action)` extension method in a C# script. +- Fixed bugs regarding removing/resetting shortcut keys, which did not work correctly for some commands. +- Fixed a bug where the Save button would remain disabled after a refresh operation finishes. +- Fixed a bug where certain actions could cause the **TOM Explorer** to lock up and not behave correctly until the application was restarted. +- Fixed a bug where deleting an object in the **TOM Explorer** would cause the selection to jump to the **Model** node, rather than the closest parent node of the deleted object. +- Fixed several bugs related to Pivot Grids. +- The semantic analyzer should no longer produce false errors when comparing against `BLANK()` in expressions such as `"string value" IN { BLANK() }`. +- Fixed a bug where changing serialization settings did not persist when a model was loaded from a TMDL folder. See [#1285](https://github.com/TabularEditor/TabularEditor3/issues/1285). +- When sorting a column in the Table Preview, where the column has `IsAvailableInMDX = false` (that is, no attribute hierarchies have been created for the column), we will not fallback to issue `TOPN` queries, since `TOPNSKIP` doesn't support sorting by columns with no attribute hierarchies. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_16_2_zh.md b/content/localization/zh/3_16_2_zh.md new file mode 100644 index 00000000..8cded5ab --- /dev/null +++ b/content/localization/zh/3_16_2_zh.md @@ -0,0 +1,113 @@ +--- +uid: release-3-16-2 +--- + +# Tabular Editor 3.16.2 + +## [**Downloads**](#tab/downloads) + +Tabular Editor 3.16.2 downloads: + +- Download [Tabular Editor 3.16.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.16.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [TabularEditor.3.16.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x64.exe) | `C689921E84B7FC10E4154EBE117E279E7C08C56BE7859E3FE3ABB0BB78CF532A` | +| [TabularEditor.3.16.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.msi) | `CCDB6707961BC23D2AF25247CF05070FDF2BE92EA96068FF05B2A6228FADD829` | +| [TabularEditor.3.16.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.zip) | `67800E0FC678D534D29DDCB2EA0887062A7F2CD7D8E86F2B158AFCAB48394307` | +| [TabularEditor.3.16.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x86.exe) | `E197015F85F7ED06B53955855F65CF8E89E6DFDEDE4E98C3A25DAE777F7D3F55` | +| [TabularEditor.3.16.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.msi) | `8EE5B7D7A1E94545EC53161F7DF0D2369F0DAB7A568277C060E765B983D6D18E` | +| [TabularEditor.3.16.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.zip) | `C692605E970A0F5B5A37E85C6FD6CFE72AC4D6DFC4B9866899188B7C1AE6EBE6` | + +*** + +## Prerequisites + +Tabular Editor 3 uses .NET 6. If you're using the portable version, you may have to manually install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3. + +*** + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in 3.16. + +## Improvements in 3.16.2 + +- Rolled back [AMO/TOM to 19.79.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/19.79.1.1), as the 19.80.0 version introduced various issues related to MFA authentication and other XMLA connectivity issues. See [#1317](https://github.com/TabularEditor/TabularEditor3/issues/1317) and [#1322](https://github.com/TabularEditor/TabularEditor3/issues/1322). + +## Bugfixes in 3.16.1 + +- Fixed a bug that prevented saved diagram files (.te3diag) from being opened correctly, see [#1313](https://github.com/TabularEditor/TabularEditor3/issues/1313) + +## Improvements in 3.16.1 + +- DAX query results now show the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. + +## New in 3.16.0 + +We have substantially overhauled how **Pivot Grids** work in this release. Some highlights include: + +- Pivot Grid layouts can now be saved and loaded to/from files! A new file format, `.te3pivot` is used to store a JSON representation of the Pivot Grid layout. +- Hidden objects (measures, columns, hierarchies) can now be used in a Pivot Grid, and object renames should no longer cause the Pivot Grid to lose its layout or clear any filters. +- A new and improved Pivot Grid **Field List**, which is now shown by default, and provides a more familiar experience when adding fields to the Pivot Grid. + +Head on over to the [Pivot Grid documentation](https://docs.tabulareditor.com/te3/features/pivot-grid.html) to learn more about these changes. + +## Improvements in 3.16.0 + +- Reduced the number of useless/redundant error messages that are shown, when DAX expression contain syntax/semantic errors. +- DAX scripts now support unspecified/empty expressions. This allows you to specify a DAX script that does not modify existing expressions on objects, or a script that explicitly sets an expression to be empty. +- You can now export DAX query results to CSV/Excel. Look for the **Export data** and **Export data (all results)** options under the **Query** menu. +- When exporting VertiPaq Analyzer statistics, we now suggest a default name for the VPAX file based on the database name. +- We changed the default keyboard shortcuts for `Editor.Dax.CollapseAllFolds`, `Editor.Dax.ExpandAllFolds` and `Editor.Dax.ToggleAllFolds` from **Ctrl+Alt+(key)** to **Ctrl+Shift+(key)**. This is to avoid conflicts with certain characters that require the **AltGr** key (which is equivalent to **Ctrl+Alt**) to be typed on non-US keyboards. The **Ctrl+Shift+(key)** shortcuts were previously used by `Editor.Dax.CollapseFold`, `Editor.Dax.ExpandFold` and `Editor.Dax.ToggleFold`. Their defaults have been changed to **Ctrl+(key)**. +- Updated [AMO/TOM to 19.80.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Menus and toolbars are now locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option. +- Our DAX semantic analyzer now supports the `WITH VISUAL SHAPE` syntax used in DAX queries that contain [visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview). Note that debugging such queries is not yet supported (as only measures can be debugged, and visual calculations are not measures). +- Show a warning when debugging a Pivot Grid cell value or DAX query that includes calculation items in the filter context (which the TE3 debugger currently doesn't support). + +## Bugfixes in 3.16.0 + +- Pressing control-key combinations that do not have any keybinding assigned, should no longer cause special control chars to be inserted in code editors. +- Macros that have been modified and saved, should no longer execute multiple times when invoked through the UI. +- The `.Output()` method should now show the output dialog on subsequent macro executions, even when the **Don't show more outputs** option was checked on a previous execution. +- Unquoted table name references that also happen to be DAX keywords (such as `Currency`), will no longer be treated as keywords during auto-formatting (i.e. they will not be capitalized). Moreover, certain object properties in DAX scripts can now also be empty. View the updated [DAX Scripts documentation](https://docs.tabulareditor.com/te3/features/dax-scripts.html) for more information. +- Errors during DAX script execution are now handled gracefully, and the changes made by the script before the error was encountered, are automatically rolled back. +- Fixed a bug where macro buttons assigned to custom toolbars did not persist after restarting the application. +- Fixed a bug that would cause Tabular Editor to crash when using the `ForEach(IEnumerable, Action)` extension method in a C# script. +- Fixed bugs regarding removing/resetting shortcut keys, which did not work correctly for some commands. +- Fixed a bug where the Save button would remain disabled after a refresh operation finishes. +- Fixed a bug where certain actions could cause the **TOM Explorer** to lock up and not behave correctly until the application was restarted. +- Fixed a bug where deleting an object in the **TOM Explorer** would cause the selection to jump to the **Model** node, rather than the closest parent node of the deleted object. +- Fixed several bugs related to Pivot Grids. +- The semantic analyzer should no longer produce false errors when comparing against `BLANK()` in expressions such as `"string value" IN { BLANK() }`. +- Fixed a bug where changing serialization settings did not persist when a model was loaded from a TMDL folder. See [#1285](https://github.com/TabularEditor/TabularEditor3/issues/1285). +- When sorting a column in the Table Preview, where the column has `IsAvailableInMDX = false` (that is, no attribute hierarchies have been created for the column), we will not fallback to issue `TOPN` queries, since `TOPNSKIP` doesn't support sorting by columns with no attribute hierarchies. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_17_0_zh.md b/content/localization/zh/3_17_0_zh.md new file mode 100644 index 00000000..b559e81f --- /dev/null +++ b/content/localization/zh/3_17_0_zh.md @@ -0,0 +1,115 @@ +--- +uid: release-3-17-0 +--- + +# Tabular Editor 3.17.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.17.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.17.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.17.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.msi) + +Tabular Editor 3.17.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.17.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.exe) +- Download [Tabular Editor 3.17.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.17.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `9D0609022B672A1E47FF78D0DE2FA2C1451A1661E41D95391F33E6B5144BC58B` | +| [TabularEditor.3.17.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.msi) | .NET 8 | 64 bit | `8A9768B969A7D22D8956A11C6CF46AF78C6070B7153F08C44576360A7C278421` | +| [TabularEditor.3.17.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.zip) | .NET 8 | 64 bit | `7E279D9395D3F7EB426293589414D520033CE8621C2364882489080D07DB81A1` | +| [TabularEditor.3.17.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `0FAD1867F9496F3DCDC6B31AA163451102C42CFA6C5FE05B89114C76DD568ACA` | +| [TabularEditor.3.17.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.msi) | .NET 8 | 32 bit | `6CFD937E0B69F56800FF0411AAEA65CA2109316D4B1B2231E41634CBCEDDB096` | +| [TabularEditor.3.17.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.zip) | .NET 8 | 32 bit | `A81F137DE5EB572A06DB93865CB75818A595A80B30E486232A395ED5BABD114F` | +| [TabularEditor.3.17.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.exe) | .NET 6 | 64 bit | `4594B299DC4469EB5767F542F7CD242A10A7C89DEB52AE5987DACDE75B7C985C` | +| [TabularEditor.3.17.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.msi) | .NET 6 | 64 bit | `F77CEC56BAA47ACB1B981CB6C4117A4F3BC5C803C65532A7D4AEDFF03EA45E93` | +| [TabularEditor.3.17.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.zip) | .NET 6 | 64 bit | `C5B8A3F5AEBA292E3390036399BDC8551093A9030379D3BE359676EDF660C643` | +| [TabularEditor.3.17.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.exe) | .NET 6 | 32 bit | `34889BAE93D1C1E6C1BD7FCBF7B82F02DE974018B8C123D260EF894D0954F454` | +| [TabularEditor.3.17.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.msi) | .NET 6 | 32 bit | `28D167AF729AB0C1BAD6F76A010F5907DE7A5717B01E0ADAD7CBFB1ADD0E7917` | +| [TabularEditor.3.17.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.zip) | .NET 6 | 32 bit | `DED76DB0F699B6024F1AF768D32DF134B8D5CFED1B33C489FD2BE0349DD931CA` | + +*** + +## New in 3.17.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/08/14/tabular-editor-3-august-2024-release) to get a brief overview of the most important updates in this release. + +- We're excited to let you know, that Tabular Editor 3 is now available for [.NET 8](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8/overview). We will continue to support .NET 6 until the end of 2024, however we recommend switching to the .NET 8 version as soon as possible. In our testing, the .NET 8 version starts up ~20% faster, while also consuming less memory. +- The portable builds of Tabular Editor 3 now include the relevant .NET runtime, so you no longer need to install the .NET 6/8 Windows Desktop runtime separately. + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Improvements in 3.17.0 + +- DAX query results and table previews now show the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. +- Shared expressions can now be excluded from being deployed using the Deployment Wizard. This enhancement allows you to retain existing shared expressions on the destination server as-is, when deploying a model, even if shared expressions were created/deleted/modified in the model being deployed. +- The DAX debugger **Locals** window now lets you "inspect" results, similar to the **Watch** window. By default, inspector results are shown in a popup dialog rather than as a new DAX Query, but you can control this behavior under **Tools > Preferences > DAX Debugger**. Click the magnifying glass icon next to the value in the **Locals** or **Watch** view to inspect the value. See the updated [DAX Debugger documentation](xref:dax-debugger#locals) for more information. +- When debugging a scalar predicate in a filter argument of [`CALCULATE`](https://dax.guide/calculate) or [`CALCULATETABLE`](https://dax.guide/calculatetable), the **Locals** view now shows additional details about the scalar predicate and the resulting filter expression. See the updated [DAX Debugger documentation](xref:dax-debugger#scalar-predicates) for more information. +- DAX scripts can now be applied when the script contains semantic errors. A warning will be shown if there are any semantic errors to make the end user aware if they want to proceed with the current errors or cancel and fix the semantic errors. Syntax errors, on the other hand, will still prevent the script from being applied. +- Added auto-complete support for a few more DAX `INFO.*` functions. +- The DAX Optimizer Integration (Preview) feature now lets you switch between personal or group accounts in group licensing scenarios. You can choose which account you want to use, through the **Options** dropdow menu. See also [#1288](https://github.com/TabularEditor/TabularEditor3/issues/1288). Moreover, you can now change the _Fixed_ or _Ignored_ status of an issue directly from the DAX Optimizer Results view. +- The Table Import Wizard and Update Table Schema feature now supports **Databricks Multicloud**, in addition to **Azure Databricks**. For more information, see the discussion on [#1347](https://github.com/TabularEditor/TabularEditor3/discussions/1347). +- The Preferences for the VertiPaq Analyzer were expanded to configure the column batch size. This preference controls the number of columns processed at a time during column statistics analysis and it can be found under **Tools > Preferences > VertiPaq Analyzer**. The default value for this preference is 50. +- Custom formatting applied to Pivot Grids (icons, data bars, highlighted cells, etc.) is now preserved when the Pivot Grid layout is saved to a file and later reloaded. +- Pivot Grids now also preserve any sorting applied to fields when the grid is refreshed or when the grid layout is saved to a file and later reloaded. + +## Bugfixes in 3.17.0 + +- Fixed an bug introduced in 3.16.0, which caused an application freeze for several seconds after loading a diagram file (.te3diag) +- Fixed an issue that prevented saving the options in the "Find/Replace" dialog box between sessions, when using the "Find all" button. Now, the last search preferences will be retained in the next session. +- Fixed an issue that prevented the deployment of deletions for data sources, roles, and role members to an existing model. Previously, the corresponding checkboxes in the Deployment Wizard were disabled when there were no data sources or roles in the model. Now, these checkboxes remain enabled when deploying changes to an existing model, allowing for the deployment of these object's deletions. +- Fixed an issue that prevented files with the .ovpax extension from opening as a file or model. The possibility to open .ovpax files and models is now supported. +- Fixed a bug where the wrong file type might have been suggested by the file dialog window when exporting obfuscated files from the VertiPaq Analyzer. Now, when exporting an obfuscated file, the save dialog will correctly suggest using the ".ovpax" extension. +- Fixed a bug where toolbar buttons would stay disabled when the Expression Editor was docked as a tool window rather than as a document tab. +- Fixed a bug that prevented opening semantic models saved as ".tmdl" with [Power BI Project files (PBIP)](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview). +- Fixed a bug that caused the application to hang during manual activation. +- Macro recorder should no longer generate duplicate code. Moreover, the recorder should now also generate code when objects are deleted. +- **Auto formatting** settings for **DAX Editors**, including DAX Query, DAX Script, and DAX expressions in the Expression Editor, are now applied instantly, without the need to restart the application. +- Fixed an issue where unchecking the **Encrypt connection** option did not disable encryption in the connection string for Microsoft SQL Server data sources. +- Fixed a bug where ODBC username and password were not added to the connection string when importing tables or updating table schema. This issue would prevent users from importing tables or updating table schema when using ODBC connections against some data sources, such as Snowflake or Oracle. +- Fixed a bug where it was not possible to list the ODBC DSNs when importing tables, if no User DSNs were present on the machine. +- When querying schema information from an ODBC source, we now use various fallbacks, which should improve compatibility with more ODBC drivers, such as the Oracle in OraClient12Home1 driver. +- Fixed a bug where data sources referenced in M queries would appear as implicit data sources in the Import Table Wizard. +- Fixed a bug where some Pivot Grid toolbar buttons would remain disabled, after a Pivot Grid was reloaded from a file. +- Fixed a bug where constants in M expressions (such as `Order.Ascending`) would result in an **Unknown identifier** error, when using the **Update Table Schema** feature. See [#1362](https://github.com/TabularEditor/TabularEditor3/issues/1362). +- When using the DAX `DIVIDE` function with a non-numeric 3rd argument, the DAX parser now correctly determines the resulting data type to be Variant. +- Fixed a bug that prevented Tabular Editor from loading model metadata from a TMDL folder with no database.tmdl file. + +> [!NOTE] +> Microsoft has announced that [TMDL is in GA](https://powerbi.microsoft.com/en-us/blog/announcing-general-availability-of-tabular-model-definition-language-tmdl/) as of August 2nd, 2024. Please note that Tabular Editor 3 is using a version of the [AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/19.79.1.1), which was released before TMDL was announced as GA. This version should still be fully compatible with TMDL, however, we recommend keeping a backup of your TMSL (.bim) files, just in case. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_17_1_zh.md b/content/localization/zh/3_17_1_zh.md new file mode 100644 index 00000000..2d2e31d5 --- /dev/null +++ b/content/localization/zh/3_17_1_zh.md @@ -0,0 +1,119 @@ +--- +uid: release-3-17-1 +--- + +# Tabular Editor 3.17.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.17.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.17.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.17.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.msi) + +Tabular Editor 3.17.1 **.NET 6** downloads: + +- Download [Tabular Editor 3.17.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.exe) +- Download [Tabular Editor 3.17.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.17.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `484500CF3604481EA6815430FAEFE25239A38AF0718A9C512D162C9CEE54D062` | +| [TabularEditor.3.17.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.msi) | .NET 8 | 64 bit | `F3B299C413B9016737AA355B0122FA70E960878AD5AC741FC8062FCDA4FAB03D` | +| [TabularEditor.3.17.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.zip) | .NET 8 | 64 bit | `3F339FA67969BF2E40C8A1DAAD31CDB138635B3F6B9ACE624CBD4C99EC2150E4` | +| [TabularEditor.3.17.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `27F4720A2A2B8C5374ECD1EE5FF8B8C6CBC18D24871FC189FD31D894C9CF21A4` | +| [TabularEditor.3.17.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.msi) | .NET 8 | 32 bit | `790C81816CD91E2F8AD0550B5425A21751BC62BA2FDA50F09F0FC1FEC8DB00F4` | +| [TabularEditor.3.17.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.zip) | .NET 8 | 32 bit | `3669E1275CB5A9796178BFA12A3BE300FB95E4574EFD196F56301826893282AB` | +| [TabularEditor.3.17.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.exe) | .NET 6 | 64 bit | `1A8D105C0E0568C759B8B927EB33F0E6BB7C65D5670F07A8FC745BAF609227C0` | +| [TabularEditor.3.17.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.msi) | .NET 6 | 64 bit | `E8BFF47E4C023B79C5320291135E9BF498F34F8B86D668E1CA0B04381826DF26` | +| [TabularEditor.3.17.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.zip) | .NET 6 | 64 bit | `DCED49B7C1247FBCF3003FC034A8BCB1760CB7082BC3FB3FA20F9E3041A0C9D4` | +| [TabularEditor.3.17.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.exe) | .NET 6 | 32 bit | `E1795E02E9DD33902BBF5C7ABD8FFD939CFBC9EFFCDFE13888E3AE25B3BFE3EC` | +| [TabularEditor.3.17.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.msi) | .NET 6 | 32 bit | `0194C67FC4F81F9A5AF8A379A75A68F6FE063378887A439F63F18EB43690F866` | +| [TabularEditor.3.17.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.zip) | .NET 6 | 32 bit | `21D1C7DA741D4153694A30588B488FB62D2129B06906E4FC7CA95EB3A063A9F1` | + +*** + +## Bugfixes in 3.17.1 + +- Fixed a bug related to OS regional settings, which would cause a crash upon entering the **Preferences** dialog for the first time. + +## New in 3.17.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/08/14/tabular-editor-3-august-2024-release) to get a brief overview of the most important updates in this release. + +- We're excited to let you know, that Tabular Editor 3 is now available for [.NET 8](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8/overview). We will continue to support .NET 6 until the end of 2024, however we recommend switching to the .NET 8 version as soon as possible. In our testing, the .NET 8 version starts up ~20% faster, while also consuming less memory. +- The portable builds of Tabular Editor 3 now include the relevant .NET runtime, so you no longer need to install the .NET 6/8 Windows Desktop runtime separately. + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Improvements in 3.17.0 + +- DAX query results and table previews now show the "long time format" for datetime values, rather than "short time". This way, seconds are also shown in the result grid. +- Shared expressions can now be excluded from being deployed using the Deployment Wizard. This enhancement allows you to retain existing shared expressions on the destination server as-is, when deploying a model, even if shared expressions were created/deleted/modified in the model being deployed. +- The DAX debugger **Locals** window now lets you "inspect" results, similar to the **Watch** window. By default, inspector results are shown in a popup dialog rather than as a new DAX Query, but you can control this behavior under **Tools > Preferences > DAX Debugger**. Click the magnifying glass icon next to the value in the **Locals** or **Watch** view to inspect the value. See the updated [DAX Debugger documentation](xref:dax-debugger#locals) for more information. +- When debugging a scalar predicate in a filter argument of [`CALCULATE`](https://dax.guide/calculate) or [`CALCULATETABLE`](https://dax.guide/calculatetable), the **Locals** view now shows additional details about the scalar predicate and the resulting filter expression. See the updated [DAX Debugger documentation](xref:dax-debugger#scalar-predicates) for more information. +- DAX scripts can now be applied when the script contains semantic errors. A warning will be shown if there are any semantic errors to make the end user aware if they want to proceed with the current errors or cancel and fix the semantic errors. Syntax errors, on the other hand, will still prevent the script from being applied. +- Added auto-complete support for a few more DAX `INFO.*` functions. +- The DAX Optimizer Integration (Preview) feature now lets you switch between personal or group accounts in group licensing scenarios. You can choose which account you want to use, through the **Options** dropdow menu. See also [#1288](https://github.com/TabularEditor/TabularEditor3/issues/1288). Moreover, you can now change the _Fixed_ or _Ignored_ status of an issue directly from the DAX Optimizer Results view. +- The Table Import Wizard and Update Table Schema feature now supports **Databricks Multicloud**, in addition to **Azure Databricks**. For more information, see the discussion on [#1347](https://github.com/TabularEditor/TabularEditor3/discussions/1347). +- The Preferences for the VertiPaq Analyzer were expanded to configure the column batch size. This preference controls the number of columns processed at a time during column statistics analysis and it can be found under **Tools > Preferences > VertiPaq Analyzer**. The default value for this preference is 50. +- Custom formatting applied to Pivot Grids (icons, data bars, highlighted cells, etc.) is now preserved when the Pivot Grid layout is saved to a file and later reloaded. +- Pivot Grids now also preserve any sorting applied to fields when the grid is refreshed or when the grid layout is saved to a file and later reloaded. + +## Bugfixes in 3.17.0 + +- Fixed an bug introduced in 3.16.0, which caused an application freeze for several seconds after loading a diagram file (.te3diag) +- Fixed an issue that prevented saving the options in the "Find/Replace" dialog box between sessions, when using the "Find all" button. Now, the last search preferences will be retained in the next session. +- Fixed an issue that prevented the deployment of deletions for data sources, roles, and role members to an existing model. Previously, the corresponding checkboxes in the Deployment Wizard were disabled when there were no data sources or roles in the model. Now, these checkboxes remain enabled when deploying changes to an existing model, allowing for the deployment of these object's deletions. +- Fixed an issue that prevented files with the .ovpax extension from opening as a file or model. The possibility to open .ovpax files and models is now supported. +- Fixed a bug where the wrong file type might have been suggested by the file dialog window when exporting obfuscated files from the VertiPaq Analyzer. Now, when exporting an obfuscated file, the save dialog will correctly suggest using the ".ovpax" extension. +- Fixed a bug where toolbar buttons would stay disabled when the Expression Editor was docked as a tool window rather than as a document tab. +- Fixed a bug that prevented opening semantic models saved as ".tmdl" with [Power BI Project files (PBIP)](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview). +- Fixed a bug that caused the application to hang during manual activation. +- Macro recorder should no longer generate duplicate code. Moreover, the recorder should now also generate code when objects are deleted. +- **Auto formatting** settings for **DAX Editors**, including DAX Query, DAX Script, and DAX expressions in the Expression Editor, are now applied instantly, without the need to restart the application. +- Fixed an issue where unchecking the **Encrypt connection** option did not disable encryption in the connection string for Microsoft SQL Server data sources. +- Fixed a bug where ODBC username and password were not added to the connection string when importing tables or updating table schema. This issue would prevent users from importing tables or updating table schema when using ODBC connections against some data sources, such as Snowflake or Oracle. +- Fixed a bug where it was not possible to list the ODBC DSNs when importing tables, if no User DSNs were present on the machine. +- When querying schema information from an ODBC source, we now use various fallbacks, which should improve compatibility with more ODBC drivers, such as the Oracle in OraClient12Home1 driver. +- Fixed a bug where data sources referenced in M queries would appear as implicit data sources in the Import Table Wizard. +- Fixed a bug where some Pivot Grid toolbar buttons would remain disabled, after a Pivot Grid was reloaded from a file. +- Fixed a bug where constants in M expressions (such as `Order.Ascending`) would result in an **Unknown identifier** error, when using the **Update Table Schema** feature. See [#1362](https://github.com/TabularEditor/TabularEditor3/issues/1362). +- When using the DAX `DIVIDE` function with a non-numeric 3rd argument, the DAX parser now correctly determines the resulting data type to be Variant. +- Fixed a bug that prevented Tabular Editor from loading model metadata from a TMDL folder with no database.tmdl file. + +> [!NOTE] +> Microsoft has announced that [TMDL is in GA](https://powerbi.microsoft.com/en-us/blog/announcing-general-availability-of-tabular-model-definition-language-tmdl/) as of August 2nd, 2024. Please note that Tabular Editor 3 is using a version of the [AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/19.79.1.1), which was released before TMDL was announced as GA. This version should still be fully compatible with TMDL, however, we recommend keeping a backup of your TMSL (.bim) files, just in case. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_18_0_zh.md b/content/localization/zh/3_18_0_zh.md new file mode 100644 index 00000000..db4a88e2 --- /dev/null +++ b/content/localization/zh/3_18_0_zh.md @@ -0,0 +1,105 @@ +--- +uid: release-3-18-0 +--- + +# Tabular Editor 3.18.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.18.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.18.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.18.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.msi) + +Tabular Editor 3.18.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.18.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.exe) +- Download [Tabular Editor 3.18.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.18.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `BFA440499E7B3FC985971CD0E7FD3BA4C0E8B72CF4A4EA338C6452F1C4E0C6C9` | +| [TabularEditor.3.18.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.msi) | .NET 8 | 64 bit | `9B7FD24086ECA00CA21FE0534AC2AFB1F742181B318E0CC772956F4422E49FC7` | +| [TabularEditor.3.18.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.zip) | .NET 8 | 64 bit | `E69C894268FFEAFB52CFD87DD0D8F265816D1B334159D8F60B69800853221351` | +| [TabularEditor.3.18.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `666D717326A87358C285F6C3E57D213B812A7913935A2332E08C57572DE5CB81` | +| [TabularEditor.3.18.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.msi) | .NET 8 | 32 bit | `C0FCC0A23CDEA32383287F3E54A849A2830B79985E5DF3C597643AD8F9239555` | +| [TabularEditor.3.18.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.zip) | .NET 8 | 32 bit | `CF6FAF0E370B50CD9D87D2FD0B262B013F1B69DA321297D52D7D2B28F299350C` | +| [TabularEditor.3.18.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.exe) | .NET 6 | 64 bit | `79AF51FD6AB6F55ACAEC9A468D05B3D8FE061A7D68DBBF2C11D52683D72D693B` | +| [TabularEditor.3.18.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.msi) | .NET 6 | 64 bit | `3A5C8CBAEFF09F802C4B3F176349ECA3611CEDD70A7554450C31BCB45920C6C4` | +| [TabularEditor.3.18.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.zip) | .NET 6 | 64 bit | `538DF3C2A5DB59E2DA728EE857C57C2BBB2CBCFE749230FA50971D333145E223` | +| [TabularEditor.3.18.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.exe) | .NET 6 | 32 bit | `CB3BC45D7E44A689B6242F34463C4BE6179709E846867635CAFCBD3E0A15CCF6` | +| [TabularEditor.3.18.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.msi) | .NET 6 | 32 bit | `221BA75A2C3277732B65576572AF498FEDA0E64A00075E0B194AF9A7E16C9CBF` | +| [TabularEditor.3.18.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.zip) | .NET 6 | 32 bit | `02DF85DF19B4FF360413412A08020485BF40CFA5AD9BD4F99489D3D93664C1CB` | + +*** + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.18.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/10/31/tabular-editor-3-october-2024-release) to get a brief overview of the most important updates in this release. + +- Our **DAX Optimizer integration** is now out of preview, and we've also made a few updates, so that it now supports the [new evaluation metrics that were part of DAX Optimizer 1.2](https://www.tabulartools.com/blog/introducing-new-evaluation-metrics-in-dax-optimizer-1-2/). Oh, and by the way - all **Enterprise Edition** Tabular Editor 3 users now get 4 free DAX Optimizer runs per day. Download Tabular Editor 3.18.0 from one of the links above, and get your DAX Optimizer redemption code through the **Help > About Tabular Editor** menu item. +- We're happy to introduce a new feature across all DAX editors in Tabular Editor 3: **Code Actions**. This productivity feature discretely provides suggestions for improving your DAX code and lets you apply the suggestion with a single click. For example, the feature can be used to remove unused variables, follow best practices for column and measure references, rewrite table filters as [more efficient column filters](https://www.sqlbi.com/articles/filter-columns-not-tables-in-dax/), and [much, much more](xref:code-actions). We plan to add additional actions in future releases, so stay tuned! +- After we upgraded to the [latest version of the Microsoft AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices/), the behavior of the **Integrated** authentication option changed, such that the Entra ID account selector/MFA popup is no longer shown, if the Windows OS is already connected to an Entra ID account. As such, we've added a new authentication option, **Microsoft Entra MFA**, which will force the account selector/MFA popup to appear, letting you choose a different account than the one currently logged in to Windows, if needed. + +## Improvements in 3.18.0 + +- The user interface preferences have been expanded to allow hiding model source details from the title bar, helping to protect sensitive information during recordings and presentations. +- The user interface preferences now include a new "Recent Items" section. This section enables customization of the number of recent files and models displayed in the file menu and the servers displayed in recent connections. The new preferences also allow clearing these items. +- The Semantic Analyzer now shows a warning if a variable is used directly as the 1st argument of [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE). Since variables are unaffected by context transitions or modified filter contexts, using a variable this way is most likely unintentional. +- Our SQL editor now uses an improved color scheme, making it easier to distinguish SQL keywords from identifiers. +- Upgraded AMO/TOM and other dependencies to their latest versions. +- We're now using Compatibility Level 1606 for new Power BI / Fabric semantic models. At this level, a new Model property [ValueFilterBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.valuefilterbehaviortype?view=analysisservices-dotnet) is available, which can be used to control the _auto-exist_ behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/SUMMARIZECOLUMNS). +- We've added support for the TOM [ChangedProperties](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.changedproperty?view=analysisservices-dotnet) collection (on Tables, Measures, Columns, and a few other objects). This collection is used on composite or Direct Lake models, to indicate that a property (such as a column **Name**) has changed, and should no longer be synchronized from the underlying source. +- Upgraded VertiPaq Analyzer to latest version [(1.7.2)](https://github.com/sql-bi/VertiPaq-Analyzer/releases/tag/v1.7.2), which fixes an issue regarding extracting stats on a model containing Field Parameters / Group By Columns. +- Upgraded our version of the Snowflake .NET connector to v. 4.1.0. This addresses the following vulnerabilities: [CVE-2023-34230](https://nvd.nist.gov/vuln/detail/CVE-2023-34230) and [CVE-2023-51662](https://nvd.nist.gov/vuln/detail/CVE-2023-51662). +- The diagram component should now be considerably faster when working with large diagrams with many relationships. +- Columns in the Data Preview can now be hidden by right-clicking on the column header and selecting "Hide This Column". To show hidden columns, right-click on a column header and select "Column chooser". This will bring up a window from where you can access previously hidden columns. + +## Bugfixes in 3.18.0 + +- Fixed a bug where the "Server" dropdown in the **Load semantic model from database** dialog would not show recently used servers. +- Data Preview settings (sort order, filters, etc.) are now preserved after refreshing the preview, resolving a previous bug where settings were not maintained. +- Fixed a crash which could happen when undoing (Ctrl+Z) while or immediately after using the "Rename" refactoring in a DAX editor. +- The main UI is now properly locked from user interactions while the "Please wait" dialog is shown, such as when performing a table schema update. +- Semantic Analyzer should no longer show a warning when referencing the internal "FormatString" measure in a DAX expression. As a consequence, it is now possible to debug queries that contain such references (even though the FormatString expression itself cannot currently be debugged), see [#1377](https://github.com/TabularEditor/TabularEditor3/issues/1377). + +## Known issues in 3.18.0 + +- If you're getting the error message **Can't obtain account information for '(e-mail)' while trying to refresh the token.** it usually helps to perform the operation again. This is an issue in the newer versions of the AMO/TOM client libraries. You should also be able to avoid this issue by choosing the **Microsoft Entra MFA** authentication option, instead of the **Integrated** option, when initially connecting. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor your DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_18_1_zh.md b/content/localization/zh/3_18_1_zh.md new file mode 100644 index 00000000..4b78f67b --- /dev/null +++ b/content/localization/zh/3_18_1_zh.md @@ -0,0 +1,122 @@ +--- +uid: release-3-18-1 +--- + +# Tabular Editor 3.18.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.18.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.18.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.18.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.msi) + +Tabular Editor 3.18.1 **.NET 6** downloads: + +- Download [Tabular Editor 3.18.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.exe) +- Download [Tabular Editor 3.18.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.18.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `BA7D2450DC4DC48BD04679828C47799E4036D3E28EE2B7B8FEB3AD84372C81B8` | +| [TabularEditor.3.18.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.msi) | .NET 8 | 64 bit | `BD8763B06EE2F8D821EC4491D1931DF5F9AEA52109F99400EA1E7556DA86A9A4` | +| [TabularEditor.3.18.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.zip) | .NET 8 | 64 bit | `24FF4ABC8EF8D890CE182FBB346A210F480EB9343123C37292258DDD97418F82` | +| [TabularEditor.3.18.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `F184D2F50FCA465230DB05237196AEF3B75286726ABF8CC05181023D0BB91289` | +| [TabularEditor.3.18.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.msi) | .NET 8 | 32 bit | `293D34EF6AF79102C89AA65579D06A169AB955FD75F55BEED919EC5C2A49E319` | +| [TabularEditor.3.18.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.zip) | .NET 8 | 32 bit | `3E3D185C5BEB2A6F32F6851AED5FB9696F012B83CE57D144FC0F4F361DB8DFC5` | +| [TabularEditor.3.18.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.exe) | .NET 6 | 64 bit | `E56BE607444CC2EDBB5328C3BDFED965EA5713BE48D4A9FA06A9011413BA4679` | +| [TabularEditor.3.18.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.msi) | .NET 6 | 64 bit | `8850C65EBA73A9EE89D0FCE4976681FB9CEBCA6F46170B6D0AD6198CBFC3D61E` | +| [TabularEditor.3.18.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.zip) | .NET 6 | 64 bit | `0BA57CFF5C0E928B2CE4EC69CDB8C3CF7273E5CA4FAA083BC58FD763636AD52F` | +| [TabularEditor.3.18.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.exe) | .NET 6 | 32 bit | `5813FF7B483594191150D32377A24C85ABD172BE1C7C1D3520A1B223E1646F4D` | +| [TabularEditor.3.18.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.msi) | .NET 6 | 32 bit | `E097DC640265B4F1DF9B867EDB28CBAE2BD474DCC766DE7333ACA354CEEAA318` | +| [TabularEditor.3.18.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.zip) | .NET 6 | 32 bit | `4D811E4D0EF0ACE08C7155F8F9A2613C8F5F861026E5ADFF9AE1F6794EE3D399` | + +*** + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Improvements in 3.18.1 + +- The Semantic Analyzer no longer displays an error when using a table table name as the name of a variable. **Note:** as of this writing, the ability to use table names for variables is supported in Power BI Desktop (October 2024) and in the Power BI Service. You can control the error behavior under **Tools > Preferences > DAX Editor > DAX Settings > Table-named variables**. +- We've updated the AMO/TOM client libraries to the latest version [19.86.6](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.86.6). This should fix the **Can't obtain account information for '(e-mail)' while trying to refresh the token.** issue that some users have experienced while connected to the Power BI XMLA endpoint, see [#1387](https://github.com/TabularEditor/TabularEditor3/issues/1387). +- A new option under **Tools > Preferences > Power BI** let you specify the default authentication mode to use when connecting to Power BI / Fabric workspaces or Azure Analysis Services. This lets you, for example, specify `Microsoft Entra MFA` by default, forcing the account selector/MFA popup to show up when connecting. +- For multi-user licenses, we now show an option to change the license key, if the number of users on the license has been exceeded. This way, you no longer have to manually reset the license key [through the Windows registry](https://docs.tabulareditor.com/te3/getting-started.html#changing-a-license-key-through-the-registry). + +## Bugfixes in 3.18.1 + +- When attempting to connect to the DAX Optimizer service with a Tabular Tools account that has not been completely set up, we now show a more descriptive error message, instead of throwing an unhandled exception. +- Fixed a bug where VPAX files created in Tabular Editor 3 would be reported as being corrupted when opened in the DAX Optimizer service. +- Fixed a bug where an empty VPAX file was uploaded to the DAX Optimizer service, if the collection of VPAX statistics failed during the upload process. +- Fixed a bug where semantic engine features were not always updated for the **Expression Editor**, when opening a new model (potentially causing false errors to appear in the editor). +- Semantic Analyzer should no longer cause an "An item with the same key has already been added." exception in models with complex, nested DAX expressions, see [#1390](https://github.com/TabularEditor/TabularEditor3/issues/1390) and [#1393](https://github.com/TabularEditor/TabularEditor3/issues/1393). +- Semantic Analyzer now correctly infers the data type of an expression such as `SELECTEDVALUE('MyTable'[String Column], BLANK())` (in this case, the resulting data type should be **String**, but previously it was inferred as **Variant**). +- Fixed a bug where the **Simplify variable** code actions would produce code that was not semantically equivalent to the original code. Moreover, this action will no longer cause a "loop" of code actions to be applied, see [#1386](https://github.com/TabularEditor/TabularEditor3/issues/1386). + +## New in 3.18.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/10/31/tabular-editor-3-october-2024-release) to get a brief overview of the most important updates in this release. + +- Our **DAX Optimizer integration** is now out of preview, and we've also made a few updates, so that it now supports the [new evaluation metrics that were part of DAX Optimizer 1.2](https://www.tabulartools.com/blog/introducing-new-evaluation-metrics-in-dax-optimizer-1-2/). Oh, and by the way - all **Enterprise Edition** Tabular Editor 3 users now get 4 free DAX Optimizer runs per day. Download Tabular Editor 3.18.0 from one of the links above, and get your DAX Optimizer redemption code through the **Help > About Tabular Editor** menu item. +- We're happy to introduce a new feature across all DAX editors in Tabular Editor 3: **Code Actions**. This productivity feature discretely provides suggestions for improving your DAX code and lets you apply the suggestion with a single click. For example, the feature can be used to remove unused variables, follow best practices for column and measure references, rewrite table filters as [more efficient column filters](https://www.sqlbi.com/articles/filter-columns-not-tables-in-dax/), and [much, much more](xref:code-actions). We plan to add additional actions in future releases, so stay tuned! +- After we upgraded to the [latest version of the Microsoft AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices/), the behavior of the **Integrated** authentication option changed, such that the Entra ID account selector/MFA popup is no longer shown, if the Windows OS is already connected to an Entra ID account. As such, we've added a new authentication option, **Microsoft Entra MFA**, which will force the account selector/MFA popup to appear, letting you choose a different account than the one currently logged in to Windows, if needed. + +## Improvements in 3.18.0 + +- The user interface preferences have been expanded to allow hiding model source details from the title bar, helping to protect sensitive information during recordings and presentations. +- The user interface preferences now include a new "Recent Items" section. This section enables customization of the number of recent files and models displayed in the file menu and the servers displayed in recent connections. The new preferences also allow clearing these items. +- The Semantic Analyzer now shows a warning if a variable is used directly as the 1st argument of [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE). Since variables are unaffected by context transitions or modified filter contexts, using a variable this way is most likely unintentional. +- Our SQL editor now uses an improved color scheme, making it easier to distinguish SQL keywords from identifiers. +- Upgraded AMO/TOM and other dependencies to their latest versions. +- We're now using Compatibility Level 1606 for new Power BI / Fabric semantic models. At this level, a new Model property [ValueFilterBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.valuefilterbehaviortype?view=analysisservices-dotnet) is available, which can be used to control the _auto-exist_ behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/SUMMARIZECOLUMNS). +- We've added support for the TOM [ChangedProperties](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.changedproperty?view=analysisservices-dotnet) collection (on Tables, Measures, Columns, and a few other objects). This collection is used on composite or Direct Lake models, to indicate that a property (such as a column **Name**) has changed, and should no longer be synchronized from the underlying source. +- Upgraded VertiPaq Analyzer to latest version [(1.7.2)](https://github.com/sql-bi/VertiPaq-Analyzer/releases/tag/v1.7.2), which fixes an issue regarding extracting stats on a model containing Field Parameters / Group By Columns. +- Upgraded our version of the Snowflake .NET connector to v. 4.1.0. This addresses the following vulnerabilities: [CVE-2023-34230](https://nvd.nist.gov/vuln/detail/CVE-2023-34230) and [CVE-2023-51662](https://nvd.nist.gov/vuln/detail/CVE-2023-51662). +- The diagram component should now be considerably faster when working with large diagrams with many relationships. +- Columns in the Data Preview can now be hidden by right-clicking on the column header and selecting "Hide This Column". To show hidden columns, right-click on a column header and select "Column chooser". This will bring up a window from where you can access previously hidden columns. + +## Bugfixes in 3.18.0 + +- Fixed a bug where the "Server" dropdown in the **Load semantic model from database** dialog would not show recently used servers. +- Data Preview settings (sort order, filters, etc.) are now preserved after refreshing the preview, resolving a previous bug where settings were not maintained. +- Fixed a crash which could happen when undoing (Ctrl+Z) while or immediately after using the "Rename" refactoring in a DAX editor. +- The main UI is now properly locked from user interactions while the "Please wait" dialog is shown, such as when performing a table schema update. +- Semantic Analyzer should no longer show a warning when referencing the internal "FormatString" measure in a DAX expression. As a consequence, it is now possible to debug queries that contain such references (even though the FormatString expression itself cannot currently be debugged), see [#1377](https://github.com/TabularEditor/TabularEditor3/issues/1377). + +## Known issues in 3.18.0 + +- If you're getting the error message **Can't obtain account information for '(e-mail)' while trying to refresh the token.** it usually helps to perform the operation again. This is an issue in the newer versions of the AMO/TOM client libraries. You should also be able to avoid this issue by choosing the **Microsoft Entra MFA** authentication option, instead of the **Integrated** option, when initially connecting. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor your DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_18_2_zh.md b/content/localization/zh/3_18_2_zh.md new file mode 100644 index 00000000..912da159 --- /dev/null +++ b/content/localization/zh/3_18_2_zh.md @@ -0,0 +1,127 @@ +--- +uid: release-3-18-2 +--- + +# Tabular Editor 3.18.2 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.18.2 **.NET 8** downloads: + +- Download [Tabular Editor 3.18.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.18.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.msi) + +Tabular Editor 3.18.2 **.NET 6** downloads: + +- Download [Tabular Editor 3.18.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.exe) +- Download [Tabular Editor 3.18.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.18.2.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `A01E48D94F299EF1007CB9448EC032CC71BBAC6C70635F3B4FECE28912B7864A` | +| [TabularEditor.3.18.2.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.msi) | .NET 8 | 64 bit | `2EFEEE533A9ABD7CA0B318B7121F8B96D8ED8F6240273F1F85F143021FADD8C6` | +| [TabularEditor.3.18.2.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.zip) | .NET 8 | 64 bit | `B48731C3F6A931FF4F4DE464FBEB33A36E2AF47CEA70CBA5AAF0248B776E59B9` | +| [TabularEditor.3.18.2.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `461FD252C968D7F5DFA8056DC8BD8B4180F4CF45C47E4131501A868E7E70797A` | +| [TabularEditor.3.18.2.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.msi) | .NET 8 | 32 bit | `BDAB08680B239046CCBCB727AA0E884D2711AD0A87713B512BEDE628C23667DB` | +| [TabularEditor.3.18.2.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.zip) | .NET 8 | 32 bit | `A50CA2CC53B659BB8B29A9FFE78B1FD1A91FEFC65C5D507E0506D2AFE35F56CC` | +| [TabularEditor.3.18.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.exe) | .NET 6 | 64 bit | `57FA61B26152CF6DB811E316943D97D4467DB336301C6520423F695A862547A1` | +| [TabularEditor.3.18.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.msi) | .NET 6 | 64 bit | `F4E6C8E4C895AB364D3DCF0926175F981E7A1DBD8F7F7D83C5831B96450E8AE2` | +| [TabularEditor.3.18.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.zip) | .NET 6 | 64 bit | `4B83EB04FCF2E82433A4B76FBA260485A4FAE15F84920C4197D2C502BA98D090` | +| [TabularEditor.3.18.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.exe) | .NET 6 | 32 bit | `2609223F9D88E5229E09C9A6A5AA7E419EBD2D57719E38B7A5E9E05E78D6AC3B` | +| [TabularEditor.3.18.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.msi) | .NET 6 | 32 bit | `223FF7F181EF2F633274295E54B2D2C2D442D675404158BE27BEB37F6B5B1CB4` | +| [TabularEditor.3.18.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.zip) | .NET 6 | 32 bit | `7884B5649DE1A1A78163C9AD6A50F2BE9B6BBD5949E1F5C53503A2C857819EA7` | + +*** + +> [!IMPORTANT] +> .NET 6 will be going [out-of-support in November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## Bugfixes in 3.18.2 + +- Fixed a regression related to OS regional settings, which would cause a crash upon entering the Preferences dialog for the first time. +- Fix flickering in the Data Refresh view and show proper warning icon for warning messages in the output + +## Improvements in 3.18.1 + +- The Semantic Analyzer no longer displays an error when using a table table name as the name of a variable. **Note:** as of this writing, the ability to use table names for variables is supported in Power BI Desktop (October 2024) and in the Power BI Service. You can control the error behavior under **Tools > Preferences > DAX Editor > DAX Settings > Table-named variables**. +- We've updated the AMO/TOM client libraries to the latest version [19.86.6](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.86.6). This should fix the **Can't obtain account information for '(e-mail)' while trying to refresh the token.** issue that some users have experienced while connected to the Power BI XMLA endpoint, see [#1387](https://github.com/TabularEditor/TabularEditor3/issues/1387). +- A new option under **Tools > Preferences > Power BI** let you specify the default authentication mode to use when connecting to Power BI / Fabric workspaces or Azure Analysis Services. This lets you, for example, specify `Microsoft Entra MFA` by default, forcing the account selector/MFA popup to show up when connecting. +- For multi-user licenses, we now show an option to change the license key, if the number of users on the license has been exceeded. This way, you no longer have to manually reset the license key [through the Windows registry](https://docs.tabulareditor.com/te3/getting-started.html#changing-a-license-key-through-the-registry). + +## Bugfixes in 3.18.1 + +- When attempting to connect to the DAX Optimizer service with a Tabular Tools account that has not been completely set up, we now show a more descriptive error message, instead of throwing an unhandled exception. +- Fixed a bug where VPAX files created in Tabular Editor 3 would be reported as being corrupted when opened in the DAX Optimizer service. +- Fixed a bug where an empty VPAX file was uploaded to the DAX Optimizer service, if the collection of VPAX statistics failed during the upload process. +- Fixed a bug where semantic engine features were not always updated for the **Expression Editor**, when opening a new model (potentially causing false errors to appear in the editor). +- Semantic Analyzer should no longer cause an "An item with the same key has already been added." exception in models with complex, nested DAX expressions, see [#1390](https://github.com/TabularEditor/TabularEditor3/issues/1390) and [#1393](https://github.com/TabularEditor/TabularEditor3/issues/1393). +- Semantic Analyzer now correctly infers the data type of an expression such as `SELECTEDVALUE('MyTable'[String Column], BLANK())` (in this case, the resulting data type should be **String**, but previously it was inferred as **Variant**). +- Fixed a bug where the **Simplify variable** code actions would produce code that was not semantically equivalent to the original code. Moreover, this action will no longer cause a "loop" of code actions to be applied, see [#1386](https://github.com/TabularEditor/TabularEditor3/issues/1386). + +## New in 3.18.0 + +Check out our [release blog](https://blog.tabulareditor.com/2024/10/31/tabular-editor-3-october-2024-release) to get a brief overview of the most important updates in this release. + +- Our **DAX Optimizer integration** is now out of preview, and we've also made a few updates, so that it now supports the [new evaluation metrics that were part of DAX Optimizer 1.2](https://www.tabulartools.com/blog/introducing-new-evaluation-metrics-in-dax-optimizer-1-2/). Oh, and by the way - all **Enterprise Edition** Tabular Editor 3 users now get 4 free DAX Optimizer runs per day. Download Tabular Editor 3.18.0 from one of the links above, and get your DAX Optimizer redemption code through the **Help > About Tabular Editor** menu item. +- We're happy to introduce a new feature across all DAX editors in Tabular Editor 3: **Code Actions**. This productivity feature discretely provides suggestions for improving your DAX code and lets you apply the suggestion with a single click. For example, the feature can be used to remove unused variables, follow best practices for column and measure references, rewrite table filters as [more efficient column filters](https://www.sqlbi.com/articles/filter-columns-not-tables-in-dax/), and [much, much more](xref:code-actions). We plan to add additional actions in future releases, so stay tuned! +- After we upgraded to the [latest version of the Microsoft AMO/TOM client library](https://www.nuget.org/packages/Microsoft.AnalysisServices/), the behavior of the **Integrated** authentication option changed, such that the Entra ID account selector/MFA popup is no longer shown, if the Windows OS is already connected to an Entra ID account. As such, we've added a new authentication option, **Microsoft Entra MFA**, which will force the account selector/MFA popup to appear, letting you choose a different account than the one currently logged in to Windows, if needed. + +## Improvements in 3.18.0 + +- The user interface preferences have been expanded to allow hiding model source details from the title bar, helping to protect sensitive information during recordings and presentations. +- The user interface preferences now include a new "Recent Items" section. This section enables customization of the number of recent files and models displayed in the file menu and the servers displayed in recent connections. The new preferences also allow clearing these items. +- The Semantic Analyzer now shows a warning if a variable is used directly as the 1st argument of [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE). Since variables are unaffected by context transitions or modified filter contexts, using a variable this way is most likely unintentional. +- Our SQL editor now uses an improved color scheme, making it easier to distinguish SQL keywords from identifiers. +- Upgraded AMO/TOM and other dependencies to their latest versions. +- We're now using Compatibility Level 1606 for new Power BI / Fabric semantic models. At this level, a new Model property [ValueFilterBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.valuefilterbehaviortype?view=analysisservices-dotnet) is available, which can be used to control the _auto-exist_ behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/SUMMARIZECOLUMNS). +- We've added support for the TOM [ChangedProperties](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.changedproperty?view=analysisservices-dotnet) collection (on Tables, Measures, Columns, and a few other objects). This collection is used on composite or Direct Lake models, to indicate that a property (such as a column **Name**) has changed, and should no longer be synchronized from the underlying source. +- Upgraded VertiPaq Analyzer to latest version [(1.7.2)](https://github.com/sql-bi/VertiPaq-Analyzer/releases/tag/v1.7.2), which fixes an issue regarding extracting stats on a model containing Field Parameters / Group By Columns. +- Upgraded our version of the Snowflake .NET connector to v. 4.1.0. This addresses the following vulnerabilities: [CVE-2023-34230](https://nvd.nist.gov/vuln/detail/CVE-2023-34230) and [CVE-2023-51662](https://nvd.nist.gov/vuln/detail/CVE-2023-51662). +- The diagram component should now be considerably faster when working with large diagrams with many relationships. +- Columns in the Data Preview can now be hidden by right-clicking on the column header and selecting "Hide This Column". To show hidden columns, right-click on a column header and select "Column chooser". This will bring up a window from where you can access previously hidden columns. + +## Bugfixes in 3.18.0 + +- Fixed a bug where the "Server" dropdown in the **Load semantic model from database** dialog would not show recently used servers. +- Data Preview settings (sort order, filters, etc.) are now preserved after refreshing the preview, resolving a previous bug where settings were not maintained. +- Fixed a crash which could happen when undoing (Ctrl+Z) while or immediately after using the "Rename" refactoring in a DAX editor. +- The main UI is now properly locked from user interactions while the "Please wait" dialog is shown, such as when performing a table schema update. +- Semantic Analyzer should no longer show a warning when referencing the internal "FormatString" measure in a DAX expression. As a consequence, it is now possible to debug queries that contain such references (even though the FormatString expression itself cannot currently be debugged), see [#1377](https://github.com/TabularEditor/TabularEditor3/issues/1377). + +## Known issues in 3.18.0 + +- If you're getting the error message **Can't obtain account information for '(e-mail)' while trying to refresh the token.** it usually helps to perform the operation again. This is an issue in the newer versions of the AMO/TOM client libraries. You should also be able to avoid this issue by choosing the **Microsoft Entra MFA** authentication option, instead of the **Integrated** option, when initially connecting. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor your DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_19_0_zh.md b/content/localization/zh/3_19_0_zh.md new file mode 100644 index 00000000..3ecec622 --- /dev/null +++ b/content/localization/zh/3_19_0_zh.md @@ -0,0 +1,115 @@ +--- +uid: release-3-19-0 +--- + +# Tabular Editor 3.19.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.19.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.19.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.19.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.msi) + +Tabular Editor 3.19.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.19.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.exe) +- Download [Tabular Editor 3.19.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.19.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `8F5B7C34E176EC2A62B2E5A9DE661DFC8B10FC2590BBBFAB14EC9D06B147A0AC` | +| [TabularEditor.3.19.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.msi) | .NET 8 | 64 bit | `20E4BFFCB4075251706D0C93C3A2C62F4E7A7A400BFCBA910EA1481DB5FBF1C6` | +| [TabularEditor.3.19.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.zip) | .NET 8 | 64 bit | `96C35863B2A269E51C805FF587422C68774CF85B941F5F026214CE3397452865` | +| [TabularEditor.3.19.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `C1A05DBDBF519F648BD9A93397604E3434CB535C719CD8742C94A7A375754FC7` | +| [TabularEditor.3.19.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.msi) | .NET 8 | 32 bit | `220A0F308176CCBAE275550D385EB494EB25EC1EE4012D50F25327E5BE1AB446` | +| [TabularEditor.3.19.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.zip) | .NET 8 | 32 bit | `5033510733AD854E0DB8F1E07E67772ACC4674CDD877DBAE85AA0A11483FB8DA` | +| [TabularEditor.3.19.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.exe) | .NET 6 | 64 bit | `D46E23C0A07DCE8F23CBC68E761EE3080614E0B074387A890AD96F3BAA4C44C9` | +| [TabularEditor.3.19.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.msi) | .NET 6 | 64 bit | `D4232D572749D526AB12D8A9585CAE67B26BE5074D3FC080C440B08CC4F956BF` | +| [TabularEditor.3.19.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.zip) | .NET 6 | 64 bit | `20633917724A65B4BED74BEDBF079156461727DD61272A40E304B7E11717775F` | +| [TabularEditor.3.19.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.exe) | .NET 6 | 32 bit | `BF36180EB0CAEDCAFB858A44C011FBB78B9754A3F4FC4945BBC647DCD36AC9E3` | +| [TabularEditor.3.19.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.msi) | .NET 6 | 32 bit | `2087C1A2261955ED7390A56ED9FF6009DA8CFE036752C272F6AC8D7E35A22657` | +| [TabularEditor.3.19.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.zip) | .NET 6 | 32 bit | `1724276318F02CC12782E4F8225722B1410A9797AE6871C26C29F59D40EE0A0B` | + +*** + +> [!IMPORTANT] +> .NET 6 is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization to plan ahead, as we will no longer be providing .NET 6 builds of Tabular Editor 3 after December 2024. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.19.0 + +This release is all about quality-of-life improvements and bugfixes. + +Check out our [release blog](https://blog.tabulareditor.com/2024/12/19/tabular-editor-3-december-2024-release/) for a brief overview and a video showing the most important updates in this release. + +- Our DAX code editors now support the **Expand selection** shortcut (Ctrl+Shift+E), which expands the selection to the next logical code block. This is useful, for example, when the cursor is inside a DAX function call, and you want to select the entire function call. Repeatedly pressing Ctrl+Shift+E will expand the selection to the next logical code block, eventually selecting the entire DAX expression. +- We've modified how execution of DAX queries work, due to [popular demand](https://github.com/TabularEditor/TabularEditor3/discussions/1359): + - The **Execute** action (F5) will now execute only the selected portion of the query when text is selected. If no text is selected, the entire query will be executed. + - **Execute Selection** (Shift+F5) will also execute the selected portion similar to the **Execute** action above, but when nothing is selected this action only executes the `EVALUATE` statement under the cursor. + - We've introduced an **Execute full query** action (no default keybinding), in case you need a way to execute the full query without changing your current selection. + - Last, but certainly not least, you can now _execute partial code_. To do this, simply select a portion of code, such as a table or scalar expression anywhere inside your query (even in comments) and hit F5. Tabular Editor will take care of wrapping scalar expressions in curly braces, wrapping column references in a call to [`DISTINCT`](https://dax.guide/DISTINCT), and adding the `EVALUATE` statement, such that a valid DAX query will be sent to the server. +- Across all of our DAX editors, the vertical scrollbar will now indicate the location of any warnings/errors, as well as applicable [Code Actions](xref:code-actions) in the **Improvements** and **Readability** categories. Mouse over the scrollbar indicator to see a tooltip with a description of the issue, and click to navigate directly to it. This is especially useful when working with large DAX expressions, queries or scripts. If you find this feature distracting, it can be toggled off under **Tools > Preferences > Text Editors > Show indicators on scrollbar**. +- Pin, Unpin, and Delete functionality for the Recent Files and Recent Models menus: Added the ability to pin items to the top of the "Recent Files" and "Recent Models" menus, unpin them, or delete them entirely using a new right-click pop-up menu. Pinned items are visually marked with an icon and prioritized at the top of the menus. + +> [!NOTE] +> As a reminder, all shortcuts can be customized under **Tools > Preferences > Keyboard**. The shortcut keys mentioned in this document are the default settings. + +## Improvements in 3.19.0 + +- We have improved the **Data Refresh** view so progress events that relate to the same table, are now being grouped together. This makes it easier to understand the progress of the refresh operation, especially when refreshing large models with many tables. +- When jumping to a specific line of code outside the range of code currently visible in the editor, we now scroll the editor such that the destination line is vertically placed at the center of the editor, rather than near the top/bottom. +- A new right-click menu action has been added to the DAX query results grid, which will let you show the actual query that was executed (as Tabular Editor may modify the query to add a row limit, or to turn a partial selection into a valid query as mentioned above). +- The "Load Semantic Model from Database" dialog now restores preferences for recently connected servers, including Authentication mode, username (excluding passwords), connection mode, and status bar color. +- Updated AMO/TOM to [19.87.2](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.87.2). +- Our offline schema detection (based on our M query parser) now fully supports the use of `PowerPlatform.Dataflows`, see [#970](https://github.com/TabularEditor/TabularEditor3/issues/970). +- When copying/duplicating tables in the model, the inserted table is typically renamed (to ensure uniqueness of table names in the model). When this happens, we now automatically fix-up DAX expressions of objects within that table. For example, calculated columns or Row-Level Security filter expressions on the table, are now updated to use the name of the inserted table. You can toggle off this behavior under **Tools > Preferences > Modeling operations > Clipboard operations**. +- The summary page of the **Deployment Wizard** has been slightly improved, so that it now shows the source and destination Compatibility Levels in case they differ. It also shows a warning icon and a tooltip if the source Compatibility Level is lower than the destination. + +## Bugfixes in 3.19.0 + +- The **Data Refresh** view will no longer scroll to the top when new progress events are added to the list. +- Data Refresh operations are disabled when connected to a model in Power BI Desktop, as Desktop does not support refresh operations initiated from external tools. +- Fixed an issue with the [**Rewrite table filter as scalar predicate**](https://docs.tabulareditor.com/te3/features/code-actions.html#improvements) code action not properly qualifying columns with the table name after the rewrite, potentially causing the resulting DAX to be invalid. +- Fixed an issue with the [**Split multi-column filter into multiple filters**](https://docs.tabulareditor.com/te3/features/code-actions.html#improvements) action, where filters would be deleted, when the original filter contained more than 2 operands. +- When hitting F12 (Go to definition) on an object reference inside a **DAX Script**, the editor will now correctly jump to the object definition inside the script (if it is present), rather than switch to the **Expression Editor**. +- When connected to the Power BI XMLA endpoint or an instance of Azure Analysis Services, attempting to impersonate multiple roles in a Pivot Grid, a Data Preview, or a DAX Query, should now work correctly (instead of only the first role in the list being applied). +- Various bugfixes in the M analyzer, to support more complex M queries for purposes of offline schema detection. For example, we are now able to correctly infer the table schema resulting from an M query that uses a custom function, such as the one in [this discussion](https://github.com/TabularEditor/TabularEditor3/discussions/1413#discussioncomment-11532634). +- Fixed a bug which would cause a crash when selecting both a table and a column (in another table) in the TOM Explorer, and then invoking the right-click menu. +- Fixed an issue where clicking the "Back" button in the deployment wizard after selecting the Microsoft Entra MFA authentication option incorrectly triggered a login pop-up. The "Back" button now properly navigates to the previous step without attempting to authenticate. +- Fixed "Object reference not set to an instance of an object" bug when clicking on the "Export build..." button in the **Deployment Wizard** (regression in 3.17.0). +- Fixed the _JSON DDL request failed: Unrecognised JSON Property: expressions_-error upon deploying a model against Analysis Services on SQL Server 2016 or 2017, while the "Deploy shared expressions" option was unchecked. +- Fixed the _Value cannot be null. (Parameter 'source')_ when attempting to import or update the table schema from a Dataflows entity that does not define any columns. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_1_0_zh.md b/content/localization/zh/3_1_0_zh.md new file mode 100644 index 00000000..79223bfd --- /dev/null +++ b/content/localization/zh/3_1_0_zh.md @@ -0,0 +1,67 @@ +# Tabular Editor 3.1.0 + +- Download [Tabular Editor 3.1.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.0](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.0.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +**NOTE:** If you previously installed one of the BETA builds, you will have to manually uninstall that before installing this new version. + +## New features in 3.1.0 + +- The Table Import Wizard is finally here! And it's better than ever before. Read [this article](https://docs.tabulareditor.com/te3/importing-tables.html) for more information. It currently works for SQL, ODBC and OLE DB, but let us know if you need support for other types of data sources. +- Offline (i.e. without being connected to Analysis Services) detection of table schema changes now works - even for M partitions and implicit data sources. +- Objects can now be shown/hidden in perspectives through the TOM context menu, similar to TE2. +- The Import/Export translations option is now available, similar to TE2. +- Added the Batch Rename Dialog, similar to TE2 (the dialog shows up when selecting multiple objects and hitting "F2" for rename). +- Added the Mark as Date Table dialog, similar to TE2. + +## Improvements in 3.1.0 + +- Copying a single cell from a DAX query result now formats the value such that it can be easily pasted into a DAX expression, see [#200](https://github.com/TabularEditor/TabularEditor3/issues/200). +- Added "Delete relationship" option to diagram context menu, see [#195](https://github.com/TabularEditor/TabularEditor3/issues/195). +- Added "Remove field" option to Pivot Grid context menu. +- Model-wide actions such as Create Table, Refresh, Import Tables, etc. are now available through the "Model" menu. +- AuthenticationKind property on Structured Data Sources now has a dropdown. The Options property can now be edited as well and the Query property has been exposed. +- TOM Explorer context menu items have been rearranged to align better with TE2. +- Role members can now be edited directly by right-clicking on a role. +- Dependencies can now be copied from the Dependency View to either Text/JSON format, similar to TE2. +- New skin palette options for the "Basic" and "Bezier" skins (which are vector based, and thus look much better in Hi-DPI than the VS-like skins). Find the new palettes at the bottom of the "Window" menu. + +## Bugfixes in 3.1.0 + +- Fixed an issue with the Select Database dialog when sorting the databases, see [#201](https://github.com/TabularEditor/TabularEditor3/issues/201). +- Fixed a crash with the Select Display Folder dialog, see [#199](https://github.com/TabularEditor/TabularEditor3/issues/199). +- Fixed a crash when switching from the Classic workspace, see [#198](https://github.com/TabularEditor/TabularEditor3/issues/198). +- Translations and perspective info is now retained when dragging/dropping calculated columns or measures between tables, see [#194](https://github.com/TabularEditor/TabularEditor3/issues/194). +- Fixed an issue with unwanted newlines in M code, see [#193](https://github.com/TabularEditor/TabularEditor3/issues/193). +- Fixed a focus issue with the Add Table to Diagram dialog, see [#183](https://github.com/TabularEditor/TabularEditor3/issues/183). +- Fixed a crash when right-clicking various places in a Pivot Grid, see [#175](https://github.com/TabularEditor/TabularEditor3/issues/175). +- Fixed an issue with unwanted TOM refreshes from interfering external change traces. +- Fixed an issue with Workspace Mode warning about Unsaved Changes +- Remove memberId property when deploying roles, see [TE2 #906](https://github.com/TabularEditor/TabularEditor/issues/906). +- Fixed issue with TOM Explorer copy/paste ops (possible related to [#184](https://github.com/TabularEditor/TabularEditor/issues/184)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_1_1_zh.md b/content/localization/zh/3_1_1_zh.md new file mode 100644 index 00000000..aca7b216 --- /dev/null +++ b/content/localization/zh/3_1_1_zh.md @@ -0,0 +1,62 @@ +# Tabular Editor 3.1.1 + +- Download [Tabular Editor 3.1.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.1](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.1.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.1 + +- Shared Expressions (Power Query / M expressions) can now be serialized as individual files. You can control the serialization under **Tools > Preferences > Save-to-folder** or for an existing model under **Model > Serialization options...** ([#218](https://github.com/TabularEditor/TabularEditor3/issues/218)) +- New options for controlling how perspective memberships are applied to new objects under **Tools > Preferences > Modeling Operations** (see issue [#216](https://github.com/TabularEditor/TabularEditor3/issues/216)). +- `PrivacySetting` property can now be excluded from serialization, to prevent issues with Microsoft.AnalysisServices.Deployment. This is controlled under **Model > Serialization options...** (see issue [#210](https://github.com/TabularEditor/TabularEditor3/issues/210)). +- You can now define enums, structs and classes directly within a C# script, making it easier to structure and reuse C# code. +- VertiPaq Analyzer now has an option to collect statistics from data (**Tools > Preferences > VertiPaq Analyzer**), improving the quality of the statistics, for example when columns have IsAvailableInMDX = false. See issue [#190](https://github.com/TabularEditor/TabularEditor3/issues/290). +- When a new model is created, Tabular Editor 3 now prompts if the model should be saved as a file or folder, the first time it is saved. You can also set the default mode under **Tools > Preferences > General > Default save format for new models**. See issue [#50](https://github.com/TabularEditor/TabularEditor3/issues/50). +- Improved startup performance (some users have reported additional startup time gains by adding the `-multicorejit` switch to the TabularEditor3.exe shortcut). +- Restructured the "Model" menu to make options such as "New calculation group" readily available. +- Updated AMO/TOM client libraries to [19.26.1.7](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Model Role Members can now be iterated individually in the Best Practice Analyzer +- "Workspace" within the "Window" menu has been renamed to "Layout" to avoid confusion with [Workspace Mode](https://docs.tabulareditor.com/te3/tutorials/workspace-mode.html). +- Added Ctrl+Shift+D as a shortcut for "Deploy" +- Support for new DAX functions ([`HASH`](https://dax.guide/hash), [`NAMEOF`](https://dax.guide/nameof), [`COLUMNSTATISTICS`](https://dax.guide/columnstatistics), [`BITAND`](https://dax.guide/bitand), [`BITLSHIFT`](https://dax.guide/bitlshift), [`BITOR`](https://dax.guide/bitor), [`BITRSHIFT`](https://dax.guide/bitrshift), [`BITXOR`](https://dax.guide/bitxor)) and support for optional column name parameter in [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). + +## Bugfixes in 3.1.1 + +- TOM Explorer should no longer freeze or crash when deleting objects (see issues [#223](https://github.com/TabularEditor/TabularEditor3/issues/223), [#209](https://github.com/TabularEditor/TabularEditor3/issues/209)). +- Fixed a color issue with dark themes in editors ([#207](https://github.com/TabularEditor/TabularEditor3/issues/207)) and icons ([#215](https://github.com/TabularEditor/TabularEditor3/issues/215)) +- Tables are now sorted alphabetically in the "Create/Edit Relationship" dialog (see issue [#214](https://github.com/TabularEditor/TabularEditor3/issues/214) +- Fixed an issue with C# scripts that prevented saving them as macros (see issue [#208](https://github.com/TabularEditor/TabularEditor3/issues/208)). +- Fixed an issue with data source passwords/credentials not being properly applied to workspace database (see issue [#205](https://github.com/TabularEditor/TabularEditor3/issues/205)). +- "Select all columns" checkbox should no longer cause a crash (see issue [#204](https://github.com/TabularEditor/TabularEditor3/issues/204)). +- Tabular Editor now always looks in the installation directory when a script references external DLL's (using the `#r` precompiler directive), see issue [#192](https://github.com/TabularEditor/TabularEditor3/issues/192). +- Fixed a bug with linguistic schema that caused Q&A to stop working some cases +- Filtering on a date column in Data Preview should no longer cause a crash +- When selecting all perspectives in the TOM Explorer perspectives-dropdown, objects that do not included in any perspectives are no longer shown. Also fixed an issue with the dropdown box not updating perspective names. +- Allow using certain DAX keywords as variables (`WEEK`, `DAY`, `INTEGER`, etc.) without showing an error. +- Fix issue with serialization options not being stored the first time a model is saved. +- Fixed an issue with the DAX parser which would cause a crash upon loading a model (see [#229](https://github.com/TabularEditor/TabularEditor3/issues/229)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_1_2_zh.md b/content/localization/zh/3_1_2_zh.md new file mode 100644 index 00000000..913d4ed4 --- /dev/null +++ b/content/localization/zh/3_1_2_zh.md @@ -0,0 +1,69 @@ +# Tabular Editor 3.1.2 + +- Download [Tabular Editor 3.1.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.2](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.2.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Bugfixes in 3.1.2 + +- Fixed an issue with Update Table Schema not working for SQL DW / Synapse SQL Pool data sources, see [#231](https://github.com/TabularEditor/TabularEditor3/issues/231). +- Fixed an issue where ignored rules were still considered by the Best Practice Analyzer, see [#203](https://github.com/TabularEditor/TabularEditor3/issues/203). +- Fixed an issue where models could not be saved to disk (file or folder) due to a JSON serialization error, see [#232](https://github.com/TabularEditor/TabularEditor3/issues/232). +- Fixed an issue that caused a crash when inspecting the property values of a Structured Data Source. + +## Improvements in 3.1.1 + +- Shared Expressions (Power Query / M expressions) can now be serialized as individual files. You can control the serialization under **Tools > Preferences > Save-to-folder** or for an existing model under **Model > Serialization options...** ([#218](https://github.com/TabularEditor/TabularEditor3/issues/218)) +- New options for controlling how perspective memberships are applied to new objects under **Tools > Preferences > Modeling Operations** (see issue [#216](https://github.com/TabularEditor/TabularEditor3/issues/216)). +- `PrivacySetting` property can now be excluded from serialization, to prevent issues with Microsoft.AnalysisServices.Deployment. This is controlled under **Model > Serialization options...** (see issue [#210](https://github.com/TabularEditor/TabularEditor3/issues/210)). +- You can now define enums, structs and classes directly within a C# script, making it easier to structure and reuse C# code. +- VertiPaq Analyzer now has an option to collect statistics from data (**Tools > Preferences > VertiPaq Analyzer**), improving the quality of the statistics, for example when columns have IsAvailableInMDX = false. See issue [#190](https://github.com/TabularEditor/TabularEditor3/issues/290). +- When a new model is created, Tabular Editor 3 now prompts if the model should be saved as a file or folder, the first time it is saved. You can also set the default mode under **Tools > Preferences > General > Default save format for new models**. See issue [#50](https://github.com/TabularEditor/TabularEditor3/issues/50). +- Improved startup performance (some users have reported additional startup time gains by adding the `-multicorejit` switch to the TabularEditor3.exe shortcut). +- Restructured the "Model" menu to make options such as "New calculation group" readily available. +- Updated AMO/TOM client libraries to [19.26.1.7](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Model Role Members can now be iterated individually in the Best Practice Analyzer +- "Workspace" within the "Window" menu has been renamed to "Layout" to avoid confusion with [Workspace Mode](https://docs.tabulareditor.com/te3/tutorials/workspace-mode.html). +- Added Ctrl+Shift+D as a shortcut for "Deploy" +- Support for new DAX functions ([`HASH`](https://dax.guide/hash), [`NAMEOF`](https://dax.guide/nameof), [`COLUMNSTATISTICS`](https://dax.guide/columnstatistics), [`BITAND`](https://dax.guide/bitand), [`BITLSHIFT`](https://dax.guide/bitlshift), [`BITOR`](https://dax.guide/bitor), [`BITRSHIFT`](https://dax.guide/bitrshift), [`BITXOR`](https://dax.guide/bitxor)) and support for optional column name parameter in [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). + +## Bugfixes in 3.1.1 + +- TOM Explorer should no longer freeze or crash when deleting objects (see issues [#223](https://github.com/TabularEditor/TabularEditor3/issues/223), [#209](https://github.com/TabularEditor/TabularEditor3/issues/209)). +- Fixed a color issue with dark themes in editors ([#207](https://github.com/TabularEditor/TabularEditor3/issues/207)) and icons ([#215](https://github.com/TabularEditor/TabularEditor3/issues/215)) +- Tables are now sorted alphabetically in the "Create/Edit Relationship" dialog (see issue [#214](https://github.com/TabularEditor/TabularEditor3/issues/214) +- Fixed an issue with C# scripts that prevented saving them as macros (see issue [#208](https://github.com/TabularEditor/TabularEditor3/issues/208)). +- Fixed an issue with data source passwords/credentials not being properly applied to workspace database (see issue [#205](https://github.com/TabularEditor/TabularEditor3/issues/205)). +- "Select all columns" checkbox should no longer cause a crash (see issue [#204](https://github.com/TabularEditor/TabularEditor3/issues/204)). +- Tabular Editor now always looks in the installation directory when a script references external DLL's (using the `#r` precompiler directive), see issue [#192](https://github.com/TabularEditor/TabularEditor3/issues/192). +- Fixed a bug with linguistic schema that caused Q&A to stop working some cases +- Filtering on a date column in Data Preview should no longer cause a crash +- When selecting all perspectives in the TOM Explorer perspectives-dropdown, objects that do not included in any perspectives are no longer shown. Also fixed an issue with the dropdown box not updating perspective names. +- Allow using certain DAX keywords as variables (`WEEK`, `DAY`, `INTEGER`, etc.) without showing an error. +- Fix issue with serialization options not being stored the first time a model is saved. +- Fixed an issue with the DAX parser which would cause a crash upon loading a model (see [#229](https://github.com/TabularEditor/TabularEditor3/issues/229)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_1_3_zh.md b/content/localization/zh/3_1_3_zh.md new file mode 100644 index 00000000..93cf4fc9 --- /dev/null +++ b/content/localization/zh/3_1_3_zh.md @@ -0,0 +1,73 @@ +# Tabular Editor 3.1.3 + +- Download [Tabular Editor 3.1.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.3](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Bugfixes in 3.1.3 + +- Fixed a memory leak that occurs when the application is idle. This issue has existed since v. 3.1.1. + +## Bugfixes in 3.1.2 + +- Fixed an issue with Update Table Schema not working for SQL DW / Synapse SQL Pool data sources, see [#231](https://github.com/TabularEditor/TabularEditor3/issues/231). +- Fixed an issue where ignored rules were still considered by the Best Practice Analyzer, see [#203](https://github.com/TabularEditor/TabularEditor3/issues/203). +- Fixed an issue where models could not be saved to disk (file or folder) due to a JSON serialization error, see [#232](https://github.com/TabularEditor/TabularEditor3/issues/232). +- Fixed an issue that caused a crash when inspecting the property values of a Structured Data Source. + +## Improvements in 3.1.1 + +- Shared Expressions (Power Query / M expressions) can now be serialized as individual files. You can control the serialization under **Tools > Preferences > Save-to-folder** or for an existing model under **Model > Serialization options...** ([#218](https://github.com/TabularEditor/TabularEditor3/issues/218)) +- New options for controlling how perspective memberships are applied to new objects under **Tools > Preferences > Modeling Operations** (see issue [#216](https://github.com/TabularEditor/TabularEditor3/issues/216)). +- `PrivacySetting` property can now be excluded from serialization, to prevent issues with Microsoft.AnalysisServices.Deployment. This is controlled under **Model > Serialization options...** (see issue [#210](https://github.com/TabularEditor/TabularEditor3/issues/210)). +- You can now define enums, structs and classes directly within a C# script, making it easier to structure and reuse C# code. +- VertiPaq Analyzer now has an option to collect statistics from data (**Tools > Preferences > VertiPaq Analyzer**), improving the quality of the statistics, for example when columns have IsAvailableInMDX = false. See issue [#190](https://github.com/TabularEditor/TabularEditor3/issues/290). +- When a new model is created, Tabular Editor 3 now prompts if the model should be saved as a file or folder, the first time it is saved. You can also set the default mode under **Tools > Preferences > General > Default save format for new models**. See issue [#50](https://github.com/TabularEditor/TabularEditor3/issues/50). +- Improved startup performance (some users have reported additional startup time gains by adding the `-multicorejit` switch to the TabularEditor3.exe shortcut). +- Restructured the "Model" menu to make options such as "New calculation group" readily available. +- Updated AMO/TOM client libraries to [19.26.1.7](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Model Role Members can now be iterated individually in the Best Practice Analyzer +- "Workspace" within the "Window" menu has been renamed to "Layout" to avoid confusion with [Workspace Mode](https://docs.tabulareditor.com/te3/tutorials/workspace-mode.html). +- Added Ctrl+Shift+D as a shortcut for "Deploy" +- Support for new DAX functions ([`HASH`](https://dax.guide/hash), [`NAMEOF`](https://dax.guide/nameof), [`COLUMNSTATISTICS`](https://dax.guide/columnstatistics), [`BITAND`](https://dax.guide/bitand), [`BITLSHIFT`](https://dax.guide/bitlshift), [`BITOR`](https://dax.guide/bitor), [`BITRSHIFT`](https://dax.guide/bitrshift), [`BITXOR`](https://dax.guide/bitxor)) and support for optional column name parameter in [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). + +## Bugfixes in 3.1.1 + +- TOM Explorer should no longer freeze or crash when deleting objects (see issues [#223](https://github.com/TabularEditor/TabularEditor3/issues/223), [#209](https://github.com/TabularEditor/TabularEditor3/issues/209)). +- Fixed a color issue with dark themes in editors ([#207](https://github.com/TabularEditor/TabularEditor3/issues/207)) and icons ([#215](https://github.com/TabularEditor/TabularEditor3/issues/215)) +- Tables are now sorted alphabetically in the "Create/Edit Relationship" dialog (see issue [#214](https://github.com/TabularEditor/TabularEditor3/issues/214) +- Fixed an issue with C# scripts that prevented saving them as macros (see issue [#208](https://github.com/TabularEditor/TabularEditor3/issues/208)). +- Fixed an issue with data source passwords/credentials not being properly applied to workspace database (see issue [#205](https://github.com/TabularEditor/TabularEditor3/issues/205)). +- "Select all columns" checkbox should no longer cause a crash (see issue [#204](https://github.com/TabularEditor/TabularEditor3/issues/204)). +- Tabular Editor now always looks in the installation directory when a script references external DLL's (using the `#r` precompiler directive), see issue [#192](https://github.com/TabularEditor/TabularEditor3/issues/192). +- Fixed a bug with linguistic schema that caused Q&A to stop working some cases +- Filtering on a date column in Data Preview should no longer cause a crash +- When selecting all perspectives in the TOM Explorer perspectives-dropdown, objects that do not included in any perspectives are no longer shown. Also fixed an issue with the dropdown box not updating perspective names. +- Allow using certain DAX keywords as variables (`WEEK`, `DAY`, `INTEGER`, etc.) without showing an error. +- Fix issue with serialization options not being stored the first time a model is saved. +- Fixed an issue with the DAX parser which would cause a crash upon loading a model (see [#229](https://github.com/TabularEditor/TabularEditor3/issues/229)). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_1_4_zh.md b/content/localization/zh/3_1_4_zh.md new file mode 100644 index 00000000..dcbbc973 --- /dev/null +++ b/content/localization/zh/3_1_4_zh.md @@ -0,0 +1,48 @@ +# Tabular Editor 3.1.4 + +- Download [Tabular Editor 3.1.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.4](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.4 + +- Added a few toolbar shortcuts to menus (for example, you can now manage BPA rules under **Tools > Manage BPA rules...**) +- Can now create DAX scripts for calculated columns and calculated tables by selecting them in the TOM Explorer and right-clicking +- Improved error message behavior in Pivot Grid +- Added "Launch Tabular Editor 3" button to installer, see [#202](https://github.com/TabularEditor/TabularEditor3/issues/202) + +## Bugfixes in 3.1.4 + +- Columns/measures with brackets in their names and tables with single quotes in their name now no longer generates a false semantic error, see [#239](https://github.com/TabularEditor/TabularEditor3/issues/239). +- Fixed a bug that caused a false semantic error when using certain words as variable names. +- Fixed a bug that could sometimes cause a crash while defining a variable in DAX. +- Fixed a bug that caused a false semantic error when using TOPNSKIP with certain arguments. +- The `SelectObject` method (and methods that wrap it) now returns null when the user hits the "Cancel" button, see [#247](https://github.com/TabularEditor/TabularEditor3/issues/247). +- Fixed an issue with the `ExportProperties` / `ImportProperties` methods not working for object collections, see [#245](https://github.com/TabularEditor/TabularEditor3/issues/245). +- Fixed an issue that prevented pasting calculation items, see [#237](https://github.com/TabularEditor/TabularEditor3/issues/237) +- Fixed a "Duplicate key" error which would occur when updating a table schema for a table that contained similarly named columns (i.e. "Customer Key" and "CustomerKey"). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_1_5_zh.md b/content/localization/zh/3_1_5_zh.md new file mode 100644 index 00000000..39fcf1ae --- /dev/null +++ b/content/localization/zh/3_1_5_zh.md @@ -0,0 +1,47 @@ +# Tabular Editor 3.1.5 + +- Download [Tabular Editor 3.1.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.5](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.5 + +- You can now **impersonate** users or roles on DAX queries, Pivot Grids and Table Previews. This is useful for testing RLS and OLS settings. [More information](https://docs.tabulareditor.com/onboarding/refresh-preview-query.html#impersonation). +- DAX scripts now support calculation groups and calculation items. This allows you to view all calculation group logic (including format string expressions) in a single document. [Example](https://docs.tabulareditor.com/onboarding/dax-script-introduction.html#example-3-calculation-group). +- When right-clicking on a measure reference in a DAX query or DAX script, there is now an option to add the definition of that measure [including all dependencies](https://docs.tabulareditor.com/onboarding/dax-script-introduction.html#define-measures). +- You can now pan diagrams by dragging an empty area (see [#275](https://github.com/TabularEditor/TabularEditor3/issues/275)). + +## Bugfixes in 3.1.5 + +- Fixed issue with the built-in schema updater when a `null` value is encountered in an M expression (see [#282](https://github.com/TabularEditor/TabularEditor3/issues/282)). +- Semantic analyzer no longer reports an error when using the `RELATED` function in an argument to `SELECTCOLUMNS`(when no name argument is specified). +- Macros can now be edited/renamed without disappearing from toolbar customizations (see [#266](https://github.com/TabularEditor/TabularEditor3/issues/266)). +- All custom toolbars can now be renamed/deleted after restarting the application (see [#260](https://github.com/TabularEditor/TabularEditor3/issues/260)). +- Fixed selection/context menu when selecting a folder of folders (see [#248](https://github.com/TabularEditor/TabularEditor3/issues/248)). +- Prevented crash when simultaneously selecting tables/table objects. +- Fixed various issues/crashes when importing tables (ODBC NullReferenceException, and more). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_1_6_zh.md b/content/localization/zh/3_1_6_zh.md new file mode 100644 index 00000000..337c12d5 --- /dev/null +++ b/content/localization/zh/3_1_6_zh.md @@ -0,0 +1,66 @@ +# Tabular Editor 3.1.6 + +- Download [Tabular Editor 3.1.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.6](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.6 + +- DAX editor improvements: + - **Offline DAX formatting now available**. The "Format DAX" buttons and shortcuts (F6) now use the built-in DAX formatter instead of www.daxformatter.com. The built-in formatter has a few more configuration options and also fixes column and measure references that do not follow best practices, and more. Since the built-in formatter does not perform a web request, it is also significantly faster. If you encounter an issue with the built-in formatter, you can disable it by enabling the \*\*Use daxformatter.com instead of built-in formatter" under **Tools > Preferences > DAX Editor**. + - You can now configure keywords/functions to be formatted with different casing, based on your preferences. Find the settings under **Tools > Preferences > DAX Editor > Auto Formatting**, see [#58](https://github.com/TabularEditor/TabularEditor3/issues/58). [More details](xref:personalizing-te3#dax-settings). + - Added an option for "Debug comma" formatting for DAX queries (puts all commas in front of the line, for easy comment/uncomment of subexpressions), see [#96](https://github.com/TabularEditor/TabularEditor3/issues/96). + - You can now select an entire object reference (measure, column, etc.) by double-clicking on it (previously, only the word under the cursor would get selected). + - When a subexpression is selected and an opening brace (parenthesis or curly brace) is entered, the selection is wrapped with a matching closing brace, see [#48](https://github.com/TabularEditor/TabularEditor3/issues/48). + - Code assist no longer interferes when writing comments. +- TE3 can now import and update table schemas from Snowflake (Power BI data models only). +- Updated TOM to 19.27.2.1 +- C# script method `SelectObjects` is now available, which prompt the user to select one or more objects given a list of objects. +- New option, **Tools > Preferences > TOM Explorer > Show full branch**. When this is checked, filtering the TOM Explorer will also show all child objects, even when they do not match the filter string. See [#276](https://github.com/TabularEditor/TabularEditor3/issues/276). +- New option, **Tools > Preferences > TOM Explorer > Always show delete warnings**. When this is checked, all delete operations will display a confirmation dialog. When unchecked, only multi-select deletions and deletion of objects referenced by other objects will display the confirmation dialog (remember, every operation can be undone in Tabular Editor). See [#10](https://github.com/TabularEditor/TabularEditor3/issues/10). +- Added the "Apply Refresh Policy" menu option on tables, when applicable. See [Configure Incremental Refresh with Tabular Editor](https://www.youtube.com/watch?v=icCGFG6KpIA) for more information, see also [#291](https://github.com/TabularEditor/TabularEditor3/issues/291). +- Added the DAX dependency view to the **View** menu, and added a checkbox that lets the dependency view track the current selection in the TOM Explorer, see[#10](https://github.com/TabularEditor/TabularEditor3/issues/10). + +## Bugfixes in 3.1.6 + +- The Preferences, SelectItems and Save/Edit Macro dialogs can now be resized, see[#51](https://github.com/TabularEditor/TabularEditor3/issues/51). +- When an "Update table schema" operation is performed against a Power BI Desktop model that uses native queries for data import, we will bring the PBI Desktop instance to the front, as a dialog pops up in Desktop which needs to be accepted, before the "Update table schema" operation can complete, see issue [#55](https://github.com/TabularEditor/TabularEditor3/issues/55). +- Taskbar icon should no longer break when upgrading. See[#163](https://github.com/TabularEditor/TabularEditor3/issues/163). +- When updating table schemas, you will now be shown a connection dialog that allows you to change the auth mode. See[#262](https://github.com/TabularEditor/TabularEditor3/issues/262). +- The `MemberId` role member property is now removed automatically only when deploying a model to Azure AS or Power BI. See [#263](https://github.com/TabularEditor/TabularEditor3/issues/263). +- Fixed an issue with freezing UI when queuing multiple refresh operations, see [#281](https://github.com/TabularEditor/TabularEditor3/issues/281). +- AAD object picker should now produce a well-formed object name. See[#286](https://github.com/TabularEditor/TabularEditor3/issues/286). +- When executing a DAX script that creates a calculation group, the ordinals are now assigned correctly, see [#296](https://github.com/TabularEditor/TabularEditor3/issues/296). +- CTRL + arrows can now be used to expand/collapse all nodes in the TOM Explorer, similar to TE 2.x, see [#297](https://github.com/TabularEditor/TabularEditor3/issues/297). +- When executing a DAX script that creates a calculation group, the column name is now assigned correctly, see [#298](https://github.com/TabularEditor/TabularEditor3/issues/298). +- Fixed a bug where DAX script locales were not updated correctly when switching between US/Non-US mode. +- Fixed a crash that would occur when trying to connect to an AS server contains databases with no compatibility level (happens when connecting to an instance of AS tabular that shares its data dir with an instance of AS multidimensional). +- Fixed a bug that would sometimes cause the "Update table schema" feature to report all columns as missing from the source. +- Fixed an issue with the Table Preview feature, that would cause grid columns to be configured incorrectly, when using impersonation. +- Fixed an issue with semantic change notification bar not disappearing when saving the model. +- Fixed an issue with property grid edits not being committed automatically when saving the model. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_1_7_zh.md b/content/localization/zh/3_1_7_zh.md new file mode 100644 index 00000000..6462ffc9 --- /dev/null +++ b/content/localization/zh/3_1_7_zh.md @@ -0,0 +1,53 @@ +# Tabular Editor 3.1.7 + +- Download [Tabular Editor 3.1.7 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.1.7](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.1.7 + +- When a DAX query causes Analysis Services to return an error message, that message is now displayed in place of the previous result grid. +- Grids can now be zoomed (ctrl+mouse wheel)! +- Various auto-complete improvements and auto-indent improvements. +- A new right-click menu makes it easy to add table permissions to roles (previously, you would have to add a table permission by assigning an RLS expression or specify an OLS setting). See issue [#257](https://github.com/TabularEditor/TabularEditor3/issues/257). You can add multiple table permissions across multiple roles at once. +- The "Select database" dialog now remembers sort order of columns. See [#321](https://github.com/TabularEditor/TabularEditor3/issues/321). + +## Bugfixes in 3.1.7 + +- Fix issue with SaveModelMetadataBackup not working for database IDs (when IDs and Names are different). +- Fix crash when resetting auto format preferences +- Fix missing export of TOM in VPAX. Fix message dialog when VPAX contains TOM. +- Improved DAX (offline) formatting, see issue [#306](https://github.com/TabularEditor/TabularEditor3/issues/306). +- Fixed issue with `FormatDax(...)` and `CallDaxFormatter()` helper functions when using the default (offline) formatter, see [#307](https://github.com/TabularEditor/TabularEditor3/issues/307). +- Fixed an issue with auto-complete sometimes getting "stuck". +- Fewer windows/dialogs should have display scaling issues when the Windows display resolution or scaling is changed. See [#308](https://github.com/TabularEditor/TabularEditor3/issues/308) and [#81](https://github.com/TabularEditor/TabularEditor3/issues/81). +- Auto-formatter should no longer repeat multi-line comment blocks. See [#319](https://github.com/TabularEditor/TabularEditor3/issues/319]. +- Fixed an issue with the background semantic analysis reporting invalid DAX errors, see [#311](https://github.com/TabularEditor/TabularEditor3/issues/311). +- Opening the BPA manager through the menu bar should no longer cause a crash, see [#312](https://github.com/TabularEditor/TabularEditor3/issues/312). +- Saving a model in workspace mode, that was loaded from a Database.json file, should no longer cause a "Save failed!" error, see issue [#322](https://github.com/TabularEditor/TabularEditor3/issues/322). +- Comments are now correctly retained when applying a DAX script, see issue [#323](https://github.com/TabularEditor/TabularEditor3/issues/323). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_20_0_zh.md b/content/localization/zh/3_20_0_zh.md new file mode 100644 index 00000000..f8dd0c34 --- /dev/null +++ b/content/localization/zh/3_20_0_zh.md @@ -0,0 +1,117 @@ +--- +uid: release-3-20-0 +--- + +# Tabular Editor 3.20.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.20.0 **.NET 8** downloads: + +- Download [Tabular Editor 3.20.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.20.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) + +Tabular Editor 3.20.0 **.NET 6** downloads: + +- Download [Tabular Editor 3.20.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe) +- Download [Tabular Editor 3.20.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.20.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `0E2CA7EF182E7D8DD3D4CFE7F3AB550236BF7AA7E8EDC7AB01E739A3441F2333` | +| [TabularEditor.3.20.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi) | .NET 8 | 64 bit | `7B38FF22B71FB7C0B4AE7E258FFB9AFF4D7D32835AEED2A5382405D539B68710` | +| [TabularEditor.3.20.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip) | .NET 8 | 64 bit | `3CA79DC8E8F58DDADDE068774106193D46A59BFF85E604B429DE732D4B23CAEA` | +| [TabularEditor.3.20.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `9CEF083B2F972E5A380BBCFF79F349D7860D81DC7A50F05BBA52305C75E7A071` | +| [TabularEditor.3.20.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) | .NET 8 | 32 bit | `86ABFC4EBEFC905F996D335515C761C63F9A9BDA3A13C6CE018E523DD8705182` | +| [TabularEditor.3.20.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) | .NET 8 | 32 bit | `1A2E934CF58AF8B42B1D6A94B91138C1854D6FD127FE28CB38DE3395111A880F` | +| [TabularEditor.3.20.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe) | .NET 6 | 64 bit | `964C72AF3DECF1FD6988998FA8963828C6A62CA4FA978D44DC10DE1983D1C562` | +| [TabularEditor.3.20.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi) | .NET 6 | 64 bit | `502378EFE2C5D3EFD77D4493ECFFBC01D1D9402E57DB471DD3E578526730959C` | +| [TabularEditor.3.20.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip) | .NET 6 | 64 bit | `E2108460A36871D872F29DC8FE17C2385B3299D326ED3FFD402A551AB57A4A40` | +| [TabularEditor.3.20.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) | .NET 6 | 32 bit | `9050A1D090D8D11263C2F85FDFB79CA84201F3A8D80444B7E0EDC4C2DE46DEB8` | +| [TabularEditor.3.20.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) | .NET 6 | 32 bit | `E8C8EC487D293CA22014A35120C7E936E69CAEC541670C145F06BE5E9F68C1B0` | +| [TabularEditor.3.20.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) | .NET 6 | 32 bit | `235A4D73BA4377E7D6DC625121060DB84B64C32FE37230B678EE463F3F3ADAC7` | + +*** + +> [!IMPORTANT] +> .NET 6 is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization, as we will stop providing .NET 6 builds of Tabular Editor 3 during 2025. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.20.0 + +Check out our [release blog](https://blog.tabulareditor.com/2025/02/21/tabular-editor-3-february-2025-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.20.0 + +- All [code actions](xref:code-actions) now show a tooltip in the context menu when hovering over the menu item, with a short description of the action. The tooltip also contains a link to a knowledge-base (KB) article with more information about the action. +- We've also added a few new code actions in this release, based on popular demand. For example, we will now suggest that you use the `IN` operator instead of using a compound expression with `OR` / `||`. View the [full list of available code actions here](xref:code-actions#list-of-code-actions). +- Introduced a new user interface preference labeled "Use compact file paths" to toggle between displaying compact (shortened) file paths and full file paths in the Recent Files and Recent Models menus. +- When editing a model that's loaded in Power BI Desktop (January 2025 or newer), Tabular Editor will now let you edit any object and property by default, except tables and partitions, in alignment with the modeling operations supported by the new [TMDL View](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-tmdl-view) in Power BI Desktop. +- When changing the DAX expression of a calculated table, Tabular Editor 3 will now attempt to infer the resulting columns of the table, even if the expression has an error. +- A new DAX Query preference labeled "Keep existing sorting and filtering in the result grid" has been added to the DAX Query menus and toolbar, allowing users to control how sorting and filtering are preserved in the result grids between query executions. +- We've made several improvements to our **Diagram View**. Most importantly, it now renders much faster, especially when many tables/relationships are present. But there are also several visual tweaks. +- We've improved the C# auto-complete feature, so that it now shows only items that are relevant for the current target. For example, if you type `Selected.Column.DataType = `, the listbox will now only show the valid [`DataType` enum values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.datatype?view=analysisservices-dotnet#fields). Moreover, if the same type exists in different namespaces, we now show the namespace in a parenthesis, to disambiguate the items in the list. +- Updated AMO/TOM to the latest version [19.88.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). +- We have added auto-complete support to the new DAX scalar inspection functions, [`ISINT64`](https://dax.guide/isint64), [`ISBOOLEAN`](https://dax.guide/isboolean), [`ISDOUBLE`](https://dax.guide/isboolean), [`ISDECIMAL`](https://dax.guide/isdecimal), [`ISDATETIME`](https://dax.guide/isdatetime), [`ISSTRING`](https://dax.guide/isstring), and [`ISNUMERIC`](https://dax.guide/isnumeric). + +## Bugfixes in 3.20.0 + +- The **Rewrite using ISBLANK** DAX Code Action will no longer trigger when using non-strict equality comparisons, e.g. `x = BLANK()`, as this is semantically different from `ISBLANK(x)`. +- Various bugfixes for unhandled exceptions in the DAX Editor. +- The Semantic Analyzer now correctly shows an error message if using a group-by column within a call to [`SUMMARIZE`](https://dax.guide/summarize), which has no relation to the base table. +- When creating VPAX files through the **DAX Optimizer** view, we will now use the **Full** extraction mode for Direct Lake models, producing a VPAX file that is valid for DAX Optimizer analysis. +- Various Pivot Grid bugfixes and stability improvements. +- Fixed a bug where unassigning/resetting an Editor shortcut, would not be effective until restarting the application. +- Fixed a bug where certain editor shortcuts (such as "Duplicate Line (Ctrl+D)") would trigger an action in the TOM Explorer with the same key binding, even when the editor was focused. +- Fixed a bug where adding a level to a hierarchy in a Power BI Desktop model, would not include the column reference, causing an error when attempting to save the change. +- Fixed a bug that would cause a crash when executing a DAX script containing certain syntax or errors. +- Creating and editing DAX scripts should no longer cause the UI to lock up, which could happen when the script contained syntax or semantic errors. +- Fixed a bug that would sometimes cause the **Data Refresh** view to lock up/crash while a refresh was in progress. +- Fixed a bug causing a crash when loading a model and then navigating to a partition with a [Data Coverage Definition](https://learn.microsoft.com/en-us/analysis-services/tom/table-partitions?view=asallproducts-allversions#define-the-data-coverage-of-the-directquery-partition). +- The auto-complete feature of C# scripts should now work correctly when making multiple insertions in the script, such as in [#1327](https://github.com/TabularEditor/TabularEditor3/issues/1327). +- Hitting F12 (Go to Definition) on a measure format string expression reference, will now correctly navigate to the referenced measure's format string expression property, rather than the base expression property. +- Fixed an issue with our Semantic Analyzer, that didn't correctly detect when a relationship was activated by the [`USERELATIONSHIP`](https://dax.guide/userelationship) function. +- Fixed an issue with false circular dependency errors appearing while editing the DAX of calculated columns. +- Fixed a bug that prevented **TE3 Business Edition** license holders to connect to Power BI Premium-Per-User (PPU) workspaces, in some regions. + +> [!IMPORTANT] +> Due to technical limitations, previous versions of TE3 might sometimes allow **Business Edition** license holders to connect to Power BI Premium / Fabric Capacity workspaces, even though [this is not allowed per the Business Edition license terms](xref:editions). If you are facing issues connecting to the Power BI XMLA endpoint after upgrading to 3.20.0, please reach out to [licensing@tabulareditor.com](mailto:licensing@tabulareditor.com) so we can assist you in finding a suitable solution going forward. + +## Known issues in 3.20.0 + +- The Semantic Analyzer doesn't correctly detect relationship activations with `USERELATIONSHIP` when there are only inactive relationships between two tables. +- The Semantic Analyzer doesn't always infer the correct data type for the column returned by the [`GENERATESERIES`](https://dax.guide/generateseries) function. +- The new **Diagram view** does not correctly indicate bi-directional relationships. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_20_1_zh.md b/content/localization/zh/3_20_1_zh.md new file mode 100644 index 00000000..049b4894 --- /dev/null +++ b/content/localization/zh/3_20_1_zh.md @@ -0,0 +1,115 @@ +--- +uid: release-3-20-1 +--- + +# Tabular Editor 3.20.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.20.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.20.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.20.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) + +Tabular Editor 3.20.1 **.NET 6** downloads: + +- Download [Tabular Editor 3.20.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe) +- Download [Tabular Editor 3.20.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.20.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `4A5BB249049A32A3C2BA14140AFF6BDE6340DEDA217E4E1D6D33A9699E8D0558` | +| [TabularEditor.3.20.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi) | .NET 8 | 64 bit | `189EB204E1ED778F66132019BBAB70CAC7A6C8C2B04955BF45C80F6E7CC52B19` | +| [TabularEditor.3.20.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip) | .NET 8 | 64 bit | `6B324C0D6EFD1C7453302F6C8AF1F49A0C8D127C7FCEE9880A652279E2850016` | +| [TabularEditor.3.20.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `735297DAC09D7342F556C52D81224B6A91B1E7E7837102520114A310939E3C9F` | +| [TabularEditor.3.20.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) | .NET 8 | 32 bit | `2C0D29C4030882BB445DF5A00A5CF3D821A30FD3B2D6A182BEE1917D873F3E9F` | +| [TabularEditor.3.20.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) | .NET 8 | 32 bit | `3180ED45BFF0BF6D720A851415B36A52E155671B38E7E515A75CABCEF1F8E1E0` | +| [TabularEditor.3.20.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe) | .NET 6 | 64 bit | `04B2999366C284AC520A4234BA51BA2D9D3E05D4753FFF7DE5B8FF28B1AB56A9` | +| [TabularEditor.3.20.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi) | .NET 6 | 64 bit | `3E45C228B500D538B9AD7E373F938F4F3B7E2B10B7E61AFC4FED6946CE97B467` | +| [TabularEditor.3.20.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip) | .NET 6 | 64 bit | `C40BF90E2D3DD3226EB35B6BB32D1876736D3B044787416C0EF07536FFE6AB89` | +| [TabularEditor.3.20.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) | .NET 6 | 32 bit | `40FF4D8860C065455A7BDE98EA7241FF174BE059610B8E3589FA6FF41539D6DB` | +| [TabularEditor.3.20.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) | .NET 6 | 32 bit | `4F04C3097862C40C37C366BE2DB00994D7791F1BEDCD8DE18140BBEC960D0266` | +| [TabularEditor.3.20.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) | .NET 6 | 32 bit | `39D8D73522089C4E547455E183082312E4067F54D4CC53A5115110B5194229E7` | + +*** + +> [!IMPORTANT] +> .NET 6 is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime) now, please contact your IT organization, as we will stop providing .NET 6 builds of Tabular Editor 3 during 2025. Alternatively, use our portable builds, which include the required .NET runtime. + +## Bugfixes in 3.20.1 + +- Fixed an issue that prevented users from authenticating against Azure Databricks using "Azure AD" (aka. "Entra ID") authentication. See [#1451](https://github.com/TabularEditor/TabularEditor3/issues/1451). + +## New in 3.20.0 + +Check out our [release blog](https://blog.tabulareditor.com/2025/02/21/tabular-editor-3-february-2025-release/) to get a brief overview of the most important updates in this release. + +## Improvements in 3.20.0 + +- All [code actions](xref:code-actions) now show a tooltip in the context menu when hovering over the menu item, with a short description of the action. The tooltip also contains a link to a knowledge-base (KB) article with more information about the action. +- We've also added a few new code actions in this release, based on popular demand. For example, we will now suggest that you use the `IN` operator instead of using a compound expression with `OR` / `||`. View the [full list of available code actions here](xref:code-actions#list-of-code-actions). +- Introduced a new user interface preference labeled "Use compact file paths" to toggle between displaying compact (shortened) file paths and full file paths in the Recent Files and Recent Models menus. +- When editing a model that's loaded in Power BI Desktop (January 2025 or newer), Tabular Editor will now let you edit any object and property by default, except tables and partitions, in alignment with the modeling operations supported by the new [TMDL View](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-tmdl-view) in Power BI Desktop. +- When changing the DAX expression of a calculated table, Tabular Editor 3 will now attempt to infer the resulting columns of the table, even if the expression has an error. +- A new DAX Query preference labeled "Keep existing sorting and filtering in the result grid" has been added to the DAX Query menus and toolbar, allowing users to control how sorting and filtering are preserved in the result grids between query executions. +- We've made several improvements to our **Diagram View**. Most importantly, it now renders much faster, especially when many tables/relationships are present. But there are also several visual tweaks. +- We've improved the C# auto-complete feature, so that it now shows only items that are relevant for the current target. For example, if you type `Selected.Column.DataType = `, the listbox will now only show the valid [`DataType` enum values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.datatype?view=analysisservices-dotnet#fields). Moreover, if the same type exists in different namespaces, we now show the namespace in a parenthesis, to disambiguate the items in the list. +- Updated AMO/TOM to the latest version [19.88.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). +- We have added auto-complete support to the new DAX scalar inspection functions, [`ISINT64`](https://dax.guide/isint64), [`ISBOOLEAN`](https://dax.guide/isboolean), [`ISDOUBLE`](https://dax.guide/isboolean), [`ISDECIMAL`](https://dax.guide/isdecimal), [`ISDATETIME`](https://dax.guide/isdatetime), [`ISSTRING`](https://dax.guide/isstring), and [`ISNUMERIC`](https://dax.guide/isnumeric). + +## Bugfixes in 3.20.0 + +- The **Rewrite using ISBLANK** DAX Code Action will no longer trigger when using non-strict equality comparisons, e.g. `x = BLANK()`, as this is semantically different from `ISBLANK(x)`. +- Various bugfixes for unhandled exceptions in the DAX Editor. +- The Semantic Analyzer now correctly shows an error message if using a group-by column within a call to [`SUMMARIZE`](https://dax.guide/summarize), which has no relation to the base table. +- When creating VPAX files through the **DAX Optimizer** view, we will now use the **Full** extraction mode for Direct Lake models, producing a VPAX file that is valid for DAX Optimizer analysis. +- Various Pivot Grid bugfixes and stability improvements. +- Fixed a bug where unassigning/resetting an Editor shortcut, would not be effective until restarting the application. +- Fixed a bug where certain editor shortcuts (such as "Duplicate Line (Ctrl+D)") would trigger an action in the TOM Explorer with the same key binding, even when the editor was focused. +- Fixed a bug where adding a level to a hierarchy in a Power BI Desktop model, would not include the column reference, causing an error when attempting to save the change. +- Fixed a bug that would cause a crash when executing a DAX script containing certain syntax or errors. +- Creating and editing DAX scripts should no longer cause the UI to lock up, which could happen when the script contained syntax or semantic errors. +- Fixed a bug that would sometimes cause the **Data Refresh** view to lock up/crash while a refresh was in progress. +- Fixed a bug causing a crash when loading a model and then navigating to a partition with a [Data Coverage Definition](https://learn.microsoft.com/en-us/analysis-services/tom/table-partitions?view=asallproducts-allversions#define-the-data-coverage-of-the-directquery-partition). +- The auto-complete feature of C# scripts should now work correctly when making multiple insertions in the script, such as in [#1327](https://github.com/TabularEditor/TabularEditor3/issues/1327). +- Hitting F12 (Go to Definition) on a measure format string expression reference, will now correctly navigate to the referenced measure's format string expression property, rather than the base expression property. +- Fixed an issue with our Semantic Analyzer, that didn't correctly detect when a relationship was activated by the [`USERELATIONSHIP`](https://dax.guide/userelationship) function. +- Fixed an issue with false circular dependency errors appearing while editing the DAX of calculated columns. +- Fixed a bug that prevented **TE3 Business Edition** license holders to connect to Power BI Premium-Per-User (PPU) workspaces, in some regions. + +> [!IMPORTANT] +> Due to technical limitations, previous versions of TE3 might sometimes allow **Business Edition** license holders to connect to Power BI Premium / Fabric Capacity workspaces, even though [this is not allowed per the Business Edition license terms](xref:editions). If you are facing issues connecting to the Power BI XMLA endpoint after upgrading to 3.20.0, please reach out to [licensing@tabulareditor.com](mailto:licensing@tabulareditor.com) so we can assist you in finding a suitable solution going forward. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_21_0_zh.md b/content/localization/zh/3_21_0_zh.md new file mode 100644 index 00000000..18bd250d --- /dev/null +++ b/content/localization/zh/3_21_0_zh.md @@ -0,0 +1,91 @@ +--- +uid: release-3-21-0 +--- + +# Tabular Editor 3.21.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.21.0 downloads: + +- Download [Tabular Editor 3.21.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.21.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.21.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `A3F944C0945B3FD3AD0595A05D1BCAFAF6BBB8DCFB48F40002C799F91415764E` | +| [TabularEditor.3.21.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi) | .NET 8 | 64 bit | `251510EB41FDEA73CB21C7637FD9CD2F74691B416894B318A5BDAEE96595BEAD` | +| [TabularEditor.3.21.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip) | .NET 8 | 64 bit | `385A8F00F76A1621B063DA1B3AEA2FA726F308E1A2E829D8FF27FC743B0A57E1` | +| [TabularEditor.3.21.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `CF4BAA7B9E74E9EE19BE41DA195DBD260F4922081F44FCC7CC66AD12A702FBD5` | +| [TabularEditor.3.21.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) | .NET 8 | 32 bit | `81425B72EA2E1CB5E2A8101ECC7F0F2B259E4FD90482CAD7B0F9DCAB3F5CE298` | +| [TabularEditor.3.21.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) | .NET 8 | 32 bit | `99BE7DA061A0C47A1D5BA1169D9DDAA521CDB974F135004478334BDD0E469D0B` | + +*** + +> [!IMPORTANT] +> We are no longer providing .NET 6 builds of Tabular Editor 3, as this is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime), please contact your IT organization. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.21.0 + +Check out our [release blog](https://tabulareditor.com/blog/tabular-editor-3-april-2025-release) to get a brief overview of the most important updates in this release. + +## Improvements in 3.21.0 + +- We've made even more visual tweaks and improvements to our **Diagram view** in this release: + - Icons visually indicate column data types. + - Double-arrows when a relationship uses bi-directional cross filtering + - A chevron button in the top-right corner of the table allows you to quickly toggle between various ways of displaying the columns in the table: All columns, key columns only, or no columns at all. + - Various font size adjustments and other minor tweaks +- Updated AMO/TOM to the latest version [19.94.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.94.1.1). +- We have added a new property on the `Model` object, `MetadataSource`, which includes information about where the model metadata was loaded from. This is useful for C# scripts, for example if a script needs to iterate files in the same folder structure that the model metadata was loaded from. See the [API docs](https://docs.tabulareditor.com/api/TabularEditor.TOMWrapper.Model.html#TabularEditor_TOMWrapper_Model_MetadataSource) for more information. +- DAX Optimizer users can now also view the results for RLS and Calculation Item expressions through our **DAX Optimizer Integration**. +- You can now script individual objects as [TMDL (Tabular Model Definition Language)](https://learn.microsoft.com/en-us/analysis-services/tmdl/tmdl-overview?view=asallproducts-allversions) through the **TOM Explorer**. This is useful when you want to copy TMDL scripts from Tabular Editor to Power BI Desktop. Right-click an object and choose **Export script > TMDL**. You'll have the option of exporting the script to a file or directly to the clipboard. + +## Bugfixes in 3.21.0 + +- Sorting by "Progress" or "Duration" in the **Data Refresh** view should now work correctly. Moreover, the "Duration" is no longer reset at the end of the refresh operation, for certain objects. +- Various bugfixes related to the view of progress events in the **Data Refresh** view. For example, progress events should now arrive even if a previous session has expired (for example when Tabular Editor was idle for 60 minutes or more). +- When partition deployment is disabled, or enabled but with incremental refresh partitions skipped, we now also leave the refresh policy settings on the table untouched (i.e. **Source Expression**, **Polling Expression**, etc.) +- The Semantic Analyzer should no longer report an error when tables are connected by only inactive relationships, and a relationship is activated using the [`USERELATIONSHIP`](https://dax.guide/userelationship/) function. +- Fixed a bug where the Semantic Analyzer determined the wrong resulting data type when using the [`GENERATESERIES`](https://dax.guide/generateseries/) function. +- Fixed a bug with the Semantic Analyzer reporting false "not found" errors when [`DEFINE`ing](https://dax.guide/DEFINE) and referencing tables and columns inside a DAX script/query. +- It is no longer possible to assign an empty name to an object through the **TOM Explorer**. +- Certain words that were previously treated as reserved keywords, will no longer produce a semantic error, when used as unquoted table / variable references. +- Fixed a bug where the DAX debugger didn't correctly gray out the inactive branch when using IF.EAGER or IF with only 2 parameters. +- When opening a model with a workspace connection (i.e. Tabular Editor 3's Workspace Mode feature), we now correctly show the Microsoft Entra MFA prompt, if this was the authentication method used when the connection to the workspace database was originally established. +- Our code editors now fully supports wide characters / unicode emojis (note, this is not an endorsement of emojis in DAX, but it is now possible to use them without breaking the editor :)). +- If the .tmuo file contains invalid JSON, Tabular Editor will now show an error message and continue loading the model without the options specified in the file, instead of causing an unhandled exception. +- Fixed a bug where the Refresh Policy options would not appear in the **Properties** grid on a table in a model loaded from disk, if the table did not have any partitions specified in the loaded metadata. +- The `Ctrl+U` (Uncomment Code) and `Ctrl+/` (Toggle comments) shortcuts were not working properly because of conflicts with other editor keyboard shortcuts. We have removed the default shortcuts from the conflicting commands. If you need keyboard bindings for the _Editor.Lowercase_ and _Editor.Uppercase_ commands (previously `Ctrl+U` and `Ctrl+Shift+U` respectively), you can set these up through **Tools > Preferences > Keyboard**. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_22_0_zh.md b/content/localization/zh/3_22_0_zh.md new file mode 100644 index 00000000..eadc242a --- /dev/null +++ b/content/localization/zh/3_22_0_zh.md @@ -0,0 +1,92 @@ +--- +uid: release-3-22-0 +--- + +# Tabular Editor 3.22.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.22.0 downloads: + +- Download [Tabular Editor 3.22.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.22.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.22.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `07CEF5470991300856C4F6057A95CE547DBC5F6803E4283063ACE11CA8397D3B` | +| [TabularEditor.3.22.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi) | .NET 8 | 64 bit | `1DD07DDF45997F5314656A7F600E1DBC11CBF623A0F09A9B1EF9C975E70ABDB5` | +| [TabularEditor.3.22.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip) | .NET 8 | 64 bit | `6CABFD02E7C04D319DDB85581B7EB13633F5AB0716F5B5612738A3BEC498D917` | +| [TabularEditor.3.22.0.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `A5DB72C8FF6CBDCC167C8368B1ECA92567041E4A716F6971B5C15204FEBD797B` | +| [TabularEditor.3.22.0.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) | .NET 8 | 32 bit | `01960E2F3D493FB9FB96FC946A5BE522D191DDBFCECF79AD5ACD4DF1D249D3E9` | +| [TabularEditor.3.22.0.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) | .NET 8 | 32 bit | `8558D7BE5C01ED04E19B17330A5215EA92BAAEE82C4E5EB4F5436CC62CA04F02` | + +*** + +## New in 3.22.0 + +Check out our [release blog](https://tabulareditor.com/blog/tabular-editor-3-june-2025-release) to get a brief overview of the most important updates in this release. + +(**Enterprise Edition only**) Tabular Editor 3 now fully supports Direct Lake on OneLake and Direct Lake on SQL. This means: + +- The Table Import Wizard has new import options for Fabric Warehouses and Lakehouses. You no longer need to know the SQL analytics endpoint of the Warehouse/Lakehouse you wish to connect to. Instead, we show you a list of all the Warehouses/Lakehouses in your workspace, allowing you to choose the one you wish to use. +- On the last page of the Table Import Wizard, you can choose whether to use Direct Lake in OneLake or SQL mode, or whether to configure the table for plain old "import" mode. +- When the model contains tables in Direct Lake on OneLake mode, you can now also add tables in Import mode, in order to create mixed mode/hybrid models. +- When previewing data in Direct Lake tables, we no longer restrict the number of rows returned (so you can freely scroll through all the data in the table, just like in Import mode). Be aware that all columns are swapped into the Semantic Model in the Fabric capacity when you perform a data preview. Consider using a DAX Query if you are concerned about memory consumption on your Fabric capacity. + +> [!NOTE] +> We no longer configure Direct Lake models to use a case _sensitive_ collation. If you plan to use Direct Lake on SQL with a Fabric Warehouse that uses a case sensitive collation, you must manually fill out the **Collation** property of your semantic model _before_ adding any tables or other objects. + +For more information, view our [Direct Lake Guidance article](xref:direct-lake-guidance). + +## Improvements in 3.22.0 + +- When saving a model as a single file, the **Save file** dialog now suggests "model.bim" as the default file name. +- Updated various dependencies to their latest versions, including [AMO/TOM to 19.98.0.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). This update fixes longstanding authentication issues with Work or School accounts and repeated sign in promts. +- Changed the default Compatibility Level for new Power BI / Fabric semantic models to **1609**, which allows you to control how [Selection Expressions](https://powerbi.microsoft.com/en-us/blog/deep-dive-into-selection-expressions-for-calculation-groups/) on your Calculation Groups behave by default, through the Model [SelectionExpressionBehavior](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.model.selectionexpressionbehavior?view=analysisservices-dotnet) property. +- DAX query editor support for the [`MPARAMETER`](https://dax.guide/st/mparameter/) keyword, see [#1467](https://github.com/TabularEditor/TabularEditor3/issues/1467). +- Our DAX editors now support **word based** auto complete search terms. In other words, if you type `sales ytd` in the editor, the auto complete will now suggest measures such as `[Sales Margin YTD]`, `[Sales Revenue YTD]`, etc. +- With the June 2025 update of Power BI Desktop, [external tools can now perform any write operation on the semantic model](https://powerbi.microsoft.com/en-us/blog/power-bi-june-2025-feature-summary/#post-30307-_Toc269410729). As such, we no longer restrict the modeling operations available in Tabular Editor, when connecting to a model in this or newer versions of Power BI Desktop. + +## Bugfixes in 3.22.0 + +- Added exception handling when encountering IOException's during save-to-folder operations (where we sometimes need to delete folders in the folder structure, which can be blocked by file system locks placed by version control systems). +- Fixed a bug where certain keyboard shortcuts (both default and customized) didn't work when the "What's new" page was focused. +- When assigning a custom keyboard shortcut that is already assigned to another command, we now show a warning message and remove the shortcut from the other command, to avoid ambiguity. +- Fixed a bug where the Semantic Analyzer showed a false error message when using unqualified column references in a DAX window function. See [#1460](https://github.com/TabularEditor/TabularEditor3/issues/1460). +- Fixed a bug that could sometimes cause the **Data Refresh** view to freeze, requiring an app restart to resolve. See [#1461](https://github.com/TabularEditor/TabularEditor3/issues/1461). +- Fixed several smaller DAX editor issues related to auto complete, auto formatting, and syntax highlighting of keywords. +- Query Group names (i.e. "display folders" for Shared M expressions and M partitions) can now be modified. Also, if pasting an object with a query group into a model that doesn't contain said query group, it will be created automatically, so as to avoid the error message on subsequent Save / Deployment of the model. +- If pasting an object containing a Shared Expression reference to a model that does not contain the Shared Expression, we remove the reference to avoid "object does not exist" errors when saving/deploying the model to Analysis Services / Power BI. +- Fixed a bug where it was sometimes not possible to Undo previous changes, after saving the model metadata back to the server. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_22_1_zh.md b/content/localization/zh/3_22_1_zh.md new file mode 100644 index 00000000..b7400e58 --- /dev/null +++ b/content/localization/zh/3_22_1_zh.md @@ -0,0 +1,95 @@ +--- +uid: release-3-22-1 +--- + +# Tabular Editor 3.22.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.22.1 downloads: + +- Download [Tabular Editor 3.22.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.22.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.22.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe) | .NET 8 | 64 bit | `F8BA7D9FFA0E334F0506822CE41FE18F3E0F41499E7B729CEE8D0D6FCA4C50A7` | +| [TabularEditor.3.22.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi) | .NET 8 | 64 bit | `EEB0101CA523A633AAD233087977F574B68945F051F1E0030CCA60C0B8E331D9` | +| [TabularEditor.3.22.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip) | .NET 8 | 64 bit | `1A4F9D02004996C4A921AE78E9827314EFA95AA88D2BC59BF569AD4F3EA83362` | +| [TabularEditor.3.22.1.Installer.x86.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) | .NET 8 | 32 bit | `B04C58D262AE1F0C32DD940F0BE96A3245F5AB0FA82066F6CAAFC21B2B09C85A` | +| [TabularEditor.3.22.1.x86.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) | .NET 8 | 32 bit | `8AFD8E7589830D2385957B073E965EFEB439438950797F5BBBAE29BB5E454E34` | +| [TabularEditor.3.22.1.x86.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) | .NET 8 | 32 bit | `70E6F993C8C2D11D4A09DB9D1C8D6CF93F83E72105824F6ACDDB0C5D1B2DA477` | + +*** + +> [!IMPORTANT] +> We are no longer providing .NET 6 builds of Tabular Editor 3, as this is [out-of-support as of November 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). If you are not able to install the [.NET 8 Desktop runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime), please contact your IT organization. Alternatively, use our portable builds, which include the required .NET runtime. + +## New in 3.22.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +(**Enterprise Edition only**) Tabular Editor 3 now fully supports Direct Lake over OneLake and Direct Lake over SQL. This means: + +- The Table Import Wizard has new import options for Fabric Warehouses and Lakehouses. You no longer need to know the SQL analytics endpoint of the Warehouse/Lakehouse you wish to connect to. Instead, we show you a list of all the Warehouses/Lakehouses in your workspace, allowing you to choose the one you wish to use. +- On the last page of the Table Import Wizard, you can choose whether to use Direct Lake in OneLake or SQL mode, or whether to configure the table for plain old "import" mode. +- When the model contains tables in Direct Lake over OneLake mode, you can now also add tables in Import mode, in order to create mixed mode/hybrid models. +- When previewing data in Direct Lake tables, we no longer restrict the number of rows returned (so you can freely scroll through all the data in the table, just like in Import mode). Be aware that all columns are swapped into the Semantic Model in the Fabric capacity when you perform a data preview. Consider using a DAX Query if you are concerned about memory consumption on your Fabric capacity. + +> [!NOTE] +> We no longer configure Direct Lake models to use a case _sensitive_ collation. If you plan to use Direct Lake over SQL with a Fabric Warehouse that uses a case sensitive collation, you must manually fill out the **Collation** property of your semantic model _before_ adding any tables or other objects. + +## Improvements in 3.22.0 + +- When saving a model as a single file, the **Save file** dialog now suggests "model.bim" as the default file name. +- Updated various dependencies to their latest versions, including [AMO/TOM to 19.98.0.3](https://www.nuget.org/packages/Microsoft.AnalysisServices/). This update fixes longstanding authentication issues with Work or School accounts and repeated sign in promts. +- DAX query editor support for the [`MPARAMETER`](https://dax.guide/st/mparameter/) keyword, see [#1467](https://github.com/TabularEditor/TabularEditor3/issues/1467). +- Our DAX editors now support **word based** auto complete search terms. In other words, if you type `sales ytd` in the editor, the auto complete will now suggest measures such as `[Sales Margin YTD]`, `[Sales Revenue YTD]`, etc. +- With the June 2025 update of Power BI Desktop, [external tools can now perform any write operation on the semantic model](https://powerbi.microsoft.com/en-us/blog/power-bi-june-2025-feature-summary/#post-30307-_Toc269410729). As such, we no longer restrict the modeling operations available in Tabular Editor, when connecting to a model in this or newer versions of Power BI Desktop. + +## Bugfixes in 3.22.1 + +- Fixed a bug where the **Data Refresh** view would turn blank and not show additional refresh operations until the app was restarted. See [#1461](https://github.com/TabularEditor/TabularEditor3/issues/1461). + +## Bugfixes in 3.22.0 + +- Added exception handling when encountering IOException's during save-to-folder operations (where we sometimes need to delete folders in the folder structure, which can be blocked by file system locks placed by version control systems). +- Fixed a bug where certain keyboard shortcuts (both default and customized) didn't work when the "What's new" page was focused. +- When assigning a custom keyboard shortcut that is already assigned to another command, we now show a warning message and remove the shortcut from the other command, to avoid ambiguity. +- Fixed a bug where the Semantic Analyzer showed a false error message when using unqualified column references in a DAX window function. See [#1460](https://github.com/TabularEditor/TabularEditor3/issues/1460). +- Fixed a bug that could sometimes cause the **Data Refresh** view to freeze, requiring an app restart to resolve. See [#1461](https://github.com/TabularEditor/TabularEditor3/issues/1461). +- Fixed several smaller DAX editor issues related to auto complete, auto formatting, and syntax highlighting of keywords. +- Query Group names (i.e. "display folders" for Shared M expressions and M partitions) can now be modified. Also, if pasting an object with a query group into a model that doesn't contain said query group, it will be created automatically, so as to avoid the error message on subsequent Save / Deployment of the model. +- Fixed a bug where it was sometimes not possible to Undo previous changes, after saving the model metadata back to the server. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_23_0_zh.md b/content/localization/zh/3_23_0_zh.md new file mode 100644 index 00000000..90d599b7 --- /dev/null +++ b/content/localization/zh/3_23_0_zh.md @@ -0,0 +1,105 @@ +--- +uid: release-3-23-0 +--- + +# Tabular Editor 3.23.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.23.0 downloads: + +- Download [Tabular Editor 3.23.0 (x64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.23.0 (ARM64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.23.0.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe) | .NET 8 | x64 | `AFC65EB335297D644071565277A79AC28F425E77915A43FE4140FDAA73298E52` | +| [TabularEditor.3.23.0.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi) | .NET 8 | x64 | `08430DFA78C8565DDB93352963EA5AF90718F454BCC2D8EE7CE4B96BD8D4A50C` | +| [TabularEditor.3.23.0.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip) | .NET 8 | x64 | `B38957E4E9AF4D4ECBFF86820F4318081A663BF0F94F18038A5A009823D4F8EA` | +| [TabularEditor.3.23.0.Installer.ARM64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) | .NET 8 | ARM64 | `936E0D27006C337E20C03445D8D030E74D4CB0E811EF2F8E4EEE06EA360963F1` | +| [TabularEditor.3.23.0.ARM64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) | .NET 8 | ARM64 | `8EC2BC63BFBBF39314E39D795507E24DC3D6CD16F4D90DEE0E2ECD1BF0753924` | +| [TabularEditor.3.23.0.ARM64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) | .NET 8 | ARM64 | `FAB055031ABABB1F390F8E1DEE1BD3B1FDC5D09102D1B052830EF8CB7167CB22` | + +*** + +> [!NOTE] +> We are now providing native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) builds in addition to regular 64-bit (x64) builds. 32-bit (x86) builds have been discontinued. + +## New in 3.23.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +- Tabular Editor 3 now supports **DAX User-Defined Functions (UDFs)**. This is a big, important feature, and we can't do it justice in a few bullet points. Please check out the [dedicated documentation section](xref:udfs) to learn more. +- As if one big feature wasn't enough, we also added support for **Calendars** in this release. Again, please see the [dedicated documentation section](xref:calendars) to learn more. + +> [!NOTE] +> [Tabular Editor 3.23.1](xref:release-3-23-1) contains several important bugfixes related to UDFs and Calendars, so if you plan to use these features, we recommend updating to 3.23.1. + +- The **Table Import Wizard** now supports **Fabric SQL Databases** and **Fabric Mirrored Databases** as data sources, both for Import and Direct Lake mode models, in line with the [announcement in the Power BI Desktop July 2025 update](https://powerbi.microsoft.com/en-us/blog/power-bi-july-2025-feature-summary/#post-30545-_Toc203388697). +- Native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) support. +- Preparations for upcoming Power BI features (which we can't disclose just yet). + +## Improvements in 3.23.0 + +- Main window now remembers its position & size. Can be disabled in Preferences > Tabular Editor > User Interface > Layout. +- Messages view now copies the selected cell rather than the whole row by default, Ctrl+Shift+C can be used to copy the whole row as before. There is a new right click context menu with these (Copy Cell, Copy Row) options as well. +- Updated 3rd party dependencies including AMO/TOM to [v. 19.103.2](https://www.nuget.org/packages/Microsoft.AnalysisServices/). +- A new word wrap option is now exposed in toolbar, menu (Edit > Word Wrap) and preferences window (Text Editors > General). Line wrap indicators can also be enabled in the preferences. +- The C# script editor's auto complete now provides more flexible search (i.e. search for partial matches and search by capital letters). +- You can now use the "Apply" or "Apply selection" action on DAX queries containing [`DEFINE COLUMN`](https://www.sqlbi.com/articles/introducing-define-column-in-dax-queries/) or [`DEFINE TABLE`](https://www.sqlbi.com/articles/introducing-define-table-in-dax-queries/) statements, in addition to `DEFINE MEASURE` statements. This will create the corresponding calculated columns or calculated tables in the model, or update their DAX expressions if they already exist. +- Peek definition window now lets user scroll the main DAX editor instead of swallowing mouse scroll inputs while the mouse is on it. +- Peek definition window height is now adjusted more tightly. +- Semantic Analyzer no longer shows "Multiple column cannot be converted to a scalar value" errors, when there are other, more indicative error messages. + +## Bugfixes in 3.23.0 + +- Fixed a bug where you would have to enable **Allow unsupported modelling operations** in order to make any changes to a model in Power BI Desktop, even though modelling operations were supported. +- Fixed a bug where main window exceeds screen dimensions depending on resolution and DPI scaling. +- Fixed toolbar customization settings such as "Large icons", "Show ScreenTips on toolbars" etc. not persisting after restarting TE3. +- Fixed a visual glitch where TOM Explorer's Perspective and Language drop-down controls have duplicate buttons. +- Fixed a bunch of issues with "Peek definiton" feature: + - Peek definition is closed on undo/redo operations + - Peek definition is invisible when used on the last line of DAX editor + - Peek definition turns invisible when the line ending of the peeked reference is deleted + - Peek definition is also closed when trying to instead close auto-complete popup with ESC + - Peek definition is also closed when trying to instead clear rectangular-selection with ESC + - When a new line is added to the left of peeked reference, peek definition turns invisible and empty padding space incorrectly appears above the peeked reference + - Fix empty padding space appearing under the wrong line if the caret is on a different line than the peeked reference when the peek definition is triggered +- Calltips in the C# code editor are now sized correctly, ensuring that all of the calltip text is visible. +- Fixed a bug where Fabric Warehouses were not correctly listed in the Fabric connection dialog (instead they were shown as type "Unknown"). +- DAX autocomplete should no longer suggest `DAY` for the <Interval> parameter of the [`PARALLELPERIOD`](https://dax.guide/parallelperiod) function, as this is not a valid value for that parameter. +- Calltips will now update correctly when swapping between different syntax alternatives using the up/down arrows. +- Fixed a bug where code actions did not update correctly when switching between objects. +- Fix line numbers in code editors getting cut off when zoomed in. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_23_1_zh.md b/content/localization/zh/3_23_1_zh.md new file mode 100644 index 00000000..a045c071 --- /dev/null +++ b/content/localization/zh/3_23_1_zh.md @@ -0,0 +1,78 @@ +--- +uid: release-3-23-1 +--- + +# Tabular Editor 3.23.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.23.1 downloads: + +- Download [Tabular Editor 3.23.1 (x64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.23.1 (ARM64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be activated after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | .NET runtime | Platform | SHA-256 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | ------------------------------------------------------------------ | +| [TabularEditor.3.23.1.Installer.x64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe) | .NET 8 | x64 | `9FD7A96EC346CB7C32C3EE9468A0542A41AF25204C2C1D2DE79D16B32AFD7505` | +| [TabularEditor.3.23.1.x64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi) | .NET 8 | x64 | `F65112E90C0E49CD767C2FBFDA43D6E7FEDA7ADF2A07C08FC49F7D283BCA1BF4` | +| [TabularEditor.3.23.1.x64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip) | .NET 8 | x64 | `C25883760ED505437B78F69A1B5DA6471E083AB897FE32D6313EDCC155ABEE69` | +| [TabularEditor.3.23.1.Installer.ARM64.Net8.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) | .NET 8 | ARM64 | `DCCBAC2ED50459D40AECD5487E6F59EDA4C7863428FD68C126A6F4C4BE729362` | +| [TabularEditor.3.23.1.ARM64.Net8.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) | .NET 8 | ARM64 | `53CDFD40F4CAF622054459B31A9AD72EABC25392CC2023A236971D388F8F9A5A` | +| [TabularEditor.3.23.1.ARM64.Net8.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) | .NET 8 | ARM64 | `C97DC82AF4234162405AE25B77157C8B73837A1D336E2F9BEE66BAFA1D1AF28C` | + +*** + +> [!NOTE] +> We are now providing native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) builds in addition to regular 64-bit (x64) builds. 32-bit (x86) builds have been discontinued. + +## New in 3.23.0 + +Check out our [release blog](https://blog.tabulareditor.com/) to get a brief overview of the most important updates in this release. + +- Tabular Editor 3 now supports **DAX User-Defined Functions (UDFs)**. This is a big, important feature, and we can't do it justice in a few bullet points. Please check out the [dedicated documentation section](xref:udfs) to learn more. +- As if one big feature wasn't enough, we also added support for **Calendars** in this release, including DAX parser and editor support for 8 new DAX functions related to week-based time intelligence. Again, please see the [dedicated documentation section](xref:calendars) to learn more. + +## Improvements in 3.23.1 + +- We added Compatibility Level 1700 (SQL Server 2025) to the dropdown in the **New Model** dialog. Moreover, the default Compatibility Level for Power BI models has been updated to 1702 (which is needed for UDFs and Calendars). + +## Bugfixes in 3.23.1 + +- This update fixes several bugs related to UDFs and Calendars compared to 3.23.0. Mostly related to our built-in DAX parser, but also several tweaks and stability improvements for things like autocomplete, formatting, etc. +- We have downgraded the version of MSAL (Microsoft.Identity.Client) library to [4.72.1](https://www.nuget.org/packages/Microsoft.Identity.Client/4.72.1), as the newer versions of this library (used in the previous release of Tabular Editor 3), do not work well with the AS client library, [causing the application to hang when using the Microsoft Entra ID authentication option](https://github.com/TabularEditor/TabularEditor3/issues/1485). +- Removed the **Duplicate** and **Cut/Copy/Paste/Delete** actions for Calculated Table Columns, as these objects cannot be manually added/removed from tables, and doing so would cause issues upon saving the changes to Analysis Services / Power BI. You should modify the DAX of the calculated table instead. +- Mirrored Azure Databricks catalogs are now also shown in the Table Import Wizard UI, when choosing the **Fabric Mirrored Database** option. +- Fixed an issue where opening a model created with older versions of Power BI Desktop would cause a "The given key 'Extended Properties' was not present in the dictionary" error. +- Fixed a bug that prevented forward references in DAX script object properties. I.e. you no longer get an error if the `FormatString` property of a measure references a measure defined later in the script. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://youtu.be/O4ATwdzCvWc) to get a quick tour of the main features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger +- DAX Optimizer integration +- Code Actions to easily refactor you DAX. + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_2_0_zh.md b/content/localization/zh/3_2_0_zh.md new file mode 100644 index 00000000..43b9aed2 --- /dev/null +++ b/content/localization/zh/3_2_0_zh.md @@ -0,0 +1,45 @@ +# Tabular Editor 3.2.0 + +- Download [Tabular Editor 3.2.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.0](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.2.0 + +- We are proud to introduce the **DAX debugger** in this update of Tabular Editor 3. Check out [this article](https://docs.tabulareditor.com/te3/features/dax-debugger.html) to get started. +- Application startup time and footprint has been greatly improved. +- We have overhauled the layout customizations engine to address various issues (disappearing expression editors, missing toolbar buttons, etc.) **Please be aware that any layout customizations you have previously made will no longer work in v. 3.2.0**. +- Updated TOM to [19.32.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). + +## Bugfixes in 3.2.0 + +- Fixed an issue with the `CallDaxFormatter` method not respecting short/long formatting default, see [#324](https://github.com/TabularEditor/TabularEditor3/issues/324). +- Fixed an issue with formatting of calculation item properties in a DAX script. +- 3rd party assemblies can now be loaded from locations other than the installation folder, see [#340](https://github.com/TabularEditor/TabularEditor3/issues/340). +- Fixes an issue with automatic formula fixup when a column that was referenced in a CROSSFILTER or USERELATIONSHIP function call was renamed. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_2_1_zh.md b/content/localization/zh/3_2_1_zh.md new file mode 100644 index 00000000..1de0a5b9 --- /dev/null +++ b/content/localization/zh/3_2_1_zh.md @@ -0,0 +1,65 @@ +# Tabular Editor 3.2.1 + +- Download [Tabular Editor 3.2.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.1](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/#licensing)._ + +## Improvements in 3.2.1 + +- The debugger has been improved in various ways. For example, it is now easier to manage Watch expressions through a right-click context menu. You can also quickly add a measure, a variable reference, or a subexpression to the Watch expression view by right-clicking in the editor. See [this article](https://docs.tabulareditor.com/te3/features/dax-debugger.html) for more information. +- A new serialization option is available, which ensures that the JSON arrays for roles/perspectives are sorted by name when saved to disk, see [#341](https://github.com/TabularEditor/TabularEditor3/issues/341). Find the new option under **Tools > Preferences > File Formats > Sort arrays by name** (or to change the setting for an existing model go to **Model > Serialization options...**). + +## Bugfixes in 3.2.1 + +- Debugger now supports DAX queries that use the ROLLUPGROUP function. +- Fixed a bug with inverse filter being sent to the DAX debugger when starting from a Pivot Grid with a filter on a column containing two unique values. +- General DAX debugger stability improvements, see [#369]((https://github.com/TabularEditor/TabularEditor3/issues/369). +- The step over (F10) and step in (F11) shortcuts in the DAX debugger now behave more intuitively. +- Fix crash on model load when TOM Explorer has not yet been initialized, see issue [#357](https://github.com/TabularEditor/TabularEditor3/issues/357). +- Fixed an issue with workspace layout not being restored correctly on application restart or when switching between layouts. +- Ensure content of auto-hide panels is loaded when the panel is expanding +- Semantic analyzer should no longer report an error when the 3rd arg of the [SEARCH](https://dax.guide/search) or [FIND](https://dax.guide/find) functions is omitted. +- Semantic analyzer should no longer report errors when using the [ROLLUPGROUP](https://dax.guide/rollupgroup) and [ROLLUP](https://dax.guide/rollup) DAX functions (sometimes seen in queries generated by PBI Desktop). +- Various offline DAX formatter improvements, to make the offline formatter more consistent with https://daxformatter.com. +- Fix issue with comment frames being added to the previous expression in a DAX script, see [#331](https://github.com/TabularEditor/TabularEditor3/issues/331). +- Fix application crash at launch, issue [#328](https://github.com/TabularEditor/TabularEditor3/issues/328). +- Allow setting translated properties of multiple objects at once, see issue [#359](https://github.com/TabularEditor/TabularEditor3/issues/359). +- Fix refresh progress indicator "stuck", see issue [#360](https://github.com/TabularEditor/TabularEditor3/issues/360). +- Fix diagram font scaling, see issue [#351](https://github.com/TabularEditor/TabularEditor3/issues/351). +- Fix call tree rendering in high-dpi, see issue [#355](https://github.com/TabularEditor/TabularEditor3/issues/355). +- Ensure DAX scripts are parsed immediately when loaded from a file, see issue [#352](https://github.com/TabularEditor/TabularEditor3/issues/352). +- Fix bug that caused TE3 to stop syncing metadata from AS after the first change, see [#353](https://github.com/TabularEditor/TabularEditor3/issues/353). +- Fix issue with dependency tree not getting correctly rebuilt in some cases, see [#364](https://github.com/TabularEditor/TabularEditor3/issues/364). +- Replace existing table should no longer cause a crash, see issue [#368](https://github.com/TabularEditor/TabularEditor3/issues/368). +- Fix BPA not running until BPA view is first shown, see issue [#367](https://github.com/TabularEditor/TabularEditor3/issues/367). +- Use a single partition for AS change detection when connected to AS standard tier (which doesn't allow tables with multiple partitions). See [#336](https://github.com/TabularEditor/TabularEditor3/discussions/336). +- Inherit perspective membership for columns added through schema compare. See issue [#342](https://github.com/TabularEditor/TabularEditor3/discussions/342). +- Use default network credentils for web proxy (should solve issue with 407-errors when connecting to AS behind proxy). +- Semantic analyzer should no longer report an error when variable references are quoted, see issue [#302](https://github.com/TabularEditor/TabularEditor3/discussions/302). +- Improved display of error messages from Pivot Grids (they now appear in the **Messages view**). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_2_2_zh.md b/content/localization/zh/3_2_2_zh.md new file mode 100644 index 00000000..a09dbdd6 --- /dev/null +++ b/content/localization/zh/3_2_2_zh.md @@ -0,0 +1,75 @@ +# Tabular Editor 3.2.2 + +- Download [Tabular Editor 3.2.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.2](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Improvements in 3.2.2 + +- Added support for Query Groups (aka. Power Query "folders") on partitions and named expressions +- Prompt for first partition type. See [#406](https://github.com/TabularEditor/TabularEditor3/issues/406) +- Aligned display of relationship names to be similar to how VertiPaq Analyzer in DAX Studio displays the names. +- Allow debug commas in the Expression Editor, see [#407](https://github.com/TabularEditor/TabularEditor3/issues/407) +- Allow doubleclicking on any expression object in the TOM Explorer (such as partitions) to bring the quick editor into view +- Changed "Mixed" label to "Hybrid" on tables that contain multiple partitions types +- Pivot Grid: + - Pivot Grid now displays a grand total when slicing on a field that only has a single value (when field is used in the rows/columns area) + - Fields added to the Pivot Grid through the TOM Explorer context menu are now added "right-most".- Focus pivot grid cell on right-click +- DAX debugger improvements: + - Can now view and enable/disable individual filters from the outer filter context + - Added tooltips for watch/locals value types. + - Better determination and ordering of local items from current call (includes subexpressions within the same evaluation context, etc.) + - No longer shows a context transition on the evaluation context stack, when debugging a measure reference (step into the measure reference to see the context transition) + - No longer use TREATAS against SSAS 2016 + - Improved F10 (step over) within measures + - Improved auto-complete for Watch expression editor (is now able to suggest row context columns, variables, etc.) +- Updated TOM to [19.34.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/) + +## Bugfixes in 3.2.2 + +- Added more TOM properties, i.e.: Refresh Policy Mode (used to set up Hybrid tables refresh policy) +- Fix activation wizard hang, see [#419](https://github.com/TabularEditor/TabularEditor3/issues/419) +- Make sure custom toolbars can still be dragged/docked and customized after first layout restore. See issue [#413](https://github.com/TabularEditor/TabularEditor3/issues/413) +- Fix issue with properties panel not showing when invoking through context menu, see [#375](https://github.com/TabularEditor/TabularEditor3/issues/375) +- Prevent crash when navigating to Data Refresh from status bar, see issue [#370](https://github.com/TabularEditor/TabularEditor3/issues/370) +- Fixed an issue where application crashes when closing while a refresh is running in the background. +- Prevent expression editor from appearing when clicking in the Diagram. See issue [#43](https://github.com/TabularEditor/TabularEditor3/issues/43). Also improves behavior of selecting/dragging columns in the diagram view. +- Added missing fields to VeritPaq Analyzer, see [#372](https://github.com/TabularEditor/TabularEditor3/issues/372) +- Improved Pivot Grid behavior of calculation group columns. See [#412](https://github.com/TabularEditor/TabularEditor3/issues/412) +- Ensure Dependency View is updated every time a semantic analysis completes (such as when a model is modified through Power BI), see [#401](https://github.com/TabularEditor/TabularEditor3/issues/401) +- Do not suggest calc group functions in auto-complete, unless writing a calc item expression, see issue [#387](https://github.com/TabularEditor/TabularEditor3/issues/387) +- Fixed an issue where after uncommenting a selection, "undo" no longer behaves correctly. See [#301](https://github.com/TabularEditor/TabularEditor3/issues/301) +- Added shortcuts for comment (Ctrl+Shift+K)/uncomment (Ctrl+Shift+U). See [#371](https://github.com/TabularEditor/TabularEditor3/issues/371) +- Added shortcuts (Alt+Up/Down arrow) for moving selected lines up/down in text editors. See [#371](https://github.com/TabularEditor/TabularEditor3/issues/371) +- Fix stackoverflow exception when dragging windows around in certain ways. See [#354](https://github.com/TabularEditor/TabularEditor3/issues/354) +- Fix bug with macro recorder not stopping when a C# script view is closed, causing subsequent crash when a model object or property is changed. +- Macro recorder now also produces code for calc item expression changes as well as hierarchy level and calc item ordinal changes. See [#230](https://github.com/TabularEditor/TabularEditor3/issues/230) +- Debugger: Fix DAX generation for variables in outer filter context, see issue [#418](https://github.com/TabularEditor/TabularEditor3/issues/418) +- Check for and delete TablePermissions with invalid table references upon model load (previously, TE would not allow loading a model with such invalid references) +- Clear filter when a field is removed/hidden from a Pivot Grid, see issue [#427](https://github.com/TabularEditor/TabularEditor3/issues/427) + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_2_3_zh.md b/content/localization/zh/3_2_3_zh.md new file mode 100644 index 00000000..4d989808 --- /dev/null +++ b/content/localization/zh/3_2_3_zh.md @@ -0,0 +1,64 @@ +# Tabular Editor 3.2.3 + +- Download [Tabular Editor 3.2.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.2.3](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Improvements in 3.2.3 + +- Updated TOM to [19.36.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/) +- Use compatibility level 1569 for new PBI models +- Allow serialization of CalculationGroups and CalculationItems using ExportProperties. See [#976](https://github.com/TabularEditor/TabularEditor/issues/976) +- Allow specifying MemberID on .AddExternalMember and .AddWindowsMember, see [#484](https://github.com/TabularEditor/TabularEditor3/issues/484) and [#483](https://github.com/TabularEditor/TabularEditor3/issues/483) +- Allow specifying raw XMLA in calls to ExecuteCommand, as discussed in [#495](https://github.com/TabularEditor/TabularEditor3/issues/495) +- Allow copying Pivot Grid MDX query to clipboard by right-clicking anywhere in the Pivot Grid, see [#494](https://github.com/TabularEditor/TabularEditor3/issues/494). +- Improved BPA view (show severity, category) as well as tooltips. See [#489](https://github.com/TabularEditor/TabularEditor3/issues/489). +- Change default on the VertiPaq Analyzer "Read statistics from data" setting to "false" to align with DAX Studio / Bravo. +- Added new option to make Auto Complete popups less aggressive (only popup after entering a letter character), see[#459](https://github.com/TabularEditor/TabularEditor3/issues/459/). Locate this setting under **Tools > Preferences > DAX Editor > Code Assist**. + +## Bugfixes in 3.2.3 + +- Fix issue with table permissions not being properly deserialized. See [#446](https://github.com/TabularEditor/TabularEditor3/issues/446). +- Fix crash during startup with certain layouts, see issue [#455](https://github.com/TabularEditor/TabularEditor3/issues/455). +- Fixed an issue that could cause the application to crash when measures or other objects have curly braces in their names. +- Remove asterisk'ed properties (keys, passwords) when "Include sensitive" is set to false. See [#479](https://github.com/TabularEditor/TabularEditor3/issues/479). +- Fix save-to-folder serialization when using invalid file/folder names as object names, or when an object name contains a trailing space. Similar to [#952](https://github.com/TabularEditor/TabularEditor/issues/952) and [#978](https://github.com/TabularEditor/TabularEditor/issues/978). +- Show all refresh options if at least 1 non-calculated table is selected, see issue [#487](https://github.com/TabularEditor/TabularEditor3/issues/487) +- Fix semantic analyzer column lineage issue with UNION, see [#482](https://github.com/TabularEditor/TabularEditor3/issues/482). +- Fix issue with shortcuts not working on floating windows, see [#480](https://github.com/TabularEditor/TabularEditor3/issues/480). +- Do not show "EnableRefreshPolicy" property for calc tables, calc groups, or DirectQuery tables, see [#470](https://github.com/TabularEditor/TabularEditor3/issues/470). +- Fix Import Table Wizard issue when creating new structured data sources in some scenarios (for example, Oracle data sources). +- Fix crash when trying to add Structured ODBC data source through Import wizard. +- Fix diagram select issue when clicking on a column in another table. +- Fix issue with TOM explorer not updating to show the proper object type of a partition when its mode is changed +- Fix format of measures displayed in Pivot Grid, see [#492](https://github.com/TabularEditor/TabularEditor3/issues/492) +- Auto-complete should not insert parentheses if there's already an opening parenthesis by the cursor, see[#459](https://github.com/TabularEditor/TabularEditor3/issues/459/) +- Fixed autocomplete for CONVERT 2nd param (data type), see [#474](https://github.com/TabularEditor/TabularEditor3/issues/474). +- Starting a new rename operation should complete any existing ones, see[#461](https://github.com/TabularEditor/TabularEditor3/issues/461/). +- Fix issue with multiple EVALUATE statements not respecting ORDER BY when executing selection only. Also fixed an issue where ORDER BY didn't work on tables with names that are also DAX functions. See [#472](https://github.com/TabularEditor/TabularEditor3/issues/472) + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_3_0_zh.md b/content/localization/zh/3_3_0_zh.md new file mode 100644 index 00000000..bb6daadf --- /dev/null +++ b/content/localization/zh/3_3_0_zh.md @@ -0,0 +1,87 @@ +# Tabular Editor 3.3.0 + +- Download [Tabular Editor 3.3.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.msi) _(recommended)_ +- Download [Tabular Editor 3.3.0](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.msi) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +Tabular Editor 3 is now using [.NET 6](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-6) (we've been using .NET Framework 4.8.2 until now). With .NET 6, Microsoft has provided a unified and modern application development platform, which includes multiple performance improvements and security updates. As a Tabular Editor 3 user, you shouldn't notice any differences other than a slightly increased download size and possible performance improvements. + +**NOTE**: You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0. Make sure to grab the **Desktop** runtime that matches your version of Tabular Editor 3: + +- [.NET Desktop Runtime x64](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.6-windows-x64-installer) +- [.NET Desktop Runtime x86](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.6-windows-x86-installer) + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_3_1_zh.md b/content/localization/zh/3_3_1_zh.md new file mode 100644 index 00000000..298364d0 --- /dev/null +++ b/content/localization/zh/3_3_1_zh.md @@ -0,0 +1,101 @@ +# Tabular Editor 3.3.1 + +- Download [Tabular Editor 3.3.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.1](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.1.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) as well as the [Microsoft Visual C++ Redistributable package](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.1 + +- New Installer which automatically downloads and installs missing .NET Runtime and VC++ prerequisites, if they are missing. +- Added support for the DAX [`NETWORKDAYS`](https://dax.guide/NETWORKDAYS/) function. +- Updated TOM to [19.42.0.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) + +## Bugfixes in 3.3.1 + +- Fixed an issue with C# tooltips not showing xmldoc comments, unless application launched from installation folder. +- Semantic Analyzer now correctly reports an error when using special MDX reserved keywords as unquoted table references. +- Fixed an issue where attempting to deploy a model loaded from a .pbit file would fial. +- Fixed an issue with compilation of C# scripts and macros. See [#570](https://github.com/TabularEditor/TabularEditor3/issues/570), [#573](https://github.com/TabularEditor/TabularEditor3/issues/573) and [#580](https://github.com/TabularEditor/TabularEditor3/issues/580). +- Fixed an issue that prevented loading models containing calculation groups with one or more erroneous measures, see [#571](https://github.com/TabularEditor/TabularEditor3/issues/571). +- Fixed an issue with the diagram not automatically refreshing after reloading a model, see [#572](https://github.com/TabularEditor/TabularEditor3/issues/572). +- Fixed an issue that prevented the C# script engine from importing certain DLLs, see [#574](https://github.com/TabularEditor/TabularEditor3/issues/574). +- Fixed an issue that prevented connecting to Power BI Desktop after making a choice in the "Local instances" dropdown, see [#579](https://github.com/TabularEditor/TabularEditor3/issues/579). +- Fixed an issue where the TOM Explorer would select all objects (even when filtering the TOM Explorer), when pressing CTRL+A, see [#582](https://github.com/TabularEditor/TabularEditor3/issues/582). +- Various stability improvements based on anonymous telemetry/error reports. + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_3_2_zh.md b/content/localization/zh/3_3_2_zh.md new file mode 100644 index 00000000..da2b57e1 --- /dev/null +++ b/content/localization/zh/3_3_2_zh.md @@ -0,0 +1,106 @@ +# Tabular Editor 3.3.2 + +- Download [Tabular Editor 3.3.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.2](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x86.zip) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) as well as the [Microsoft Visual C++ Redistributable package](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.3.2 + +- Fixed a bug in the installer, which caused some files not to be updated when performing an in-place upgrade, which in turn could cause application crashes and other issues, see [#586](https://github.com/TabularEditor/TabularEditor3/issues/586). +- Added support for the `ExpressionSource` property on the [NamedExpression](xref:TabularEditor.TOMWrapper.NamedExpression) class. + +## Improvements in 3.3.1 + +- New Installer which automatically downloads and installs missing .NET Runtime and VC++ prerequisites, if they are missing. +- Added support for the DAX [`NETWORKDAYS`](https://dax.guide/NETWORKDAYS/) function. +- Updated TOM to [19.42.0.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) + +## Bugfixes in 3.3.1 + +- Fixed an issue with C# tooltips not showing xmldoc comments, unless application launched from installation folder. +- Semantic Analyzer now correctly reports an error when using special MDX reserved keywords as unquoted table references. +- Fixed an issue where attempting to deploy a model loaded from a .pbit file would fial. +- Fixed an issue with compilation of C# scripts and macros. See [#570](https://github.com/TabularEditor/TabularEditor3/issues/570), [#573](https://github.com/TabularEditor/TabularEditor3/issues/573) and [#580](https://github.com/TabularEditor/TabularEditor3/issues/580). +- Fixed an issue that prevented loading models containing calculation groups with one or more erroneous measures, see [#571](https://github.com/TabularEditor/TabularEditor3/issues/571). +- Fixed an issue with the diagram not automatically refreshing after reloading a model, see [#572](https://github.com/TabularEditor/TabularEditor3/issues/572). +- Fixed an issue that prevented the C# script engine from importing certain DLLs, see [#574](https://github.com/TabularEditor/TabularEditor3/issues/574). +- Fixed an issue that prevented connecting to Power BI Desktop after making a choice in the "Local instances" dropdown, see [#579](https://github.com/TabularEditor/TabularEditor3/issues/579). +- Fixed an issue where the TOM Explorer would select all objects (even when filtering the TOM Explorer), when pressing CTRL+A, see [#582](https://github.com/TabularEditor/TabularEditor3/issues/582). +- Various stability improvements based on anonymous telemetry/error reports. + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_3_3_zh.md b/content/localization/zh/3_3_3_zh.md new file mode 100644 index 00000000..e30e1a99 --- /dev/null +++ b/content/localization/zh/3_3_3_zh.md @@ -0,0 +1,132 @@ +# Tabular Editor 3.3.3 + +- Download [Tabular Editor 3.3.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.3](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.3 + +- **The Import Table Wizard now allows you to import tables from a Power BI Dataflow.** Note that this option is only available when working on Power BI datasets. Moreover, Tabular Editor can now perform a schema update of tables based on Power BI dataflows, even when working offline (i.e. when not connected to the Power BI XMLA endpoint). +- C# scripts: Entering a closing parenthesis or bracket now closes the auto-complete box. Moreover, the pre-selection of the auto-complete box based on the current search string has been improved. +- C# scripts: Runtime error messages now include stack traces, making debugging easier. +- The default compatibility level for new Power BI datasets is now 1570. +- Under **Tools > Preferences > File formats**, we now have a set of options that allow you to specify the default compatibility level and whether or not to use a workspace database, when creating a new model. +- Instead of throwing a connection error, SQL server connections that fail because of an untrusted certificate, now prompt you if you want to trust the certificate and reconnect. +- It is now possible to disable automatic formula fix-up (under Tools > Preferences > Modeling Operations), see also [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- Added an .msi version of the installer, which is useful for unattended installations or installations through software packaging. +- 32 bit installers should now allow installation on 64 bit systems (but not vice versa). +- Added "Lock column width" right-click menu option on TOM Explorer, table preview, VertiPaq analyzer, etc. When checked, columns are always resized to match the width of the grid, changing the behavior of "Best fit (All columns)". This solves issue [#603](https://github.com/TabularEditor/TabularEditor3/issues/603) and also addresses one of the suggestions in [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- More column options in DAX query results, when right-clicking on a result column header. For example, you can hide/show columns, display a find panel for quickly filtering using a text string, and even group by columns to display the query results hierarchically. Note that sorting/grouping/filtering of query results only happens locally on the cached result (which is typically the first 1000 rows of a query). Adjust your DAX query if you need to perform these operations on the full set of data. +- BPA rules can now be downloaded from URLs using basic authentication, see [#604](https://github.com/TabularEditor/TabularEditor3/issues/604). + +## Bugfixes in 3.3.3 + +- Fix several issues related to macro compilation/execution, see [#587](https://github.com/TabularEditor/TabularEditor3/issues/587) and [#573](https://github.com/TabularEditor/TabularEditor3/issues/573). +- Fix issue with calls to `FormatDax` through scripts not working when using daxformatter.com, see [#592](https://github.com/TabularEditor/TabularEditor3/issues/592). +- Fix issue with scripts not able to call the Error and Warning global methods +- Fix issue with macros not being able to compile when the code contains an aliased using directive +- Fix issue with macros NullReferenceException when calling methods like EvaluateDax, etc. +- Fixed syntax highlighting of unquoted table references which are also keywords (for example 'Currency' is valid as an unquoted table reference in DAX, but it was previously colored as if it was a keyword) +- Got rid of the Visual C++ Redistributable dependency, which, when not installed, caused Tabular Editor to crash often. + +## Bugfixes in 3.3.2 + +- Fixed a bug in the installer, which caused some files not to be updated when performing an in-place upgrade, which in turn could cause application crashes and other issues, see [#586](https://github.com/TabularEditor/TabularEditor3/issues/586). +- Added support for the `ExpressionSource` property on the [NamedExpression](xref:TabularEditor.TOMWrapper.NamedExpression) class. + +## Improvements in 3.3.1 + +- New Installer which automatically downloads and installs missing .NET Runtime and VC++ prerequisites, if they are missing. +- Added support for the DAX [`NETWORKDAYS`](https://dax.guide/NETWORKDAYS/) function. +- Updated TOM to [19.42.0.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) + +## Bugfixes in 3.3.1 + +- Fixed an issue with C# tooltips not showing xmldoc comments, unless application launched from installation folder. +- Semantic Analyzer now correctly reports an error when using special MDX reserved keywords as unquoted table references. +- Fixed an issue where attempting to deploy a model loaded from a .pbit file would fial. +- Fixed an issue with compilation of C# scripts and macros. See [#570](https://github.com/TabularEditor/TabularEditor3/issues/570), [#573](https://github.com/TabularEditor/TabularEditor3/issues/573) and [#580](https://github.com/TabularEditor/TabularEditor3/issues/580). +- Fixed an issue that prevented loading models containing calculation groups with one or more erroneous measures, see [#571](https://github.com/TabularEditor/TabularEditor3/issues/571). +- Fixed an issue with the diagram not automatically refreshing after reloading a model, see [#572](https://github.com/TabularEditor/TabularEditor3/issues/572). +- Fixed an issue that prevented the C# script engine from importing certain DLLs, see [#574](https://github.com/TabularEditor/TabularEditor3/issues/574). +- Fixed an issue that prevented connecting to Power BI Desktop after making a choice in the "Local instances" dropdown, see [#579](https://github.com/TabularEditor/TabularEditor3/issues/579). +- Fixed an issue where the TOM Explorer would select all objects (even when filtering the TOM Explorer), when pressing CTRL+A, see [#582](https://github.com/TabularEditor/TabularEditor3/issues/582). +- Various stability improvements based on anonymous telemetry/error reports. + +## Improvements in 3.3.0 + +- Updated TOM to [19.39.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64/) +- Tabular Editor 3 now uses [Roslyn](https://github.com/dotnet/roslyn) for C# script compilation. This means that your C# scripts can now use all the wonderful new language features of [C# 10.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10). Moreover, you can define classes and other types directly within your scripts. Last but not least, we finally have Roslyn-powered **code completion** and **calltips** for C# scripts (see screenshot). + ![Csharp Intellisense](~/content/assets/images/csharp-intellisense.png) +- On a similar note, make sure to check out our new [Scripting API](xref:api-index) docs site, where you'll find up-to-date documentation for all of the objects and members you can access through Tabular Editor 3's C# scripting feature. +- We also have a great improvement for the auto complete feature in our DAX editors, which will now show tooltips providing more information about the objects in the auto complete list. The tooltip will show the `Description` of measures, columns, etc. If no description is specified, we'll show the first 10 lines of DAX code on the object: + ![Dax Intellisense Improv](~/content/assets/images/dax-intellisense-improv.png) +- When opening a model from Analysis Services or the Power BI XMLA endpoint, we now provide options to help you avoid making changes to the model by mistake, which is useful when you have multiple instances of Tabular Editor 3 open. The **Mode** dropdown (see screenshot below) lets you open a model in read-only or read/refresh-only mode. The **Status bar color** dropdown lets you set a color for Tabular Editor 3's status bar, so you can easily distinguish for example production, test, and dev models that are simultaneously open in different instances of Tabular Editor. See [#558](https://github.com/TabularEditor/TabularEditor3/issues/558). + ![New Open Fromdb Options](~/content/assets/images/new-open-fromdb-options.png) +- We have finally added the "Duplicate object" context menu option (Ctrl+D) in the TOM Explorer, see [#501](https://github.com/TabularEditor/TabularEditor3/issues/501). +- Added support for Snowflake OAuth and ExternalBrowser authentication, see [#546](https://github.com/TabularEditor/TabularEditor3/issues/546). +- Property grid now has a search bar. +- Added more proxy configuration options under **Tools** > **Preferences** > **Proxy Settings**. +- Updated SQL Native Client library to the latest version. Connections to SQL Server now require encryption by default (unless connecting to localhost). +- Added a **Refresh clear** option at the model, table and partition levels, see [#511](https://github.com/TabularEditor/TabularEditor3/issues/511). +- Added checkbox to open data models without workspace database, [#523](https://github.com/TabularEditor/TabularEditor3/issues/523). + +## Bugfixes in 3.3.0 + +- Fixed an issue with how the semantic analyzer handles the `NAMEOF` DAX function, which could sometimes cause a crash, see [#538](https://github.com/TabularEditor/TabularEditor3/issues/538). +- Property grids and collection editors now use the DevExpress com are now skinned and scaled correctly on hi-dpi monitors, see [#548](https://github.com/TabularEditor/TabularEditor3/issues/548). +- Fixed a bug where the **Refresh model** submenu would sometimes disappear from the **Model** menu. +- "**Update table schema...**" will now correctly deal with columns where the name has only changed in casing. +- TE3 Business Edition now prevents adding multiple partitions/perspectives to AS models (which will prevent TE3 from loading the same model later due to edition restrictions). +- Fixed an issue where editor actions would sometimes be disabled, see [#519](https://github.com/TabularEditor/TabularEditor3/issues/519). +- Fixed an issue with the **Cancel** and **Cancel All** buttons not being enabled after starting a refresh operation. +- Fixed an issue where refresh progress would not show when refreshing a Power BI model through the XMLA endpoint. +- Fix typo, see [#553](https://github.com/TabularEditor/TabularEditor3/issues/553). +- Fix issue with calltips appearing despite unticking the "Show parameter info automatically" setting, see [#545](https://github.com/TabularEditor/TabularEditor3/issues/545). +- Fix comment/uncomment bug, see [#536](https://github.com/TabularEditor/TabularEditor3/issues/536). +- Fix issue with wrong return type on CUSTOMDATA(), see [#527](https://github.com/TabularEditor/TabularEditor3/issues/527). +- In the data preview, when filtering a string column for "(Blanks)", we now include both BLANK and "" strings, see [#524](https://github.com/TabularEditor/TabularEditor3/issues/524). +- Fix "Tabular Editor was not able to open the specified file" error when attempting to open a database.json file through the generic open file dialog, while "All files" is selected in the dropdown. See also [#563](https://github.com/TabularEditor/TabularEditor3/issues/563). +- Fix bug with Save feature not respecting serialization settings checkbox choice. +- Fix color of link in status bar. See [#521](https://github.com/TabularEditor/TabularEditor3/issues/521). +- Fix crash when attempting to clear orphaned traces in the preferences dialog. +- Fix false positive semantic error issue when comparing with variants, see [#516](https://github.com/TabularEditor/TabularEditor3/issues/516). +- Fix issue with DAX generation when debugging a variable assignment containing IF/SWITCH function calls, see [#513](https://github.com/TabularEditor/TabularEditor3/issues/513). +- Do not allow WEEK as interval parameter for DATEADD. See [#508](https://github.com/TabularEditor/TabularEditor3/issues/508). +- Show calc item error indicator on the calc group table, see [#506](https://github.com/TabularEditor/TabularEditor3/issues/506). +- Fix issue with c# script method `ImportProperties` not correctly resolving object paths. +- Added link to self-service portal when number of installations exceeded. Updated URLs/links to various places +- Better DAX code generation when debugging USERELATIONSHIP. +- Allow unchecking saving model metadata backup preference. Better error message when model metadata backup fails. Allow cancellation of model metadata backup. +- Fixed an issue with REMOVEFILTERS. See [#562](https://github.com/TabularEditor/TabularEditor3/issues/562). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_3_4_zh.md b/content/localization/zh/3_3_4_zh.md new file mode 100644 index 00000000..6f476f96 --- /dev/null +++ b/content/localization/zh/3_3_4_zh.md @@ -0,0 +1,73 @@ +# Tabular Editor 3.3.4 + +- Download [Tabular Editor 3.3.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.4](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.4 + +- Updated TOM to v. [19.46.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Updated Microsoft.Data.SqlClient to v. [5.0.0](https://www.nuget.org/packages/Microsoft.Data.SqlClient). +- Updated SciLexer.dll to v. 4.4.6, which is not affected by [this CVE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2019-16294). +- Multiple minor fixes and improvements. +- New/Edit Relationship dialog improvements: Columns are sorted alphabetically and by matching type. We now also suggest the "to-column" based on the name of the "from-column". +- Changed default CL for new Power BI datasets to 1571 and added support for the [ObjectTranslation.Altered](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.objecttranslation.altered?view=analysisservices-dotnet) property, which should be set to "true" to prevent metadata translations from being overwritten from the source, when creating DirectQuery over AS datasets. +- Added a new shortcut, **Ctrl+Alt+S**, to save the current model. See [#595](https://github.com/TabularEditor/TabularEditor3/issues/595), [#561](https://github.com/TabularEditor/TabularEditor3/issues/561). +- Added shortcut **Ctrl+Shift+F6** for Debug Comma DAX formatting. See [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- Offline Schema Detection should now work when parameters such as Server Name and Database Name are stored in shared M expressions. + +## Bugfixes in 3.3.4 + +- Fixed an issue where the Udate Table Schema option would report all columns as removed, see [#612](https://github.com/TabularEditor/TabularEditor3/issues/612). +- Fix false semantic analyzer errors when using nested filter expressions. +- Fix false semantic analyzer errors when using `NATURALINNERJOIN` / `NATURALLEFTOUTERJOIN` on tables that are joind by relationships instead of common columns. +- Fix issue when trying to show connection dialog for ODBC connectors, see [#448](https://github.com/TabularEditor/TabularEditor3/issues/448) +- AAD authentication with Microsoft.Data.SqlClient now displays a modal popup (instead of opening the OS browser) +- Fix issue with SQL Server connection dialog "advanced button" sometimes causing a crash. +- Table Import Wizard now allows previewing data on Azure Synapse (the NOLOCK hint is no longer added to the data preview query) +- 32 bit installer should now correctly check for the 32 bit .NET Desktop Runtime +- DAX autocomplete can now also suggest Variant-typed scalar variables, see [#615](https://github.com/TabularEditor/TabularEditor3/issues/615) +- Fixed an issue with the DAX debugger not being able to display local/watch expressions with nested conditional branches. +- Include SciLexer.dll in application folder instead of extracting/Loading it to %LocalAppData%\Temp. Should prevent the "Exception has been thrown by the target of an invocation" error seen sometimes when group policy prevents loading DLLs from this location. +- Fixed an issue with the Property Grid not being able to set nested properties on multiple selections. See [#614](https://github.com/TabularEditor/TabularEditor3/issues/614). +- Fixed an issue where the Property Grid did not refresh to show dynamically added/removed properties, for example when toggling the "Incremental Refresh Policy" property. +- Fixed an issue where an AAS Developer Tier instance would be regarded as a Standard Tier instance, preventing connectivity with TE3 Business Edition +- Fix issue with NAMEOF autocomplete not showing all column/measure references in some situations, see [#620](https://github.com/TabularEditor/TabularEditor3/issues/620). +- Fixed an issue with certain DAX keywords (START, ORDER, RETURN, etc.) not being treated as an error, when used as table references without quotes. This bug also prevented proper formatting of code containing a quoted reference to such tables. +- Fixed the "4096 (0x1000) is an invalid culture identifier", see [#576](https://github.com/TabularEditor/TabularEditor3/issues/576). +- Prevent find/replace search crash, see [#611](https://github.com/TabularEditor/TabularEditor3/issues/611). +- Show all properties when in read-only mode, see [#596](https://github.com/TabularEditor/TabularEditor3/issues/596). +- Removed animation for pinned/unpinned windows, see [#595](https://github.com/TabularEditor/TabularEditor3/issues/595). +- Don't autobrace in DAX comments, see [#597](https://github.com/TabularEditor/TabularEditor3/issues/597). +- Fix issue with default CL value causing crash in Preferences dialog when set to a non-standard value. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_3_5_zh.md b/content/localization/zh/3_3_5_zh.md new file mode 100644 index 00000000..7a9bcd86 --- /dev/null +++ b/content/localization/zh/3_3_5_zh.md @@ -0,0 +1,80 @@ +# Tabular Editor 3.3.5 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.3.5 downloads: + +- Download [Tabular Editor 3.3.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.5 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.3.5.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x64.exe) | `5DEBB2304B418C4654BADCB18A477192D95A1308EA0BFF64E9C886846D991F6B` | +| [TabularEditor.3.3.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.msi) | `CC5A83963C4C69C3778E0729A0726B473BA9E85F895CDD9F60C6D480A8C81C9A` | +| [TabularEditor.3.3.5.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.zip) | `C7F2FEDC9F00EE0EFC7633AA72FB7C338FCFFDF952FCB2054B6E7A353972E187` | +| [TabularEditor.3.3.5.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x86.exe) | `0684C85CFD1ADA9290924345B17FCA5743D4B94C9D22E21D50DFE10D0B27676D` | +| [TabularEditor.3.3.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.msi) | `3A1BF0431BC0271598139D5AA28007D05E1B6C2D800953AAD29091606C2C3CD5` | +| [TabularEditor.3.3.5.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.zip) | `92F7014F15513BBF41AF4800FD8CCDF83B20C13D3C78005C96CE45F8CF7E8DF1` | + +*** + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.5 + +- New splash screen and icon, matching our new website brand. +- Updated TOM to [19.48.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Tabular Editor 3 now has a set of [configurable policies](https://docs.tabulareditor.com/common/policies.html), which let IT organisations govern certain Tabular Editor 3 features. +- Column widths can now be locked on the Messages, Macros and BPA views. +- Improved the Macros view with a right-click menu and toolbar buttons to open/edit macros. +- Added semantic analyzer and autocomplete support for the [`EVALUATEANDLOG`](https://dax.guide/evaluateandlog) and [`SAMPLEAXISWITHLOCALMINMAX`](https://dax.guide/sampleaxiswithlocalminmax) DAX functions. +- The "Revert" File menu option is now also available when a model was loaded from disk. +- DAX debugger now supports more types of DAX queries, specifically it is now possible to debug cell values when the query uses [`ADDCOLUMNS`](https://dax.guide/addcolumns), [`CALCULATETABLE`](https://dax.guide/calculatetable), [`SAMPLE`](https://dax.guide/sample), [`SAMPLEAXISWITHLOCALMINMAX`](https://dax.guide/sampleaxiswithlocalminmax), [`SUBSTITUTEWITHINDEX`](https://dax.guide/substitutewithindex) and [`SUMMARIZE`](https://dax.guide/summarize). This should ensure that most types of queries generated by PBI Desktop can be used with the TE3 debugger. Note that only cell values that originate from explicit measures can be debugged. +- Added a "Step into selection" option in the DAX debugger to make navigation easier. Use the shortcut key (Ctrl+B) or right-click anywhere in the code and choose "Step into selection" to navigate. +- Better visualisation of objects with errors/warnings in the TOM Explorer. Better icons in the Data Refresh tab. + +## Bugfixes in 3.3.5 + +- More reliable detection of Azure AS Developer tier (D1), which would sometimes prevent Business Edition customers from accessing the AAS instance. +- Allow role name changes in PBI Desktop restricted mode, see [#624](https://github.com/TabularEditor/TabularEditor3/issues/624). +- Fix SortByColumn not settable, see [#625](https://github.com/TabularEditor/TabularEditor3/issues/625). +- Fixed an issue that would prevent Tabular Editor to connect to ODBC data sources, when connection string properties were specified as "Extended Properties" in the connection string. +- Use TOP row limit clause for Snowflake ODBC by default. +- Fix issue with wait spinner overlapping "SelectItem" dialog when executed as script/macro. See [#622](https://github.com/TabularEditor/TabularEditor3/issues/622). +- Fixed an issue with how the debugger handles (blank) and binary values in filters. +- Automatic fallback to `Protocol Format=xml` if the connection fails due to invalid Binary XML. See [#637](https://github.com/TabularEditor/TabularEditor3/issues/637). +- Fix "Batch rename" not available in Power BI Desktop models. +- Add M parser support for special characters, see [#638](https://github.com/TabularEditor/TabularEditor3/issues/638). +- Treat 'version' as a DAX reserved word (i.e. always quote and show an error if used unquoted or as a variable name). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- \ No newline at end of file diff --git a/content/localization/zh/3_3_6_zh.md b/content/localization/zh/3_3_6_zh.md new file mode 100644 index 00000000..7c106038 --- /dev/null +++ b/content/localization/zh/3_3_6_zh.md @@ -0,0 +1,86 @@ +# Tabular Editor 3.3.6 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.3.6 downloads: + +- Download [Tabular Editor 3.3.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.3.6 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.3.6.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x64.exe) | `87D03220E55CF557356B82B718E80723FC2C92C840452A2B584488990E7CE04F` | +| [TabularEditor.3.3.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.msi) | `372543CF203E5796F917F370FE9533C8C26BF549EE730A8FAEA366B8D473BA8A` | +| [TabularEditor.3.3.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.zip) | `58025CA72C569DB9F1FDAA02A7EBEDB00FB0C22B39C669454219AABC9F5291AC` | +| [TabularEditor.3.3.6.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x86.exe) | `4699A0C2B0C67EFD2301F1F4F886A6B58160925AC2CBBEE83C49CFB7B4ADBF9D` | +| [TabularEditor.3.3.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.msi) | `F37723385F9B0EB80F797D4853E5250D3E1B152FAAC3F4BBD0FAE06B5F441090` | +| [TabularEditor.3.3.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.zip) | `5DC066325E635769487EE23D52BECF410665028C20C76E4A51CB1647E83DD783` | + +*** + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.3.6 + +- Updated TOM to [19.52.2.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Added support for measure Format String expressions (Compatibility Level 1601 or higher). +- Table `SourceExpression` and `PollingExpression` M queries can now be edited through the primary Expression Editor. +- Right-clicking on an expression property (such as `SourceExpression`, `PollingExpression`, `FormatStringExpression`, etc.) in the property grid now has a shortcut to edit the value in the primary Expression Editor. +- A Data Column's `SourceColumn` property value now appears in the "Expression" column of the TOM Explorer +- Added TOM Explorer and VertiPaq Analyzer column header tooltips. +- M parser improvements and support for additional M functions when performing offline Schema Updates, including support for CommandTimeout, and other connection options. +- Tabular Editor now displays a toast notification when a data refresh operation finishes in the background. This can be disabled under **Tools > Preferences > Features > Notifications**. +- Added support for new DAX functions ([OFFSET](https://dax.guide/offset), [TOJSON](https://dax.guide/tojson), [TOCSV](https://dax.guide/tocsv), and more). +- Macros are now compiled in a background thread, which improves application start-up time, and also fixes [#708](https://github.com/TabularEditor/TabularEditor3/issues/708). +- Updated to use the latest version of [VertiPaq Analyzer](https://github.com/sql-bi/VertiPaq-Analyzer). +- Added Compatibility Level 1600 as new default for SQL Server 2022 models. + +## Bugfixes in 3.3.6 + +- DAX debugger now correctly preserves the original query expression when debugging, thus preserving the original shadow filter context and any auto-exist modifications to table filters. Among other things, this means that expressions containing `ALLSELECTED` can now be debugged properly, see [#669](https://github.com/TabularEditor/TabularEditor3/issues/669). +- Improved async connectivity during Table Import Wizard / Schema Update. Also improved error handling - for example when SQL connection fails due to a missing certificate. +- Fixed an issue with the Delete button not working in the Macros view. +- Fixed an issue with the M parser not supporting records when the field name contains a space, such as `[Order Date]`. This should allow the Schema Update feature to work in offline mode, when an M expression contains such a record reference. +- Fixed a bug where the .tmuo file was not updated when using workspace mode with a folder structure, causing credentials to not be saved between sessions. +- Fixed a bug that allows searching all expression properties, see [#663](https://github.com/TabularEditor/TabularEditor3/issues/663). +- Fixed an issue where the debugger script did not close when closing a model. +- Removed the possibility of adding partitions to calculated tables. +- Fixed an issue where the application would sometimes crash when using the Find/Replace dialog. +- Fixed incorrect tooltip for New DAX Script button, see [#678](https://github.com/TabularEditor/TabularEditor3/issues/678). +- Fixed an issue where floating docs being closed would not prompt for save, see [#673](https://github.com/TabularEditor/TabularEditor3/issues/673). +- Fixed an issue where the column filter on a Data Preview, would sometimes crash the application when toggling (All) or (Blank) values. +- Fixed an issue with Snowflake data type inference when using Schema Update or Table Import Wizard (NUMBER columns would get imported as Double when they should be imported as Int64 or Decimal). +- Semantic Analyzer should no longer report an error when extension columns are used in [SUMMARIZE](https://dax.guide/summarize). +- Semantic Analyzer now reports an error when 'ID' is used as a table reference without quotes. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_4_0_zh.md b/content/localization/zh/3_4_0_zh.md new file mode 100644 index 00000000..52fef2a1 --- /dev/null +++ b/content/localization/zh/3_4_0_zh.md @@ -0,0 +1,104 @@ +# Tabular Editor 3.4.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.4.0 downloads: + +- Download [Tabular Editor 3.4.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.4.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.4.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x64.exe) | `FC244BDF95D4401B36816F743BF872E2533800DDC1EDD3FAA5679F20B584F762` | +| [TabularEditor.3.4.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.msi) | `FEE6D3ABE2EE58CEC3D2DFF1A83475347C70645AB3604B92FB3FBE586C9B01DD` | +| [TabularEditor.3.4.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.zip) | `0E62FBA977DEDC80ABA49DE469B8DDD8987C11641F722207A0CF6C03333D1682` | +| [TabularEditor.3.4.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x86.exe) | `E2C7BDA32F12B8778F6E6FD468E6298061FE96D88CBCBC5629137B70100ECC88` | +| [TabularEditor.3.4.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.msi) | `717889EA2808F96E26869A6522D331F92935A7F3C7D50D51023A2127CADB2A98` | +| [TabularEditor.3.4.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.zip) | `A6CB763B9476A92E781221C9278DFB4D0813D81C0B951C0350E96FFBF86AE37E` | + +*** + +## Important! + +**NOTE**: Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New features in 3.4.0 + +- Updated TOM to [19.54.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Tabular Editor 3 now supports the [new DAX window functions](https://pbidax.wordpress.com/2022/12/15/introducing-dax-window-functions-part-1/) announced in the Power BI Desktop December 2022 update. +- Customizable keyboard shortcuts are here! Do you want to always use CTRL+S to save the model, regardless of context? Do you want to assign a hotkey to perform a model refresh? How about an editor shortcut to [select all occurrences of current selection](https://github.com/TabularEditor/TabularEditor3/issues/630)? Find this feature under **Tools > Preferences > Keyboard**. More info [here](xref:preferences#tabular-editor--keyboard). +- All code editors now allow multiple selections (i.e. hold down CTRL and drag using the mouse, to create a new selection), in addition to rectangular selections (holding down ALT while dragging or using SHIFT + arrow keys). + +## Minor improvements in 3.4.0 + +- Tabular Editor 3 now displays the correct icon in the Power BI External Tools ribbon. +- Consolidated editing of Column-type properties in the property grid. You can now specify a column by typing its name in the property grid. When more than 7 columns are present, a "select column" dialog appears instead of a dropdown. This also fixes [#738](https://github.com/TabularEditor/TabularEditor3/issues/738). +- Removed square brackets from column names in Table Preview +- It is now possible to connect and select a different Power BI workspace in the Import Table Wizard. +- Pivot Grid field list is now a dockable window, see [#742](https://github.com/TabularEditor/TabularEditor3/issues/742). +- DAX calltips are now formatted correctly when the source descriptions contain HTML tags. +- All code editors now have much improved rectangular selections, when using the keyboard to perform selection. Moreover, copy/paste now works more intuitively with rectangular selections. +- Added option to lock menus and toolbar, to prevent accidentally dragging them around, in the Tools > Customize dialog (under the "Options" tab). +- Scintilla multiple selection add next/add each now respects search flags specified in the Find Dialog. +- Allow File.SaveModel shortcut to work regardless of context, see [#762](https://github.com/TabularEditor/TabularEditor3/issues/762). +- It is now possible to cancel a long-running save operation, such as when the database is locked by a refresh operation. See [#730](https://github.com/TabularEditor/TabularEditor3/issues/730). +- Create/edit relationship dialog can now be resized, see [#732](https://github.com/TabularEditor/TabularEditor3/issues/732). +- Allow arrow key expand/collapse on all tree lists (including BPA, dependency view and data refresh view), see [#775](https://github.com/TabularEditor/TabularEditor3/issues/775). +- We've listened to your feedback! "Show relationships from table" is now back in the Dependency View, see [#731](https://github.com/TabularEditor/TabularEditor3/issues/731). + +## Bugfixes in 3.4.0 + +- The AAD connect dialog should now show up as a modal dialog in all cases. +- Create undo transaction when multiple objects are edited in batch +- An object property (such as SortByColumn) can now be cleared by right-clicking and choosing "Reset". +- Right-click shortcut for editing table expression properties (SourceExpression, PollingExpression, etc.) are now available, see [#721](https://github.com/TabularEditor/TabularEditor3/issues/721). +- Pivot Grid should no longer freeze when fields are dragged on top of it, see [#676](https://github.com/TabularEditor/TabularEditor3/issues/676). +- Fix issue [#723](https://github.com/TabularEditor/TabularEditor3/issues/723). +- Fixed an issue that prevented table schema updates and crashed the Import Table Wizard, when attempting to import from an existing Power BI Dataflow, specified in the .tmuo file. +- Fixed an issue with the DAX debugger generating invalid watch expression DAX queries, see [#770](https://github.com/TabularEditor/TabularEditor3/issues/770). +- Fixed an issue which would sometimes cause the debugger windows to crash (showing red crosses on a white background). +- Fixed an issue where the Import Table Wizard would sometimes show Dataflows with no names. +- "Revert" button should always be enabled now. Moreover, a confirmation prompt is only shown when changes have been made. See [#729](https://github.com/TabularEditor/TabularEditor3/issues/729). +- Showing the field list no longer clears the Pivot Gird, see [#741](https://github.com/TabularEditor/TabularEditor3/issues/741). +- Fixed an issue where columns in the TOM Explorer would sometims be "cut off" when the application is launched. +- TOM Explorer now only allows adding EntityPartitions on Power BI datasets +- Fix dependency view crash issue, see [#758](https://github.com/TabularEditor/TabularEditor3/issues/758) +- Fixed an issue where floating windows could spawn outside the visible screen area when the application is restarted, see [#652](https://github.com/TabularEditor/TabularEditor3/issues/652). +- Fix issue with recent server not being persisted. +- Fixed a few bugs related to how actions appear in the "Model" and/or "Context" menu. For example, "Script DAX" in the Model menu, only scripted objects within the current selection, where as it was intended to script all objects in the model. +- Fix horizontal scrollbar behavior of text editors. +- SQL Connection Dialog should now persist its changes to the connection string, see [#755](https://github.com/TabularEditor/TabularEditor3/issues/755). +- Selecting a database after filtering the list in the "Choose database" dialog, now ensures that the correct database is actually loaded. See [#761](https://github.com/TabularEditor/TabularEditor3/issues/761). +- Fix issue when scrolling through tables (see [#733](https://github.com/TabularEditor/TabularEditor3/issues/733), and row count not updating when applying filter criteria. + +_The Tabular Editor 3 team wishes you all a great holiday season and a happy new year!_ + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_4_1_zh.md b/content/localization/zh/3_4_1_zh.md new file mode 100644 index 00000000..d681e071 --- /dev/null +++ b/content/localization/zh/3_4_1_zh.md @@ -0,0 +1,92 @@ +# Tabular Editor 3.4.1 + +# [**Downloads**](#tab/downloads) + +> [!WARNING] +> This build has an error that causes the Semantic Analyzer to report incorrect "circular dependency" errors in DAX calculations. We recommend upgrading to [3.4.2](3_4_2.md) instead. + +Tabular Editor 3.4.1 downloads: + +- Download [Tabular Editor 3.4.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.4.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.4.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x64.exe) | `AFBB88611C71DA2BC546A15194CC55A646F9CE7BA4952BF839DA1E41E679A3AC` | +| [TabularEditor.3.4.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.msi) | `635CEB55B229937A15A1537919D7B8E555835BDF4F680D18E2716E1012D167E3` | +| [TabularEditor.3.4.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.zip) | `3A41845DB69F80F6887236B8469080B28FB6ACCBDBA4ACFAB6466E2938257DE2` | +| [TabularEditor.3.4.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x86.exe) | `5D9B05EFC3B5577F7FC199D1B6197493DF4E948A5F527BBD14453C44C49C9A54` | +| [TabularEditor.3.4.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.msi) | `F6B53BB2E0D3D323ECE9CACA46EDFB08A5194BAAC141FB037DFCB40FF6FBE23A` | +| [TabularEditor.3.4.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.zip) | `EC71D1A9648605E0ADBE5F0371EA1B552B46F93930806B599FBD1AFDCE8B9212` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New features in 3.4.1 + +- Updated TOM to [19.55.3](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- New [Perspective Editor](xref:perspective-editor) view. + +## Minor improvements in 3.4.1 + +- DAX debugger now supports window functions ([`OFFSET`](https://dax.guide/offset), [`INDEX`](https://dax.guide/index) and [`WINDOW`](https://dax.guide/window)). +- DAX debugger now lets you debug a measure that is being referenced in a table constructor, such as `EVALUATE { [Internet Sales] }` or in the [`ROW`](https://dax.guide/row) function. +- The **Evaluation Context** view now shows the expression of table variables used as filters. +- Resetting the window layout through the **Window** menu, now no longer affects toolbar buttons (these can be modified or reset through the **Tools > Customize** dialog). + +## Bugfixes in 3.4.1 + +- Fixed an issue with the search box above the keyboard command list in the preferences dialog. +- DAX editors now deal correctly with nested comments, see [#681](https://github.com/TabularEditor/TabularEditor3/issues/681). +- Attempting to debug query-scoped measures no longer causes a crash. +- Fixed an issue that caused relationship lines in the diagram view to become "stuck", see [#787](https://github.com/TabularEditor/TabularEditor3/issues/787). +- When tracking TOM Explorer selection in the dependency view, application should no longer crash when selecting a relationships, see [#782](https://github.com/TabularEditor/TabularEditor3/issues/782). +- Fixed the "DataSourceConverter cannot convert from TabularEditor.TOMWrapper.ProviderDataSource" error, when attempting to change or reset the DataSource property on a partition. +- Tabular Editor 3 should no longer replace blank characters at the end of file names with `%20`, when using "Save to folder". +- Expression Editor should no longer be empty until its header is clicked, see [#739](https://github.com/TabularEditor/TabularEditor3/issues/739). +- DAX debugger now correctly simulates the auto-exist behavior of [`SUMMARIZECOLUMNS`](https://dax.guide/summarizecolumns). +- Fixed an issue where the presence of `ALL()`, `ALLSELECTED()`, and other filter removal functions, did not cause outer filters to be striked out (indicating that the filters had been overwritten) in the **Evaluation Context** view. +- Fixed the missing context menu option to refresh a Calculated Table or Calculation Group. +- Fixed an issue that would sometimes cause a crash when attempting to perform a schema update. +- It is now no longer possible to debug a measure that has been removed from the model (which would otherwise cause a crash). +- Better exception handling when objects are pasted into the TOM Explorer. +- Fixed an issue that would cause a crash when an object is deleted while being shown in the **Search Results** view. +- Fixed an issue that would cause a crash in the **Table Preview**, when columns or tables were deleted. +- Semantic Analyzer no longer reports an error when the `` parameter of a window function is left blank, or when it contains extension columns. See [#807](https://github.com/TabularEditor/TabularEditor3/issues/807). +- The "Reset" button in the Customize dialog should no longer remove all buttons from a toolbar. +- C# script editor should no longer insert an additional tab or newline character when performing an auto complete by pressing one of these keys. +- Fixed an issue when calling the `DependsOn.Deep()` method through a C# script. +- DAX editor should no longer crash while attempting to autoformat the code. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_4_2_zh.md b/content/localization/zh/3_4_2_zh.md new file mode 100644 index 00000000..0fe4efea --- /dev/null +++ b/content/localization/zh/3_4_2_zh.md @@ -0,0 +1,61 @@ +# Tabular Editor 3.4.2 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.4.2 downloads: + +- Download [Tabular Editor 3.4.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.4.2 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.4.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x64.exe) | `A29C41F0EFCA0FC34D515C49B1EA1F74D0205A953851F20D50AA2513D86C4A64` | +| [TabularEditor.3.4.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.msi) | `177F3B15C3248561B01F528FD62BE804CF92176EB17B6CC10C7FF362F69A81CC` | +| [TabularEditor.3.4.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.zip) | `F586BCA4807D31F2DE47C3E1464D47936B4FAAA20138B7C509FBD757F666E642` | +| [TabularEditor.3.4.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x86.exe) | `0D323514339011C0AE057F1ADC102D1B141B91A5DB8DD5CDFC8E9FD8231AF1DE` | +| [TabularEditor.3.4.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.msi) | `CE838594BDD8AE4A875DBA07C479A063270666CF63D19D93D81F9D0C5ED2E172` | +| [TabularEditor.3.4.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.zip) | `50AB9A22CF9332CA8B2793D26CFCF74DDAF11BF281BD00103AE37772FE9ADADF` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.4.2 + +- Fixed an issue with the Semantic Analyzer reporting "circular dependency" errors, when there are none. See [#811](https://github.com/TabularEditor/TabularEditor3/issues/811). +- Find/Replace should no longer replace all occurrences in the document, when setting "Look in" to "Selection", see [#293](https://github.com/TabularEditor/TabularEditor3/issues/293). +- Copy/pasting cultures between models should no longer cause a crash, see issue [#798](https://github.com/TabularEditor/TabularEditor3/issues/798). Note that ObjectTranslations referring to objects that do not exist in the destination model, are deleted. +- DAX debugger should now allow inspecting multi-row watch expressions in all cases. +- DAX debugger should no longer crash when attempting to debug the result of a query such as `EVALUATE { [Measure that uses ALLSELECTED] }` + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- \*DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_5_0_zh.md b/content/localization/zh/3_5_0_zh.md new file mode 100644 index 00000000..c1a15d17 --- /dev/null +++ b/content/localization/zh/3_5_0_zh.md @@ -0,0 +1,90 @@ +--- +uid: release-3-5-0 +--- + +# Tabular Editor 3.5.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.5.0 downloads: + +- Download [Tabular Editor 3.5.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.5.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.5.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x64.exe) | `AD96A3A2A5672D412C2DF74939AF36EA888483137753D6048AD66D3C84386723` | +| [TabularEditor.3.5.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.msi) | `3DBA3D9054A1422A7C7DEF83EFB1458935A77143B1C887A2EC628F58D8B2E52A` | +| [TabularEditor.3.5.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.zip) | `56E7658E9C4C11DC3E31DEF0E27717DB8CF67185E6A00C7B28E02EFA1EF8F5FC` | +| [TabularEditor.3.5.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x86.exe) | `2C2B2D756087CEF15461693F830DA83CBFEF472CD2D3E6AFEB3164059BA2D8AD` | +| [TabularEditor.3.5.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.msi) | `0B0A206DB149C5C53A4A765AD2E014657DA3DF8B70DFCD0464A4E22CA1871F45` | +| [TabularEditor.3.5.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.zip) | `EC06DFBBBF2F70B111532967D4B8A618317B9B201ED7B75FAC3B2CB050626831` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.5.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/03/15/tabular-editor-3-march-2023-release/) to get an overview of the most important updates in this release. + +- Updated TOM to [19.57.2.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- This release introduces **Table Groups** which lets you organise tables into "folders" in the TOM Explorer. [Learn more](xref:table-groups). +- Default shortcut for uncommenting code now set to Ctrl+U +- Tabular Editor will now attempt to automatically reconnect to Analysis Services, when the session timeout has expired. This means it should no longer be necessary to close and reopen table previews, DAX query windows and Pivot Grids. See [#650](https://github.com/TabularEditor/TabularEditor3/issues/650), [#803](https://github.com/TabularEditor/TabularEditor3/issues/803). +- Added a new set of overloaded C# script methods `Macro(...)`. These are an alias for `CustomAction(...)`. The API documentation has been updated accordingly. +- When using Tabular Editor in **Workspace Mode**, incremental refresh partitions are not overridden upon workspace database updates. Moreover, a new serialization option **Ignore incremental refresh partitions** is now available, and enabled by default for new models. This option will make sure that partitions governed by incremental refresh, are not serialized when saving a model as a .bim or folder structure. This makes it easier to integrate models using incremental refresh with version control. +- Added toolbar button to toggle display folders in the **Perspective Editor view**. Toggling a Display Folder in the Perspective Editor, will toggle all objects within that folder. The Perspective Editor now also provides a visual indication if a table or folder contains both items that are included in the perspective, and items that are not. +- Tabular Editor now has full support for Oracle data sources. You must have the [ODP.NET managed drivers](https://www.oracle.com/database/technologies/odac-downloads.html) installed, which is also a requirement if you want to import data from Oracle in Power BI Desktop. + +## Bugfixes in 3.5.0 + +- Auto-format should no longer erase code when the DAX Editor is configured to use tabs +- "Open macro" button in the **Macros** view will now be enabled whenever a macro is selected +- It should no longer be necessary to reset the window layout, in order for the **Perspective Editor** view to appear +- Main Menu bar will no longer reset when a macro is added as a new button +- Fixed a bug that sometimes prevented Tabular Editor from opening a .bim file or .json folder structure containing Power BI specific TOM properties. +- `ResolveObjectPath` now supports the "old" path format, similar to TE2. See [#1077](https://github.com/TabularEditor/TabularEditor/issues/1077). +- BPA rules that rely on the `Expression` property on tables, should no longer fail. +- Macros can now be saved/compiled even if their name contains a double quote. +- Fixed various issues with the `CustomAction(...)` C# script method. +- Perspective Editor now correctly deals with hidden tables containing visible measures. +- Fixed an issue that prevented setting the **Default Measure** property on the Model object through the **Properties View**. +- **Calculate Table** context menu option will no longer show when working offline. +- Fixed an issue that caused the C# autocomplete dropdown to "absorb" a period key press. +- Fixed an issue with the semantic analyzer reporting incorrect parameter usage to the DAX [XIRR](https://dax.guide/xirr) function. +- Relationship Editor now allows creating relationships between columns of different, but compatible, data types. +- Fixed the "The key didn't match any rows" error, when attempting to perform a schema update on a table using an M Partition. +- Tables using incremental refresh policy now work with the Update Table Schema feature. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_5_1_zh.md b/content/localization/zh/3_5_1_zh.md new file mode 100644 index 00000000..8d0492df --- /dev/null +++ b/content/localization/zh/3_5_1_zh.md @@ -0,0 +1,72 @@ +--- +uid: release-3-5-1 +--- + +# Tabular Editor 3.5.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.5.1 downloads: + +- Download [Tabular Editor 3.5.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.5.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.5.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x64.exe) | `02B75E0FE9CE11619078DC85BD18BE807AB4541BFEEC54C4A98395A11E91D9D3` | +| [TabularEditor.3.5.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.msi) | `B6FB6E49825CDE135E35461073F4BAB567D557CB9BB8BF6E2CCC3F22A9B21A0D` | +| [TabularEditor.3.5.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.zip) | `D01E533144582980D407CE7870421C69398AC6677DBB9119020A7FC836F4C5DC` | +| [TabularEditor.3.5.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x86.exe) | `2389206632421968499CBEFF74AECE4BD592E157EDE32AA5F5C953A5213B21C9` | +| [TabularEditor.3.5.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.msi) | `D1AFEA6FB0781349074B9B91723EE2058651B6B77AD81778606E88D870EF432D` | +| [TabularEditor.3.5.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.zip) | `B0241F8C4067A849EEF04CFF9E67E0DBC80E29EB0F9BDDA167D967C123081259` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes and improvements in 3.5.1 + +- Updated TOM to [19.60.0](https://www.nuget.org/packages/Microsoft.AnalysisServices.retail.amd64/). +- Fixed an issue with the Edit Relationship dialog showing an incompatible data type warning, even if the data types on both columns are identical, see [#855](https://github.com/TabularEditor/TabularEditor3/issues/855). Moreover, when connected to an instance of Analysis Services, the dialog now displays RI violation and duplicate value warnings. +- Fixed an issue that would sometimes cause the application to freeze when opening a file or folder structure from disk. +- Fixed an issue that prevented editing RLS expressions when a role contained a "." in its name. +- When an object is shown in multiple display folders, the TOM Explorer didn't correctly refresh its properties in all places. This has been fixed. +- "Model" is now treated as a reserved word in the Semantic Analyzer, see [#852](https://github.com/TabularEditor/TabularEditor3/issues/852). +- The .pbitool file (used for External Tool integration with PBI Desktop) now uses the updated TE3 icon. +- The Create Workspace Database dialog now validates the database name, preventing special characters that are not supported by Analysis Services. +- Fixed an issue with auto-indent overwriting characters in the DAX editor. See [#857](https://github.com/TabularEditor/TabularEditor3/issues/857). +- You can now create add tables/calculation groups directly to a table group through the table group's right-click context menu. +- Fixed an regression in 3.5.0, where importing columns or performing a schema update on a table from an MS SQL-flavored data source, would result in the wrong data type being assigned to the column. +- Fixed an issue where closing a bracket or parenthesis would sometimes "snap" the cursor to the wrong position in the DAX editor. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_6_0_zh.md b/content/localization/zh/3_6_0_zh.md new file mode 100644 index 00000000..6ded9dd5 --- /dev/null +++ b/content/localization/zh/3_6_0_zh.md @@ -0,0 +1,83 @@ +--- +uid: release-3-6-0 +--- + +# Tabular Editor 3.6.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.6.0 downloads: + +- Download [Tabular Editor 3.6.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.6.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.6.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x64.exe) | `3D19445617BE4D8091DDF1F5C54D8783A2BFF49B5CD628F2D0725ED858D70981` | +| [TabularEditor.3.6.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.msi) | `C295556551595351BFDB1CDC0C6990BDF187493CC4233BD3C099439FFFD390B6` | +| [TabularEditor.3.6.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.zip) | `971B6EC8AAB6BBEE77769FD81873D371B4BEA3417CC2689C571D868B0234AE10` | +| [TabularEditor.3.6.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x86.exe) | `05411C0D29025BCCAED2A90DE95759A2C7476CFBFCDB1B52CBFDF9A753C1A94E` | +| [TabularEditor.3.6.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.msi) | `E4DA4EBEA597419E2FA753E4CE9AC798193812D1D350C8EC1222762CE34E15AC` | +| [TabularEditor.3.6.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.zip) | `CB3DD1ED971C31781F13932AA3F3C9C3AB662AB8185243C7F672B398262CB5FB` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.6.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/04/19/tabular-editor-3-april-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor 3 now has native support for **Databricks**. This means you can now connect to a Databricks SQL endpoint when importing tables using the Table Import Wizard. For more information, see our [release blog post](https://blog.tabulareditor.com/2023/04/19/tabular-editor-3-april-2023-release). +- We added support for the new DAX functions [`RANK`](https://dax.guide/rank) and [`ROWNUMBER`](https://dax.guide/rownumber) introduced in the [April 2023 update of Power BI Desktop](https://powerbi.microsoft.com/en-us/blog/power-bi-april-2023-feature-summary/). In addition, our code complete now shows all available keywords for the <Blanks> and <Order> arguments of the window and [`ORDERBY`](https://dax.guide/orderby) functions. + +## Minor improvements in 3.6.0 + +- We no longer perform a (potentiallys slow) conflict check before saving changes to the workspace database. The assumption is that each developer uses their own personal workspace database, so conflicts should not occur. +- C# scripting: The `IAnnotationObject` interface has been extended with a `ClearAnnotations()` method. +- When adding a dynamic format string expression to a measure, we now clear the static format string property (as it is not possible for measures to have both static and dynamic format strings assigned). +- Updated TOM to [19.61.1.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64). +- Default Compatibility Level for new Power BI models created with Tabular Editor, is now 1601. Moreover, the "create new model" dialog now lets you specify any compatibility level. + +## Bugfixes in 3.6.0 + +- Oracle download instructions updated to instruct users to use the ODAC (not ODP.NET) drivers. +- Removed restrictions on special characters in database names, when opening or creating a new database. +- Fixed an issue that caused the database name property within the .bim / database.json file, to be updated with the name of the workspace database. +- DAX debugger stability improvements. +- .tmuo files are no longer saved, when the "Create user options (.tmuo) file" option is unchecked. +- Fixed an issue where code complete would sometimes "absorb" closing brackets. +- Semantic Analyzer no longer reports an error when using [`SELECTEDMEASURE`](https://dax.guide/selectedmeasure) (and related functions) in the context of measure expressions and format string expressions. +- Fixed an issue where the M query generated for new tables imported from an existing implicit (SQL) data source, would not work correctly when attempting to refresh the table. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_7_0_zh.md b/content/localization/zh/3_7_0_zh.md new file mode 100644 index 00000000..c11fd521 --- /dev/null +++ b/content/localization/zh/3_7_0_zh.md @@ -0,0 +1,100 @@ +--- +uid: release-3-7-0 +--- + +# Tabular Editor 3.7.0 + +> [!IMPORTANT] +> A bug preventing creation of new models with workspace databases was identified in this version of Tabular Editor 3. Please use [version 3.7.1](xref:release-3-7-1) instead. + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.7.0 downloads: + +- Download [Tabular Editor 3.7.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.7.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.7.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x64.exe) | `ECE2DF7E9C43E9647CA3BC3DA7AC0E0110B57E82C40A70C4A81843F77FEC5907` | +| [TabularEditor.3.7.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.msi) | `E31DF5C97BA5650E91636ECC24FD8DAE68CC6E0717FFE32A94A76500A31271EE` | +| [TabularEditor.3.7.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.zip) | `91E0A94B943D256666055F4799280D25D00F65B14F658ADD41D8247BC8814A8C` | +| [TabularEditor.3.7.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x86.exe) | `EEAFA4229DEA82FD94B8CF735AC97A4319DA697A2F26376D6F7D527AEE29112A` | +| [TabularEditor.3.7.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.msi) | `C92577A971733C2F3E3A1852629B4F6A9C6D0AB9FE979337483EDFA3066306C8` | +| [TabularEditor.3.7.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.zip) | `390375585D0C4E97C53A79690D35A354EB131A3F5B60A072FA7E0909B8CE3DA0` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.7.0 + +Check out our [release blog](https://blog.tabulareditor.com/?p=2146) to get an overview of the most important updates in this release. + +- This release introduces the [Metadata Translations Editor](xref:metadata-translation-editor), which provides a fast an easy way to view, compare and edit all metadata translations applied across model objects. +- Tabular Editor 3 now supports the new [Tabular Model Definition Language (TMDL)](https://powerbi.microsoft.com/en-us/blog/announcing-public-preview-of-the-tabular-model-definition-language-tmdl/) as a format for saving/loading model metadata. You can enable TMDL (preview) serialization mode under **Preferences > Tools > Save-to-folder**. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work.\*\*. + +## Minor improvements in 3.7.0 + +- Now using latest version of [VertiPaq Analyzer](https://github.com/sql-bi/VertiPaq-Analyzer). This fixes an issue with collecting stats on models with Dynamic Format Strings, among other things. +- We now show a more meaningful error message, when a paste operation fails because of incompatible model metadata. +- Analysis Services trace events that are received after a data refresh job completes, are now correctly assigned to that job, enabling proper propagation of error/warning messages, as well as progress counts. See [#735](https://github.com/TabularEditor/TabularEditor3/issues/735). +- The data preview window is now able to use the DAX [`OFFSET`](https://dax.guide/offset) function, which enables the preview to show all rows of non-DirectQuery tables, even when a model is in DirectQuery mode (such as when hybrid tables are present in the model), see [#500](https://github.com/TabularEditor/TabularEditor3/issues/500), [#837](https://github.com/TabularEditor/TabularEditor3/issues/837). +- When deplying a model as a new database, we now add a dummy partition to tables that use incremental refresh policy, when no partitions are present in the model metadata, to ensure the deployment succeeds. +- Data preview retains any filters applied, when a table is refreshed/processed. See [#780](https://github.com/TabularEditor/TabularEditor3/issues/780). +- When a table does not contain columns in a non-queryable state, the data preview now uses the table name directly in the generated DAX query, instead of wrapping it in a call to [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). This should speed up the data preview on older versions of Analysis Services. See [#126](https://github.com/TabularEditor/TabularEditor3/issues/126). +- TE3 now uses the latest version of [Microsoft.Identity.Client](https://www.nuget.org/packages/Microsoft.Identity.Client). +- Offline schema detection now supports using Shared (M) Expressions which define custom functions. + +## Bugfixes in 3.7.0 + +- There was a problem in the newest version of AdomdClient used in 3.6.0, which causes a Pivot Grid to fail with an XML error message, when connected to the Power BI XMLA endpoint. We have downgraded AdomdClient to [19.55.3.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64/19.55.3.1), which solves this issue for now. +- Fixed an issue where local instances of Power BI Desktop were not shown in the "Local instances" dropdown. +- Fixed an issue where TE3 would not allow loading a model that did not have a database name specified. +- The "Please Wait" dialogs should no longer obstruct Azure AD sign-in windows. +- Stability improvements. +- Fixed an issue where the application would crash when attempting to copy/paste measures with dynamic format strings, see [#1099](https://github.com/TabularEditor/TabularEditor/issues/1099). +- DAX scripting of measures with format strings/dynamic format strings, now works as intended. +- Query-scoped columns are now handled correctly by the DAX semantic analyzer and auto-complete feature. See [#890](https://github.com/TabularEditor/TabularEditor3/issues/890). +- Open Model/File dialogs now correctly filters "database.json" files instead of showing all .json files in a folder. +- Fixed some visual issues with buttons on various prompt dialogs. +- Fixed an issue where the database selection is incorrect, when the list is filtered. See [#886](https://github.com/TabularEditor/TabularEditor3/issues/886). +- Fixed an issue where the "Save Model" action (Ctrl+Alt+S) was not enabled, even though the message bar indicated that the model had unsaved changes. +- Fixed an issue with "phantom" semantic errors in the DAX Editor, see [#792](https://github.com/TabularEditor/TabularEditor3/issues/792). +- Preview data should now respect the format string assigned to a column, see [#820](https://github.com/TabularEditor/TabularEditor3/issues/820). +- DAX query results should now show the time portion of DateTime values, when it is not 00:00:00. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_7_1_zh.md b/content/localization/zh/3_7_1_zh.md new file mode 100644 index 00000000..651c3e82 --- /dev/null +++ b/content/localization/zh/3_7_1_zh.md @@ -0,0 +1,101 @@ +--- +uid: release-3-7-1 +--- + +# Tabular Editor 3.7.1 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.7.1 downloads: + +- Download [Tabular Editor 3.7.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.7.1 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.7.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x64.exe) | `C1A2DBF3E8800BC0F55C4D4B6A2FF4989952015C182C079EE2A4579A6426BDF3` | +| [TabularEditor.3.7.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.msi) | `D9EDEF51E8113FD871485C2C5F647016B99FEAC582A1528CA8E8AD5EFD08CE40` | +| [TabularEditor.3.7.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.zip) | `168E49DB30597419D44352DED0E020EF711C306D906985929F14DCEB15654DB1` | +| [TabularEditor.3.7.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x86.exe) | `4F26EA53998852F7768DA81F94D05C4540101F3639AA4045F66CE6AE2ADD7EA2` | +| [TabularEditor.3.7.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.msi) | `5A3D57DB293CFE09AB9C8FF46FCECA34BBDC0A773B7990F6BEDDE00C1C6945EE` | +| [TabularEditor.3.7.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.zip) | `3B63395FC1CD8C5B1D4B7DBA2E0FAAD86D7ECD93D1ADE7B524CD4FE16F235456` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Bugfixes in 3.7.1 + +- Fixed the "Object reference not set to an instance of an object", which would occur when attempting to create a new model using a workspace database. + +## New in 3.7.0 + +Check out our [release blog](https://blog.tabulareditor.com/?p=2146) to get an overview of the most important updates in this release. + +- This release introduces the [Metadata Translations Editor](xref:metadata-translation-editor), which provides a fast an easy way to view, compare and edit all metadata translations applied across model objects. +- Tabular Editor 3 now supports the new [Tabular Model Definition Language (TMDL)](https://powerbi.microsoft.com/en-us/blog/announcing-public-preview-of-the-tabular-model-definition-language-tmdl/) as a format for saving/loading model metadata. You can enable TMDL (preview) serialization mode under **Preferences > Tools > Save-to-folder**. + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work.\*\*. + +## Minor improvements in 3.7.0 + +- Now using latest version of [VertiPaq Analyzer](https://github.com/sql-bi/VertiPaq-Analyzer). This fixes an issue with collecting stats on models with Dynamic Format Strings, among other things. +- We now show a more meaningful error message, when a paste operation fails because of incompatible model metadata. +- Analysis Services trace events that are received after a data refresh job completes, are now correctly assigned to that job, enabling proper propagation of error/warning messages, as well as progress counts. See [#735](https://github.com/TabularEditor/TabularEditor3/issues/735). +- The data preview window is now able to use the DAX [`OFFSET`](https://dax.guide/offset) function, which enables the preview to show all rows of non-DirectQuery tables, even when a model is in DirectQuery mode (such as when hybrid tables are present in the model), see [#500](https://github.com/TabularEditor/TabularEditor3/issues/500), [#837](https://github.com/TabularEditor/TabularEditor3/issues/837). +- When deplying a model as a new database, we now add a dummy partition to tables that use incremental refresh policy, when no partitions are present in the model metadata, to ensure the deployment succeeds. +- Data preview retains any filters applied, when a table is refreshed/processed. See [#780](https://github.com/TabularEditor/TabularEditor3/issues/780). +- When a table does not contain columns in a non-queryable state, the data preview now uses the table name directly in the generated DAX query, instead of wrapping it in a call to [`SELECTCOLUMNS`](https://dax.guide/selectcolumns). This should speed up the data preview on older versions of Analysis Services. See [#126](https://github.com/TabularEditor/TabularEditor3/issues/126). +- TE3 now uses the latest version of [Microsoft.Identity.Client](https://www.nuget.org/packages/Microsoft.Identity.Client). +- Offline schema detection now supports using Shared (M) Expressions which define custom functions. + +## Bugfixes in 3.7.0 + +- There was a problem in the newest version of AdomdClient used in 3.6.0, which causes a Pivot Grid to fail with an XML error message, when connected to the Power BI XMLA endpoint. We have downgraded AdomdClient to [19.55.3.1](https://www.nuget.org/packages/Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64/19.55.3.1), which solves this issue for now. +- Fixed an issue where local instances of Power BI Desktop were not shown in the "Local instances" dropdown. +- Fixed an issue where TE3 would not allow loading a model that did not have a database name specified. +- The "Please Wait" dialogs should no longer obstruct Azure AD sign-in windows. +- Stability improvements. +- Fixed an issue where the application would crash when attempting to copy/paste measures with dynamic format strings, see [#1099](https://github.com/TabularEditor/TabularEditor/issues/1099). +- DAX scripting of measures with format strings/dynamic format strings, now works as intended. +- Query-scoped columns are now handled correctly by the DAX semantic analyzer and auto-complete feature. See [#890](https://github.com/TabularEditor/TabularEditor3/issues/890). +- Open Model/File dialogs now correctly filters "database.json" files instead of showing all .json files in a folder. +- Fixed some visual issues with buttons on various prompt dialogs. +- Fixed an issue where the database selection is incorrect, when the list is filtered. See [#886](https://github.com/TabularEditor/TabularEditor3/issues/886). +- Fixed an issue where the "Save Model" action (Ctrl+Alt+S) was not enabled, even though the message bar indicated that the model had unsaved changes. +- Fixed an issue with "phantom" semantic errors in the DAX Editor, see [#792](https://github.com/TabularEditor/TabularEditor3/issues/792). +- Preview data should now respect the format string assigned to a column, see [#820](https://github.com/TabularEditor/TabularEditor3/issues/820). +- DAX query results should now show the time portion of DateTime values, when it is not 00:00:00. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_8_0_zh.md b/content/localization/zh/3_8_0_zh.md new file mode 100644 index 00000000..bde45799 --- /dev/null +++ b/content/localization/zh/3_8_0_zh.md @@ -0,0 +1,83 @@ +--- +uid: release-3-8-0 +--- + +# Tabular Editor 3.8.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.8.0 downloads: + +- Download [Tabular Editor 3.8.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.8.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.8.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x64.exe) | `0FB0AB8BD7E209E739786F1E348645D40AEFFB2D1963E44231164A1783D5A928` | +| [TabularEditor.3.8.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.msi) | `0F4FC4B7F0F483E58D5752AFCF7C28C03F29FD739093688D48E1C6C34186CEF1` | +| [TabularEditor.3.8.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.zip) | `448B9BBB5EEAC450CF4A9654E002A5C471843FD9D49882D9646C3EC34822165A` | +| [TabularEditor.3.8.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x86.exe) | `6018121D47096E7086C66CD9B142112F8D5D999F779E6DB1799E39298F41FEE9` | +| [TabularEditor.3.8.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.msi) | `6DEA4B5E29B67CA6B42446C6F8A29B9E9A7A89F72076232E46C4FFC301758EB5` | +| [TabularEditor.3.8.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.zip) | `69A3858F2B43C0338DE805902DF3B5FEF66DD713FFE2A4A66124B46BD0D803BD` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## Improvements in 3.8.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/06/26/tabular-editor-3-june-2023-release/) to get an overview of the most important updates in this release. + +- Tabular Editor 3 now lets you open [Power BI Desktop project (.pbip) files](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview) or folders containing .pbip files. When such a folder contains multiple datasets, a list is shown, letting you select which one to open. +- The [June 2023 update of Power BI Desktop](https://powerbi.microsoft.com/en-us/blog/power-bi-june-2023-feature-summary/) now supports a much larger range of modelling operations that can be performed through external tools ("hardening"). In other words, when you connect Tabular Editor to Power BI Desktop (June 2023 or newer), you will now be able to add/edit calculated columns, calculated tables, relationships, hierarchies, and much more. +- We're now using the latest version of TOM/AMO ([19.65.4](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64)). + +> [!NOTE] +> TMDL and Power BI Desktop Projects (.pbip) is still in preview, and as such, these features must also be considered preview features of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work.\*\*. + +## Bugfixes in 3.8.0 + +- Dependency view now has much better performance for models with large and complex dependency graphs. +- Some users have reported that editing certain properties, through the **Properties view**, caused the application to crash. This should no longer be the case. +- Semantic Analyzer should no longer report errors when a DAX query contains both query-scoped columns and query-scoped tables. +- Semantic Analyzer now correctly handles DAX expressions containing UTF-32 characters (emojis), although the DAX editor still has issues dealing with these. In general, we recommend avoiding the use of emojis in DAX expressions. +- Fixed a bug where repeatedly hitting Ctrl+Z (Undo) would clear the Expression Editor and even bring in unrelated expressions. +- Perspective Editor now correctly updates to reflect when new objects are added/removed to/from the model. +- VertiPaq Analyzer should no longer crash when a model contains Dynamic Format Strings. +- Fixed a regression with importing tables from Snowflake, which caused columns to have incorrect datatypes assigned. +- Fixed a regression with update schema/importing tables Snowflake, where the implicit data source properties had to be re-entered in the connection dialog. +- Fixed an issue where the toolbar buttons related to the Expression Editor would disappear, if the Expression Editor was docked as a tool window (i.e. not as a document window). +- DAX editors now perform a new semantic analysis, when changes that can impact DAX semantics are made to the model. This should ensure that the error messages shown in the DAX editor are always valid. +- Fixed an issue where the DAX debugger would be unavailable, even for seemingly simple DAX queries. + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/3_9_0_zh.md b/content/localization/zh/3_9_0_zh.md new file mode 100644 index 00000000..6366f42e --- /dev/null +++ b/content/localization/zh/3_9_0_zh.md @@ -0,0 +1,95 @@ +--- +uid: release-3-9-0 +--- + +# Tabular Editor 3.9.0 + +# [**Downloads**](#tab/downloads) + +Tabular Editor 3.9.0 downloads: + +- Download [Tabular Editor 3.9.0 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x64.exe) _(recommended)_ +- Download [Tabular Editor 3.9.0 (32 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x86.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.msi) + +_If you haven't used Tabular Editor 3 before, you are eligible to a 30 day trial, which can be requested after installation. You can also [purchase a license](https://tabulareditor.com/licensing)._ + +# [**SHA-256 checksums**](#tab/checksums) + +| File | SHA-256 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | +| [TabularEditor.3.9.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x64.exe) | `4D7F3932425BBC06F7933C1930B0B619D5CB6AC8AE0C511F9FB8B17BF3BDBDD6` | +| [TabularEditor.3.9.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.msi) | `79F6A150059E104CD43D7923D591A45C689C2D53C6207C439CB826E8AE32F72C` | +| [TabularEditor.3.9.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.zip) | `EBB35030615A0E2DF2ACCC8888A524867718EB2123A8B4D78BCB8BB6407B3F33` | +| [TabularEditor.3.9.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x86.exe) | `80B74191635224DDBDDBC717CCBD300018F3733974259FBB1A2721204B09FCAD` | +| [TabularEditor.3.9.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.msi) | `295E2378110C202263255CB0781EE5C68804B390923AEB499DB586FD42B94528` | +| [TabularEditor.3.9.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.zip) | `6B14274436F1FD43C16026690FA449EDA6C86D3A6FF27A61DCCD29ED20AF0A4E` | + +*** + +### Prerequisites + +Tabular Editor 3.3.0 (and newer) uses .NET 6. You may have to install the [.NET 6.0 Runtime for Desktop](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) before you can launch Tabular Editor 3.3.0 (or newer). Starting from 3.3.1, the Tabular Editor 3 installer will download and install these prerequisites, if they are missing. + +## New in 3.9.0 + +Check out our [release blog](https://blog.tabulareditor.com/2023/07/21/tabular-editor-3-july-2023-release/) to get an overview of the most important updates in this release. + +- Customers on one of the Azure for Government cloud, can now specify the base url that Tabular Editor 3 should use, when connecting to the Power BI REST API, such as when importing tables from a Power BI Dataflow. This setting is specified under **Tools > Preferences > Power BI > Power BI Service**. +- When selecting more than one cell in a DAX query result or a Pivot Grid, we now show a summary of the values selected in the application status bar (sum, minimum, maximum, average, etc.). Hold down Shift/Ctrl to select ranges the way you'd usually do. Shift+click on a column header will select all cells in that column. See [#475](https://github.com/TabularEditor/TabularEditor3/issues/475). + +## Improvements in 3.9.0 + +- We've rearranged some of the pages and sections of the preferences dialog, making it easier to navigate. +- We're now using the latest version of TOM/AMO ([19.65.7.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.NetCore.retail.amd64)) and [TMDL preview-3](https://www.nuget.org/packages/Microsoft.AnalysisServices.Tabular.Tmdl.NetCore.retail.amd64/19.65.7.2-TmdlPreview). +- We've also updated AdomdClient to [19.65.7.2](https://www.nuget.org/packages/Microsoft.AnalysisServices.AdomdClient.NetCore.retail.amd64/), which should improve the performance of our Pivot Grid component. +- VertiPaq Analyzer has been updated to version [1.2.18](https://www.nuget.org/packages/Dax.Metadata). +- When a calculated table is left with a blank expression, we now show the error icon immediately in the TOM Explorer. +- It is now possible to add objects to Pivot Grids or Diagrams, even when those documents do not have focus (assuming no more than one such document is open). Moreover, you can now create a Pivot Grid by right-clicking on a measure, saving a few clicks, when you just need to test the value of a measure. +- We now show an error message, if attempting to assign an expression that produces a value of type 'Variant' to a calculated column (this is not allowed). +- We've added a separate option for saving zipped model.bim backups under **Tools > Preferences > Model Deployment**. You can now choose to have backups saved upon every deployment, upon every save (while connected to an instance of Analysis Services), or both. Note, this feature is not available for TE3 Desktop Edition. This also fixed issue [#796](https://github.com/TabularEditor/TabularEditor3/issues/796). +- We've added additional info columns to VertiPaq Analyzer, to align with those available in [DAX Studio](https://daxstudio.org). + +> [!NOTE] +> TMDL is still in preview, and as such, this feature must also be considered a preview feature of Tabular Editor 3. Make sure to keep a Model.bim / Database.json backup of your model metadata to avoid losing work. + +## Bugfixes in 3.9.0 + +- Fix false "Circular dependency" errors, encountered both in the DAX Editor, as well as in the TOM Explorer / Messages View. See issues [#920](https://tabulareditor.zendesk.com/agent/tickets/920) and [#931](https://github.com/TabularEditor/TabularEditor3/issues/931). +- Fixed an issue that prevented the Search and Replace dialog from searching in floating (undocked) document windows. +- Various stability improvements (should fix [#937](https://github.com/TabularEditor/TabularEditor3/issues/937), among other things). +- Fixed a crash that would occur when attempting to format DAX code containing window functions. +- Fixed a bug that caused Tabular Editor to use the System proxy when choosing Proxy Type "None" under **Tools > Preferences > Proxy settings**, and vice versa. +- Semantic Analyzer now works correctly with the [`DETAILROWS`](https://dax.guide/detailrows) function, see [#938](https://github.com/TabularEditor/TabularEditor3/issues/938). +- Fixed an issue where changing the name of a macro would not update the folder structure of macros, until the application was restarted. +- Fixed a bug that caused certain column and hierarchy properties to be read-only, preventing users from correctly setting up calculated tables, relationships, etc., while connected to Power BI Desktop. See [#929](https://github.com/TabularEditor/TabularEditor3/issues/929) and [#930](https://github.com/TabularEditor/TabularEditor3/issues/930). +- Fixed a crash in the DAX editor, when using the [`WINDOW`](https://dax.guide/window) function with certain parameters. +- Fixed an issue with the M parser not interpreting `[]` correctly, preventing the offline schema comparer from inferring metadata from an M expression such as `PowerPlatform.Dataflows([])`. See [#936](https://github.com/TabularEditor/TabularEditor3/issues/936). +- Fixed an issue where the PivotGrid would crash if a measure had a malformed format string assigned. +- Fixed an issue where the Semantic Analyzer would assign "Variant" as the data type of an expression resulting from the use of [`SWITCH`](https://dax.guide/switch) with one or more branches returning [`BLANK`](https://dax.guide/blank). +- Fixed a few bugs related to column filters on table previews. When getting the list of unique values of a column, we now read the first 5000 values (in ascending order). Previously, only 500 values were read, with no ordering specified, causing inconsistent behavior. See [#924](https://github.com/TabularEditor/TabularEditor3/issues/924). + +--- + +## Coming from Tabular Editor 2.x? + +Watch [this video](https://www.youtube.com/watch?v=pt3DdcjfImY) to get an idea of the new features in Tabular Editor 3. Also, make sure to check our [onboarding guide](https://docs.tabulareditor.com/onboarding/index.html). + +**Tabular Editor 3 major features overview:** + +- Fully customizable IDE, with multi-monitor, Hi-DPI support and themes +- New powerful DAX code editor with auto-complete, syntax checking, code folding and much, much more +- \*Workspace mode, allowing you to save your changes to disk and synchronise model metadata to Analysis Services simultaneously +- \*Preview table data with infinite scrolling, create PivotGrids or write DAX queries to browse the model or test calculation logic +- \*Schedule data refreshes +- Update Table Schemas on both Provider and Structured Data Sources (yes, even for M queries!) +- Create data model diagrams +- Create DAX scripts that allow you to edit multiple measures or other calculated objects in a single document +- Record C# scripts and save as macros (formerly known as "Custom Actions") +- VertiPaq Analyzer integration +- DAX debugger + +\*=Only while connected to an instance of Analysis Services or Power BI + +--- diff --git a/content/localization/zh/Advanced-Filtering-of-the-Explorer-Tree_zh.md b/content/localization/zh/Advanced-Filtering-of-the-Explorer-Tree_zh.md new file mode 100644 index 00000000..11ffa926 --- /dev/null +++ b/content/localization/zh/Advanced-Filtering-of-the-Explorer-Tree_zh.md @@ -0,0 +1,87 @@ +# Advanced Object Filtering + +This article describes how to use the "Filter" textbox within Tabular Editor - an incredibly useful feature when navigating complex models. + +## Filtering Mode + +As of [2.7.4](https://github.com/TabularEditor/TabularEditor/releases/tag/2.7.4), Tabular Editor now lets you decide how the filter should apply to objects in the hierarchy, and how search results are displayed. This is controlled using the three right-most toolbar buttons next to the Filter button: + +![image](https://user-images.githubusercontent.com/8976200/46567931-08a4b480-c93d-11e8-96fd-e197e87a0587.png) + +- ![image](https://user-images.githubusercontent.com/8976200/46567944-44d81500-c93d-11e8-91e2-d9822078dba7.png) **Hierarchical by parent**: The search will apply to _parent_ objects, that is Tables and Display Folders (if those are enabled). All child items will be displayed, when a parent item matches the search criteria. +- ![image](https://user-images.githubusercontent.com/8976200/46567940-2ffb8180-c93d-11e8-9fba-84fbb79b6bb3.png) **Hierarchical by children**: The search will apply to _child_ objects, that is Measures, Columns, Hierarchies, etc. Parent objects will only be displayed if they have at least one child object matching the search criteria. +- ![image](https://user-images.githubusercontent.com/8976200/46567941-37bb2600-c93d-11e8-9c02-86502f41bce8.png) **Flat**: The search will apply to all objects, and results will be displayed in a flat list. Objects that contain child items will still display these in a hierarchical manner. + +## Simple search + +Type anything into the Filter textbox and hit [Enter] to do a simple case-insensitive search within object names. For example, typing "sales" in the Filter textbox, using the "By Parent" filtering mode, will produce the following results: + +![image](https://user-images.githubusercontent.com/8976200/46568002-5f5ebe00-c93e-11e8-997b-7f89dfd92076.png) + +Expanding any of the tables will reveal all measures, columns, hierarchies and partitions of the table. If we change the filtering mode to "By Child", the results will look like this: + +![image](https://user-images.githubusercontent.com/8976200/46568016-9f25a580-c93e-11e8-9bc2-c0a16a890256.png) + +Notice how the "Employee" table now appears in the list, since it has a couple of child items (columns in this case), that contain the word "sales". + +## Wildcard search + +When typing in a string in the Filter textbox, you can use the wildcard `?` to denote any single character, and `*` to denote any sequence of characters (zero or more). So typing `*sales*` would produce exactly the same results as shown above, however typing `sales*` will only show objects whose name _starts_ with the word "sales" (again, this is case-insensitive). + +Searching for `sales*` by parent: + +![image](https://user-images.githubusercontent.com/8976200/46568043-19eec080-c93f-11e8-8d81-2a6214bfa572.png) + +Searching for `sales*` by child: + +![image](https://user-images.githubusercontent.com/8976200/46568117-f9733600-c93f-11e8-96ab-f87769b8097c.png) + +Flat search for `sales*` (toggle info columns [Ctrl]+[F1] to show detailed information about each object): + +![image](https://user-images.githubusercontent.com/8976200/46568118-042dcb00-c940-11e8-82d1-516207450559.png) + +Wildcards can be placed anywhere in the string, and you can include as many as you need. If that's not complex enough, read on... + +## Dynamic LINQ search + +You can also use [Dynamic LINQ](https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions) to search for objects, which is the same thing you do when creating [Best Practice Analyzer rules](/Best-Practice-Analyzer). To enable Dynamic LINQ mode in the filter box, simply put a `:` (colon) in front of your search string. For example, to view all objects whose name end with "Key" (case-sensitive) write: + +``` +:Name.EndsWith("Key") +``` + +...and hit [Enter]. In "Flat" filtering mode, the result looks like this: + +![image](https://user-images.githubusercontent.com/8976200/46568130-33dcd300-c940-11e8-903c-193e1acde0ad.png) + +For case-insensitive search in Dynamic LINQ, you can either convert the input string using something like: + +``` +:Name.ToUpper().EndsWith("KEY") +``` + +or you can supply the [StringComparison](https://docs.microsoft.com/en-us/dotnet/api/system.string.endswith?view=netframework-4.7.2#System_String_EndsWith_System_String_System_StringComparison_) argument, like: + +``` +:Name.EndsWith("Key", StringComparison.InvariantCultureIgnoreCase) +``` + +You are not restricted to searching within the names of objects. Dynamic LINQ search strings can be as complex as you like, to evaluate any property (as well as sub-properties) of an object. So if you want to find all objects having an expression that contains the word "TODO", you would use the following search filter: + +``` +:Expression.ToUpper().Contains("TODO") +``` + +As another example, the following will display all hidden measures in the model that are not referenced by anything else: + +``` +:ObjectType="Measure" and (IsHidden or Table.IsHidden) and ReferencedBy.Count=0 +``` + +You can also use Regular Expressions. The following will find all columns whose name contains the word "Number" OR "Amount": + +``` +:ObjectType="Column" and RegEx.IsMatch(Name,"(Number)|(Amount)") +``` + +Note, that the display options (the toolbar buttons directly above the tree), may affect the results when using "By Parent" and "By Child" filtering mode. For example, the above LINQ filter only returns columns, but if your display options are currently set to not show columns, nothing will be displayed. diff --git a/content/localization/zh/Advanced-Scripting-and-Dynamic-LINQ-quiz_zh.md b/content/localization/zh/Advanced-Scripting-and-Dynamic-LINQ-quiz_zh.md new file mode 100644 index 00000000..ec2025a6 --- /dev/null +++ b/content/localization/zh/Advanced-Scripting-and-Dynamic-LINQ-quiz_zh.md @@ -0,0 +1,108 @@ +Are you a Tabular Editor pro? + +Test your knowledge of Tabular Editor's Advanced Scripting and Dynamic LINQ filter expressions. All the questions here may be answered using just one line of code. + +If you're new to these features, the solutions presented here (both the C# and Dynamic LINQ version), provides a lot of useful information on how this stuff works, so make sure to check them out. + +*** + +#### Question #1) Total number of measures + +- How would you obtain the total number of measures in your model? + +
    C# script solution +
    Model.AllMeasures.Count().Output();
    Explanation: The Model object represents the root of the TOM tree. It supports most of the properties found in the API documentation with the addition of a number of extra properties and methods, that are only available inside Tabular Editor. The AllMeasures property is one of these extra properties, added for convenience. It simply returns a collection of all measures across all tables in the model. All collections (or more precisely, enumerables) support the powerful .NET LINQ methods. Count() is one such method, which simply returns the number of elements in the collection as an integer. Once we have that, the only thing left is to Output() it.

    +
    + +
    Dynamic LINQ solution +
    :ObjectType="Measure"
    Explanation: When you put a ':' as the first character of the Filter textbox, you enable Dynamic LINQ filtering. What that means is, that Tabular Editor evaluates the expression after the ':' character against every object in the TOM tree, returning only those objects where the expression evaluates to true. Putting the expression above into the Filter textbox, will have Tabular Editor display all objects whose ObjectType property is "Measure". The search result count at the bottom of the screen, should then tell you how many measures you have in total.

    +
    + +*** + +#### Question #2) Find all measures with "TODO" in their expression + +- What's the easiest way to find all measures that contain the word "TODO" inside their Expression property? + +
    C# script solution +
    Model.AllMeasures.Where(m => m.Expression.Contains("TODO")).Output();
    Explanation: The first part of this script is the same as in question 1. Where(x => y) is another .NET LINQ method, that filters the preceding collection based on a so-called predicate. The predicate is expressed using the special C# Lambda notation x => y. On the left side of the arrow, you declare a variable with a name of your choice. The expression to the right of the arrow will be evaluated for every object in the collection, using the variable on the left to represent individual objects. This expression can be any valid C# expression that evaluates to a boolean value (true or false). Thus, the Where method simply filters the collection to return only those objects where the Lambda expression evaluates to true. So in the example above, we decide to use m as the name of our variable, which will represent the individual measures of our model. But we only want to keep measures whose Expression property Contains the word "TODO". Makes sense?

    +
    + +
    Dynamic LINQ solution +
    :ObjectType="Measure" and Expression.Contains("TODO")
    Explanation: The first part of this Dynamic LINQ expression is identical to question 1. Dynamic LINQ lets you use many different operators such as and or or to express complex logic. Notice how the second part of the expression is similar to the C# Lambda expression used above, except that we don't declare a variable to represent the measure. Since Dynamic LINQ is evaluated against every object in the TOM tree, any property or method name we add to the expression will implicitly be evaluated against the current object. Since different types of objects have different properties, no error is produced if the Filter box contains an invalid expression. However, when writing Dynamic LINQ expressions within the Best Practice Analyzer, an error will be shown if you try to access a property or method that doesn't exist on the chosen object types. +
    + +*** + +#### Question #3) Count the number of direct measure dependencies + +- How can we know the number of measures that directly reference the currently selected measure? You can always check your answer against the "Show dependencies" dialog. + +
    C# script solution +
    Selected.Measure.ReferencedBy.Measures.Count().Output();
    Explanation: Selected.Measure refers to the currently selected measure in the explorer tree. All objects that can be referenced through DAX (measures, tables, columns, KPIs) have the ReferencedBy property, which is a special collection of objects that directly reference the former. Although we could use the LINQ-method .OfType<Measure>() to filter the collection to measures only, this particular collection contains a set of convenient properties that does this for us. One of them, is Measures.

    +
    + +
    Dynamic LINQ solution +
    :ObjectType="Measure" and DependsOn.Measures.Any(Name="Reseller Total Sales")
    Explanation: It's not possible to create a Dynamic LINQ filter expression based on the current selection, so instead we consider a specific measure in this example, [Reseller Total Sales]. The example here, will return all those objects who have a direct dependency on a measure named "Reseller Total Sales". The reason we're using "DependsOn" instead of "ReferencedBy" here, is that search filter expressions are evaluated against every single object in the model. That's the opposite of what we're doing in the C# script, where we already have a handle to a specific measure and want to obtain the list of measures referencing that measure. +
    + +*** + +#### Question #4) Recursively count the number of measure dependencies + +- Let's go deeper. How would you obtain the number of measures that depend recursively on the currently selected measure? + +
    C# script solution +
    Selected.Measure.ReferencedBy.Deep().OfType<Measure>().Count().Output();
    +Here, we add the Deep() method to recursively traverse the dependency tree, to get a collection of all objects that reference the original measure either directly, or indirectly through other objects. We have to manually filter this collection to objects of type "Measure", to avoid seeing Calculated Columns, RLS Expressions, etc. The only thing left then, is to Count() the number of items in this result and Output() it to the screen.

    By the way, if we wanted to display a list of these measures instead of just the count, we could write: +
    Selected.Measure.ReferencedBy.Deep().OfType().Output();
    +
    + +
    Dynamic LINQ solution +
    :ObjectType="Measure" and DependsOn.Deep().Any(Name="Reseller Total Sales")
    Explanation: All methods that can be called using C# may also be called using Dynamic LINQ. So just like we did above, we're calling the Deep() method to recursively traverse the dependency tree upwards, to find all objects that have a dependency on an object named "Reseller Total Sales". Strictly speaking, this is not exactly the same as the C# expression above, as we would also get a positive hit on non-measure type objects with the name "Reseller Total Sales". To work around that, we could either explicitly state that we only want to consider measures... +
    :DependsOn.Deep().Any(Name="Reseller Total Sales" and ObjectType="Measure")
    +...or we could use the DaxObjectFullName property to check for a hit (column names would be fully qualified, and measures must be uniquely named across the entire model): +
    :DependsOn.Deep().Any(DaxObjectFullName="[Reseller Total Sales]")
    +
    + +*** + +#### Question #5) List all related dimensions + +- Given a fact table `'Reseller Sales'`, how do we obtain a list of all related dimension tables? + +
    C# script solution +
    var t = Model.Tables["Reseller Sales"];
    +t.UsedInRelationships.Where(r => r.FromTable == t).Select(r => r.ToTable).Output();
    Explanation: Okay, I admit, this one is a little tricky and because I used a variable to hold the given table, we end up with 2 lines of code instead of one. The naïve approach would be to simply write t.RelatedTables.Output();, but since the question specifically asked us to output only related dimension tables, we need to consider only those relationships where our given table is on the "From" side. That is the purpose of t.UsedInRelationships.Where(r => r.FromTable == t). If we just wanted the list of outgoing relationships, we'd be done here, but since we want a list of the tables pointed to by those relationships, we need to project this list to get the `ToTable` property of each relationship. That's exactly what .Select(r => r.ToTable) does. Makes sense? Now check out the Dynamic LINQ solution below.

    + +
    Dynamic LINQ solution +
    :UsedInRelationships.Any(ToTable=current and FromTable.Name = "Reseller Sales")
    Explanation: Let's read this expression from left to right, keeping in mind that this is evaluated for every object in the model. UsedInRelationships is a list of relationships in which the current object participates. At this point, we've ruled out anything that's not a table or a column object, as these are the only ones that have the UsedInRelationships property. To filter anything that's not a dimension table, we only want to consider relationships pointing to the current object, from the table in question. .Any( ... ) evaluates to true if at least one of the relationships satisfies the condition: ToTable=current and FromTable.Name = "Reseller Total Sales". The special keyword current refers to the current object being evaluated. As we're equating this with the ToTable property of the relationship, we're ruling out columns from the search result, as this property can only be of type Table. FromTable.Name = ... is self-explanatory. +
    + +*** + +#### Question #6) Find all objects with the words "Total" and "Amount" (in that order) in their name + +![image](https://user-images.githubusercontent.com/8976200/44931220-c2dd4680-ad15-11e8-9e52-29ec07f1edb6.png) + +Hint: The regular expression for that would be `Total.*Amount` + +
    C# script solution +
    Model.AllMeasures.Where(m => System.Text.RegularExpressions.Regex.IsMatch(m.Name, "Total.*Amount")).Output();
    Explanation: This one is actually quite annoying to do in the Advanced Script tab. Strictly speaking, we would actually have to search all the collections (Tables, AllMeasures, AllColumns, AllHierarchies, ...) and then concatenate the result, if we wanted to see them all in one view. Additionally, since the System.Text.RegularExpressions namespace is not in scope by default, the script is not really that typing-friendly. Check out the Dynamic LINQ solution instead.

    + +
    Dynamic LINQ solution +
    :Regex.IsMatch(Name, "Total.*Amount")
    +Beautiful, isn't it? +
    + +*** + +#### Question #7) Same as #6 but with a case-_in_sensitive search + +
    C# script solution +
    Model.AllMeasures.Where(m => System.Text.RegularExpressions.Regex.IsMatch(m.Name, "Total.*Amount", RegexOptions.IgnoreCase)).Output();
    + +
    Dynamic LINQ solution +
    :Regex.IsMatch(Name, "Total.*Amount", "IgnoreCase")
    + +#### Stay tuned for more... diff --git a/content/localization/zh/Advanced-Scripting_zh.md b/content/localization/zh/Advanced-Scripting_zh.md new file mode 100644 index 00000000..98e98b2a --- /dev/null +++ b/content/localization/zh/Advanced-Scripting_zh.md @@ -0,0 +1,266 @@ +# Advanced Scripting + +This is an introduction to the Advanced Scripting capabilities of Tabular Editor. Information in this document is subject to change. Also, make sure to check out our script library @csharp-script-library, for some more real-life examples of what you can do with the scripting capabilities of Tabular Editor. + +## What is Advanced Scripting? + +The goal of the UI of Tabular Editor is to make it easy to perform most tasks commonly needed when building Tabular Models. For example, changing the Display Folder of multiple measures at once is just a matter of selecting the objects in the explorer tree and then dragging and dropping them around. The right-click context menu of the explorer tree provides a convenient way to perform many of these tasks, such as adding/removing objects from perspectives, renaming multiple objects, etc. + +There may be many other common workflow tasks, which are not as easily performed through the UI however. For this reason, Tabular Editor introduces Advanced Scripting, which lets advanced users write a script using C# syntax, to more directly manipulate the objects in the loaded Tabular Model. + +## Objects + +The [scripting API](xref:api-index) provides access to two top-level objects, `Model` and `Selected`. The former contains methods and properties that allow you to manipulate all objects in the Tabular Model, whereas the latter exposes only objects that are currently selected in the explorer tree. + +The `Model` object is a wrapper of the [Microsoft.AnalysisServices.Tabular.Model](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) class, exposing a subset of its properties, with some additional methods and properties for easier operations on translations, perspectives and object collections. The same applies to any descendant objects, such as Table, Measure, Column, etc. which all have corresponding wrapper objects. Please see for a complete listing of objects, properties and methods in the Tabular Editor wrapper library. + +The main advantage of working through this wrapper is, that all changes will be undoable from the Tabular Editor UI. Simply press CTRL+Z after executing a script, and you will see that all changes made by the script are immediately undone. Furthermore, the wrapper provides convenient methods that turn many common tasks into simple one-liners. We will provide some examples below. It is assumed that the reader is already somewhat familiar with C# and LINQ, as these aspects of Tabular Editors scripting capabilities will not be covered here. Users unfamiliar with C# and LINQ should still be able to follow the examples given below. + +## Setting object properties + +If you want to change a property of one object in particular, obviously the easiest way to do so would be directly through the UI. But as an example, let us see how we could achieve the same thing through scripting. + +Say you want to change the Format String of your [Sales Amount] measure in the 'FactInternetSales' table. If you locate the measure in the explorer tree, you can simply drag it onto the script editor. Tabular Editor will then generate the following code, which represents this particular measure in the Tabular Object Model: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"] +``` + +Adding an extra dot (.) after the right-most bracket, should make the autocomplete menu pop up, showing you which properties and methods exist on this particular measure. Simply choose "FormatString" in the menu, or write the first few letters and hit Tab. Then, enter an equal sign followed by "0.0%". Let us also change the Display Folder of this measure. Your final code should look like this: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"].FormatString = "0.0%"; +Model.Tables["FactInternetSales"].Measures["Sales Amount"].DisplayFolder = "New Folder"; +``` + +**Note:** Remember to put the semicolon (;) at the end of each line. This is a requirement of C#. If you forget it, you will get a syntax error message when trying to execute the script. + +Hit F5 or the "Play" button above the script editor to execute the script. Immediately, you should see the measure moving around in the explorer tree, reflecting the changed Display Folder. If you examine the measure in the Property Grid, you should also see that the Format String property has changed accordingly. + +### Working with multiple objects at once + +Many objects in the object model, are actually collections of multiple objects. For example, each Table object has a Measures collection. The wrapper exposes a series of convenient properties and methods on these collections, to make it easy to set the same property on multiple objects at once. This is described in detail below. Additionally, you may use all the standard LINQ extension methods to filter and browse the objects of a collection. + +Below is a few examples of the most commonly used LINQ extension methods: + +- `Collection.First([predicate])` Returns the first object in the collection satisfying the optional [predicate] condition. +- `Collection.Any([predicate])` Returns true if the collection contains any objects (optionally satisfying the [predicate] condition). +- `Collection.Where(predicate)` Returns a collection that is the original collection filtered by the predicate condition. +- `Collection.Select(map)` Projects each object in the collection into another object according to the specified map. +- `Collection.ForEach(action)` Performs the specified action on each element in the collection. + +In the above examples, `predicate` is a lambda expression that takes a single object as input, and returns a boolean value as output. For example, if `Collection` is a collection of measures, a typical `predicate` could look like: + +`m => m.Name.Contains("Reseller")` + +This predicate would return true only if the Name of the measure contains the character string "Reseller". Wrap the expression in curly braces and use the `return` keyword, if you need more advanced logic: + +```csharp +.Where(obj => { + if(obj is Column) { + return false; + } + return obj.Name.Contains("test"); +}) +``` + +Going back to the examples above, `map` is a lambda expression that takes a single object as input, and returns any single object as output. `action` is a lambda expression that takes a single object as input, but does not return any value. + +Use the IntelliSense functionality of the Advanced Script editor to see what other LINQ methods exist, or refer to the [LINQ-to-Objects documentation](https://msdn.microsoft.com/en-us/library/9eekhta0.aspx). + +## Working with the **Model** object + +To quickly reference any object in the currently loaded Tabular Model, you can drag and drop the object from the explorer tree and into the Advanced Scripting editor: + +![Dragging and dropping an object into the Advanced Scripting editor](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/DragDropTOM.gif) + +Please refer to the [TOM documentation](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) for an overview of which properties exist on the Model and its descendant objects. Additionally, refer to for a complete listing of the properties and methods exposed by the wrapper object. + +## Working with the **Selected** object + +Being able to explicitly refer to any object in the Tabular Model is great for some workflows, but sometimes you want to cherry pick objects from the explorer tree, and then execute a script against only the selected objects. This is where the `Selected` object comes in handy. + +The `Selected` object provides a range of properties that make it easy to identify what is currently selected, as well as limiting the selection to objects of a particular type. When browsing with Display Folders, and one or more folders are selected in the explorer tree, all their child items are considered to be selected as well. +For single selections, use the singular name for the type of object you want to access. For example, + +`Selected.Hierarchy` + +refers to the currently selected hierarchy in the tree, provided that one and only one hierarchy is selected. Use the plural type name, in case you want to work with multiselections: + +`Selected.Hierarchies` + +All properties that exist on the singular object, also exist on its plural form, with a few exceptions. This means that you can set the value of these properties for multiple objects at once, with just one line of code and without using the LINQ extension methods mentioned above. For example, say you wanted to move all currently selected measures into a new Display Folder called "Test": + +`Selected.Measures.DisplayFolder = "Test";` + +If no measures are currently selected in the tree, the above code does nothing, and no error is raised. Otherwise, the DisplayFolder property will be set to "Test" on all selected measures (even measures residing within folders, as the `Selected` object also includes objects in selected folders). If you use the singular form `Measure` instead of `Measures`, you will get an error unless the current selection contains exactly one measure. + +Although we cannot set the Name property of multiple objects at once, we still have some options available. If we just want to replace all occurrences of some character string with another, we can use the provided "Rename" method, like so: + +```csharp +Selected.Measures + .Rename("Amount", "Value"); +``` + +This would replace any occurence of the word "Amount" with the word "Value" in the names of all currently selected measures. +Alternatively, we may use the LINQ ForEach()-method, as described above, to include more advanced logic: + +```csharp +Selected.Measures + .ForEach(m => if(m.Name.Contains("Reseller")) m.Name += " DEPRECATED"); +``` + +This example will append the text " DEPRECATED" to the names of all selected measures where the names contain the word "Reseller". Alternatively, we could use the LINQ extension method `Where()` to filter the collection before applying the `ForEach()` operation, which would yield exactly the same result: + +```csharp +Selected.Measures + .Where(m => m.Name.Contains("Reseller")) + .ForEach(m => m.Name += " DEPRECATED"); +``` + +## Helper methods + +To make debugging scripts easier, Tabular Editor provides a set of special helper methods. Internally, these are static methods decorated with the `[ScriptMethod]`-attribute. This attribute allows scripts to call the methods directly, without the need to specify a namespace or class name. Plugins may also use the `[ScriptMethod]` attribute to expose public static methods for scripting in a similar way. + +As of 2.7.4, Tabular Editor provides the following script methods. Note that some of these may be invoked as extension methods. For example, `object.Output();` and `Output(object);` are equivalent. + +- `Output(object);` - displays detailed information about the specified object or collection of objects in a popup dialog. When executed through the UI, the user has an option to ignore additional popups. When executed through the CLI, the information is outputted to the console. +- `SaveFile(filePath, content);` - convenient way to save text data to a file. +- `ReadFile(filePath);` - convenient way to load text data from a file. +- `ExportProperties(objects, properties);` - convenient way to export a set of properties from multiple objects as a TSV string. +- `ImportProperties(tsvData);` - convenient way to load properties into multiple objects from a TSV string. +- `CustomAction(name);` - invoke a Custom Action by name. +- `CustomAction(objects, name);` - invoke a Custom Action on the specified objects. +- `ConvertDax(dax, useSemicolons);` - converts a DAX expression between US/UK and non-US/UK locales. If `useSemicolons` is true (default) the `dax` string is converted from the native US/UK format to non-US/UK. That is, commas (list separators) will be converted to semicolons and periods (decimal separators) will be converted to commas. Vice versa if `useSemicolons` is set to false. +- `FormatDax(IEnumerable objects, bool shortFormat, bool? skipSpace)` - formats DAX expressions on all objects in the provided collection +- `FormatDax(IDaxDependantObject obj)` - queues an object for DAX expression formatting when script execution is complete, or when the `CallDaxFormatter` method is called. +- `CallDaxFormatter(bool shortFormat, bool? skipSpace)` - formats all DAX expressions on objects enqueued so far +- `Info(string);` - Displays an informational message in a popup dialog. When the script is running in the CLI, an information message is written to the console. +- `Warning(string);` - Displays a warning message in a popup dialog. When the script is running in the CLI, a warning message is written to the console. +- `Error(string);` - Displays an error message in a popup dialog. When the script is running in the CLI, an error message is written to the console. + +You can find an updated list of all helper methods [here](xref:script-helper-methods). + +### Debugging scripts + +As mentioned above, you can use the `Output(object);` method to pause script execution, and open a dialog box with information about the passed object. You can also use this method as an extension method, invoking it as `object.Output();`. The script is resumed when the dialog is closed. + +The dialog will appear in one of four different ways, depending on the kind of object being output: + +- Singular objects (such as strings, ints and DateTimes, except any object that derives from TabularNamedObject) will be displayed as a simple message dialog, by invoking the `.ToString()` method on the object: + +![image](https://user-images.githubusercontent.com/8976200/29941982-9917d0cc-8e94-11e7-9e78-24aaf11fd311.png) + +- Singular TabularNamedObjects (such as Tables, Measures or any other TOM NamedMetadataObject available in Tabular Editor) will be shown in a Property Grid, similar to when an object has been selected in the Tree Explorer. Properties on the object may be edited in the grid, but note that if an error is encountered at a later point in the script execution, the edit will be automatically undone, if "Rollback on error" is enabled: + +![image](https://user-images.githubusercontent.com/8976200/29941852-2acc9846-8e94-11e7-9380-f84fef26a78c.png) + +- Any IEnumerable of objects (except TabularNamedObjects) will be displayed in a list, where each list item shows the `.ToString()` value and type of the object in the IEnumerable: + +![image](https://user-images.githubusercontent.com/8976200/29942113-02dad928-8e95-11e7-9c04-5bb87b396f3f.png) + +- Any IEnumerable of TabularNamedObjects will cause the dialog to display a list of the objects on the left, and a Property Grid on the right. The Property Grid will be populated from whatever object is selected in the list, and properties may be edited just as when a single TabularNamedObject is being output: + +![image](https://user-images.githubusercontent.com/8976200/29942190-498cbb5c-8e95-11e7-8455-32750767cf13.png) + +You can tick the "Don't show more outputs" checkbox at the lower left-hand corner, to prevent the script from halting on any further `.Output()` invocations. + +## .NET references + +[Tabular Editor version 2.8.6](https://github.com/TabularEditor/TabularEditor/tree/2.8.6) makes it a lot easier to write complex scripts. Thanks to the new pre-processor, you can now use the `using` keyword to shorten class names, etc. just like in regular C# source code. In addition, you can include external assemblies by using the syntax `#r ""` similar to .csx scripts used in Azure Functions. + +For example, the following script will now work as expected: + +```csharp +// Assembly references must be at the very top of the file: +#r "System.IO.Compression" + +// Using keywords must come before any other statements: +using System.IO.Compression; +using System.IO; + +var xyz = 123; + +// Using statements still work the way they're supposed to: +using(var data = new MemoryStream()) +using(var zip = new ZipArchive(data, ZipArchiveMode.Create)) +{ + // ... +} +``` + +By default, Tabular Editor applies the following `using` keyword (even though they are not specified in the script), to make common tasks easier: + +```csharp +using System; +using System.Linq; +using System.Collections.Generic; +using Newtonsoft.Json; +using TabularEditor.TOMWrapper; +using TabularEditor.TOMWrapper.Utils; +using TabularEditor.UI; +``` + +In addition, the following .NET Framework assemblies are loaded by default: + +- System.Dll +- System.Core.Dll +- System.Data.Dll +- System.Windows.Forms.Dll +- Microsoft.Csharp.Dll +- Newtonsoft.Json.Dll +- TomWrapper.Dll +- TabularEditor.Exe +- Microsoft.AnalysisServices.Tabular.Dll + +## Compiling with Roslyn + +If you prefer to compile your scripts using the new Roslyn compiler introduced with Visual Studio 2017, you can set this up under File > Preferences > General, starting with Tabular Editor version 2.12.2. This allows you to use newer C# language features such as string interpolation. Simply specify the path to the directory that holds the compiler executable (`csc.exe`) and specify the language version as an option for the compiler: + +![image](https://user-images.githubusercontent.com/8976200/92464140-0902f580-f1cd-11ea-998a-b6ecce57b399.png) + +### Visual Studio 2017 + +For a typical Visual Studio 2017 Enterprise installation, the Roslyn compiler is located here: + +``` +c:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Roslyn +``` + +This includes the C# 6.0 language features by default. + +![image](https://user-images.githubusercontent.com/8976200/92464584-a52cfc80-f1cd-11ea-9b66-3b47ac36f6c6.png) + +### Visual Studio 2019 + +For a typical Visual Studio 2019 Community installation, the Roslyn compiler is located here: + +``` +c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn +``` + +The compiler that ships with VS2019 supports C# 8.0 language features, which can be enabled by specifying the following as compiler options: + +``` +-langversion:8.0 +``` + +### Visual Studio 2022 + +For a typical Visual Studio 2022 **Community Edition**, the Roslyn compiler is located here: + +``` +C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\csc.exe +``` + +If you use another edition of Visual Studio 2022, the path might be slightly different. For example, for the **Enterprise Edition**, it is located here: + +``` +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\Roslyn +``` + +The compiler that ships with the most recent update of VS2022 supports [C# 12.0 language features](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12), which can be enabled by specifying the following as compiler options: + +``` +-langversion:12.0 +``` diff --git a/content/localization/zh/Advanced-features_zh.md b/content/localization/zh/Advanced-features_zh.md new file mode 100644 index 00000000..eff815cc --- /dev/null +++ b/content/localization/zh/Advanced-features_zh.md @@ -0,0 +1,113 @@ +# Advanced Features + +In addition to the features mentioned in the [Features at a glance](/te2/Features-at-a-glance) article, Tabular Editor also supports the following features for advanced usage. + +## Replace tables + +As of version 2.7, you can now replace a table simply by copying (CTRL+C) one table - even from another instance of Tabular Editor - and then selecting the table you want to replace, before hitting paste (CTRL+V). A prompt will ask you to confirm whether you really want to replace the table ("Yes"), insert as a new table ("No") or cancel the operation entirely: + +![image](https://user-images.githubusercontent.com/8976200/36545892-40983114-17ea-11e8-8825-e8de6fd4e284.png) + +If you choose "Yes", the selected table will be replaced with the table in the clipboard. Furthermore, all relationships pointing to or from that table will be updated to use the new table. For this to work, columns participating in relationships must have the same name and data type in both the original table, and the inserted table. + +## Roles and Row-Level Security + +As of version 2.1, Roles are now visible in the Explorer Tree. You can right-click the tree to create new roles, delete or duplicate existing roles. You can view and edit the members of each role, by locating the role in the Explorer Tree, and navigating to the "Role Members" property in the Property Grid. Note that when deploying, the [Deployment Wizard](/te2/Advanced-features#deployment-wizard) does not deploy role members by default. + +The biggest advantage of working with Roles through Tabular Editor, is that each Table object has a "Row Level Filters" property, which lets you view and edit the filters defined on that table, across all roles: + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/RLSTableContext.png) + +Of course, you can also view the filters across all tables in one particular role, similar to the UI of SSMS or Visual Studio: + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/RLSRoleContext.png) + +## View Table Partitions + +TODO + +## DAX Expression Editor + +TODO + +## Script Editor + +TODO (For now, please view [this article](/te2/Advanced-Scripting)) + +## Scripting/referencing objects + +You can use drag-and-drop functionality, to script out objects in the following ways: + +- Drag one or more objects to another Windows application (text editor or SSMS) + JSON code representing the dragged object(s) will be created. When dragging the Model node, a Table, a Role or a Data Source, a "createOrReplace" script is created. + +- Dragging an object (measure, column or table) into the DAX expression editor, will insert a fully-qualified DAX-reference to the object in question. + +- Dragging an object to the Advanced Script editor, will insert the C# code necessary to access the object through the TOM tree. + +## Deployment Wizard + +Tabular Editor comes with a deployment wizard that provides a few benefits compared to deploying from SSDT - especially when deploying to an existing database. After choosing a server and a database to deploy to, you have the following options for the deployment at hand: + +![Deployment Wizard](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Deployment.png) + +Leaving the "Deploy Connections" box unchecked, will make sure that all the data sources on the target database stay untouched. You will get an error if your model contains one or more tables with a data source, that does not already exist in the target database. + +Similarly, leaving out "Deploy Table Partitions", will make sure that existing partitions on your tables are not changed, leaving the data in the partitions intact. + +When the "Deploy Roles" box is checked, the roles in the target database will be updated to reflect what you have in the loaded model, however if the "Deploy Role Members" is unchecked, the members of each role will be unchanged in the target database. + +## Metadata Backup + +If you wish, Tabular Editor can automatically save a backup copy of the existing model metadata, prior to each save (when connected to an existing database) or deployment. This is useful if you're not using a version control system, but still need to rollback to a previous version of your model. + +To enable this setting, go to "File" > "Preferences", enable the checkbox and choose a folder to place the metadata backups: + + + +If the setting is enabled, a compressed (zipped) version of the existing model metadata will be saved to this location whenever you use the Deployment Wizard, or when you click the "Save" button while connected to a (workspace) database. + +## Formula Fix-up and Formula Dependencies + +Tabular Editor continuously parses the DAX expressions of all measures, calculated columns and calculated tables in your model, to construct a dependency tree of these objects. This dependency tree is used for the Formula Fix-up functionality, which may be enabled under "File" > "Preferences". Formula Fix-up automatically updates the DAX expression of any measure, calculated column or calculated table, whenever an object that was referenced in the expression is renamed. + +To visualize the dependency tree, right-click the object in the explorer tree and choose "Show dependencies..." + +![image](https://cloud.githubusercontent.com/assets/8976200/22482528/b37d27e2-e7f9-11e6-8b89-c503f9fffcac.png) + +## Import/Export Translations + +Select one or more cultures in the Explorer Tree, right-click and choose "Export Translations..." to generate a .json file that can be imported later in either Tabular Editor or Visual Studio. Choose "Import Translations..." to import a corresponding .json file. You can choose whether to overwrite existing translations. If you don't, translations defined in the .json file will only be applied to objects that do not already have a translation for the given culture. + +## Folder Serialization + +This feature allows you to more easily integrate your SSAS Tabular Models in a file-based source control environment such as TFS, SubVersion or Git. By choosing "File" > "Save to Folder...", Tabular Editor will deconstruct the Model.bim file and save its content as separate files in a folder structure similar to the structure of the JSON within the Model.bim. When subsequently saving the model, only files with changed metadata will be touched, meaning most version control systems can easily detect which changes have been done to the model, making source merging and conflict handling a lot easier, than when working with a single Model.bim file. + +![image](https://cloud.githubusercontent.com/assets/8976200/22483167/5e07ad52-e7fc-11e6-890f-5c0d20fff0cb.png) + +By default, objects are serialized down to the lowest object level (meaning measures, columns and hierarchies are stored as individual .json files). + +Additionally, Tabular Editor's [command-line syntax](xref:command-line-options) supports loading a model from this folder structure and deploying it directly to a database, making it easy for you to automate builds for continuous integration workflows. + +If you want to customize the granularity at which metadata is saved to individual files, go to File > Preferences and click the "Save to folder"-tab. Here, it's possible to toggle some serialization options which are passed to the TOM when serializing into JSON. Furthermore, you can check/uncheck the types of objects for which individual files will be generated. In some Version Control scenarios, you might want to store everything related to one table in a file on its own, where as in other scenarios you may need individual files for columns and measures. + +These settings are saved in an annotation on the model, the first time you use the Save to Folder function, so that the settings are reused when the model is loaded and the "Save"-button is subsequently clicked. If you want to apply new settings, use "File > Save to Folder..." again. + + + +## User Settings Files + +When Tabular Editor is executed, it writes some additional files to the disk at various locations. What follows is a description of these files and their content: + +### In %ProgramData%\TabularEditor + +- **BPARules.json** Best Practice Analyzer rules that are available to all users. +- **TOMWrapper.dll** This file is used when executing scripts inside Tabular Editor. You can also reference the .dll in your own .NET projects, to utilise the wrapper code. If you are having issues executing advanced scripts after upgrading Tabular Editor, please delete this file and restart Tabular Editor. +- **Preferences.json** This file stores all preferences set in the File > Preferences dialog. + +### In %AppData%\Local\TabularEditor + +- **BPARules.json** Best Practice Analyzer rules that are available only to the current user. +- **CustomActions.json** Custom script actions that can be invoked from the right-click menu or the Tools-menu of the Explorer Tree. These actions can be created on the Advanced Script Editor tab. +- **RecentFiles.json** Stores a list of recently opened .bim files. The last most 10 items in this list is displayed in the File > Recent Files menu. +- **RecentServers.json** Stores a list of recently accessed server names. These are displayed in the dropdown portion of the "Connect to Database" dialog box and in the Deployment Wizard. diff --git a/content/localization/zh/Best-Practice-Analyzer-Improvements_zh.md b/content/localization/zh/Best-Practice-Analyzer-Improvements_zh.md new file mode 100644 index 00000000..e78c71ab --- /dev/null +++ b/content/localization/zh/Best-Practice-Analyzer-Improvements_zh.md @@ -0,0 +1,68 @@ +# Best Practice Analyzer Improvements + +As of [Tabular Editor 2.8.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.8.1), the Best Practice Analyzer has received a major overhaul. + +The first thing you'll notice, is that Tabular Editor now reports the number of Best Practice issues directly within the main UI: + +![image](https://user-images.githubusercontent.com/8976200/53631987-baee5880-3c0b-11e9-9d66-e906cccce2be.png) + +Whenever a change is made to the model, the Best Practice Analyzer scans your model for issues in the background. You can disable this feature under File > Preferences. + +Clicking the link (or pressing F10), brings up the new and improved Best Practice Analyzer UI: + +![image](https://user-images.githubusercontent.com/8976200/53631947-9eeab700-3c0b-11e9-9217-5739d4de2f88.png) + +If you've used the Best Practice Analyzer in previous versions, the first thing you'll notice is that the UI has been completely redesigned, making it take up less real estate on your screen. This allows you to dock the window on one side of your desktop, while keeping the main window in the other side, allowing you to work with both at once. + +The Best Practice Analyzer window continuously lists all the **effective rules** on your model as well as the objects that are in violation of each rule. Right-clicking anywhere inside the list or using the toolbar buttons at the top of the window, let's you perform the following actions: + +- **Manage rules...**: This opens the Manage Rules UI, which we will cover below. This UI can also be accessed through the "Tools > Manage BPA Rules..." menu of the main UI. +- **Go to object...**: Choosing this option or double-clicking on an object in the list, takes you to the same object in the main UI. +- **Ignore item/items**: Selecting one or more objects in the list and choosing this option, will apply an annotation to the chosen objects indicating that the Best Practice Analyzer should ignore the objects going forward. If you ignored an object by mistake, toggle the "Show ignored" button at the top of the screen. This will let you unignore an object that was previously ignored. +- **Ignore rule**: If you've selected one or more rules in the list, this option will put an annotation at the model level that indicates, that the selected rule should always be ignored. Again, by toggling the "Show ignored" button, you can unignore rules as well. +- **Generate fix script**: Rules that have an easy fix (meaning the issue can be resolved simply by setting a single property on the object), will have this option enabled. By clicking, you will get a C# script copied into your clipboard. This script can then be subsequently pasted into the [Advanced Scripting](/Advanced-Scripting) area of Tabular Editor, where you can review it before executing it to apply the fix. +- **Apply fix**: This option is also available for rules than have an easy fix, as mentioned above. Instead of copying the script to the clipboard, it will be executed immediately. + +## Managing Best Practice Rules + +If you need to add, remove or modify the rules applying to your model, there's a brand new UI for that as well. You can bring it up by clicking the top-left button on the Best Practice Analyzer window, or by using the "Tools > Manage BPA Rules..." menu item in the main window. + +![image](https://user-images.githubusercontent.com/8976200/53632990-2f29fb80-3c0e-11e9-82fe-ee9c921662c7.png) + +This UI contains two lists: The top list represents the **collections** of rules that are currently loaded. Selecting a collection in this list, will display all the rules that are defined within this collection in the bottom list. By default, three rule collections will show up: + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%AppData%\..\Local\TabularEditor\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +If the same rule (by ID) is located in more than one collection, the order of precedence is from top to bottom, meaning a rule defined within the model takes precedence over a rule, with the same ID, defined on the local machine. This allows you to override existing rules, for example to take model specific conventions into account. + +At the top of the list, you'll see a special collection called **(Effective rules)**. Selecting this collection will show you the list of rules that actually apply to the currently loaded model, respecting the precedence of rules with identical ID's, as mentioned above. The lower list will indicate which collection a rule belongs to. Also, you will notice that a rule will have its name striked out, if a rule with a similar ID exists in a collection of higher precedence: + +![image](https://user-images.githubusercontent.com/8976200/53633831-74e7c380-3c10-11e9-925e-1419987f5a17.png) + +### Adding additional collections + +A new feature in Tabular Editor 2.8.1, is the possibility of including rules from other sources on a model. If, for example, you have a rules file located on a network share, you can now include that file as a rule collection in the current model. If you have write access to the location of the file, you'll also be able to add/modify/remove rules from the file. Rule collections that are added this way take precedence over rules that are defined within the model. If you add multiple such collections, you can shift them up and down to control their mutual precedence. + +Click the "Add..." button to add a new rule collection to the model. This provides the following options: + +![image](https://user-images.githubusercontent.com/8976200/53634211-7cf43300-3c11-11e9-8fed-7df113264a6f.png) + +- **Create new Rule File**: This will create a new, empty, .json file at the specified location, which you can subsequently add rules to. When choosing the file, notice that there is an option for using relative file paths. This is useful when you want to store the rule file in the same code repository as the current model. However, please be aware that a relative rule file reference only works, when the model has been loaded from disk (since there is no working directory when loading a model from an instance of Analysis Services). +- **Include local Rule File**: Use this option if you already have a .json file containing rules, that you want to include in your model. Again, you have the option of using relative file paths, which may be beneficial if the file is located close to the model metadata. If the file is located on a network share (or generally, on a drive different than where the currently loaded model metadata resides), you can only include it using an absolute path. +- **Include Rule File from URL**: This option lets you specify an HTTP/HTTPS URL, that should return a valid rule definition (json). This is useful if you want to include rules from an online source, for example the [standard BPA rules](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json) from the [BestPracticeRules GitHub site](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules). Note that rule collections added from online sources will be read-only. + +### Modifying rules within a collection + +The lower part of the screen will let you add, edit, clone and delete rules within the currently selected collection, provided you have write access to the location where the collection is stored. Also, the "Move to..." button allows you to move or copy the selected rule to another collection, making it easy to manage multiple collections of rules. The UI for editing a rule definition is unchanged from previous versions of Tabular Editor, so please refer to the [old Best Practice Analyzer article](/Best-Practice-Analyzer#rule-expression-samples) for more information on how to use that. + +### Rule Description Placeholders + +One small improvement compared to previous versions, is that you can now use the following placeholder values within the Best Practice Rule's description. This provides more customisable descriptions that will appear as tooltips in the Best Practice UI: + +- `%object%` returns a fully qualified DAX reference (if applicable) to the current object +- `%objectname%` returns only the name of the current object +- `%objecttype%` returns the type of the current object + +![image](https://user-images.githubusercontent.com/8976200/53671918-587f7180-3c78-11e9-855f-ed497f2c0c98.png) diff --git a/content/localization/zh/Best-Practice-Analyzer_zh.md b/content/localization/zh/Best-Practice-Analyzer_zh.md new file mode 100644 index 00000000..3a91ba69 --- /dev/null +++ b/content/localization/zh/Best-Practice-Analyzer_zh.md @@ -0,0 +1,148 @@ +# Best Practice Analyzer + +> [!NOTE] +> Some of the information and screenshots in this article is outdated, as the Best Practice Analyzer has received a [complete overhaul in Tabular Editor v. 2.8.1](Best-Practice-Analyzer-Improvements.md). Information on Dynamic LINQ (rule expressions) is still up-to-date. + +Inspired by [this excellent suggestion](https://github.com/TabularEditor/TabularEditor/issues/39), I am proud to present the Best Practice Analyzer (BPA) - a brand new feature of Tabular Editor. Go to the Tools-menu and click "Best Practice Analyzer...", this will open the following window (you can continue working on your model in the main window, while the BPA window stays open): + +![image](https://cloud.githubusercontent.com/assets/8976200/25298153/07cb3ae0-26f3-11e7-84cb-1c27a5911560.png) + +BPA lets you define rules on the metadata of your model, to encourage certain conventions and best practices while developing in SSAS Tabular. + +Clicking one of the rules in the top list, will show you all objects that satisfy the conditions of the given rule in the bottom list: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298226/9c036214-26f3-11e7-97ea-03ef82366eb5.png) + +Double-clicking an object in the list switches the focus back to the main Tabular Editor window, where the object will be selected in the Explorer Tree ("Go to object..."). It is also possible to specify that a rule should be ignored entirely (can also be done by removing the checkmarks from the rule list), or ignored only for a specific object. Ignores are stored in the metadata annotations of the Model.bim file. + +To create a new rule, simply click "Add rule..." while you have a Tabular Model loaded in Tabular Editor. This opens a new window, where you can give your rule a name, a description and specify the conditions of the rule: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298330/4178cbe4-26f4-11e7-97ee-d80c1dbc54ed.png) + +A visual rule builder is planned for a later release. For now, you specify the rule condition using a [Dynamic LINQ expression](https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions) that allows you to access all properties on the type(s) of object(s) specified in the dropdown. All objects that satisfy the condition will show up in the BPA UI when the rule is selected. + +By default, a rule created this way will be added to the metadata annotations of the Model object and stored in the Model.bim file or the connected database, when you click "Save" in Tabular Editor. You can promote a rule stored locally in a model to a "global" rule. Global rules are stored in your %AppData%\Local\TabularEditor folder in a file called "BPARules.json". You can also put the BPARules.json in the %ProgramData%\TabularEditor folder, to make the rules available to all users on the machine. + +Note that the rule ID's must always be unique. In case a rule within the model metadata has the same ID as a rule in the %AppData% or %ProgramData% folder, the order of precedence is: + +- Rules stored locally in the model +- Rules stored in the %AppData%\Local folder +- Rules stored in the %ProgramData% folder + +## Rule Expression Samples + +In this section, you'll see some examples of Dynamic LINQ expressions that can be used to define rules. The expression that is entered in the Rule Expression Editor, will be evaluated whenever focus leaves the textbox, and any syntax errors will be shown on top of the screen: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380170/9f01634e-29af-11e7-952e-e10a1f28df32.png) + +Your rule expressions may access any public properties on the objects in the TOM. If you try to access a property that does not exist on that type of object, an error will also be shown: + +![image](https://cloud.githubusercontent.com/assets/8976200/25381302/798bab98-29b3-11e7-931e-789e5286fc45.png) + +"Expression" does not exist on the "Column" object, but if we switch the dropdown to "Calculated Columns", the statement above works fine: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380451/87b160da-29b0-11e7-8e2e-c4e47593007d.png) + +Dynamic LINQ supports all the standard arithmetic, logical and comparison operators, and using the "."-notation, you can access subproperties and -methods of all objects. + +``` +String.IsNullOrWhitespace(Expression) and not Name.StartsWith("Dummy") +``` + +The above statement, applied to Calculated Columns, Calculated Tables or Measures, flags those that have an empty DAX expression unless the object's name starts with the text "Dummy". + +Using LINQ, we can also work with collections of objects. The following expression, applied to tables, will find those that have more than 10 columns which are not organized in Display Folders: + +``` +Columns.Count(DisplayFolder = "") > 10 +``` + +Whenever we use a LINQ method to iterate over a collection, the expression used as an argument to the LINQ method is evaluated on the items in the collection. Indeed, DisplayFolder is a property on columns that does not exist at the Table level. + +Here, we see this rule in action on the Adventure Works tabular model. Note how the "Reseller" table shows up as being in violation, while the "Reseller Sales" does not show up (columns in the latter have been organized in Display Folders): + +![image](https://cloud.githubusercontent.com/assets/8976200/25380809/d9d1c3a4-29b1-11e7-839e-29450ad39c8a.png) + +To refer to the parent object inside a LINQ method, use the special "outerIt" syntax. This rule, applied to tables, will find those that contain columns whose name does not start with the table name: + +``` +Columns.Any(not Name.StartsWith(outerIt.Name)) +``` + +It would probably make more sense to apply this rule to Columns directly, in which case it should be written as: + +``` +not Name.StartsWith(Table.Name) +``` + +To compare against enumeration properties, simply pass the enumerated value as a string. This rule, will find all columns whose name end with the word "Key" or "ID", but where the SummarizeBy property has not been set to "None": + +``` +(Name.EndsWith("Key") or Name.EndsWith("ID")) and SummarizeBy <> "None" +``` + +## Finding unused objects + +When building Tabular Models it is important to avoid high-cardinality columns at all costs. Typical culprits are system timestamps, technical keys, etc. that have been imported to the model by mistake. In general, we should make sure that the model only contains columns that are actually needed. Wouldn't it be nice if the Best Practice Analyzer could tell us which columns are likely not needed at all? + +The following rule will report columns that: + +- ...are hidden (or whose parent table is hidden) +- ...are not referenced by any DAX expressions (considers all DAX expressions in the model - even drillthrough and RLS filter expressions) +- ...do not participate in any relationships +- ...are not used as the "Sort By"-column of any other column +- ...are not used as levels of a hierarchy. + +The Dynamic LINQ expression for this BPA rule is: + +``` +(IsHidden or Table.IsHidden) +and ReferencedBy.Count = 0 +and (not UsedInRelationships.Any()) +and (not UsedInSortBy.Any()) +and (not UsedInHierarchies.Any()) +``` + +The same technique can be used to find unused measures. It's a little simpler, since measures can't participate in relationships, etc. So instead, let's spice things up a bit, by also considering whether any downstream objects that reference a given measure, are visible or not. That is, if measure [A] is referenced by measure [B], and both measure [A]" and [B] are hidden, and no other DAX expressions refer to these two measures, we should let the developer know that it is safe to remove both of them: + +``` +(IsHidden or Table.IsHidden) +and not ReferencedBy.AllMeasures.Any(not IsHidden) +and not ReferencedBy.AllColumns.Any(not IsHidden) +and not ReferencedBy.AllTables.Any(not IsHidden) +and not ReferencedBy.Roles.Any() +``` + +## Fixing objects + +In some cases, it is possible to automatically fix the issues on objects satisfying the criteria of a rule. For example when it's just a matter of setting a simple property on the object. Take a closer look at the JSON behind the following rule: + +```json +{ + "ID": "FKCOLUMNS_HIDDEN", + "Name": "Hide foreign key columns", + "Category": null, + "Description": "Columns used on the Many side of a relationship should be hidden.", + "Severity": 1, + "Scope": "Column", + "Expression": "Model.Relationships.Any(FromColumn = outerIt) and not IsHidden and not Table.IsHidden", + "FixExpression": "IsHidden = true", + "Compatibility": [ + 1200, + 1400 + ], + "IsValid": false +} +``` + +This rule finds all columns that are used in a relationship (on the "Many"/"From" side), but where the column or its parent table are not hidden. It is recommended that such columns are never shown, as users should filter data using the related (dimension) table instead. So the fix in this case, would be to set the columns IsHidden property to true, which is exactly what the "FixExpression" string above does. To see this in action, right-click any objects that violate the rule, and choose "Generate Fix Script". This puts a small script into the clipboard, which can be pasted into the Advanced Script Editor, from where you can easily review the code and execute it: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298489/9035bab6-26f5-11e7-8134-8502daaf4132.png) + +Remember that you can always undo (CTRL+Z) changes done to a model after script execution. + +Feedback on this new tool is most welcome! In the future, we plan to provide a set of universal Best Practices that will ship with Tabular Editor to get you started. Furthermore, plans are in motion to make the Best Practice Analyzer available as a plug-in to Visual Studio, so those of you not using Tabular Editor can still benefit from it. + +## Official Best Practice Rules + +Microsoft has provided a set of standard Best Practice Rules. The definition of these rules is available in [this GitHub repository](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules). Microsoft encourages community contributions and feedback to this repository. For more details and background on these rules, please view [this official blogpost](https://powerbi.microsoft.com/en-us/blog/best-practice-rules-to-improve-your-models-performance/). diff --git a/content/localization/zh/Command-line-Options_zh.md b/content/localization/zh/Command-line-Options_zh.md new file mode 100644 index 00000000..78a929c4 --- /dev/null +++ b/content/localization/zh/Command-line-Options_zh.md @@ -0,0 +1,268 @@ +--- +uid: command-line-options +title: Command Line +author: Daniel Otykier +updated: 2021-08-26 +--- + +# Command Line + +Tabular Editor can be executed from the command-line to perform various tasks, which may be useful in Automated Build and Deployment scenarios, etc. + +**Note:** Since TabularEditor.exe is a WinForms application, executing it directly from a windows command-prompt will cause the thread to return immediately to the prompt. This may cause issues in command scripts, etc. To wait for TabularEditor.exe to complete its command-line tasks, always execute it using: `start /wait TabularEditor ...` + +To view the command-line options available in Tabular Editor, run the following command: + +**Windows Command line:** + +```shell +start /wait TabularEditor.exe /? +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru -ArgumentList "/?" +``` + +Output: + +```cmd +Usage: + +TABULAREDITOR ( file | server database | -L [name] ) [-S script1 [script2] [...]] + [-SC] [-A [rules] | -AX rules] [(-B | -F | -TMDL) output [id]] [-V | -G] [-T resultsfile] + [-D [server database [-L user pass] [-F | -O [-C [plch1 value1 [plch2 value2 [...]]]] + [-P [-Y]] [-S] [-R [-M]]] + [-X xmla_script]] [-W] [-E]] + +file Full path of the Model.bim file or database.json model folder to load. +server Server\instance name or connection string from which to load the model +database Database ID of the model to load. If blank (") picks the first available + database on the server. +-L / -LOCAL Connects to a Power BI Desktop (local) instance of Analysis Services. If no + name is specified, this assumes that exactly 1 instance is running. Otherwise, + name should match the name of the .pbix file loaded in Power BI Desktop. +-S / -SCRIPT Execute the specified script on the model after loading. + scriptN Full path of one or more files containing a C# script to execute or an inline + script. +-SC / -SCHEMACHECK Attempts to connect to all Provider Data Sources in order to detect table schema + changes. Outputs... + ...warnings for mismatched data types and unmapped source columns + ...errors for unmapped model columns. +-A / -ANALYZE Runs Best Practice Analyzer and outputs the result to the console. + rules Optional path of file or URL of additional BPA rules to be analyzed. If + specified, model is not analyzed against local user/local machine rules, + but rules defined within the model are still applied. +-AX / -ANALYZEX Same as -A / -ANALYZE but excludes rules specified in the model annotations. +-B / -BIM / -BUILD Saves the model (after optional script execution) as a Model.bim file. + output Full path of the Model.bim file to save to. + id Optional id/name to assign to the Database object when saving. +-F / -FOLDER Saves the model (after optional script execution) as a Folder structure. + output Full path of the folder to save to. Folder is created if it does not exist. + id Optional id/name to assign to the Database object when saving. +-TMDL Saves the model (after optional script execution) as a TMDL folder structure. + output Full path of the TMDL folder to save to. Folder is created if it does not exist. + id Optional id/name to assign to the Database object when saving. +-V / -VSTS Output Visual Studio Team Services logging commands. +-G / -GITHUB Output GitHub Actions workflow commands. +-T / -TRX Produces a VSTEST (trx) file with details on the execution. + resultsfile File name of the VSTEST XML file. +-D / -DEPLOY Command-line deployment + If no additional parameters are specified, this switch will save model metadata + back to the source (file or database). + server Name of server to deploy to or connection string to Analysis Services. + database ID of the database to deploy (create/overwrite). + -L / -LOGIN Disables integrated security when connecting to the server. Specify: + user Username (must be a user with admin rights on the server) + pass Password + -F / -FULL Deploy the full model metadata, allowing overwrite of an existing database. + -O / -OVERWRITE Allow deploy (overwrite) of an existing database. + -C / -CONNECTIONS Deploy (overwrite) existing data sources in the model. After the -C switch, you + can (optionally) specify any number of placeholder-value pairs. Doing so, will + replace any occurrence of the specified placeholders (plch1, plch2, ...) in the + connection strings of every data source in the model, with the specified values + (value1, value2, ...). + -P / -PARTITIONS Deploy (overwrite) existing table partitions in the model. + -Y / -SKIPPOLICY Do not overwrite partitions that have Incremental Refresh Policies defined. + -S / -SHARED Deploy (overwrite) shared expressions. + -R / -ROLES Deploy roles. + -M / -MEMBERS Deploy role members. + -X / -XMLA No deployment. Generate XMLA/TMSL script for later deployment instead. + xmla_script File name of the new XMLA/TMSL script output. + -W / -WARN Outputs information about unprocessed objects as warnings. + -E / -ERR Returns a non-zero exit code if Analysis Services returns any error messages after + the metadata was deployed / updated. +``` + +> [!WARNING] +> The addition of the `-S` / `-SHARED` deployment option flag in [Tabular Editor 2.27.0](https://github.com/TabularEditor/TabularEditor/releases/tag/2.27.0) is a **breaking change**. If you're using the Tabular Editor CLI to perform deployments and you are upgrading from an earlier version of Tabular Editor, make sure to include that flag in your CLI commands, as **shared expressions will otherwise not be deployed**. + +> [!TIP] +> The `-F` flag was introduced in [Tabular Editor 2.27.0](https://github.com/TabularEditor/TabularEditor/releases). It is used to perform a "full" deployment and is equivalent to specifying `-O -C -P -S -R -M`. + +## Connecting to Azure Analysis Services + +You can use any valid SSAS connection string in place of a server name in the command. The following command loads a model from Azure Analysis Services and saves it locally as a Model.bim file: + +**Windows Command Line:** + +```shell +start /wait TabularEditor.exe "Provider=MSOLAP;Data Source=asazure://northeurope.asazure.windows.net/MyAASServer;User ID=xxxx;Password=xxxx;Persist Security Info=True;Impersonation Level=Impersonate" MyModelDB -B "C:\Projects\FromAzure\Model.bim" +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -ArgumentList "`"Provider=MSOLAP;Data Source=asazure://northeurope.asazure.windows.net/MyAASServer;User ID=xxxx;Password=xxxx;Persist Security Info=True;Impersonation Level=Impersonate`" MyModelDB -B C:\Projects\FromAzure\Model.bim" +``` + +If you prefer to connect using a Service Principal (Application ID and Key) instead of Azure Active Directory authentication, you can use the following connection string: + +``` +Provider=MSOLAP;Data Source=asazure://northeurope.asazure.windows.net/MyAASServer;User ID=app:@;Password=;Persist Security Info=True;Impersonation Level=Impersonate +``` + +## Automating script changes + +If you have created a script inside Tabular Editor, and you want to apply this script to a Model.bim file prior to deployment, you can use the command-line option "-S" (Script): + +**Windows Command Line:** + +```shell +start /wait TabularEditor.exe "C:\Projects\MyModel\Model.bim" -S "C:\Projects\MyModel\MyScript.cs" -D localhost\tabular MyModel +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -ArgumentList "`"C:\Projects\MyModel\Model.bim`" -S `"C:\Projects\MyModel\MyScript.cs`" -D `"localhost\tabular`" `"MyModel`"" +``` + +This command will load the Model.bim file in Tabular Editor, apply the specified script and deploy the modified model to the "localhost\tabular" server as a new database "MyModel". Use the "-O" (Overwrite) switch if you want to overwrite an existing database on the server with the same name. + +You can use the "-B" (Build) switch instead of the "-D" (Deploy) switch, to output the modified model as a new Model.bim file, instead of deploying it directly to a server. This is useful if you want to deploy the model using another deployment tool, or if you want to inspect the model in Visual Studio or Tabular Editor prior to deployment. It could also be useful for automated build scenarios, where you want to store the modified model as an artifact of the release, before deploying. + +## Modifying connection strings during deployment + +Let's assume you have a model containing a Data Source with the following connection string: + +``` +Provider=SQLOLEDB.1;Data Source=sqldwdev;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DW +``` + +During deployment, you want to modify the string, to point to a UAT or production database. The best way to do this, is to first use a script, that changes the entire connection string into a placeholder value, and then use the -C switch to swap the placeholder with the actual connection string. + +Put the following script into a file called "ClearConnectionStrings.cs" or similar: + +```csharp +// This will replace the connection string of all Provider (legacy) data sources in the model +// with a placeholder based on the name of the data source. E.g., if your data source is called +// "SQLDW", the connection string after running this script would be "SQLDW": + +foreach(var ds in Model.DataSources.OfType()) + ds.ConnectionString = ds.Name; +``` + +We can instruct Tabular Editor to execute the script, and then perform placeholder swapping using the following command: + +**Windows Command Line:** + +```shell +start /wait TabularEditor.exe "Model.bim" -S "ClearConnectionStrings.cs" -D localhost\tabular MyModel -C "SQLDW" "Provider=SQLOLEDB.1;Data Source=sqldwprod;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DW" +``` + +**PowerShell:** + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -ArgumentList "Model.bim -S ClearConnectionStrings.cs -D localhost\tabular MyModel -C SQLDW `"Provider=SQLOLEDB.1;Data Source=sqldwprod;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DW`"" +``` + +The command above, will deploy the Model.bim file as a new SSAS database "MyModel" on the "localhost\tabular" SSAS instance. Before deployment, the script is used to replace all connection strings on provider (legacy) data sources, with the name of the data source, to be used as a placeholder. Assuming we only have a single data source called "SQLDW", the -C switch will then update the connection string, replacing "SQLDW" with the entire string specified. + +This technique is useful for scenarios, where you want to deploy the same model to multiple environments that should process data from different (identical) sources - for example, a production, pre-prod or UAT database. If using Azure DevOps (see below), consider using a variable to store the actual connection string to be used, instead of hardcoding it in the command. + +## Integration with Azure DevOps + +If you want to use the Tabular Editor CLI inside an Azure DevOps pipeline, you should use the "-V" switch on any TabularEditor.exe command executed by your script. This switch will cause Tabular Editor to output logging commands in a [format readable by Azure DevOps](https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md). These allow Azure DevOps to react properly to errors, etc. + +When performing deployment through the command-line, information about unprocessed objects will be outputted to the prompt. In automated deployment scenarios, you may want your build agent to react to situations where objects become unprocessed, for example when adding new columns, changing the DAX expression of a calculated table, etc. In this case, you can use the "-W" switch in addition to the "-V" switch mentioned above, to output this information as warnings. Doing so, will cause the deployment to return the "SucceededWithIssues" status to Azure DevOps, after deployment is completed. You may also use the "-E" switch if you want the deployment to return status "Failed" in case the server reports any DAX errors back after successful deployment. + +`start /wait` is not necessary when executing TabularEditor.exe within a Command Line Task in an Azure DevOps pipeline. This is because the Command Line Task will not complete, until all threads spawned by the task have terminated. In other words, you need only use `start /wait` if you have additional commands following the call to TabularEditor.exe, and in this case, make sure to use `start /B /wait`. The `/B` switch is required in order for the output from TabularEditor.exe to be correctly piped back to the pipeline log. + +```shell +TabularEditor.exe "C:\Projects\My Model\Model.bim" -D ssasserver databasename -O -C -P -S -V -E -W +``` + +Or with multiple commands: + +```shell +start /B /wait TabularEditor.exe "C:\Projects\Finance\Model.bim" -D ssasserver Finance -O -C -P -S -V -E -W +start /B /wait TabularEditor.exe "C:\Projects\Sales\Model.bim" -D ssasserver Sales -O -C -P -S -V -E -W +``` + +The figure below shows what such a build looks like in Azure DevOps: + +![image](https://user-images.githubusercontent.com/8976200/27128146-bc044356-50fd-11e7-9a67-b893fc48ea50.png) + +If the deployment fails for any reason, Tabular Editor returns the "Failed" status to Azure DevOps, regardless of whether or not you are using the "-W" switch. + +For more information on Azure DevOps and Tabular Editor, [take a look at this blog series](https://tabulareditor.github.io/2019/02/20/DevOps1.html) (especially [chapter 3](https://tabulareditor.github.io/2019/10/08/DevOps3.html) and onward). + +### Azure DevOps PowerShell Task + +If you prefer to use a PowerShell task instead of a command line task, you must execute TabularEditor.exe using the `Start-Process` cmdlet, as demonstrated above. In addition, make sure to pass the process exit code as the exit parameter in your PowerShell script, so that errors occurring in Tabular Editor will cause the PowerShell task to fail: + +```powershell +$p = Start-Process -filePath TabularEditor.exe -Wait -NoNewWindow -PassThru ` + -argumentList "`"C:\Projects\My Model\Model.bim`" -D ssasserver databasename -O -C -P -S -V -E -W" +exit $p.ExitCode +``` + +## Running the Best Practice Analyzer + +You can use the "-A" switch to have Tabular Editor scan your model for all objects that are in violation of any Best Practice Rules defined on the local machine (in the %AppData%\..\Local\TabularEditor\BPARules.json file), or as annotations within the model itself. Alternatively, you can specify a path of a .json file containing Best Practice Rules after the "-A" switch, to scan the model using the rules defined in the file. Objects that are in violation will be outputted to the console. + +If you're also using the "-V" switch, the severity level of each rule will determine how the rule violation is reported to the build pipeline: + +- Severity = 1 will be informational only +- Severity = 2 will cause a WARNING +- Severity >= 3 will cause an ERROR + +## Performing a data source schema check + +As of [version 2.8](https://github.com/TabularEditor/TabularEditor/releases/tag/2.8), you can use the -SC (-SCHEMACHECK) switch to validate table source queries. This is equivalent to invoking the [Refresh Table Metadata UI](xref:importing-tables-te2#refreshing-table-metadata) except that no changes will be made to the model, but schema differences will be reported to the console. Changed Data Types and columns that were added to the source will be reported as warnings. Missing source columns will be reported as errors. If both the -SC (-SCHEMACHECK) and -S (-SCRIPT) switch are specified, the schema check will run AFTER the script has successfully executed, allowing you to modify Data Source properties before the schema check is performed, for example in order to specify a credential password. + +You can also annotate tables and columns if you want the schema check to treat them in a specific way. [More information here](xref:importing-tables-te2#ignoring-objects). + +## Command Line output and Exit Codes + +The command line provides various details, depending on the switches used and any events encountered during execution. Exit Codes were introduced in [version 2.7.4](https://github.com/TabularEditor/TabularEditor/releases/tag/2.7.4). + +| Level | Command | Message | Clarification | +| ----------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Error | (Any) | Invalid argument syntax | Invalid arguments were provided to the Tabular Editor CLI | +| Error | (Any) | File not found: ... | | +| Error | (Any) | Error loading file: ... | The file is corrupt or does not contain valid TOM metadata in a JSON format | +| Error | (Any) | Error loading model: ... | Not able to connect to the provided Analysis Services instance, database not found, database metadata corrupt or database not of a supported compatibility level | +| Error | -SCRIPT | Specified script file not found | | +| Error | -SCRIPT | Script compilation errors: | Script contained invalid C# syntax. Details will be outputted on the following lines. | +| Error | -SCRIPT | Script execution error: ... | Unhandled exception when executing the script. | +| Information | -SCRIPT | Script line #: ... | Use of the `Info(string)` or `Output(string)` methods within the script. | +| Warning | -SCRIPT | Script warning: ... | Use of the `Warning(string)` method within the script. | +| Error | -SCRIPT | Script error: ... | Use of the `Error(string)` method within the script. | +| Error | -FOLDER, -BIM | -FOLDER and -BIM arguments are mutually exclusive. | Tabular Editor can not save the currently loaded model to a folder structure and a .bim file in a single execution. | +| Error | -ANALYZE | Rulefile not found: ... | | +| Error | -ANALYZE | Invalid rulefile: ... | The specified BPA rulefile is corrupt or does not contain valid JSON. | +| Information | -ANALYZE | ... violates rule ... | Best Practice Analyzer results for rules of severity level 1 or lower. | +| Warning | -ANALYZE | ... violates rule ... | Best Practice Analyzer results for rules of severity level 2. | +| Error | -ANALYZE | ... violates rule ... | Best Practice Analyzer results for rules of severity level 3 or higher. | +| Error | -DEPLOY | Deployment failed! ... | Failure reason returned directly from Analysis Service instance (for example: Database not found, Database override not allowed, etc.) | +| Information | -DEPLOY | Unprocessed object: ... | Objects that are in state "NoData" or "CalculationNeeded" after succesful deployment. Use the -W switch to treat these as Level=Warning. | +| Warning | -DEPLOY | Object not in "Ready" state: ... | Objects that are in state "DependencyError", "EvaluationError" or "SemanticError" after succesful deployment. If using the -W switch, also includes objects in state "NoData" or "CalculationNeeded". | +| Warning | -DEPLOY | Error on X:... | Objects containing invalid DAX after succesful deployment (measures, calculated columns, calculated tables, roles). Use the -E switch to treat these as Level=Error. | + +If any of the "Error" level outputs are encountered, Tabular Editor will return Exit Code = 1. Otherwise 0. diff --git a/content/localization/zh/Custom-Actions_zh.md b/content/localization/zh/Custom-Actions_zh.md new file mode 100644 index 00000000..c7cce03f --- /dev/null +++ b/content/localization/zh/Custom-Actions_zh.md @@ -0,0 +1,70 @@ +# Custom Actions + +> [!NOTE] +> Please note that this functionality is unrelated to the Custom Actions feature available for Multidimensional models. + +Say you have created a useful script using the `Selected` object, and you want to be able to execute the script several times on different objects in the explorer tree. Instead of hitting the "Play" button whenever you want to execute the script, Tabular Editor lets you save it as a Custom Action: + +![image](https://user-images.githubusercontent.com/8976200/33581673-0db35ed0-d952-11e7-90cd-e3164e198865.png) + +After saving the custom action, you will see that it is now available directly from the right-click context menu of the explorer tree, making it very easy to invoke the script on any objects selected in the tree. You can create as many custom actions as you want. Use backslashes (\\) in the names to create a submenu structure within the context menu. + +![Custom Actions show up directly in the context menu](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/InvokeCustomAction.png) + +Custom Actions are stored in the CustomActions.json file within %AppData%\Local\TabularEditor. In the above example, the contents of this file will look like this: + +```json +{ + "Actions": [ + { + "Name": "Custom Formatting\\Number with 1 decimal", + "Enabled": "true", + "Execute": "Selected.Measures.ForEach(m => m.FormatString = \"0.0\";", + "Tooltip": "Sets the FormatString property to \"0.0\"", + "ValidContexts": "Measure, Column" + } + ] +} +``` + +As you can see, `Name` and `Tooltip` gets their values from whatever was specified when the action was saved. `Execute` is the actual script to be executed when the action is invoked. Note that any syntax errors in the CustomActions.json file will cause Tabular Editor to skip loading all Custom Actions entirely, so make sure you can successfully execute a script inside the Advanced Scripting editor, before saving it as a Custom Action. + +The `ValidContexts` property holds a list of object types for which the Action will be available. When selecting objects in the tree, a selection containing any objects different from the types listed in the `ValidContexts` property will hide the action from the context menu. + +## Controlling Action Availability + +If you need even more control on when an action can be invoked from the context menu, you can set the `Enabled` property to a custom expression that must return a boolean value, indicating whether the action will be available for the given selection. By default, the `Enabled` property has the value "true", which means that the action will always be enabled within the valid context. Keep this in mind, when using the singular object references on the `Selected` object, such as `Selected.Measure` or `Selected.Table`, as these will throw an error if the current selection does not contain exactly one of that type of object. In such a case, it is recommended to use the `Enabled` property to check that one and only one object of the required type, has been selected: + +```json +{ + "Actions": [ + { + "Name": "Reset measure name", + "Enabled": "Selected.Measures.Count == 1", + "Execute": "Selected.Measure.Name == \"New Measure\"", + "ValidContexts": "Measure" + } + ] +} +``` + +This will disable the context menu item, unless exactly one measure has been selected in the tree. + +## Reusing custom actions + +Release 2.7 introduces a new script method `CustomAction(...)`, which may be called to invoke previously saved Custom Actions. You can use this method as a stand-alone method (similar to `Output(...)`), or you can use it as an extension method on any set of objects: + +```csharp +// Executes "My custom action" against the current selection: +CustomAction("My custom action"); + +// Executes "My custom action" against all tables in the model: +CustomAction(Model.Tables, "My custom action"); + +// Executes "My custom action" against every measure in the current selection whose name starts with "Sum": +Selected.Measures.Where(m => m.Name.StartsWith("Sum")).CustomAction("My custom action"); +``` + +Note that you must specify the full name of the Custom Action, including any context menu folder names. + +If no action with the given name is found, an error is raised when the script is executed. diff --git a/content/localization/zh/DI001_zh.md b/content/localization/zh/DI001_zh.md new file mode 100644 index 00000000..3afd7558 --- /dev/null +++ b/content/localization/zh/DI001_zh.md @@ -0,0 +1,43 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/zh/DI002_zh.md b/content/localization/zh/DI002_zh.md new file mode 100644 index 00000000..0a691706 --- /dev/null +++ b/content/localization/zh/DI002_zh.md @@ -0,0 +1,48 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/zh/DI003_zh.md b/content/localization/zh/DI003_zh.md new file mode 100644 index 00000000..531867b8 --- /dev/null +++ b/content/localization/zh/DI003_zh.md @@ -0,0 +1,44 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/zh/DI004_zh.md b/content/localization/zh/DI004_zh.md new file mode 100644 index 00000000..828627ff --- /dev/null +++ b/content/localization/zh/DI004_zh.md @@ -0,0 +1,44 @@ +--- +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) \ No newline at end of file diff --git a/content/localization/zh/DI005_zh.md b/content/localization/zh/DI005_zh.md new file mode 100644 index 00000000..303fe0e3 --- /dev/null +++ b/content/localization/zh/DI005_zh.md @@ -0,0 +1,78 @@ +--- +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], ALL(Products), 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], + ALL(Products), + 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. \ No newline at end of file diff --git a/content/localization/zh/DI006_zh.md b/content/localization/zh/DI006_zh.md new file mode 100644 index 00000000..f60c71bd --- /dev/null +++ b/content/localization/zh/DI006_zh.md @@ -0,0 +1,46 @@ +--- +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. \ No newline at end of file diff --git a/content/localization/zh/DI007_zh.md b/content/localization/zh/DI007_zh.md new file mode 100644 index 00000000..b4b153ec --- /dev/null +++ b/content/localization/zh/DI007_zh.md @@ -0,0 +1,46 @@ +--- +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. \ No newline at end of file diff --git a/content/localization/zh/DI008_zh.md b/content/localization/zh/DI008_zh.md new file mode 100644 index 00000000..7275d066 --- /dev/null +++ b/content/localization/zh/DI008_zh.md @@ -0,0 +1,70 @@ +--- +uid: DI008 +category: Code actions +sub-category: Improvements +title: Remove superfluous CALCULATE +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI008` (Improvement) **Remove superfluous CALCULATE** + +## Description + +Do not explicitly call [`CALCULATE`](https://dax.guide/CALCULATE) or [`CALCULATETABLE`](https://dax.guide/CALCULATETABLE), when it is not necessary. + +### Example 1 - Measure reference with no filter context modifiers + +In the below examples, `[Total Sales]` is a measure reference. + +Change: + +```dax +CALCULATE([Total Sales]) +``` + +To: + +```dax +[Total Sales] +``` + +### Example 2 - Measure reference in a row context + +Change: + +```dax +AVERAGEX(Product, CALCULATE([Total Sales])) +``` + +To: + +```dax +AVERAGEX(Product, [Total Sales]) +``` + +### Example 3 - Constant values are not affected by filter context modifications + +Change: + +```dax +VAR _salesWithTax = [Total Sales] * 1.25 +RETURN + CALCULATE(_salesWithTax, Product[Color] = "Red") +``` + +To: + +```dax +VAR _salesWithTax = [Total Sales] * 1.25 +RETURN + _salesWithTax +``` + +## Why is Tabular Editor suggesting this? + +The `CALCULATE` function is used to modify the filter context of a calculation and force a context transition when needed. However, when the expression is not impacted by a context transition, and the filter context is not modified, the `CALCULATE` function is superfluous and can be removed (Example 1). This can make the code easier to read and understand. + +Moreover, if the `CALCULATE` function is only used to enforce a context transition and not modify the filter context (i.e. no filter arguments), but the expression is a simple measure reference, then the `CALCULATE` function can be removed (Example 2), since measure references perform implicit context transitions, when evaluated in a row context. + +Lastly, if the expression is constant (such as when referencing a variable that was defined outside of the `CALCULATE` function, such as in Example 3 above), the modified filter context will not affect the result of the expression, and the `CALCULATE` function including all filter arguments can be removed. \ No newline at end of file diff --git a/content/localization/zh/DI009_zh.md b/content/localization/zh/DI009_zh.md new file mode 100644 index 00000000..1eaba092 --- /dev/null +++ b/content/localization/zh/DI009_zh.md @@ -0,0 +1,32 @@ +--- +uid: DI009 +category: Code actions +sub-category: Improvements +title: Avoid calculate shortcut syntax +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI009` (Improvement) **Avoid calculate shortcut syntax** + +## Description + +Do not use the calculate shortcut syntax. + +### Example + +Change: + +```dax +[Total Sales](Products[Color] = "Red") +``` + +To: + +```dax +CALCULATE([Total Sales], Products[Color] = "Red") +``` + +## Why is Tabular Editor suggesting this? + +The calculate shortcut syntax is a shorthand for the `CALCULATE` function, where the first argument is the measure to evaluate, and the second argument is the filter expression. While this syntax is valid, it is not recommended, as it can be confusing to read and understand. It is better to use the `CALCULATE` function explicitly, as it makes the code more readable and maintainable. \ No newline at end of file diff --git a/content/localization/zh/DI010_zh.md b/content/localization/zh/DI010_zh.md new file mode 100644 index 00000000..56111791 --- /dev/null +++ b/content/localization/zh/DI010_zh.md @@ -0,0 +1,34 @@ +--- +uid: DI010 +category: Code actions +sub-category: Improvements +title: Use MIN/MAX instead of IF +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI010` (Improvement) **Use MIN/MAX instead of IF** + +## Description + +When a conditional expression is used to return the minimum or maximum of two values, it is more efficient and compact to use the [`MIN`](https://dax.guide/MIN) or [`MAX`](https://dax.guide/MAX) function. + +### Example + +Change: + +```dax +IF([Total Sales] > 0, [Total Sales], 0)) +``` + +To: + +```dax +MAX([Total Sales], 0) +``` + +## Why is Tabular Editor suggesting this? + +A common anti-pattern in DAX is to use an `IF` statement to return the smaller or larger of two values, by first comparing them, and then returning the appropriate value. However, this pattern can be simplified by using the `MIN` or `MAX` functions, which are more efficient and easier to read. The `MIN` function, when called with two arguments, returns the smallest value of the two arguments, while the `MAX` function returns the largest value. By using these functions, the code becomes more concise and easier to understand. + +Moreover, if any measure references are included in the arguments, they are only evaluated once, which can improve performance. \ No newline at end of file diff --git a/content/localization/zh/DI011_zh.md b/content/localization/zh/DI011_zh.md new file mode 100644 index 00000000..edc71011 --- /dev/null +++ b/content/localization/zh/DI011_zh.md @@ -0,0 +1,34 @@ +--- +uid: DI011 +category: Code actions +sub-category: Improvements +title: Use ISEMPTY instead of COUNTROWS +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI011` (Improvement) **Use ISEMPTY instead of COUNTROWS** + +## Description + +When checking if a table is empty, it is more efficient to use the [`ISEMPTY`](https://dax.guide/ISEMPTY) function than to count the rows of the table. + +### Example + +Change: + +```dax +IF(COUNTROWS(Products) = 0, "No products", "Products exist") +``` + +To: + +```dax +IF(ISEMPTY(Products), "No products", "Products exist") +``` + +## Why is Tabular Editor suggesting this? + +When checking if a table is empty, a common anti-pattern in DAX is to use the `COUNTROWS` function to count the rows of the table, and then compare the result to zero. However, this pattern is inefficient, as it requires the engine to count all rows of the table, even if the only thing we are interested in is whether the table is empty or not. + +By using the `ISEMPTY` function, the engine can stop counting rows as soon as it finds the first row, which is much more efficient. The `ISEMPTY` function returns `TRUE` if the table is empty, and `FALSE` otherwise, which makes it a more efficient and readable way to check if a table is empty. \ No newline at end of file diff --git a/content/localization/zh/DI012_zh.md b/content/localization/zh/DI012_zh.md new file mode 100644 index 00000000..11950544 --- /dev/null +++ b/content/localization/zh/DI012_zh.md @@ -0,0 +1,34 @@ +--- +uid: DI012 +category: Code actions +sub-category: Improvements +title: Use DIVIDE instead of division +author: Daniel Otykier +updated: 2025-01-03 +--- + +Code action `DI012` (Improvement) **Use DIVIDE instead of division** + +## Description + +When using an arbitrary expression in the denominator of a division, use [`DIVIDE`](https://dax.guide/DIVIDE) instead of the division operator, to avoid division by zero errors. + +### Example + +Change: + +```dax +[Total Sales] / [Total Cost] +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +## Why is Tabular Editor suggesting this? + +When dividing two numbers in DAX, it is common to use the division operator `/`. However, if the denominator is zero, the result of the division is an error. This can be problematic in certain scenarios, as it can cause the entire expression to fail. Downstream measures may use [`IFERROR`](https://dax.guide/IFERROR) to handle this, but a more elegant and better performing solution is to use the `DIVIDE` function, which returns a specific value or (Blank) if the denominator is zero. This makes the code more robust and easier to read. + +Tabular Editor will not suggest this action if the denominator is guaranteed to be non-zero, such as when dividing by a (non-zero) constant, in which case the division operator `/` is preferred. \ No newline at end of file diff --git a/content/localization/zh/DI013_zh.md b/content/localization/zh/DI013_zh.md new file mode 100644 index 00000000..d64ae31e --- /dev/null +++ b/content/localization/zh/DI013_zh.md @@ -0,0 +1,32 @@ +--- +uid: DI013 +category: Code actions +sub-category: Improvements +title: Use division instead of DIVIDE +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DI013` (Improvement) **Use division instead of DIVIDE** + +## Description + +When the 2nd argument of [`DIVIDE`](https://dax.guide/DIVIDE) is a non-zero constant, it is more efficient to use the division operator. + +### Example + +Change: + +```dax +DIVIDE([Total Sales], 1.25) +``` + +To: + +```dax +[Total Cost] / 1.25 +``` + +## Why is Tabular Editor suggesting this? + +The `DIVIDE` function is a robust way to handle division by zero errors, as it returns a specific value or (Blank) if the denominator is zero. However, when the denominator is guaranteed to be non-zero, such as when dividing by a (non-zero) constant, the division operator `/` is more efficient and easier to read. By using the division operator, the code becomes more concise and easier to understand. \ No newline at end of file diff --git a/content/localization/zh/DI014_zh.md b/content/localization/zh/DI014_zh.md new file mode 100644 index 00000000..190db2d9 --- /dev/null +++ b/content/localization/zh/DI014_zh.md @@ -0,0 +1,46 @@ +--- +uid: DI014 +category: Code actions +sub-category: Improvements +title: Replace IFERROR with DIVIDE +author: Daniel Otykier +updated: 2025-01-08 +--- + +Code action `DI014` (Improvement) **Replace IFERROR with DIVIDE** + +## Description + +Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IFERROR`](https://dax.guide/IFERROR) to provide an alternate result when a division has a zero demoninator. + +### Example 1 + +Change: + +```dax +IFERROR([Total Sales] / [Total Cost], BLANK()) +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +### Example 2 + +Change: + +```dax +IFERROR(([Total Sales] - [Total Cost]) / [Total Cost], 1) +``` + +To: + +```dax +DIVIDE([Total Sales] - [Total Cost], [Total Cost], 1) +``` + +## Why is Tabular Editor suggesting this? + +A common anti-pattern in DAX is to check for division-by-zero errors by using the `IFERROR` function. This pattern should be avoided, as evaluation errors add overhead to the query execution. Instead, the `DIVIDE` function should be used, as it checks that the denominator is not zero before the division is carried out. Moreover, using floating point arithmetics, the `DIVIDE` function is more robust and handles edge cases better than the `IFERROR` function. By using the `DIVIDE` function, the code becomes more concise and easier to understand. \ No newline at end of file diff --git a/content/localization/zh/DI015_zh.md b/content/localization/zh/DI015_zh.md new file mode 100644 index 00000000..3134307b --- /dev/null +++ b/content/localization/zh/DI015_zh.md @@ -0,0 +1,46 @@ +--- +uid: DI015 +category: Code actions +sub-category: Improvements +title: Replace IF with DIVIDE +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DI015` (Improvement) **Replace IF with DIVIDE** + +## Description + +Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IF`](https://dax.guide/IF), to more easily check for zero or blank in the demoninator. + +### Example 1 + +Change: + +```dax +IF([Total Cost] = 0, BLANK(), [Total Sales] / [Total Cost]) +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +### Example 2 + +Change: + +```dax +IF([Total Cost] <> 0, [Total Sales] / [Total Cost]) +``` + +To: + +```dax +DIVIDE([Total Sales], [Total Cost]) +``` + +## Why is Tabular Editor suggesting this? + +The `DIVIDE` function is a more concise and readable way to handle division by zero or blank values. By using `DIVIDE`, you make your code more robust and easier to understand. Moreover, the `DIVIDE` function is more efficient than using `IF` to check for zero or blank values, as it only evaluates the denominator once. \ No newline at end of file diff --git a/content/localization/zh/DR001_zh.md b/content/localization/zh/DR001_zh.md new file mode 100644 index 00000000..188d8122 --- /dev/null +++ b/content/localization/zh/DR001_zh.md @@ -0,0 +1,58 @@ +--- +uid: DR001 +category: Code actions +sub-category: Readability +title: Convert to scalar predicate +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DR001` (Readability) **Convert to scalar predicate** + +## Description + +A column filter can be written more concisely as a scalar predicate, without explicitly using the [`FILTER`](https://dax.guide/FILTER) function. + +### Example 1 + +Change: + +```dax +CALCULATE( + [Invoice Amount], + FILTER(ALL('Document'[Document Type]), 'Document'[Document Type] = "Sales Order") +) +``` + +To: + +```dax +CALCULATE( + [Invoice Amount], + 'Document'[Document Type] = "Sales Order" +) +``` + +### Example 2 + +Change: + +```dax +CALCULATE( + [Invoice Amount], + FILTER(VALUES('Document'[Document Type]), 'Document'[Document Type] = "Sales Order") +) +``` + +To: + +```dax +CALCULATE( + [Invoice Amount], + KEEPFILTERS('Document'[Document Type] = "Sales Order") +) +``` + +## Why is Tabular Editor suggesting this? + +A scalar predicate is a simpler and more concise way (e.g. "syntax sugar") to express a column filter, compared to using the `FILTER` function explicitly. By using a scalar predicate, the code becomes easier to read and understand, as it removes unnecessary complexity and makes the intent of the filter expression more clear. \ No newline at end of file diff --git a/content/localization/zh/DR002_zh.md b/content/localization/zh/DR002_zh.md new file mode 100644 index 00000000..1cc27e87 --- /dev/null +++ b/content/localization/zh/DR002_zh.md @@ -0,0 +1,36 @@ +--- +uid: DR002 +category: Code actions +sub-category: Readability +title: Use aggregator instead of iterator +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DR002` (Readability) **Use aggregator instead of iterator** + +## Description + +Use an aggregator function instead of an iterator function when possible, to simplify the code. + +### Example + +Change: + +```dax +SUMX(Sales, Sales[Line Amount]) +``` + +To: + +```dax +SUM(Sales[Line Amount]) +``` + +## Why is Tabular Editor suggesting this? + +When you need to aggregate the values of a single column only, aggregator functions ([`SUM`](https://dax.guide), [`MIN`](https://dax.guide), [`MAX`](https://dax.guide), etc.) use simpler, more concise syntax, than their equivalent iterator functions ([`SUMX`](https://dax.guide), [`MINX`](https://dax.guide), [`MAXX`](https://dax.guide), etc.) and should be preferred to make the code more readable. + +## Related to: + +- [DR003 - Use VALUES instead of SUMMARIZE](xref:DR003) \ No newline at end of file diff --git a/content/localization/zh/DR003_zh.md b/content/localization/zh/DR003_zh.md new file mode 100644 index 00000000..63f2c47e --- /dev/null +++ b/content/localization/zh/DR003_zh.md @@ -0,0 +1,36 @@ +--- +uid: DR003 +category: Code actions +sub-category: Readability +title: Use VALUES instead of SUMMARIZE +author: Daniel Otykier +updated: 2025-01-06 +--- + +Code action `DR003` (Readability) **Use VALUES instead of SUMMARIZE** + +## Description + +When [`SUMMARIZE`](https://dax.guide/SUMMARIZE) only specifies a single column, and that column belongs to the table specified in the first argument, the code can be more concisely written using [`VALUES`](https://dax.guide/VALUES). + +### Example + +Change: + +```dax +SUMMARIZE(Sales, Sales[Product Key]) +``` + +To: + +```dax +VALUES(Sales[Product Key]) +``` + +## Why is Tabular Editor suggesting this? + +The `SUMMARIZE` function is a powerful function that can be used to group data and calculate aggregates. However, when you only need to retrieve the distinct values of a single column, the `VALUES` function is more concise and easier to read. By using the `VALUES` function, the code becomes more readable and the intent of the expression is clearer. + +## Related to: + +- [DR002 - Use aggregator instead of iterator](xref:DR002) \ No newline at end of file diff --git a/content/localization/zh/DR004_zh.md b/content/localization/zh/DR004_zh.md new file mode 100644 index 00000000..f1a7cb7f --- /dev/null +++ b/content/localization/zh/DR004_zh.md @@ -0,0 +1,48 @@ +--- +uid: DR004 +category: Code actions +sub-category: Readability +title: Prefix variable +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR004` (Readability) **Prefix variable** + +## Description + +It is recommended to use a consistent prefix for variables, to more easily distinguish them from table references. The default prefix is `_`, but you can configure which prefix to use, to match your preferred style, under **Tools > Preferences > DAX Editor > Code Actions**. + +### Example + +Change: + +```dax +VAR sales = SUM('Internet Sales'[Sales Amount]) +RETURN sales * 1.25; +``` + +To: + +```dax +VAR _sales = SUM('Internet Sales'[Sales Amount]) +RETURN _sales * 1.25; +``` + +## Why is Tabular Editor suggesting this? + +This code action is designed to improve the readability of your DAX code. By using a consistent naming convention for your variables, it is easier to understand the purpose of each variable, and to distinguish between variables and tables. + +Moreover, using a special character (such as an underscore) as a prefix for variables can help to avoid naming conflicts with table names, in case a table with the same name as the variable is added to the model in the future. + +## 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: + +- [DR005 - Prefix temporary column](xref:DR005) + +## Further reading: + +- [SQLBI: Naming variables in DAX](https://www.sqlbi.com/blog/marco/2019/01/15/naming-variables-in-dax/) \ No newline at end of file diff --git a/content/localization/zh/DR005_zh.md b/content/localization/zh/DR005_zh.md new file mode 100644 index 00000000..3741704e --- /dev/null +++ b/content/localization/zh/DR005_zh.md @@ -0,0 +1,50 @@ +--- +uid: DR005 +category: Code actions +sub-category: Readability +title: Prefix temporary column +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR005` (Readability) **Prefix temporary column** + +## Description + +It is recommended to use a consistent prefix for temporary columns, to more easily distinguish them from base columns or measures. The default prefix is `@` but you can configure which prefix to use, to match your preferred style, under **Tools > Preferences > DAX Editor > Code Actions**. + +### Example + +Change: + +```dax +ADDCOLUMNS( + 'Sales', + "Sales With Tax", 'Sales'[Sales Amount] * 1.25 +) +``` + +To: + +```dax +ADDCOLUMNS( + 'Sales', + "@Sales With Tax", 'Sales'[Sales Amount] * 1.25 +) +``` + +## Why is Tabular Editor suggesting this? + +This code action is designed to improve the readability of your DAX code. By using a consistent naming convention for your temporary columns, it is easier to understand the purpose of each column, and to distinguish between base columns, measures, and extension columns. + +## 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: + +- [DR004 - Prefix variable](xref:DR004) + +## Further reading: + +- [SQLBI: Naming temporary columns in DAX](https://www.sqlbi.com/articles/naming-temporary-columns-in-dax/) \ No newline at end of file diff --git a/content/localization/zh/DR006_zh.md b/content/localization/zh/DR006_zh.md new file mode 100644 index 00000000..ab5b8691 --- /dev/null +++ b/content/localization/zh/DR006_zh.md @@ -0,0 +1,48 @@ +--- +uid: DR006 +category: Code actions +sub-category: Readability +title: Move constant aggregation to variable +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR006` (Readability) **Move constant aggregation to variable** + +## Description + +When an aggregation function is used inside an iterator or a scalar predicate, the aggregation produces the same result for every row of the iteration, and therefore the aggregation could be moved to a DAX variable outside of the iteration. + +### Example + +Change: + +```dax +CALCULATE( + [Total Sales], + 'Date'[Date] = MAX('Date'[Date]) +) +``` + +To: + +```dax +VAR _maxDate = MAX('Date'[Date]) +RETURN + CALCULATE( + [Total Sales], + 'Date'[Date] = _maxDate + ) +``` + +## Why is Tabular Editor suggesting this? + +A common point of confusion for new DAX developers is the concept of row context and filter context. When an aggregation is used inside an iterator or a scalar predicate, the aggregation produces the same result for every row of the iteration. This is what enables syntax such as `'Date'[Date] = MAX('Date'[Date])`. While this syntax works and is efficient, it can be confusing to new developers - especially those with a SQL background, where this kind of syntax would be considered an error. + +Historically, variables were not supported in DAX, so the only way to achieve this kind syntax was to use the aggregation directly in the iterator. However, with the introduction of variables in DAX, it is now possible to move the aggregation to a variable outside of the iteration. This makes the code more readable and easier to understand for new developers. It also makes it easier to debug the code, as you can inspect the value of the variable outside of the iteration. + +## Remarks + +By default, Tabular Editor uses `_` as a prefix for variables. You can change the prefix under **Tools > Preferences > DAX Editor > Code Actions**. + +The name assigned to the variable is the concatenation of the aggregation function and the column name. If the variable name is not unique within the scope, a number is appended to make it unique. \ No newline at end of file diff --git a/content/localization/zh/DR007_zh.md b/content/localization/zh/DR007_zh.md new file mode 100644 index 00000000..49e33716 --- /dev/null +++ b/content/localization/zh/DR007_zh.md @@ -0,0 +1,38 @@ +--- +uid: DR007 +category: Code actions +sub-category: Readability +title: Simplify 1-variable block +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR007` (Readability) **Simplify 1-variable block** + +## Description + +A variable block with only one variable can be simplified by moving the expression directly into the `RETURN` part of the block. This assumes the variable is only referenced once without any context modifiers. + +### Example + +Change: + +```dax +VAR _sales = [Total Sales] +RETURN + _sales * 1.25 +``` + +To: + +```dax +[Total Sales] * 1.25 +``` + +## Why is Tabular Editor suggesting this? + +When variable declarations are sufficiently simple, and when the variable is used exactly once in the `RETURN` part of the code without any context modifications, there is no need to declare the variable at all. This makes the code more concise and easier to read. + +## Related to: + +- [DR008 - Simplify multi-variable block](xref:DR008) \ No newline at end of file diff --git a/content/localization/zh/DR008_zh.md b/content/localization/zh/DR008_zh.md new file mode 100644 index 00000000..16243251 --- /dev/null +++ b/content/localization/zh/DR008_zh.md @@ -0,0 +1,43 @@ +--- +uid: DR008 +category: Code actions +sub-category: Readability +title: Simplify multi-variable block +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR008` (Readability) **Simplify multi-variable block** + +## Description + +A variable block with multiple variables where each is a simple measure reference, which are only used once in the `RETURN` section without any context modifiers, should be simplified. + +### Example + +Change: + +```dax +VAR _sales = [Total Sales] +VAR _cost = [Total Cost] +RETURN + _sales - _cost +``` + +To: + +```dax +[Total Sales] - [Total Cost] +``` + +## Why is Tabular Editor suggesting this? + +A common pattern in DAX is to declare a variable for each measure that is used in a calculation. This is a good practice when the value of a measure is needed in multiple places in the calculation (for performance reasons). However, when each such variable is used exactly once in the `RETURN` part of the code, in an evaluation context that would not change the result of the measure, there is no need to declare the variables at all. Instead, referencing the measures directly in the calculation should be preferred to make the code more concise and easier to read. + +## Remarks: + +The [DAX Debugger in Tabular Editor 3](xref:dax-debugger) will show the values of measures used in the calculation within the **Locals** view. This makes it easy to inspect the values of the measures during debugging, even when their values are not stored in variables. + +## Related to: + +- [DR007 - Simplify 1-variable block](xref:DR007) \ No newline at end of file diff --git a/content/localization/zh/DR009_zh.md b/content/localization/zh/DR009_zh.md new file mode 100644 index 00000000..b77682b8 --- /dev/null +++ b/content/localization/zh/DR009_zh.md @@ -0,0 +1,33 @@ +--- +uid: DR009 +category: Code actions +sub-category: Readability +title: Rewrite using DISTINCTCOUNT +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR009` (Readability) **Rewrite using DISTINCTCOUNT** + +## Description + +Instead of using a combination of [`COUNTROWS`](https://dax.guide/COUNTROWS) and [`DISTINCT`](https://dax.guide/DISTINCT) to count the number of distinct values in a column, use the [`DISTINCTCOUNT`](https://dax.guide/DISTINCTCOUNT) function. + +### Example + +Change: + +```dax +COUNTROWS(DISTINCT(Sales[CalendarDate])) +``` + +```` + +To: +```dax +DISTINCTCOUNT(Sales[CalendarDate]) +```` + +## Why is Tabular Editor suggesting this? + +While both options produce the same result and the same query plan (i.e. identical performance), the `DISTINCTCOUNT` function is more concise and easier to read than the combination of `COUNTROWS` and `DISTINCT`. By using `DISTINCTCOUNT`, the code becomes more readable and the intent of the expression is clearer. \ No newline at end of file diff --git a/content/localization/zh/DR010_zh.md b/content/localization/zh/DR010_zh.md new file mode 100644 index 00000000..cbaf0069 --- /dev/null +++ b/content/localization/zh/DR010_zh.md @@ -0,0 +1,36 @@ +--- +uid: DR010 +category: Code actions +sub-category: Readability +title: Rewrite using COALESCE +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR010` (Readability) **Rewrite using COALESCE** + +## Description + +Instead of using [`IF`](https://dax.guide/IF) to return the first non-blank value from a list of expressions, use the [`COALESCE`](https://dax.guide/COALESCE) function. + +### Example + +Change: + +```dax +IF( + ISBLANK(Product[Long Description]), + Product[Short Description], + Product[Long Description] +) +``` + +To: + +```dax +COALESCE(Product[Long Description], Product[Short Description]) +``` + +## Why is Tabular Editor suggesting this? + +The `COALESCE` function is a more concise and easier to read way of returning the first non-blank value from a list of expressions. By using `COALESCE`, the code becomes more readable and the intent of the expression is clearer. \ No newline at end of file diff --git a/content/localization/zh/DR011_zh.md b/content/localization/zh/DR011_zh.md new file mode 100644 index 00000000..061a242d --- /dev/null +++ b/content/localization/zh/DR011_zh.md @@ -0,0 +1,48 @@ +--- +uid: DR011 +category: Code actions +sub-category: Readability +title: Rewrite using ISBLANK +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR011` (Readability) **Rewrite using ISBLANK** + +## Description + +Instead of comparing an expression with the value returned by [`BLANK()`](https://dax.guide/BLANK), use the [`ISBLANK`](https://dax.guide/ISBLANK) function. + +### Example + +Change: + +```dax +IF( + Document[Type] == BLANK(), + [Sales Amount], + [Sales Amount] * 1.25 +) +``` + +To: + +```dax +IF( + ISBLANK(Document[Type]), + [Sales Amount], + [Sales Amount] * 1.25 +) +``` + +## Why is Tabular Editor suggesting this? + +The `ISBLANK` function is a more concise and easier to read way of checking if an expression returns a blank value. By using `ISBLANK`, the code becomes more readable and the intent of the expression is clearer. + +## Remarks + +This code action only applies to [strict equality comparison (==)](https://dax.guide/op/strictly-equal-to/) with `BLANK()`. The regular equality comparison `Document[Type] = BLANK()` does not produce the same result as `ISBLANK(Document[Type])` if `[Type]` is an empty string, or zero (in which case `ISBLANK(Document[Type])` would return `FALSE` while `Document[Type] = BLANK()` would return `TRUE`). + +## Further reading + +- [SQLBI: Handling BLANK in DAX](https://www.sqlbi.com/articles/blank-handling-in-dax/) \ No newline at end of file diff --git a/content/localization/zh/DR012_zh.md b/content/localization/zh/DR012_zh.md new file mode 100644 index 00000000..40df35c4 --- /dev/null +++ b/content/localization/zh/DR012_zh.md @@ -0,0 +1,41 @@ +--- +uid: DR012 +category: Code actions +sub-category: Readability +title: Remove unnecessary BLANK +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR012` (Readability) **Remove unnecessary BLANK** + +## Description + +Some DAX functions, such as [`IF`](https://dax.guide/IF) and [`SWITCH`](https://dax.guide/SWITCH) already return [`BLANK()`](https://dax.guide/BLANK) when the condition is false, so there is no need to explicitly specify `BLANK()`. + +### Example + +Change: + +```dax +SWITCH( + Document[Type], + "Invoice", [Invoice Amount], + "Credit Note", [Credit Note Amount], + BLANK() +) +``` + +To: + +```dax +SWITCH( + Document[Type], + "Invoice", [Invoice Amount], + "Credit Note", [Credit Note Amount] +) +``` + +## Why is Tabular Editor suggesting this? + +The `BLANK()` function is redundant when used as the last argument in an `IF` or `SWITCH` function, as these functions already return `BLANK()` when the condition is false. By removing the `BLANK()` function, the code becomes more concise and easier to read. \ No newline at end of file diff --git a/content/localization/zh/DR013_zh.md b/content/localization/zh/DR013_zh.md new file mode 100644 index 00000000..2b6404dd --- /dev/null +++ b/content/localization/zh/DR013_zh.md @@ -0,0 +1,46 @@ +--- +uid: DR013 +category: Code actions +sub-category: Readability +title: Simplify negated logic +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR013` (Readability) **Simplify negated logic** + +## Description + +When a logical expression is negated, it is often more readable to rewrite the expression using the inverted operator. + +### Example 1 + +Change: + +```dax +NOT([Sales Amount] = [Budget Amount]) +``` + +To: + +```dax +[Sales Amount] <> [Budget Amount] +``` + +### Example 2 + +Change: + +```dax +NOT([Cost Amount] < [Sales Amount]) +``` + +To: + +```dax +[Cost Amount] >= [Sales Amount] +``` + +## Why is Tabular Editor suggesting this? + +Negated logic can be harder to read and understand than non-negated logic. By removing the negation (the [`NOT`](https://dax.guide/NOT) operator) and inverting the comparison operator, the code becomes more concise and easier to read. \ No newline at end of file diff --git a/content/localization/zh/DR014_zh.md b/content/localization/zh/DR014_zh.md new file mode 100644 index 00000000..9e5216ba --- /dev/null +++ b/content/localization/zh/DR014_zh.md @@ -0,0 +1,32 @@ +--- +uid: DR014 +category: Code actions +sub-category: Readability +title: Simplify using IN +author: Daniel Otykier +updated: 2025-01-09 +--- + +Code action `DR014` (Readability) **Simplify using IN** + +## Description + +Rewrite compound predicates (equality comparisons of the same expression that are combined using [`OR`](https://dax.guide/OR) or [`||`](https://dax.guide/op/or/)) with the [`IN`](https://dax.guide/IN) operator. + +### Example + +Change: + +```dax +IF(Document[Type] = "Invoice" || Document[Type] = "Credit Note", 1, 0) +``` + +To: + +```dax +IF(Document[Type] IN {"Invoice", "Credit Note"}, 1, 0) +``` + +## Why is Tabular Editor suggesting this? + +The `IN` operator is more concise and easier to read than multiple `||` operators or `OR` function calls. It also makes it easier to add or remove values from the list of values to compare against. \ No newline at end of file diff --git a/content/localization/zh/FAQ_zh.md b/content/localization/zh/FAQ_zh.md new file mode 100644 index 00000000..b2da1fda --- /dev/null +++ b/content/localization/zh/FAQ_zh.md @@ -0,0 +1,21 @@ +# Frequently Asked Questions + +## What is Tabular Editor? + +Essentially, Tabular Editor provides a UI for editing the metadata making up an Analysis Services Tabular Model. The main difference between using Tabular Editor for editing a model versus using Visual Studio, is that Tabular Editor does not load any _data_ - only _metadata_. This means that no validations or calculations are performed when you create and modify measures, display folders, etc. Validations and calculations are performed only when the user chooses to persist the changes to the database. This provides a better developer experience for medium to large sized models, which tend to be slow to work with in Visual Studio. + +Additionally, Tabular Editor has a lot of [features](Features-at-a-glance.md) that will generally boost your productivity and make certain tasks easier. + +## Why do we need yet another tool for SSAS Tabular? + +Working with Analysis Services Tabular, you may already be familiar with SQL Server Data Tools (Visual Studio), [DAX Editor](https://www.sqlbi.com/tools/dax-editor/), [DAX Studio](https://www.sqlbi.com/tools/dax-studio/), [BISM Normalizer](http://bism-normalizer.com/) and [BIDSHelper](https://bidshelper.codeplex.com/). These are all excellent tools, each with their own purposes. Tabular Editor is not intended to replace any of these tools, but should rather be seen as a supplement to them. Please view the [Features at a glance](Features-at-a-glance.md) article, to see why Tabular Editor is justified. + +## Why isn't Tabular Editor available as a plug-in for Visual Studio? + +While a better user experience for working with Tabular Models inside Visual Studio would definitely be appreciated, a stand-alone tool provides some benefits over a plug-in: First of all, you **don't need a Visual Studio/SSDT installation to use Tabular Editor**. Tabular Editor only requires the AMO libraries, which is quite a small installation compared to VS. Secondly, TabularEditor.exe can be executed with command-line options for deployment, scripting, etc., which would not be possible in a .vsix (plug-in) project. + +Also worth mentioning: Tabular Editor can be downloaded as a [standalone .zip file](https://github.com/TabularEditor/TabularEditor/releases/latest/download/TabularEditor.Portable.zip), meaning you do not need to install anything. In other words, you can run Tabular Editor without having admin rights on your Windows machine. Simply download the zip file, extract it, and run TabularEditor.exe. + +## What features are planned for upcoming releases? + +You can view the current roadmap [here](Roadmap.md). diff --git a/content/localization/zh/Features-at-a-glance_zh.md b/content/localization/zh/Features-at-a-glance_zh.md new file mode 100644 index 00000000..febd7ca2 --- /dev/null +++ b/content/localization/zh/Features-at-a-glance_zh.md @@ -0,0 +1,90 @@ +# Basic Features + +The following article will give you a quick overview of the most important features of Tabular Editor. + +## Load/save Model.bim files + +Hitting CTRL+O shows an Open File dialog, which lets you select a Model.bim file to load in Tabular Editor. The file must be of Compatibility Level 1200 or newer (JSON format). CTRL+S saves any changes you make in Tabular Editor back to the file (we recommend backing up your Model.bim files before using Tabular Editor). If you want to deploy the loaded model to an Analysis Services server instance, see [Deployment](/te2/Features-at-a-glance#deployment) below. + +## Connect/deploy to SSAS Tabular Databases + +Hitting CTRL+SHIFT+O lets you open a Tabular Model directly from a Tabular Database that has already been deployed. Enter the server address and (optionally) provide a username and password. After hitting "OK", you will be prompted with a list of databases and the server. Select the one you want to load, and click "OK" again. + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Connect.png) + +The dialog shown also lets you connect to Azure Analysis Services instances, if you provide the full name of the Azure AS instance, starting with "azureas://". The "Local Instance" dropdown, may be used to browse and connect to any running instances of Power BI Desktop or Visual Studio Integrated Workspaces. **Note that although Tabular Editor can make changes to a Power BI model through the TOM, this is not supported by Microsoft and may corrupt your .pbix file. Proceed at your own risk!** + +Any time you press CTRL+S after the database has been loaded, the database will be updated with any changes you've made in Tabular Editor. Client tools (Excel, Power BI, DAX Studio, etc.) should be able to immediately view the changes in the database after this. Note that you may need to manually recalculate objects in the model, depending on the changes made, to successfully query the model. + +If you want to save the connected model to a Model.bim file, choose "Save As..." from the "File" menu. + +## Deployment + +If you want to deploy the currently loaded model to a new database, or overwrite an existing database with the model changes (for example when loading from a Model.bim file), use the Deployment Wizard under "Model" > "Deploy...". The wizard will guide you through the deployment process, and allow you to choose which areas of the model to deploy. More information can be found [here](/te2/Advanced-features#deployment-wizard). + +## Hierarchical display + +Objects of the loaded model are shown in the Explorer Tree, on the left side of the screen. By default, all object types (visible tables, roles, relationships, etc.) are shown. If you only want to see tables, measures, columns and hierarchies, go to the "View" menu and toggle off "Show all object types". + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/AllObjectTypes.png) + +Expanding a table in the "Tables" group, you will find the measures, columns and hierarchies contained in the table presented in their respective display folders by default. This way, objects are arranged similar to how end-users would see them in client tools: + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/DisplayFolders.png) + +Use the buttons immediately above the Explorer Tree, to toggle invisible objects, display folders, measures, columns and hierarchies, or to filter objects by name. You can rename an object by selecting it in then hitting F2. This also works for display folders. If you double-click a measure or calculated column, you may edit its [DAX expression](/te2/Advanced-features#dax-expression-editor). Right-clicking will show a context menu, providing a range of handy shortcuts for operations such as setting visibility, perspective inclusion, adding columns to a hierarchy, etc. + +## Editing properties + +The Property Grid on the lower right side of the screen, shows most of the properties for the object(s) selected in the Explorer Tree. If you select multiple objects at once, the Property Grid lets you simultaneously edit properties for the selected objects. This is useful for example when setting the Format String property. Examples of properties you can set through the Property Grid: + +- Name (you can rename objects directly in the Explorer Tree by hitting F2) +- Description +- Display Folder (can also be renamed directly in the Explorer Tree, also [drag/drop](/te2/Features-at-a-glance#drag-and-drop-objects)) +- Hidden (can be set for multiple objects through the right-click context menu in the Explorer Tree) +- Format String + +Different properties exist, depending on what kind of object was selected. + +## Duplicate objects and batch renamings + +The right-click context menu in the Explorer Tree lets you duplicate measures and columns. The duplicated objects will have their names suffixed by "copy". Furthermore, you can perform batch renames by selecting multiple objects and right-clicking in the Explorer Tree. + +![](https://github.com/TabularEditor/TabularEditor/blob/master/Documentation/BatchRename.png) + +You may use RegEx for your renamings, and optionally choose whether translations should be renamed as well. + +## Drag and drop objects + +By far the most useful feature of Tabular Editor, when working on models with many measures/columns organised in display folders. Check out the animation below: + +![](https://github.com/TabularEditor/TabularEditor/blob/master/Documentation/DragDropFolders.gif) + +Notice how the display folder property of every single object below the folder is changed, when the entire folder is dragged. No more going over measures/columns one-by-one, to change the display folder structure. What you see is what you get. + +(This works with translations too!) + +## Working with Perspectives and Translations + +You can add/edit existing perspectives and translations (cultures), by clicking the Model node in the Explorer Tree, and locating the relevant properties at the bottom of the property grid. Alternatively, when your Explorer Tree is [showing all object types](/te2/Features-at-a-glance#hierarchical-display), you can view and edit perspectives, cultures and roles directly in the tree. + +![](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/RolesPerspectivesTranslations.png) + +You can duplicate an existing perspective, role or translation by opening the right-click menu and choose "Duplicate". This will create an exact copy of the object, which you can then modify to your needs. + +To view perspectives and/or translations "in action", use the two dropdown lists in the toolbar near the top of the screen. Choosing a perspective will hide all objects that are not included in that perspective, while choosing a translation will show all objects in the tree using the translated names and display folders. When hitting F2 to change the names of objects/display folders or when dragging objects around in the tree, the changes will only apply to the selected translation. + +## Perspectives/Translations within object context + +When one or more objects are selected in the tree, you will find 4 special property collections within the Property Grid: + +- **Captions**, **Descriptions** and **Display Folders** shows a list of all cultures in the model, with the translated names, descripions and display folders respectively of the selected objects for each culture. +- **Perspectives** shows a list of all perspectives in the model, with an indication of whether or nor the selected objects belong to each perspective. + +You can use these collections in the Property Grid to change the translations and perspective inclusions for one or more objects at at time. + +## Undo/Redo support + +Any change you make in Tabular Editor can be undone using CTRL+Z and subsequently redone using CTRL+Y. There is no limit to the number of operations that can be undone, but the stack is reset when you open a Model.bim file or load a model from a database. + +When deleting objects from the model, all translations, perspectives and relationships that reference the deleted objects are also automatically deleted (where as Visual Studio normally shows an error message that the object cannot be deleted). If you make a mistake, you can use the Undo functionality to restore the deleted object, which will also restore any translations, perspectives or relationships that were deleted. Note that even though Tabular Editor can detect DAX formula dependencies, Tabular Editor will not warn you in case you delete a measure or column which is used in the DAX expression of another measure or calculated column. diff --git a/content/localization/zh/FormatDax_zh.md b/content/localization/zh/FormatDax_zh.md new file mode 100644 index 00000000..1dedadba --- /dev/null +++ b/content/localization/zh/FormatDax_zh.md @@ -0,0 +1,62 @@ +# FormatDax deprecation + +The `FormatDax` method (which is one of the available [helper methods](/Advanced-Scripting.md#helper-methods) in Tabular Editor) has been deprecated with the release of Tabular Editor 2.13.0. + +The reason for the deprecation is that the web service at https://www.daxformatter.com/ was starting to experience a heavy load of multiple request in quick succession, which were causing issues at their end. This is because the `FormatDax` method performs a web request each time it is called in a script, and many people have been using scripts such as the following: + +**Don't do this!** + +```csharp +foreach(var m in Model.AllMeasures) +{ + // DON'T DO THIS + m.Expression = FormatDax(m.Expression); +} +``` + +This is fine for small models with a few tens of measures, but the traffic on www.daxformatter.com indicates that a script such as the above is being executed across multiple models with thousands of measures, even several times per day! + +To address this issue, Tabular Editor 2.13.0 will show a warning when `FormatDax` is called more than three times in a row, using the syntax above. In addition, subsequent calls will be throttled with a 5 second delay between each call. + +## Alternative syntax + +Tabular Editor 2.13.0 introduces two different ways of calling FormatDax. The above script can be rewritten into either of the following: + +```csharp +foreach(var m in Model.AllMeasures) +{ + m.FormatDax(); +} +``` + +...or simply...: + +```csharp +Model.AllMeasures.FormatDax(); +``` + +Both these approaches will batch all www.daxformatter.com calls into a single request. You may also use the global method syntax if you prefer: + +```csharp +foreach(var m in Model.AllMeasures) +{ + FormatDax(m); +} +``` + +...or simply...: + +```csharp +FormatDax(Model.AllMeasures); +``` + +## More details + +Technically, `FormatDax` has now been implemented as two overloaded extension methods: + +1. `void FormatDax(this IDaxDependantObject obj)` +2. `void FormatDax(this IEnumerable objects, bool shortFormat = false, bool? skipSpaceAfterFunctionName = null)` + +Overload #1 above will queue the provided object for formatting when script execution completes, or when a call is made to the new `void CallDaxFormatter()` method. Overload #2 will immediately call www.daxformatter.com with a single web request that will format all DAX expressions for all the objects provided in the enumerable. You may use either of these methods as you see fit. + +Note that the new method does not take any string arguments. It considers all DAX properties on the provided object for formatting (for measures, this is the Expression and DetailRowsExpression properties, for KPIs, this is the StatusExpression, TargetExpression and TrendExpression, etc.). diff --git a/content/localization/zh/Getting-Started_zh.md b/content/localization/zh/Getting-Started_zh.md new file mode 100644 index 00000000..a889f917 --- /dev/null +++ b/content/localization/zh/Getting-Started_zh.md @@ -0,0 +1,109 @@ +--- +uid: getting-started-te2 +title: Getting Started +author: Daniel Otykier +updated: 2021-09-21 +--- + +# Getting Started + +## Installation + +Simply download the .msi file from the [Release page](https://github.com/TabularEditor/TabularEditor/releases/latest) and run the .msi installation. + +## Prerequisites + +None. + +> [!NOTE] +> Tabular Editor uses the [Tabular Object Model](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) to load and save metadata to and from Model.bim files or existing databases. This is included in the .msi installer. Visit the official Microsoft documentation for [Analysis Services Client Libraries](https://docs.microsoft.com/en-us/azure/analysis-services/analysis-services-data-providers). + +## System requirements + +- **Operating system:** Windows 7, Windows 8, Windows 10, Windows Server 2016, Windows Server 2019 or newer +- **.NET Framework:** [4.6](https://dotnet.microsoft.com/download/dotnet-framework) + +## Working with Tabular Editor + +The recommended workflow is to set up the tables and relationships using SSDT as normal, and then use Tabular Editor to do the rest. That is: Create calculated columns, measures, hierarchies, perspectives, translations, display folders, and every other kind of fine-tuning you can think of. + +Load a Model.bim file by choosing the Open > From File... option in the File menu (CTRL+O), or open an existing database from an instance of Analysis Services by choosing the Open > From DB... option. In the latter case, you will be prompted for a server name and optional credentials: + +![Connecting to an already deployed Tabular Model](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Connect.png) + +This also works with the new Azure Analysis Services PaaS. The "Local Instance" dropdown, may be used to browse and connect to any running instances of Power BI Desktop or Visual Studio Integrated Workspaces. **Note that although Tabular Editor can make changes to a Power BI model through the TOM, not all modeling operations are supported by Microsoft. [More information](/te2/Power-BI-Desktop-Integration.html)** + +After clicking "OK", you will be presented with a list of databases on the server. + +This is how the UI looks after a model has been loaded into Tabular Editor: + +![The main UI of Tabular Editor](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Main%20UI.png) + +The tree on the left side of the screen, displays all tables in the Tabular Model. Expanding a table will show all columns, measures and hierarchies within the table, grouped by their Display Folders. Use the buttons just above the tree, to toggle display folders, hidden objects, certain types of objects, or filter out objects by names. Right-clicking anywhere in the tree, will bring up a context menu with common actions, such as adding new measures, making an object hidden, duplicating objects, deleting objects, etc. Hit F2 to rename the currently selected object or multiselect and right-click to batch rename multiple objects. + +![Batch Renaming lets you rename multiple objects simultaneously](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/BatchRename.png) + +On the top right side of the main UI, you see the DAX Editor, which may be used to edit the DAX expression of any measure or calculated column in the model. Click the "DAX Formatter" button to automatically format the code through www.daxformatter.com. + +Use the property grid in the lower right corner, to examine and set properties of objects, such as Format String, Description along with translations and perspective memberships. You can also set the Display Folder property here, but it's easier to simply drag and drop objects within the tree to update their Display Folder (try selecting multiple objects using CTRL or SHIFT). + +To edit perspectives or translations (cultures), select the "Model" object in the tree, and locate the "Model Perspectives" or "Model Cultures" properties, in the property grid. Click the small elipsis button to open a collection editor for adding/removing/editing perspectives/cultures. + +![Editing perspectives - click the elipsis button to the right](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Edit%20Perspectives.png) + +To save your changes back to the Model.bim file, click the save button or hit CTRL+S. If you opened an existing Tabular Database, the changes are saved directly back to the database. You will be prompted if the database was changed since you loaded it into Tabular Editor. You can always undo your changes by pressing CTRL+Z. + +If you want to deploy your model to another location, go to the "Model" menu and choose "Deploy". + +## Deployment + +Tabular Editor comes with a deployment wizard that provides a few benefits compared to deploying from SSDT - especially when deploying to an existing database. After choosing a server and a database to deploy to, you have the following options for the deployment at hand: + +![Deployment Wizard](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/Deployment.png) + +Leaving the "Deploy Connections" box unchecked, will make sure that all the data sources on the target database stay untouched. You will get an error if your model contains one or more tables with a data source, that does not already exist in the target database. + +Similarly, leaving out "Deploy Table Partitions", will make sure that existing partitions on your tables are not changed, leaving the data in the partitions intact. + +When the "Deploy Roles" box is checked, the roles in the target database will be updated to reflect what you have in the loaded model, however if the "Deploy Role Members" is unchecked, the members of each role will be unchanged in the target database. + +## Command Line usage + +You can use the command line for automated deployment. All deployment options that are available through the GUI, are also available through the command line. + +### Deployment Examples + +`TabularEditor.exe c:\Projects\Model.bim` + +Opens the Tabular Editor GUI and loads the specified Model.bim file (without deploying anything). + +`TabularEditor.exe c:\Projects\Model.bim -deploy localhost AdventureWorks` + +Deploys the specified Model.bim file to the SSAS instance running on localhost, overwriting or creating the AdventureWorks database. The GUI will not be loaded. + +By default, partitions, data sources and roles will not be overwritten in the target database. This behaviour can be changed by adding one or more of the following switches to the command above: + +- `-P` Overwrite **p**artitions +- `-C` Overwrite **c**onnections (data sources) +- `-R` Overwrite **r**oles +- `-M` Overwrite role **m**embers + +More information on command-line options can be found [here](/te2/Command-line-Options.html). + +> [!NOTE] +> Since TabularEditor.exe is a Windows Forms application, running it from the command line will execute the application in a different thread, returning control to the caller immediately. This may cause issues when running deployments as part of a batch job where you need to await succesful deployment before proceeding with the job. If you experience these issues, use `start /wait` to let TabularEditor finish its job before returning control to the caller: +> +> `start /wait TabularEditor.exe c:\Projects\Model.bim -deploy localhost AdventureWorks` + +## Advanced Scripting + +Tabular Editor lets you use C# to script changes to the loaded model. This is practical when you want to apply several changes to many objects at once. The Advanced Script editor has access to two objects: + +- `Selected` which represents all objects that are currently selected in the explorer tree. +- `Model` which represents the entire Tabular Object Model tree. + +The Advanced Script editor has some limited IntelliSense functionality to get you started: + +![IntelliSense helps you create scripts for Tabular Editor](https://raw.githubusercontent.com/TabularEditor/TabularEditor/master/Documentation/AdvancedEditor%20intellisense.png) + +More documentation and examples on Advanced Scripting, can be [found here](/te2/Advanced-Scripting.html). diff --git a/content/localization/zh/Importing-Tables_zh.md b/content/localization/zh/Importing-Tables_zh.md new file mode 100644 index 00000000..d279fe06 --- /dev/null +++ b/content/localization/zh/Importing-Tables_zh.md @@ -0,0 +1,151 @@ +--- +uid: importing-tables-te2 +title: Importing Tables +author: Daniel Otykier +updated: 2020-05-03 +--- + +'# Importing Tables + +If you already have a Legacy Data Source in your model, you can right click it, and choose "Import Tables...". Tabular Editor will attempt to connect using the data provider and credentials specified in the Data Source. If successful, you should get a list of all the databases, tables and views accessible through the Data Source: + +![image](https://user-images.githubusercontent.com/8976200/49701892-35ea3900-fbf2-11e8-951a-8858179426c6.png) + +Clicking a table or view on the left-hand side will display a preview of the data on the right. You can deselect columns that you do not want to include, although [the data import best practice](https://www.sqlbi.com/articles/data-import-best-practices-in-power-bi/) suggests to always use views, and include only columns in those views that are needed in the Tabular Model. The UI will show you the resulting SQL query. By default, Tabular Editor will import a table/view using `SELECT * FROM ...`, but if you toggle any column in the preview, the resulting query will include an explicit list of columns. To switch back to `SELECT * FROM ...`, toggle the "Select all columns" checkbox in the upper right corner. + +You can select multiple tables/views to import at once. When you click "Import", all selected tables/views will be imported as new tables with all columns populated from the metadata. A single partition will be created on each table, holding the resulting SQL query from the UI. + +That's it! No more going back and forth between Tabular Editor and SSDT. + +## A note on Legacy vs. Structured Data Sources + +As there is currently no way for Tabular Editor to infer the metadata returned from M (Power Query) expressions, this UI only supports Legacy (aka. Provider) Data Sources. If you must use Structured Data Sources, you can still use a temporary Legacy connection to import the table schema initially (assuming your data source can be accessed through SQL, OLE DB or ODBC), and then manually switch the partitions on the imported tables, to use the Structured Data Sources. If you are importing data from "exotic" data sources, such as web services, Azure Data Lake Storage, etc. schema metadata can not be imported automatically, but [there is an option for providing the metadata information through the clipboard](/Importing-Tables#power-query-data-sources). + +In general, though, it is recommended to always use a Legacy connection for the following types of sources: + +- SQL Server databases +- Azure SQL Databases +- Azure SQL Data Warehouse +- Azure Databricks (through ODBC) +- Any relational OLEDB data source +- Any relational ODBC source + +For authentication using Azure Active Directory with MFA, please see here. + +## Importing without a pre-existing Data Source + +If your model does not yet contain any data sources, you can import tables by going to the "Model" menu and clicking "Import Tables...". The resulting UI looks like this: + +![image](https://user-images.githubusercontent.com/8976200/49702141-74cdbe00-fbf5-11e8-8a88-5bc2a0a6c80d.png) + +Leaving the selection at "Create a new Data Source and add it to the model" will display the Connection Dialog UI when clicking "Next". This dialog lets you specify the connection details: + +![image](https://user-images.githubusercontent.com/8976200/49702167-a5adf300-fbf5-11e8-8d06-d6670ad456d4.png) + +When clicking "OK", a (Legacy) Data Source using the specified connection will be created in your model, and you will be taken to the import page shown above. + +The next option on the list, "Use a temporary connection", will not cause a new Data Source to be added to the model. This means that you are responsible for assigning a Data Source to the partitions of the newly imported table, before deploying the model. + +The last option, "Manually import metadata from another application", is used when you want to import a new table based on a list of column metadata. This is useful for Structured (Power Query) Data Sources, [see below](/Importing-Tables#power-query-data-sources). + +## SQL capabilities + +For non-SQL Server data sources (or more precisely, data sources that do not use the Native SQL Client driver), please pay attention to the two dropdown-boxes near the bottom of the screen: + +![image](https://user-images.githubusercontent.com/8976200/51613859-b952b600-1f24-11e9-8fd7-7c5269aaab26.png) + +The "Reduce rows using"-dropdown lets you specify which row reduction clause to use, when querying the source for preview data, since the Table Import Wizard will only retrieve 200 rows of data from the source table or view. You can choose between the most common row reduction clauses, such as "TOP", "LIMIT", "FETCH FIRST", etc. + +The "Identifier quotes"-dropdown lets you specify how object names (column, tables) should be quoted in the generated SQL statements. This applies to both the data preview, as well as the SQL statement used in the table partition query, when the table is imported to the tabular model. By default, square brackets are used, but this can be changed to other common types of identifier quotes. + +## Changing the source of a table + +Another way to bring up the import page, is to right-click on an existing table (that uses a Legacy Data Source), and choose "Select Columns...". If that table was previously imported using the UI, the import page should show up with the source table/view and imported columns pre-selected. You may add/remove columns or even choose an entirely different table to be imported in place of the table you selected in your model. Keep in mind that any columns in your table, that were deselected or no longer exists in your source table/view will be removed from your model. You can always undo operations such as this using CTRL+Z. + +## Refreshing Table Metadata + +As of version 2.8, Tabular Editor has a new UI feature that lets you easily check for schema drift. That is, detecting columns that had their data type changed, or were added or removed to source tables and views. This check may be invoked at the Model level (again, this only applies to Legacy Data Sources), at the Data Source level, at the Table level or at the Partition level. This is done by right-clicking the object and choosing "Refresh Table Metadata..." + +![image](https://user-images.githubusercontent.com/8976200/49702346-7e582580-fbf7-11e8-9a62-04c6963179e5.png) + +Changes are detected based on the "Source Column" and "Data Type" properties of all data columns on the respective tables. If any changes are detected, Tabular Editor will display the above UI, detailing the changes. You may deselect changes that you do not want to apply to your model, although keep in mind that some changes may cause processing errors (for example, source columns that do not exist in the source table/view/query). + +This mechanism (as well as the Import Table UI) uses the FormatOnly-flag, when querying the metadata from the source. This means that you can have table partitions that use Stored Procedures. The FormatOnly-flag ensures that the Stored Proc is never executed directly. Instead, static analysis is performed by the server, in order to return only metadata describing the result set that would be returned from the Stored Proc upon execution. Depending on your RDBMS, there may be some limitations of the FormatOnly-flag when used with Stored Procedures. For more information on this topic when using SQL Server as a data source, please see [this article](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql?view=sql-server-2017#remarks). + +### CLI support + +You can perform a schema check at the model level from the command line by using the `-SC` flag. Note that the schema check, when executed through the CLI, will only report mapping issues. It will not make any changes to your model. This is useful if you're using Tabular Editor within CI/CD pipelines, as mapping issues could potentially cause problems after deploying your model to a test/production environment. + +### Ignoring objects + +As of Tabular Editor 2.9.8, you can exclude objects from schema checks / metadata refresh. This is controlled by setting an annotation on the objects that you wish to leave out. As the annotation name, use the codes listed below. You can leave the annotation value blank or set it to "1", "true" or "yes". Setting the annotation value to "0", "false" or "no" will effectively disable the annotation, as if it didn't exist: + +**Table flags:** + +- `TabularEditor_SkipSchemaCheck`: Causes Tabular Editor to completely skip a schema check on this table. +- `TabularEditor_IgnoreSourceColumnAdded`: Tabular Editor will ignore additional columns that are not mapped to any table columns on this table. +- `TabularEditor_IgnoreDataTypeChange`: Tabular Editor will ignore mismatched data types on any column of the table. +- `TabularEditor_IgnoreMissingSourceColumn`: Tabular Editor will ignore imported columns where the source column apparently does not exist in the source. + +**Column flags:** + +- `TabularEditor_IgnoreDataTypeChange`: Tabular Editor will ignore mismatched data type on this specific column. +- `TabularEditor_IgnoreMissingSourceColumn`: Tabular Editor will ignore an apparently missing source column for this specific column. + +The flags impact schema checking through both the UI and the CLI. + +### Treating warnings as errors + +By default, the CLI will report an error when a partition query could not be executed, or when the imported table contains a column that does not match any column in the source query. The CLI will report a warning when a column's data type does not match the column in the source query, or if the source query contains columns that are not mapped to any columns in the imported table. The CLI will also report a warning when source queries of different partitions on the same table, do not return the same columns. + +Starting with Tabular Editor version 2.14.1, you can change the behaviour of the CLI such that all warnings as listed above are reported as errors. To do this, add the following annotation at the **model** level: + +- `TabularEditor_SchemaCheckNoWarnings`: Causes Tabular Editor to treat all schema check warnings as errors. + +## Azure Active Directory with MFA + +If you want to import tables from an Azure SQL Database or Azure Synapse SQL pool, you will likely need Azure Active Directory multi-factor authentication. Unfortunately, this is not supported by the SQL Native Client provider used in .NET Framework. Instead, use the MSOLEDBSQL provider (which also has the benefit that it is generally faster than the native client, when Analysis Services reads data from the table). Make sure you have the [latest (x86) version](https://docs.microsoft.com/en-us/sql/connect/oledb/download-oledb-driver-for-sql-server?view=sql-server-ver15) of this driver installed, to make this work on your local machine. + +Here are step by step instructions to set up the data source to work with MFA: + +1. Create a new legacy data source and add it to your model. Model > New Data Source (Legacy) +2. Specify `System.Data.OleDb` as the Provider property and use a connection string that looks as follows, substituting the correct server, database and user names: + +### For Synapse SQL pools: + +``` +Provider=MSOLEDBSQL;Data Source=-ondemand.sql.azuresynapse.net;User ID=daniel@adventureworks.com;Database=;Authentication=ActiveDirectoryInteractive +``` + +### For Azure SQL databases: + +``` +Provider=MSOLEDBSQL;Data Source=.database.windows.net;User ID=daniel@adventureworks.com;Database=;Authentication=ActiveDirectoryInteractive +``` + +3. To import tables from this source, right-click on the data source and choose "Import Tables...", the Import Table Wizard UI should appear showing a list of tables/views from the source. Note, that for Synapse SQL pools, you may have to specify "TOP (without NOLOCK)" as a row clause, in order for the data preview to work. +4. When deploying your model to Analysis Services, you will most likely need to specify other credentials, such as a Service Principal application ID and secret or a SQL account, in order for Analysis Services to authenticate itself against the source when refreshing table data. This can be specified using TMSL or SSMS post-deployment, or you can set this up as [part of your CI/CD deployment pipeline](https://tabulareditor.com/2020/06/20/DevOps5.html#creating-your-first-release-pipeline). + +## Manually importing schema/metadata + +If you're using a data source not supported by the Import Tables Wizard, you have the option of manually importing metadata. This option provides a UI where you can enter or paste in a table schema on the left hand side, which will be automatically parsed for column name and data type information. Alternatively, you can manually type each column name on the right hand side and choose a data type in the drop down. Either way, this is faster than manually creating a table and adding individual data columns through the main UI. When you're done, hit "Import!", adjust the table name and partition expression. + +When parsing the text on the left hand side, Tabular Editor searches for certain keywords, in order to determine how the information is structured. It's pretty liberal in the way it interprets data, so you can, for example, paste in a list of columns from a CREATE TABLE SQL script, or the output of the Power Query `Table.Schema(...)` function as described below. The only requirements is that each line of text represents one column of source data. + +![image](https://user-images.githubusercontent.com/8976200/70419758-6f07f400-1a66-11ea-838d-9a587c8021ca.png) + +## Power Query data sources + +Since there is no officially supported way to execute or validate a Power Query/M expression, Tabular Editor only has limited support for Power Query data sources. As of 2.9.0, you may use the "Manually import metadata from another application"-option of the Import Table Wizard, as described above, to import a schema from a Power Query query in Excel or Power BI Desktop. The workflow is the following: + +- First, make sure your model contains a Power Query Data Source. Right-click Data Sources > New Data Source (Power Query). If you're going to load data from a SQL Server, specify "tds" as the protocol and fill out the Database, Server and AuthenticationKind properties. + ![image](https://user-images.githubusercontent.com/8976200/70418811-6dd5c780-1a64-11ea-8332-d074c6b2d5c2.png) +- For other types of data sources, it may be easier to create the initial model and first few tables in SSDT, to figure out how the Data Source should be configured, and then use the technique below only when adding additional tables. +- Use Power Query within Excel or Power BI Desktop to connect to your source data and apply any transformations needed. +- Using Power Query's Advanced Editor, add a step that uses the `Table.Schema(...)` [M function](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the previous output: + ![image](https://user-images.githubusercontent.com/8976200/70416018-5562ae80-1a5e-11ea-8962-529304ce83f0.png) +- Select the full output preview, copy it into the clipboard (CTRL+A, CTRL+C) and paste it into the schema/metadata textbox in the Import Tables Wizard: + ![image](https://user-images.githubusercontent.com/8976200/70416817-2e0ce100-1a60-11ea-9e2b-430cecf88d0a.png) +- Click "Import!" and provide a proper name for your table. +- Lastly, paste the original M expression you used in Excel/Power BI, from before you modified it with the `Table.Schema(...)` function, into the partition on the newly created table. Modify the M expression to point to the source you specified in the first step: + ![image](https://user-images.githubusercontent.com/8976200/70418985-dae95d00-1a64-11ea-8bfb-8dda16c33742.png) diff --git a/content/localization/zh/Keyboard-Shortcuts_zh.md b/content/localization/zh/Keyboard-Shortcuts_zh.md new file mode 100644 index 00000000..8fae7189 --- /dev/null +++ b/content/localization/zh/Keyboard-Shortcuts_zh.md @@ -0,0 +1,64 @@ +# Keyboard Shortcuts + +As of version 2.7.3, Tabular Editor now supports the following keyboard shortcuts: + +| General | Shortcut | +| ---------------------------------------------------------- | ------------------------------------ | +| New model | Ctrl+N | +| Load model from a file | Ctrl+O | +| Load model from a database | Ctrl+Shift+O | +| Save model | Ctrl+S | +| Copy selection | Ctrl+C | +| Cut selection | Ctrl+X | +| Paste | Ctrl+V | +| Undo | Ctrl+Z | +| Redo | Ctrl+Y | +| Select All | Ctrl+A | +| ~Launch Deployment Wizard~ | ~F6~ | +| Launch Best Practice Analyzer | F10 | + +| Expression Editor | Shortcut | +| ------------------------------------------- | --------------- | +| Find | Ctrl+F | +| Find and replace | Ctrl+H | +| Go to definition | F12 | +| Navigate back | Alt+Left arrow | +| Navigate forward | Alt+Right arrow | +| Format DAX | F6 | +| Format DAX (Short lines) | Ctrl+F6 | +| Comment lines | Ctrl+Shift+C | +| Uncomment lines | Ctrl+Shift+U | + +| Script Editor | Shortcut | +| ---------------- | -------- | +| Find | Ctrl+F | +| Find and replace | Ctrl+H | +| Run script | F5 | + +| Explorer tree | Shortcut | +| ----------------------------------------------- | ----------------------------- | +| Navigate up or down | Up / Down arrow | +| Expand / collapse current node | Right / Left arrow | +| Expand / collapse current node and all subnodes | Ctrl+Right / Left arrow | +| Expand / collapse entire tree | Ctrl+Shift+Right / Left arrow | +| Toggle measures | Ctrl+1 | +| Toggle columns | Ctrl+2 | +| Toggle hierarchies | Ctrl+3 | +| Toggle display folders | Ctrl+4 | +| Toggle hidden objects | Ctrl+5 | +| Toggle Metadata Columns | Ctrl+F1 | +| Toggle Alphabetical Ordering | Ctrl+F2 | +| Toggle all object types | Ctrl+F3 | +| Filter | Ctrl+F | +| Toggle filter | Ctrl+Shift+F | +| Edit Expression | Enter | +| Navigate back | Alt+Left arrow | +| Navigate forward | Alt+Right arrow | +| Show dependencies | F3 | +| Make invisible | Ctrl+I | +| Make visible | Ctrl+U | +| Create new measure | Alt+1 | +| Create new calculated column | Alt+2 | +| Create new hierarchy | Alt+3 | +| Create new data column | Alt+4 | +| Create new table | Alt+5 | diff --git a/content/localization/zh/Maintaining-Calculations-using-Scripting_zh.md b/content/localization/zh/Maintaining-Calculations-using-Scripting_zh.md new file mode 100644 index 00000000..c7d0d4b5 --- /dev/null +++ b/content/localization/zh/Maintaining-Calculations-using-Scripting_zh.md @@ -0,0 +1,19 @@ +This article demonstrates how you can use the Advanced Scripting feature in Tabular Editor, to maintain DAX logic across several objects in a consistent way. In the [Useful Script Snippets article](/Useful-script-snippets), we already saw [how we can use Custom Actions to quickly generate many measures](/Useful-script-snippets#generate-time-intelligence-measures) with similar logic, which can be useful when creating Time Intelligence calculations, for example. + +In this article, we're going to expand on this idea by creating a scripting "framework", which will allow us to centrally define all the calculations we need within a TSV file (Tabulator Separated Values). The advantages of using a TSV file is that it can be easily edited within Excel, while at the same time being easy to parse and load from within a script in Tabular Editor. + +For this article, we will focus on the Internet Sales fact and related dimensions of good 'ol Adventure Works: + +![image](https://user-images.githubusercontent.com/8976200/44193845-85cd5d80-a134-11e8-8f39-2da1380fdc63.png) + +The fact table has a number of numeric columns which are simply aggregated up as seven simple `SUM` measures: + +![image](https://user-images.githubusercontent.com/8976200/44196409-270be200-a13c-11e8-9994-0a8f2fa19e1a.png) + +For the purposes of this article, we'll call these the **base measures**. In real life, the formula of the base measures could be more complex, but that does not matter in general, as we will see in a moment. The central idea, is that we will use our TSV file to define a set of formulas involving the base measures as well as filter contexts that will be applied outside the calculations. + +\*\*\* TODO \*\*\* + +, as long as the calculations we are trying to build can still be constructed from one or more base measures, evaluated within any valid filter context. + +\*\*\* TODO \*\*\* diff --git a/content/localization/zh/Master-model-pattern_zh.md b/content/localization/zh/Master-model-pattern_zh.md new file mode 100644 index 00000000..d8dad54f --- /dev/null +++ b/content/localization/zh/Master-model-pattern_zh.md @@ -0,0 +1,325 @@ +# Master Model Pattern + +It is not uncommon to have several Tabular models in an organisation, with a substantial amount of functional overlap. For the development team, keeping these models up to date with shared features can be a pain point. In this article, we'll see an alternate approach that may be suitable in situations where it makes sense to combine all these models into a single "Master" model, that is then deployed partially into several different subset models. Tabular Editor enables this approach by utilising perspectives in a special way (while still allowing perspectives to work the usual way). + +**Disclaimer:** While this technique works, it is not supported by Microsoft, and there is a fair amount of learning, scripting and hacking involved. Decide for yourself whether you think it's the right approach for your team. + +For simplicity, consider the AdventureWorks sample model: + +![image](https://user-images.githubusercontent.com/8976200/43959290-895c1c96-9cae-11e8-8112-008f54cb400a.png) + +Let's say that for some reason, these is a need to deploy everything relating to Internet Sales as one model, and everything relating to Reseller Sales as another. This could be for security reasons, performance, scalability, or maybe even because your team is servicing a number of external clients, where each client needs their own copy of the model, containing both shared and specific functionality. + +Instead of actually maintaining one development branch for each of the different versions, the technique presented here, lets you maintain just one model using metadata to indicate how the model should be split upon deployment. + +## (Ab)using perspectives + +The idea is quite simple. Start by adding a number of new perspectives to your model, corresponding to the number of target models you need to deploy to. Make sure to prefix these perspectives in a consistent way, to separate them from user-oriented perspectives: + +![image](https://user-images.githubusercontent.com/8976200/43960154-6b637042-9cb1-11e8-906b-6671bbb9558e.png) + +Here, we use a `$`-sign as the prefix on the perspective names. Later on we will see how these perspectives are stripped from the model, so that end users will not see them. They are only used by the model developers. + +Now, simply add all objects needed in the individual models to these perspectives. Use the Perspective dropdown in Tabular Editor to confirm that a model contains the necessary objects. Here's a handy script that can be used to ensure that all dependencies are included in the perspective as well: + +```csharp +// Look through all hierarchies in the current perspective: +foreach(var h in Model.AllHierarchies.Where(h => h.InPerspective[Selected.Perspective])) +{ + // Make sure columns used in hierarchy levels are included in the perspective: + foreach(var level in h.Levels) { + level.Column.InPerspective[Selected.Perspective] = true; + } +} + +// Loop through all measures and columns in the current perspective: +foreach(var obj in Model.AllMeasures.Cast() + .Concat(Model.AllColumns).Where(m => m.InPerspective[Selected.Perspective]) + .OfType().ToList()) +{ + // Loop through all objects that the current object depends on: + foreach(var dep in obj.DependsOn.Deep()) + { + // Include columns, measure and table dependencies: + var columnDep = dep as Column; if(columnDep != null) columnDep.InPerspective[Selected.Perspective] = true; + var measureDep = dep as Measure; if(measureDep != null) measureDep.InPerspective[Selected.Perspective] = true; + var tableDep = dep as Table; if(tableDep != null) tableDep.InPerspective[Selected.Perspective] = true; + } +} + +// Look through all columns that have a SortByColumn in the current perspective: +foreach(var c in Model.AllColumns.Where(c => c.InPerspective[Selected.Perspective] && c.SortByColumn != null)) +{ + c.SortByColumn.InPerspective[Selected.Perspective] = true; +} +``` + +**Explanation:** First, the script loops through all hierarchies in the current perspective (the perspective currently selected in the dropdown at the top of the screen). For every such hierarchy, it ensures that all columns used as hierarchy levels appear in the perspective. Next, the script loops through all columns and measures of the current perspective. For each of these objects, all DAX dependencies in the form of measure-, column- or table references are also included in the perspective. Please note that expressions such as `DISTINCTCOUNT('Customer'[CustomerId])` will result in all columns of the 'Customer' table being included in the perspective, as Tabular Editor treats such an expression as having a dependency both on the [CustomerId] column itself, and on the 'Customer' table. Lastly, the script ensures that any columns that are used as a "Sort By"-column, are also included in the perspective. + +I recommend saving this script as a Custom Action at the Model level, to make it easy to invoke it going forward. + +By the way, if you want to make a copy of a perspective, you can already do that through the UI. Click on the "Perspectives" node in the explorer tree, and then click the ellipsis button in the property grid: + +![image](https://user-images.githubusercontent.com/8976200/44028910-c7ffab80-9efb-11e8-813a-5b0f5c137bab.png) + +This will open a dialog that lets you create and delete perspectives, as well as clone existing perspectives: + +![image](https://user-images.githubusercontent.com/8976200/44028953-f13c91ca-9efb-11e8-936a-1f0e1d4eb93f.png) + +To supplement this, here's a script that removes all invisible and unused objects from a perspective, in case you need to clean up a bit: + +```csharp +// Loop through all columns of the current perspective: +foreach(var c in Model.AllColumns.Where(c => c.InPerspective[Selected.Perspective])) { + if( + // If the column is hidden (or the parent table is hidden): + (c.IsHidden || c.Table.IsHidden) + + // And not used in any relationships: + && !c.UsedInRelationships.Any() + + // And not used as the SortByColumn for any other columns in the perspective: + && !c.UsedInSortBy.Any(sb => !sb.IsHidden && sb.InPerspective[Selected.Perspective]) + + // And not used in any hierarchies in the perspective: + && !c.UsedInHierarchies.Any(h => h.InPerspective[Selected.Perspective]) + + // And not referenced in any DAX expression for other visible objects in the perspective: + && !c.ReferencedBy.Deep().OfType() + .Any(obj => obj.InPerspective[Selected.Perspective] && !(obj as IHideableObject).IsHidden) + + // And not referenced by any roles: + && !c.ReferencedBy.Roles.Any() ) + { + // If all of the above, then the column can be removed from the current perspective: + c.InPerspective[Selected.Perspective] = false; + } +} + +// Loop through all measures of the current perspective: +foreach(var m in Model.AllMeasures.Where(m => m.InPerspective[Selected.Perspective])) { + if( + // If the measure is hidden (or the parent table is hidden): + (m.IsHidden || m.Table.IsHidden) + + // And not referenced in any DAX expression for other visible objects in the perspective: + && !m.ReferencedBy.Deep().OfType() + .Any(obj => obj.InPerspective[Selected.Perspective] && !(obj as IHideableObject).IsHidden) + ) + { + // If all of the above, then the column can be removed from the current perspective: + m.InPerspective[Selected.Perspective] = false; + } +} +``` + +**Explanation:** The script first loops through all columns of the currently selected perspective. It removes a column from the perspective only if all of the following are true: + +- The column is hidden (or the table in which the column resides is hidden) +- The column does not participate in any relationships +- The column is not used as the SortByColumn of any other visible column in the perspective +- The column is not used as a level in any hierarchies in the perspective +- The column is not directly or indirectly referenced in any DAX expressions on other visible objects in the perspective +- The column is not used in any row level filter expressions + +For measures, we do the same thing, but simplified to only remove measures that meet the following criteria: + +- The measure is hidden (or the table in which the measure resides is hidden) +- The measure is not directly or indirectly referenced in any DAX expressions on other visible objects in the perspective + +If you're a team of developers working on the model, you should already be using Tabular Editors ["Save to Folder" functionality](/Advanced-features#folder-serialization) together with a source control environment such as Git. Make sure to check the "Serialize perspectives per-object" option under "File" > "Preferences" > "Save to Folder", to avoid getting heaps of merge conflicts on your perspective definitions. + +![image](https://user-images.githubusercontent.com/8976200/44029969-935e0efe-9eff-11e8-93de-c1223f7ebe7f.png) + +## Adding more fine-grained control + +By now, you've probably guessed that we're going to use scripting to create one version of the model for every of our prefixed developer perspectives. The script will simply remove all objects from the model, that are not included in a given developer perspective. However, before we do that, there are a couple more situations we need to handle. + +### Controlling non-perspective objects + +Some objects, such as perspectives, data sources and roles, are not included nor excluded from perspectives themselves, but we may still need a way to specify which of our model versions they should belong to. For this, we're going to use annotations. So going back to our Adventure Works model, we may want the "Inventory" and "Internet Operation" perspectives to appear in "$InternetModel" and "$ManagementModel", while "Reseller Operation" should appear in "$ResellerModel" and "$ManagementModel". + +So let's add a new annotation called "DevPerspectives" on each of the 3 original perspectives, and let's just supply the names of the developer perspectives as a comma-separated string: + +![image](https://user-images.githubusercontent.com/8976200/44032304-01bdcc70-9f07-11e8-9b28-db0912ea1ade.png) + +When adding new _user_ perspectives to the model, remember to add the same annotation and provide the names of the developer perspectives that you want the _user_ perspective included in. When scripting the final model versions later on, we will use the information in these annotations to include the perspectives needed. We can do the same thing for data sources and roles. + +### Controlling object metadata + +There may also be situations where the same measure should have slightly different expressions or format strings across the different model versions. Again, we can use annotation to provide the metadata per developer perspective, and then apply the metadata when we script out the final model. + +The easiest way to get all object properties serialized into text, would probably be the [ExportProperties](/Useful-script-snippets#export-object-properties-to-a-file) script function. However, that's a little overkill for our use case, so let's just specify directly which properties we want to store as annotations. Create the following script: + +```csharp +foreach(var m in Selected.Measures) { + m.SetAnnotation(Selected.Perspective.Name + "_Expression", m.Expression); + m.SetAnnotation(Selected.Perspective.Name + "_FormatString", m.FormatString); + m.SetAnnotation(Selected.Perspective.Name + "_Description", m.Description); +} +``` + +And save it as a custom action named "Save Metadata as Annotations": + +![image](https://user-images.githubusercontent.com/8976200/44033695-7a754482-9f0b-11e8-937b-0bc0987ce7cb.png) + +Similarly, save the following script as a custom action called "Load Metadata from Annotations": + +```csharp +foreach(Measure m in Selected.Measures) { + var expr = m.GetAnnotation(Selected.Perspective.Name + "_Expression"); if(expr == null) continue; + m.Expression = expr; + m.FormatString = m.GetAnnotation(Selected.Perspective.Name + "_FormatString"); + m.Description = m.GetAnnotation(Selected.Perspective.Name + "_Description"); +} +``` + +The idea is that we create one annotation for each of the properties we would like to maintain different versions of, per developer perspective. If you need to maintain other properties than those shown in the script (Expression, FormatString, Description) separately, just add them to the script. You can do the same thing for other object types, but it probably won't make sense for much other than measures and perhaps calculated columns and partitions (to maintain different query expressions per model version, for example). + +Use your new custom actions to apply model version specific changes to the developer perspectives (or add the annotations by hand). For example, in our Adventure Works sample, we want the [Day Count] measure to have a different expression in the $ResellerModel perspective, so we apply the changes to the measure, and invoke the "Save Metadata as Annotations" action while having selected the "$ResellerModel" perspective in the dropdown: + +![image](https://user-images.githubusercontent.com/8976200/44033944-3104e414-9f0c-11e8-9f06-396bf85a0e4f.png) + +In the screenshot above, we have 3 annotations for each of the developer perspectives. In reality, though, we would only need to create these annotations for those developer perspectives where the properties should differ from their native values. + +## Altering partition queries + +We can use a similar technique to apply changes to partition queries between the different versions. For example, we may want different SQL `WHERE` criterias on some partition queries depending on the version. Let's start by creating a set of new annotations on our _table_ objects, to specify the base SQL query we want our partitions to use for each version. Here, for example, we want to restrict which records are included in the Product table on two of our three versions: + +![image](https://user-images.githubusercontent.com/8976200/44736562-69221580-aaa4-11e8-82ee-88388015d30d.png) + +For tables that have multiple partitions, we specify the WHERE criteria using "placeholders", that will be replaced later on: + +![image](https://user-images.githubusercontent.com/8976200/44737015-b3f05d00-aaa5-11e8-9bad-cadd5b4dae35.png) + +Define the placeholder values within each partition (note, you must be using [Tabular Editor v. 2.7.3](https://github.com/TabularEditor/TabularEditor/releases/tag/2.7.3) or newer to edit partition annotations through the UI): + +![image](https://user-images.githubusercontent.com/8976200/44737199-2a8d5a80-aaa6-11e8-8813-8189b593da98.png) + +In dynamic partitioning scenarios, don't forget to include these annotations in the script you're using when creating the new partitions. In the next section, we'll see how to apply these placeholder values during deployment. + +## Deploying different versions + +Finally, we are ready to deploy our model as 3 different versions. Unfortunately, the Deployment Wizard UI in Tabular Editor cannot split up the model for us based on the perspectives and annotations we created, so we'd have to create an additional script, that strips down our model to a specific version. This script can then be executed as part of a command-line deployment, so that the whole deployment process can be packaged in a command file, a PowerShell executable or maybe even integrated in your build/automated deployment process? + +The script we need looks like the following. The idea is that we create one script per developer perspective. Save the script as a text file and name it something like `ResellerModel.cs`: + +```csharp +var version = "`$`ResellerModel"; // TODO: Replace this with the name of your developer perspective + +// Remove tables, measures, columns and hierarchies that are not part of the perspective: +foreach(var t in Model.Tables.ToList()) { + if(!t.InPerspective[version]) t.Delete(); + else { + foreach(var m in t.Measures.ToList()) if(!m.InPerspective[version]) m.Delete(); + foreach(var c in t.Columns.ToList()) if(!c.InPerspective[version]) c.Delete(); + foreach(var h in t.Hierarchies.ToList()) if(!h.InPerspective[version]) h.Delete(); + } +} + +// Remove user perspectives based on annotations and all developer perspectives: +foreach(var p in Model.Perspectives.ToList()) { + if(p.Name.StartsWith("`$`")) p.Delete(); + + // Keep all other perspectives that do not have the "DevPerspectives" annotation, while removing + // those that have the annotation, if is not specified in the annotation: + if(p.GetAnnotation("DevPerspectives") != null && !p.GetAnnotation("DevPerspectives").Contains(version)) + p.Delete(); +} + +// Remove data sources based on annotations: +foreach(var ds in Model.DataSources.ToList()) { + if(ds.GetAnnotation("DevPerspectives") == null) continue; + if(!ds.GetAnnotation("DevPerspectives").Contains(version)) ds.Delete(); +} + +// Remove roles based on annotations: +foreach(var r in Model.Roles.ToList()) { + if(r.GetAnnotation("DevPerspectives") == null) continue; + if(!r.GetAnnotation("DevPerspectives").Contains(version)) r.Delete(); +} + +// Modify measures based on annotations: +foreach(Measure m in Model.AllMeasures) { + var expr = m.GetAnnotation(version + "_Expression"); if(expr == null) continue; + m.Expression = expr; + m.FormatString = m.GetAnnotation(version + "_FormatString"); + m.Description = m.GetAnnotation(version + "_Description"); +} + +// Set partition queries according to annotations: +foreach(Table t in Model.Tables) { + var queryWithPlaceholders = t.GetAnnotation(version + "_PartitionQuery"); if(queryWithPlaceholders == null) continue; + + // Loop through all partitions in this table: + foreach(Partition p in t.Partitions) { + + var finalQuery = queryWithPlaceholders; + + // Replace all placeholder values: + foreach(var placeholder in p.Annotations.Keys) { + finalQuery = finalQuery.Replace("%" + placeholder + "%", p.GetAnnotation(placeholder)); + } + + p.Query = finalQuery; + } +} + +// TODO: Modify other objects based on annotations, if applicable... +``` + +**Explanation:** First, we remove all tables, columns, measures and hierarchies, that are not part of the perspective defined in line 1 of the script. Then, we remove any additional objects where we may have applied the "DevPerspectives" annotation as described previously, along with all the developer perspectives themselves. Afterwards, we apply any changes to measure expressions, format strings or descriptions based on the annotations, if any. Finally, we apply partition queries as defined in annotations (if any), while also replacing placeholder values with the annotated values (if any). + +Note that we could also just add additional specific model changes directly to this script, if we wanted to, but the whole point of this exercise was how we can maintain several models directly from within Tabular Editor. The script above is the same, regardless of which version we want to deploy (except, of course, for line 1). + +Finally, we can load our Model.bim file, execute the script, and deploy the modified model in one go, using the following [command line syntax](/Command-line-Options): + +```sh +start /wait /d "c:\Program Files (x86)\Tabular Editor" TabularEditor.exe Model.bim -S ResellerModel.cs -D localhost AdventureWorksReseller -O -R +``` + +To deploy the Internet or Management versions, we would need to do the same, providing the corresponding scripts: + +```sh +start /wait /d "c:\Program Files (x86)\Tabular Editor" TabularEditor.exe Model.bim -S InternetModel.cs -D localhost AdventureWorksInternet -O -R +start /wait /d "c:\Program Files (x86)\Tabular Editor" TabularEditor.exe Model.bim -S ManagementModel.cs -D localhost AdventureWorksManagement -O -R +``` + +This assumes that you are executing the command line within the directory of your Model.bim file (or Database.json file if using the "Save to Folder"-functionality). The -S switch instructs Tabular Editor to apply the supplied script to the model, and the -D switch performs the deployment. The -O switch allows overwriting an existing database with the same name, and the -R switch indicates that we also want to overwrite roles of the target database. + +## Master model processing + +If you have a dedicated processing server and large amounts of data overlap between the individual models, it may make sense for you to process the data into the master model first, before splitting it up. This way, you can avoid processing the same data several times, into individual models. **This assumes, however, that you are not processing any tables where the partition query has been changed between versions, as shown in [this section](/Master-model-pattern#altering-partition-queries).** The recipe for this is outlined below: + +1. (Optional - in case there were metadata changes) Deploy your master model to your processing server +2. Perform the processing you need on your master model (do not process tables that have version-specific partition queries). +3. Synchronise the master model into every individual model and use the command above to strip down the individual models after synchronisation, followed by a ProcessRecalc if necessary. +4. (Optional) Process any tables on the individual models, that have version-specific partition queries. + +## Tips and tricks + +When you're starting to use custom annotations a lot, there may be situations where you want to list all objects with a specific annotation. This is where the Dynamic LINQ expressions of the Filter-box comes in handy. + +First off, let's say we wanted to find all objects where we added an annotation with the name "$InternetModel_Expression". Type the following into the filter textbox and hit ENTER: + +``` +:GetAnnotation("`$`InternetModel_Expression")<>null +``` + +Or, if you want to find all objects, that have an annotation ending with the word "_Expression", use: + +``` +:GetAnnotations().Any(EndsWith("_Expression")) +``` + +Note that these functions are case-sensitive, so if your annotation was written in lowercase, the above filter would not catch it. + +You could also search for objects where the annotation had a specific value: + +``` +:GetAnnotation(`$`InternetModel_Description).Contains("TODO") +``` + +## Conclusion + +The technique described here can be very helpful when maintaining many similar models with a lots of shared functionality, such as Calendar tables and other common dimensions. The scripts used can be neatly reused as Custom Actions within Tabular Editor, while the actual deployment can be automated in various ways. diff --git a/content/localization/zh/Power-BI-Desktop-Integration_zh.md b/content/localization/zh/Power-BI-Desktop-Integration_zh.md new file mode 100644 index 00000000..3fe205f7 --- /dev/null +++ b/content/localization/zh/Power-BI-Desktop-Integration_zh.md @@ -0,0 +1,25 @@ +# Power BI Desktop Integration + +As of July 2020, [Power BI Desktop adds support for External Tools](https://docs.microsoft.com/da-dk/power-bi/create-reports/desktop-external-tools). This allows Tabular Editor to perform certain modeling operations when working with Imported or DirectQuery data in Desktop. + +![image](https://user-images.githubusercontent.com/8976200/87296924-dcea3180-c507-11ea-9cf9-2f647d26a2a9.png) + +## Prerequisites + +- [July 2020 version of Power BI Desktop](https://www.microsoft.com/en-us/download/details.aspx?id=58494) (or newer) +- [Latest version of Tabular Editor](https://github.com/TabularEditor/TabularEditor/releases/latest) +- Enable [Enhanced Metadata](https://docs.microsoft.com/en-us/power-bi/connect-data/desktop-enhanced-dataset-metadata) under Power BI Desktop's Preview Features + +Also, it is highly recommended that [automatic date/time](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-auto-date-time) is **disabled** (Power BI Desktop setting under "Data Load"). + +## Supported Modeling Operations + +By default, Tabular Editor will only let you edit a limited number of objects and properties when connected to a Power BI Desktop model. These are: + +- Measures (add/remove/edit any property) +- Calculation Groups and Calculation Items (add/remove/edit any property) +- Perspectives (add/remove/edit any property) +- Translations (add/remove) + - You can apply metadata translations to any object in the model, although be aware that Power BI Desktop does not yet support translations to the default model culture. + +**Note:** If you enable the "Allow unsupported Power BI features (experimental)" option under Tabular Editor's File > Preferences dialog, Tabular Editor will let you edit **any** object and property, potentially causing model changes that are not supported by Power BI Desktop, which may cause a crash or a corrupt .pbix file. In this case, Microsoft Support will not be able to help you, so use at your own risk, and keep a backup of your .pbix file just in case. diff --git a/content/localization/zh/RW001_zh.md b/content/localization/zh/RW001_zh.md new file mode 100644 index 00000000..847d77fb --- /dev/null +++ b/content/localization/zh/RW001_zh.md @@ -0,0 +1,35 @@ +--- +uid: RW001 +category: Code actions +sub-category: Rewrites +title: Rewrite TOTALxTD using CALCULATE +author: Daniel Otykier +updated: 2025-02-10 +--- + +Code action `RW001` (Rewrites) **Rewrite TOTALxTD using CALCULATE** + +## Description + +Functions such as [`TOTALMTD`](https://dax.guide/TOTALMTD), [`TOTALQTD`](https://dax.guide/TOTALQTD) and [`TOTALYTD`](https://dax.guide/TOTALYTD) can be rewritten using the [`CALCULATE`](https://dax.guide/CALCULATE) function. + +### Example + +Change: + +```dax + TOTALYTD([Total Sales], 'Date'[Date]) +``` + +To: + +```dax +CALCULATE([Total Sales], DATESYTD('Date'[Date])) +``` + +## Why is Tabular Editor suggesting this? + +This rewrite is useful in case you want to add additional filters or modify the calculation context. + +> [!NOTE] +> This code action is in the **Rewrites** category, which means that it does not represent a general recommendation or best practice. Instead, the code action provides a quick way to rewrite the code in a different way, for example as part of a larger refactoring. After applying the code action and until further edits are made, you may see an **Improvement** or **Readability** code action that suggests to modify the code back to its original state. \ No newline at end of file diff --git a/content/localization/zh/RW002_zh.md b/content/localization/zh/RW002_zh.md new file mode 100644 index 00000000..8c873a72 --- /dev/null +++ b/content/localization/zh/RW002_zh.md @@ -0,0 +1,61 @@ +--- +uid: RW002 +category: Code actions +sub-category: Rewrites +title: Rewrite using FILTER +author: Daniel Otykier +updated: 2025-02-10 +--- + +Code action `RW002` (Rewrites) **Rewrite using FILTER** + +## Description + +A scalar predicate in a filter argument to `CALCULATE` is equivalent to a 1-column table expression that uses `FILTER`. + +### Example 1 + +Change: + +```dax +CALCULATE([Total Sales], Products[Color] = "Red") +``` + +To: + +```dax +CALCULATE( + [Total Sales], + FILTER( + ALL(Products[Color]), + Products[Color] = "Red") + ) +) +``` + +### Example 2 + +Change: + +```dax +CALCULATE([Total Sales], KEEPFILTERS(Products[Color] = "Red")) +``` + +To: + +```dax +CALCULATE( + [Total Sales], + FILTER( + VALUES(Products[Color]), + Products[Color] = "Red") + ) +) +``` + +## Why is Tabular Editor suggesting this? + +This rewrite is useful in case you want to add more complex filtering logic. + +> [!NOTE] +> This code action is in the **Rewrites** category, which means that it does not represent a general recommendation or best practice. Instead, the code action provides a quick way to rewrite the code in a different way, for example as part of a larger refactoring. After applying the code action and until further edits are made, you may see an **Improvement** or **Readability** code action that suggests to modify the code back to its original state. \ No newline at end of file diff --git a/content/localization/zh/RW003_zh.md b/content/localization/zh/RW003_zh.md new file mode 100644 index 00000000..18689b8b --- /dev/null +++ b/content/localization/zh/RW003_zh.md @@ -0,0 +1,32 @@ +--- +uid: RW003 +category: Code actions +sub-category: Rewrites +title: Invert IF +author: Daniel Otykier +updated: 2025-02-10 +--- + +Code action `RW003` (Rewrites) **Invert IF** + +## Description + +To improve readability, it is sometimes useful to invert `IF` statements. + +### Example + +Change: + +```dax +IF(a < b, "B is greater", "A is greater") +``` + +To: + +```dax +IF(a > b, "A is greater", "B is greater") +``` + +## Why is Tabular Editor suggesting this? + +This code action provides a quick way to invert the logic of an `IF` statement, which can make the code easier to read. The readability of the code is subjective and depends on the context, which is why this code action is in the **Rewrites** category rather than the **Readability** category. \ No newline at end of file diff --git a/content/localization/zh/Roadmap_zh.md b/content/localization/zh/Roadmap_zh.md new file mode 100644 index 00000000..f445bd1c --- /dev/null +++ b/content/localization/zh/Roadmap_zh.md @@ -0,0 +1,95 @@ +# Roadmap + +- Scripting objects into TMSL or DAX (compatible with DAX Editor) +- IntelliSense in DAX expression editor +- Create plug-in for Visual Studio, to launch Tabular Editor +- Tabular Editor plug-in architecture / public API for developers +- Automated build, test, publishing and documentation using VSTS +- [Done] Formula fix-up (i.e. automatically fixing DAX expressions when renaming objects) +- [Done] UI for showing object dependencies +- [Done] Scripting changes from the command-line +- [Done] Possibility to read/edit more object types (tables, partitions, data columns) +- [Done] Split a Model.bim into multiple json files (for example, one file per table) for better integration into Source Control workflows. +- [Done] Import/export translations + +## Scripting objects into TMSL or DAX + +It should be possible, when selecting one or more objects in the explorer tree, to generate a script for these objects. In fact, this is already possible by dragging and dropping the objects into another text editor (or SSMS), but there should be a similar right-click option to more clearly communicate to end-users what's going on. It should be possible to generate both TMSL scripts (for SSMS) or DAX-style code, usable in [DAX Editor](https://github.com/DaxEditor/). + +Today, measures and calculated columns can be dragged between instances of Tabular Editor to copy them between models, but to better expose this functionality, there should be an UI option for importing a provided piece of TMSL, either from the clipboard or from a file. See [this issue](https://github.com/TabularEditor/TabularEditor/issues/69). Lastly, the standard copy-paste shortcuts should be enabled. + +## Create plug-in for Visual Studio, to launch Tabular Editor + +A simple context menu extension to Visual Studio, that will simply ensure the Model.bim file is closed and then launch TabularEditor.exe with the Model.bim file loaded. + +## IntelliSense in DAX expression editor + +When writing DAX code in the expression editor, an autocompletebox should pop-up to help complete table names, column names, measure names or functions (and their arguments). + +See also [this issue](https://github.com/TabularEditor/TabularEditor/issues/64). + +## Tabular Editor plug-in architecture / public API for developers + +People who prefer to script tabular models using C# can already today use the TOMWrapper.dll instead of using the Analysis Services TOM API directly. This provides some benefits, for example, the TOMWrapper namespace makes it easier to work with perspectives and translations, thanks to the convenient methods and properties available. + +Taking this one step further, it would be interesting to expose more Tabular Editor functionality to developers: + +- Parsing of DAX objects +- Accessing Best Practice Analyzer results +- Tabular Editor UI (making it possible to create "plug-ins" for Tabular Editor with/without custom UI) + +## Automated build, test, publishing and documentation using VSTS + +DevOps using VSTS and general clean-up of Tabular Editor source code. + +## Formula fix-up + +When any model object is renamed, all DAX expressions refering that object should be updated to reflect the changed name. + +**Update**: As of 2.2, this feature can now be toggled on under "File" > "Preferences". + +## UI for showing object dependencies + +Right-clicking a measure or calculated column should display a dependency tree in a pop-up dialog. It should be possible to show either objects that depend on the chosen object, or objects on which the chosen object depend. + +**Update**: As of 2.2, this feature is available. Simply right-click an object and choose "Show dependencies...". + +## Scripting changes from the command-line + +Today, it is possible to deploy a model directly from the command-line. Similarly, it should be possible to pipe in a .cs file, containing a C# script to be executed on the model. After script execution, it should be possible to save or deploy the updated model. This requires a few changes to the current command-line options. + +**Update**: As of 2.3, scripts can be executed from the command-line, by using the "-S" switch. Deployment works as usual, but if you want to save the modified model as a .bim, you can use the "-B" switch. + +## Possibility to read/edit more object types + +Tabular Editor currently only lets end-users read and edit a subset of the objects in the Tabular Object Model. It is desirable to allow all objects in the model tree, to be accessible in Tabular Editor: Relationships, KPIs, Calculated Tables and Roles should be directly editable. Data Sources, tables, data columns and table partitions should be editable with some constraints (for example, we should not expect Tabular Editor to be able to fetch data schemas from arbitrary data sources and queries). + +**Update**: As of 2.1, many new object types are now visible directly in the Tree Explorer. Using the right-click menu, you can create, duplicate and delete many of these objects (roles, perspectives, translations). We're still lacking support for creating/deleting relationships and data sources, but this will come in a future release. + +**Update**: As of 2.2, we can now create and delete relationships. More object types comming later. + +**Update**: As of 2.3, tables, partitions and data columns can now be edited. Visual Studio is now only needed to create the blank model itself - everything else can be done in Tabular Editor. + +**Update**: Previous update was a lie! I forgot about KPIs - but they can now be created/edited/deleted as of version 2.4. + +## Split a Model.bim into multiple json files + +The layout and structure of the Model.bim file, makes it horrible for purposes of source control and versioning. Not only is the entire Tabular Object Model written into just one file, the file also contains "ModifiedTime" information everywhere in the structure, making source control DIFF operations useless. + +For better release management workflows with Tabular Models, it would be interesting if Tabular Editor could save/load a Model.bim file as a folder structure with individual files for measures, calculated columns, etc. There should be command-line options available for exporting/importing Model.bim files from/to this format, and it should be possible to deploy directly from this format (in cases where you don't need the Model.bim file itself). These individual files should contain the same JSON as the Model.bim file, but without the "ModifiedTime" information, so that they can easily be used in a version control system, allowing multiple developers to work on the same model at once. + +**Update**: [Available in 2.2](/Advanced-features#folder-serialization). + +**Update**: As of 2.3, options exist to store Perspective and Translation metadata as annotations on the individual objects. This is useful for source control scenarios with multiple developers, to avoid having single files that gets lots of edits when developers change translations, perspective memberships, etc. + +## Power BI Compatibility + +Today, it is already possible to connect Tabular Editor to a model hosted by Power BI Desktop. The approach is similar to what is [described here for Excel and SSMS](http://biinsight.com/connect-to-power-bi-desktop-model-from-excel-and-ssms/). Doing this, it is actually possible to add Display Folders to the Power BI Desktop model, and they actually stay in Power BI, even after saving and reopening the .pbix file. However, it seems that there are some compatibility level issues, which should be looked into before proceeding. + +**Update**: As of 2.1, Tabular Editor now detects running instances of Power BI Desktop and Visual Studio Integrated Workspaces. You can connect to these instances and make changes as you would normal instances, although this approach of changing Power BI and Integrated Workspace models is not supported by Microsoft. + +## Import/Export translations + +This is a standard feature in SSDT, which would be useful to have in Tabular Editor as well. + +**Update**: [Available in 2.2](/Advanced-features#import-export-translations). diff --git a/content/localization/zh/SQL-Server-2017-support_zh.md b/content/localization/zh/SQL-Server-2017-support_zh.md new file mode 100644 index 00000000..c2ec8f4d --- /dev/null +++ b/content/localization/zh/SQL-Server-2017-support_zh.md @@ -0,0 +1,35 @@ +# SQL Server 2017 Support + +Starting from version 2.3, Tabular Editor now also supports SQL Server 2017 (Compatibility Level 1400). This means that the Tabular Editor UI exposes some of the new functionality described [here](https://blogs.msdn.microsoft.com/analysisservices/2017/04/19/whats-new-in-sql-server-2017-ctp-2-0-for-analysis-services/). + +Please note, however, that you need to download the [proper build of Tabular Editor](https://github.com/TabularEditor/TabularEditor/releases/tag/2.5-CL1400) to use these features. This is because a new set of client libraries are provided by Microsoft for SQL Server 2017 / SSDT 17.0, and these libs are incompatible with the SQL Server 2016-build of Tabular Editor. The new libraries can be obtained through the new [version of SSDT](https://docs.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt) (requires Visual Studio 2015). + +If you don't need Compatibility Level 1400 features, you can still use the SQL Server 2016-build of [Tabular Editor](https://github.com/TabularEditor/TabularEditor/releases/tag/2.5). + +Here is a quick rundown of how the new features are used in Tabular Editor: + +## Date Relationships + +All relationships now expose the "Join on Date Behavior" property in the property grid: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297821/9dd46be0-26f0-11e7-92bf-10a921ed20dc.png) + +## Variations (column/hierarchy reuse) + +You can set up variations on a column, by expanding the "Variations" property in the property grid: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297845/c69ecc5a-26f0-11e7-93af-b7a2a0cc9310.png) + +Note that you can also specify **Object Level Security** at the column level. + +Clicking the ellipsis button opens the Variations Collection Editor, from where you can set up how columns and hierarchies are resurfaced in Power BI: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297884/fd4faf58-26f0-11e7-9a1a-df7a1b05f663.png) + +Remember to set the "Show As Variations Only" property to "True" at the table level: + +![image](https://cloud.githubusercontent.com/assets/8976200/25297917/2c1e4b64-26f1-11e7-8ce6-a62aef2b7d8a.png) + +**Detail Row Expressions** can be set directly on tables and measures. At this time, however, no syntax highlighting or IntelliSense is available. + +Hierarchy objects exposes a new **Hide Members** property that is useful for ragged hierarchies. diff --git a/content/localization/zh/TabularEditor.TOMWrapper_zh.md b/content/localization/zh/TabularEditor.TOMWrapper_zh.md new file mode 100644 index 00000000..1a349020 --- /dev/null +++ b/content/localization/zh/TabularEditor.TOMWrapper_zh.md @@ -0,0 +1,2354 @@ +# TabularEditor.TOMWrapper Reference + +This is auto-generated documentation for the TOMWrapper API. Use CTRL+F or the sidebar on the right, to locate a specific class, property or method. + +## `AddObjectType` + +```csharp +public enum TabularEditor.TOMWrapper.AddObjectType + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | ---------------- | ------- | +| `1` | Measure | | +| `2` | CalculatedColumn | | +| `3` | Hierarchy | | + +## `CalculatedColumn` + +Base class declaration for CalculatedColumn + +```csharp +public class TabularEditor.TOMWrapper.CalculatedColumn + : Column, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject, IExpressionObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | ------------------ | ---------------------------------------------------------------------------- | +| `Dictionary>` | Dependencies | | +| `String` | Expression | Gets or sets the Expression of the CalculatedColumn. | +| `Boolean` | IsDataTypeInferred | Gets or sets the IsDataTypeInferred of the CalculatedColumn. | +| `CalculatedColumn` | MetadataObject | | +| `Boolean` | NeedsValidation | | + +Methods + +| Type | Name | Summary | +| -------------------- | -------------------------------------------------------------------------------------------------------- | ------- | +| `TabularNamedObject` | Clone(`String` newName = null, `Boolean` includeTranslations = True) | | +| `TabularNamedObject` | CloneTo(`Table` table, `String` newName = null, `Boolean` includeTranslations = True) | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | + +## `CalculatedTable` + +```csharp +public class TabularEditor.TOMWrapper.CalculatedTable + : Table, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IHideableObject, IDescriptionObject, IAnnotationObject, ITabularObjectContainer, IDetailObjectContainer, ITabularPerspectiveObject, IDaxObject, IDynamicPropertyObject, IErrorMessageObject, IExpressionObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | --------------- | ------- | +| `Dictionary>` | Dependencies | | +| `String` | Expression | | +| `Boolean` | NeedsValidation | | +| `String` | ObjectTypeName | | + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `void` | CheckChildrenErrors() | | +| `Boolean` | Editable(`String` propertyName) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | ReinitColumns() | Call this method after the model is saved to a DB, to check for changed columns (in case of expression changes) | + +## `CalculatedTableColumn` + +Base class declaration for CalculatedTableColumn + +```csharp +public class TabularEditor.TOMWrapper.CalculatedTableColumn + : Column, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject + +``` + +Properties + +| Type | Name | Summary | +| ----------------------- | ------------------ | --------------------------------------------------------------------------------- | +| `Column` | ColumnOrigin | Gets or sets the ColumnOrigin of the CalculatedTableColumn. | +| `Boolean` | IsDataTypeInferred | Gets or sets the IsDataTypeInferred of the CalculatedTableColumn. | +| `Boolean` | IsNameInferred | Gets or sets the IsNameInferred of the CalculatedTableColumn. | +| `CalculatedTableColumn` | MetadataObject | | +| `String` | SourceColumn | Gets or sets the SourceColumn of the CalculatedTableColumn. | + +## `Column` + +Base class declaration for Column + +```csharp +public abstract class TabularEditor.TOMWrapper.Column + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `Alignment` | Alignment | Gets or sets the Alignment of the Column. | +| `String` | DataCategory | Gets or sets the DataCategory of the Column. | +| `DataType` | DataType | Gets or sets the DataType of the Column. | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | +| `String` | Description | Gets or sets the Description of the Column. | +| `String` | DisplayFolder | Gets or sets the DisplayFolder of the Column. | +| `Int32` | DisplayOrdinal | Gets or sets the DisplayOrdinal of the Column. | +| `String` | ErrorMessage | Gets or sets the ErrorMessage of the Column. | +| `String` | FormatString | Gets or sets the FormatString of the Column. | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsAvailableInMDX | Gets or sets the IsAvailableInMDX of the Column. | +| `Boolean` | IsDefaultImage | Gets or sets the IsDefaultImage of the Column. | +| `Boolean` | IsDefaultLabel | Gets or sets the IsDefaultLabel of the Column. | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Column. | +| `Boolean` | IsKey | Gets or sets the IsKey of the Column. | +| `Boolean` | IsNullable | Gets or sets the IsNullable of the Column. | +| `Boolean` | IsUnique | Gets or sets the IsUnique of the Column. | +| `Boolean` | KeepUniqueRows | Gets or sets the KeepUniqueRows of the Column. | +| `Column` | MetadataObject | | +| `Column` | SortByColumn | Gets or sets the SortByColumn of the Column. | +| `String` | SourceProviderType | Gets or sets the SourceProviderType of the Column. | +| `ObjectState` | State | Gets or sets the State of the Column. | +| `AggregateFunction` | SummarizeBy | Gets or sets the SummarizeBy of the Column. | +| `Table` | Table | | +| `Int32` | TableDetailPosition | Gets or sets the TableDetailPosition of the Column. | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Column. | +| `TranslationIndexer` | TranslatedDisplayFolders | Collection of localized Display Folders for this Column. | +| `ColumnType` | Type | Gets or sets the Type of the Column. | +| `IEnumerable` | UsedInHierarchies | Enumerates all hierarchies in which this column is used as a level. | +| `IEnumerable` | UsedInRelationships | Enumerates all relationships in which this column participates (either as or ). | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `void` | Delete() | | +| `String` | GetAnnotation(`String` name) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `ColumnCollection` + +Collection class for Column. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.ColumnCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------------------- | ------------------- | ------- | +| `Alignment` | Alignment | | +| `String` | DataCategory | | +| `DataType` | DataType | | +| `String` | Description | | +| `String` | DisplayFolder | | +| `Int32` | DisplayOrdinal | | +| `String` | FormatString | | +| `Boolean` | IsAvailableInMDX | | +| `Boolean` | IsDefaultImage | | +| `Boolean` | IsDefaultLabel | | +| `Boolean` | IsHidden | | +| `Boolean` | IsKey | | +| `Boolean` | IsNullable | | +| `Boolean` | IsUnique | | +| `Boolean` | KeepUniqueRows | | +| `Table` | Parent | | +| `Column` | SortByColumn | | +| `String` | SourceProviderType | | +| `AggregateFunction` | SummarizeBy | | +| `Int32` | TableDetailPosition | | + +Methods + +| Type | Name | Summary | +| --------------------- | ---------------------------------- | ------- | +| `IEnumerator` | GetEnumerator() | | +| `String` | ToString() | | + +## `Culture` + +Base class declaration for Culture + +```csharp +public class TabularEditor.TOMWrapper.Culture + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| ----------------------------- | ---------------------------- | ------- | +| `String` | DisplayName | | +| `Culture` | MetadataObject | | +| `String` | Name | | +| `ObjectTranslationCollection` | ObjectTranslations | | +| `String` | StatsColumnCaptions | | +| `String` | StatsColumnDisplayFolders | | +| `String` | StatsHierarchyCaptions | | +| `String` | StatsHierarchyDisplayFolders | | +| `String` | StatsLevelCaptions | | +| `String` | StatsMeasureCaptions | | +| `String` | StatsMeasureDisplayFolders | | +| `String` | StatsTableCaptions | | +| `Boolean` | Unassigned | | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `CultureCollection` + +Collection class for Culture. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.CultureCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------- | ------ | ------- | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `CultureConverter` + +```csharp +public class TabularEditor.TOMWrapper.CultureConverter + : TypeConverter + +``` + +Methods + +| Type | Name | Summary | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | CanConvertFrom(`ITypeDescriptorContext` context, `Type` sourceType) | | +| `Boolean` | CanConvertTo(`ITypeDescriptorContext` context, `Type` destinationType) | | +| `Object` | ConvertFrom(`ITypeDescriptorContext` context, `CultureInfo` culture, `Object` value) | | +| `Object` | ConvertTo(`ITypeDescriptorContext` context, `CultureInfo` culture, `Object` value, `Type` destinationType) | | +| `StandardValuesCollection` | GetStandardValues(`ITypeDescriptorContext` context) | | +| `Boolean` | GetStandardValuesExclusive(`ITypeDescriptorContext` context) | | +| `Boolean` | GetStandardValuesSupported(`ITypeDescriptorContext` context) | | + +## `Database` + +```csharp +public class TabularEditor.TOMWrapper.Database + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------ | ------- | +| `Nullable` | CompatibilityLevel | | +| `Nullable` | CreatedTimestamp | | +| `String` | ID | | +| `Nullable` | LastProcessed | | +| `Nullable` | LastSchemaUpdate | | +| `Nullable` | LastUpdate | | +| `String` | Name | | +| `String` | ServerName | | +| `String` | ServerVersion | | +| `Database` | TOMDatabase | | +| `Nullable` | Version | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `DataColumn` + +Base class declaration for DataColumn + +```csharp +public class TabularEditor.TOMWrapper.DataColumn + : Column, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IAnnotationObject, ITabularPerspectiveObject, IDaxObject + +``` + +Properties + +| Type | Name | Summary | +| ------------ | -------------- | ---------------------------------------------------------------- | +| `DataColumn` | MetadataObject | | +| `String` | SourceColumn | Gets or sets the SourceColumn of the DataColumn. | + +## `DataSource` + +Base class declaration for DataSource + +```csharp +public abstract class TabularEditor.TOMWrapper.DataSource + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------------------------------------------------------------------------- | +| `String` | Description | Gets or sets the Description of the DataSource. | +| `DataSource` | MetadataObject | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this DataSource. | +| `DataSourceType` | Type | Gets or sets the Type of the DataSource. | + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------ | ------- | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `DataSourceCollection` + +Collection class for DataSource. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.DataSourceCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------- | ----------- | ------- | +| `String` | Description | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `Dependency` + +```csharp +public struct TabularEditor.TOMWrapper.Dependency + +``` + +Fields + +| Type | Name | Summary | +| --------- | -------------- | ------- | +| `Int32` | from | | +| `Boolean` | fullyQualified | | +| `Int32` | to | | + +## `DependencyHelper` + +```csharp +public static class TabularEditor.TOMWrapper.DependencyHelper + +``` + +Static Methods + +| Type | Name | Summary | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `void` | AddDep(this `IExpressionObject` target, `IDaxObject` dependsOn, `Int32` fromChar, `Int32` toChar, `Boolean` fullyQualified) | | +| `String` | NoQ(this `String` objectName, `Boolean` table = False) | Removes qualifiers such as ' ' and [ ] around a name. | + +## `DeploymentMode` + +```csharp +public enum TabularEditor.TOMWrapper.DeploymentMode + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | -------------- | ------- | +| `0` | CreateDatabase | | +| `1` | CreateOrAlter | | + +## `DeploymentOptions` + +```csharp +public class TabularEditor.TOMWrapper.DeploymentOptions + +``` + +Fields + +| Type | Name | Summary | +| ---------------- | ----------------- | ------- | +| `Boolean` | DeployConnections | | +| `DeploymentMode` | DeployMode | | +| `Boolean` | DeployPartitions | | +| `Boolean` | DeployRoleMembers | | +| `Boolean` | DeployRoles | | + +Static Fields + +| Type | Name | Summary | +| ------------------- | ------------- | ------- | +| `DeploymentOptions` | Default | | +| `DeploymentOptions` | StructureOnly | | + +## `DeploymentResult` + +```csharp +public class TabularEditor.TOMWrapper.DeploymentResult + +``` + +Fields + +| Type | Name | Summary | +| ----------------------- | -------- | ------- | +| `IReadOnlyList` | Issues | | +| `IReadOnlyList` | Warnings | | + +## `DeploymentStatus` + +```csharp +public enum TabularEditor.TOMWrapper.DeploymentStatus + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | --------------- | ------- | +| `0` | ChangesSaved | | +| `1` | DeployComplete | | +| `2` | DeployCancelled | | + +## `Folder` + +Represents a Folder in the TreeView. Does not correspond to any object in the TOM. Implements IDisplayFolderObject since a Folder can itself be located within another display folder. Implements IParentObject since a Folder can contain child objects. + +```csharp +public class TabularEditor.TOMWrapper.Folder + : IDetailObject, ITabularTableObject, ITabularNamedObject, ITabularObject, INotifyPropertyChanged, ITabularObjectContainer, IDetailObjectContainer, IErrorMessageObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------ | ------------------------ | ------- | +| `IDetailObjectContainer` | Container | | +| `Culture` | Culture | | +| `String` | DisplayFolder | | +| `String` | ErrorMessage | | +| `String` | FullPath | | +| `TabularModelHandler` | Handler | | +| `Int32` | MetadataIndex | | +| `Model` | Model | | +| `String` | Name | | +| `ObjectType` | ObjectType | | +| `Table` | ParentTable | | +| `String` | Path | | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDisplayFolders | | +| `TranslationIndexer` | TranslatedNames | | + +Events + +| Type | Name | Summary | +| ----------------------------- | --------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | CheckChildrenErrors() | | +| `void` | Delete() | Deleting a folder does not delete child objects - it just removes the folder. Any child folders are retained (but will be moved up the display folder hierarchy). | +| `IEnumerable` | GetChildren() | | +| `IEnumerable` | GetChildrenByFolders(`Boolean` recursive = False) | | +| `void` | SetFolderName(`String` newName) | | +| `void` | UndoSetPath(`String` value) | | + +Static Methods + +| Type | Name | Summary | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `Folder` | CreateFolder(`Table` table, `String` path = , `Boolean` useFixedCulture = False, `Culture` fixedCulture = null) | | + +## `FolderHelper` + +```csharp +public static class TabularEditor.TOMWrapper.FolderHelper + +``` + +Static Methods + +| Type | Name | Summary | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------- | ------- | +| `String` | ConcatPath(this `String` path, `String` additionalPath) | | +| `String` | ConcatPath(this `IEnumerable` pathBits) | | +| `IDetailObjectContainer` | GetContainer(this `IDetailObject` obj) | | +| `String` | GetDisplayFolder(this `IDetailObject` folderObject, `Culture` culture) | | +| `String` | GetFullPath(`ITabularNamedObject` obj) | | +| `Boolean` | HasAncestor(this `IDetailObject` child, `ITabularNamedObject` ancestor, `Culture` culture) | | +| `Boolean` | HasParent(this `IDetailObject` child, `ITabularNamedObject` parent, `Culture` culture) | | +| `Int32` | Level(this `String` path) | | +| `String` | PathFromFullPath(`String` path) | | +| `void` | SetDisplayFolder(this `IDetailObject` folderObject, `String` newFolderName, `Culture` culture) | | +| `String` | TrimFolder(this `String` folderPath) | | + +## `Hierarchy` + +Base class declaration for Hierarchy + +```csharp +public class TabularEditor.TOMWrapper.Hierarchy + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IDescriptionObject, IAnnotationObject, ITabularObjectContainer, ITabularPerspectiveObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------------ | ------------------------------------------------------------------------------------------- | +| `String` | Description | Gets or sets the Description of the Hierarchy. | +| `String` | DisplayFolder | Gets or sets the DisplayFolder of the Hierarchy. | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Hierarchy. | +| `LevelCollection` | Levels | | +| `Hierarchy` | MetadataObject | | +| `Boolean` | Reordering | Set to true, when multiple levels are going to be re-ordered as one action. | +| `ObjectState` | State | Gets or sets the State of the Hierarchy. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Hierarchy. | +| `TranslationIndexer` | TranslatedDisplayFolders | Collection of localized Display Folders for this Hierarchy. | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | ------------------------------------------------------------------------------------------------- | ------- | +| `Level` | AddLevel(`Column` column, `String` levelName = null, `Int32` ordinal = -1) | | +| `Level` | AddLevel(`String` columnName, `String` levelName = null, `Int32` ordinal = -1) | | +| `void` | AddLevels(`IEnumerable` columns, `Int32` ordinal = -1) | | +| `void` | CompactLevelOrdinals() | | +| `void` | Delete() | | +| `void` | FixLevelOrder(`Level` level, `Int32` newOrdinal) | | +| `String` | GetAnnotation(`String` name) | | +| `IEnumerable` | GetChildren() | | +| `void` | Init() | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | SetLevelOrder(`IList` order) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `HierarchyCollection` + +Collection class for Hierarchy. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.HierarchyCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ------------- | ------- | +| `String` | Description | | +| `String` | DisplayFolder | | +| `Boolean` | IsHidden | | +| `Table` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `HierarchyColumnConverter` + +```csharp +public class TabularEditor.TOMWrapper.HierarchyColumnConverter + : TableColumnConverter + +``` + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------- | ------- | +| `Boolean` | GetStandardValuesExclusive(`ITypeDescriptorContext` context) | | +| `Boolean` | IsValid(`ITypeDescriptorContext` context, `Object` value) | | + +## `IAnnotationObject` + +```csharp +public interface TabularEditor.TOMWrapper.IAnnotationObject + : ITabularObject, INotifyPropertyChanged + +``` + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------ | ------- | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `IClonableObject` + +```csharp +public interface TabularEditor.TOMWrapper.IClonableObject + +``` + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------- | ------- | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | + +## `IDaxObject` + +```csharp +public interface TabularEditor.TOMWrapper.IDaxObject + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | ----------------- | ------- | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | + +## `IDescriptionObject` + +Objects that can have descriptions + +```csharp +public interface TabularEditor.TOMWrapper.IDescriptionObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------- | +| `String` | Description | | +| `TranslationIndexer` | TranslatedDescriptions | | + +## `IDetailObject` + +Represents an object than can be contained in a Display Folder. Examples: - Measures - Columns - Hierarchies - Folders + +```csharp +public interface TabularEditor.TOMWrapper.IDetailObject + : ITabularTableObject, ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------------ | ------- | +| `String` | DisplayFolder | | +| `TranslationIndexer` | TranslatedDisplayFolders | | + +## `IDetailObjectContainer` + +Represents an objects that can contain other objects as well as display folders. Examples: - Folders - Table + +```csharp +public interface TabularEditor.TOMWrapper.IDetailObjectContainer + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------- | ----------- | ------- | +| `Table` | ParentTable | | + +Methods + +| Type | Name | Summary | +| ---------------------------- | -------------------------------------------------------------------- | ------- | +| `IEnumerable` | GetChildrenByFolders(`Boolean` recursive = False) | | + +## `IErrorMessageObject` + +Objects that can have error messages + +```csharp +public interface TabularEditor.TOMWrapper.IErrorMessageObject + +``` + +Properties + +| Type | Name | Summary | +| -------- | ------------ | ------- | +| `String` | ErrorMessage | | + +## `IExpressionObject` + +```csharp +public interface TabularEditor.TOMWrapper.IExpressionObject + : IDaxObject, ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | --------------- | ------- | +| `Dictionary>` | Dependencies | | +| `String` | Expression | | +| `Boolean` | NeedsValidation | | + +## `IHideableObject` + +Objects that can be shown/hidden + +```csharp +public interface TabularEditor.TOMWrapper.IHideableObject + +``` + +Properties + +| Type | Name | Summary | +| --------- | -------- | ------- | +| `Boolean` | IsHidden | | + +## `IntelliSenseAttribute` + +```csharp +public class TabularEditor.TOMWrapper.IntelliSenseAttribute + : Attribute, _Attribute + +``` + +Properties + +| Type | Name | Summary | +| -------- | ----------- | ------- | +| `String` | Description | | + +## `ITabularNamedObject` + +```csharp +public interface TabularEditor.TOMWrapper.ITabularNamedObject + : ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | --------------- | ------- | +| `Int32` | MetadataIndex | | +| `String` | Name | | +| `TranslationIndexer` | TranslatedNames | | + +## `ITabularObject` + +```csharp +public interface TabularEditor.TOMWrapper.ITabularObject + : INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------------ | ---------- | ------- | +| `Model` | Model | | +| `ObjectType` | ObjectType | | + +## `ITabularObjectCollection` + +```csharp +public interface TabularEditor.TOMWrapper.ITabularObjectCollection + : IEnumerable + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | -------------- | ------- | +| `String` | CollectionName | | +| `TabularModelHandler` | Handler | | +| `IEnumerable` | Keys | | + +Methods + +| Type | Name | Summary | +| -------------------------- | ---------------------------------------------------- | ------- | +| `void` | Add(`TabularNamedObject` obj) | | +| `void` | Clear() | | +| `Boolean` | Contains(`Object` value) | | +| `Boolean` | Contains(`String` key) | | +| `ITabularObjectCollection` | GetCurrentCollection() | | +| `Int32` | IndexOf(`TabularNamedObject` obj) | | +| `void` | Remove(`TabularNamedObject` obj) | | + +## `ITabularObjectContainer` + +TabularObjects that can contain other objects should use this interface. + +```csharp +public interface TabularEditor.TOMWrapper.ITabularObjectContainer + +``` + +Methods + +| Type | Name | Summary | +| ---------------------------------- | -------------------------------- | ------- | +| `IEnumerable` | GetChildren() | | + +## `ITabularPerspectiveObject` + +Objects that can be shown/hidden in individual perspectives + +```csharp +public interface TabularEditor.TOMWrapper.ITabularPerspectiveObject + : IHideableObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ------------- | ------- | +| `PerspectiveIndexer` | InPerspective | | + +## `ITabularTableObject` + +Object that belongs to a specific table. + +```csharp +public interface TabularEditor.TOMWrapper.ITabularTableObject + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged + +``` + +Properties + +| Type | Name | Summary | +| ------- | ----- | ------- | +| `Table` | Table | | + +Methods + +| Type | Name | Summary | +| ------ | --------------------------- | ------- | +| `void` | Delete() | | + +## `KPI` + +Base class declaration for KPI + +```csharp +public class TabularEditor.TOMWrapper.KPI + : TabularObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, IDescriptionObject, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------------------------------------------------------------------ | +| `String` | Description | Gets or sets the Description of the KPI. | +| `Measure` | Measure | Gets or sets the Measure of the KPI. | +| `KPI` | MetadataObject | | +| `String` | StatusDescription | Gets or sets the StatusDescription of the KPI. | +| `String` | StatusExpression | Gets or sets the StatusExpression of the KPI. | +| `String` | StatusGraphic | Gets or sets the StatusGraphic of the KPI. | +| `String` | TargetDescription | Gets or sets the TargetDescription of the KPI. | +| `String` | TargetExpression | Gets or sets the TargetExpression of the KPI. | +| `String` | TargetFormatString | Gets or sets the TargetFormatString of the KPI. | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this KPI. | +| `String` | TrendDescription | Gets or sets the TrendDescription of the KPI. | +| `String` | TrendExpression | Gets or sets the TrendExpression of the KPI. | +| `String` | TrendGraphic | Gets or sets the TrendGraphic of the KPI. | + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------ | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `Level` + +Base class declaration for Level + +```csharp +public class TabularEditor.TOMWrapper.Level + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject, ITabularTableObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | -------------------------------------------------------------------- | +| `Column` | Column | Gets or sets the Column of the Level. | +| `String` | Description | Gets or sets the Description of the Level. | +| `Hierarchy` | Hierarchy | Gets or sets the Hierarchy of the Level. | +| `Level` | MetadataObject | | +| `Int32` | Ordinal | Gets or sets the Ordinal of the Level. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Level. | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| `void` | Delete() | Deletes the level from the hierarchy. | +| `String` | GetAnnotation(`String` name) | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `LevelCollection` + +Collection class for Level. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.LevelCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ----------- | ----------- | ------- | +| `String` | Description | | +| `Hierarchy` | Parent | | + +Methods + +| Type | Name | Summary | +| --------- | --------------------------------------- | ------- | +| `void` | Add(`Level` item) | | +| `Boolean` | Remove(`Level` item) | | +| `String` | ToString() | | + +## `LogicalGroup` + +```csharp +public class TabularEditor.TOMWrapper.LogicalGroup + : ITabularNamedObject, ITabularObject, INotifyPropertyChanged, ITabularObjectContainer + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | --------------- | ------- | +| `Int32` | MetadataIndex | | +| `Model` | Model | | +| `String` | Name | | +| `ObjectType` | ObjectType | | +| `TranslationIndexer` | TranslatedNames | | + +Events + +| Type | Name | Summary | +| ----------------------------- | --------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | -------------------------------- | ------- | +| `IEnumerable` | GetChildren() | | + +## `LogicalTreeOptions` + +```csharp +public enum TabularEditor.TOMWrapper.LogicalTreeOptions + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | -------------- | ------- | +| `1` | DisplayFolders | | +| `2` | Columns | | +| `4` | Measures | | +| `8` | KPIs | | +| `16` | Hierarchies | | +| `32` | Levels | | +| `64` | ShowHidden | | +| `128` | AllObjectTypes | | +| `256` | ShowRoot | | +| `447` | Default | | + +## `Measure` + +Base class declaration for Measure + +```csharp +public class TabularEditor.TOMWrapper.Measure + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDetailObject, ITabularTableObject, IHideableObject, IErrorMessageObject, IDescriptionObject, IExpressionObject, IDaxObject, IAnnotationObject, ITabularPerspectiveObject, IDynamicPropertyObject, IClonableObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------------------ | ------------------------ | ------------------------------------------------------------------------- | +| `DataType` | DataType | Gets or sets the DataType of the Measure. | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | +| `Dictionary>` | Dependencies | | +| `String` | Description | Gets or sets the Description of the Measure. | +| `String` | DisplayFolder | Gets or sets the DisplayFolder of the Measure. | +| `String` | ErrorMessage | Gets or sets the ErrorMessage of the Measure. | +| `String` | Expression | Gets or sets the Expression of the Measure. | +| `String` | FormatString | Gets or sets the FormatString of the Measure. | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Measure. | +| `Boolean` | IsSimpleMeasure | Gets or sets the IsSimpleMeasure of the Measure. | +| `KPI` | KPI | Gets or sets the KPI of the Measure. | +| `Measure` | MetadataObject | | +| `Boolean` | NeedsValidation | | +| `ObjectState` | State | Gets or sets the State of the Measure. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Measure. | +| `TranslationIndexer` | TranslatedDisplayFolders | Collection of localized Display Folders for this Measure. | + +Methods + +| Type | Name | Summary | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `TabularNamedObject` | Clone(`String` newName = null, `Boolean` includeTranslations = True) | | +| `TabularNamedObject` | CloneTo(`Table` table, `String` newName = null, `Boolean` includeTranslations = True) | | +| `void` | Delete() | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `MeasureCollection` + +Collection class for Measure. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.MeasureCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | --------------- | ------- | +| `String` | Description | | +| `String` | DisplayFolder | | +| `String` | Expression | | +| `String` | FormatString | | +| `Boolean` | IsHidden | | +| `Boolean` | IsSimpleMeasure | | +| `KPI` | KPI | | +| `Table` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `Model` + +Base class declaration for Model + +```csharp +public class TabularEditor.TOMWrapper.Model + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject, ITabularObjectContainer + +``` + +Fields + +| Type | Name | Summary | +| -------------- | ------------------ | ------- | +| `LogicalGroup` | GroupDataSources | | +| `LogicalGroup` | GroupPerspectives | | +| `LogicalGroup` | GroupRelationships | | +| `LogicalGroup` | GroupRoles | | +| `LogicalGroup` | GroupTables | | +| `LogicalGroup` | GroupTranslations | | + +Properties + +| Type | Name | Summary | +| --------------------------- | ---------------------- | -------------------------------------------------------------------- | +| `IEnumerable` | AllColumns | | +| `IEnumerable` | AllHierarchies | | +| `IEnumerable` | AllLevels | | +| `IEnumerable` | AllMeasures | | +| `String` | Collation | Gets or sets the Collation of the Model. | +| `String` | Culture | Gets or sets the Culture of the Model. | +| `CultureCollection` | Cultures | | +| `Database` | Database | | +| `DataSourceCollection` | DataSources | | +| `DataViewType` | DefaultDataView | Gets or sets the DefaultDataView of the Model. | +| `ModeType` | DefaultMode | Gets or sets the DefaultMode of the Model. | +| `String` | Description | Gets or sets the Description of the Model. | +| `Boolean` | HasLocalChanges | Gets or sets the HasLocalChanges of the Model. | +| `IEnumerable` | LogicalChildGroups | | +| `Model` | MetadataObject | | +| `PerspectiveCollection` | Perspectives | | +| `RelationshipCollection2` | Relationships | | +| `ModelRoleCollection` | Roles | | +| `String` | StorageLocation | Gets or sets the StorageLocation of the Model. | +| `TableCollection` | Tables | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Model. | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | ------------------------------------------------------------------------------------------ | ------- | +| `CalculatedTable` | AddCalculatedTable() | | +| `Perspective` | AddPerspective(`String` name = null) | | +| `SingleColumnRelationship` | AddRelationship() | | +| `ModelRole` | AddRole(`String` name = null) | | +| `Table` | AddTable() | | +| `Culture` | AddTranslation(`String` cultureId) | | +| `String` | GetAnnotation(`String` name) | | +| `IEnumerable` | GetChildren() | | +| `void` | Init() | | +| `void` | LoadChildObjects() | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `ModelRole` + +Base class declaration for ModelRole + +```csharp +public class TabularEditor.TOMWrapper.ModelRole + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | ------------------------------------------------------------------------ | +| `String` | Description | Gets or sets the Description of the ModelRole. | +| `ModelRole` | MetadataObject | | +| `ModelPermission` | ModelPermission | Gets or sets the ModelPermission of the ModelRole. | +| `RoleRLSIndexer` | RowLevelSecurity | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this ModelRole. | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------------------------ | ------- | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `void` | Delete() | | +| `String` | GetAnnotation(`String` name) | | +| `void` | InitRLSIndexer() | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `ModelRoleCollection` + +Collection class for ModelRole. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.ModelRoleCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ----------------- | --------------- | ------- | +| `String` | Description | | +| `ModelPermission` | ModelPermission | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `NullTree` + +```csharp +public class TabularEditor.TOMWrapper.NullTree + : TabularTree, INotifyPropertyChanged + +``` + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------------- | ------- | +| `void` | OnNodesChanged(`ITabularObject` nodeItem) | | +| `void` | OnNodesInserted(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnNodesRemoved(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnStructureChanged(`ITabularNamedObject` obj = null) | | + +## `ObjectOrder` + +```csharp +public enum TabularEditor.TOMWrapper.ObjectOrder + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ----- | ------------ | ------- | +| `0` | Alphabetical | | +| `1` | Metadata | | + +## `ObjectType` + +```csharp +public enum TabularEditor.TOMWrapper.ObjectType + : Enum, IComparable, IFormattable, IConvertible + +``` + +Enum + +| Value | Name | Summary | +| ------ | -------------------- | ------- | +| `-2` | Group | | +| `-1` | Folder | | +| `1` | Model | | +| `2` | DataSource | | +| `3` | Table | | +| `4` | Column | | +| `5` | AttributeHierarchy | | +| `6` | Partition | | +| `7` | Relationship | | +| `8` | Measure | | +| `9` | Hierarchy | | +| `10` | Level | | +| `11` | Annotation | | +| `12` | KPI | | +| `13` | Culture | | +| `14` | ObjectTranslation | | +| `15` | LinguisticMetadata | | +| `29` | Perspective | | +| `30` | PerspectiveTable | | +| `31` | PerspectiveColumn | | +| `32` | PerspectiveHierarchy | | +| `33` | PerspectiveMeasure | | +| `34` | Role | | +| `35` | RoleMembership | | +| `36` | TablePermission | | +| `1000` | Database | | + +## `Partition` + +Base class declaration for Partition + +```csharp +public class TabularEditor.TOMWrapper.Partition + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDynamicPropertyObject, IErrorMessageObject, ITabularTableObject, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | ---------------------- | ------------------------------------------------------------------------ | +| `DataSource` | DataSource | | +| `DataViewType` | DataView | Gets or sets the DataView of the Partition. | +| `String` | Description | Gets or sets the Description of the Partition. | +| `String` | ErrorMessage | Gets or sets the ErrorMessage of the Partition. | +| `String` | Expression | | +| `Partition` | MetadataObject | | +| `ModeType` | Mode | Gets or sets the Mode of the Partition. | +| `String` | Name | | +| `String` | Query | | +| `DateTime` | RefreshedTime | | +| `String` | Source | | +| `PartitionSourceType` | SourceType | Gets or sets the SourceType of the Partition. | +| `ObjectState` | State | Gets or sets the State of the Partition. | +| `Table` | Table | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Partition. | + +Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------ | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `PartitionCollection` + +Collection class for Partition. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.PartitionCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------------- | ----------- | ------- | +| `DataViewType` | DataView | | +| `String` | Description | | +| `ModeType` | Mode | | +| `Table` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `Perspective` + +Base class declaration for Perspective + +```csharp +public class TabularEditor.TOMWrapper.Perspective + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| -------------------- | ---------------------- | -------------------------------------------------------------------------- | +| `String` | Description | Gets or sets the Description of the Perspective. | +| `Perspective` | MetadataObject | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Perspective. | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------------------------ | ------- | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `void` | Delete() | | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `PerspectiveCollection` + +Collection class for Perspective. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------- | ----------- | ------- | +| `String` | Description | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `PerspectiveColumnIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveColumnIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| -------- | ------ | ------- | +| `Column` | Column | | + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------- | ------- | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveHierarchyIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveHierarchyIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ----------- | --------- | ------- | +| `Hierarchy` | Hierarchy | | + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------- | ------- | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveIndexer` + +```csharp +public abstract class TabularEditor.TOMWrapper.PerspectiveIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Fields + +| Type | Name | Summary | +| -------------------- | ------------- | ------- | +| `TabularNamedObject` | TabularObject | | + +Properties + +| Type | Name | Summary | +| ---------------------------------- | -------------- | ------- | +| `Boolean` | Item | | +| `Boolean` | Item | | +| `IEnumerable` | Keys | | +| `Dictionary` | PerspectiveMap | | +| `String` | Summary | | + +Methods + +| Type | Name | Summary | +| ----------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `void` | All() | Includes the object in all perspectives. | +| `Dictionary` | Copy() | | +| `void` | CopyFrom(`PerspectiveIndexer` source) | | +| `void` | CopyFrom(`IDictionary` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | None() | | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveMeasureIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveMeasureIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ------- | ------- | +| `Measure` | Measure | | + +Methods + +| Type | Name | Summary | +| ------ | ---------------------------------------------------------------------------------- | ------- | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `PerspectiveTableIndexer` + +```csharp +public class TabularEditor.TOMWrapper.PerspectiveTableIndexer + : PerspectiveIndexer, IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ----- | ------- | +| `Boolean` | Item | | +| `Table` | Table | | + +Methods + +| Type | Name | Summary | +| ------------------ | ---------------------------------------------------------------------------------- | ------- | +| `PerspectiveTable` | EnsurePTExists(`Perspective` perspective) | | +| `void` | Refresh() | | +| `void` | SetInPerspective(`Perspective` perspective, `Boolean` included) | | + +## `ProviderDataSource` + +Base class declaration for ProviderDataSource + +```csharp +public class TabularEditor.TOMWrapper.ProviderDataSource + : DataSource, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IDescriptionObject, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | ----------------- | ----------------------------------------------------------------------------- | +| `String` | Account | Gets or sets the Account of the ProviderDataSource. | +| `String` | ConnectionString | Gets or sets the ConnectionString of the ProviderDataSource. | +| `ImpersonationMode` | ImpersonationMode | Gets or sets the ImpersonationMode of the ProviderDataSource. | +| `DatasourceIsolation` | Isolation | Gets or sets the Isolation of the ProviderDataSource. | +| `Boolean` | IsPowerBIMashup | | +| `String` | Location | | +| `Int32` | MaxConnections | Gets or sets the MaxConnections of the ProviderDataSource. | +| `ProviderDataSource` | MetadataObject | | +| `String` | MQuery | | +| `String` | Name | | +| `String` | Password | Gets or sets the Password of the ProviderDataSource. | +| `String` | Provider | Gets or sets the Provider of the ProviderDataSource. | +| `String` | SourceID | | +| `Int32` | Timeout | Gets or sets the Timeout of the ProviderDataSource. | + +Methods + +| Type | Name | Summary | +| --------- | --------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `Boolean` | Editable(`String` propertyName) | | +| `void` | Init() | | + +## `Relationship` + +Base class declaration for Relationship + +```csharp +public abstract class TabularEditor.TOMWrapper.Relationship + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IAnnotationObject + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------ | -------------------------- | -------------------------------------------------------------------------------- | +| `CrossFilteringBehavior` | CrossFilteringBehavior | Gets or sets the CrossFilteringBehavior of the Relationship. | +| `Table` | FromTable | Gets or sets the FromTable of the Relationship. | +| `Boolean` | IsActive | Gets or sets the IsActive of the Relationship. | +| `DateTimeRelationshipBehavior` | JoinOnDateBehavior | Gets or sets the JoinOnDateBehavior of the Relationship. | +| `Relationship` | MetadataObject | | +| `Boolean` | RelyOnReferentialIntegrity | Gets or sets the RelyOnReferentialIntegrity of the Relationship. | +| `SecurityFilteringBehavior` | SecurityFilteringBehavior | Gets or sets the SecurityFilteringBehavior of the Relationship. | +| `ObjectState` | State | Gets or sets the State of the Relationship. | +| `Table` | ToTable | Gets or sets the ToTable of the Relationship. | +| `RelationshipType` | Type | Gets or sets the Type of the Relationship. | + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------ | ------- | +| `String` | GetAnnotation(`String` name) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | + +## `RelationshipCollection` + +Collection class for Relationship. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.RelationshipCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------ | -------------------------- | ------- | +| `CrossFilteringBehavior` | CrossFilteringBehavior | | +| `Boolean` | IsActive | | +| `DateTimeRelationshipBehavior` | JoinOnDateBehavior | | +| `Model` | Parent | | +| `Boolean` | RelyOnReferentialIntegrity | | +| `SecurityFilteringBehavior` | SecurityFilteringBehavior | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `RelationshipCollection2` + +```csharp +public class TabularEditor.TOMWrapper.RelationshipCollection2 + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| ------------------------------ | -------------------------- | ------- | +| `CrossFilteringBehavior` | CrossFilteringBehavior | | +| `Boolean` | IsActive | | +| `DateTimeRelationshipBehavior` | JoinOnDateBehavior | | +| `Model` | Parent | | +| `Boolean` | RelyOnReferentialIntegrity | | +| `SecurityFilteringBehavior` | SecurityFilteringBehavior | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `RoleRLSIndexer` + +The RoleRLSIndexer is used to browse all filters across all tables in the model, for one specific role. This is in contrast to the TableRLSIndexer, which browses the filters across all roles in the model, for one specific table. + +```csharp +public class TabularEditor.TOMWrapper.RoleRLSIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Fields + +| Type | Name | Summary | +| ----------- | ---- | ------- | +| `ModelRole` | Role | | + +Properties + +| Type | Name | Summary | +| --------------------------- | ------- | ------- | +| `String` | Item | | +| `String` | Item | | +| `IEnumerable` | Keys | | +| `Dictionary` | RLSMap | | +| `String` | Summary | | + +Methods + +| Type | Name | Summary | +| --------------------- | ------------------------------------------------------------------- | ------- | +| `void` | Clear() | | +| `void` | CopyFrom(`RoleRLSIndexer` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | Refresh() | | +| `void` | SetRLS(`Table` table, `String` filterExpression) | | + +## `SerializeOptions` + +```csharp +public class TabularEditor.TOMWrapper.SerializeOptions + +``` + +Fields + +| Type | Name | Summary | +| ----------------- | ------------------------ | ------- | +| `Boolean` | IgnoreInferredObjects | | +| `Boolean` | IgnoreInferredProperties | | +| `Boolean` | IgnoreTimestamps | | +| `HashSet` | Levels | | +| `Boolean` | PrefixFilenames | | +| `Boolean` | SplitMultilineStrings | | + +Static Properties + +| Type | Name | Summary | +| ------------------ | ------- | ------- | +| `SerializeOptions` | Default | | + +## `SingleColumnRelationship` + +Base class declaration for SingleColumnRelationship + +```csharp +public class TabularEditor.TOMWrapper.SingleColumnRelationship + : Relationship, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IAnnotationObject, IDynamicPropertyObject + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | --------------- | --------------------------------------------------------------------------------- | +| `RelationshipEndCardinality` | FromCardinality | Gets or sets the FromCardinality of the SingleColumnRelationship. | +| `Column` | FromColumn | Gets or sets the FromColumn of the SingleColumnRelationship. | +| `SingleColumnRelationship` | MetadataObject | | +| `String` | Name | | +| `RelationshipEndCardinality` | ToCardinality | Gets or sets the ToCardinality of the SingleColumnRelationship. | +| `Column` | ToColumn | Gets or sets the ToColumn of the SingleColumnRelationship. | + +Methods + +| Type | Name | Summary | +| --------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | Browsable(`String` propertyName) | | +| `void` | Delete() | | +| `Boolean` | Editable(`String` propertyName) | | +| `void` | Init() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `String` | ToString() | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +## `Table` + +Base class declaration for Table + +```csharp +public class TabularEditor.TOMWrapper.Table + : TabularNamedObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable, IHideableObject, IDescriptionObject, IAnnotationObject, ITabularObjectContainer, IDetailObjectContainer, ITabularPerspectiveObject, IDaxObject, IDynamicPropertyObject, IErrorMessageObject + +``` + +Properties + +| Type | Name | Summary | +| ---------------------------- | ---------------------- | -------------------------------------------------------------------- | +| `IEnumerable` | AllLevels | | +| `ColumnCollection` | Columns | | +| `String` | DataCategory | Gets or sets the DataCategory of the Table. | +| `String` | DaxObjectFullName | | +| `String` | DaxObjectName | | +| `String` | DaxTableName | | +| `HashSet` | Dependants | | +| `String` | Description | Gets or sets the Description of the Table. | +| `String` | ErrorMessage | | +| `HierarchyCollection` | Hierarchies | | +| `PerspectiveIndexer` | InPerspective | | +| `Boolean` | IsHidden | Gets or sets the IsHidden of the Table. | +| `MeasureCollection` | Measures | | +| `Table` | MetadataObject | | +| `String` | Name | | +| `Table` | ParentTable | | +| `PartitionCollection` | Partitions | | +| `TableRLSIndexer` | RowLevelSecurity | | +| `String` | Source | | +| `PartitionSourceType` | SourceType | | +| `TranslationIndexer` | TranslatedDescriptions | Collection of localized descriptions for this Table. | + +Methods + +| Type | Name | Summary | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `CalculatedColumn` | AddCalculatedColumn(`String` name = null, `String` expression = null, `String` displayFolder = null) | | +| `DataColumn` | AddDataColumn(`String` name = null, `String` sourceColumn = null, `String` displayFolder = null) | | +| `Hierarchy` | AddHierarchy(`String` name = null, `String` displayFolder = null, `Column[]` levels) | | +| `Hierarchy` | AddHierarchy(`String` name, `String` displayFolder = null, `String[]` levels) | | +| `Measure` | AddMeasure(`String` name = null, `String` expression = null, `String` displayFolder = null) | | +| `Boolean` | Browsable(`String` propertyName) | | +| `void` | CheckChildrenErrors() | | +| `void` | Children_CollectionChanged(`Object` sender, `NotifyCollectionChangedEventArgs` e) | | +| `TabularNamedObject` | Clone(`String` newName = null, `Boolean` includeTranslations = False) | | +| `void` | Delete() | | +| `Boolean` | Editable(`String` propertyName) | | +| `String` | GetAnnotation(`String` name) | | +| `IEnumerable` | GetChildren() | Returns all columns, measures and hierarchies inside this table. | +| `IEnumerable` | GetChildrenByFolders(`Boolean` recursive) | | +| `void` | Init() | | +| `void` | InitRLSIndexer() | | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | | +| `void` | SetAnnotation(`String` name, `String` value, `Boolean` undoable = True) | | +| `void` | Undelete(`ITabularObjectCollection` collection) | | + +Static Fields + +| Type | Name | Summary | +| -------- | --------------------- | ------- | +| `Char[]` | InvalidTableNameChars | | + +## `TableCollection` + +Collection class for Table. Provides convenient properties for setting a property on multiple objects at once. + +```csharp +public class TabularEditor.TOMWrapper.TableCollection + : TabularObjectCollection, IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection
    , IEnumerable
    , IList
    , ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------- | ------------ | ------- | +| `String` | DataCategory | | +| `String` | Description | | +| `Boolean` | IsHidden | | +| `Model` | Parent | | + +Methods + +| Type | Name | Summary | +| -------- | ----------------------------- | ------- | +| `String` | ToString() | | + +## `TableExtension` + +```csharp +public static class TabularEditor.TOMWrapper.TableExtension + +``` + +Static Methods + +| Type | Name | Summary | +| --------------------- | ---------------------------------------------------- | ------- | +| `PartitionSourceType` | GetSourceType(this `Table` table) | | + +## `TableRLSIndexer` + +The TableRLSIndexer is used to browse all filters defined on one specific table, across all roles in the model. This is in contrast to the RoleRLSIndexer, which browses the filters across all tables for one specific role. + +```csharp +public class TabularEditor.TOMWrapper.TableRLSIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Fields + +| Type | Name | Summary | +| ------- | ----- | ------- | +| `Table` | Table | | + +Properties + +| Type | Name | Summary | +| ------------------------------- | ------- | ------- | +| `String` | Item | | +| `String` | Item | | +| `IEnumerable` | Keys | | +| `Dictionary` | RLSMap | | +| `String` | Summary | | + +Methods + +| Type | Name | Summary | +| --------------------- | ---------------------------------------------------------------------- | ------- | +| `void` | Clear() | | +| `void` | CopyFrom(`TableRLSIndexer` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | Refresh() | | +| `void` | SetRLS(`ModelRole` role, `String` filterExpression) | | + +## `TabularCollectionHelper` + +```csharp +public static class TabularEditor.TOMWrapper.TabularCollectionHelper + +``` + +Static Methods + +| Type | Name | Summary | +| ------ | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| `void` | InPerspective(this `IEnumerable
    ` tables, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` columns, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` hierarchies, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` measures, `String` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable
    ` tables, `Perspective` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` columns, `Perspective` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` hierarchies, `Perspective` perspective, `Boolean` value) | | +| `void` | InPerspective(this `IEnumerable` measures, `Perspective` perspective, `Boolean` value) | | +| `void` | SetDisplayFolder(this `IEnumerable` measures, `String` displayFolder) | | + +## `TabularCommonActions` + +Provides convenient methods for common actions on a Tabular Model, that often involve changing multiple objects at once. For example, these methods may be used to easily perform UI drag and drop operations that will change hierarchy levels, display folders, etc. + +```csharp +public class TabularEditor.TOMWrapper.TabularCommonActions + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | ------- | ------- | +| `TabularModelHandler` | Handler | | + +Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `void` | AddColumnsToHierarchy(`IEnumerable` columns, `Hierarchy` hierarchy, `Int32` firstOrdinal = -1) | | +| `Level` | AddColumnToHierarchy(`Column` column, `Hierarchy` hierarchy, `Int32` ordinal = -1) | | +| `void` | MoveObjects(`IEnumerable` objects, `Table` newTable, `Culture` culture) | | +| `String` | NewColumnName(`String` prefix, `Table` table) | | +| `String` | NewMeasureName(`String` prefix) | | +| `void` | ReorderLevels(`IEnumerable` levels, `Int32` firstOrdinal) | | +| `void` | SetContainer(`IEnumerable` objects, `IDetailObjectContainer` newContainer, `Culture` culture) | | + +## `TabularConnection` + +```csharp +public static class TabularEditor.TOMWrapper.TabularConnection + +``` + +Static Methods + +| Type | Name | Summary | +| -------- | ------------------------------------------------------------------------------------------------- | ------- | +| `String` | GetConnectionString(`String` serverName) | | +| `String` | GetConnectionString(`String` serverName, `String` userName, `String` password) | | + +## `TabularCultureHelper` + +```csharp +public static class TabularEditor.TOMWrapper.TabularCultureHelper + +``` + +Static Methods + +| Type | Name | Summary | +| --------- | ------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `Boolean` | ImportTranslations(`String` culturesJson, `Model` Model, `Boolean` overwriteExisting, `Boolean` haltOnError) | | + +## `TabularDeployer` + +```csharp +public class TabularEditor.TOMWrapper.TabularDeployer + +``` + +Static Methods + +| Type | Name | Summary | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | Deploy(`Database` db, `String` targetConnectionString, `String` targetDatabaseName) | Deploys the specified database to the specified target server and database ID, using the specified options. Returns a list of DAX errors (if any) on objects inside the database, in case the deployment was succesful. | +| `DeploymentResult` | Deploy(`Database` db, `String` targetConnectionString, `String` targetDatabaseID, `DeploymentOptions` options) | Deploys the specified database to the specified target server and database ID, using the specified options. Returns a list of DAX errors (if any) on objects inside the database, in case the deployment was succesful. | +| `String` | GetTMSL(`Database` db, `Server` server, `String` targetDatabaseID, `DeploymentOptions` options) | | +| `void` | SaveModelMetadataBackup(`String` connectionString, `String` targetDatabaseID, `String` backupFilePath) | | +| `void` | WriteZip(`String` fileName, `String` content) | | + +## `TabularModelHandler` + +```csharp +public class TabularEditor.TOMWrapper.TabularModelHandler + : IDisposable + +``` + +Fields + +| Type | Name | Summary | +| ---------------------------------------------- | ------------------ | ------- | +| `Dictionary` | WrapperCollections | | +| `Dictionary` | WrapperLookup | | + +Properties + +| Type | Name | Summary | +| ------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `TabularCommonActions` | Actions | | +| `Boolean` | AutoFixup | Specifies whether object name changes (tables, column, measures) should result in automatic DAX expression updates to reflect the changed names. When set to true, all expressions in the model are parsed, to build a dependency tree. | +| `Database` | Database | | +| `Boolean` | DelayBuildDependencyTree | | +| `IList>` | Errors | | +| `Boolean` | HasUnsavedChanges | | +| `Boolean` | IsConnected | | +| `Model` | Model | | +| `String` | Status | | +| `TabularTree` | Tree | | +| `UndoManager` | UndoManager | | +| `Int64` | Version | | + +Methods + +| Type | Name | Summary | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `IDetailObject` | Add(`AddObjectType` objectType, `IDetailObjectContainer` container) | | +| `void` | BeginUpdate(`String` undoName) | | +| `void` | BuildDependencyTree(`IExpressionObject` expressionObj) | | +| `void` | BuildDependencyTree() | | +| `ConflictInfo` | CheckConflicts() | | +| `IList` | DeserializeObjects(`String` json) | | +| `void` | Dispose() | | +| `void` | DoFixup(`IDaxObject` obj, `String` newName) | Changes all references to object "obj", to reflect "newName" | +| `Int32` | EndUpdate(`Boolean` undoable = True, `Boolean` rollback = False) | | +| `Int32` | EndUpdateAll(`Boolean` rollback = False) | | +| `Model` | GetModel() | | +| `Boolean` | ImportTranslations(`String` culturesJson, `Boolean` overwriteExisting, `Boolean` ignoreInvalid) | Applys translation from a JSON string. | +| `void` | SaveDB() | Saves the changes to the database. It is the users responsibility to check if changes were made to the database since it was loaded to the TOMWrapper. You can use Handler.CheckConflicts() for this purpose. | +| `void` | SaveFile(`String` fileName, `SerializeOptions` options) | | +| `void` | SaveToFolder(`String` path, `SerializeOptions` options) | | +| `String` | ScriptCreateOrReplace() | Scripts the entire database | +| `String` | ScriptCreateOrReplace(`TabularNamedObject` obj) | Scripts the entire database | +| `String` | ScriptTranslations(`IEnumerable` translations) | | +| `String` | SerializeObjects(`IEnumerable` objects) | | +| `void` | UpdateFolders(`Table` table) | | +| `void` | UpdateLevels(`Hierarchy` hierarchy) | | +| `void` | UpdateObject(`ITabularObject` obj) | | +| `void` | UpdateTables() | | + +Static Fields + +| Type | Name | Summary | +| -------- | ------------------------------------------- | ------- | +| `String` | PROP_ERRORS | | +| `String` | PROP_HASUNSAVEDCHANGES | | +| `String` | PROP_ISCONNECTED | | +| `String` | PROP_STATUS | | + +Static Properties + +| Type | Name | Summary | +| --------------------- | --------- | ------- | +| `TabularModelHandler` | Singleton | | + +Static Methods + +| Type | Name | Summary | +| ----------------------------------------------- | ------------------------------------------------------------ | ------- | +| `List>` | CheckErrors(`Database` database) | | +| `List>` | CheckProcessingState(`Database` database) | | + +## `TabularNamedObject` + +A TabularObject is a wrapper for the Microsoft.AnalysisServices.Tabular.NamedMetadataObject class. This wrapper is used for all objects that are to be viewable and editable in the Tabular Editor. The same base class is used for all kinds of objects in a Tabular Model. This base class provides method for editing the (localized) name and description. + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularNamedObject + : TabularObject, ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging, ITabularNamedObject, IComparable + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | --------------- | -------------------------------------------------------------- | +| `Int32` | MetadataIndex | | +| `NamedMetadataObject` | MetadataObject | | +| `String` | Name | | +| `TranslationIndexer` | TranslatedNames | Collection of localized names for this object. | + +Methods + +| Type | Name | Summary | +| -------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `TabularNamedObject` | Clone(`String` newName, `Boolean` includeTranslations) | | +| `Int32` | CompareTo(`Object` obj) | | +| `void` | Delete() | | +| `void` | Init() | | +| `void` | Undelete(`ITabularObjectCollection` collection) | Hacky workaround needed to undo a delete operations. Derived classes must take care to update any objects "owned" by the object in question. For example, a Measure must take care of updating the wrapper for its KPI (if any). | + +## `TabularObject` + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularObject + : ITabularObject, INotifyPropertyChanged, INotifyPropertyChanging + +``` + +Fields + +| Type | Name | Summary | +| -------------------------- | ---------- | ------- | +| `ITabularObjectCollection` | Collection | | +| `TabularModelHandler` | Handler | | + +Properties + +| Type | Name | Summary | +| -------------------- | ------------------------ | ------- | +| `MetadataObject` | MetadataObject | | +| `Model` | Model | | +| `ObjectType` | ObjectType | | +| `String` | ObjectTypeName | | +| `TranslationIndexer` | TranslatedDescriptions | | +| `TranslationIndexer` | TranslatedDisplayFolders | | + +Events + +| Type | Name | Summary | +| ------------------------------ | ---------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | +| `PropertyChangingEventHandler` | PropertyChanging | | + +Methods + +| Type | Name | Summary | +| --------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | Init() | Derived members should override this method to instantiate child objects | +| `void` | OnPropertyChanged(`String` propertyName, `Object` oldValue, `Object` newValue) | | +| `void` | OnPropertyChanging(`String` propertyName, `Object` newValue, `Boolean&` undoable, `Boolean&` cancel) | Called before a property is changed on an object. Derived classes can control how the change is handled. Throw ArgumentException within this method, to display an error message in the UI. | +| `Boolean` | SetField(`T&` field, `T` value, `String` propertyName = null) | | + +## `TabularObjectCollection` + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularObjectCollection + : IList, ICollection, IEnumerable, INotifyCollectionChanged, ICollection, IEnumerable, IList, ITabularObjectCollection, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------------------------------------- | ------------------------ | ------- | +| `String` | CollectionName | | +| `Int32` | Count | | +| `TabularModelHandler` | Handler | | +| `Boolean` | IsFixedSize | | +| `Boolean` | IsReadOnly | | +| `Boolean` | IsSynchronized | | +| `T` | Item | | +| `T` | Item | | +| `IEnumerable` | Keys | | +| `NamedMetadataObjectCollection` | MetadataObjectCollection | | +| `String` | Summary | | +| `Object` | SyncRoot | | + +Events + +| Type | Name | Summary | +| ------------------------------------- | ----------------- | ------- | +| `NotifyCollectionChangedEventHandler` | CollectionChanged | | + +Methods + +| Type | Name | Summary | +| -------------------------- | ---------------------------------------------------------- | ------- | +| `void` | Add(`T` item) | | +| `void` | Add(`TabularNamedObject` item) | | +| `Int32` | Add(`Object` value) | | +| `void` | Clear() | | +| `Boolean` | Contains(`T` item) | | +| `Boolean` | Contains(`Object` value) | | +| `Boolean` | Contains(`String` name) | | +| `void` | CopyTo(`T[]` array, `Int32` arrayIndex) | | +| `void` | CopyTo(`Array` array, `Int32` index) | | +| `void` | ForEach(`Action` action) | | +| `ITabularObjectCollection` | GetCurrentCollection() | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `Int32` | IndexOf(`TabularNamedObject` obj) | | +| `Int32` | IndexOf(`T` item) | | +| `Int32` | IndexOf(`Object` value) | | +| `void` | Insert(`Int32` index, `T` item) | | +| `void` | Insert(`Int32` index, `Object` value) | | +| `void` | Refresh() | | +| `void` | Remove(`TabularNamedObject` item) | | +| `Boolean` | Remove(`T` item) | | +| `void` | Remove(`Object` value) | | +| `void` | RemoveAt(`Int32` index) | | + +## `TabularObjectComparer` + +```csharp +public class TabularEditor.TOMWrapper.TabularObjectComparer + : IComparer, IComparer + +``` + +Properties + +| Type | Name | Summary | +| ------------- | ----- | ------- | +| `ObjectOrder` | Order | | + +Methods + +| Type | Name | Summary | +| ------- | ---------------------------------------------------------------------------- | ------- | +| `Int32` | Compare(`Object` x, `Object` y) | | +| `Int32` | Compare(`ITabularNamedObject` x, `ITabularNamedObject` y) | | + +## `TabularObjectHelper` + +```csharp +public static class TabularEditor.TOMWrapper.TabularObjectHelper + +``` + +Static Methods + +| Type | Name | Summary | +| --------- | ----------------------------------------------------------------------------------------------- | ------- | +| `String` | GetLinqPath(this `TabularNamedObject` obj) | | +| `String` | GetName(this `ITabularNamedObject` obj, `Culture` culture) | | +| `String` | GetObjectPath(this `MetadataObject` obj) | | +| `String` | GetObjectPath(this `TabularObject` obj) | | +| `String` | GetTypeName(this `ObjectType` objType, `Boolean` plural = False) | | +| `String` | GetTypeName(this `ITabularObject` obj, `Boolean` plural = False) | | +| `Boolean` | SetName(this `ITabularNamedObject` obj, `String` newName, `Culture` culture) | | +| `String` | SplitCamelCase(this `String` str) | | + +## `TabularTree` + +The TabularLogicalModel controls the relation between TabularObjects for display in the TreeViewAdv control. Each individual TabularObject does not know or care about its logical relation to other objects (for example, through DisplayFolders in a specific culture). TabularObjects only care about their physical relations which are inherited from the Tabular Object Model directly (i.e., a measure belongs to a table, etc.). + +```csharp +public abstract class TabularEditor.TOMWrapper.TabularTree + : INotifyPropertyChanged + +``` + +Fields + +| Type | Name | Summary | +| ---------------------------- | ---------- | ------- | +| `Dictionary` | FolderTree | | + +Properties + +| Type | Name | Summary | +| --------------------- | ----------- | ------- | +| `Culture` | Culture | | +| `String` | Filter | | +| `TabularModelHandler` | Handler | | +| `Model` | Model | | +| `LogicalTreeOptions` | Options | | +| `Perspective` | Perspective | | +| `Int32` | UpdateLocks | | + +Events + +| Type | Name | Summary | +| ----------------------------- | --------------- | ------- | +| `PropertyChangedEventHandler` | PropertyChanged | | + +Methods + +| Type | Name | Summary | +| ---------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | BeginUpdate() | | +| `void` | EndUpdate() | | +| `IEnumerable` | GetChildren(`ITabularObjectContainer` tabularObject) | This method encapsulates the logic of how the tree representation of the tabular model should be structured | +| `Func` | GetFolderMutation(`Object` source, `Object` destination) | | +| `Func` | GetFolderMutation(`String` oldPath, `String` newPath) | | +| `void` | ModifyDisplayFolder(`Table` table, `String` oldPath, `String` newPath, `Culture` culture) | Updates the DisplayFolder property of all tabular objects within one table. Objects residing in subfolders to the updated path, will also be updated. | +| `void` | OnNodesChanged(`ITabularObject` nodeItem) | | +| `void` | OnNodesInserted(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnNodesInserted(`ITabularObject` parent, `IEnumerable` children) | | +| `void` | OnNodesRemoved(`ITabularObject` parent, `ITabularObject[]` children) | | +| `void` | OnNodesRemoved(`ITabularObject` parent, `IEnumerable` children) | | +| `void` | OnStructureChanged(`ITabularNamedObject` obj = null) | | +| `void` | SetCulture(`String` cultureName) | | +| `void` | SetPerspective(`String` perspectiveName) | | +| `void` | UpdateFolder(`Folder` folder, `String` oldFullPath = null) | | +| `Boolean` | VisibleInTree(`ITabularNamedObject` tabularObject) | | + +## `TranslationIndexer` + +```csharp +public class TabularEditor.TOMWrapper.TranslationIndexer + : IEnumerable, IEnumerable, IExpandableIndexer + +``` + +Properties + +| Type | Name | Summary | +| --------------------- | --------------- | ------- | +| `String` | DefaultValue | | +| `String` | Item | | +| `String` | Item | | +| `IEnumerable` | Keys | | +| `String` | Summary | | +| `Int32` | TranslatedCount | | + +Methods + +| Type | Name | Summary | +| ---------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void` | Clear() | Clears all translated values for the object. | +| `Boolean` | Contains(`Culture` culture) | | +| `Dictionary` | Copy() | | +| `void` | CopyFrom(`TranslationIndexer` translations, `Func` mutator = null) | | +| `void` | CopyFrom(`IDictionary` source) | | +| `String` | GetDisplayName(`String` key) | | +| `IEnumerator` | GetEnumerator() | | +| `void` | Refresh() | | +| `void` | Reset() | Resets the translations of the object. Caption translations are removed, making the object appear with the base name in all locales. Display Folder and Description translations are set to the untranslated value of the object. | +| `void` | SetAll(`String` value) | | + + diff --git a/content/localization/zh/Training-Webinar-for-Tabular-Editor_zh.md b/content/localization/zh/Training-Webinar-for-Tabular-Editor_zh.md new file mode 100644 index 00000000..ac0ee77c --- /dev/null +++ b/content/localization/zh/Training-Webinar-for-Tabular-Editor_zh.md @@ -0,0 +1,30 @@ +# Video Tutorials + +In collaboration with [PowerBI.Tips](https://powerbi.tips/about/) Daniel Otykier conducts 4 hours of training related to the Tabular Editor Program. Watch the following videos below to learn more about this tool and see how to use it in your everyday job. + +Webinar Topics + +- Introduction to Tabular Editor +- Using Scripting +- Reviewing your data model with the Best Practice Analyzer +- Deploying your model with Azure DevOps + +## Introduction to Tabular Editor + +[![Intro to Tabular Editor](http://img.youtube.com/vi/c-jZMzsvKnM/0.jpg)](http://www.youtube.com/watch?v=c-jZMzsvKnM "Intro To Tabular Editor") + +## Using Scripting + +[![Intro to Tabular Editor](http://img.youtube.com/vi/EHs5r3XCkO8/0.jpg)](http://www.youtube.com/watch?v=EHs5r3XCkO8 "Intro To Tabular Editor") + +## Best Practice Analyzer + +[![Intro to Tabular Editor](http://img.youtube.com/vi/5WnN0NG2nBk/0.jpg)](http://www.youtube.com/watch?v=5WnN0NG2nBk "Intro To Tabular Editor") + +## Deploying with DevOps + +[![Intro to Tabular Editor](http://img.youtube.com/vi/fzZgXe3MjhI/0.jpg)](http://www.youtube.com/watch?v=fzZgXe3MjhI "Intro To Tabular Editor") + +Special thanks to PowerBI.Tips for setting up these free webinars. +Visit PowerBI.tips on YouTube - https://www.youtube.com/powerbitips +Visit PowerBI.tips - https://powerbi.tips diff --git a/content/localization/zh/Useful-script-snippets_zh.md b/content/localization/zh/Useful-script-snippets_zh.md new file mode 100644 index 00000000..b694854e --- /dev/null +++ b/content/localization/zh/Useful-script-snippets_zh.md @@ -0,0 +1,988 @@ +--- +uid: useful-script-snippets +title: Useful script snippets +author: Daniel Otykier +--- + +# Useful Script Snippets + +Here's a collection of small script snippets to get you started using the [Advanced Scripting functionality](/Advanced-Scripting) of Tabular Editor. Many of these scripts are useful to save as [Custom Actions](/Custom-Actions), so that you can easily reuse them from the context menu.' + +Also, make sure to check out our script library @csharp-script-library, for some more real-life examples of what you can do with the scripting capabilities of Tabular Editor. + +*** + +## Create measures from columns + +```csharp +// Creates a SUM measure for every currently selected column and hide the column. +foreach(var c in Selected.Columns) +{ + var newMeasure = c.Table.AddMeasure( + "Sum of " + c.Name, // Name + "SUM(" + c.DaxObjectFullName + ")", // DAX expression + c.DisplayFolder // Display Folder + ); + + // Set the format string on the new measure: + newMeasure.FormatString = "0.00"; + + // Provide some documentation: + newMeasure.Description = "This measure is the sum of column " + c.DaxObjectFullName; + + // Hide the base column: + c.IsHidden = true; +} +``` + +This snippet uses the `
    .AddMeasure(, , )` function to create a new measure on the table. We use the `DaxObjectFullName` property to get the fully qualified name of the column for use in the DAX expression: `'TableName'[ColumnName]`. + +*** + +## Generate Time Intelligence measures + +First, create custom actions for individual Time Intelligence aggregations. For example: + +```csharp +// Creates a TOTALYTD measure for every selected measure. +foreach(var m in Selected.Measures) { + m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.DisplayFolder // Display Folder + ); +} +``` + +Here, we use the `DaxObjectName` property, to generate an unqualified reference for use in the DAX expression, as this is a measure: `[MeasureName]`. Save this as a Custom Action called "Time Intelligence\Create YTD measure" that applies to measures. Create similar actions for MTD, LY, and whatever else you need. Then, create the following as a new action: + +```csharp +// Invoke all Time Intelligence Custom Actions: +CustomAction(@"Time Intelligence\Create YTD measure"); +CustomAction(@"Time Intelligence\Create MTD measure"); +CustomAction(@"Time Intelligence\Create LY measure"); +``` + +This illustrates how you can execute one (or more) Custom Actions from within another action (beware of circular references - that will cause Tabular Editor to crash). Save this as a new Custom Action "Time Intelligence\All of the above", and you will have an easy way to generate all your Time Intelligence measures with a single click: + +![image](https://user-images.githubusercontent.com/8976200/36632257-5565c8ca-197c-11e8-8498-82667b6e1049.png) + +Of course, you may also put all your time intelligence calculations into a single script such as the following: + +```csharp +var dateColumn = "'Date'[Date]"; + +// Creates time intelligence measures for every selected measure: +foreach(var m in Selected.Measures) { + // Year-to-date: + m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Previous year: + m.Table.AddMeasure( + m.Name + " PY", // Name + "CALCULATE(" + m.DaxObjectName + ", SAMEPERIODLASTYEAR(" + dateColumn + "))", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Year-over-year + m.Table.AddMeasure( + m.Name + " YoY", // Name + m.DaxObjectName + " - [" + m.Name + " PY]", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Year-over-year %: + m.Table.AddMeasure( + m.Name + " YoY%", // Name + "DIVIDE([" + m.Name + " YoY], [" + m.Name + " PY])", // DAX expression + m.DisplayFolder // Display Folder + ).FormatString = "0.0 %"; // Set format string as percentage + + // Quarter-to-date: + m.Table.AddMeasure( + m.Name + " QTD", // Name + "TOTALQTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.DisplayFolder // Display Folder + ); + + // Month-to-date: + m.Table.AddMeasure( + m.Name + " MTD", // Name + "TOTALMTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.DisplayFolder // Display Folder + ); +} +``` + +### Including additional properties + +If you want to set additional properties on the newly created measure, the above script can be modified like so: + +```csharp +// Creates a TOTALYTD measure for every selected measure. +foreach(var m in Selected.Measures) { + var newMeasure = m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.DisplayFolder // Display Folder + ); + newMeasure.FormatString = m.FormatString; // Copy format string from original measure + foreach(var c in Model.Cultures) { + newMeasure.TranslatedNames[c] = m.TranslatedNames[c] + " YTD"; // Copy translated names for every culture + newMeasure.TranslatedDisplayFolders[c] = m.TranslatedDisplayFolders[c]; // Copy translated display folders + } +} +``` + +*** + +## Setting default translations + +Sometimes it is useful to have default translations applied to all (visible) objects. In this case, a default translation is just the original name/description/display folder of an object. One of the advantages of this, is that all translation objects will be included when exporting translations in the JSON format, i.e. for use with [SSAS Tabular Translator](https://www.sqlbi.com/tools/ssas-tabular-translator/). + +The script below will loop through all cultures in the model, and for every visible object, that doesn't already have a translation, it will assign the default values: + +```csharp +// Apply default translations to all (visible) translatable objects, across all cultures in the model: +foreach(var culture in Model.Cultures) +{ + ApplyDefaultTranslation(Model, culture); + foreach(var perspective in Model.Perspectives) + ApplyDefaultTranslation(perspective, culture); + foreach(var table in Model.Tables.Where(t => t.IsVisible)) + ApplyDefaultTranslation(table, culture); + foreach(var measure in Model.AllMeasures.Where(m => m.IsVisible)) + ApplyDefaultTranslation(measure, culture); + foreach(var column in Model.AllColumns.Where(c => c.IsVisible)) + ApplyDefaultTranslation(column, culture); + foreach(var hierarchy in Model.AllHierarchies.Where(h => h.IsVisible)) + ApplyDefaultTranslation(hierarchy, culture); + foreach(var level in Model.AllLevels.Where(l => l.Hierarchy.IsVisible)) + ApplyDefaultTranslation(level, culture); +} + +void ApplyDefaultTranslation(ITranslatableObject obj, Culture culture) +{ + // Only apply the default translation when a translation does not already exist: + if(string.IsNullOrEmpty(obj.TranslatedNames[culture])) + { + // Default name translation: + obj.TranslatedNames[culture] = obj.Name; + + // Default description translation: + var dObj = obj as IDescriptionObject; + if(dObj != null && string.IsNullOrEmpty(obj.TranslatedDescriptions[culture]) + && !string.IsNullOrEmpty(dObj.Description)) + { + obj.TranslatedDescriptions[culture] = dObj.Description; + } + + // Default display folder translation: + var fObj = obj as IFolderObject; + if(fObj != null && string.IsNullOrEmpty(fObj.TranslatedDisplayFolders[culture]) + && !string.IsNullOrEmpty(fObj.DisplayFolder)) + { + fObj.TranslatedDisplayFolders[culture] = fObj.DisplayFolder; + } + } +} +``` + +*** + +## Handling perspectives + +Measures, columns, hierarchies and tables all expose the `InPerspective` property, which holds a True/False value for every perspective in the model, that indicates if the given object is a member of that perspective or not. So for example: + +```csharp +foreach(var measure in Selected.Measures) +{ + measure.InPerspective["Inventory"] = true; + measure.InPerspective["Reseller Operation"] = false; +} +``` + +The script above ensures that all selected measures are visible in the "Inventory" perspective and hidden in the "Reseller Operation" perspective. + +In addition to getting/setting the membership in an individual perspective, the `InPerspective` property also supports the following methods: + +- `<>.InPerspective.None()` - removes the object from all perspectives. +- `<>.InPerspective.All()` - includes the object in all perspectives. +- `<>.CopyFrom(string[] perspectives)` - includes the object in all specified perspectives (array of string containing names of the perspectives). +- `<>.CopyFrom(perspectiveIndexer perspectives)` - copies perspective inclusions from another `InPerspective` property. + +The latter may be used to copy perspective memberships from one object to another. For example, say have a base measure [Reseller Total Sales], and you want to make sure that all currently selected measures are visible in the same perspectives as this base measure. The following script does the trick: + +```csharp +var baseMeasure = Model.Tables["Reseller Sales"].Measures["Reseller Total Sales"]; + +foreach(var measure in Selected.Measures) +{ + /* Uncomment the line below, if you want 'measure' to be hidden + from perspectives that 'baseMeasure' is hidden in: */ + // measure.InPerspective.None(); + + measure.InPerspective.CopyFrom(baseMeasure.InPerspective); +} +``` + +This technique can be used also when generating new objects from code. For example, if we want to ensure that auto-generated Time Intelligence measures are only visible in the same perspectives as their base measure, we can extend the script from the previous section as: + +```csharp +// Creates a TOTALYTD measure for every selected measure. +foreach(var m in Selected.Measures) { + var newMeasure = m.Table.AddMeasure( + m.Name + " YTD", // Name + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.DisplayFolder // Display Folder + ); + newMeasure.InPerspective.CopyFrom(m.InPerspective); // Apply perspectives from the base measure +} +``` + +*** + +## Generating partitions + +If you need to provide custom partitioning for a table, C# scripting can help you quickly generate many partitions. The basic idea is to add an annotation to your table, containing the SQL or M query to use as a template for each partition. The script will then swap in filter parameters as needed. For example, using SQL partitions, we could add an annotation named `PartitionTemplateSQL` and set its value to `SELECT * FROM fact_ResellerSales WHERE CalendarID BETWEEN {0} AND {1}`. The `{0}` and `{1}` placeholders will be replaced by our script, when generating the final partitions. In this case, `CalendarID` is an integer, but in general, it is your job to ensure that the resulting string is a valid SQL (or M) query. + +![](https://user-images.githubusercontent.com/8976200/70135273-07c6fa00-168a-11ea-84f6-90f0b3498ed8.png) + +The example here generates one partition per month. Select a table that has the `PartitionTemplateSQL` annotation assigned, then run the script. + +```csharp +var firstPartition = new DateTime(2018,1,1); // First partition date +var lastPartition = new DateTime(2020,12,1); // Last partition date + +var templateSql = Selected.Table.GetAnnotation("PartitionTemplateSQL"); +if(string.IsNullOrEmpty(templateSql)) throw new Exception("No partition template!"); + +var currentPartition = firstPartition; +while(currentPartition <= lastPartition) +{ + // Calculate the from and to CalendarID's (integer values) based on the currentPartition date: + var calendarIdFrom = currentPartition.ToString("yyyyMMdd"); + var calendarIdTo = currentPartition.AddMonths(1).AddDays(-1).ToString("yyyyMMdd"); + + // Determine a unique name for the partition - since we're partitioning at a monthly level, we just use yyyyMM: + var partitionName = Selected.Table.Name + "_" + currentPartition.ToString("yyyyMM"); + + // Swap in the placeholder values in the partition template SQL: + var partitionQuery = string.Format(templateSql, calendarIdFrom, calendarIdTo); + + // Create the partition (use .AddMPartition if you used an M query template instead of SQL): + Selected.Table.AddPartition(partitionName, partitionQuery); + + // Increment to next month (change this to .AddDays, .AddYears, etc. if you need more or fewer partitions): + currentPartition = currentPartition.AddMonths(1); +} +``` + +*** + +## Export object properties to a file + +For some workflows, it may be useful to edit multiple object properties in bulk using Excel. Use the following snippet to export a standard set of properties to a .TSV file, which can then be subsequently imported (see below). + +```csharp +// Export properties for the currently selected objects: +var tsv = ExportProperties(Selected); +SaveFile("Exported Properties 1.tsv", tsv); +``` + +The resulting .TSV file looks like this, when opened in Excel: +![image](https://user-images.githubusercontent.com/8976200/36632472-e8e96ef6-197e-11e8-8285-6816b09ad036.png) +The contents of the first column (Object) is a reference to the object. If the contents of this column is changed, subsequent import of the properties might not work correctly. To change the name of an object, only change the value in the second column (Name). + +By default, the file is saved to the same folder as TabularEditor.exe is located. By default, only the following properties are exported (where applicable, depending on the type of object exported): + +- Name +- Description +- SourceColumn +- Expression +- FormatString +- DataType + +To export different properties, supply a comma-separated list of property names to be exported as the 2nd argument to `ExportProperties`: + +```csharp +// Export the names and Detail Rows Expressions for all measures on the currently selected table: +var tsv = ExportProperties(Selected.Table.Measures, "Name,DetailRowsExpression"); +SaveFile("Exported Properties 2.tsv", tsv); +``` + +The available property names can be found in the [TOM API documentation](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.aspx). These are mostly identical to the names shown in the Tabular Editor property grid in CamelCase and with spaces removed (with a few exceptions, for example, the "Hidden" property is called `IsHidden` in the TOM API). + +To import properties, use the following snippet: + +```csharp +// Imports and applies the properties in the specified file: +var tsv = ReadFile("Exported Properties 1.tsv"); +ImportProperties(tsv); +``` + +### Exporting indexed properties + +As of Tabular Editor 2.11.0, the `ExportProperties` and `ImportProperties` methods support indexed properties. Indexed properties are properties that take a key in addition to the property name. One example is `myMeasure.TranslatedNames`. This property represents the collection of all strings applied as name translations for `myMeasure`. In C#, you can access the translated caption of a specific culture using the indexing operator: `myMeasure.TranslatedNames["da-DK"]`. + +Long story short, you can now export all translations, perspective information, annotations, extended properties, row-level- and object-level security information on objects in your Tabular model. + +For example, the following script will produce a TSV file of all model measures and information about which perspectives each is visible in: + +```csharp +var tsv = ExportProperties(Model.AllMeasures, "Name,InPerspective"); +SaveFile(@"c:\Project\MeasurePerspectives.tsv", tsv); +``` + +The TSV file looks like this, when opened in Excel: + +![image](https://user-images.githubusercontent.com/8976200/85208532-956dec80-b331-11ea-8568-32dbd4cc5516.png) + +And just as shown above, you can make changes in Excel, hit save, and then load the updated values back into Tabular Editor using `ImportProperties`. + +If you want to list only a specific or a few specific perspectives, you can specify those in the 2nd argument in the call to `ExportProperties`: + +```csharp +var tsv = ExportProperties(Model.AllMeasures, "Name,InPerspective[Inventory]"); +SaveFile(@"c:\Project\MeasurePerspectiveInventory.tsv", tsv); +``` + +Similarly, for translations, annotations, etc. For example, if you wanted to see all danish translations applied to tables, columns, hierarchies, levells and measures: + +```csharp +// Construct a list of objects: +var objects = new List(); +objects.AddRange(Model.Tables); +objects.AddRange(Model.AllColumns); +objects.AddRange(Model.AllHierarchies); +objects.AddRange(Model.AllLevels); +objects.AddRange(Model.AllMeasures); + +var tsv = ExportProperties(objects, "Name,TranslatedNames[da-DK],TranslatedDescriptions[da-DK],TranslatedDisplayFolders[da-DK]"); +SaveFile(@"c:\Project\ObjectTranslations.tsv", tsv); +``` + +*** + +## Generating documentation + +The `ExportProperties` method shown above, can also be used if you want to document all or parts of your model. The following snippet will extract a set of properties from all visible measures or columns in a Tabular Model, and save it as a TSV file: + +```csharp +// Construct a list of all visible columns and measures: +var objects = Model.AllMeasures.Where(m => !m.IsHidden && !m.Table.IsHidden).Cast() + .Concat(Model.AllColumns.Where(c => !c.IsHidden && !c.Table.IsHidden)); + +// Get their properties in TSV format (tabulator-separated): +var tsv = ExportProperties(objects,"Name,ObjectType,Parent,Description,FormatString,DataType,Expression"); + +// (Optional) Output to screen (can then be copy-pasted into Excel): +// tsv.Output(); + +// ...or save the TSV to a file: +SaveFile("documentation.tsv", tsv); +``` + +*** + +## Generating measures from a file + +The above techniques of exporting/importing properties, is useful if you want to edit object properties in bulk of _existing_ objects in your model. What if you want to import a list of measures that do not already exist? + +Let's say you have a TSV (tab-separated values) file that contains Names, Descriptions and DAX Expressions of measures you'd like to import into an existing Tabular Model. You can use the following script to read in the file, split it out into rows and columns, and generate the measures. The script also assigns a special annotation to each measure, so that it can delete measures that were previously created using the same script. + +```csharp +var targetTable = Model.Tables["Program"]; // Name of the table that should hold the measures +var measureMetadata = ReadFile(@"c:\Test\MyMeasures.tsv"); // c:\Test\MyMeasures.tsv is a tab-separated file with a header row and 3 columns: Name, Description, Expression + +// Delete all measures from the target table that have an "AUTOGEN" annotation with the value "1": +foreach(var m in targetTable.Measures.Where(m => m.GetAnnotation("AUTOGEN") == "1").ToList()) +{ + m.Delete(); +} + +// Split the file into rows by CR and LF characters: +var tsvRows = measureMetadata.Split(new[] {'\r','\n'},StringSplitOptions.RemoveEmptyEntries); + +// Loop through all rows but skip the first one: +foreach(var row in tsvRows.Skip(1)) +{ + var tsvColumns = row.Split('\t'); // Assume file uses tabs as column separator + var name = tsvColumns[0]; // 1st column contains measure name + var description = tsvColumns[1]; // 2nd column contains measure description + var expression = tsvColumns[2]; // 3rd column contains measure expression + + // This assumes that the model does not already contain a measure with the same name (if it does, the new measure will get a numeric suffix): + var measure = targetTable.AddMeasure(name); + measure.Description = description; + measure.Expression = expression; + measure.SetAnnotation("AUTOGEN", "1"); // Set a special annotation on the measure, so we can find it and delete it the next time the script is executed. +} +``` + +If you need to automate this process, save the above script into a file and use the [Tabular Editor CLI](/Command-line-Options) as follows: + +```powershell +start /wait TabularEditor.exe "" -S "" -B "" +``` + +for example: + +```powershell +start /wait TabularEditor.exe "c:\Projects\AdventureWorks\Model.bim" -S "c:\Projects\AutogenMeasures.cs" -B "c:\Projects\AdventureWorks\Build\Model.bim" +``` + +...or, if you prefer to run the script against an already deployed database: + +```powershell +start /wait TabularEditor.exe "localhost" "AdventureWorks" -S "c:\Projects\AutogenMeasures.cs" -D "localhost" "AdventureWorks" -O +``` + +*** + +## Creating Data Columns from Partition Source metadata + +**Note:** If you're using version 2.7.2 or newer, make sure to try the new "Import Table..." feature. + +If a table uses a Query partition based on an OLE DB provider data source, we can automatically refresh the column metadata of that table by executing the following snippet: + +```csharp +Model.Tables["Reseller Sales"].RefreshDataColumns(); +``` + +This is useful when adding new tables to a model, to avoid having to create every Data Column on the table manually. The snippet above assumes that the partition source can be accessed locally, using the existing connection string of the Partition Source for the 'Reseller Sales' table. The snippet above will extract the schema from the partition query, and add a Data Column to the table for every column in the source query. + +If you need to supply a different connection string for this operation, you can do that in the snippet as well: + +```csharp +var source = Model.DataSources["DWH"] as ProviderDataSource; +var oldConnectionString = source.ConnectionString; +source.ConnectionString = "..."; // Enter the connection string you want to use for metadata refresh +Model.Tables["Reseller Sales"].RefreshDataColumns(); +source.ConnectionString = oldConnectionString; +``` + +This assumes that the partitions of the 'Reseller Sales' table is using a Provider Data Source with the name "DWH". + +*** + +## Format DAX expressions + +Please see [FormatDax](/FormatDax) for more information. + +```csharp +// Works in Tabular Editor version 2.13.0 or newer: +Selected.Measures.FormatDax(); +``` + +Alternate syntax: + +```csharp +// Works in Tabular Editor version 2.13.0 or newer: +foreach(var m in Selected.Measures) + m.FormatDax(); +``` + +*** + +## Generate list of source columns for a table + +The following script outputs a nicely formatted list of source columns for the currently selected table. This may be useful if you want to replace partition queries that use `SELECT *` with explicit columns. + +```csharp +string.Join(",\r\n", + Selected.Table.DataColumns + .OrderBy(c => c.SourceColumn) + .Select(c => "[" + c.SourceColumn + "]") + ).Output(); +``` + +*** + +## Auto-creating relationships + +If you're consistently using a certain set of naming conventions within your team, you'll quickly find that scripts can be even more powerful. + +The following script, when executed on one or more fact tables, will automatically create relationships to all relevant dimension tables, based on column names. The script will search for fact table columns having the name pattern `xxxyyyKey` where the xxx is an optional qualifier for role-playing use, and the yyy is the dimension table name. On the dimension table, a column named `yyyKey` must exist and have the same data type as the column on the fact table. For example, a column named "ProductKey" will be related to the "ProductKey" column on the Product table. You can specify a different column name suffix to use in place of "Key". + +If a relationship already exists between the fact and dimension table, the script will create the new relationship as inactive. + +```csharp +var keySuffix = "Key"; + +// Loop through all currently selected tables (assumed to be fact tables): +foreach(var fact in Selected.Tables) +{ + // Loop through all SK columns on the current table: + foreach(var factColumn in fact.Columns.Where(c => c.Name.EndsWith(keySuffix))) + { + // Find the dimension table corresponding to the current SK column: + var dim = Model.Tables.FirstOrDefault(t => factColumn.Name.EndsWith(t.Name + keySuffix)); + if(dim != null) + { + // Find the key column on the dimension table: + var dimColumn = dim.Columns.FirstOrDefault(c => factColumn.Name.EndsWith(c.Name)); + if(dimColumn != null) + { + // Check whether a relationship already exists between the two columns: + if(!Model.Relationships.Any(r => r.FromColumn == factColumn && r.ToColumn == dimColumn)) + { + // If relationships already exists between the two tables, new relationships will be created as inactive: + var makeInactive = Model.Relationships.Any(r => r.FromTable == fact && r.ToTable == dim); + + // Add the new relationship: + var rel = Model.AddRelationship(); + rel.FromColumn = factColumn; + rel.ToColumn = dimColumn; + factColumn.IsHidden = true; + if(makeInactive) rel.IsActive = false; + } + } + } + } +} +``` + +*** + +## Create DumpFilters measure + +Inspired by [this article](https://www.sqlbi.com/articles/displaying-filter-context-in-power-bi-tooltips/), here's a script that will create a [DumpFilters] measure on the currently selected table: + +```csharp +var dax = "VAR MaxFilters = 3 RETURN "; +var dumpFilterDax = @"IF ( + ISFILTERED ( {0} ), + VAR ___f = FILTERS ( {0} ) + VAR ___r = COUNTROWS ( ___f ) + VAR ___t = TOPN ( MaxFilters, ___f, {0} ) + VAR ___d = CONCATENATEX ( ___t, {0}, "", "" ) + VAR ___x = ""{0} = "" & ___d + & IF(___r > MaxFilters, "", ... ["" & ___r & "" items selected]"") & "" "" + RETURN ___x & UNICHAR(13) & UNICHAR(10) +)"; + +// Loop through all columns of the model to construct the complete DAX expression: +bool first = true; +foreach(var column in Model.AllColumns) +{ + if(!first) dax += " & "; + dax += string.Format(dumpFilterDax, column.DaxObjectFullName); + if(first) first = false; +} + +// Add the measure to the currently selected table: +Selected.Table.AddMeasure("DumpFilters", dax); +``` + +*** + +## CamelCase to Proper Case + +A common naming scheme for columns and tables on a relation database, is CamelCase. That is, names do not contain any spaces and individual words start with a capital letter. In a Tabular model, tables and columns that are not hidden, will be visible to business users, and so it would often be preferable to use a "prettier" naming scheme. The following script will convert CamelCased names to Proper Case. Sequences of uppercase letters are kept as-is (acronyms). For example, the script will convert the following: + +- `CustomerWorkZipcode` to `Customer Work Zipcode` +- `CustomerAccountID` to `Customer Account ID` +- `NSASecurityID` to `NSA Security ID` + +I highly recommend saving this script as a Custom Action that applies to all object types (except Relationships, KPIs, Table Permissions and Translations, as these do not have an editable "Name" property): + +```csharp +foreach(var obj in Selected.OfType()) { + var oldName = obj.Name; + var newName = new System.Text.StringBuilder(); + for(int i = 0; i < oldName.Length; i++) { + // First letter should always be capitalized: + if(i == 0) newName.Append(Char.ToUpper(oldName[i])); + + // A sequence of two uppercase letters followed by a lowercase letter should have a space inserted + // after the first letter: + else if(i + 2 < oldName.Length && char.IsLower(oldName[i + 2]) && char.IsUpper(oldName[i + 1]) && char.IsUpper(oldName[i])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + + // All other sequences of a lowercase letter followed by an uppercase letter, should have a space + // inserted after the first letter: + else if(i + 1 < oldName.Length && char.IsLower(oldName[i]) && char.IsUpper(oldName[i+1])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + else + { + newName.Append(oldName[i]); + } + } + obj.Name = newName.ToString(); +} +``` + +*** + +## Exporting dependencies between tables and measures + +Let's say you have a large, complex model, and you want to know which measures are potentially affected by changes to the underlying data. + +The following script loops through all the measures of your model, and for each measure, it outputs a list of tables that measure depends on - both directly and indirectly. The list is outputted as a Tab-separated file. + +```csharp +string tsv = "Measure\tDependsOnTable"; // TSV file header row + +// Loop through all measures: +foreach(var m in Model.AllMeasures) { + + // Get a list of ALL objects referenced by this measure (both directly and indirectly through other measures): + var allReferences = m.DependsOn.Deep(); + + // Filter the previous list of references to table references only. For column references, let's get th + // table that each column belongs to. Finally, keep only distinct tables: + var allTableReferences = allReferences.OfType
    () + .Concat(allReferences.OfType().Select(c => c.Table)).Distinct(); + + // Output TSV rows - one for each table reference: + foreach(var t in allTableReferences) + tsv += string.Format("\r\n{0}\t{1}", m.Name, t.Name); +} + +tsv.Output(); +// SaveFile("c:\\MyProjects\\SSAS\\MeasureTableDependencies.tsv", tsv); // Uncomment this line to save output to a file +``` + +*** + +## Setting up Aggregations (Power BI Dataset only) + +As of [Tabular Editor 2.11.3](https://github.com/TabularEditor/TabularEditor/releases/tag/2.11.3), you can now set the `AlternateOf` property on a column, enabling you to define aggregation tables on your model. This feature is enabled for Power BI Datasets (Compatibility Level 1460 or higher) through the Power BI Service XMLA endpoint. + +Select a range of columns and run the following script to initiate the `AlternateOf` property on them: + +```csharp +foreach(var col in Selected.Columns) col.AddAlternateOf(); +``` + +Work your way through the columns one by one, to map them to the base column and set the summarization accordingly (Sum/Min/Max/GroupBy). Alternatively, if you want to automate this process, and your aggregation table columns have identical names as the base table columns, you can use the following script, which will map the columns for you: + +```csharp +// Select two tables in the tree (ctrl+click). The aggregation table is assumed to be the one with fewest columns. +// This script will set up the AlternateOf property on all columns on the aggregation table. Agg table columns must +// have the same name as the base table columns for this script to work. +var aggTable = Selected.Tables.OrderBy(t => t.Columns.Count).First(); +var baseTable = Selected.Tables.OrderByDescending(t => t.Columns.Count).First(); + +foreach(var col in aggTable.Columns) +{ + // The script will set the summarization type to "Group By", unless the column uses data type decimal/double: + var summarization = SummarizationType.GroupBy; + if(col.DataType == DataType.Double || col.DataType == DataType.Decimal) + summarization = SummarizationType.Sum; + + col.AddAlternateOf(baseTable.Columns[col.Name], summarization); +} +``` + +After running the script, you should see that the `AlternateOf` property has been assigned on all columns on your agg table (see screenshot below). Keep in mind, that the base table partition must use DirectQuery for aggregations to work. + +![image](https://user-images.githubusercontent.com/8976200/85851134-6ed70800-b7ae-11ea-82eb-37fcaa2ca9c4.png) + +*** + +## Querying Analysis Services + +As of version [2.12.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.12.1), Tabular Editor now provides a number of helper methods for executing DAX queries and evaluating DAX expressions against your model. These methods work only when model metadata have been loaded directly from an instance of Analysis Services, such as when using the "File > Open > From DB..." option, or when using the Power BI external tools integration of Tabular Editor. + +The following methods are available: + +| Method | Description | +| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void ExecuteCommand(string tmslOrXmla, bool isXmla = false)` | This methods passes the specified TMSL or XMLA script to the connected instance of Analysis Services. This is useful when you want to refresh data in a table on the AS instance. Note that if you use this method to perform metadata changes to your model, your local model metadata will become out-of-sync with the metadata on the AS instance, and you may receive a version conflict warning the next time you try to save the model metadata. Set the `isXmla` parameter to `true` if sending an XMLA script. | +| `IDataReader ExecuteReader(string dax)` | Executes the specified DAX _query_ against the connected AS database and returns the resulting [AmoDataReader](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.amodatareader?view=analysisservices-dotnet) object. A DAX query contains one or more [`EVALUATE`](https://dax.guide/EVALUATE) statements. Note that you can not have multiple open data readers at once. Tabular Editor will automatically close them in case you forget to explicitly close or dispose the reader. | +| `DataSet ExecuteDax(string dax)` | Executes the specified DAX _query_ against the connected AS database and returns a [DataSet](https://docs.microsoft.com/en-us/dotnet/api/system.data.dataset?view=netframework-4.6) object containing the data returned from the query. A DAX query contains one or more [`EVALUATE`](https://dax.guide/EVALUATE) statements. The resulting DataSet object contains one DataTable for each `EVALUATE` statement. Returning very large data tables is not recommended as they may cause out-of-memory or other stability errors. | +| `object EvaluateDax(string dax)` | Executes the specified DAX _expression_ against the connected AS database and returns an object representing the result. If the DAX expression is scalar, an object of the relevant type is returned (string, long, decimal, double, DateTime). If the DAX expression is table-valued, a [DataTable](https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable?view=netframework-4.6) is returned. | + +The methods are scoped to the `Model.Database` object, but they can also be executed directly without any prefix. + +Darren Gosbell presents an interesting use-case of generating data-driven measures using the `ExecuteDax` method [here](https://darren.gosbell.com/2020/08/the-best-way-to-generate-data-driven-measures-in-power-bi-using-tabular-editor/). + +Another option is to create a reusable script for refreshing a table. For example, to perform a recalculation, use this: + +```csharp +var type = "calculate"; +var database = Model.Database.Name; +var table = Selected.Table.Name; +var tmsl = "{ \"refresh\": { \"type\": \"%type%\", \"objects\": [ { \"database\": \"%db%\", \"table\": \"%table%\" } ] } }" + .Replace("%type%", type) + .Replace("%db%", database) + .Replace("%table%", table); + +ExecuteCommand(tmsl); +``` + +### Clearing the Analysis Services engine cache + +As of Tabular Editor 2.16.6 or Tabular Editor 3.2.3, you can use the following syntax to send raw XMLA commands to Analysis Services. The example below shows how this can be used to clear the AS engine cache: + +```csharp +var clearCacheXmla = string.Format(@" + + {0} + +", Model.Database.ID); + +ExecuteCommand(clearCacheXmla, isXmla: true); +``` + +### Visualize query results + +You can also use the `Output` helper method to visualize the result of a DAX expression returned from `EvaluateDax` directly: + +```csharp +EvaluateDax("1 + 2").Output(); // An integer +EvaluateDax("\"Hello from AS\"").Output(); // A string +EvaluateDax("{ (1, 2, 3) }").Output(); // A table +``` + +![image](https://user-images.githubusercontent.com/8976200/91638299-bbd59580-ea0e-11ea-882b-55bff73c30fb.png) + +...or, if you want to return the value of the currently selected measure: + +```csharp +EvaluateDax(Selected.Measure.DaxObjectFullName).Output(); +``` + +![image](https://user-images.githubusercontent.com/8976200/91638367-6f3e8a00-ea0f-11ea-90cd-7d2e4cff6e31.png) + +And here's a more advanced example that allows you to select and evaluate multiple measures at once: + +```csharp +var dax = "ROW(" + string.Join(",", Selected.Measures.Select(m => "\"" + m.Name + "\", " + m.DaxObjectFullName).ToArray()) + ")"; +EvaluateDax(dax).Output(); +``` + +![image](https://user-images.githubusercontent.com/8976200/91638356-546c1580-ea0f-11ea-8302-3e40829e00dd.png) + +If you're really advanced, you could use SUMMARIZECOLUMNS or some other DAX function to visualize the selected measure sliced by some column: + +```csharp +var dax = "SUMMARIZECOLUMNS('Product'[Color], " + string.Join(",", Selected.Measures.Select(m => "\"" + m.Name + "\", " + m.DaxObjectFullName).ToArray()) + ")"; +EvaluateDax(dax).Output(); +``` + +![image](https://user-images.githubusercontent.com/8976200/91638389-9b5a0b00-ea0f-11ea-819f-d3eee3ddfa71.png) + +Remember you can save these scripts as Custom Actions by clicking the "+" icon just above the script editor. This way, you get an easily reusable collection of DAX queries that you can execute and visualize directly from inside the Tabular Editor context menu: + +![image](https://user-images.githubusercontent.com/8976200/91638790-305e0380-ea12-11ea-9d84-313f4388496f.png) + +### Exporting data + +You can use the following script to evaluate a DAX query and stream the results to a file (the script uses a tab-separated file format): + +```csharp +using System.IO; + +// This script evaluates a DAX query and writes the results to file using a tab-separated format: + +var dax = "EVALUATE 'Customer'"; +var file = @"c:\temp\file.csv"; +var columnSeparator = "\t"; + +using(var daxReader = ExecuteReader(dax)) +using(var fileWriter = new StreamWriter(file)) +{ + // Write column headers: + fileWriter.WriteLine(string.Join(columnSeparator, Enumerable.Range(0, daxReader.FieldCount - 1).Select(f => daxReader.GetName(f)))); + + while(daxReader.Read()) + { + var rowValues = new object[daxReader.FieldCount]; + daxReader.GetValues(rowValues); + var row = string.Join(columnSeparator, rowValues.Select(v => v == null ? "" : v.ToString())); + fileWriter.WriteLine(row); + } +} +``` + +If you come up with some other interesting uses of these methods, please consider sharing them in the [community scripts repository](https://github.com/TabularEditor/Scripts). Thanks! + +*** + +## Replace Power Query server and database names + +Power BI Dataset that import data from SQL Server-based datasources, often contain M expressions that look like the following. Tabular Editor does unfortunately not have any mechanism for "parsing" such an expression, but if we wanted to replace the server and database names in this expression with something else, without knowing the original values, we can exploit the fact that the values are enclosed in double quotes: + +```M +let + Source = Sql.Databases("devsql.database.windows.net"), + AdventureWorksDW2017 = Source{[Name="AdventureWorks"]}[Data], + dbo_DimProduct = AdventureWorksDW2017{[Schema="dbo",Item="DimProduct"]}[Data] +in + dbo_DimProduct +``` + +The following script will replace the first occurrence of a value in double quotes with a server name, and the second occurrence of a value in double quotes with a database name. Both replacement values are read from environment variables: + +```csharp +// This script is used to replace the server and database names across +// all power query partitions, with the ones provided through environment +// variables: +var server = "\"" + Environment.GetEnvironmentVariable("SQLServerName") + "\""; +var database = "\"" + Environment.GetEnvironmentVariable("SQLDatabaseName") + "\""; + +// This function will extract all quoted values from the M expression, returning a list of strings +// with the values extracted (in order), but ignoring any quoted values where a hashtag (#) precedes +// the quotation mark: +var split = new Func>(m => { + var result = new List(); + var i = 0; + foreach(var s in m.Split('"')) { + if(s.EndsWith("#") && i % 2 == 0) i = -2; + if(i >= 0 && i % 2 == 1) result.Add(s); + i++; + } + return result; +}); +var GetServer = new Func(m => split(m)[0]); // Server name is usually the 1st encountered string +var GetDatabase = new Func(m => split(m)[1]); // Database name is usually the 2nd encountered string + +// Loop through all partitions on the model, replacing the server and database names from the partitions +// with the ones specified in environment variables: +foreach(var p in Model.AllPartitions.OfType()) +{ + if (p.Expression.Contains("Source = Sql.Database")) + { + var oldServer = "\"" + GetServer(p.Expression) + "\""; + var oldDatabase = "\"" + GetDatabase(p.Expression) + "\""; + p.Expression = p.Expression.Replace(oldServer, server).Replace(oldDatabase, database); + } +} +``` + +*** + +## Replace Power Query data sources and partitions with Legacy + +If you are working with a Power BI-based model that uses Power Query (M) expressions for partitions against a SQL Server-based data source, you will unfortunately not be able to use Tabular Editor 2's Data Import wizard or perform a schema check (i.e. comparing imported columns with columns in the data source). + +To solve this issue, you can run the following script on your model, to replace the power query partitions with corresponding native SQL query partitions, and to create a legacy (provider) data source on the model, which will work with Tabular Editor 2's Import Data wizard: + +There are two versions of the script: The first one uses the MSOLEDBSQL provider for the created legacy data source, and hardcoded credentials. This is useful for local development. The second one uses the SQLNCLI provider, which is available on Microsoft-hosted build agents on Azure DevOps, and reads credentials and server/database names from environment variables, making the script useful for integration in Azure Pipeliens. + +MSOLEDBSQL version, which reads connection information from M partitions and prompts for user name and password through Azure AD: + +```csharp +#r "Microsoft.VisualBasic" + +// This script replaces all Power Query partitions on this model with a +// legacy partition using the provided connection string with INTERACTIVE +// AAD authentication. The script assumes that all Power Query partitions +// load data from the same SQL Server-based data source. + +// Provide the following information: +var authMode = "ActiveDirectoryInteractive"; +var userId = Microsoft.VisualBasic.Interaction.InputBox("Type your AAD user name", "User name", "name@domain.com", 0, 0); +if(userId == "") return; +var password = ""; // Leave blank when using ActiveDirectoryInteractive authentication + +// This function will extract all quoted values from the M expression, returning a list of strings +// with the values extracted (in order), but ignoring any quoted values where a hashtag (#) precedes +// the quotation mark: +var split = new Func>(m => { + var result = new List(); + var i = 0; + foreach(var s in m.Split('"')) { + if(s.EndsWith("#") && i % 2 == 0) i = -2; + if(i >= 0 && i % 2 == 1) result.Add(s); + i++; + } + return result; +}); +var GetServer = new Func(m => split(m)[0]); // Server name is usually the 1st encountered string +var GetDatabase = new Func(m => split(m)[1]); // Database name is usually the 2nd encountered string +var GetSchema = new Func(m => split(m)[2]); // Schema name is usually the 3rd encountered string +var GetTable = new Func(m => split(m)[3]); // Table name is usually the 4th encountered string + +var server = GetServer(Model.AllPartitions.OfType().First().Expression); +var database = GetDatabase(Model.AllPartitions.OfType().First().Expression); + +// Add a legacy data source to the model: +var ds = Model.AddDataSource("AzureSQL"); +ds.Provider = "System.Data.OleDb"; +ds.ConnectionString = string.Format( + "Provider=MSOLEDBSQL;Data Source={0};Initial Catalog={1};Authentication={2};User ID={3};Password={4}", + server, + database, + authMode, + userId, + password); + +// Remove Power Query partitions from all tables and replace them with a single Legacy partition: +foreach(var t in Model.Tables.Where(t => t.Partitions.OfType().Any())) +{ + var mPartitions = t.Partitions.OfType(); + if(!mPartitions.Any()) continue; + var schema = GetSchema(mPartitions.First().Expression); + var table = GetTable(mPartitions.First().Expression); + t.AddPartition(t.Name, string.Format("SELECT * FROM [{0}].[{1}]", schema, table)); + foreach(var p in mPartitions.ToList()) p.Delete(); +} +``` + +SQLNCLI version reading connection info from environment variables: + +```csharp +// This script replaces all Power Query partitions on this model with a +// legacy partition, reading the SQL server name, database name, user name +// and password from corresponding environment variables. The script assumes +// that all Power Query partitions load data from the same SQL Server-based +// data source. + +var server = Environment.GetEnvironmentVariable("SQLServerName"); +var database = Environment.GetEnvironmentVariable("SQLDatabaseName"); +var userId = Environment.GetEnvironmentVariable("SQLUserName"); +var password = Environment.GetEnvironmentVariable("SQLUserPassword"); + +// This function will extract all quoted values from the M expression, returning a list of strings +// with the values extracted (in order), but ignoring any quoted values where a hashtag (#) precedes +// the quotation mark: +var split = new Func>(m => { + var result = new List(); + var i = 0; + foreach(var s in m.Split('"')) { + if(s.EndsWith("#") && i % 2 == 0) i = -2; + if(i >= 0 && i % 2 == 1) result.Add(s); + i++; + } + return result; +}); +var GetServer = new Func(m => split(m)[0]); // Server name is usually the 1st encountered string +var GetDatabase = new Func(m => split(m)[1]); // Database name is usually the 2nd encountered string +var GetSchema = new Func(m => split(m)[2]); // Schema name is usually the 3rd encountered string +var GetTable = new Func(m => split(m)[3]); // Table name is usually the 4th encountered string + +// Add a legacy data source to the model: +var ds = Model.AddDataSource("AzureSQL"); +ds.Provider = "System.Data.SqlClient"; +ds.ConnectionString = string.Format( + "Server={0};Initial Catalog={1};Persist Security Info=False;User ID={2};Password={3}", + server, + database, + userId, + password); + +// Remove Power Query partitions from all tables and replace them with a single Legacy partition: +foreach(var t in Model.Tables.Where(t => t.Partitions.OfType().Any())) +{ + var mPartitions = t.Partitions.OfType(); + if(!mPartitions.Any()) continue; + var schema = GetSchema(mPartitions.First().Expression); + var table = GetTable(mPartitions.First().Expression); + t.AddPartition(t.Name, string.Format("SELECT * FROM [{0}].[{1}]", schema, table)); + foreach(var p in mPartitions.ToList()) p.Delete(); +} +``` diff --git a/content/localization/zh/Workspace-Database_zh.md b/content/localization/zh/Workspace-Database_zh.md new file mode 100644 index 00000000..98c3fe27 --- /dev/null +++ b/content/localization/zh/Workspace-Database_zh.md @@ -0,0 +1,48 @@ +## Introducing Workspace Databases + +Tabular Editor 3.0 supports editing model metadata loaded from disk with a simultaneous connection to a database deployed to an instance of Analysis Services. We call this database the _workspace database_. Going forward, this is the recommended approach to tabular modeling within Tabular Editor. + +This makes the development workflow a lot simpler, since you only need to hit Save (Ctrl+S) once, to simultaneously save your changes to the disk **and** update the metadata in the workspace database. This also has the advantage, that any error messages returned from Analysis Services, are immediately visible in Tabular Editor upon hitting Save. In a sense, this is similar to the way SSDT / Visual Studio or Power BI Desktop does, except that you are in control of when the workspace database is updated. + +When you load a model from a Model.bim file or folder structure, you will see the following prompt: + +![image](https://user-images.githubusercontent.com/8976200/58166683-a65db180-7c8a-11e9-9df3-be9a716b3ad1.png) + +- **Yes**: Model metadata is loaded from disk and then immediately deployed to an instance of Analysis Services. Tabular Editor will then connect to the newly deployed database. The next time the same model is loaded from disk, Tabular Editor will redeploy and connect to the database automatically. +- **No**: Model metadata is loaded from disk into Tabular Editor as usual, without connecting to an instance of Analysis Services. +- **No, don't ask again**: Same as the option above, but Tabular Editor will not ask again the next time the same model is loaded. + +### Setting up a Workspace Database + +When you select the "Yes" option in the prompt shown above, you will be asked for a servername and (optional) credentials to an instance of Analysis Services. Hitting "OK" will show you a list of databases already on the instance. Tabular Editor assumes that you want to deploy a new database and provides a default name for the new database, based on your Windows username and the current date and time: + +![image](https://user-images.githubusercontent.com/8976200/58179509-a10f5f80-7ca8-11e9-9764-4cb76b9d1a8b.png) + +If you want to use and existing database as your workspace database, simply select it on the list. **Warning: If you choose an existing database, it will be overwritten with the metadata of the model loaded from disk. For this reason it is not recommended to set up workspace databases on a production instance!** + +### The User Options file (.tmuo) + +To track the workspace settings for each model in your file system, Tabular Editor 3.0 introduces a new file of type .tmuo (short for Tabular Model User Options), which will be placed next to the Model.bim or Database.json file. + +The .tmuo file is just a simple json document with the following content: + +```json +{ + "UseWorkspace": true, + "WorkspaceConnection": "Data Provider=MSOLAP;Data Source=localhost", + "WorkspaceDatabase": "AdventureWorks_WS_Feature123" +} +``` + +When loading model metadata from disk, Tabular Editor looks for the presence of a .tmuo file within the same directory as the loaded model file. The name of the .tmuo file must follow the pattern: + +``` +..tmuo +``` + +The reason that the file contains a username, is to prevent multiple developers from inadvertently overwriting each others workspace databases in parallel development workflows. If the file is present and the "UseWorkspace" flag in the file is set to "true", Tabular Editor will perform the following steps when loading a model from disk: + +1. Deploy the model metadata to the workspace database (overwriting existing metadata), using the server- and database name specified in the .tmuo file. +2. Connect to the newly deployed database in "workspace mode". + +When in "workspace mode", Tabular Editor simultaneously saves your model to disk and updates the workspace database, whenever you hit Save (ctrl+s). This lets you rapidly test new code and see error messages provided by Analysis Services, without having to manually deploy the database or invoking File > Save As... or File > Save to Folder... whenever you want to persist model metadata to disk. diff --git a/content/localization/zh/as-cicd_zh.md b/content/localization/zh/as-cicd_zh.md new file mode 100644 index 00000000..a6353f13 --- /dev/null +++ b/content/localization/zh/as-cicd_zh.md @@ -0,0 +1,10 @@ +--- +uid: as-cicd +title: Analysis Services CI/CD with Azure DevOps and Tabular Editor +author: Daniel Otykier +updated: 2021-10-04 +--- + +# Analysis Services CI/CD with Azure DevOps and Tabular Editor + +(WIP) \ No newline at end of file diff --git a/content/localization/zh/beta-16_6_zh.md b/content/localization/zh/beta-16_6_zh.md new file mode 100644 index 00000000..56989f3e --- /dev/null +++ b/content/localization/zh/beta-16_6_zh.md @@ -0,0 +1,95 @@ +# Tabular Editor 3 BETA-16.6 Release Notes + +- Download [Tabular Editor 3 BETA-16.6](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-16.6.x86.msi) +- Download [Tabular Editor 3 BETA-16.6 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-16.6.x64.msi) + +## Updates in BETA-16.6: + +- Fixed an issue with the "Group By Columns" collection editor's Add-button. +- Changed the default Compatibility Level for new Power BI Datasets to 1560. +- Allow creation of new table-level objects (measures, columns, hierarchies) when the currently selected object is a table-level object itself. + +## Updates in BETA-16.5: + +- Installer should now correctly register Tabular Editor 3 as an external tool for Power BI Desktop +- Added the "-nosplash" CLI option, which is used when Power BI Desktop launches Tabular Editor 3, as the splash screen could sometimes cause Tabular Editor 3 to become "hidden" behind Power BI Desktop. After upgrading Tabular Editor 3, make sure you restart Power BI Desktop. +- Download links now uses our Azure CDN which is where we will host Tabular Editor 3 binaries going forward. The following URLs always point to the latest version of Tabular Editor 3: + - https://cdn.tabulareditor.com/files/latest/TabularEditor.3.x86.msi + - https://cdn.tabulareditor.com/files/latest/TabularEditor.3.x64.msi + +## Updates in BETA-16.4: + +A rather big list of bug fixes and minor improvements incoming: + +### General improvements: + +- Name of .pbix file is now used as the database name when saving a .pbix model as a .bim/folder structure. +- Added x64 support (both x64 and x86 builds are targeting "Any CPU", but the latter has the "Prefer32Bits" flag set) +- Installer has been updated. It's now using WiX, which ensures that the registry and local app data folder are neatly cleaned when the product is uninstalled. In addition, it looks better :-) +- Macro recorder now supports recording of most (all?) model changes that can be done through the UI +- Added support for multi-column scalar predicates, which is a new DAX syntax that was added recently. Tabular Editor tries to guess which version of Analysis Services is used based on the model metadata, but since this is not always possible (e.g. when working offline), you can override how Tabular Editor treats multi-column scalar predicate table filter expressions under Tools > Preferences > DAX Editor > General > Semantic Engine Features). +- Updated TOM to version 19.18.0. + +### Usability improvements: + +- Increased the "hitbox" of the expand/collapse arrow in TOM Explorer increased (see [this comment](https://github.com/TabularEditor3/PublicPreview/issues/81#issuecomment-789637586)) +- Double-clicking the icon next to an object in the TOM Explorer now brings the DAX Expression Editor into view. + +### Bug fixes: + +- Fixed DAX semantic analyzer issue, which would cause "ghost" error messages in certain expressions +- Fixed issue #75 +- Fixed issue #77 +- Fixed issue #84 +- Fixed a number of crashes based on telemetry. @**Everyone**: Keep sending those error reports when an exception occurs, and please provide descriptions - they are invaluable when trying to figure out what went wrong! Thanks! + +## Updates in BETA-16.3: + +- "Custom Actions" have been renamed to "Macros". + - There's a new window that lets you manage all macros currently defined. Edit an existing macro by doubleclicking on an item. + - Once a C# script is saved as a macro, the document will update the macro on subsequent saves (Ctrl+S). Use File > Save As... if you need to save the script as a file. + - Macros can have identical names. They are distinguished internally using an auto-assigned ID. + - Fixed an issue that prevented a macro from being saved +- The Window menu now also contains a "New" submenu, containing the same menu items as "File > New" +- Inactive toolbars and menus are now hidden by default, to reduce UI cluttering (can be changed in Tools > Preferences > User Interface). +- Fixed a DAX parser bug that caused `GENERATESERIES` to provide a table with a wrongly-named column, possibly related to #61 +- Fix for issue #74 (EndBatch() called before BeginBatch() crash) +- Added warning and refresh of local TOM tree upon save to DB, if changes were made to the deployed model metadata outside of Tabular Editor + +## Updates in BETA-16.2: + +- Table Preview can now auto-refresh similar to DAX queries/pivot grids (see issue #73) +- Fixed a bug that would prevent Table Preview from showing a calculated table that had not been refreshed +- DAX script support for creating calculated columns and calculated tables +- DAX scripts can now be partially executed (see issue #69). 4 buttons should light up on the "DAX Script" toolbar, when editing a DAX script. These buttons have the following shortcuts: + - `F5` will apply the full script. + - `Shift+F5` will apply the full script and also sync the connected database. + - `F8` will apply only the current selection. + - `Shift+F8` will apply the current selection and sync the connected database. +- Added a watermark to the diagram view to guide users on how to add tables to the diagram (see issue #76) +- Background Best Practice Analysis should no longer freeze the UI (see issue #79) +- Toolbar buttons/context menu options for ignoring rules/objects on the Best Practice Analyzer view, should now work correctly +- The "please wait" form should no longer overlap any dialogs being spawned from a C# script +- Various bug fixes (possibly related to issue #74) + +## Updates in BETA-16.1: + +- Measures now use a "calculator" icon, to better align the experience with Power BI Desktop. Calculation Item icons have also been changed slightly, so that they are distinguishable from measures. +- Key columns are now shown in **bold** +- Added "Define Measure" and "Inline Measure" refactoring options +- Improved auto-complete behaviour around DEFINE / EVALUATE statements of DAX queries. For example, autocomplete can now also suggest measures, columns and tables defined inside the query. +- Auto-complete now also suggests measures for the Name parameter of functions such as SUMMARIZECOLUMNS, ADDCOLUMNS, etc., completing both the Name and the Expression parameter at once: + ![autocomplete names](https://user-images.githubusercontent.com/8976200/107629428-66aada80-6c62-11eb-91e4-d5528947840a.gif) +- Revisited #42. +- Deployment Wizard now stores deployment preferences (destination + options) to the .tmuo file sitting next to the Model.bim or Database.json file on disk. This makes it easier to perform deployments when switching between different models, if each model is always deployed to the same destination. +- Updated TOM to 19.16.3. Should fix issue #63. +- Fixed issue #64. +- Fixed a bug with model files appearing in the "Recent Files" menu. + +## Updates in BETA-16.0: + +- Deployment Wizard updated. Also fixes issue #42 and #43. +- Support for DEFINE COLUMN and TABLE syntax in DAX queries +- The File menu now has a "Recent Files" and a "Recent Tabular Models" submenu. The former holds references to the 10 most recent DAX scripts, model diagrams, DAX queries and C# scripts that were saved/opened. The latter holds references to the 10 most recent model files (bim / pbit / folder). +- Fixed #67 +- Fixed #66 diff --git a/content/localization/zh/beta-17_4_zh.md b/content/localization/zh/beta-17_4_zh.md new file mode 100644 index 00000000..092c1eec --- /dev/null +++ b/content/localization/zh/beta-17_4_zh.md @@ -0,0 +1,66 @@ +# Tabular Editor 3 BETA-17.4 Release Notes + +- Download [Tabular Editor 3 BETA-17.4](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-17.4.x86.msi) +- Download [Tabular Editor 3 BETA-17.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-17.4.x64.msi) + +## Updates in BETA-17.4: + +- Fix issue with DAX semantic analyzer reporting false circular dependencies in some situations. +- DAX editors now shows keyboard shortcuts in right-click context menu +- Peek Definition editor can now be closed by pressing ESC while the cursor is inside the Peek Definition editor. Also, AutoComplete/Calltips should no longer show up within the editor, since it is read-only by design. +- Allow specifying an AlternateOf BaseColumn property when using the "Count" summarization. +- Improved support for connection strings that point to Power BI service dataset. + +## Updates in BETA-17.3: + +- Tables can now be dragged into the Diagram View (see #15) +- Inline/Define measures in DAX script mode now work as expected (see #91) +- VertiPaq Analyzer should now correctly pick up data model changes made outside of Tabular Editor when collecting statistics +- VertiPaq Analyzer data can now be accessed through scripts (see #90): There's a new global script method, `CollectVertiPaqAnalyzerStats();`, as well as two new extension methods for Tables and Columns: `.GetCardinality()` and `.GetTotalSize()`. +- Multiple improvements to the AutoComplete feature. For example, when typing code between square brackets (see #92) +- Circular dependencies between query-scoped objects in a DAX query or scripted objects in a DAX script, should no longer cause a crash +- Added a new DAX Auto Formatting option to control whether extension columns are always qualified, even when the table name is blank, such as `''[MyExtColumn]`. +- Fixed a crash that would sometimes occur when double-clicking an item in the Messages View +- Fixed error messages for the ISSELECTEDMEASURE, SELECTEDMEASURE, SELECTEDMEASURENAME and SELECTEDMEASUREFORMATSTRING functions, when used outside of a calculation item or measure expression. + +## Updates in BETA-17.2: + +- Fixed an issue with VertiPaq Analyzer assembly versions. +- Added "Partitions" pane to VeritPaq Analyzer. +- Installer will no longer delete the `%LocalAppData%\TabularEditor3` folder contents, allowing users to persist settings through upgrades/uninstalls. +- Support for drag/drop of objects into DAX and C# editors (#15). +- Support for drag/drop of selected text in all code editors. Hold down CTLR while dragging to copy the selection. +- Support for the new OneWay_LeftFiltersRight and OneWay_RightFiltersLeft arguments in the DAX CROSSFILTER function. +- Upgraded TOM to 19.20.1. +- Various stability improvements. + +## Updates in BETA-17.1: + +![image](https://user-images.githubusercontent.com/8976200/112887423-762b9900-90d3-11eb-8248-d9da55fe8fe3.png) + +- Added [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/) (you may need to delete the Layout.gz file under %LocalAppData%\TabularEditor3 and/or reset to the Default window workspace if the new view doesn't appear in the UI) + - Collects statistics (column and table cardinalities and sizes) which will then show up in the TOM Explorer tooltips as well as when hovering over a column or table reference in any DAX editor. + - Import/Export statistics from/to VPAX files + - Load a model from a VPAX file +- Allow editing synonyms +- Include SortByColumn in dependency view + +## Bug fixes in BETA-17.1: + +- Fixed issue with copy/pasting cultures overwriting existing cultures + +## Updates in BETA-17.0: + +- Tabular Editor 3 now lets you edit M Expressions and Partition queries in the main expression editor (see #2) +- All 4 flavours of code editors (DAX, C#, SQL, M) can now be configured independently under Tools > Preferences > Text Editors (e.g. line numbers, indentation guides, whitespace, etc.) +- Code editors now supports multi-paste (#87). You can toggle this feature off under Tools > Preferences > Text Editors > General. + +## Bug fixes in BETA-17.0: + +- Macro recorder now generates proper code to reference the original object, when an objects name is changed. +- The ALT key will no longer shift focus to the menu bar (this was interfering with block-selections in text editors). Instead, you can use F10 to switch the focus. ALT+letter key combinations can still be used to navigate menus. +- Tabular Editor 3 now properly deals with the LineageTag property, for example when copying a measure within a Power BI Desktop model +- Macros can now use the FormatDax method. +- Various TOMWrapper bugfixes ported from Tabular Editor 2. +- Fixed property grid behavior for read-only items (they are now grayed-out in the property grid). +- Added right-click options on certain properties in the property grid (for example to add/remove AlternateOf objects, KPIs and more). diff --git a/content/localization/zh/beta-18_1_zh.md b/content/localization/zh/beta-18_1_zh.md new file mode 100644 index 00000000..f9e62d3d --- /dev/null +++ b/content/localization/zh/beta-18_1_zh.md @@ -0,0 +1,38 @@ +# Tabular Editor 3 BETA-18.1 Release Notes + +- Download [Tabular Editor 3 BETA-18.1](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.1.x86.msi) +- Download [Tabular Editor 3 BETA-18.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.1.x64.msi) + +## New features in this release: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in this release: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor3/PublicPreview/blob/master/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/zh/beta-18_2_zh.md b/content/localization/zh/beta-18_2_zh.md new file mode 100644 index 00000000..f012c218 --- /dev/null +++ b/content/localization/zh/beta-18_2_zh.md @@ -0,0 +1,42 @@ +# Tabular Editor 3 BETA-18.2 Release Notes + +- Download [Tabular Editor 3 BETA-18.2](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.2.x86.msi) +- Download [Tabular Editor 3 BETA-18.2 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.2.x64.msi) + +## Bugfixes in BETA-18.2: + +- The DAX parser now correctly recognizes object names containing double quotes (see issue #22). + +## New features in BETA-18.1: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in BETA-18.1: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor3/PublicPreview/blob/master/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/zh/beta-18_3_zh.md b/content/localization/zh/beta-18_3_zh.md new file mode 100644 index 00000000..9eb4de06 --- /dev/null +++ b/content/localization/zh/beta-18_3_zh.md @@ -0,0 +1,48 @@ +# Tabular Editor 3 BETA-18.3 Release Notes + +- Download [Tabular Editor 3 BETA-18.3](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.3.x86.msi) +- Download [Tabular Editor 3 BETA-18.3 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.3.x64.msi) + +## Bugfixes in BETA-18.3: + +- Improved semantic analyzer performance on large models (regression in BETA-18.x) +- Queuing a data refresh operation should no longer freeze the UI +- Keyboard buttons (left/right arrows and F2 for rename) may now again be used to navigate the Tabular Explorer tree + +## Bugfixes in BETA-18.2: + +- The DAX parser now correctly recognizes object names containing double quotes (see issue #22). + +## New features in BETA-18.1: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in BETA-18.1: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor/TabularEditor3/blob/master/media/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/zh/beta-18_4_zh.md b/content/localization/zh/beta-18_4_zh.md new file mode 100644 index 00000000..ddbca1c0 --- /dev/null +++ b/content/localization/zh/beta-18_4_zh.md @@ -0,0 +1,59 @@ +# Tabular Editor 3 BETA-18.4 Release Notes + +- Download [Tabular Editor 3 BETA-18.4](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.4.x86.msi) +- Download [Tabular Editor 3 BETA-18.4 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.4.x64.msi) + +## New features in BETA-18.4: + +- Tabular Editor 3 will now store (encrypted) credentials for data sources in the personal .tmuo file. This is ideal when using a workspace database, as you can then specify a set of credentials different from those defined in the Model.bim file. If you're using version control, make sure to ignore the .tmuo extension. Even though the credentials in the file are encrypted with the Windows user key, the idea is that each developer can have their own .tmuo file containing credentials and preferences that apply only for them, and therefore this file should not be included in version control. +- Tabular Editor 3 now prompts for credentials that are going to be overwritten during a deployment operation, so you no longer have to set the credentials through another tool after deployment. Please note that Power Query data sources will always have their credentials wiped during a deployment operation, so credentials for these types of data sources must be entered upon every deployment. +- Upon creating a new model, you will now have the option to connect to a workspace database immediately (recommended). + +## Bugfixes in BETA-18.4: + +- Fixed an issue with keyboard shortcuts and certain actions (Undo/Redo, etc.) not always being enabled when switching the focus between different editors. +- Find/replace dialog now has a minimum size to avoid scrollbars. + +## Bugfixes in BETA-18.3: + +- Improved semantic analyzer performance on large models (regression in BETA-18.x) +- Queuing a data refresh operation should no longer freeze the UI +- Keyboard buttons (left/right arrows and F2 for rename) may now again be used to navigate the Tabular Explorer tree + +## Bugfixes in BETA-18.2: + +- The DAX parser now correctly recognizes object names containing double quotes (see issue #22). + +## New features in BETA-18.1: + +- Update Table Schema from Power Query sources (see below) + +## Bugfixes in BETA-18.1: + +- Tabular Editor will now remember skin settings between upgrades +- Fixed a bug with lineage tags causing crashes when copying Calculated Tables or Calculation Group Tables +- Fixed a false error on the COALESCE and COMBINEVALUES DAX functions +- Included Microsoft.AnalysisServices.dll in the distribution, which should ensure that Tabular Editor can properly import/export VPAX files +- Tabular Editor will now automatically reestablish connection to AS for data refresh purposes + +## Update Table Schema from Power Query sources + +A new release of the Tabular Editor 3 beta is here. And I'm really excited about this one, for one particular reason: + +For the first time ever, Tabular Editor can now detect schema changes on Power Query data sources and partitions. And not just for relational data sources, but for ANY Power Query expression that can be evaluated by your Analysis Services engine. "How on earth is that even possible?!?", you might be thinking. Well, pay close attention to that last sentence: "ANY Power Query expression that can be evaluated by your Analysis Services engine". + +A little known fact about the Analysis Services engine is that it is actually a transactional system. This means that we can start a transaction against a database that is already deployed on Analysis Services, make some metadata changes, refresh some data, query some data and then finally roll back the transaction, leaving the database in the original state as if we didn't even touch it at all. + +So, in order to detect schema changes for Power Query partitions, Tabular Editor 3 will now add a hidden, temporary table to the model, populate that table using the M-function [`Table.Schema`](https://docs.microsoft.com/en-us/powerquery-m/table-schema) on the source query that we want to detect the schema for. Then, that temporary table is refreshed on the server (using the credentials that are already present on the server to access the data source) - this refresh only takes a split second, thanks to query folding happening inside the M engine. Finally, Tabular Editor will query the table to read the schema, before rolling back the entire transaction. The result: + +![image](https://github.com/TabularEditor/TabularEditor3/blob/master/media/update%20schema.gif?raw=true) + +The only caveat is of course that Tabular Editor 3 has to be connected to an instance of Analysis Services, but it doesn't matter whether or not the model you're working with holds any data - as long as the credentials to the data sources are stored in AS (and AS can actually access the data source). This technique is particularly useful if you use Tabular Editor 3's [workspace mode](https://docs.tabulareditor.com/Workspace-Database.html). + +In addition to detecting column names and data types, Tabular Editor 3 will also let you update the Description property from the source (if present). On SQL Server sources, this would be the MS_Description extended property. If a column is renamed in the source, it will show up in the Apply Schema Changes dialog as a column import and a column remove. However, as shown in the GIF above, if you Ctrl+Right Click on these two schema changes, you can combine them as a single "rename source column" schema change. The advantage of this approach, is that Tabular Editor 3 will automatically fix up any DAX expressions that reference the renamed column. + +### Limitations in this release: + +- The schema compare option is only available for Power Query partitions while Tabular Editor is connected to an instance of Analysis Services +- Schema compare while offline will only be available for Legacy (Provider) partitions, similar to Tabular Editor 2.X. However, this functionality is not included in BETA-18.1, as I am initially looking for feedback on schema compare for Power Query partitions. Both this feature and the Import Tables Wizard will be available in the next beta release. +- This feature can be used on a Power BI Desktop model as well, but keep in mind that adding/modifying/deleting columns on a table is not among the [supported modeling operations for External Tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). Also, be aware that Power BI Desktop may be caching metadata for certain types of data sources, so you may have to run a refresh within Power BI Desktop before Tabular Editor can pick up the schema changes. diff --git a/content/localization/zh/beta-18_5_zh.md b/content/localization/zh/beta-18_5_zh.md new file mode 100644 index 00000000..a322b59a --- /dev/null +++ b/content/localization/zh/beta-18_5_zh.md @@ -0,0 +1,20 @@ +- Download [Tabular Editor 3 BETA-18.5](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.5.x86.msi) +- Download [Tabular Editor 3 BETA-18.5 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.BETA-18.5.x64.msi) +- [All releases](https://docs.tabulareditor.com/projects/te3/en/latest/downloads.html) + +## New features in BETA-18.5: + +- The Search dialog (CTRL+F) now supports searching the entire model. When this option is selected in the dropdown, another dropdown appears that lets you choose which object properties to search. There are also options for regular expressions, backslash expressions and also [Dynamic LINQ search, similar to Tabular Editor 2.x](https://docs.tabulareditor.com/Advanced-Filtering-of-the-Explorer-Tree.html) (Dynamic LINQ can also be enabled by entering `:` as the first character in the "Find what" field). Search results are displayed in a separate window, and double-clicking on an item in the search results window will take you directly to that item, highlighting the relevant property in the property grid: + +![image](https://user-images.githubusercontent.com/30911111/119983803-edd94f80-bfc0-11eb-91cb-aee084e0c83d.png) + +- Added support for DAX date literal syntax `dt"2021-05-27"` +- Updated TOM to version 19.21.0 + +## Bugfixes and minor updates in BETA-18.5: + +- Added multiline string editor for table SourceExpressions +- Ensure relationship names are not regenerated when cutting and pasting +- Added BPA support for the `it` keyword in FixExpressions, see https://github.com/TabularEditor/TabularEditor/issues/846 +- Improved behavior of Find/Replace window when switching between documents/UI elements +- Fixed a bug with the precedence order of the NOT keyword, see https://github.com/TabularEditor/TabularEditor3/issues/5. diff --git a/content/localization/zh/boosting-productivity-te3_zh.md b/content/localization/zh/boosting-productivity-te3_zh.md new file mode 100644 index 00000000..4a7bce6c --- /dev/null +++ b/content/localization/zh/boosting-productivity-te3_zh.md @@ -0,0 +1,26 @@ +--- +uid: boosting-productivity-te3 +title: Boosting productivity with Tabular Editor 3 +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Boosting productivity with Tabular Editor 3 + +
    + +This section contains a number of articles that will let you quickly become familiar with Tabular Editor 3 and its main features, with an emphasis on how to get stuff done in the most productive way possible. + +Below is an overview of the articles and what you will learn in each: + +- @importing-tables-data-modeling: This article describes how to import tables, upate table schemas and visualize and edit relationships. +- @refresh-preview-query: This article describes how to schedule refresh operations, how to preview table data, how to view summarized data using Pivot Grids, how to create and execute DAX queries and how to use Tabular Editor 3's integrated version of [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/). +- @creating-and-testing-dax: This article introduces Tabular Editor 3's powerful DAX editor and demonstrates how to quickly add and edit DAX calculations to your model such as measures, calculated columns and calculated tables. +- @dax-script-introduction: This article demonstrates how to use the DAX scripting feature, to write, maintain and test complex business logic across multiple measures, by combining their definition in a single DAX script. +- @bpa: This article provides more details on the Best Practice Analyzer, and how to set up customizable Best Practice rules to improve the code quality of your models. +- @cs-scripts-and-macros: This article introduces the concepts of C# scripts in Tabular Editor 3, the script recorder and how to save scripts as reusable macros that can be integrated into the UI. +- @personalizing-te3: This article takes you through the wide range of configuration options and preferences available in Tabular Editor 3, to tweak the tool to your needs. + +# Next steps + +- @downloads \ No newline at end of file diff --git a/content/localization/zh/bpa-view_zh.md b/content/localization/zh/bpa-view_zh.md new file mode 100644 index 00000000..d9937aa6 --- /dev/null +++ b/content/localization/zh/bpa-view_zh.md @@ -0,0 +1,13 @@ +--- +uid: bpa-view +title: Best Practice Analyzer view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +[!include[using-bpa](~/content/common/using-bpa.md)] diff --git a/content/localization/zh/bpa_zh.md b/content/localization/zh/bpa_zh.md new file mode 100644 index 00000000..19d64d45 --- /dev/null +++ b/content/localization/zh/bpa_zh.md @@ -0,0 +1,116 @@ +--- +uid: bpa +title: Improve code quality with the Best Practice Analyzer +author: Daniel Otykier +updated: 2021-11-02 +--- + +# Improve code quality with the Best Practice Analyzer + +By now, you are probably already aware that the Tabular Object Model (TOM) is a relatively complex data structure, with many different types of objects and properties. It is not always clear what the best values to assign to these properties are, and many times it depends on specific use cases or model designs. Tabular Editor's **Best Practice Analyzer** continuously scans the TOM for violations of best practice rules that you can define. This helps you verify that object properties are always set to their ideal values. + +Things you can check with the Best Practice Analyzer: + +- **DAX Expressions** Create rules that warn you when certain DAX functions or constructs are used. +- **Formatting** Create rules that remind you to specify format strings, descriptions, etc. +- **Naming conventions** Create rules that check whether certain types of objects (e.g. key columns, hidden columns, etc.) follow certain name patterns. +- **Performance** Create rules that check various performance-related aspects of your model, for example to encourage reducing the number of calculated columns, etc. + +The Best Practice Analyzer has access to the full metadata of the model, and can also access VertiPaq Analyzer statistics for more advanced scenarios. + +> [!NOTE] +> Tabular Editor does not ship with any rules out-of-the-box. You will have to define your own rules initially, or use a set of standard rules such as [those recommended by the Power BI CAT Team](https://powerbi.microsoft.com/en-ca/blog/best-practice-rules-to-improve-your-models-performance/). + +# Managing Best Practice Rules + +In order to add, remove or modify rules applying to your model, use the "Tools > Manage BPA Rules..." menu option. + +![Bpa Manager](~/content/assets/images/bpa-manager.png) + +This UI contains two lists: The top list represents the **collections** of rules that are currently loaded. Selecting a collection in this list, will display all the rules that are defined within this collection in the bottom list. When a model is loaded, you will see the following three rule collections: + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%LocalAppData%\TabularEditor3\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +If the same rule (by ID) is located in more than one collection, the order of precedence is from top to bottom, meaning a rule defined within the model takes precedence over a rule, with the same ID, defined on the local machine. This allows you to override existing rules, for example to take model specific conventions into account. + +At the top of the list, you'll see a special collection called **(Effective rules)**. Selecting this collection will show you the list of rules that actually apply to the currently loaded model, respecting the precedence of rules with identical ID's, as mentioned above. The lower list will indicate which collection a rule belongs to. Also, you will notice that a rule will have its name striked out, if a rule with a similar ID exists in a collection of higher precedence: + +![Rule Overrides](~/content/assets/images/rule-overrides.png) + +## Adding additional collections + +Rule collections can be added to a specific model. If you have a rules file located on a network share, you can include that file as a rule collection in the current model. If you have write access to the location of the file, you'll also be able to add/modify/remove rules from the file. Rule collections that are added this way take precedence over rules that are defined within the model. If you add multiple such collections, you can shift them up and down to control their mutual precedence. + +Click the "Add..." button to add a new rule collection to the model. This provides the following options: + +![Add Best Practice rule collection](~/content/assets/images/add-rule-file.png) + +- **Create new Rule File**: This will create a new, empty, .json file at a specified location, which you can subsequently add rules to. When choosing the file, notice that there is an option for using relative file paths. This is useful when you want to store the rule file in the same code repository as the current model. However, please be aware that a relative rule file reference only works, when the model has been loaded from disk (since there is no working directory when loading a model from an instance of Analysis Services). +- **Include local Rule File**: Use this option if you already have a .json file containing rules, that you want to include in your model. Again, you have the option of using relative file paths, which may be beneficial if the file is located close to the model metadata. If the file is located on a network share (or generally, on a drive different than where the currently loaded model metadata resides), you can only include it using an absolute path. +- **Include Rule File from URL**: This option lets you specify an HTTP/HTTPS URL, that should return a valid set of rules (in json format). This is useful if you want to include rules from an online source, for example the [standard BPA rules](https://raw.githubusercontent.com/TabularEditor/BestPracticeRules/master/BPARules-standard.json) from the [BestPracticeRules GitHub site](https://github.com/TabularEditor/BestPracticeRules). Note that rule collections added from online sources will be read-only. + +## Modifying rules within a collection + +The lower part of the screen will let you add, edit, clone and delete rules within the currently selected collection, provided you have write access to the location where the collection is stored. Moreover, the "Move to..." button allows you to move or copy the selected rule to another collection, making it easy to manage multiple collections of rules. + +## Adding rules + +To add a new rule to a collection, click on the **New rule...** button. This brings up the Best Practice Rule editor (see screenshot below). + +![Bpa Rule Editor](~/content/assets/images/bpa-rule-editor.png) + +When creating a new rule, you must specify the following details: + +- **Name**: The name of the rule, which will be displayed to users of Tabular Editor +- **ID**: An internal ID of the rule. Must be unique within a rule collection. If multiple rules have identical IDs across different collections, only the rule within the collection of the highest precedence is applied. +- **Severity**: The severity is not used within Tabular Editor's UI, but when running a Best Practice Analysis through [Tabular Editor's command line interface](xref:command-line-options), the number determines how "severe" a rule violation is. + - 1 = Information only + - 2 = Warning + - 3 (or above) = Error +- **Category**: This is used for logically grouping rules together to make management of rules easier. +- **Description** (optional): Can be used to provide a description of what the rule is intended for. Will be shown in the Best Practice Analyzer view as a tooltip. You may use the following placeholder values within the description field, to provide a more contextual message: + - `%object%` returns a fully qualified DAX reference (if applicable) to the current object + - `%objectname%` returns only the name of the current object + - `%objecttype%` returns the type of the current object +- **Applies to**: Select the type of object(s) to which the rule should apply. +- **Expression**: Type a [Dynamic LINQ](https://dynamic-linq.net/expression-language) search expression which should evaluate to `true` for those objects (among the object types selected in the **Applies to** dropdown) that violate the rule. The Dynamic LINQ expression can access the TOM properties available on the selected object types, as well as a wide range of standard .NET methods and properties. +- **Minimum compatibility level**: Some TOM properties are not available at all compatibility levels. If you are creating generic rules, use this dropdown to specify the minimum compatibility level of the models to which the rule should apply. + +When a rule is saved to a rule collection on disk, all of the above properties are stored in a JSON format. You can add/edit/delete rules by editing the JSON file as well, which also allows you to specify the `FixExpression` property on a rule. This is a string that is used to generate a [C# script](xref:cs-scripts-and-macros) which will be applied to the model in order to fix the rule violation. + +# Using the Best Practice Analyzer view + +Tabular Editor displays the best practice rule violations within the **Best Practice Analyzer view**. You can also see the number of rule violations in the status bar at the bottom of the main window. To bring the view into focus, use the **View > Best Practice Analyzer** menu option or blick on the "# BP issues" button in the status bar. + +![Best Practice Analyzer View](~/content/assets/images/best-practice-analyzer-view.png) + +The **Best Practice Analyzer view** shows a list of all rules that have objects in violation. Below each rule is a list of the violating objects. You can double-click on an object in the list, to navigate to that object in the **TOM Explorer**. + +![Item options](~/content/assets/images/bpa-options.png) + +When right-clicking on an object, you are presented with a number of options as shown above. These are: + +- **Go to object**: This is identical to double-clicking on an object, in order to navigate to that object in the **TOM Explorer**. +- **Ignore object**: This adds an annotation on the object, instructing the Best Practice Analyzer to ignore this particular rule on that object. Ignored rules are specified using their ID. +- **Generate fix script**: This option is available only if a rule has the `FixExpression` property specified. When choosing this option, Tabular Editor creates a new C# script based on the `FixExpression` of the selected rule(s). +- **Apply fix**: This option is available only if a rule has the `FixExpression` property specified. When choosing this option, Tabular Editor executes the `FixExpression` of the selected rule(s) in order to automatically fix the rule violation. + +> [!NOTE] +> You can multi-select objects in the Best Practice Analyzer view, by holding down the Shift or Ctrl keys. + +The options shown above are also available as toolbar buttons at the top of the **Best Practice Analyzer view**. In addition, there are buttons available for expanding/collapsing all items, showing ignored rules/objects and for performing a manual refresh (which is needed when background scans are disabled, see below). + +# Disabling the Best Practice Analyzer + +In some cases, you may want to disable the Best Practice Analyzer background scan. For example, when you have rules that take a relatively long time to evaluate, or when you are working with very large models. + +The background scan can be disabled under **Tools > Preferences > Features > Best Practice Analyzer** by unchecking the **Scan for Best Practice violations in the background**. + +Note that you can still manually perform a scan using the **Refresh** button of the **Best Practice Analyzer view**, as mentioned above, even when background scans are disabled. + +# Next steps + +- @cs-scripts-and-macros +- @personalizing-te3 \ No newline at end of file diff --git a/content/localization/zh/calendars_zh.md b/content/localization/zh/calendars_zh.md new file mode 100644 index 00000000..76acb477 --- /dev/null +++ b/content/localization/zh/calendars_zh.md @@ -0,0 +1,53 @@ +--- +uid: calendars +title: Calendars (Enhanced Time Intelligence) +author: Daniel Otykier +updated: 2025-09-15 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Calendars (Enhanced Time Intelligence) + +The September 2025 release of Power BI Desktop introduced a new Public Preview feature called "Enhanced Time Intelligence". This feature lets you define custom calendars in your semantic model, and it also introduces 8 new DAX functions that work with these calendars, enabling week-based time intelligence calculations that were difficult to perform previously. + +Tabular Editor 3 has support for Calendars and the new DAX functions since version 3.23.0. + +## Defining a Calendar + +![Creating a calendar](~/content/assets/images/calendar-create.png) + +1. Right-click on a table in your model (typically a Date table) and select **Create > Calendar...**. +2. Give your calendar a name, e.g. "Fiscal" + +Once calendars are added to a table, they will be shown in the TOM Explorer under the **Calendars** node: + +![Calendar in TOM Explorer](~/content/assets/images/calendar-tom-explorer.png) + +Before you can use a calendar in your DAX calculations, you need to configure it by specifying which columns in the table represent the different calendar attributes. You can do this by right-clicking on the calendar in the TOM Explorer, then choosing the **Edit Column Mappings...** option: + +![Editing calendar column mappings](~/content/assets/images/edit-calendar-mappings.png) + +For each calendar, you can add one or more so-called **Column Associations**. Each such association maps a column from the table, to a specific **Time Unit** (e.g. Year, Month, Week, etc.). You can also add additional associated columns for each mapping, which are typically used for columns that represent the same time unit, but in a different format. For example, you might have a "Month" column that contains the month number (1-12), and a "Month Name" column that contains the month name ("January", "February", etc.). Both of these columns can be associated with the "MonthOfYear" time unit. + +![Calendar column associations](~/content/assets/images/calendar-example.png) + +## Using Calendars in DAX + +Once you've defined a calendar and mapped its columns, you can start using it in your DAX calculations. Calendars work with all DAX functions that accept a date column as input (such as [`TOTALYTD`](https://dax.guide/totalytd), [`CLOSINGBALANCEMONTH`](https://dax.guide/closingbalancemonth) and [`DATEADD`](https://dax.guide/dateadd)). + +Moreover, 8 new DAX functions for week-based time intelligence have been introduced. These exclusively work with calendars: + +- [`CLOSINGBALANCEWEEK`](https://dax.guide/closingbalanceweek) +- [`OPENINGBALANCEWEEK`](https://dax.guide/openingbalanceweek) +- [`STARTOFWEEK`](https://dax.guide/startofweek) +- [`ENDOFWEEK`](https://dax.guide/endofweek) +- [`NEXTWEEK`](https://dax.guide/nextweek) +- [`PREVIOUSWEEK`](https://dax.guide/previousweek) +- [`DATESWTD`](https://dax.guide/dateswtd) +- [`TOTALWTD`](https://dax.guide/totalwtd) + +Click the links above to learn more about each function. \ No newline at end of file diff --git a/content/localization/zh/code-actions_zh.md b/content/localization/zh/code-actions_zh.md new file mode 100644 index 00000000..d285158e --- /dev/null +++ b/content/localization/zh/code-actions_zh.md @@ -0,0 +1,133 @@ +--- +uid: code-actions +title: Code Actions +author: Daniel Otykier +updated: 2024-10-30 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Code Actions + +Tabular Editor 3.18.0 introduces a new feature called **Code Actions**. This feature is enabled by default but can be disabled in the **Tools > Preferences** dialog under **Text Editors > DAX Editor > Code Actions**. + +Code Actions is a productivity feature that discretely provides suggestions for improving your DAX code. You can apply the suggestions with a single click. Code Actions also provides easy access to common code refactoring operations. + +Code Actions are separated into three different categories: + +1. **Improvements**: These are recommended suggestions for improving your DAX code in terms of: + - Following best practices + - Avoiding common pitfalls and anti-patterns + - Avoiding obsolete or deprecated DAX features + - Writing better, more performant DAX code +2. **Readability**: These are suggestions for making your DAX code more readable by... + - Simplifying complex expressions, when possible + - Remove redundant or unnecessary code + - Applying consistent formatting and naming conventions +3. **Rewrites**: These are suggestions for refactoring your DAX code. They are not necessarily improvements but are often useful for larger code refactorings. Examples are: + - Convert DAX "syntax sugar" to more verbose but more explicit code + - Rename all occurrences of a variable or an extension column + - Format code + +## How to use Code Actions + +A new command and corresponding toolbar/menu buttons have been added, **Show Code Actions**, with a default keyboard shortcut of `Ctrl+.`. This command will show the applicable Code Actions at the current cursor position: + +![Code Action Invoke Menu](~/content/assets/images/code-action-invoke-menu.png) + +You can also find the applicable Code Actions through the **Refactor** submenu of the right-click context menu: + +![Code Action Refactor Submenu](~/content/assets/images/code-action-refactor-submenu.png) + +Lastly, a lightbulb or screwdriver icon is shown in the editor's left margin when the cursor is placed on a code segment with applicable actions. Clicking on the icon will also bring up the Code Actions menu: + +![Code Actions Margin](~/content/assets/images/code-action-margin.png) + +When you hover the mouse cursor over an action in the Code Actions menu, a tooltip will show more information about the action. Click the "Learn more" link, to view the knowledge-base (KB) article for the action. + +![Code Action Tooltip](~/content/assets/images/code-action-tooltip.png)] + +## Code Action indicators + +**Improvements** and **Readability** Code Actions will also be indicated visually in the code editor. This lets you quickly determine which parts of your code can be improved or made more readable. + +- **Improvements** are shown with orange dots under the first few characters of the code segment (unless that code segment already displays an orange warning squiggly). A _lightbulb_ icon will appear in the left margin when the cursor is moved over the code segment. +- **Readability** actions are shown with teal green dots under the first few characters of the code segment. When the cursor is moved over the code segment, a _screwdriver_ icon will appear in the left margin. +- **Rewrites** are not visually indicated in the code itself; however, the _screwdriver_ icon will appear in the left margin when the cursor is placed on a code segment with applicable rewrites. + +## Apply to all occurrences + +Some Code Actions can be applied to all occurrences within the current DAX expression, DAX script, or DAX query rather than just the code segment under the cursor. When this is the case, the Code Action will be shown in the Code Actions menu with " (All occurrences)" appended to the action description. Clicking on the action will apply the change to all occurrences in the document. + +In the screenshot below, for example, the **Prefix variable with '_'** action can be applied to all occurrences (i.e., all variables) in the document, not just the `totalSales` variable under the cursor: + +![Code Action All Occurrences](~/content/assets/images/code-action-all-occurrences.png) + +## List of Code Actions + +The table below lists all currently available Code Actions. You can toggle off Code Actions in the **Tools > Preferences** dialog under **Text Editors > DAX Editor > Code Actions** (a future update will let you toggle individual actions for a more customized experience). Some Code Actions also have additional configuration options, such as which prefix to use for variable names. + +### Improvements + +The Code Actions below will appear with orange dots under the first two characters of the applicable code and a lightbulb icon in the left margin when the cursor is placed on the code segment: + +| ID | Name | Description | +| ----- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DI001 | [Remove unused variable](xref:DI001) | Variables not referenced anywhere should be removed. Example:
    `VAR a = 1 VAR b = 2 RETURN a` -> `VAR a = 1 RETURN a` | +| DI002 | [Remove all unused variables](xref:DI002) | Variables that are not being used (directly or indirectly through other variables) in the `RETURN` part of a variable block should be removed. Example:
    `VAR a = 1 VAR b = a RETURN 123` -> `123` | +| DI003 | [Remove table name](xref:DI003) | Measure references should not include the table name, as the table name is unnecessary when referencing measures. Moreover, this practice makes measure references more easily distinguishable from column references. Example:
    `Sales[Total Sales]` -> `[Total Sales]` | +| DI004 | [Add table name](xref:DI004) | Column references should include the table name to avoid ambiguities and to more easily distinguish column references from measure references. Example:
    `SUM([SalesAmount])` -> `SUM(Sales[SalesAmount])` | +| DI005 | [Rewrite table filter as scalar predicate](xref:DI005) | A common anti-pattern in DAX is to filter a table inside a [`CALCULATE`](https://dax.guide/CALCULATE) filter argument when it is sufficient to filter one or more columns from that table. Example:
    `CALCULATE([Total Sales], FILTER(Products, Products[Color] = "Red"))` -> `CALCULATE([Total Sales], KEEPFILTERS(Products[Color] = "Red"))`
    This Code Action supports various variations of the original expression. | +| DI006 | [Split multi-column filter into multiple filters](xref:DI006) | When filtering a table on multiple columns combined using `AND` (or the equivalent `&&` operator), better performance can often be achieved by specifying multiple filters, one for each column. Example:
    `CALCULATE(..., Products[Color] = "Red" && Products[Size] = "Large")` -> `CALCULATE(..., Products[Color] = "Red", Products[Size] = "Large")` | +| DI007 | [Simplify SWITCH statement](xref:DI007) | 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:
    `SWITCH(TRUE(), a = 1, ..., a = 2, ...)` -> `SWITCH(a, 1, ..., 2, ...)` | +| DI008 | [Remove superfluous CALCULATE](xref:DI008) | A [`CALCULATE`](https://dax.guide/CALCULATE) function that is not necessary because it does not modify the filter context, or because an implicit context transition would happen anyway, should be removed. Examples:
    `CALCULATE([Total Sales])` -> `[Total Sales]`
    `AVERAGEX(Product, CALCULATE([Total Sales]))` -> `AVERAGEX(Product, [Total Sales])`

    Also applies when the first argument of `CALCULATE` / `CALCULATETABLE` is a DAX variable, e.g.:
    `VAR x = [Total Sales] RETURN CALCULATE(x, Product[Color] = "Red")` ->
    `VAR x = [Total Sales] RETURN x` | +| DI009 | [Avoid calculate shortcut syntax](xref:DI009) | Example:
    `[Total Sales](Products[Color] = "Red")` -> `CALCULATE([Total Sales], Products[Color] = "Red")` | +| DI010 | [Use MIN/MAX instead of IF](xref:DI010) | When a conditional expression is used to return the minimum or maximum of two values, it is more efficient and compact to use the [`MIN`](https://dax.guide/MIN) or [`MAX`](https://dax.guide/MAX) function. Example:
    `IF(a > b, a, b)` -> `MAX(a, b)` | +| DI011 | [Use ISEMPTY instead of COUNTROWS](xref:DI011) | When checking if a table is empty, it is more efficient to use the [`ISEMPTY`](https://dax.guide/ISEMPTY) function than to count the rows of the table. Examples:
    `COUNTROWS(Products) = 0` -> `ISEMPTY(Products)` | +| DI012 | [Use DIVIDE instead of division](xref:DI012) | When using an arbitrary expression in the denominator of a division, use [`DIVIDE`](https://dax.guide/DIVIDE) instead of the division operator to avoid division by zero errors. Example:
    `x / y` -> `DIVIDE(x, y)` | +| DI013 | [Use division instead of DIVIDE](xref:DI013) | When the 2nd argument of [`DIVIDE`](https://dax.guide/DIVIDE) is a non-zero constant, it is more efficient to use the division operator. Example:
    `DIVIDE(x, 2)` -> `x / 2` | +| DI014 | [Replace IFERROR with DIVIDE](xref:DI014) | Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IFERROR`](https://dax.guide/IFERROR) to provide an alternate result when a division has a zero denominator. Example:
    `IFERROR(x / y, 0)` -> `DIVIDE(x, y, 0)` | +| DI015 | [Replace IF with DIVIDE](xref:DI015) | Use the [`DIVIDE`](https://dax.guide/DIVIDE) function instead of [`IF`](https://dax.guide/IF) to more easily check for zero or blank in the denominator. Example:
    `IF(y <> 0, x / y)` -> `DIVIDE(x, y)` | + +### Readability + +The Code Actions below will appear with teal green dots under the first two characters of the applicable code and a screwdriver icon in the left margin when the cursor is placed on the code segment + +| ID | Name | Description | | | | | | | +| ----- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | ------------------------------------------------------------------------------------------------ | - | ----- | - | ------------------------------- | +| DR001 | [Convert to scalar predicate](xref:DR001) | A column filter can be written more concisely as a scalar predicate without explicitly using the [`FILTER`](https://dax.guide/FILTER) function. Examples:
    `FILTER(ALL(Products[Color]), Products[Color] = "Red")` -> `Products[Color] = "Red"`
    `FILTER(VALUES(Products[Color]), Products[Color] = "Red")` -> `KEEPFILTERS(Products[Color] = "Red")` | | | | | | | +| DR002 | [Use aggregator instead of iterator](xref:DR002) | Use an aggregator function instead of an iterator function when possible to simplify the code. Example:
    `SUMX(Products, Products[SalesAmount])` -> `SUM(Products[SalesAmount])` | | | | | | | +| DR003 | [Use VALUES instead of SUMMARIZE](xref:DR003) | When [`SUMMARIZE`](https://dax.guide/SUMMARIZE) only specifies a single column, and that column belongs to the table specified in the first argument, the code can be more concisely written using [`VALUES`](https://dax.guide/VALUES). Example:
    `SUMMARIZE(Products, Products[Color])` -> `VALUES(Products[Color])` | | | | | | | +| DR004 | [Prefix variable](xref:DR004) | Variables should use a consistent naming convention. It is recommended to use a prefix, such as an underscore. You can configure which prefix to use to match your preferred style. Example:
    `VAR totalSales = SUM(Sales[SalesAmount])` -> `VAR _totalSales = SUM(Sales[SalesAmount])` | | | | | | | +| DR005 | [Prefix temporary columns](xref:DR005) | Using a consistent prefix for temporary columns is recommended to more easily distinguish them from base columns or measures. You can configure which prefix to use to match your preferred style. Example:
    `ADDCOLUMNS(Product, "SalesByProd", [Sales])` -> `ADDCOLUMNS(Product, "@SalesByProd", [Sales])` | | | | | | | +| DR006 | [Move constant aggregation to variable](xref:DR006) | When an aggregation function is used inside an iterator or a scalar predicate, the aggregation produces the same result for every row of the iteration. Therefore, the aggregation could be moved to a DAX variable outside of the iteration. Example:
    `CALCULATE(..., 'Date'[Date] = MAX('Date'[Date]))` ->
    `VAR _maxDate = MAX('Date'[Date]) RETURN CALCULATE(..., 'Date'[Date] = _maxDate)` | | | | | | | +| DR007 | [Simplify 1-variable block](xref:DR007) | A variable block with only one variable can be simplified by moving the expression directly into the `RETURN` part of the block. This assumes the variable is only referenced once without any context modifiers. Example:
    `VAR _result = [Sales] * 1.25 RETURN _result` -> `[Sales] * 1.25` | | | | | | | +| DR008 | [Simplify multi-variable block](xref:DR008) | A variable block with multiple variables where each is a simple measure reference, which is only used once in the `RETURN` section without any context modifiers, should be simplified. Example:
    `VAR _sales = [Sales] VAR _cost = [Cost] RETURN _sales - _cost` -> `[Sales] - [Cost]` | | | | | | | +| DR009 | [Rewrite using DISTINCTCOUNT](xref:DR009) | Instead of using `COUNTROWS(DISTINCT(T[c])` to count the number of distinct values in a column, use the [`DISTINCTCOUNT`](https://dax.guide/DISTINCTCOUNT) function. | | | | | | | +| DR010 | [Rewrite using COALESCE](xref:DR010) | Instead of using `IF` to return the first non-blank value from a list of expressions, use the [`COALESCE`](https://dax.guide/COALESCE) function. Example:
    `IF(ISBLANK([Sales]), [Sales2], [Sales])` -> `COALESCE([Sales], [Sales2])` | | | | | | | +| DR011 | [Rewrite using ISBLANK](xref:DR011) | Instead of comparing an expression with [`BLANK()`](https://dax.guide/BLANK), use the [`ISBLANK`](https://dax.guide/ISBLANK) function. Example:
    `IF([Sales] = BLANK(), [Budget], [Sales])` -> `IF(ISBLANK([Sales], [Budget], [Sales])` | | | | | | | +| DR012 | [Remove unnecessary BLANK](xref:DR012) | Some DAX functions, such as [`IF`](https://dax.guide/IF) and [`SWITCH`](https://dax.guide/SWITCH) already return `BLANK()` when the condition is false, so there is no need to explicitly specify `BLANK()`. Example:
    `IF(a > b, a, BLANK())` -> `IF(a > b, a)` | | | | | | | +| DR013 | [Simplify negated logic](xref:DR013) | When a logical expression is negated, it is often more readable to rewrite the expression using the negated operator. Example:
    `NOT(a = b)` -> `a <> b` | | | | | | | +| DR014 | [Simplify using IN](xref:DR014) | Rewrite compound predicates (equality comparisons of the same expression that are combined using [`OR`](https://dax.guide/OR) or [\` | | `](https://dax.guide/op/or/)) with the [`IN`](https://dax.guide/IN) operator. Example:
    `a = 1 | | a = 2 | | a = 100`->`a IN { 1, 2, 100 }\` | + +### Rewrites + +The Code Actions below will appear with a screwdriver icon in the left margin when the cursor is placed on the code segment. + +| ID | Name | Description | +| ----- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RW001 | [Rewrite TOTALxTD using CALCULATE](xref:RW001) | Functions such as [`TOTALMTD`](https://dax.guide/TOTALMTD), [`TOTALQTD`](https://dax.guide/TOTALQTD) and [`TOTALYTD`](https://dax.guide/TOTALYTD) can be rewritten using the [`CALCULATE`](https://dax.guide/CALCULATE) function, which is more expressive and provides greater flexibility. Example:
    `TOTALYTD([Total Sales], 'Date'[Date])` -> `CALCULATE([Total Sales], DATESYTD('Date'[Date]))` | +| RW002 | [Rewrite using FILTER](xref:RW002) | A scalar predicate in a filter argument to `CALCULATE` can be rewritten using `FILTER`. This is useful, for example, when you need to add more complex filtering logic. Example:
    `CALCULATE(..., Products[Color] = "Red")` -> `CALCULATE(..., FILTER(ALL(Products[Color]), Products[Color] = "Red"))` | +| RW003 | [Invert IF](xref:RW003) | To improve readability, it is sometimes useful to invert `IF` statements. Example:
    `IF(a < b, "B is greater", "A is greater")` -> `IF(a > b, "A is greater", "B is greater")` | + +## Customizing Code Actions + +You can customize the behavior of Code Actions through the **Tools > Preferences** dialog under **Text Editors > DAX Editor > Code Actions**. Here, you can toggle the feature on and off and configure additional options for some Code Actions, such as the prefix to use for variable names and extension columns. + +We plan to add more configuration options to this screen in future versions, such as an option to toggle individual Code Actions on and off. Stay tuned! + +![Code Actions Preferences](~/content/assets/images/code-actions-preferences.png) + diff --git a/content/localization/zh/common-features_zh.md b/content/localization/zh/common-features_zh.md new file mode 100644 index 00000000..5d02a922 --- /dev/null +++ b/content/localization/zh/common-features_zh.md @@ -0,0 +1,5 @@ +# Common features + +A lot of Tabular Editor functionality is shared between both Tabular Editor 2.x and Tabular Editor 3.x. This section holds articles that are related to such shared functionality. + +A few minor differences exist, which are highlighted whenever they occur. For example, C# scripting is called "Advanced Scripting" in Tabular Editor 2.x, and macros are called "Custom Actions". diff --git a/content/localization/zh/connecting-to-azure-databricks_zh.md b/content/localization/zh/connecting-to-azure-databricks_zh.md new file mode 100644 index 00000000..fe2d83a4 --- /dev/null +++ b/content/localization/zh/connecting-to-azure-databricks_zh.md @@ -0,0 +1,205 @@ +--- +uid: connecting-to-azure-databricks +title: Connecting to Azure Databricks +author: David Bojsen +updated: 2025-08-05 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Connecting to Azure Databricks + +Tabular Editor 3 supports connecting to Azure Databricks as a data source for your semantic models. This tutorial will guide you through the process of setting up a connection to Azure Databricks and importing data from it. + +## Prerequisites + +Before you begin, ensure you have the following: + +- A valid Azure Databricks workspace +- Appropriate permissions to access the Databricks data +- Tabular Editor 3 (Desktop, Business, or Enterprise edition) + +## Authentication Methods + +When connecting to Azure Databricks, you have two main authentication methods: + +### 1. Microsoft Entra ID (formerly Azure AD) Authentication + +This is the recommended approach for connecting to Azure Databricks when your organization uses Microsoft Entra ID. This method provides seamless single sign-on and better security through managed identities. + +#### About the Tabular Editor Enterprise Application + +When you connect to Azure Databricks using Microsoft Entra ID authentication, Tabular Editor uses a registered enterprise application named "Tabular Editor 3 - User Delegated Access to Azure Databricks" with the Application (client) ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c`. + +This enterprise application requires the following API permissions: + +- **Microsoft Graph** (`00000003-0000-0000-c000-000000000000`) + - `offline_access` (Delegated) - This permission allows Tabular Editor to maintain access to the data you've given it permission to access, even when you're not actively using the application. This is needed for maintaining a persistent connection to Databricks. + - `openid` (Delegated) - Allows users to sign in to the app with their work or school accounts and allows the app to see basic user profile information. + - `profile` (Delegated) - Allows the app to see basic profile information such as name, email, picture, username. + - `User.Read` (Delegated) - Allows the app to read your profile, and to identify you when accessing the Databricks API. + +- **Azure Databricks API** (`2ff814a6-3304-4ab8-85cb-cd0e6f879c1d`) + - `user_impersonation` (Delegated) - Access Azure Databricks on behalf of the signed-in user. This allows Tabular Editor to connect to your Databricks workspace using your credentials. + +For more information about Microsoft Entra ID permissions, please refer to the [Microsoft documentation on permission types](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent) and [application consent experience](https://learn.microsoft.com/en-us/azure/active-directory/develop/application-consent-experience). + +> [!IMPORTANT] +> These permissions are required for Tabular Editor to access your Azure Databricks data securely through your Microsoft Entra ID credentials. Without these permissions, Tabular Editor cannot authenticate to your Azure Databricks workspace properly. + +#### Consent Process for Microsoft Entra ID Authentication + +When you first attempt to connect to Azure Databricks using Microsoft Entra ID authentication, you may be prompted to consent to the required permissions. The consent process depends on your organization's Microsoft Entra ID policies: + +##### User Consent + +If your organization allows user consent for applications: + +1. You will see a consent prompt from Microsoft asking for permission to allow Tabular Editor to access Azure Databricks on your behalf +2. Review the permissions being requested +3. Click **Accept** to grant consent + +> [!NOTE] +> Whether admin consent is required depends on your organization's Microsoft Entra ID policies, not necessarily the specific API permissions being requested. Many organizations allow users to consent to delegated permissions themselves, while others require administrator approval for all third-party applications regardless of permission level. + +##### Admin Consent Required + +If your organization restricts user consent (common in enterprise environments): + +1. You will receive an error message indicating that admin consent is required +2. You'll need to contact your IT department or Microsoft Entra ID administrator +3. Provide them with: + - Application Name: "Tabular Editor 3 - User Delegated Access to Azure Databricks" + - Application ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c` + - Required Permissions: Microsoft Graph (offline_access, openid, profile, User.Read) and Azure Databricks API (user_impersonation) + +Your administrator can grant organization-wide consent in one of two ways: + +**Option 1: Through the Microsoft Entra ID Admin Portal** + +1. Navigate to Microsoft Entra ID > Enterprise Applications +2. Search for "Tabular Editor 3 - User Delegated Access to Azure Databricks" +3. Select the application and go to Permissions +4. Click "Grant admin consent for [Organization]" + +**Option 2: Using the Direct Admin Consent URL** +Administrators can use the following direct link to grant consent: + +``` +https://login.microsoftonline.com/organizations/v2.0/adminconsent?client_id=ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c&scope=https://graph.microsoft.com/offline_access%20https://graph.microsoft.com/openid%20https://graph.microsoft.com/profile%20https://graph.microsoft.com/User.Read%202ff814a6-3304-4ab8-85cb-cd0e6f879c1d/user_impersonation&redirect_uri=https://tabulareditor.com +``` + +For more information about admin consent, see Microsoft's documentation on [Configure how users consent to applications](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent). + +#### Steps for Microsoft Entra ID Authentication: + +1. In Tabular Editor 3, go to **Model** > **Import tables...** +2. Select **New Source** > **Databricks** +3. In the connection dialog: + - Enter your Databricks workspace URL (format: `https://.azuredatabricks.net`) + - Select **Microsoft Entra ID** as the authentication method + - For HTTP Path, specify the path to your Databricks cluster (e.g., `/sql/1.0/warehouses/`) + +> [!NOTE] +> Your Databricks workspace URL should be in the format `https://.azuredatabricks.net` - for example, `https://westeurope.azuredatabricks.net`. + +### 2. Personal Access Token (PAT) Authentication + +If Microsoft Entra ID integration is not available or if you prefer token-based authentication, you can use a Personal Access Token. + +#### Steps for PAT Authentication: + +1. Generate a Personal Access Token in your Azure Databricks workspace: + - Go to your Databricks workspace + - Click on your user profile icon in the top-right corner + - Select **User Settings** + - Go to the **Access Tokens** tab + - Click **Generate New Token** + - Provide a name and optionally set an expiration time + - Click **Generate** and copy the token value + +2. In Tabular Editor 3, go to **Model** > **Import tables...** + +3. Select **New Source** > **Databricks** + +4. In the connection dialog: + - Enter your Databricks workspace URL + - Select **Personal Access Token** as the authentication method + - Paste your token into the Token field + - For HTTP Path, specify the path to your Databricks cluster (e.g., `/sql/1.0/warehouses/`) + +## Finding Your HTTP Path + +The HTTP Path parameter is essential for connecting to your Databricks SQL warehouse. To find this value: + +1. Go to your Databricks workspace +2. Navigate to **SQL** > **SQL Warehouses** +3. Select the SQL warehouse you want to connect to +4. Look for the **Connection Details** section +5. Copy the HTTP Path value which should be in the format: `/sql/1.0/warehouses/` + +## Importing Tables from Databricks + +Once you've configured your connection: + +1. Click **Test Connection** to verify your credentials and connection settings +2. If the connection is successful, click **Next** +3. Select whether to import specific tables/views or use a custom SQL query +4. If selecting tables/views: + - Browse through the available catalogs, schemas, and tables + - Select the tables you wish to import + - Optionally preview and filter columns +5. Review your selections and click **Import** to finalize + +## Troubleshooting Connection Issues + +If you encounter issues connecting to Azure Databricks: + +- Verify your workspace URL is correct and accessible +- Ensure your Personal Access Token hasn't expired (if using PAT authentication) +- Check that your user account has the necessary permissions in Databricks +- Verify the HTTP Path points to an active SQL warehouse +- Ensure your network allows connections to the Databricks service + +### Resolving Microsoft Entra ID Authentication Issues + +If you're using Microsoft Entra ID authentication and encounter errors: + +#### "AADSTS65001: The user or administrator has not consented to use the application" + +This error occurs when the required permissions haven't been granted: + +1. If you have sufficient privileges: + - Click the consent link in the error message + - Review and accept the permissions request + +2. If you don't have sufficient privileges: + - Contact your IT administrator + - Provide them with the application ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c` + - Request they grant organizational consent for the Tabular Editor enterprise application + +#### "AADSTS700016: Application with identifier was not found in the directory" + +This may occur if your organization uses a restricted application policy: + +1. Contact your Microsoft Entra ID administrator +2. Request that they add the Tabular Editor enterprise application (ID: `ea0fc0fe-ed02-40d7-a29a-cc0a59d8b42c`) to your organization's allowed application list + +> [!TIP] +> In some organizations, IT departments may require a formal request or security review before approving new enterprise applications. Be prepared to explain that this application is used by Tabular Editor 3 to securely connect to Azure Databricks resources using the organization's existing Microsoft Entra ID authentication infrastructure. + +## Using Update Table Schema with Databricks + +After importing tables from Azure Databricks, you can use Tabular Editor's **Update Table Schema** feature to keep your model in sync with changes in the Databricks tables. + +To update the schema: + +1. Right-click on the imported table in the TOM Explorer +2. Select **Update Table Schema** +3. Review any detected changes and apply them as needed + +For complex queries or if you encounter issues with schema detection, consider enabling the **Use Analysis Services for change detection** option under **Tools** > **Preferences** > **Schema Compare** as described in the [Updating Table Schema](xref:importing-tables#updating-table-schema-through-analysis-services) documentation. + diff --git a/content/localization/zh/creating-and-testing-dax_zh.md b/content/localization/zh/creating-and-testing-dax_zh.md new file mode 100644 index 00000000..4a1d8a0e --- /dev/null +++ b/content/localization/zh/creating-and-testing-dax_zh.md @@ -0,0 +1,131 @@ +--- +uid: creating-and-testing-dax +title: Adding measures and other calculated objects +author: Daniel Otykier +updated: 2021-10-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Adding measures and other calculated objects + +Ever since Tabular Editor 2.x got released in early 2017, the ability to quickly modify DAX expressions across measures has always been the most popular feature of the tool. Combined with back and forward navigation, copy/paste operations, DAX dependency visualisation and undo/redo support, the tool has always been the preferred option for anyone working with large and complex data models, where the ability to quickly make multiple smaller changes is crucial. + +The only complaint in this regard, by users of Tabular Editor 2.x, was the lack of DAX code assist features (sometimes called "IntelliSense"). Especially when you are not a 100% proficient with DAX (and very few people are!), having the DAX code editor assist you in remembering syntax, function parameters, etc. is incredibly helpful. + +This has all been addressed with the new DAX code editor used by Tabular Editor 3. + +![Editing a complex DAX expression](~/content/assets/images/dax-editor-screenshot.png) + +The remainder of this article describes how to create measures and other calculated objects, and how to modify the DAX expressions on these objects. To learn more about the many features of the DAX code editor, see . + +# Adding measures + +Once you have [imported some tables](xref:importing-tables-data-modeling#importing-new-tables) to your model and [created relationships between them](xref:importing-tables-data-modeling#modifying-relationships-using-the-diagram), it is time to add some explicit measures containing your business logic. + +> [!TIP] +> Technically, you are not required to add explicit measures to your model before visualizing data in a Power BI report. However, it is a best practice to always do so, as MDX-based client tools (such as Excel and Tabular Editor 3's Pivot Grid) requires explicit measures. In addition, [Calculation Groups](https://docs.microsoft.com/en-us/analysis-services/tabular-models/calculation-groups?view=asallproducts-allversions) only apply to explicit measures. + +To add a new measure using Tabular Editor, right-click on the table in which you want to add the measure, then choose **Create > Measure** (ALT+1). + +![Adding New Measure](~/content/assets/images/adding-new-measure.png) + +When a new measure is added, the name of that measure will be editable. Hit ENTER when you have provided a name for the measure. You can always edit the name later in the **Properties** view or by pressing F2 while the measure is selected in the **TOM Explorer**. + +The **Expression Editor** view is used to provide the DAX expression for the measure. As you enter the code, notice how the DAX editor provides code suggestions and even underlines syntax or semantic errors. + +![Add Measure Edit Dax](~/content/assets/images/add-measure-edit-dax.png) + +The dropdown box at the top left corner of the **Expression Editor** is used to switch between different DAX properties of the currently selected object. For example, in newer versions of Analysis Services, measures have an `Expression` property as well as a [`Detail Rows Expression`](https://www.sqlbi.com/articles/controlling-drillthrough-in-excel-pivottables-connected-to-power-bi-or-analysis-services/). Other types of objects can have different properties that contain DAX code. For example, [KPIs](https://docs.microsoft.com/en-us/analysis-services/tabular-models/kpis-ssas-tabular?view=asallproducts-allversions) have three different DAX properties. To add a KPI in Tabular Editor, right-click on a measure and choose **Create > KPI**. + +![Editing Kpis](~/content/assets/images/editing-kpis.png) + +If you want your measure to be hidden, simply right-click and choose the **Make invisible** (CTRL+I) option. Likewise, you can unhide a measure by choosing the **Make visible** (CTRL+U) option. + +## Other measure properties + +In addition to the `Name`, `Expression` and `Hidden` properties, you can use the **Properties** view to review and edit the value of all properties of the currently selected object(s) in the **TOM Explorer**. For measures, this is where you can set the `Format String`, for example. For more information, see [Properties view](xref:properties-view). + +# Adding calculated columns + +To add a calculated column, right-click on the table on which you want to add the column, and choose **Create > Calculated Column** (ALT+2). Give the column a name and edit its DAX expression using the **Expression Editor**, similar to how we did for measures above. + +> [!IMPORTANT] +> This option is not available by default when connected to a Power BI Desktop model. This is because of the [limitations of Power BI Desktop support for external tools](xref:desktop-limitations). Click the link to learn more. + +> [!NOTE] +> When the DAX expression of a calculated column has been changed, the table in which the column resides has to be refreshed before the column can be used in a report. See for more information. + +# Adding calculated tables + +To add a calculated table, right-click on the model or on the "Tables" folder, and choose **Create > Calculated Table** (ALT+6). Give the table a name and edit its DAX expression using the **Expression Editor**, similar to how we did for measures above. Notice that the columns on the table changes automatically, when you make a change to the DAX expression. This can cause cascading effects, if other DAX expressions reference the table, or if columns are used in a hierarchy. + +> [!IMPORTANT] +> This option is not available by default when connected to a Power BI Desktop model. This is because of the [limitations of Power BI Desktop support for external tools](xref:desktop-limitations). Click the link to learn more. + +> [!NOTE] +> When the DAX expression of a calculated table has been changed, the table has to be refreshed before it can be used in a report. See for more information. + +# Adding calculation groups + +To add a [calculation group](https://docs.microsoft.com/en-us/analysis-services/tabular-models/calculation-groups?view=asallproducts-allversions), right-click on the model or on the "Tables" folder, and choose **Create > Calculation Group** (ALT+7). Give the Calculation Group a name. Also consider a different name for the default **Name** column. + +> [!IMPORTANT] +> This option is only available on models at compatibility level 1500 or higher. + +To add calculation items, right-click on the newly created calculation group and choose **Create > Calculation Item**. Give the Calculation Item a name and edit its DAX expression using the **Expression Editor** similar to how we did for measures above. + +You can arrange the display order of Calculation Items by dragging them around in the TOM Explorer, or by setting the `Ordinal` property within the **Properties** view. + +> [!NOTE] +> When Calculation Items are added, renamed or removed from a Calculation Group, the Calculation Group has to be refreshed before it can be used in a report. See for more information. + +# Common modeling operations + +## Copy / paste + +All objects in the TOM Explorer can be copied and pasted with Tabular Editor. You can even copy and paste between different instances of Tabular Editor, and even between Tabular Editor 2.x and Tabular Editor 3. You can use the familiar keyboard shortcuts: + +- **Edit > Copy** (CTRL+C) +- **Edit > Cut** (CTRL+X) +- **Edit > Paste** (CTRL+V) + +> [!TIP] +> If you want to replace one table with another, retaining all existing relationships to/from that table, copy a table to the clipboard, then select the table you wish to replace in the TOM Explorer and paste. You will be prompted whether you want to replace the selected table with the one in the clipboard. + +## Undo / redo + +Whenever a change is made to an object or property in Tabular Editor, the complete history of changes is tracked, allowing you to undo every change made. You can use the familiar keyboard shortcuts: + +- **Edit > Undo** (CTRL+Z) +- **Edit > Redo** (CTRL+Y) + +> [!NOTE] +> All text editors in Tabular Editor 3 have their own undo/redo history, so if the cursor is currently within a text editor, the keyboard shortcuts will undo/redo the typing within that editor. You can use the options in the **Edit** menu to perform an undo/redo at the model level, or deactivate the current text editor by clicking on another element in the user interface (such as the TOM Explorer). + +# Navigation + +While the cursor is over an object reference in the DAX editor, right-click and choose **Go to definition** (F12) to quickly jump to that object. Of course, you can also navigate between objects using the TOM Explorer. + +You can use the arrow buttons in the top right corner of the **Expression Editor** to jump quickly back and forth between objects visited. + +## DAX Dependencies + +To view DAX dependencies between objects, select an object in the **TOM Explorer**, then right-click and choose **Show dependencies** (SHIFT+F12). This will open a window that displays the dependencies (in both directions) of the selected object. Double-click on an object in this window to quickly navigate to that object. + +![Dax Dependencies And Tom Explorer](~/content/assets/images/dax-dependencies-and-tom-explorer.png) + +# Display folders + +Once your model starts to gain a considerable number of measures, a good practice is to organize them using Display Folders. In Tabular Editor, to create a Display Folder, either edit the `Display Folder` property through the **Properties** view, or alternatively, right-click on the measure(s), and select the **Create > Display Folder** option. + +You can also cut/copy/paste or drag and drop objects between display folders. + +# Next steps + +- @dax-script-introduction +- @bpa +- @cs-scripts-and-macros \ No newline at end of file diff --git a/content/localization/zh/creating-macros_zh.md b/content/localization/zh/creating-macros_zh.md new file mode 100644 index 00000000..010be8a1 --- /dev/null +++ b/content/localization/zh/creating-macros_zh.md @@ -0,0 +1,66 @@ +--- +uid: creating-macros +title: Creating macros +author: Morten Lønskov +updated: 2023-12-07 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Creating macros + +Macros are C# scripts that have been saved in Tabular Editor to be easily reused across semantic models. +Saving a script as a Macro will allow that macro to be used when right clicking on the objects in the TOM Explorer making it simple to apply the script to your model. + +## Creating a Macro + +The first step in creating a Macro is to create and test a C# script. + +> [!TIP] +> ne easy way to get started with C# scripting is to use the built in record function that lets you record the actions you take in the TOM Explorer. +> his way you can see how to interact with the different model objects and create reusable scripts. +> nother way is to reuse existing scripts such as those in our [script library](xref:csharp-script-library). +> n this tutorial we use the script [Format Numeric Measures](xref:script-format-numeric-measures) to showcase the Macro functionality. + +Once the script works according requirements the script can be saved using the toolbar button "Save as Macro" which will open the "Save Macro" window. + +![Macro Create infobox](~/content/assets/images/features/macros/macro_tutorial_create_infobox.png) + +The "Save Macro" window allows three options: + +1. Macro Name: Give the Macro a name and use backslash "\" to create folder path for the macro (See below) +2. Provide a tooltip for the Macro to remember what it does in detail +3. Select a context where the Macro should be available. + +![Macro Save infobox](~/content/assets/images/features/macros/macro_tutorial_save_window.png) + +In the above example the Macro will be saved in a folder called Formatting\Beginner and the script is called "Format Numeric Measures". It will be saved in the context of measures. + +### Macro Context + +Macros are saved in a "valid context" that determines which objects in the model the script can be applied to. + +This Macro can then be used when Right Clicking on a measure in the TOM Explorer. The context given while saving the Macro determines which objects will show the Macro when right clicking on that object. + +Tabular Editor will suggest a context based on the script that is being saved. + +![Macro Menu Shortcut](~/content/assets/images/features/macros/macro_tutorial_menu_shortcut.png) + +## Edit a Macro + +A macro can be opened by double clicking it in the Macro pane and after editing the C# script saved using _Ctrl + S_ or the Edit Macro button. + +![Macro Edit Infobox](~/content/assets/images/features/macros/macro_tutorial_edit_infobox.png) + +## Macro JSON file + +Macros are stored in the %LocalAppFolder%/TabularEditor3 as a JSON file called MacroActions.json. For more information on file types in Tabular Editor please see [Supported File Types](xref:supported-files#macroactionsjson) + +## Macro file example + +An example of a MacroActions.JSON file can be found here. It contains several of the C# scripts from our script library: [Download example MacroActions File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/MacroActions.json) + + diff --git a/content/localization/zh/cs-scripts-and-macros_zh.md b/content/localization/zh/cs-scripts-and-macros_zh.md new file mode 100644 index 00000000..35d5f195 --- /dev/null +++ b/content/localization/zh/cs-scripts-and-macros_zh.md @@ -0,0 +1,150 @@ +--- +uid: cs-scripts-and-macros +title: Introduction to C# scripts and macros +author: Daniel Otykier +updated: 2021-11-03 +--- + +# Introduction to C# scripts and macros + +Any software that claims to improve your productivity should provide some means of **automating user interactions**. In Tabular Editor, you can write C# scripts for exactly this purpose. With C# scripts in Tabular Editor, you can, for example: + +- Automate creation of TOM objects such as measures, tables, calculation items +- Interact with the currently selected object(s) in the TOM Explorer +- Automatically assign properties to multiple objects +- Import and export metadata in various formats, for auditing or documentation purposes + +If a script modifies your model metadata, you will be able to view the modifications immediately in the TOM Explorer and the Properties view. Moreover, you can **undo script changes**, effectively rolling back the model metadata to the point before the script was executed. If a script fails execution, the changes are automatically rolled back by default. + +Tabular Editor 3 includes a simple **script recorder** which helps you learn the syntax used, by incrementally adding lines of script code as you make changes to your model. + +A script can be saved as a standalone file (`.csx` file extension), which can be shared among Tabular Editor users. In addition, a script can be stored as a reusable **macro**, which integrates the script more closely with Tabular Editors user interface. + +# Creating a script + +To create a new C# script, use the **File > New > C# Script** menu option. Note that this option is available even when no model is loaded in Tabular Editor. + +For your first script, enter the following code: + +```csharp +Info("Hello world!"); +``` + +Hit F5 to run the code. + +![Your very first script](~/content/assets/images/first-script.png) + +If you made a mistake while typing the code, any syntax errors will be shown in the **Messages view**. + +- To save the script as a file, simply hit **File > Save** (Ctrl+S). +- To open a script from a file, use the **File > Open > File...** (Ctrl+O) option. The Open File dialog will look for files with the `.cs` or `.csx` extensions by default. + +# Using the script recorder + +While a C# script is in focus, you can start the script recorder in Tabular Editor by using the **C# Script > Record script** menu option. While the script is recording, any change you make to your model metadata will cause additional lines of code to be added to the script. Note that you cannot edit the script manually until you stop the recording. + +![Csharp Script Recorder](~/content/assets/images/csharp-script-recorder.png) + +# Accessing model metadata + +In order to access specific objects within the currently loaded model, you need to use the C# syntax for navigating through the Tabular Object Model (TOM) hierarchy. The root of this hierarchy is the `Model` object. + +The script below outputs the name of the currently loaded model. If no model is loaded, a warning is displayed. + +```csharp +if(Model != null) + Info("The name of the current model is: " + Model.Name); +else + Warning("No model is currently loaded!"); +``` + +The `Model` object is a wrapper of the [Microsoft.AnalysisServices.Tabular.Model](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) class, exposing a subset of its properties, with some additional methods and properties for convenience. + +To access a specific measure, you will need to know the name of that measure as well as the name of the table the measure resides in: + +```csharp +var myMeasure = Model.Tables["Internet Sales"].Measures["Internet Total Sales"]; +myMeasure.Description = "The formula for this measure is: " + myMeasure.Expression; +``` + +Line 1 in the script above locates the "Internet Total Sales" measure on the "Internet Sales" table, then stores a reference to that measure in the `myMeasure` variable. + +Line 2 in the script sets the description of the measure, based on a hardcoded string and the (DAX) expression of the measure. + +Tabular Editor can auto-generate the code that references a specific object, by dragging and dropping the object from the TOM Explorer into the C# script view. + +![Generate an object reference by dragging](~/content/assets/images/generate-csharp-code.gif) + +Most TOM objects (tables, columns, measures, etc.) in Tabular Editor, exposes the same set of properties that are available when using the AMO/TOM client libraries directly. For this reason, you can refer to [Microsoft's AMO/TOM documentation](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular?view=analysisservices-dotnet), to learn which properties are available. For example, [here](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.measure?view=analysisservices-dotnet#properties) is the documentation for available measure properties. + +# Accessing current TOM Explorer selection + +To make scripts reusable, it is rarely enough to be able to reference objects in the model directly by name, as shown above. Instead, it is useful to refer to whichever object(s) is currently selected in Tabular Editor's **TOM Explorer view**. This is possible through the use of the `Selected` object. + +```csharp +Info("You have currently selected: " + Selected.Measures.Count + " measure(s)."); +``` + +The `Selected` object by itself is a collection of all objects currently selected, including objects within selected display folders. In addition, the `Selected` object contains multiple properties that makes it easy to refer to specific object types, such as the `.Measures` property shown in the example above. In general, these properties exist in both a plural (`.Measures`) and a singular (`.Measure`) form. The former is a collection that you can iterate through, and which will be empty if the current selection does not contain any objects of that type, where as the latter is a reference to the currently selected object, if and only if exactly one of that type of object is selected. + +The @useful-script-snippets article contains many examples of scripts that use the `Selected` object to perform various tasks. + +# Interacting with the user + +In the examples above, we used the `Info(...)` and `Warning(...)` global methods to show a message to the user in various flavors. Tabular Editor provides a number of these global methods as well as extension methods for showing and collecting information, and for various other common tasks. The most commonly used are listed below: + +- `void Output(object value)` - halts script execution and displays detailed information about the provided object. When the provided object is a TOM object or a collection of TOM objects, a detailed view of all properties are shown. +- `void SaveFile(string filePath, string content)` - convenient way to save text data to a file. +- `string ReadFile(string filePath)` - convenient way to load text data from a file. +- `string ExportProperties(IEnumerable objects, string properties = "...")` - convenient way to export a set of properties from multiple objects as a TSV string. +- `void ImportProperties(string tsvData)` - convenient way to load properties into multiple objects from a TSV string. +- `string ConvertDax(dax, useSemicolons)` - converts a DAX expression between US/UK and non-US/UK locales. If `useSemicolons` is true (default) the `dax` string is converted from the native US/UK format to non-US/UK. That is, commas (list separators) will be converted to semicolons and periods (decimal separators) will be converted to commas. Vice versa if `useSemicolons` is set to false. +- `void FormatDax(IEnumerable objects, bool shortFormat, bool? skipSpace)` - formats DAX expressions on all objects in the provided collection +- `void FormatDax(IDaxDependantObject obj)` - queues an object for DAX expression formatting when script execution is complete, or when the `CallDaxFormatter` method is called. +- `void CallDaxFormatter(bool shortFormat, bool? skipSpace)` - formats all DAX expressions on objects enqueued so far +- `void Info(string message)` - Displays an informational message. +- `void Warning(string message)` - Displays a warning message. +- `void Error(string message)` - Displays an error message. +- `measure SelectMeasure(Measure preselect = null, string label = "...")` - Displays a list of all measures and �prompts the user to select one. +- `T SelectObject(this IEnumerable objects, T preselect = null, string label = "...") where T: TabularNamedObject` - Displays a list of the provided objects, prompting the user to select one, and returns that object (or null if the cancel button was pressed). +- `IList SelectObjects(this IEnumerable objects, IEnumerable preselect = null, string label = "...") where T: TabularNamedObject` - Displays a list of the provided objects, prompting the user to select any number of objects and returns the list of objects selected (or null if the cancel button was pressed). + +# Saving a script as a macro + +Scripts that you use often can be saved as reusabe macros, which are always available when you launch Tabular Editor. Moreover, macros are automatically integrated in the context menu of the **TOM Explorer view** and you can even use the **Tools > Customize...** option to add macros to existing or custom menus and toolbars. + +To save a script as a macro, use the **C# Script > Save as Macro...** option. + +![Save New Macro](~/content/assets/images/save-new-macro.png) + +Provide a name for your macro. You can use backslashes to organize macros into folders, i.e. a name such as "My Macros\Test" will create a "My Macros" submenu in the context menu of the TOM Explorer, and within this submenu there will be a "Test" menu option that invokes the script. + +You may also provide an optional tooltip which will be displayed when hovering over the menu option created by the macro. + +You should also specify the macro context, which specifies the type(s) of objects that needs to be selected in order for the macro to be available in the context menu. + +Lastly, you can specify a C# expression which should evaluate to true/false (typically based on the `Selected` or `Model` objects) under **Macro enabled condition (advanced)**. This lets you control more granularly whether the macro should be enabled or not, based on the current selection. For example, you could use the following expression: + +```csharp +Selected.Measures.Count == 1 +``` + +to enable your macro only when exactly 1 measure is selected. + +# Managing macros + +You can view all previously saved macros in the **Macros view**. To bring this view into focus, use the **View > Macros** menu option. This view allows you to: + +- **Rename a macro** (simply put the cursor into the **Name** column and type the new name) +- **Delete a macro.** Select it and click the red "X" button above the list of macros. +- **Edit a macro.** Double-click the macro in the list (double-click on the "Id" column of the list). This will open the macro in a new C# script view, where you can make code changes. Hit Ctrl+S to save the code changes. If you need to edit other macro properties (tooltip, macro context, etc.), use the **C# Script > Edit Macro...** menu option. + +# Next steps + +- @personalizing-te3 +- @boosting-productivity-te3 + +# Further reading + +- @csharp-scripts +- @useful-script-snippets \ No newline at end of file diff --git a/content/localization/zh/csharp-script-Template_zh.md b/content/localization/zh/csharp-script-Template_zh.md new file mode 100644 index 00000000..d5f24a8a --- /dev/null +++ b/content/localization/zh/csharp-script-Template_zh.md @@ -0,0 +1,40 @@ +--- +uid: csharp-script-template +title: +author: +updated: yyyy-mm-dd +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Title + +## Script Purpose + +

    + +> [!NOTE] +> This script does not work when connected to a Power BI Desktop model, due to the limitations of Power BI Desktop External tools: [External Tool Limitations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). You can still experiment with the script by enabling unsupported modeling operations under "File > Preferences" (TE2) or "Tools > Preferences" (TE3) + +

    + +## Script + +### Script Title + +```csharp +// Scripts Goes here +``` + +### Explanation + +## Example Output + +
    +Image description + \ No newline at end of file diff --git a/content/localization/zh/csharp-script-library-advanced_zh.md b/content/localization/zh/csharp-script-library-advanced_zh.md new file mode 100644 index 00000000..1bfd33d4 --- /dev/null +++ b/content/localization/zh/csharp-script-library-advanced_zh.md @@ -0,0 +1,30 @@ +--- +uid: script-library-advanced +title: Advanced C# Scripts +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# C# Script Library: Advanced Scripts + +These are more advanced scripts with sophisticated functionalities requiring a more advanced understanding of the C# language and TOM. They are more difficult to modify and thus recommended only once you have become comfortable with the foundations of C# Scripting in Tabular Editor. + +
    +
    + +|
    Script Name
    | Purpose | Use-case | +| ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Count Model Objects](xref:script-count-things) | Counts all the different objects by type in a model. | When you need an overview of the model contents or want to count objects by type. | +| [Output Object Details in a Grid](xref:script-output-things) | Outputs object details in a grid view. | When you need to output object details in a grid view for inspection. | +| [Create Date Table](xref:script-create-date-table) | Creates a formatted Date table based on selected Date columns in the model. | When you need to create a new date table based on a template. | +| [Create M Parameter (Auto-Replace)](xref:script-create-and-replace-parameter) | Creates a new M Parameter and automatically adds it to M Partitions. | When you want to replace strings in multiple partitions (i.e. connection strings) with a dynamic M Parameter. | +| [Format Power Query](xref:script-format-power-query) | Formats the Power Query of a selected M Partition by using the powerqueryformatter.com API. | When you have complex Power Query and need to make it more readable for reading or making changes. | +| [Implement Incremental Refresh](xref:script-implement-incremental-refresh) | Configures Incremental Refresh automatically using parameters from a UI dialogue box. | When you need to implement incremental refresh but aren't comfortable with the configuration in the table settings. | +| [Remove Measures with Errors](xref:script-remove-measures-with-error) | Creates a new M Parameter and automatically adds it to M Partitions. | When you want to replace strings in multiple partitions (i.e. connection strings) with a dynamic M Parameter. | +| [Find & Replace in Selected Measures](xref:script-find-replace) | Searches for a substring in the DAX of selected measures, replacing with another substring. | When you need to quickly find/replace values in multiple DAX measures (i.e. `CALCULATE` filter or broken object references). | +| [Databricks Semantic Model Set-up](xref:script-databricks-semantic-model-set-up) | Friendly name tables and columns and set column best practices | When your Databricks object names need making more user friendly. | +| [Create Databricks Relationships](xref:script-create-databricks-relationships) | Create relationships based on primary and foreign key definitions in Databricks Unity Catalog | When you want to re-use Databricks relationship definitions that have already been defined in Unity Catalog. | +| [Add Databricks Metadata Descriptions](xref:script-add-databricks-metadata-descriptions) | Update table and column descriptions based on Databricks Unity Catalog | When you want to re-use Databricks table and column comments that have already been defined in Unity Catalog. | \ No newline at end of file diff --git a/content/localization/zh/csharp-script-library-beginner_zh.md b/content/localization/zh/csharp-script-library-beginner_zh.md new file mode 100644 index 00000000..d566b8ea --- /dev/null +++ b/content/localization/zh/csharp-script-library-beginner_zh.md @@ -0,0 +1,29 @@ +--- +uid: script-library-beginner +title: Beginner C# Scripts +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# C# Script Library: Beginner Scripts + +These are more basic scripts that are easy to understand or modify. They have a defined scope and limited complexity; you don't need a reasonable knowledge of the C# language to use, understand and modify these scripts. They are thus a good place to start when beginning to author C# Scripts in Tabular Editor. + +
    +
    + +|
    Script Name
    | Purpose | Use-case | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [Count Table Rows](xref:script-count-rows) | Evaluates a COUNTROWS ( 'Table' ) of a selected table. | When you want to check how many rows are in a table, or if it's been loaded. | +| [Create Sum Measures from Columns](xref:script-create-sum-measures-from-columns) | Create SUM ( 'Table'[Column] ) measures from any selected column. | When you have many columns in a new table / model and must make many measures at once. | +| [Create Measure Table](xref:script-create-measure-table) | Create a measure table | When you want to create an empty table to use as an organizing measure table | +| [Create Table Groups](xref:script-create-table-groups) | Organize the model into Table Groups | When you want to have an automatic organization of your tables using the table group feature of Tabular Editor 3 | +| [Create M Parameter](xref:script-create-m-parameter) | Create a new M Parameter in 'Shared Expressions' | When you want to create a parameter to use in other Power Query queries (M Partitions / Shared Expressions). | +| [Edit Hidden Partitions](xref:script-edit-hidden-partitions) | Reveals the properties of hidden partitions in Calc. Groups & Calc. Tables | When you need to see or edit the TOM properties of these hidden partitions. | +| [Format Numeric Measures](xref:script-format-numeric-measures) | Formats the chosen measures | When you want to quickly apply a format string to the currently selected measures | +| [Show Data Source Dependencies](xref:script-show-data-source-dependencies) | Shows dependencies for data sources | For explicit (legacy) data sources it can be hard to know exactly where they are used. This script shows you which partition reference the chosen data source | +| [Create Field Parameters](xref:create-field-parameter) | Quickly create a field parameter table | Choose the objects that should be in the field parameter and the script will take care of the rest | +| [Display Unique Column Values](xref:script-display-unique-column-values) | Display unique values in a column | When you want to see the unique values in the currently selected column | \ No newline at end of file diff --git a/content/localization/zh/csharp-script-library_zh.md b/content/localization/zh/csharp-script-library_zh.md new file mode 100644 index 00000000..81dfa18a --- /dev/null +++ b/content/localization/zh/csharp-script-library_zh.md @@ -0,0 +1,41 @@ +--- +uid: csharp-script-library +title: C# Script Library +author: Morten Lønskov +updated: 2023-02-23 +--- + +# C# Script Library + +![C# Script Library](~/content/assets/images/Cscripts/script-library-header.png) + +--- + +This section contains official Tabular Editor scripts that have been verified and validated by the Tabular Editor team. These scripts are used in demos, conferences and documentation by the Tabular Editor team, and are maintained here for your convenience. Use of these scripts are still your own responsibility. + +There are also other resources online with C# Scripts that are maintained by the community such as PowerBI.tips excellent repository: [PowerBI.Tips C# Script Repository](https://github.com/PowerBI-tips/TabularEditor-Scripts) and Michael Kovalsky's excellent blog [ElegantBI](https://www.elegantbi.com/) and [Repository for Tabular Scripts](https://github.com/m-kovalsky/Tabular) + +## Tabular Editor Versions + +The top of each article denotes script compatability in TE2.x (Tabular Editor 2) and/or TE3.x (Tabular Editor 3) + +### Scripting with Tabular Editor as a Power BI External Tool + +

    + +> [!NOTE] +> Some scripts does not work when connected to a Power BI Desktop model, due to the limitations of Power BI Desktop External tools: [External Tool Limitations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). You can still experiment with the script by enabling unsupported modeling operations under preferences.

    + +### [Tabular Editor 2 Preferences](#tab/TE2Preferences) + +"File > Preferences" +![Edit Hidden Partitions](~/content/assets/images/te2-file-menu.png) + +### [Tabular Editor 3 Preferences](#tab/TE3Preferences) + +"Tools > Preferences" +![Edit Hidden Partitions](~/content/assets/images/tools-menu.png) + + + + diff --git a/content/localization/zh/csharp-scripts_zh.md b/content/localization/zh/csharp-scripts_zh.md new file mode 100644 index 00000000..6e113ddb --- /dev/null +++ b/content/localization/zh/csharp-scripts_zh.md @@ -0,0 +1,275 @@ +--- +uid: csharp-scripts +title: C# Scripts +author: Daniel Otykier +updated: 2025-08-27 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# C# Scripts + +This is an introduction to the C# Scripting capabilities of Tabular Editor 3. Information in this document is subject to change. Also, make sure to check out our script library @csharp-script-library, for some more real-life examples of what you can do with the scripting capabilities of Tabular Editor. + +## Why C# scripting? + +The goal of the UI of Tabular Editor is to make it easy to perform most tasks commonly needed when building Tabular Models. For example, changing the Display Folder of multiple measures at once is just a matter of selecting the objects in the explorer tree and then dragging and dropping them around. The right-click context menu of the explorer tree provides a convenient way to perform many of these tasks, such as adding/removing objects from perspectives, renaming multiple objects, etc. + +There may be many other common workflow tasks, which are not as easily performed through the UI however. For this reason, Tabular Editor offers C# scripting, which lets advanced users write a script using C# syntax, to more directly manipulate the objects in the loaded Tabular Model. + +## Code Assist + +The C# script editor supports Roslyn-powered completion and call tips and from Tabular Editor 3.23.0, completion supports substring and capital-letters acronym matching. + +## Objects + +The [scripting API](xref:api-index) provides access to two top-level objects, `Model` and `Selected`. The former contains methods and properties that allow you to manipulate all objects in the Tabular Model, whereas the latter exposes only objects that are currently selected in the explorer tree. + +The `Model` object is a wrapper of the [Microsoft.AnalysisServices.Tabular.Model](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) class, exposing a subset of it’s properties, with some additional methods and properties for easier operations on translations, perspectives and object collections. The same applies to any descendant objects, such as Table, Measure, Column, etc. which all have corresponding wrapper objects. Please see for a complete listing of objects, properties and methods in the Tabular Editor wrapper library. + +The main advantage of working through this wrapper is, that all changes will be undoable from the Tabular Editor UI. Simply press CTRL+Z after executing a script, and you will see that all changes made by the script are immediately undone. Furthermore, the wrapper provides convenient methods that turn many common tasks into simple one-liners. We will provide some examples below. It is assumed that the reader is already somewhat familiar with C# and LINQ, as these aspects of Tabular Editors scripting capabilities will not be covered here. Users unfamiliar with C# and LINQ should still be able to follow the examples given below. + +## Setting object properties + +If you want to change a property of one object in particular, obviously the easiest way to do so would be directly through the UI. But as an example, let us see how we could achieve the same thing through scripting. + +Say you want to change the Format String of your [Sales Amount] measure in the 'FactInternetSales' table. If you locate the measure in the explorer tree, you can simply drag it onto the script editor. Tabular Editor will then generate the following code, which represents this particular measure in the Tabular Object Model: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"] +``` + +Adding an extra dot (.) after the right-most bracket, should make the autocomplete menu pop up, showing you which properties and methods exist on this particular measure. Simply choose "FormatString" in the menu, or write the first few letters and hit Tab. Then, enter an equal sign followed by "0.0%". Let us also change the Display Folder of this measure. Your final code should look like this: + +```csharp +Model.Tables["FactInternetSales"].Measures["Sales Amount"].FormatString = "0.0%"; +Model.Tables["FactInternetSales"].Measures["Sales Amount"].DisplayFolder = "New Folder"; +``` + +**Note:** Remember to put the semicolon (;) at the end of each line. This is a requirement of C#. If you forget it, you will get a syntax error message when trying to execute the script. + +Hit F5 or the "Play" button above the script editor to execute the script. Immediately, you should see the measure moving around in the explorer tree, reflecting the changed Display Folder. If you examine the measure in the Property Grid, you should also see that the Format String property has changed accordingly. + +### Working with multiple objects at once + +Many objects in the object model, are actually collections of multiple objects. For example, each Table object has a Measures collection. The wrapper exposes a series of convenient properties and methods on these collections, to make it easy to set the same property on multiple objects at once. This is described in detail below. Additionally, you may use all the standard LINQ extension methods to filter and browse the objects of a collection. + +Below is a few examples of the most commonly used LINQ extension methods: + +- `Collection.First([predicate])` Returns the first object in the collection satisfying the optional [predicate] condition. +- `Collection.Any([predicate])` Returns true if the collection contains any objects (optionally satisfying the [predicate] condition). +- `Collection.Where(predicate)` Returns a collection that is the original collection filtered by the predicate condition. +- `Collection.Select(map)` Projects each object in the collection into another object according to the specified map. +- `Collection.ForEach(action)` Performs the specified action on each element in the collection. + +In the above examples, `predicate` is a lambda expression that takes a single object as input, and returns a boolean value as output. For example, if `Collection` is a collection of measures, a typical `predicate` could look like: + +`m => m.Name.Contains("Reseller")` + +This predicate would return true only if the Name of the measure contains the character string "Reseller". Wrap the expression in curly braces and use the `return` keyword, if you need more advanced logic: + +```csharp +.Where(obj => { + if(obj is Column) { + return false; + } + return obj.Name.Contains("test"); +}) +``` + +Going back to the examples above, `map` is a lambda expression that takes a single object as input, and returns any single object as output. `action` is a lambda expression that takes a single object as input, but does not return any value. + +## Working with the **Model** object + +To quickly reference any object in the currently loaded Tabular Model, you can drag and drop the object from the explorer tree and into the C# script editor: + +![Dragging and dropping an object into the C# script editor](~/content/assets/images/drag-object-to-script.gif) + +Please refer to the [TOM documentation](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.model.aspx) for an overview of which properties exist on the Model and its descendant objects. Additionally, refer to for a complete listing of the properties and methods exposed by the wrapper object. + +## Working with the **Selected** object + +Being able to explicitly refer to any object in the Tabular Model is great for some workflows, but sometimes you want to cherry pick objects from the explorer tree, and then execute a script against only the selected objects. This is where the `Selected` object comes in handy. + +The `Selected` object provides a range of properties that make it easy to identify what is currently selected, as well as limiting the selection to objects of a particular type. When browsing with Display Folders, and one or more folders are selected in the explorer tree, all their child items are considered to be selected as well. +For single selections, use the singular name for the type of object you want to access. For example, + +`Selected.Hierarchy` + +refers to the currently selected hierarchy in the tree, provided that one and only one hierarchy is selected. Use the plural type name, in case you want to work with multiselections: + +`Selected.Hierarchies` + +All properties that exist on the singular object, also exist on its plural form, with a few exceptions. This means that you can set the value of these properties for multiple objects at once, with just one line of code and without using the LINQ extension methods mentioned above. For example, say you wanted to move all currently selected measures into a new Display Folder called "Test": + +`Selected.Measures.DisplayFolder = "Test";` + +If no measures are currently selected in the tree, the above code does nothing, and no error is raised. Otherwise, the DisplayFolder property will be set to "Test" on all selected measures (even measures residing within folders, as the `Selected` object also includes objects in selected folders). If you use the singular form `Measure` instead of `Measures`, you will get an error unless the current selection contains exactly one measure. + +Although we cannot set the Name property of multiple objects at once, we still have some options available. If we just want to replace all occurrences of some character string with another, we can use the provided "Rename" method, like so: + +```csharp +Selected.Measures + .Rename("Amount", "Value"); +``` + +This would replace any occurence of the word "Amount" with the word "Value" in the names of all currently selected measures. +Alternatively, we may use the LINQ ForEach()-method, as described above, to include more advanced logic: + +```csharp +Selected.Measures + .ForEach(m => if(m.Name.Contains("Reseller")) m.Name += " DEPRECATED"); +``` + +This example will append the text " DEPRECATED" to the names of all selected measures where the names contain the word "Reseller". Alternatively, we could use the LINQ extension method `Where()` to filter the collection before applying the `ForEach()` operation, which would yield exactly the same result: + +```csharp +Selected.Measures + .Where(m => m.Name.Contains("Reseller")) + .ForEach(m => m.Name += " DEPRECATED"); +``` + +## Helper methods + +Tabular Editor provides a set of special helper methods to make certain script tasks easier to achieve. Note that some of these may be invoked as extension methods. For example, `object.Output();` and `Output(object);` are equivalent. + +- `void Output(object value)` - halts script execution and displays information about the provided object. When the script is running as part of a command line execution, this will write a string representation of the object to the console. +- `void SaveFile(string filePath, string content)` - convenient way to save text data to a file. +- `string ReadFile(string filePath)` - convenient way to load text data from a file. +- `string ExportProperties(IEnumerable objects, string properties)` - convenient way to export a set of properties from multiple objects as a TSV string. +- `void ImportProperties(string tsvData)` - convenient way to load properties into multiple objects from a TSV string. +- `void CustomAction(string name)` - invoke a macro by name. +- `void CustomAction(this IEnumerable objects, string name)` - invoke a macro on the specified objects. +- `string ConvertDax(string dax, bool useSemicolons)` - converts a DAX expression between US/UK and non-US/UK locales. If `useSemicolons` is true (default) the `dax` string is converted from the native US/UK format to non-US/UK. That is, commas (list separators) will be converted to semicolons and periods (decimal separators) will be converted to commas. Vice versa if `useSemicolons` is set to false. +- `void FormatDax(this IEnumerable objects, bool shortFormat, bool? skipSpace)` - formats DAX expressions on all objects in the provided collection +- `void FormatDax(this IDaxDependantObject obj)` - queues an object for DAX expression formatting when script execution is complete, or when the `CallDaxFormatter` method is called. +- `void CallDaxFormatter(bool shortFormat, bool? skipSpace)` - formats all DAX expressions on objects enqueued so far +- `void Info(string)` - Writes an informational message to the console (only when the script is executed as part of a command line execution). +- `void Warning(string)` - Writes a warning message to the console (only when the script is executed as part of a command line execution). +- `void Error(string)` - Writes an error message to the console (only when the script is executed as part of a command line execution). +- `T SelectObject(this IEnumerable objects, T preselect = null, string label = "Select object") where T: TabularNamedObject` - Displays a dialog to the user prompting to select one of the objects specified. If the user cancels the dialog, this method returns null. +- `void CollectVertiPaqAnalyzerStats()` - If Tabular Editor is connected to an instance of Analysis Services, this runs the VertiPaq Analyzer statistics collector. +- `long GetCardinality(this Column column)` - If VertiPaq Analyzer statistics are available for the current model, this method returns the cardinality of the specified column. + +For a full list of available helper methods and their syntax, view @script-helper-methods. + +### Debugging scripts + +As mentioned above, you can use the `Output(object);` method to pause script execution, and open a dialog box with information about the passed object. You can also use this method as an extension method, invoking it as `object.Output();`. The script is resumed when the dialog is closed. + +The dialog will appear in one of four different ways, depending on the kind of object being output: + +- Singular objects (such as strings, ints and DateTimes, except any object that derives from TabularNamedObject) will be displayed as a simple message dialog, by invoking the `.ToString()` method on the object: + +![C-sharp Output](~/content/assets/images/c-sharp-script-output-function.png) + +- Singular TabularNamedObjects (such as Tables, Measures or any other TOM NamedMetadataObject available in Tabular Editor) will be shown in a Property Grid, similar to when an object has been selected in the Tree Explorer. Properties on the object may be edited in the grid, but note that if an error is encountered at a later point in the script execution, the edit will be automatically undone, if "Auto-Rollback" is enabled: + +![C-sharp Output](~/content/assets/images/c-sharp-script-auto-rollback.png) + +- Any IEnumerable of objects (except TabularNamedObjects) will be displayed in a list, where each list item shows the `.ToString()` value and type of the object in the IEnumerable: + +![C-sharp Output](~/content/assets/images/c-sharp-script-output-to-string-function.png) + +- Any IEnumerable of TabularNamedObjects will cause the dialog to display a list of the objects on the left, and a Property Grid on the right. The Property Grid will be populated from whatever object is selected in the list, and properties may be edited just as when a single TabularNamedObject is being output: + +![C-sharp Output](~/content/assets/images/c-sharp-script-output-function-enumerated.png) + +You can tick the "Don't show more outputs" checkbox at the lower left-hand corner, to prevent the script from halting on any further `.Output()` invocations. + +## .NET references + +You can use the `using` keyword to shorten class names, etc. just like in regular C# source code. In addition, you can include external assemblies by using the syntax `#r ""` similar to .csx scripts used in Azure Functions. + +For example, the following script will now work as expected: + +```csharp +// Assembly references must be at the very top of the file: +#r "System.IO.Compression" + +// Using keywords must come before any other statements: +using System.IO.Compression; +using System.IO; + +var xyz = 123; + +// Using statements still work the way they're supposed to: +using(var data = new MemoryStream()) +using(var zip = new ZipArchive(data, ZipArchiveMode.Create)) +{ + // ... +} +``` + +By default, Tabular Editor applies the following `using` keyword (even though they are not specified in the script), to make common tasks easier: + +```csharp +using System; +using System.Linq; +using System.Collections.Generic; +using Newtonsoft.Json; +using TabularEditor.TOMWrapper; +using TabularEditor.TOMWrapper.Utils; +using TabularEditor.UI; +``` + +In addition, the following .NET Framework assemblies are loaded by default: + +- System.Dll +- System.Core.Dll +- System.Data.Dll +- System.Windows.Forms.Dll +- Microsoft.Csharp.Dll +- Newtonsoft.Json.Dll +- TomWrapper.Dll +- TabularEditor.Exe +- Microsoft.AnalysisServices.Tabular.Dll + +## Compatibility + +The scripting APIs for Tabular Editor 2 and Tabular Editor 3 are mostly compatible, however, there are cases where you want to conditionally compile code depending on which version you're using. For this, you can use preprocessor directives, which were introduced in Tabular Editor 3.10.0. + +```csharp +#if TE3 + // This code will only be compiled when the script is running in TE3 (version 3.10.0 or newer). + Info("Hello from TE3!"); +#else + // This code will be compiled in all other cases. + Info("Hello from TE2!"); +#endif +``` + +If you need to know the exact version of Tabular Editor at script runtime, you can inspect the assembly version: + +```csharp +var currentVersion = typeof(Model).Assembly.GetName().Version; +Info(currentVersion.ToString()); +``` + +The public product version (for example, "2.20.2" or "3.10.1") can be found using this code: + +```csharp +using System.Diagnostics; + +var productVersion = FileVersionInfo.GetVersionInfo(Selected.GetType().Assembly.Location).ProductVersion; +productVersion.Output(); // productVersion is a string ("2.20.2" or "3.10.1", for example) +``` + +If you just want the major version number (as an integer), use: + +```csharp +var majorVersion = Selected.GetType().Assembly.GetName().Version.Major; +majorVersion.Output(); // majorVersion is an integer (2 or 3) +``` + +## Known issues and limitations + +- Certain script operations may cause the Tabular Editor 3 application to crash or become unresponsive, due to the way scripts are executed. For example, a script with an infinite loop (`while(true) {}`) will cause the application to hang. If this happens, you will have to end the Tabular Editor process through the Windows Task Manager. + +If you intend to save the script as a [macro](xref:creating-macros), please be aware of the following limitations: + +- If the script body contains local methods with access modifiers (`public`, `static`, etc.), the script cannot be saved as a macro. Remove the access modifiers, or move the method into a class instead. +- Macros currently do not support the `await` keyword, if used in the script body. If your script body calls into asynchronous methods, you should use `MyAsyncMethod.Wait()` or `MyAsyncMethod.Result` instead of `await MyAsyncMethod()`. It is fine to use `await` in `async` methods that are defined elsewhere in the script. \ No newline at end of file diff --git a/content/localization/zh/data-refresh-view_zh.md b/content/localization/zh/data-refresh-view_zh.md new file mode 100644 index 00000000..11ff997b --- /dev/null +++ b/content/localization/zh/data-refresh-view_zh.md @@ -0,0 +1,26 @@ +--- +uid: data-refresh-view +title: Data Refresh view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + partial: TE3 Desktop Edition includes this feature, however refreshing tables through External Tools is not currently supported by Microsoft and may cause issues in Power BI Desktop. + - edition: Business + - edition: Enterprise +--- + +# Data Refresh View + +The Data Refresh view allows you to investigate in detail how your data is being refreshed on the server. +A new active refresh will appear when a new refresh is triggered through the TOM Explorer. + +
    + Data Refresh View
    Figure 1: Data Refresh View in Tabular Editor. New refresh can be started by right-clicking a table and selecting refresh
    +
    + +A new refresh will run in the background so that you can continue to build your dataset, and Tabular Editor will let you know if the refresh fails with a pop up. + +> [!WARNING] +> If you are using TE as an External Tool to Power BI and have activated _Allow Unsupported modeling operations_ do _NOT_ start a refresh as this is prone to corrupt your .pbix file. diff --git a/content/localization/zh/data-security-about_zh.md b/content/localization/zh/data-security-about_zh.md new file mode 100644 index 00000000..c1a0ac12 --- /dev/null +++ b/content/localization/zh/data-security-about_zh.md @@ -0,0 +1,395 @@ +--- +uid: data-security-about +title: What is Data Security? +author: Kurt Buhler +updated: 2023-03-02 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# What is Data Security? + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-visual-abstract.png) + +--- + +Published datasets can be configured with Data Security using [Row-Level Security (RLS)](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls) (for Tables) or [Object-Level Security (OLS)](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-ols?tabs=table) (for Tables & Columns). **The purpose of Data Security is to ensure users only see and use data they are permitted to, both in published reports and when making their own, self-service data solutions.** To do this, users are assigned to **Roles** which have **RLS** or **OLS** rules configured, which **filter (RLS)** or **restrict (OLS)** queries generated by reports & client tools like Power BI Desktop or Excel. + +While [not obligatory](https://learn.microsoft.com/en-us/power-bi/guidance/rls-guidance#when-to-avoid-using-rls), [Data Security is a common feature of a robust, secure & compliant enterprise BI solution](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-report-consumer-planning#enforce-data-security-based-on-consumer-identity). This series is a functional introduction to Data Security, as it pertains to tabular modeling & Tabular Editor. + +_Both RLS & OLS can be easily configured, modified and tested from within Tabular Editor._ + +--- + +- **About Data Security and RLS/OLS (This Article):** A functional overview of RLS & OLS. +- [**Modify/Setup an RLS Configuration:**](data-security-setup-rls.md) How to configure RLS in a dataset. +- [**Modify/Setup an OLS Configuration:**](data-security-setup-ols.md) How to configure OLS in a dataset. +- [**Testing RLS/OLS with Impersonation:**](data-security-testing.md) How to easily validate Data Security with Tabular Editor. + +
    +
    WHY CONFIGURE ROW- OR OBJECT-LEVEL SECURITY?
    + Configuring RLS or OLS can be benificial for your model & reporting: +
  • Reduce risk and improve governance by ensuring users only see data they have access to. +
  • Configure dynamic RLS with central role tables for consistency and lightweight maintenance. +
  • Have granular control over what data and objects can be queried. +
  • + +--- + +### How Does it Work? + +Data Security works at the level of the model. It is configured following the below steps: + +#### 1. **Create Roles:** + +_Roles_ are groups of users who have the same permission / data security logic. _Users_ in this case are identified by their email, or the email of an [Azure AD Security Group](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-tenant-level-planning#integration-with-azure-ad). Examples of roles: + +- Users in the same region, team or department (_EMEA_, _UA Sales Team_). +- Users with the same role, function or access clearance (_Key Account Managers_, _SC Clearance_). +- Groups defined by other business logic or arbitrary rules (_Externals_, _Build Users_). + +
    + Data Security Create Role
    Figure 1: In Tabular Editor, Roles are one of the top-level object types (like Tables, Relationships, etc).
    +
    + +> [!IMPORTANT] +> After creating a new Role in Tabular Editor, you must first set the `Model Permission` property to `Read`. + +#### 2. **Specify Rules:** + +_Rules_ are applied for each role to one or more objects, depending on the security type: + +- _RLS Table Permissions:_ DAX table expressions -- return each row evaluating `True`. These permissions traverse relationships; **the design of the model is imperative to good RLS rules.** + +
    + Data Security Create Role
    Figure 2: In Tabular Editor, Table Permissions for RLS are visible under the role. New table permissions can be created by right-clicking a Role and selecting 'Add Table Partition...'
    +
    + +
    + Data Security Create Role
    Figure 3: Table Permission DAX is visible in the Expression Editor when selecting a Table Permission.
    +
    + +- _OLS Object Permissions:_ These permissions apply to the primary objects as well as all downstream dependents. + - `Read` (Can see / query) + - `None` (Cannot see / query) + - `Default` (No policy configured; equivalent to `Read`) + +
    + Data Security Create Role
    Figure 4: In Tabular Editor, object permissions are accessible in the 'Properties' window, under the 'Translations, Perspectives, Security' heading.
    +
    + +#### 3. **Assign Users to Roles:** + +Once configured in the dataset, users must be added to their respective roles. + +- _Power BI:_ Roles are assigned either via Tabular Editor or the **Power BI/Fabric service**, [in the dataset settings from the Workspace](https://learn.microsoft.com/en-us/fabric/security/service-admin-row-level-security#manage-security-on-your-model). +- _SSAS / AAS:_ Roles are assigned via the Role object, by right-clicking and selecting "Edit Members..." +- _Power BI Embedded:_ You must [generate an embed token](https://learn.microsoft.com/en-us/power-bi/developer/embedded/cloud-rls#generate-an-embed-token). + +You can assign and remove users/groups from roles through Tabular Editor the following way: + +1. Right-Click the **Role**, select **Edit members**... + +
    + Data Security Create Role
    Figure 7:Users can be assigned to roles by right-clicking a Role and selecting 'Edit members...'.
    +
    + +2. Click the **dropdown button** on the 'Add Windows AD Member' button and choose **Azure AD Member**: + +
    + Data Security Create Role
    Figure 8: For AAS/SSAS models, users can be added via the 'Edit members...' dialog box.
    +
    + +3. Specify the Azure AD user identity (typically, the user e-mail address) as the **Member Name** property. +4. Click **OK**. +5. **Save** the model. + +> [!IMPORTANT] +> If your organisation is using on-premises Active Directory with SQL Server Analysis Services, you will need to use the **Windows AD Member** option instead of **Azure AD Member**. + +> [!NOTE] +> It is [recommended](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-tenant-level-planning#strategy-for-using-groups) to manage Data Security and Access with [Azure Active Directory Groups](https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/how-to-manage-groups).
    Using this approach is preferred you can centralize management of security & user segmentation. + +#### 4. **Provision Users Access to the Dataset:** + +_Power BI:_ Users must be given dataset access according to the [usage scenario](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-usage-scenario-overview). + +- _App Audience:_ Users / their Azure AD Groups are added to the appropriate [App Audience](https://data-goblins.com/power-bi/app-audiences). +- _Workspace Viewer:_ Users / their Azure AD Groups are added as [Workspace Viewers](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-workspaces-workspace-level-planning#workspace-access) +- _Dataset Readers:_ Users / their Azure AD Groups are given [Dataset-specific permissions](https://learn.microsoft.com/en-us/power-bi/connect-data/service-datasets-manage-access-permissions) via a Dataset or dependent item (i.e. Report). + +> [!WARNING] +> Users given [Admin, Member or Contributor Workspace Roles](https://learn.microsoft.com/en-us/power-bi/collaborate-share/service-roles-new-workspaces#workspace-roles) have **_write permissions_** to a dataset. As such, Data Security like RLS and OLS will not filter or block data for users with these roles.

    +> **_If a user is an Admin, Member or Contributor, they will be able to see all the data_**.

    +> As much as is reasonable, try to distribute and manage permissions via Power BI Apps. + +#### 5. **Validating Security:** + +RLS and OLS can only be tested with impersonation once user groups have been added & granted access. Validate security via: + +- _Tabular Editor:_ Using [User Impersonation](data-security-testing.md). +- _Power BI Service:_ In the [Dataset Security settings](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls#validating-the-role-within-the-power-bi-service). + +
    + Data Security Create Role
    Figure 5: The easiest way to test Data Security is via Impersonation with Tabular Editor. The 'Impersonation' option is possible from any data querying feature (DAX Queries, Pivot Grid, Preview Data).
    +
    + +> [!NOTE] +> To validate data security with impersonation, the below factors must be all true: +> +> - The user must be assigned a role. +> - The user must have read permissions to the dataset. +> - The user must have **build permissions** to the dataset. + +
    + Data Security Create Role
    Figure 6: A demonstration of RLS testing in Tabular Editor using impersonation. Shown is testing with (A) Data Preview, (B) DAX Queries and (C) Pivot Grid.
    +
    + +> [!IMPORTANT] +> Testing Data Security with Impersonation using Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. TE3 Desktop Licenses cannot benefit from this feature. This is because roles are assigned in the Power BI Service. + +--- + +### How Does it Look? + +Depending on how you have designed and configured Data Security, the experience may differ for users. +Below are common examples for common scenarios of RLS and/or OLS implementation in a dataset + +_Click a tab to see the example and get an explanation of each:_ + +--- + +# [None](#tab/nodatasecurity) + +**Without security, everyone with access to the dataset can see all the data.** + +The only restriction is whether they have access to the reports / datasets. + +![No security](~/content/assets/images/data-security/data-security-no-security.png) + +_In the example, both Jack & Janet can see all of the data._ + +# [Static RLS](#tab/staticrls) + +**With RLS configured, data is filtered to only rows the user are allowed to see.** This is done according to the _Table Permissions_ configured in the model for that Table & Role. These Table Permissions are DAX Table Expressions configured for a specific model table. Rows that evaluate `True` are returned; rows that return `False` are filtered out due to RLS. + +The most simple Table Permissions are _Static_: + +```dax +// Table Permission for 'Regions' table and 'CTG' role +'Regions'[Territory] = "Central Transit Gate" +``` + +![Configuration of static RLS](~/content/assets/images/data-security/data-security-static-rls.png) + +_In the example:_ + +1. _Jack can see only rows for which 'Region'[Territory] = "Central Transit Gate", since they belong to the 'CTG' Role._ +2. _Executives, whom are permitted to see all the data, are added to a role with no Table Permissions._ +3. _Tommy, a user who can access the dataset but belongs to no Role, will not see any data. All visuals and queries will return a 'grey box of death'._ + +_It is necessary to create roles when using Data Security even when there are users like Executives, who have unrestricted data access._ + +# [Dynamic RLS](#tab/dynamicrls) + +**With RLS configured, data is filtered to only rows the user are allowed to see.** +This is done according to the _Table Permissions_ configured in the model for that Table & Role. + +These Table Permissions are DAX Table Expressions configured for a specific model table. +Rows that evaluate `True` are returned; rows that return `False` are filtered out due to RLS. + +**_Dynamic_ RLS relies on the `USERPRINCIPALNAME()` or `USERNAME()` functions to compare them to a security table.** +The security table will then return logic that applies the table filter to that or another table in the model. + +This is referred to as _Dynamic_ RLS as the result will change depending on the user; the `USERPRINCIPALNAME()`. +Below is an example of a Dynamic RLS Table permission: + +```dax +// Table Permission for 'Regions' table and 'Territory Directors' role. + +// Get Current User +VAR _CurrentUser = +SELECTCOLUMNS ( + FILTER ( + 'Employees', + 'Employees'[Employee Email] = USERPRINCIPALNAME () + ), + "@Name", 'Employees'[Employee Name] +) +RETURN +'Regions'[Territory Directors] IN _CurrentUser +``` + +The above table permission gets the Employee Name alias from the 'Employees' table, which is applied without a relationship to the 'Regions' table. +The result for any user added to this role is that they will only see data where: + +1. Their e-mail is in the 'Employees'[Employee Email] column +2. Their alias in 'Employees'[Employee Name] matches one in 'Regions'[Territory Directors] + +![Dynamic RLS Configuration](~/content/assets/images/data-security/data-security-dynamic-rls.png) + +_In the example, each Territory Director only sees the Territories for which they are responsible:_ + +1. _Jack sees "Central Transit Gate" and "Io"._ +2. _Janet sees "Arcadia III"._ +3. _Elisa sees all data, as the Execs role has no Table Permissions set._ + +_Dynamic RLS is the most common way to secure an Enterprise Dataset. It usually requires configuration & maintenance of a central **Security Table** used across all Enterprise datasets._ + +# [RLS (Multiple Roles)](#tab/multipleroles) + +**When a user is assigned to multiple roles, each of which have different Table Permissions, they will see data permitted by either role.** Users will see data where at least one Table Permission DAX expression evaluates to `True` for model table rows; it takes the logical `or`. + +This is dangerous if it's not expected; some developers may anticipate the intersection to be taken; to only show rows where **both** Table Permissions return `True`. This will only happen if Table Permissions are configured for multiple tables in the model; **within a Role**, the intersection is taken for all Table Permissions in the model. + +![RLS Roles combine table permissions using a logical OR](~/content/assets/images/data-security/data-security-combining-rls-roles.png) + +_In the example:_ + +1. _Jack is assigned to the roles 'CTG' and 'FTL'. They will see any rows where 'Products'[Type] = "FTL" **OR** where 'Regions'[Territory] = "Central Transit Gate". This is likely not the expected behavior; the developer likely intends to produce the result of the 'CTG/FTL' role, which returns only rows where both are true._ +2. _Elijah has the 'FTL' role, and will only see rows where 'Products'[Type] = "FTL". +3. _Abdullah has the 'CTG/FTL' role, and will only see rows where **BOTH** 'Products'[Type] = "FTL" **AND** 'Regions'[Territory] = "Central Transit Gate"._ + +_Situations like this illustrate the importance of designing clear Data Security configuration during model design, ensuring it aligns with organizational policies and existing Data Security / Access Management practices._ + +# [OLS](#tab/ols) + +**With OLS configured as `None`, queries are prevented from being evaluated; they return an error.** This is an important distinction from RLS; RLS filters data, but OLS prevents evaluation. If the OLS permission is set to `Read`, there is no effect. This is done according to the OLS Permission Level of the Column or Table, and **affects all downstream dependents** like Relationships and Measures. + +![OLS configured for the Cost column](~/content/assets/images/data-security/data-security-ols.png) + +_In the example, the column 'Territory Sales'[Cost] has an OLS Permission of `None` for the role 'Sales'. The reason is because of the below requirement:_ + +`'Sales' users are allowed to see Sales data, but not Cost or Margin data.` + +_This means that a user belonging to the 'Sales' role like Jack will not be able to see:_ + +1. _Any query or visual referring directly to the 'Territory Sales'[Cost] column_ +2. _Any DAX measure or calculation item referring directly to the 'Territory Sales'[Cost] column, like [Margin %]_ +3. _Any DAX measure or calculation item referring _indirectly_ (downstream) to the 'Territory Sales'[Cost] column._ +4. _Any object that has a column with a relationship with 'Territory Sales'[Cost]_ + +_The result of 1-4 will be an **error** in query evaluation. A Power BI visual will return a **grey box of death**._ + +> [!WARNING] +> __Business users will often perceive expected OLS results as being a 'broken' report, visual, or query. __
    If using OLS and users are expected to confront these evaluations, try the following:
    +> +> 1. Educate users about the security. +> 2. Try to handle the error and return a more meaningful message. +> 3. In Build scenarios, consider hiding the object. +> 4. A further optimization to be tested is setting `IsPrivate` to `True` or `IsAvailableInMDX` to `False`. + +# [RLS+OLS (Single Role)](#tab/rlsols) + +With both RLS & OLS configured, there are two possible outcomes: + +1. **The user has _one role_ with RLS & OLS:** The security will work as expected, presuming it is configured correctly. +2. **The user has _multiple roles_ where RLS & OLS are configured, separately:** The role combination is unsupported and the user will get an error. + +Because of #2, if you expect to use both RLS & OLS, this must be carefully considered during model design. + +An example of #1 is below: + +![Combining OLS and RLS in the same role produces the expected outcome](~/content/assets/images/data-security/data-security-ols-and-rls-functional.png) + +_In the example:_ + +1. _Jack, who has been assigned the 'CTG' Role:_ + - _Can only see data for "Central Transit Gate" due to the RLS Table Permission on 'Regions'._ + - _Can only see Sales data; they can't see [Margin %]. This is due to the OLS Object Permission `None` on 'Territory Sales'[Cost], which affects the dependent measure [Margin %]_ +2. _Elisa, who has been assigned the 'Execs' Role, can see all the data. There has been no RLS Table Permission or OLS Object Permission (set to `Default`) configured for 'Execs'._ +3. _Tommy, who has not been assigned a Role, cannot see any data._ + +> [!WARNING] +> Scenarios combining RLS & OLS are not rare.
    Scenarios using them correctly are.
    Ensure that if you have a requirement for RLS & OLS together, carefully consider it during model design. + +# [❌ RLS+OLS (Combine Roles)](#tab/rlsolscombined) + +With both RLS & OLS configured, there are two possible outcomes: + +1. **The user has _one role_ with RLS & OLS:** The security will work as expected, assuming it is configured correctly. +2. **The user has _multiple roles_ where RLS & OLS are configured, separately:** The role combination is unsupported and the user will get an error. + +Because of #2, if you expect to use both RLS & OLS, this must be carefully considered during model design. + +An example of #2 is below: + +![❌ Combining OLS and RLS across roles will produce an error](~/content/assets/images/data-security/data-security-ols-and-rls-dysfunctional.png) + +_In the above example:_ + +1. _Jack, who has been assigned the 'Read Users' Role:_ + - _Can only see data for "Central Transit Gate" due to the RLS Table Permission on 'Regions'._ + - _Can only see Sales data; they can't see [Margin %]. This is due to the OLS Object Permission `None` on 'Territory Sales'[Cost], which affects the dependent measure [Margin %]_ +2. _Janet, who has been assigned both the 'Read Users' and 'Build Users' Role:_ + - _Cannot see any data. The combination of RLS / OLS permissions across Roles are invalid._ + +_Users granted Build Permissions to the dataset are added to the Build Azure AD Security group, which is set for the 'Build Users' role. Build users can see tables not in existing reports, so `None` OLS permission is configured for the 'Employees' table. This produces a combination where RLS and OLS permissions cannot be reconciled, resulting in an error._ + +> [!WARNING] +> Scenarios combining RLS & OLS are not rare.
    Scenarios using them correctly are.
    Ensure that if you have a requirement for RLS & OLS together, carefully consider it during model design. + +# [❌ No Roles](#tab/role) + +**No user will be able to read any data until they are added to the role**, so long as Data Security is configured in the dataset. + +![No Access or No Role](~/content/assets/images/data-security/data-security-no-role.png) + +> [!NOTE] +> Don't forget to give users access to the dataset AND add them to the security role. + +# [❌ No Access](#tab/access) + +**If a user is added to a security role, this will not automatically grant them read access to the dataset.** They will still not be able to access any dataset or reports. + +![No Access or No Role](~/content/assets/images/data-security/data-security-no-access.png) + +> [!NOTE] +> Don't forget to give users access to the dataset AND add them to the security role. + +> [!WARNING] +> **It is a best practice to avoid distribution via Workspace Roles, where feasible.**
    If necessary, ensure that the **Principle of Least Permissions** is applied : users should have the minimum access necessary to do what they need. + +# [❌ Access Via Workspace Roles](#tab/workspace) + +**If a user is given access to a dataset via the Admin, Member or Contributor roles, they will be able to view all data, irrespective of the data security configuration and their assigned roles.** This is a common mistake in scaling or self-service Power BI ecosystems, resulting in data leaks and non-compliance. + +![Problems with ](~/content/assets/images/data-security/data-security-workspace-roles.png) + +> [!WARNING] +> **It is a best practice to avoid distribution via Workspace Roles, where feasible.**
    If necessary, ensure that the **Principle of Least Permissions** is applied : users should have the minimum access necessary to do what they need. + +--- + +--- + +### Hard Limitations + +Some reporting or data modeling features will not work with RLS or OLS configuration. Examples are: + +1. [RLS Limitations](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls#considerations-and-limitations) + - Service Principles added to RLS Roles + - Testing with Direct Query models using SSO + - [Publish-to-Web in Power BI](https://learn.microsoft.com/en-us/power-bi/guidance/rls-guidance#when-to-avoid-using-rls) + +2. [OLS Limitations](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-ols?tabs=table#considerations-and-limitations) + - Combining separate RLS roles & OLS roles (discussed above) + - Q&A features + - Quick Insights + - Smart Narrative + - Excel Data Types gallery + +--- + +### Further Reading & References + +For additional, detailed reading about Data Security, see the below references: + +1. [Power BI Security Whitepaper](https://learn.microsoft.com/en-us/power-bi/guidance/whitepaper-powerbi-security) +2. [Power BI Docs - Security](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-power-bi-security) +3. [Analysis Services Docs - Object-Level Security](https://learn.microsoft.com/en-us/analysis-services/tabular-models/object-level-security?view=asallproducts-allversions) +4. [Power BI Implementation Planning - Security](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-security-report-consumer-planning) +5. [(Related) Power BI Implementation Planning - Information Protection & Data Loss Prevention (DLP)](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-info-protection-data-loss-prevention-overview) \ No newline at end of file diff --git a/content/localization/zh/data-security-setup-ols_zh.md b/content/localization/zh/data-security-setup-ols_zh.md new file mode 100644 index 00000000..365fc8f9 --- /dev/null +++ b/content/localization/zh/data-security-setup-ols_zh.md @@ -0,0 +1,103 @@ +--- +uid: data-security-setup-ols +title: Setup or Modify OLS +author: Kurt Buhler +updated: 2023-03-02 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Setup or Modify Object-Level Security (OLS) + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-configure-ols-visual-abstract.png) + +--- + +**OLS is changed by adjusting the Roles or Object Permissions defined for Tables or Columns.** Object Permissions are TOM Properties visible with the `Object Level Security` property that can be either `Default` (no OLS; functionally similar to `Read`), `Read`, or `None`. OLS differs from RLS in that it does not filter data, but prevents execution of the object **and all dependents.** This means any relationship or measure that references the object where `Object Level Security` is set to `None` will return an error upon evaluation. + +--- + +- [**About Data Security and RLS/OLS:**](data-security-about.md) A functional overview of RLS & OLS. +- [**Modify/Setup an RLS Configuration:**](data-security-setup-rls.md) How to configure RLS in a dataset. +- **Modify/Setup an OLS Configuration (This Article):** How to configure OLS in a dataset. +- [**Testing RLS/OLS with Impersonation:**](data-security-testing.md) How to easily validate Data Security with Tabular Editor. + +--- + +## Configuring OLS in Tabular Editor 3 + +_Below is an overview of common changes one might make to existing OLS. Additionally, strategies for configuring OLS for atypical objects (Measures, Calculation Groups) are described, below:_ + +--- + +### 1. Remove a Role + +To remove a Role from the model, you can simply delete the Role object with `Del` or by right-clicking and selecting 'Delete'. + +
    + Data Security Create Role
    Figure 1: Deleting a Role in the model.
    +
    + +> [!NOTE] +> All users assigned to this role will no longer be able to see model data, so long as at least one other Role exists. + +--- + +### 2. Add a New Role + +To add a Role to the model: + +1. **Right-Click the 'Roles' Object Type:** This will open the dialogue to let you create a new Role. +2. **Select 'Create' > 'Role':** Name the new role. + +
    + Data Security Create Role
    Figure 2: Creating a new Role in the model.
    +
    + +3. **Set the `Model Permission` Property to `Read`:** This is necessary for Power BI datasets. + +
    + Data Security Create Role
    Figure 3: Setting the Model Permission property is necessary for Power BI.
    +
    + +4. **Set Permissions:** Set RLS Table Permissions and/or OLS Object Permissions, as described, below. + +--- + +### 3. Remove OLS + +To remove OLS from the model, all Columns and Tables must have their `Object Level Security` property configured to `Default` for all roles. To remove Data Security from the model, all Roles must be deleted. + +
    + Data Security Create Role
    Figure 4: The Object-Level Security property can be found in the Properties pane when selecting a Column or Table. The property does not exist for Measures, Relationships and other Object Types.
    +
    + +> [!NOTE] +> Once all roles are deleted, all users will be able to see all data so long as they have _Read_ permissions on the dataset. + +--- + +### 4. Setup or Change OLS + +Setup or Modification of OLS is trivial for Columns and Table. You just have to select the object and navigate to the `Object Level Security` property, using the dropdown to change the property to the desired value. + +
    + Data Security Create Role
    Figure 4: The Object-Level Security property can be changed with an adjacent drop-down, allowing selection of Default, None or Read.
    +
    + +--- + +### 5. Combine OLS with RLS + +Successfully combining RLS with OLS requires designing a model and Data Security / Access Management strategy that align. Since RLS and OLS cannot combine across roles, this means if you plan on implementing both RLS and OLS, users are limited to a single role. + +--- + +### 6. Configure OLS for Measures + +Natively, OLS works only on Columns, Tables and their dependents; there is no `Object-Level Security` property for measures. However, since OLS also applies to dependents, it is possible to design OLS that works on measures via disconnected tables or calculation groups. To do this, the measure DAX has to be altered to evaluate a column or calculation group configured with RLS. If the `Object-Level Security` property of that object is `None`, then the Measure will not evaluate. + +See also [this article by SQLBI](https://www.sqlbi.com/articles/hiding-measures-by-using-object-level-security-in-power-bi/) which explains this approach in detail. \ No newline at end of file diff --git a/content/localization/zh/data-security-setup-rls_zh.md b/content/localization/zh/data-security-setup-rls_zh.md new file mode 100644 index 00000000..7b55b9bf --- /dev/null +++ b/content/localization/zh/data-security-setup-rls_zh.md @@ -0,0 +1,181 @@ +--- +uid: data-security-setup-rls +title: Setup or Modify RLS +author: Kurt Buhler +updated: 2023-03-14 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Configure Row-Level Security (RLS) + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-configure-rls-visual-abstract.png) + +--- + +**RLS is changed by adjusting the Roles or Table Permissions defined for Tables.** This DAX _Filter Expression_ can be viewed in the Expression Editor window when selecting a Table Permission within a particular role. This Filter Expression is the most important piece of the RLS configuration that determines what data is seen by a user. + +--- + +- [**About Data Security and RLS/OLS:**](data-security-about.md) A functional overview of RLS & OLS. +- **Modify/Setup an RLS Configuration (This Article):** How to configure RLS in a dataset. +- [**Modify/Setup an OLS Configuration:**](data-security-setup-ols.md) How to configure OLS in a dataset. +- [**Testing RLS/OLS with Impersonation:**](data-security-testing.md) How to easily validate Data Security with Tabular Editor. + +--- + +## Configuring RLS in Tabular Editor 3 + +_Below is an overview of common changes one might make to existing RLS:_ + +--- + +### 1. Remove a Role + +To remove a Role from the model, you can simply delete the Role object with `Del` or by right-clicking and selecting 'Delete'. + +
    + Data Security Create Role
    Figure 1: Deleting a Role in the model.
    +
    + +> [!NOTE] +> All users assigned to this role will no longer be able to see model data, so long as at least one other Role exists. + +--- + +### 2. Add a New Role + +To add a Role to the model: + +1. **Right-Click the 'Roles' Object Type:** This will open the dialogue to let you create a new Role. +2. **Select 'Create' > 'Role':** Name the new role. + +
    + Data Security Create Role
    Figure 2: Creating a new Role in the model.
    +
    + +3. **Set the `Model Permission` Property to `Read`:** This is necessary for any members of the role to be able to access the dataset at all. + +
    + Data Security Create Role
    Figure 3: Setting the Model Permission property is necessary.
    +
    + +4. **Set Permissions:** Set RLS Table Permissions and/or OLS Object Permissions, as described, below. + +--- + +### 3. Remove RLS + +To remove RLS from the model, all Table Permissions must be deleted. To remove Data Security from the model, all Roles must be deleted. + +> [!NOTE] +> Once all roles are deleted, all users will be able to see all data so long as they have _Read_ permissions on the dataset. + +--- + +### 4. Modify a Table Permission + +To modify an existing Table Permission for a specific role: + +1. **Expand the Role:** This will reveal the Table Permissions. +2. **Select the Table Permission:** This will reveal the DAX for the Filter Permission in the Expression Editor. + +
    + Data Security Create Role
    Figure 4: The DAX Filter Expression is visible in the Expression Editor when selecting a Table Permission.
    +
    + +3. **Adjust the Filter Expression / RLS Table Permissions:** It is recommended that you test / validate the DAX before using it: + +- Copy the Filter Expression to a new DAX Query window under an `EVALUATE` statement. +- Add it as the Expression of an `ADDCOLUMNS` statement iterating over Table, or part of the table. +- Execute it and observe the results. +- Replace `USERNAME()` or `USERPRINCIPALNAME()` in dynamic RLS with a known value from the Security Table. +- Re-run the DAX Query and validate that the results appear as expected. Repeat until satisfied. + +
    + Data Security Validation
    Figure 5: An example of how RLS can be validated from the DAX query window by using the Filter Expression inside of an Iterator over the Table (or part of the table, like the user alias). In this example, the original RLS Filter Expression in the Table Permission has been modified (Yellow) where an explicit User Principal Name in the dataset is added instead, to test (Green). The RLS code is executed inside of the ADDCOLUMNS iterator over a relevant part of the table. The checkmark indicates any row that evaluates to TRUE. The test demonstrates that the RLS is - for this UPN - working as expected, since Gal Aehad is the only user returning TRUE when their UPN is given.
    +
    + +```dax +EVALUATE + +// Create a table to test your RLS +ADDCOLUMNS ( + VALUES ( 'Regions'[Territory Directors] ), + "@RLS-Validation", + + // RLS Code + VAR _CurrentUser = + SELECTCOLUMNS ( + FILTER ( + 'Employees', + 'Employees'[Employee Email] + + // Replace USERPRINCIPALNAME() with a user email to test + = "gal.aehad@spaceparts.co" // USERPRINCIPALNAME () + ), + "@Name", 'Employees'[Employee Name] + ) + RETURN + 'Regions'[Territory Directors] IN _CurrentUser + +) + +// Order from TRUE() to FALSE() +// Where it is TRUE() the data will be visible +ORDER BY [@RLS-Validation] DESC +``` + +--- + +### 5. Add a New Table Permission to a Role + +To add a new table permission: + +1. **Right-Click the Role:** Select 'Add table permission...' + +
    + Data Security Create Role
    Figure 6: In Tabular Editor, Table Permissions for RLS are visible under the role. New table permissions can be created by right-clicking a Role and selecting 'Add Table Partition...'
    +
    + +2. **Select the Table and press 'OK':** Select the table for which you want to create the permission. +3. **Write the Filter Expression / RLS Table Permissions:** Write the DAX for the filter expression. As above, you want to validate this filter expression (See **Figure 5**): + +- Copy the Filter Expression to a new DAX Query window under an `EVALUATE` statement. +- Add it as the Expression of an `ADDCOLUMNS` statement iterating over Table, or part of the table. +- Execute it and observe the results. +- Replace `USERNAME()` or `USERPRINCIPALNAME()` in dynamic RLS with a known value from the Security Table. +- Re-run the DAX Query and validate that the results appear as expected. Repeat until satisfied. + +--- + +### 6. Assign or Remove Users from a Role + +You can assign and remove users/groups from roles through Tabular Editor. + +1. Right-Click the **Role**, select **Edit members**... + +
    + Data Security Create Role
    Figure 7:Users can be assigned to roles by right-clicking a Role and selecting 'Edit members...'.
    +
    + +2. Click the **dropdown button** on the 'Add Windows AD Member' button and choose **Azure AD Member**: + +
    + Data Security Create Role
    Figure 8: For AAS/SSAS models, users can be added via the 'Edit members...' dialog box.
    +
    + +3. Specify the Azure AD user identity (typically, the user e-mail address) as the **Member Name** property. +4. Click **OK**. +5. **Save** the model. + +> [!IMPORTANT] +> If your organisation is using on-premises Active Directory with SQL Server Analysis Services, you will need to use the **Windows AD Member** option instead of **Azure AD Member**. + +> [!NOTE] +> Once a Power BI dataset has been published to the Power BI Service, you can also manage role members through the [Dataset Security settings](https://learn.microsoft.com/en-us/power-bi/enterprise/service-admin-rls#manage-security-on-your-model). Alternatively, you can manage role members through [SQL Server Management Studio](https://learn.microsoft.com/en-us/analysis-services/tabular-models/manage-roles-by-using-ssms-ssas-tabular?view=asallproducts-allversions) (this applies to AAS/SSAS models in addition to Power BI dataset). + +--- diff --git a/content/localization/zh/data-security-testing_zh.md b/content/localization/zh/data-security-testing_zh.md new file mode 100644 index 00000000..da2cf8ab --- /dev/null +++ b/content/localization/zh/data-security-testing_zh.md @@ -0,0 +1,79 @@ +--- +uid: data-security-testing +title: Testing RLS/OLS +author: Kurt Buhler +updated: 2023-03-02 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Testing Data Security with Impersonation + +![Data Security Visual Abstract](~/content/assets/images/data-security/data-security-testing-visual-abstract.png) + +--- + +**DAX Queries**, **Pivot Grid**, or **Preview Data** enable testing of Data Security in Tabular Editor. It is recommended to _always_ test Data Security with any changes to configuration, to mitigate risk of incorrect RLS/OLS implementation and the consequences thereof. + +> [!IMPORTANT] +> Testing Data Security with Impersonation using Tabular Editor 3 is limited to datasets hosted in an Analysis Services instance or the Power BI Service. Tabular Editor 3 Desktop Licenses cannot benefit from this feature. + +--- + +- [**About Data Security and RLS/OLS:**](data-security-about.md) A functional overview of RLS & OLS. +- [**Modify/Setup an RLS Configuration:**](data-security-setup-rls.md) How to configure RLS in a dataset. +- [**Modify/Setup an OLS Configuration:**](data-security-setup-ols.md) How to configure OLS in a dataset. +- **Testing RLS/OLS with Impersonation (This Article):** How to easily validate Data Security with Tabular Editor. + +--- + +## Testing with Impersonation + +**Data Security can be easily tested using _Impersonation_ in Tabular Editor 3.** Impersonation is a feature that lets you view a query result as a model Role or User. It is similar to the _'View As Role...'_ feature in the Power BI service, with two key differences: + +1. The End-User being impersonated requires **dataset Build permissions** in addition to Role assignment & Dataset Read access. +2. Any query can be executed within Tabular Editor 3; it is not limited to available report visuals, as in the Power BI Service. + +This is valuable, as it lets the developer run defined tests to see how the result would be viewed by any end-user with Build permissions. This helps ensure that even for complex queries and DAX expressions, the Data Security works as expected, and users only see what they should see. + +> [!IMPORTANT] +> Ensure that Build permissions are not provisioned by providing end-users Workspace Roles (Contributor, Member, Admin), as these roles have **Write** permissions to the dataset and thus bypass Data Security; the testing will appear to not work, even if it's configured correctly. + +
    + Data Security Create Role
    Figure 1: A demonstration of RLS testing in Tabular Editor using impersonation. Shown is testing with (A) Data Preview, (B) DAX Queries and (C) Pivot Grid.
    +
    + +--- + +## How to Test with Impersonation + +To test with impersonation, follow the below steps: + +1. **Ensure that the Dataset Configuration & Access is correct:** + End-users being impersonated... + +- _...have been assigned to the appropriate **Roles**._ +- _...have been provisioned **Dataset Read Access**._ +- _...have been provisioned **Dataset Build Access**. (Power BI)_ +- _...**are not** Workspace Contributors, Members or Admins (Power BI)_. + +2. **Create a new DAX Query, Pivot Grid or Preview Data window:** + +- It's recommended that you start with _Preview Data_ to observe the effect on model tables +- Thereafter, perform a second validation with a _DAX Query_. This is because DAX Queries can be saved for documentation and later reference, if a change occurs in the model requiring re-testing. + +3. **Select 'Impersonation' and enter the User e-mail**: If you have implemented _Static RLS_, you can test the role, instead. + +4. **Explore the data to validate that the results appear as expected:** (according to the Security Rules). + +### Tips for Testing + +1. **Test more than one user:** It's recommended you test at least 3-10 different users per Role. You can also automate the testing to iterate through each UPN in the Security Table (i.e. using C# Scripting and Macros). + +2. **Test each Role & Table Permission:** Since each Table Permission represents a different DAX Filter Expression, they all have to be tested, separately. Ensure that each Role is tested, and that each test includes the relevant tables with configured Filter Expressions. For example, if a Role consists of table expressions on the 'Customers' and 'Products' table, ensure your query includes attributes from both tables for validation purposes. + +3. **Test many Queries/Measures:** Try to find complex queries to test, particularly those which might be problematic in the context of Data Security. For example, if calculations require comparing to a total, unfiltered average (i.e. % of total) and it's expected that _that total_ is not filtered in RLS, the developer may need to re-think the Data Security implementation as a function of the model. \ No newline at end of file diff --git a/content/localization/zh/dax-debugger_zh.md b/content/localization/zh/dax-debugger_zh.md new file mode 100644 index 00000000..1e568783 --- /dev/null +++ b/content/localization/zh/dax-debugger_zh.md @@ -0,0 +1,218 @@ +--- +uid: dax-debugger +title: DAX debugger +author: Daniel Otykier +updated: 2022-01-19 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX debugger + +> [!NOTE] +> The DAX debugger was introduced in version 3.2.0. Information in this article is subject to change as we add more capabilities to the debugger. + + + +It is no secret that DAX is a relatively complex language which is difficult to master. Most data model developers have probably experienced a situation, where the DAX code did not return the expected result. In this situation, it is helpful to break down the code, variable by variable and function call by function call, to better understand what is going on. + +Until now, this "breakdown" of the code was a tedious and time consuming task, which often involved capturing DAX queries executed by client tools, in order to break them down and execute smaller pieces of the queries in [DAX Studio](https://daxstudio.org/) or [SQL Server Management Studio](https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15). + +Tabular Editor 3 introduces the concept of the **DAX debugger**, which is a tool that makes the process of stepping into the DAX code of your model, much, much easier. At a conceptual level, the debugger is similar to traditional IDE debuggers, such as the one found in Visual Studio when developing C# applications. + +## Prerequisites + +The DAX debugger analyses the DAX code in your model and generates suitable DAX queries for evaluating sub expressions, row contexts, etc., allowing you to step through the code in an interactive fashion. + +In order for this to work, Tabular Editor 3 must operate in **connected** or **workspace mode**, such as when loading model metadata directly from Power BI Desktop or any other instance of Analysis Services. + +# Getting started + +While Tabular Editor 3 is connected to an instance of Analysis Services, the debugger can be started in one of two different ways: + +- Through a Pivot Grid +- Through a DAX query + +Once the debugger is started, you are presented with a number of new views that provide contextual information about the code being debugged, as well as a DAX script view that highlights the portion of code currently debugged. + +> [!TIP] +> Before starting a debugging session, consider formatting your DAX code to make the code easier to read. + +# Debugging through a Pivot Grid + +1. Create a new Pivot Grid (**File > New > Pivot Grid**) +2. Add the measure you wish to debug to the Pivot Grid. You can either: + +- Drag a measure from the TOM Explorer, or +- Right-click on a measure in the TOM Explorer and choose **Add to pivot grid**, or +- Select the measure from the Pivot Grid field list (**Pivot Grid > Show fields**) + +3. (Optional) Add one or more columns to the Pivot Grid in the Filter area, Columns area or Row area. +4. Right-click on the value cell within the Pivot Grid and choose **Debug this value**. + +![Debug From Pivot](~/content/assets/images/debug-from-pivot.png) + +# Debugging through a DAX Query + +1. Create a new DAX query (**File > New > DAX Query**). +2. Type in or paste the DAX query. This should typically be a query made up of a `SUMMARIZECOLUMNS` call with one or more (explicit) measures, such as the one generated by visuals in Power BI. + +> [!TIP] +> You can use the [Performance Analyzer](https://docs.microsoft.com/en-us/power-bi/create-reports/desktop-performance-analyzer) in Power BI Desktop to capture the query generated by visuals. + +3. Hit F5 to execute the query within Tabular Editor 3. Locate the value you want to debug, right-click the cell and choose **Debug**. + +![Debug From Query](~/content/assets/images/debug-from-query.png) + +# Debug views + +The debugger provides the following views (if they are hidden, they can be accessed through the **Debug > Windows** menu). + +- Locals +- Watch +- Evaluation Context +- Call Tree + +## Locals + +This view lists the columns, measures and variables within the current scope of execution and displays their values. It also displays the value of the current subexpression being debugged. Values in this list are updated automatically when stepping to a different subexpression, or when the evaluation context is changed. **Local values are always evaluated at the currently selected item of the call tree**. + +![Locals](~/content/assets/images/locals.png) + +You can inspect a locals value by clicking on the magnifying glass button within the **Value** column. This will bring up a popup dialog showing the value in more details. This is especially useful if the inspected value is a table. + +![Inspect locals value](~/content/assets/images/inspect-locals.png) + +If you prefer to inspect the locals value in a separate DAX query window, you can toggle off the **Use popup inspector** option under **Tools > Preferences > DAX Debugger > Locals**. + +![Dax Debugger Settings](~/content/assets/images/dax-debugger-settings.png) + +## Watch + +This view allows you to enter any DAX expression, which will be calculated within the current evaluation context. You can enter scalar as well as table expressions and you can use all DAX functions available and refer to variables within the current evaluation scope. Watch values are automatically updated when stepping to a different subexpression, or when the evaluation context is changed. **Watch values are always evaluated at the scope of the currently selected item in the evaluation context stack**. + +![Watch](~/content/assets/images/watch.png) + +To quickly add a variable, measure or subexpression to the Watch view, simply highlight a portion of code and drag it into the Watch view. You can also place the cursor over the expression you want to add, then right-click and choose **Watch this expression**: + +![Quick Add To Watch](~/content/assets/images/quick-add-to-watch.png) + +To add, duplicate or delete Watch expressions, use the right-click context menu of the Watch view: + +![Watch Context Menu](~/content/assets/images/watch-context-menu.png) + +The **Generate query** option is identical to the magnifying glass button within the **Value** column, highlighted in the screenshot below. By clicking this, the debugger will open a new DAX query document, that defines the context of the calculation as well as the calculation itself, allowing you to inspect the results in more details. This is particularly useful when the watch expression is a table expression, as shown below: + +![Inspect Watch](~/content/assets/images/inspect-watch.png) + +> [!TIP] +> What's the difference between the **Locals** view and the **Watch** view? +> +> - **Locals** shows the values of columns, measures, variables and other relevant sub-expressions, within the current scope of execution, including the value of the currently selected subexpression in the call tree. +> - **Watch** allows you to enter any DAX expression, which will be calculated within the current evaluation context. + +## Evaluation Context + +This view provides information about the DAX evaluation context of the current subexpression. For example, a `CALCULATE` expression might perform a context transition or add a filter to the evaluation context, or a `SUMX` iterator might add a row context. + +![Evaluation Context](~/content/assets/images/evaluation-context.png) + +You can double-click on an item in the Evaluation Context stack, to bring the focus to that item. This will cause all **Watch** expressions to be reevaluated in the new context (that is, all contexts from the bottom of the stack up to and including the currently focused item). This is illustrated in the animation below. Notice also how you can inspect the value of individual columns in the active row context by paging through rows within any active iterations: + +![Call Tree](~/content/assets/images/navigating-evaluation-context.gif) + +You can also toggle individual filters from the outer filter context (for example, grouping columns on the [`SUMMARIZECOLUMNS`](https://dax.guide/summarizecolumns) call that generated the query or filters specified in a Pivot Grid). This is illustrated in the animation below. Filters toggled this way will apply to both Watch and Locals. + +![Call Tree](~/content/assets/images/toggle-filters.gif) + +Lastly, you can browse the first 1000 rows of any iterator, setting the current row context to a specific row within those first 1000, by clicking on the Zoom button within the **Row** column. + +![Browse Row Contexts](~/content/assets/images/browse-row-contexts.png) + +## Call Tree + +This view provides an outline of the entire calculation and lets you easily navigate between subexpressions by double-clicking (you can also use shortcut keys for navigation). The tree also provides information about context transitions, iterations and row contexts. Branches of code that will not be executed (for example in an `IF` or `SWITCH` call, or when an iterator is empty) are striked out. + +![Call Tree](~/content/assets/images/call-tree.png) + +As you navigate between items in the call tree, the debug DAX script will highlight the code corresponding to the call tree item, while also indicating (with a gray background) the path taken to reach the highlighted code, as shown below: + +![Call Tree](~/content/assets/images/navigating-call-tree.gif) + +Notice how the values in the **Locals** view are updated as the tree is navigated. You can also navigate to a subexpression by placing the cursor over the expression, right-click and choose the **Step into selection** option (Ctrl+B). + +![Step into selection](~/content/assets/images/debugger-step-into-selection.png) + +## Scalar predicates + +Scalar predicates used in filter arguments of the [`CALCULATE`](https://dax.guide/calculate) or [`CALCULATETABLE`](https://dax.guide/calculatetable) functions are handled in a special way, in the **Locals** view. + +For example, the following measure uses a scalar predicate, to display only the sales made in USA or Canada. + +```dax +CALCULATE( + [Total Sales], + Geography[Country Region Code] = "US" || Geography[Country Region Code] = "CA" +) +``` + +At first glance, the expression on line 3 looks like it would return a scalar value (true/false). However, in DAX, filters are tables. In reality, the scalar predicate is converted to a table expression using the [`FILTER`](https://dax.guide/filter) function, as shown below: + +```dax +CALCULATE( + [Total Sales], + FILTER( + ALL(Geography[Country Region Code]), + Geography[Country Region Code] = "US" || Geography[Country Region Code] = "CA" + ) +) +``` + +The `FILTER` function is an iterator that iterates over the table `ALL(Geography[Country Region Code])`, that is - all the unique values of the "Country Region Code" column in the "Geography" table. Iterators generate a filter context for every row in the iteration. The scalar predicate is then evaluated in each such row context. In the case of the `FILTER` function, only the rows for which the predicate evaluates to `TRUE` are kept. In this example, the `FILTER` function would output a table with 1 column ("Country Region Code"), and 2 rows ("US" and "CA"). + +When debugging a scalar predicate, the **Locals** view will show two special items, **(Current expression)** and **(Filter expression)**. These are described below: + +![Debug Scalar Predicates](~/content/assets/images/debug-scalar-predicates.png) + +In the above screenshot: + +1. This is the scalar predicate currently being debugged. Even though this sub-expression looks like one that should return a scalar value (true/false), in reality, it returns a table. +2. **(Current expression)**: This is the _scalar_ value of the predicate, when evaluated within the current _row context_ generated by the `FILTER` function as described above. In the screenshot, the scalar value evaluates to `False`, because the value of [Country Region Code] in the current row context is "AU", as can be seen in the **Watch** view, (4). We can use the **Evaluation Context** view (5), to scroll through the rows of the iteration one by one. +3. **(Filter expression)**: This is the _table_ expression generated by the `FILTER` function, as described above. In the screenshot, this is a 1x2 table containing the values "US" and "CA". Clicking the magnifying glass button will open a popup that displays the table values in a grid. +4. We can use the **Watch** window to evaluate any DAX expression within the current evaluation context. In this case, since we have an active row context, we can directly refer to columns in the row context, such as `Geography[Country Region Code]`. We can see that the current value of this column is "AU", which is why the scalar predicate (2) evaluates to `False`. +5. We can use the **Evaluation Context** view to scroll through the rows of the iteration, one by one. This will update the values in the **Locals** view, as well as the **Watch** view, to reflect the values in the current row context. + +## Keyboard shortcuts + +Use the following keyboard shortcuts to quickly navigate the call tree: + +- **Step in (F11)** - steps into the first child of the current item in the call tree. If there are no more children, jumps to the next sibling. +- **Step out (Shift-F11)** - steps out to the parent of the current item in the call tree. +- **Step over (F10)** - jumps to the next function parameter, the next subexpression of an arithmetic operation, or steps into the current function call (if it is a non-trivial function). +- **Step back (Shift-F10)** - jumps to the previous function parameter, the previous subexpression of an arithmetic operation, or steps out to the parent of the current item if there are no parameters or subexpressions before the current item. +- **Step into selection (Ctrl-B)** - jumps to the expression under the cursor. If multiple paths lead to the same expression (for example, when a measure is referenced by multiple measures and these measures), a dialog will prompt you to choose the path. +- **Next row (F9)** - shifts the row context of the innermost iteration to the next row of the iterator. +- **Previous row (Shift-F9)** - shifts the row context of the innermost iteration to the previous row of the iterator. + +# Limitations and known issues + +The DAX debugger currently has the following limitations: + +- **UDFs:** User-defined functions (UDFs) are not currently supported. If a UDF is encountered in the code being debugged, the debugger may behave unexpectedly. +- Only a subset of DAX table expressions are supported when debugging a DAX query (for example, queries that rely on [SUMMARIZECOLUMNS](https://dax.guide/summarizecolumns) can be debugged, while other table functions are currently not supported). Queries that have been generated by Power BI (which can be captured through the Power BI Desktop Performance Analyzer) are generally supported. +- Queries that contain implicit measures or query-scoped calculations are currently not supported. +- When browsing the first 1000 rows of an iterator that arises out of a filtered table expression, the selected row in the browse window may not always correspond to the current row context in the evaluation context stack (type `CALCULATETABLE('
    ')` in the **Watch** window to inspect the current row context). +- The debugger currently only allows debugging DAX expressions on measures. +- [Visual calculations](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-visual-calculations-overview) cannot be debugged as they are defined using query-scoped columns. The debugger does not currently support query-scoped objects. +- If a measure is modified by a calculation item in the filter context, partial results shown in the Watch / Locals view of the debugger may be incorrect. + +If you encounter an issue with the debugger, other than those listed above, please post it to our [issue tracker](https://github.com/TabularEditor/TabularEditor3/issues) on the TE3 Community Support GitHub site. + +# Roadmap + +We plan to add many additional features to the DAX debugger over time, to address the issues above, and to make the tool even more capable. As always, feedback is more than welcome. Please use the [Discussions area](https://github.com/TabularEditor/TabularEditor3/discussion) for feature requests and general discussions. + +**Happy debugging!** diff --git a/content/localization/zh/dax-editor_zh.md b/content/localization/zh/dax-editor_zh.md new file mode 100644 index 00000000..3f3a0565 --- /dev/null +++ b/content/localization/zh/dax-editor_zh.md @@ -0,0 +1,70 @@ +--- +uid: dax-editor +title: DAX Editor +author: Daniel Otykier +updated: 2023-02-03 +--- + +# DAX Editor + +The **DAX Editor** is the centerpiece of Tabular Editor 3. + +It comes in three different _flavours_: + +- **Expression Editor** Used for making quick changes to singular DAX expressions on objects in the TOM Explorer. +- **DAX Query** (Connected feature) Used for writing DAX queries in order to retrieve data from the connected instance of Analysis Services / Power BI. +- **DAX Script** Used for viewing and editing DAX expressions and basic properties across multiple objects in a single document. + +All three flavours support the same operations in terms of [keyboard shortcuts](xref:shortcuts#dax-code), syntax highlighting, code assist, etc. + +## Code Assist features + +The main enabler of productivity in Tabular Editor 3's DAX Editor, is its **Parameter Info** and **Auto-Complete** features. Collectively, these are known as **Code Assist** features (other vendors use the term "IntelliSense"). + +**Parameter Info** provides details about the DAX function and its parameter at the position of the cursor. The information is displayed in a tooltip above the cursor. Hit [Esc] to close the tooltip and [Ctrl+Shift+Space] to display it. + +**Auto-Complete** provides context-sensitive suggestions as you type, in a dropdown box. You can use the keyboard to navigate the items in the dropdown and hitting [Enter] or [Tab] will insert the selected item into your code. You can hit [Esc] to close the dropdown and [Ctrl+Space] to open it. + +These features can also be invoked through the context menu of the editor. + +DAX calltips update as you cycle syntax alternatives using the Up/Down arrows. + +![Dax Code Assist](~/content/assets/images/dax-code-assist.png) + +Most aspects of code assist can be configured under [**Tools > Preferences > Text Editors > DAX Editor > Code Assist**](xref:preferences#dax-editor--code-assist). + +## Peek Definition + +While the cursor is over an object reference such as a variable or a measure reference, hit [Alt+F12] to display an inline editor with the definition of that object, below the cursor. This is useful when you want to see the DAX code of a referenced object without leaving the current position in the document. + +![Peek Definition](~/content/assets/images/peek-definition.png) + +Use the Esc key to close the Peek Definition panel again. + +## Go To Definition + +Instead of peeking, we can also jump straight to the location where the referenced object is defined. To do this, hit [F12]. If the referenced object is not defined within the current document, this operation will jump over to that object in the TOM Explorer. If needed, you can navigate back using [Alt+Left Arrow]. + +# Define Measure + +For DAX scripts and DAX queries, it is sometimes useful to include the definition of a measure that is referenced elsewhere in the code. The **Define Measure** feature lets you do that when the cursor is over a measure reference. You may also choose the **Define Measure with Dependencies** option if you want to include all downstream measure references as well. + +![Define Measure With Deps](~/content/assets/images/define-measure-with-deps.png) + +# Inline Measure + +If you want to bring the definition of a measure into the current document, the **Inline Measure** feature lets you do just that. When a row context is surronding the original measure reference, Tabular Editor automatically surrounds the measure expression with [`CALCULATE`](https://dax.guide/calculate) (which is implicit in measure references). + +# Format DAX + +The DAX Editor in Tabular Editor 3 automatically formats your code as you type, i.e. fixing casing of functions and object references, adding proper indentation and spaces between parentheses, etc. All of this can be configured under [**Tools > Preferences > Text Editors > DAX Editor > Auto Formatting**](xref:preferences#dax-editor--auto-formatting). + +However, sometimes it is necessary to format the entire document. This can be done by hitting [F6] or [Shift+F6] if you prefer more frequent line breaks. For DAX Queries, you may also use [Alt+F6] to reformat the code to always add commas at the front of a line, which is useful when debugging. + +# Refactoring + +If you want to change the name of a variable or extension column, you can use the **Refactor** option (Ctrl+R) while the cursor is located on the variable or extension column reference. This will select all instances of that object, allowing you to rename it everywhere at once. + +# Configurable keyboard shortcuts + +The DAX Editor and code editors in general are highly configurable and support a lot of additional commands for quickly and productively editing code. You can view all of these commands, as well as modify and assign keyboard shortcuts under **Tools > Preferences > Tabular Editor > Keyboard**. \ No newline at end of file diff --git a/content/localization/zh/dax-optimizer-integration_zh.md b/content/localization/zh/dax-optimizer-integration_zh.md new file mode 100644 index 00000000..db7431c9 --- /dev/null +++ b/content/localization/zh/dax-optimizer-integration_zh.md @@ -0,0 +1,123 @@ +--- +uid: dax-optimizer-integration +title: DAX Optimizer Integration +author: Daniel Otykier +updated: 2024-10-30 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX Optimizer Integration + +> [!NOTE] +> Tabular Editor 3 **Enterprise Edition** users are eligible for free DAX Optimizer access. [Learn more](https://blog.tabulareditor.com/2024/10/31/free-dax-optimizer-access-in-tabular-editor-3/) + +Tabular Editor 3.18.0 introduces **DAX Optimizer** as an integrated experience. [DAX Optimizer](https://daxoptimizer.com) is a service that helps you optimize your SSAS/Azure AS tabular models and Power BI/Fabric semantic models. The tool combines [VertiPaq Analyzer statistics](https://www.sqlbi.com/tools/vertipaq-analyzer/) with a static analysis of your DAX code, thus providing a prioritized list of recommendations, to help you quickly identify potential performance bottlenecks. + +> [!IMPORTANT] +> DAX Optimizer is a paid third-party service. In order to use the **DAX Optimizer** feature in Tabular Editor 3, you will need an [account for DAX Optimizer](https://www.daxoptimizer.com/free-tour/). + +## Video introduction + +Watch Marco Russo from [SQLBI](https://www.sqlbi.com) introduce the DAX Optimizer integration in Tabular Editor 3: + + + +## Getting started + +To access this feature, go to the **View** menu and choose **DAX Optimizer**. + +![Dax Optimizer](~/content/assets/images/dax-optimizer-view-menu.png) + +You will be presented with a new view similar to the figure below: + +![Dax Optimizer View](~/content/assets/images/dax-optimizer-view.png) + +To connect Tabular Editor 3 to the DAX Optimizer service, click **Connect...** through the **Options** menu. You will be prompted to enter your Tabular Tools (DAX Optimizer) credentials. + +If you wish to **disconnect** or **connect using a different account**, go to the **Options** menu again, and choose the **Reconnect...** option. Cancelling the dialog will disconnect the current session. + +If you want Tabular Editor 3 to automatically connect the next time the application is launched, you can check the **Connect automatically** option within the **Options** menu. If you have a DAX Optimizer account with workspaces in multiple regions, you can also choose which region to connect to through the **Options** menu. + +Lastly, the **Options** menu also lets you switch to a different account in [group scenarios](https://docs.daxoptimizer.com/how-to-guides/managing-groups). + +## Browsing workspaces and models + +Once connected, the dropdowns at the top of the view will be populated with your existing workspaces, models and model versions. Make your selections from left to right (i.e. choose the **Workspace** first, then the **Model**, then the **Version**). The view will display a summary of the currently selected model version, with information such as model size, number of tables, number of measures, etc. + +![Model Overview](~/content/assets/images/model-overview.png) + +> [!NOTE] +> Tabular Editor 3 lets you upload VPAX files in order to create new models or model versions in the DAX Optimizer service. If, however, you need to create or manage workspaces, move or share models, etc. you will need to do this through the [DAX Optimizer web interface](https://app.daxoptimizer.com). + +If a model version has not yet been analyzed, you will have an option to start the analysis. Note that, depending on your account plan, you may have a limited number of "runs" available. + +Once the analysis is complete, you will be presented with a summary showing the number of issues detected. The information shown is similar to what you would see in the DAX Optimizer web interface. + +Go to the **Issues** or **Measures** tab to view detailed results. Use the column headers to sort and filter the results. + +![Dax Optimizer Issues](~/content/assets/images/dax-optimizer-issues.png) + +## Navigating issues and measures + +When you double-click on an issue or measure in the detailed view shown above, you will be taken to the **DAX Optimizer Results** view, where the original DAX expression of the measure is shown, along with highlights of the problematic areas. The list on the left side of the screen lets you toggle which issues to highlight. Moreover, you can mark issues as **Fixed** or **Ignored** using the checkboxes within the list. + +![Dax Optimizer Results](~/content/assets/images/dax-optimizer-results.png) + +Click on the **Find in TOM Explorer...** button in the top-right area of the view, to navigate to the corresponding measure in the currently loaded model. + +Tick the **Track TOM Explorer** checkbox to keep the TOM Explorer in sync with the currently selected measure in the DAX Optimizer Results view. + +When you click on a measure reference in the DAX code panel within the **DAX Optimizer Results** view, the view will navigate to that measure. You can then use the **Back** (Alt+Left) and **Forward** (Alt+Right) buttons to navigate back and forth between the measures you have visited. + +## Upload models and model versions + +To upload VPAX statistics to DAX Optimizer, make sure Tabular Editor is currently connected to an instance of Analysis Services (SSAS, Azure AS, Power BI Desktop or Power BI/Fabric XMLA endpoint). Then, select the workspace in the top-left dropdown on the **DAX Optimizer** view. Click on **Upload...** within the **Options** menu. + +You will be presented with a dialog similar to the one shown below: + +![Upload Vpax](~/content/assets/images/upload-vpax.png) + +Here, you can choose whether the VPAX should be uploaded as a new model within the workspace, or whether the VPAX contains updated statistics for an existing model. + +- For a **new model**, you must supply a name and choose whether or not the VPAX should be [obfuscated](https://www.sqlbi.com/blog/marco/2024/03/15/vpax-obfuscator-a-library-to-obfuscate-vpax-files/) (see below for more details on obfuscation). You must also choose which [contract](https://docs.daxoptimizer.com/glossary/contract) the model should be uploaded under. This impacts the number and frequency of DAX Optimizer [_runs_](https://docs.daxoptimizer.com/glossary/run) you can subsequently perform on the model. +- For a **new model version**, you must select the existing model to update. + +Once you click the **OK** button, the VPAX file will be uploaded to DAX Optimizer, and you will be able to start analyzing the model. + +> [!NOTE] +> If no VertiPaq Analyzer statistics are available in Tabular Editor 3, these statistics will be collected for the current model before the VPAX file is uploaded. We will also automatically re-collect statistics if the last statistics collection is older than or equal to the statistics of the last VPAX file upload, for the specific model. + +### Obfuscation + +By default, VPAX files uploaded using Tabular Editor 3 will be obfuscated. In the **Upload Model** you may toggle obfuscation on/off for new model uploads. Subsequent model version uploads will be obfuscated or not depending on the first version upload. You can also export an obfuscated VPAX file locally without uploading to DAX Optimizer through the **VertiPaq Analyzer** view. In this case, a dictionary file is generated and stored on your local machine, next to the exported .ovpax file. This dictionary file is used to deobfuscate the contents of the .ovpax file. + +When obfuscated VPAX data is uploaded to the DAX Optimizer service through the **DAX Optimizer** view, Tabular Editor automatically keeps track of obfuscation dictionaries by storing them in the `%LocalAppData%\TabularEditor3\DaxOptimizer` folder on your local machine. As such, when browsing models using the **DAX Optimizer** feature in Tabular Editor 3, models are automatically deobfuscated if a suitable dictionary is found in this folder, providing a more seemless experience when using obfuscation. + +If the dictionary is not found, you will have an option to manually specify a dictionary file. + +![Obfuscated Model](~/content/assets/images/obfuscated-model.png) + +If no dictionary file is provided, you will only be able to browse the obfuscated model and DAX Optimizer results, meaning you will not be able to view the original DAX expressions or navigate to the corresponding measures in the TOM Explorer. + +[Learn more about DAX Optimizer obfuscation](https://docs.daxoptimizer.com/how-to-guides/obfuscating-files). + +> [!TIP] +> If you want to browse an obfuscated model through the DAX Optimizer web interface, you can specify a dictionary from the `%LocalAppData%\TabularEditor3\DaxOptimizer` location. The DAX Optimizer web interface performs the deobfuscation on the client side, so your dictionary is never uploaded to the DAX Optimizer service. + +### Analyze a model + +Once a VPAX file has been uploaded, please allow a few seconds for the file to be "verified" by the DAX Optimizer service. Once verified, you can perform a DAX Optimizer "run" by checking the "You agree to **consume 1 run** to analyze this model." checkbox, and then clicking the **Analyze** button in the **DAX Optimizer** view: + +![Dax Optimizer Analyze](~/content/assets/images/dax-optimizer-analyze.png) + +The analysis will take a few minutes to complete, depending on the size of the model and the number of measures. Once the analysis is complete, you will be presented with a summary of the issues detected. + +## Known issues and limitations + +The following are known issues and limitations with the **DAX Optimizer** feature, which we expect to address in future releases: + +- The **DAX Optimizer** view does not display how many "runs" are left on any given contract. As a workaround, sign in to https://app.daxoptimizer.com and click the "lightning" icon in the top-right corner, to view how many "runs" you have left per contract. \ No newline at end of file diff --git a/content/localization/zh/dax-query_zh.md b/content/localization/zh/dax-query_zh.md new file mode 100644 index 00000000..c229d881 --- /dev/null +++ b/content/localization/zh/dax-query_zh.md @@ -0,0 +1,123 @@ +--- +uid: dax-query +title: DAX Queries +author: Morten Lønskov +updated: 2025-08-27 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX Queries + +Tabular Editor has a built-in DAX query window to write and execute DAX queries against the semantic model. + +A widespread use case for DAX queries is the DAX query produced by the [Power BI Performance Analyzer](https://www.sqlbi.com/articles/introducing-the-power-bi-performance-analyzer/), where it is possible to copy the query of each visual for troubleshooting, debugging, or detailed performance analysis. + +The window can be opened while connected to a semantic model using either the **File > New > DAX Query** menu or the toolbar shortcut. + +![Dax Query New](~/content/assets/images/features/dax_query_window/create_new_dax_query.png) + +The built-in context-aware DAX Editor ensures that only the two valid DAX keywords are available when starting a new query: DEFINE or EVALUATE (Press Ctrl+Space to verify for yourself) + +## DAX Query Options + +The DAX query window has five different query options. + +![Dax Query Toolbar](~/content/assets/images/features/dax_query_window/dax_query_toolbar.png) + +1. **Execute (F5)**: If there is a selection, it executes the selected DAX; otherwise, it executes the full query in the DAX Query editor. +2. **Execute full query**: It executes the full query in the DAX Query editor +3. **Execute Selection (Shift+F5)**: If there is a selection, it executes it. Otherwise, it executes the EVALUATE statement where the cursor is currently located. +4. **Stop**: This button cancels the current query execution. +5. **Auto Execute Query**: It allows for keeping track of the connected semantic model and updating the query results whenever something changes in the model. This can be useful for understanding e.g. how the result of a measure changes if modified. +6. **Keep sorting and filtering**: It allows users to control how sorting and filtering are preserved in the result grid(s) when executing queries. There are three preferences available: + - **Never**: Sorting and filtering reset each time the query runs. + - **When query is modified**: Sorting and filtering reset only when the query structure changes. + - **Always**: Sorting and filtering persist as long as columns remain in the new query. + +The default values of "Auto Execute Query" and "Keep Sorting and Filtering" preferences can be set up in the Preferences dialog: **Tools > Preferences... > Data browsing > DAX Query** > Basic. + +### Adding or Updating Measures, Columns and Tables with DAX Queries + +Tabular Editor (3.12.0 and higher) has the ability to add or change measures directly through the DAX Query window. + +From Tabular Editor 3.23.0, Apply and Apply selection also process DEFINE COLUMN and DEFINE TABLE statements. Tabular Editor will create the corresponding calculated columns/tables in your model, or update their expressions if they already exist. + +There are four options for applying DAX Query defined measures, columns and tables to the model: + +![Dax Query Apply Measure](~/content/assets/images/features/dax_query_window/dax_query_apply_measure.png) + +The "Apply" option syncs the DAX expression for all measures, columns or tables explicitly defined in the query to the definition of the object. Any measures, columns or tables that do not already exist are created. + +"Apply Measures & Sync" applies the DAX expression to the definition of the measures, columns or tables and saves the model. + +The "Apply Selection" and "Apply Selection & Sync" will only apply the measures, columns or tables within the current selection of the query editor. + +Unlike the [DAX Script feature](xrefid:dax-scripts), only the expression property of a measure can be updated this way, as the DAX query syntax does not support specifying other properties, such as Description, Display Folder, etc. + +The "Apply" option has also been added to the right-click context menu. + +![Dax Query Apple Right Click](~/content/assets/images/features/dax_query_window/dax_query_apply_measure_right_click.png) + +The shortcuts for these commands are: + +- Apply (F7) +- Apply Measures & Sync (Shift+F7) +- Apply Selection (F8) +- Apply Selection and Synch (Shift F7) + +## DAX Query Example + +A DAX query always returns a table of results, and the simplest form of DAX query to create is one that evaluates a table within the model. + +```DAX +EVALUATE +Products +``` + +![Dax Query Evaluate Table](~/content/assets/images/features/dax_query_window/evaluate_table.png) + +It is also possible to return the value of a measure, but a table constructor {} is required around the measure name to turn the scalar value into a 1x1 table. + +```DAX +EVALUATE +{ [Invoice Lines] } +``` + +![Dax Query Evaluate Measure](~/content/assets/images/features/dax_query_window/evaluate_measure.png) + +### Multiple EVALUATE statements + +It is perfectly possible to have multiple EVALUATE statements inside the same DAX query. This query type is most often encountered with Power BI Performance Analyzer queries. + +Both tables are returned in the below statement but as separate row tabs in the result pane. + +```DAX +EVALUATE +Products + +EVALUATE +Customers +``` + +![Dax Query Evaluate Multiple Tables](~/content/assets/images/features/dax_query_window/multiple_evaluate_table.png) + +## Debugging DAX Query + +DAX queries are one of the two places where it is possible to run the [DAX Debugger](xrefid:dax-debugger), the other being the Pivot Grid. + +The DAX debugger unlocks the ability to understand how the DAX works inside a single cell. To start the debugger simply right click on the desired cell and choose 'Debug cell', which will start the debugger in the context of the chosen cell. + +![Dax Query Debugger](~/content/assets/images/features/dax_query_window/dax_query_open_dax_debugger.gif) + +## Export DAX Query results + +Tabular Editor 3, beginning from version 3.16.0, introduces the new capability of exporting the results of a DAX Query to either CSV or Excel. After running the DAX Query, a button activates in the toolbar, enabling users to save the results locally in CSV or Excel format. + +> [!TIP] +> To Export more than 1001 rows choose "click to get all rows" after running the DAX Query + +![Dax Query Export Data](~/content/assets/images/features/dax_query_window/dax_query_export_data.png) diff --git a/content/localization/zh/dax-script-introduction_zh.md b/content/localization/zh/dax-script-introduction_zh.md new file mode 100644 index 00000000..2ec06bdb --- /dev/null +++ b/content/localization/zh/dax-script-introduction_zh.md @@ -0,0 +1,210 @@ +--- +uid: dax-script-introduction +title: Using the DAX Scripting feature +author: Daniel Otykier +updated: 2021-10-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Using the DAX Scripting feature + +In the [previous article](xref:creating-and-testing-dax), you learned how to add and edit calculated objects such as measures, calculated columns, etc. in your model. + +As your model grows in complexity, you may reach a point in which it starts to become cumbersome to navigate the TOM Explorer or jump back and forth between measures, when authoring and maintaining business logic. It is not uncommon to have long chains of dependencies between measures, and so for that reason, it is sometimes useful to collect all the DAX code making up the business logic, in a single document. + +This is exactly the purpose of the new **DAX script** feature introduced in Tabular Editor 3. + +To use this feature, locate the objects for which you would like to generate a single document, in the TOM Explorer. Multi-select the objects, then right-click and choose **Script DAX**. A new document is created, containing the DAX expressions and basic properties of all the selected objects. You can also generate a DAX script for all objects within a table or all objects within the model, by choosing the table or model object respectively. + +![Dax Script](~/content/assets/images/dax-script.png) + +Editing objects through a DAX script is slightly different than editing through the **Expression Editor**. With the latter, changes are applied immediately when you navigate to a different object. In a DAX script, however, changes are not applied until you explicitly do so by using the **Script > Apply** (F5) option. If you are connected to an instance of Analysis Services, you can use the **Script > Apply & Sync** (SHIFT+F5) option to simultaneously apply the changes and save the updated model metadata to Analysis Services. + +## Working with DAX script files + +DAX scripts can be saved as text files, using the `.te3daxs` file extension. To save a DAX script as a file, simply use the **File > Save** (Ctrl+S) option. To open a DAX script from a text file, use the **File > Open > File...** (Ctrl+O) option. + +> [!NOTE] +> DAX scripts are not model specific, but since DAX expressions may point to measures, columns and tables defined in the model, there are no guarantees that any DAX script can be applied to any model. DAX scripts are mostly useful for working with several DAX objects within a single document, in the context of a specific data model. + +## DAX script editor + +The DAX script editor has all the capabilities of the DAX editor used elsewhere in Tabular Editor 3. Specifically, auto-complete, auto-formatting, calltips, etc. + +In addition, to easily manage large DAX scripts, two dropdowns are displayed at the top of the DAX script view. The dropdown on the left allows you to jump between objects defined in the script, where as the dropdown on the right allows you to jump between properties on the current object. + +![Dax Script Navigation](~/content/assets/images/dax-script-navigation.png) + +## Define measures + +If you want to include the definition of a measure that is referenced in the script, but not already defined in the script, you can do so by right-clicking on a measure reference, and choose the "Define Measure" or "Define Measure with dependencies" option. + +![Define Measure With Deps](~/content/assets/images/define-measure-with-deps.png) + +## Shortcuts + +To apply the script to the model, use the following shortcuts: + +- **F5**: Apply the entire script to the local model metadata +- **Shift+F5**: Apply the entire script to the local model metadata, then save the model metadata back to the source +- **F8**: Apply the currently selected part of the script to the local model metadata +- **Shift+F8**: Apply the currently selected part of the script to the local model metadata, then save the model metadata back to the source + +## DAX objects supported + +Tabular Editor 3 supports editing the following types of objects using a DAX script: + +- Measures (including KPIs) +- Calculated columns +- Calculated tables +- Calculation groups (including calculation items) + +# DAX script syntax + +The syntax for DAX scripts is the following: + +```dax +: +MEASURE 'Table name'[Measure name] = + [] + +COLUMN 'Table name'[Column name] = + [] + +TABLE 'Table name' = + [
    ] + +CALCULATIONGROUP 'Table name'[Column name] + [] + CALCULATIONITEM "Item 1" = + [] + CALCULATIONITEM "Item 2" = + [] + ... + +: + DetailRows = + DisplayFolder = "string" + FormatString = "string" + Description = "string" + Visible = TRUE/FALSE + KpiStatusExpression = + KpiStatusDescription = "string" + KpiStatusGraphic = "string" + KpiTrendExpression = + KpiTrendDescription = "string" + KpiTrendGraphic = "string" + KpiTargetExpression = + KpiTargetDescription = "string" + KpiTargetFormatString = "string" + +: + DisplayFolder = "string" + FormatString = "string" + Description = "string" + Visible = TRUE / FALSE + Datatype = BOOLEAN / DOUBLE / INTEGER / DATETIME / CURRENCY / STRING + +
    : + Description = "string" + Visible = TRUE / FALSE + DetailRows = + +: + Description = "string" + Visible = TRUE / FALSE + Precedence = + + + Description = "string" + Ordinal = + FormatString = +``` + +## Example 1: Measure + +As an example, the script below defines the `[Internet Total Sales]` measure on the `'Internet Sales'` table. In addition to the DAX expression of the measure, the script also includes the measure description and format string. + +```dax +---------------------------------- +-- Measure: [Internet Total Sales] +---------------------------------- +MEASURE 'Internet Sales'[Internet Total Sales] = SUM('Internet Sales'[Sales Amount]) + Description = "Returns the sum of all Internet Sales" + FormatString = "\$#,0.00;(\$#,0.00);\$#,0.00" +``` + +## Example 2: Measure with status and target KPI + +The DAX script below defines the `[Internet Current Quarter Sales Performance]` measure, which includes a KPI that has a status and a target expression. The status KPI uses the "Shapes" graphic. + +```dax +-------------------------------------------------------- +-- Measure: [Internet Current Quarter Sales Performance] +-------------------------------------------------------- +MEASURE 'Internet Sales'[Internet Current Quarter Sales Performance] = + IFERROR( + [Internet Current Quarter Sales] / [Internet Previous Quarter Sales Proportion to QTD], + BLANK() + ) + , KpiStatusExpression = + VAR x = [Internet Current Quarter Sales Performance] + RETURN + IF( + ISBLANK( x ), + BLANK(), + IF(x < 1, -1, IF(x < 1.07, 0, 1)) + ) + , KpiStatusGraphic = "Shapes" + , KpiTargetExpression = 1.1 +``` + +## Example 3: Calculation group + +The DAX script below defines the `'Time Intelligence'` calculation group with the `[Period]` column. The calculation group contains 6 calculation items that performs various time calculations. Notice how the `"YoY %"` item applies a different format string. + +```dax +----------------------------------------- +-- Calculation Group: 'Time Intelligence' +----------------------------------------- +CALCULATIONGROUP 'Time Intelligence'[Period] + Description = "Use this table to perform time calculations" + + CALCULATIONITEM "Current" = SELECTEDMEASURE() + Ordinal = 0 + + CALCULATIONITEM "MTD" = TOTALMTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 1 + + CALCULATIONITEM "YTD" = TOTALYTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 2 + + CALCULATIONITEM "PY" = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 3 + + CALCULATIONITEM "YoY" = + SELECTEDMEASURE() + - CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 4 + + CALCULATIONITEM "YoY %" = + VAR lastYear = + CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + RETURN + DIVIDE( + SELECTEDMEASURE() - lastYear, + lastYear + ) + FormatString = "Percent" + Ordinal = 5 +``` + +# Next steps + +- @bpa +- @cs-scripts-and-macros +- @personalizing-te3 \ No newline at end of file diff --git a/content/localization/zh/dax-scripts_zh.md b/content/localization/zh/dax-scripts_zh.md new file mode 100644 index 00000000..38f6ccbe --- /dev/null +++ b/content/localization/zh/dax-scripts_zh.md @@ -0,0 +1,237 @@ +--- +uid: dax-scripts +title: DAX Scripts +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX Scripts + +**DAX Script** allow you to view and edit DAX expressions and basic properties for multiple objects, in a single document. This is useful, for example, when complex business logic is spread out across multiple measures. + +You can script the DAX code for any TOM explorer object that has DAX expressions. + +To use this feature, locate the objects for which you would like to generate a single document, in the TOM Explorer. Multi-select the objects, then right-click and choose **Script DAX**. A new document is created, containing the DAX expressions and basic properties of all the selected objects. You can also generate a DAX script for all objects within a table or all objects within the model, by choosing the table or model object respectively. + +![Dax Script](~/content/assets/images/dax-script.png) + +Editing objects through a DAX script is slightly different than editing through the **Expression Editor**. With the latter, changes are applied immediately when you navigate to a different object. In a DAX script, however, changes are not applied until you explicitly do so by using the **Script > Apply** (F5) option. If you are connected to an instance of Analysis Services, you can use the **Script > Apply & Sync** (SHIFT+F5) option to simultaneously apply the changes and save the updated model metadata to Analysis Services. + +You can undo/redo changes made by a DAX script using the usual keyboard shortcuts (Ctrl+Z / Ctrl+Y). + +## Multiple DAX scripts + +You can create as many DAX scripts as you want, if you prefer to have multiple document windows open instead of a single one. This way, you can use the usual IDE features to place the documents side by side, on different monitors, etc. Be aware, that the code within DAX script windows is not updated automatically when changes are made to the object expression/properties in the TOM. So in other words, if you have two or more DAX scripts containing the definition of the same object(s), then the last script to be applied (F5), will always override any changes made through other DAX scripts, or directly through the **Properties View**. + +## Working with DAX script files + +DAX scripts can be saved as text files, using the `.te3daxs` file extension. To save a DAX script as a file, simply use the **File > Save** (Ctrl+S) option. To open a DAX script from a text file, use the **File > Open > File...** (Ctrl+O) option. + +> [!NOTE] +> DAX scripts are not model specific, but since DAX expressions may point to measures, columns and tables defined in the model, there are no guarantees that any DAX script can be applied to any model. DAX scripts are mostly useful for working with several DAX objects within a single document, in the context of a specific data model. + +## DAX script editor + +The DAX script editor has all the capabilities of the DAX editor used elsewhere in Tabular Editor 3. Specifically, auto-complete, auto-formatting, calltips, etc. + +In addition, to easily manage large DAX scripts, two dropdowns are displayed at the top of the DAX script view. The dropdown on the left allows you to jump between objects defined in the script, where as the dropdown on the right allows you to jump between properties on the current object. + +![Dax Script Navigation](~/content/assets/images/dax-script-navigation.png) + +## Define measures + +If you want to include the definition of a measure that is referenced in the script, but not already defined in the script, you can do so by right-clicking on a measure reference, and choose the "Define Measure" or "Define Measure with dependencies" option. + +![Define Measure With Deps](~/content/assets/images/define-measure-with-deps.png) + +## Shortcuts + +To apply the script to the model, use the following shortcuts: + +- **F5**: Apply the entire script to the local model metadata +- **Shift+F5**: Apply the entire script to the local model metadata, then save the model metadata back to the source +- **F8**: Apply the currently selected part of the script to the local model metadata +- **Shift+F8**: Apply the currently selected part of the script to the local model metadata, then save the model metadata back to the source + +## DAX objects supported + +Tabular Editor 3 supports editing the following types of objects using a DAX script: + +- Measures (including KPIs) +- Calculated columns +- Calculated tables +- Calculation groups (including calculation items) + +# DAX script syntax + +The syntax for DAX scripts is the following: + +```dax +: +MEASURE 'Table name'[Measure name] [= []] + [] + +COLUMN 'Table name'[Column name] [= []] + [] + +TABLE 'Table name' [= []] + [
    ] + +CALCULATIONGROUP 'Table name'[Column name] + [] + CALCULATIONITEM "Item 1" [= []] + [] + CALCULATIONITEM "Item 2" [= []] + [] + ... + +: + DetailRows = [] + DisplayFolder = ["string"] + FormatString = ["string" / ] + Description = ["string"] + Visible = TRUE/FALSE + KpiStatusExpression = [] + KpiStatusDescription = ["string"] + KpiStatusGraphic = ["string"] + KpiTrendExpression = [] + KpiTrendDescription = ["string"] + KpiTrendGraphic = ["string"] + KpiTargetExpression = [] + KpiTargetDescription = ["string"] + KpiTargetFormatString = ["string"] + +: + DisplayFolder = ["string"] + FormatString = ["string"] + Description = ["string"] + Visible = TRUE / FALSE + Datatype = BOOLEAN / DOUBLE / INTEGER / DATETIME / CURRENCY / STRING + +
    : + Description = ["string"] + Visible = TRUE / FALSE + DetailRows = [] + +: + Description = ["string"] + Visible = TRUE / FALSE + Precedence = + + + Description = ["string"] + Ordinal = + FormatString = [] +``` + +> [!TIP] +> Users of TMDL will undoubtedly have noticed that some similarities exist between the syntax of DAX scripts and the syntax of TMDL. In fact, TMDL was inspired by DAX scripts. However, to keep things simple, DAX scripts intentionally supports only objects that have one or more DAX expressions associated with them. Moreover, the DAX script syntax is designed to be compatible with the `DEFINE` section of a DAX query (provided the DAX script does not specify any object properties). TMDL, on the other hand, is used to define the entire model metadata, and is not limited to DAX objects. However, blocks of TMDL code cannot be readily used in a DAX query as the syntax for defining object names in TMDL, is not valid in DAX. + +## Example 1: Measure + +As an example, the script below defines the `[Internet Total Sales]` measure on the `'Internet Sales'` table. In addition to the DAX expression of the measure, the script also includes the measure description and format string. + +```dax +---------------------------------- +-- Measure: [Internet Total Sales] +---------------------------------- +MEASURE 'Internet Sales'[Internet Total Sales] = SUM('Internet Sales'[Sales Amount]) + Description = "Returns the sum of all Internet Sales" + FormatString = "\$#,0.00;(\$#,0.00);\$#,0.00" +``` + +## Example 2: Measure with status and target KPI + +The DAX script below defines the `[Internet Current Quarter Sales Performance]` measure, which includes a KPI that has a status and a target expression. The status KPI uses the "Shapes" graphic. + +```dax +-------------------------------------------------------- +-- Measure: [Internet Current Quarter Sales Performance] +-------------------------------------------------------- +MEASURE 'Internet Sales'[Internet Current Quarter Sales Performance] = + IFERROR( + [Internet Current Quarter Sales] / [Internet Previous Quarter Sales Proportion to QTD], + BLANK() + ) + , KpiStatusExpression = + VAR x = [Internet Current Quarter Sales Performance] + RETURN + IF( + ISBLANK( x ), + BLANK(), + IF(x < 1, -1, IF(x < 1.07, 0, 1)) + ) + , KpiStatusGraphic = "Shapes" + , KpiTargetExpression = 1.1 +``` + +## Example 3: Calculation group + +The DAX script below defines the `'Time Intelligence'` calculation group with the `[Period]` column. The calculation group contains 6 calculation items that performs various time calculations. Notice how the `"YoY %"` item applies a different format string. + +```dax +----------------------------------------- +-- Calculation Group: 'Time Intelligence' +----------------------------------------- +CALCULATIONGROUP 'Time Intelligence'[Period] + Description = "Use this table to perform time calculations" + + CALCULATIONITEM "Current" = SELECTEDMEASURE() + Ordinal = 0 + + CALCULATIONITEM "MTD" = TOTALMTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 1 + + CALCULATIONITEM "YTD" = TOTALYTD(SELECTEDMEASURE(), 'Calendar'[Date]) + Ordinal = 2 + + CALCULATIONITEM "PY" = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 3 + + CALCULATIONITEM "YoY" = + SELECTEDMEASURE() + - CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + Ordinal = 4 + + CALCULATIONITEM "YoY %" = + VAR lastYear = + CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date])) + RETURN + DIVIDE( + SELECTEDMEASURE() - lastYear, + lastYear + ) + FormatString = "Percent" + Ordinal = 5 +``` + +# Unspecified or empty expressions / properties + +As of Tabular Editor 3.16.0, it is possible to specify empty expressions and property values in DAX scripts, or omit object expressions entirely. + +For example, the following script will create a measure with an empty DAX expression, an empty format string and no Display Folder. If the measure already exists, it will be updated to have an empty DAX expression, an empty format string and no Display Folder. + +```dax +MEASURE 'Internet Sales'[Internet Total Sales] = + , Description = "TODO: Ask business how this should be implemented and formatted." + , FormatString = + , DisplayFolder = +``` + +Note that the `,` (comma) before properties following an empty expression is mandatory. Commas are optional when the preceding expression is non-empty. + +If you want to keep the existing DAX expression on a measure, you can omit the `=` sign after the object name: + +```dax +MEASURE 'Internet Sales'[Internet Total Sales] + DisplayFolder = "Totals" +``` + +The example above will update the `[Internet Total Sales]` measure to have the specified `DisplayFolder`, but will keep the existing DAX expression. All other properties on the object, such as `Description` and `FormatString`, will remain unchanged. + +These new features make it easier to write scripts that only update specific properties of an object, without having to specify the entire object definition. This way, scripts can more easily be reused across different models. diff --git a/content/localization/zh/deployment_zh.md b/content/localization/zh/deployment_zh.md new file mode 100644 index 00000000..56b10992 --- /dev/null +++ b/content/localization/zh/deployment_zh.md @@ -0,0 +1,69 @@ +--- +uid: deployment +title: Model deployment +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Model deployment + +Tabular Editor 3 (Business and Enterprise Edition) can take a copy of the currently loaded semantic model metadata, and deploy it to an Analysis Services instance, or the Power BI / Fabric XMLA endpoint. + +To perform a deployment, launch the **Deployment Wizard** through the **Model > Deploy...** menu option. + +> [NOTE] +> Tabular Editor 3 Business Edition has certain [limitations](xref:editions) regarding what type of Analysis Services instance, or Power BI / Fabric workspace is supported for XMLA connectivity. This applies to deployment as well. + +## Deployment options + +After selecting the destination server and database to deploy, you are presented with a list of **Deployment options**, as shown in the screenshot below. + +![Deployment Options](images/deployment-options.png) + +These are: + +- **Deploy Model Structure**: This indicates that the model metadata will be deployed. Unchecking this prevents you from performing the deployment (the option exists for historic reasons). +- **Deploy Data Sources**: For models that use _explicit_ data sources, this option indicates whether any such data sources will be included in the deployment. Unchecking this option may be useful, if one or more properties on a data source has been modified, and you do not intend to deploy these modifications. For example, if you are deploying model metadata from a Development environment to a Test environment, you may want to retain any connection strings, etc. on the destination environment as-is. Note that this option is typically not enabled for Power BI / Fabric semantic models, because such models use _implicit_ data sources, where credentials are managed by the Power BI service, and connection details are stored in the M queries on partitions or shared expressions in the model. +- **Deploy Table Partitions**: This option indicates whether table partitions should be deployed. In some cases, the destination database may contain partitions that are not present in the model metadata. Unchecking this option will prevent the deployment from modifying any existing partitions on the destination server. If this option is checked, Tabular Editor will synchronize the partitions on the destination server with the model metadata. If any partitions are present on the destination server, but not in the model metadata, they will be removed (including the data contained in them). + - **Deploy partitions governed by Incremental Refresh Policies**: When the **Deploy Table Partitions** option is enabled, you will have an option to avoid deploying partitions that are governed by Incremental Refresh Policies. This is useful when you have a model with partitions that created automatically by the [Incremental Refresh Policy](xref:incremental-refresh-about), and you want to deploy all partitions except those governed by the policy. +- **Deploy Model Roles**: This option indicates whether roles defined in the model should be deployed. Unchecking this option will retain existing roles on the model as-is. If you are deploying changes to tables or columns in the model, you may have to revisit [RLS or OLS settings](xref:data-security-about), to ensure that they are still valid. + - **Deploy Model Role Members**: This option indicates whether role members should be deployed. It is common to manage role members directly on the server, rather than in the model metadata. Unchecking this option will prevent the deployment from modifying any existing role members on the destination server. + +## Deployment script + +During deployment, Tabular Editor generates a [CreateOrReplace TMSL script](https://learn.microsoft.com/en-us/analysis-services/tmsl/createorreplace-command-tmsl?view=asallproducts-allversions), which is then executed against the Analysis Services engine. The CreateOrReplace script contains all the metadata required to recreate the model, including tables, columns, measures, relationships, perspectives, translations, etc. If the model does not already exist on the target server, it will be created. If the model already exists, existing objects will be replaced with the new metadata specified in the script. + +If any of the options on the **Deployment options** page were deselected, Tabular Editor will use the original metadata definition of those objects in the generated TMSL script, thus retaining their definitions as-is on the server. + +The last page of the deployment wizard lets you export the generated script, so you can review the changes before executing them. + +## Deployment impact + +> [WARNING] +> This type of deployment is a **metadata-only deployment**. Depending on the types of changes made to the model, imported data could be lost during deployment. In this case, you may need to execute a refresh operation once the deployment is complete. + +As a rule of thumb, the following changes can be made to the model without requiring a subsequent data refresh: + +- Adding/editing/removing measures and KPIs, including their DAX expressions. +- Editing properties such as FormatString, Description, DisplayFolder, etc. +- Adding/editing/removing metadata translations, perspectives, OLS and RLS roles. + +The following changes may require a **Calculate refresh**, before the objects can be queried: + +- Adding/editing calculated column, calculated tables and calculation groups +- Adding/editing relationships +- Adding/editing hierarchies +- Removing columns/tables + +The following changes may require a **Full refresh**: + +- Adding/editing partitions, tables and columns + +> [WARNING] +> Because of the potential impact of deploying a semantic model this way, we recommend not using this option to perform a deployment against a production environment. It is better to set up a [CI/CD pipeline for deploying models to production environments](https://blog.tabulareditor.com/category/ci-cd/). diff --git a/content/localization/zh/desktop-limitations_zh.md b/content/localization/zh/desktop-limitations_zh.md new file mode 100644 index 00000000..9569dfbf --- /dev/null +++ b/content/localization/zh/desktop-limitations_zh.md @@ -0,0 +1,17 @@ +--- +uid: desktop-limitations-te3 +title: Power BI Desktop limitations +author: Morten Lønskov +updated: 2023-08-21 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +[!include[Desktop limitations](~/content/common/desktop-limitations.md)] + +# Next steps + +- [Editing a Power BI dataset through the XMLA endpoint](xref:powerbi-xmla) diff --git a/content/localization/zh/diagram-view_zh.md b/content/localization/zh/diagram-view_zh.md new file mode 100644 index 00000000..0f0c9288 --- /dev/null +++ b/content/localization/zh/diagram-view_zh.md @@ -0,0 +1,109 @@ +--- +uid: diagram-view +title: Diagram View +author: Morten Lønskov +updated: 2025-04-24 +--- + +# Diagram View + +The **Diagram View** in Tabular Editor 3 is a visual representation of the semantic model. It provides an intuitive layout for viewing tables, their columns, and the relationships between them. It is particularly helpful for understanding the schema at a glance, creating relationships, and presenting models to stakeholders. A diagram can be saved as a stand alone file. See for more information. + +> [!NOTE] +> We recommend creating multiple smaller diagrams over few large diagrams. When a diagram contains more than 20 or so tables, it quickly becomes overwhelming and difficult to understand. + +After loading a model in Tabular Editor 3, choose the **File > New > Diagram** menu option to create a new diagram or open a new diagram in the main toolbar and drag and drop a table from the TOM Explorer to the diagram window. + +## Using the diagram view + +## Adding tables + +Add initial tables to the diagram in any of the following ways: + +- (Multi-)select tables in the TOM Explorer, then right-click and choose **Add to diagram**. +- (Multi-)select tables in the TOM Explorer, then drag the tables over to the diagram +- Use the **Diagram > Add tables...** menu option, and (multi-)select the tables you want to add through the dialog box. + ![Diagram Add Tables](~/content/assets/images/diagram-add-tables.png) + + To add additional tables to the diagram, use the technique above again, or right-click on an existing table in the diagram and choose one of the following options: + + - **Add tables that filter this table**: Adds all tables to the diagram which may, directly or indirectly through other tables, filter the currently selected table. Useful when starting from a fact table. + - **Add all related tables**: Adds all tables to the diagram which are directly related to the currently selected table. Useful when starting from a dimension table. + ![Add Related Tables](~/content/assets/images/add-related-tables.png) + + Before proceeding, rearrange and resize the tables in the diagram to suit your preferences, or use the **Diagram > Auto-arrange** feature to have Tabular Editor 3 lay out the tables automatically. + +## Modifying relationships using the diagram + +To add a new relationship between two tables, locate the column on the fact table (many-side) of the relationship, and drag that column over to the corresponding column on the dimension table (one-side). Confirm the settings for the relationship and hit **OK**. + +![Create Relationship](~/content/assets/images/create-relationship.png) + +To edit an existing relationship, right-click on it and choose **Edit relationship**. The right-click menu also contains shortcuts for reversing or deleting a relationship, as shown on the screenshot below. + +![Edit Relationship Diagram](~/content/assets/images/edit-relationship-diagram.png) + +> [!NOTE] +> You can also create relationships without using a diagram, through the TOM Explorer. Locate the column from which the relationship should start (many-side / fact-table side), right-click and choose **Create > Relationship from**. Specify the destination column in the Create Relationship dialog that appears on the screen. + +## Saving a diagram + +To save a diagram, simply use the **File > Save** (CTRL+S) option. Tabular Editor 3 will prompt you to save the diagram if you close the document or the application while the diagram has unsaved changes. + +> [!TIP] +> The same diagram file can be loaded for different data models. Diagrams reference tables by their names. Any tables not present in the model upon diagram load are simply removed from the diagram. + +> [!NOTE] +> Every time you add or modify a relationship, you will have to run a "calculate" refresh on the data model, before the relationships can be used when querying the model. + +## Diagram Features + +### Context Menu for Table Actions + +Right-clicking anywhere in the Diagram View opens a context menu that provides quick access to several options: + +![Diagram Context Menu](~/content/assets/images/diagram-context-menu.png) + +- **Add tables...**: Opens a dialog to manually add additional tables to the diagram. +- **Add tables that filter this table**: Automatically brings in related tables that filter the current one. +- **Add all related tables**: Loads all tables that share relationships with the selected table. +- **Fit to page**: Adjusts the diagram zoom to fit all visible tables. +- **Auto-Arrange**: Automatically arrange tables into a star schema +- **Remove from diagram**: Hides the selected table from the current view. + +### Relationship Indicators + +Relationships between tables are illustrated using directional arrows: + +- `1 - *`: Indicates a one-to-many relationship. +- `* - *`: Indicates a many-to-many relationship. +- `➝`: Indicates a single direction relationship, with the arrow defining the filter direction of the relationship. +- `⟷`: Indicates a bi-directional cross-filtering relationship. + +These visual markers allow for quick assessment of filter directionality and cardinality. + +### Column Display Toggle + +A **chevron toggle** is available in the top-right corner of each table, by clicking it you will toggle between the following options: + +![Diagram Chevron Toggle](~/content/assets/images/diagram-chevron-toggle.png) + +- **All Columns**: Displays all columns. +- **Key Columns Only**: Displays only primary and foreign keys. +- **No Columns**: Hides all columns, showing only the table header. + +The toggle helps reduce clutter, especially in complex models with many columns, making it easier to focus on relationships. + +### Column Data Type Icons + +Each column in the diagram is accompanied by an icon representing its data type: + +- Text Icon for string/text values +- Integer Icon for integer numbers +- Double Icon for double / floating-point decimal numbers +- Currency Icon for currency / fixed-point decimal numbers +- Binary Icon for binary values +- Boolean Icon for boolean (true/false) values +- Date Icon for date/time values + +This quick visual reference supports quick data validation and helps understand the data structures. \ No newline at end of file diff --git a/content/localization/zh/direct-lake-guidance_zh.md b/content/localization/zh/direct-lake-guidance_zh.md new file mode 100644 index 00000000..0e3c9a80 --- /dev/null +++ b/content/localization/zh/direct-lake-guidance_zh.md @@ -0,0 +1,191 @@ +--- +uid: direct-lake-guidance +title: Direct Lake Guidance +author: Daniel Otykier +updated: 2024-06-18 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + none: x + - edition: Enterprise +--- + +# Direct Lake Guidance + +With the release of Tabular Editor 3.22.0, we have added support for Direct Lake on OneLake in addition to Direct Lake on SQL. This article provides a short overview of the differences between these two modes, and how they compare to other storage modes available in Power BI semantic models. + +## Storage mode overview + +The following table summarizes the storage modes available in Power BI semantic models: + +| Storage Mode | Description | Recommended Use Cases | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Import | Data is imported into the semantic model and stored in the model's in-memory cache (VertiPaq). | When you need fast query performance and can afford to refresh the data periodically. | +| DirectQuery | Data is queried directly from the source at query time, without being imported into the model. Supports various sources, such as SQL, KQL and even other semantic models. | When you need real-time data access or when the data volume is too large to fit in memory. | +| Dual | A hybrid mode where the engine can choose between returning the imported data or delegating to DirectQuery, depending on the query context. | When your model contains a mix of DirectQuery and Import tables (for example when using aggregations), and you have tables that are related to both. | +| Direct Lake on OneLake | Utilizes the Delta Parquet story format to quickly swap the data into semantic model memory when needed. | When your data is already available as tables or materialized views in a Fabric Warehouse or Lakehouse. | +| Direct Lake on SQL | Older version of Direct Lake which utilizes the SQL Analytics Endpoint of Fabric Warehouses or Lakehouses. | Not recommended for new development (use Direct Lake on OneLake instead). | + +> [!NOTE] +> It is also possible to create tables that contain a mix of partitions in **Import** and **DirectQuery** mode (also known as "hybrid tables"). This is commonly done on large fact tables that require incremental refresh while some data is queried directly from the source. See [this article](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla) for more information. + +## Direct Lake on OneLake vs. Direct Lake on SQL + +[Direct Lake on OneLake](https://learn.microsoft.com/en-us/fabric/fundamentals/direct-lake-overview#key-concepts-and-terminology) was introduced in March 2025 as an alternative to Direct Lake on SQL. With Direct Lake on OneLake, there is no dependency on the SQL endpoint and no fallback to DirectQuery mode. This also means that the [usual restrictions that apply to DirectQuery models](https://learn.microsoft.com/en-us/power-bi/connect-data/desktop-directquery-about#modeling-limitations) do not apply to Direct Lake on OneLake models. + +However, as with Direct Lake on SQL, there are still some [limitations that _do_ apply](https://learn.microsoft.com/en-us/fabric/fundamentals/direct-lake-overview#considerations-and-limitations). The most important limitations are listed below. See the link for a full list of limitations: + +- Calculated columns on Direct Lake tables cannot reference columns that are sourced from OneLake. +- Calculated tables on Direct Lake models cannot refer columns on Direct Lake tables that are sourced from OneLake. + +One possible workaround for the above limitation, is to create a **composite model** by combining Direct Lake tables with Import tables. This is allowed with Direct Lake on OneLake, but not with Direct Lake on SQL. In this case, you would typically use Import mode for smaller dimension tables, where you may need to add custom groupings, which calculated columns are ideal for, while keeping the larger fact tables in Direct Lake mode. + +Alternatively, ensure that your source contains the columns it needs. If you add columns through a view, please note that the view must be materialized in the Fabric Warehouse or Lakehouse, as Direct Lake on OneLake does not support non-materialized views. + +## Collation + +When using **Direct Lake on OneLake**, the collation of the model is the same as for an Import model, which is case-insensitive by default. + +For a **Direct Lake on SQL** model, the collation is case-insensitive for queries that do not fallback to DirectQuery. If the query does fallback, the collation depends on the collation of the source. For a Fabric Warehouse, the collation might be case-sensitive, in which case you should specify a [case-sensitive collation on the model](https://data-goblins.com/power-bi/case-specific). + +> [!NOTE] +> You cannot change the collation of a model once the metadata has been deployed to Analysis Services / Power BI. As such, if you plan to use Direct Lake on SQL with a case-sensitive Fabric Warehouse, you must set the collation on the model metadata before it's deployed: +> +> 1. Create a new model in Tabular Editor 3 (File > New > Model...) +> 2. Uncheck "Use workspace database" +> 3. Set the **Collation** property on the model to `Latin1_General_100_BIN2_UTF8` +> 4. Save the model (Ctrl+S). +> 5. Now, open the model from the file you just saved. When prompted to connect to a workspace database, choose "Yes". +> +> With this approach, the model metadata gets deployed with the correct collation from the start, and you can then add tables in Direct Lake on SQL mode without running into collation issues. + +## Table Import Wizard + +To add Direct Lake tables using Tabular Editor 3's Table Import Wizard, choose **Microsoft Fabric Lakehouse**, **Microsoft Fabric Warehouse**, **Microsoft Fabric SQL Database** or **Microsoft Fabric Mirrored Database** as the source: + +![Import Table Wizard Fabric](../../assets/images/import-table-wizard-fabric.png) + +After signing in, you will be presented with a list of all available Fabric Lakehouses/Warehouses in workspaces you have access to. Select the one you want to connect to and hit **OK**: + +![Import Table Wizard Select Lakehouse](../../assets/images/import-table-wizard-select-lakehouse.png) + +Unless you want to specify a custom SQL query, or configure the tables for DirectQuery mode, simply hit **Next** to select the tables from a list of tables/views in the source: + +![Import Table Wizard Select Vs Custom Query](../../assets/images/import-table-wizard-select-vs-custom-query.png) + +Select the tables/views you wish to import. Note that **non-materialized views** are not supported in Direct Lake on OneLake mode. Attempting to add such a view to the model will result in an error upon saving the model metadata. + +![Import Table Wizard Select Objects](../../assets/images/import-table-wizard-select-objects.png) + +On the last page, choose which mode you want the table partition to be configured with: + +![Table Import Wizard Partition Mode](../../assets/images/table-import-wizard-partition-mode.png) + +The choices are: + +- Direct Lake on OneLake +- Direct Lake on SQL +- Import (M) + +> [!NOTE] +> If you're working on a model that already contains tables, one or more of the choices mentioned above may not be available, if the model does not support combining tables in different storage modes. For example, if the model contains a table in Direct Lake on SQL mode, you cannot add tables in other modes. + +## Power Query (M) expressions + +This section contains a more technical description on how the TOM objects and properties need to be configured, in case you want to manually set up tables for Direct Lake mode without using the Table Import Wizard. + +### Direct Lake on OneLake + +To manually set up a table for **Direct Lake on OneLake** mode, you need to do the following: + +1. **Create Shared Expression**: Direct Lake tables use "Entity" partitions, which much reference a Shared Expression in the model. Start out by creating this shared expression, if you don't have it already. Name it `DatabaseQuery`: + +![Create Shared Expression](../../assets/images/create-shared-expression.png) + +2. **Configure Shared Expression**: Set the **Kind** property of the expression you created in step 1 to "M", and set the _Expression_\* property to the following M query, replacing the IDs in the URL for your Fabric workspace and Lakehouse/Warehouse: + +```m +let + Source = AzureStorage.DataLake("https://onelake.dfs.fabric.microsoft.com//", [HierarchicalNavigation=true]) +in + Source +``` + +3. **Create Table and Entity Partition**: Create a new table in the model (Alt+5), then expand the table partitions in the TOM Explorer, and create new _Entity Partition_: + +![Create Entity Partition](../../assets/images/create-entity-partition.png) + +Delete the regular import partition that was automatically created when you created the table. + +4. **Configure Entity Partition**: Set the following properties on the Entity Partition: + +| Property | Value | +| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Name | (Recommended) Set to the same name as the table | +| Entity Name | (Required) Set to the name of the table in the Lakehouse/Warehouse | +| Expression Source | (Required) Set to the Shared Expression you created in step 1, typically `DatabaseQuery` | +| Mode | (Required) `DirectLake` | +| Schema Name | (Optional) Set to the schema name in the Lakehouse/Warehouse, if applicable. If not set, the default schema will be used. | + +The final result should look like this: + +![Configure Entity Partition](../../assets/images/configure-entity-partition.png) + +5. **Update column metadata**: At this stage, you should be able to use Tabular Editor's **Update Table Schema** feature to update the column metadata for the table. This will automatically retrieve the column names and data types from the Lakehouse/Warehouse: + +![Update Table Schema Entity](../../assets/images/update-table-schema-entity.png) + +Alternatively, manually add Data Columns to the table (Alt+4) and specify the `Name`, `Data Type`, `Source Column` and any other relevant properties for each column. + +> [!NOTE] +> When a Direct Lake table is added to the model, it needs to be manually "refreshed" after the first metadata deployment. Otherwise, the table will not contain any data when queried. This refresh only needs to be performed once. Tabular Editor 3 will automatically refresh the table when the model metadata is saved, if the **Auto-refresh when saving new tables** under **Tools > Preferences > Model Deployment > Data Refresh**. + +### Direct Lake on SQL + +To manually set up a table for **Direct Lake on SQL** mode, follow the steps in the section above for Direct Lake on OneLake, but use the following M query in the Shared Expression instead: + +```m +let + database = Sql.Database("", "") +in + database +``` + +Replace `` with the connection string of the [SQL Analytics Endpoint of the Fabric Warehouse](https://learn.microsoft.com/en-us/fabric/data-warehouse/query-warehouse) or [Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-analytics-endpoint), and `` with the name of the Warehouse or Lakehouse. + +### Import from Lakehouse / Warehouse + +If you want to configure a table for **Import** mode while sourcing data from a Fabric Lakehouse or Warehouse, the steps are as follows: + +1. **Create table**: Create a new table in the model (Alt+5), then expand the table partitions in the TOM Explorer. By default, you should see a single partition of type "Import" created automatically: + +![M Import Partition](../../assets/images/m-import-partition.png) + +2. **Configure Import Partition**: Set the following M query on the Import Partition: + +```m +let + Source = Sql.Database("",""), + Data = Source{[Schema="",Item="
    "]}[Data] +in + Data +``` + +Replace `` with the connection string of the [SQL Analytics Endpoint of the Fabric Warehouse](https://learn.microsoft.com/en-us/fabric/data-warehouse/query-warehouse) or [Lakehouse](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-sql-analytics-endpoint), and `` with the name of the Warehouse or Lakehouse. + +Replace `` with the schema name in the Warehouse/Lakehouse, and `
    ` with the name of the table or view you want to import. Note that tables in Import Mode can use non-materialized views as the data source, since the data is queried through the SQL endpoint during refresh operations. + +3. **Update column metadata**: Use Tabular Editor's **Update Table Schema** feature to update the column metadata for the table. This will automatically retrieve the column names and data types from the Lakehouse/Warehouse. Alternatively, create Data Columns manually (Alt+4) and specify the `Name`, `Data Type`, `Source Column` and any other relevant properties for each column. + +## Converting between storage modes + +It is straightforward to convert between Direct Lake on SQL and Direct Lake on OneLake using the information in this article, because you only need to modify the M query of the Shared Expression referenced by the Direct Lake partitions. + +If you want to convert from Import to Direct Lake it's slightly more complicated because of the different partition types involved. + +To make things easier, we have prepared a set of C# scripts that can help you convert between different storage modes: + +- [Convert Direct Lake on SQL to Direct Lake on OneLake](xref:script-convert-dlsql-to-dlol) +- [Convert Import to Direct Lake on OneLake](xref:script-convert-import-to-dlol) \ No newline at end of file diff --git a/content/localization/zh/direct-lake-sql-model_zh.md b/content/localization/zh/direct-lake-sql-model_zh.md new file mode 100644 index 00000000..ddb192d8 --- /dev/null +++ b/content/localization/zh/direct-lake-sql-model_zh.md @@ -0,0 +1,141 @@ +--- +uid: direct-lake-sql-model +title: Direct Lake on SQL Semantic Models +author: Morten Lønskov +updated: 2024-08-22 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Desktop + none: x + - edition: Business + none: x + - edition: Enterprise +--- + +# Direct Lake Semantic Models + +Direct Lake on SQL semantic models connect directly to data sources stored in [OneLake in Fabric](https://learn.microsoft.com/en-us/fabric/onelake/onelake-overview) through the SQL Endpoint. + +> [!IMPORTANT] +> As of [Tabular Editor 3.22.0](~/content/te3/other/release-notes/3_22_0.md), Tabular Editor 3 supports Direct Lake on OneLake, which is recommended in most scenarios. See our [Direct Lake guidance](xref:direct-lake-guidance) article for more information. + +Tabular Editor 3 can create and connect to this type of model. For a tutorial on this please refer to our blog article: [Direct Lake semantic models: How to use them with Tabular Editor](https://blog.tabulareditor.com/2023/09/26/fabric-direct-lake-with-tabular-editor-part-2-creation/). +Tabular Editor 3 can create direct lake semantic models with both the Lakehouse and Datawarehouse SQL Endpoint. + +Tabular Editor 2 can connect to Direct Lake semantic models, but does not have any built in functionality to create new tables or direct lake semantic models. This needs to be done manually or with a C# script. + +
    +
    Direct Lake limitations
    + There are several limitations to the changes that can be made to a Direct Lake model: Direct Lake Known Issues and Limitations We recommend this article by SQLBI for a initial overview of choosing between Direct Lake and Import mode. +
    + +## Creating a Direct Lake on SQL model in Tabular Editor 3 + +Creating a Direct Lake on SQL model in Tabular Editor 3 (3.15.0 or higher) has to be specified when the model is created in the _New Model_ dialog box, by using the Direct Lake checkbox. + +![Direct Lake New Model](~/content/assets/images/common/DirectLakeNewModelDialog.png) + +Using the checkbox ensures that Direct Lake specific properties and annotations are set, as well as limits the import of tables to Direct Lake supported sources. + +> [!NOTE] +> Direct Lake on SQL models currently use a collation that is different from regular Power BI import semantic models. This may lead to different results when querying the model, or when referencing object names in DAX code. +> For more information please see this blog post by Kurt Buhler: [Case-sensitive models in Power BI: consequences & considerations](https://data-goblins.com/power-bi/case-specific) + +> [!IMPORTANT] +> As of [Tabular Editor 3.22.0](~/content/te3/other/release-notes/3_22_0.md), the Direct Lake checkbox has been removed from the New Model dialog. You must [manually set the collation on your model to match that of your Fabric Warehouse](xref:direct-lake-guidance#collation) if using Direct Lake on SQL. + +## Framing New Models and Table Imports + +Tabular Editor 3 (3.15.0 or higher) automatically frames (refreshes) the model on first deployment. This is to ensure that Direct Lake mode is activated - otherwise the model would automatically fall back to DirectQuery. + +Additionally, on import of new tables Tabular Editor 3 (3.15.0 or higher) frames (refreshes) the model when it is saved the next time. This preference is located under **Tools > Preferences > Model Deployment > Data Refresh**. + +## Identifying a Direct Lake model + +The top title bar of Tabular Editor shows which type of model is open in that instance of Tabular Editor. Additionally, the TOM Explorer displays the type and mode of every table (Import, DirectQuery, Dual or Direct Lake). If a model contains a mix of table modes, the title bar will show "Hybrid". Currently, it is not possible for a Direct Lake on SQL model to contain tables in Import, DirectQuery or Dual mode. + +## Converting a Direct Lake model to Import Mode + +The below C# script converts and existing model into 'Import Mode'. This can be useful if the data latency requirements of your model does not require Direct Lake or you want to avoid the limitations of a Direct Lake model but have already started building one inside Fabric. + +Running the script is possible when Tabular Editor is connected to a semantic model through the XMLA endpoint. However, saving changes directly back to the Power BI/Fabric workspace is not supported by Microsoft. To circumvent this, the recommended approach is to use the "Model > Deploy..." option. This allows for the deployment of the newly converted model as a new entity in a workspace. + +> [!NOTE] +> After deploying the newly converted Import-mode model, you will need to specify the credentials for accessing the Lakehouse to refresh data into the model. + +### C# Script to convert Direct Lake model to Import Mode + +```csharp +// ********************************************************************************** +// Convert Direct Lake-mode model to Import-mode +// --------------------------------------------- +// +// When this script is executed on a semantic model, it will: +// +// - Loop through all tables. Any table that contains exactly 1 partition, which +// is in Direct Lake mode, will have its partition replaced by an equivalent +// Import-mode partition. +// - Set the collation of the model to null (default) +// +// Remarks: +// +// - The Import-mode partitions will use the SQL endpoint of the Lakehouse. +// - The script assumes that the Shared Expression which specifies the SQL endpoint +// is called "DatabaseQuery". +// - Because TE2 does not expose the "SchemaName" property on EntityPartition +// objects, we have to use reflection to access the underlying TOM objects. +// +// Compatibility: +// TE2.x, TE3.x +// ********************************************************************************** + +using System.Reflection; + +const string mImportTemplate = +@"let + Source = DatabaseQuery, + Data = Source{{[Schema=""{0}"",Item=""{1}""]}}[Data] +in + Data"; + +foreach(var table in Model.Tables) +{ + // Direct Lake-mode tables only have 1 partition... + if(table.Partitions.Count != 1) continue; + + // ...which should be in "DirectLake" mode: + var partition = table.Partitions[0]; + if(partition.Mode != ModeType.DirectLake) continue; + + // Tabular Editor unfortunately doesn't expose the SchemaName property of EntityPartitionSources, + // so we'll have to use reflection to access the underlying TOM object. + var pMetadataObjct = typeof(Partition).GetProperty("MetadataObject", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + var tomPartition = pMetadataObjct.GetValue(partition) as Microsoft.AnalysisServices.Tabular.Partition; + var tomPartitionSource = tomPartition.Source as Microsoft.AnalysisServices.Tabular.EntityPartitionSource; + + // Table does not have an EntityPartitionSource, meaning it is not a Direct Lake table + // (shouldn't happen, since we already checked for DirectLake mode above...) + if(tomPartitionSource == null) continue; + + var schemaName = tomPartitionSource.SchemaName; + var tableName = tomPartitionSource.EntityName; + + // Rename the original (Direct Lake) partition (as we can't have two partitions with the same name): + var partitionName = partition.Name; + partition.Name += "_old"; + + // Add the new (Import) partition: + table.AddMPartition(partitionName, string.Format(mImportTemplate, schemaName, tableName)); + + // Delete the old (Direct Lake) partition): + partition.Delete(); +} + +// Update model collation: +Model.Collation = null; +Model.DefaultMode = ModeType.Import; +Model.RemoveAnnotation("TabularEditor_DirectLake"); +``` \ No newline at end of file diff --git a/content/localization/zh/direct-query-over-as_zh.md b/content/localization/zh/direct-query-over-as_zh.md new file mode 100644 index 00000000..78ea07ec --- /dev/null +++ b/content/localization/zh/direct-query-over-as_zh.md @@ -0,0 +1,57 @@ +--- +uid: dq-over-as-limitations +title: Direct Query over Analysis Services +author: Morten Lønskov +updated: 2025-07-14 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +## Overview + +Tabular Editor 3 can **connect** to composite models that leverage **DirectQuery over Analysis Services (DQ‑over‑AS)**, but full modeling support is **not yet available**. Most authoring tasks work as expected; however, operations that rely on synchronising metadata with the remote semantic model—such as _Update table schema_—are currently limited. + +> [!IMPORTANT] +> Until full DQ‑over‑AS support ships, model metadata edited in Tabular Editor 3 **is not automatically kept in sync** with the source dataset. You must apply one of the work‑arounds listed below whenever columns or measures are added to the underlying Analysis Services model. + +## Current limitations + +| Feature | Status in TE3 | Notes | +| --------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------- | +| **Update table schema** | ❌ Not supported | Attempting to run **Model > Update table schema** on a DQ‑over‑AS table has no effect. | +| **Measure synchronisation** | ❌ Not supported | Measures created in the source dataset do not appear automatically in the composite model. | + +## Work‑arounds + +### 1. Manually add missing columns + +1. In **TOM Explorer**, select the table that requires the new column. +2. Choose **Add > Data Column**. +3. In the _Properties_ window, set: + + - **SourceColumnName** – _exactly_ match the **Name** of the column in the remote table. + - **SourceLineageTag** – copy the **LineageTag** value from the source column. +4. Save and deploy the model. + +> [!NOTE] +> Column names and lineage tags must match _character‑for‑character_. Any mismatch will cause deployment errors. + +### 2. Use the “Import tables from remote model” C# script + +Daniel Otykier’s article on LinkedIn provides a [ready‑made C# automation script](https://www.linkedin.com/pulse/composite-models-tabular-editor-daniel-otykier/) that: + +1. Temporarily imports full copies of tables from the remote model. +2. Lets you copy columns (and other metadata) into existing tables. +3. Deletes the temporary tables after the copy is complete. + +This approach is faster when several tables require updates. + +### 3. One‑click macro to pull new measures + +[rem-bou's](https://github.com/rem-bou) GitHub repository contains an advanced macro that scans the source dataset for measures that are **missing** in the composite model and adds them automatically: [Create-Update DQ over AS model connection](https://github.com/rem-bou/TabularEditor-Scripts/blob/main/Advanced/One-Click%20Macros/Create-Update%20DQ%20over%20AS%20model%20connection.csx) diff --git a/content/localization/zh/downloads_zh.md b/content/localization/zh/downloads_zh.md new file mode 100644 index 00000000..029a77ab --- /dev/null +++ b/content/localization/zh/downloads_zh.md @@ -0,0 +1,71 @@ +--- +uid: downloads +title: All downloads +author: Daniel Otykier +updated: 2025-09-15 +--- + +# Tabular Editor 3 Downloads + +This page provides download and installation instructions for Tabular Editor 3. + +## Latest version + +Tabular Editor 3.23.1 **.NET 8** downloads: + +- Download [Tabular Editor 3.23.1 (64 bit)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe) _(recommended)_ +- Download [Tabular Editor 3.23.1 (ARM64)](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) +- Portable versions: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) +- MSI version: [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) + +Read the [latest release notes](release-notes/3_23_1.md). + +> [!NOTE] +> As of Tabular Editor 3.23.0, we now provide native [ARM64](https://learn.microsoft.com/en-us/windows/arm/overview) builds. 32-bit (x86) builds have been discontinued. + +## Installation Instructions + +1. Download the .exe installer file. +2. Run the .exe installer. The installation wizard will guide you through the installation. +3. For instructions on how to activate the product or change a license key, see our [getting started guide](xref:getting-started). + +It is not necessary to remove previous installations when upgrading to a newer version of Tabular Editor 3. + +## History + +- 2025-09-15 **Tabular Editor 3.23.1** (_[Release notes](release-notes/3_23_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) +- 2025-08-28 **Tabular Editor 3.23.0** (_[Release notes](release-notes/3_23_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) +- 2025-06-28 **Tabular Editor 3.22.1** (_[Release notes](release-notes/3_22_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) +- 2025-06-19 **Tabular Editor 3.22.0** (_[Release notes](release-notes/3_22_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) +- 2025-04-25 **Tabular Editor 3.21.0** (_[Release notes](release-notes/3_21_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) +- 2025-04-11 **Tabular Editor 3.20.1** (_[Release notes](release-notes/3_20_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) +- 2025-02-21 **Tabular Editor 3.20.0** (_[Release notes](release-notes/3_20_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) + +For earlier builds, see the [full release history](release-history.md). diff --git a/content/localization/zh/editions_zh.md b/content/localization/zh/editions_zh.md new file mode 100644 index 00000000..8d352c2f --- /dev/null +++ b/content/localization/zh/editions_zh.md @@ -0,0 +1,130 @@ +--- +uid: editions +title: Compare editions +author: Søren Toft Joensen +updated: 2025-02-07 +--- + +# Tabular Editor 3 Editions + +This document provides an overview and comparison of the different editions of Tabular Editor 3. + +> [!NOTE] +> Tabular Editor 3 licenses are **per developer**. In other words, only the persons who use the Tabular Editor 3 product will need a license. + +## Supported Data Modeling Scenarios + +The main difference between the various editions of Tabular Editor 3, is which types of tabular data modeling scenarios they support. To understand this difference, consider that Analysis Services (Tabular) exists in a number of different "flavors": + +- Power BI Desktop (make sure you you understand the [limitations](xref:desktop-limitations)) +- Power BI Premium through the XMLA Endpoint (Premium Per User, **Premium Capacity [A, EM or P SKUs]**, **Fabric Capacity [F SKUs]**) +- SQL Server (2016+) Analysis Services (Editions: Developer, Standard, **Enterprise**) +- Azure Analysis Services (Tiers: Developer, Basic, **Standard**) + +We consider the **highlighted** flavors of Analysis Services to be Enterprise-Tier, and as such, these may only be used with Tabular Editor 3 Enterprise Edition. + +> [!IMPORTANT] +> Tabular Editor only allows editing data models using Compatibility Level 1200 or higher. This is the default on any instance of Analysis Services starting from SQL Server 2016. For the same reason, Tabular Editor does not support Excel PowerPivot, as this uses an earlier Compatibility Level. + +Please refer to the matrix below for the full overview of supported scenarios: + +| Scenario / Edition | Desktop | Business | Enterprise | +| --------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------- | +| External Tool for Power BI Desktop | | | | +| Load/save model metadata to disk\*\* | | \* | | +| Workspace Mode\*\*\* | | \* | | +| Power BI Premium Per User | | | | +| SQL Server Developer Edition | | \* | | +| SQL Server Standard Edition | | | | +| SQL Server Enterprise Edition | | | | +| Azure AS Developer Tier | | \* | | +| Azure AS Basic Tier | | | | +| Azure AS Standard Tier | | | | +| Power BI Premium Capacity (P SKUs) | | | | +| Power BI Embedded Capacity (A/EM SKUs) | | | | +| Fabric Capacity (F SKUs) | | | | + +\***Note:** Enterprise Edition is required if the Analysis Services data model contains perspectives or tables with multiple partitions (does not apply to Power BI Desktop or Power BI Premium Per User models). + +\*\***Note:** Supported file formats are: **.pbip** (Power BI Project) **.pbit** (Power BI Template), **.bim** (Analysis Services model metadata), **.vpax** (VertiPaq Analyzer) and **database.json** (Tabular Editor folder structure). + +\*\*\***Note:** Workspace Mode allows Tabular Editor 3 to simultaneously save model metadata to disk and synchronize a database on any of the editions of Analysis Services or Power BI supported by the Tabular Editor 3 edition purchased. + +## Modeling Restrictions + +We restrict a few data modeling operations inside Tabular Editor 3 as well, corresponding to the restrictions on certain Microsoft service tiers (Azure Analysis Services _Basic Tier_, SQL Server Analysis Services _Standard Edition_, and Power BI _Premium-Per-User_). + +Specifically, [Azure AS Basic Tier and SQL Server Standard Edition does not support perspectives, multiple partitions or DirectQuery](https://azure.microsoft.com/en-us/pricing/details/analysis-services/), and as such, SSAS/Azure AS models using these features require TE3 Enterprise Edition. + +Similarly, [Power BI Premium-Per-User workspaces do not support Direct Lake datasets](https://learn.microsoft.com/en-us/power-bi/enterprise/directlake-overview#prerequisites), which is why Power BI models using this feature also requires TE3 Enterprise Edition. + +| Model type | Feature | Business | Enterprise | +| --------------- | ------------------- | ------------------------------------------------------- | ------------------------------------------------------- | +| Azure AS / SSAS | Perspectives | | | +| Azure AS / SSAS | Multiple partitions | | | +| Azure AS / SSAS | DirectQuery\* | | | +| Azure AS / SSAS | Direct Lake | N/A | N/A | +| Power BI | Perspectives | | | +| Power BI | Multiple partitions | | | +| Power BI | DirectQuery | | | +| Power BI | Direct Lake | | | + +\***Note:** Analysis Services on SQL Server Standard Edition pre-2019 does not support DirectQuery. Nor does Azure AS Basic Tier. [Learn more](https://learn.microsoft.com/en-us/analysis-services/analysis-services-features-by-edition?view=asallproducts-allversions#tabular-models). + +If you attemp to open a model that uses one or more of the restricted features listed above, while on a TE3 Business Edition license, you will see the error message below: + +![This edition of Tabular Editor 3 does not support Enterprise-tier semantic models](https://github.com/TabularEditor/TabularEditorDocs/assets/8976200/7ef69593-ea4b-4a16-a8df-543f5c31ac65) + +There are no other feature differences between the Tabular Editor 3 editions, than the ones listed above. + +> [!NOTE] +> Please keep in mind that Power BI Desktop [currently does not support all Data modeling operations](xref:desktop-limitations). For this reason, Tabular Editor 3 by default blocks operations that are not supported by Power BI Desktop. However, this restriction can be removed under Tools > Preferences > Power BI. + +> [!IMPORTANT] +> Tabular Editor can only be used as an external tool for Power BI Desktop when the Power BI report (.pbix, .pbip or .pbit) file contains a data model (Import, DirectQuery or Composite). **Reports using Live connection are not supported** since these reports do not contain a data model. [More information](xref:desktop-limitations). + +## Personal vs. Transferable licenses + +Our Desktop Edition and Business Edition uses a **personal** licensing model. This means, that a user receives their own personal License Key, which can not be shared or transferred to other users. When a user no longer requires the product, their subscription should be cancelled to avoid recurring payments. + +Our Enterprise Edition uses a **transferable** licensing model. The license administrator receives a single License Key, which is then valid for a number of named users up to the quantity purchased. Users are identified by their e-mail address, which is entered the first time a user activates an installation of Tabular Editor 3. The first time a user activates a Tabular Editor 3 installation using the license key, they are "locked-in" to that license for 30 days. After the 30 day lock-in period, a user can be removed from the license at any time, freeing up the license slot for another user. License administrators can view and manage users through our [self-service portal](https://tabulareditor.com/my-account). You may also contact support for assistance. + +## Multiple installations + +Each Tabular Editor 3 user is allowed to install the tool on multiple machines depending on the type of license held: + +| | Desktop | Business | Enterprise | +| -------------------------- | ------- | -------- | ---------- | +| Simultaneous installations | 1 | 2 | 3 | + +> [!NOTE] +> Sharing a single license among multiple users is against our [licensing terms](https://tabulareditor.com/license-terms). + +You can deactivate an existing installation at any time from within the tool itself, by choosing the "Change license key..." option under "Help > About Tabular Editor". You can also deactivate an installation through our [self-service portal](https://tabulareditor.com/sign-in) by navigating to the "Licenses" tab. + +If you need more simultaneous installations of Tabular Editor 3 than listed above, please contact [licensing@tabulareditor.com](mailto:licensing@tabulareditor.com). + +## Enterprise Edition Volume Discounts + +Our Enterprise Edition is priced in tiers, according to the following table (similar discount rates apply to monthly commitment): + +| Tier | Yearly price per seat | +| ------------------ | --------------------------- | +| First 5 seats | $950.00 USD | +| Next 6-10 seats | $900.00 USD | +| Next 11-20 seats | $850.00 USD | +| Next 21-50 seats | $800.00 USD | +| Seats 51 and above | $750.00 USD | + +As an example, if you need 12 seats, the price breaks down as follow: + +```text +Seats 1-5: 5 x 950.00 = $ 4,750.00 +Seats 6-10: 5 x 900.00 = $ 4,500.00 +Seats 11-12: 2 x 850.00 = $ 1,700.00 +-------------------------------------- +Total $ 10,950.00 +====================================== +``` + +If you require more than 100 seats, please contact sales for a quote. diff --git a/content/localization/zh/find-replace_zh.md b/content/localization/zh/find-replace_zh.md new file mode 100644 index 00000000..f0868fa1 --- /dev/null +++ b/content/localization/zh/find-replace_zh.md @@ -0,0 +1,53 @@ +--- +uid: find-replace +title: Find/Replace +author: Morten Lønskov +updated: 2023-03-22 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Find + +In Tabular Editor, you can use the advanced Find functionality to search for specific expressions throughout your open documents and dataset. The Find dialog box is accessible through the keyboard shortcut Ctrl+F. + +
    + Find Dialog Box
    Figure 1: Find window in Tabular Editor. Ctrl+F opens the dialog box
    +
    + +To perform a search, define the expression you want to search for, and use the Options to determine if certain criteria should be met. For example, you can choose whether the case should match between your find expression and the found text or use regular expressions to search with. + +## Look in + +Additionally, you can specify where to Look in, different areas of your Tabular Editor instance, to limit or expand the scope of your search. The Look in options include: + +
    + Find and Replace Dialog Box
    Figure 2: Find/Replace window in Tabular Editor. Ctrl+F opens the dialog box
    +
    + +- _Selection_: Search within the selection in the current open document (Cannot search through your dataset) +- _Current document_: Search through the entire document that you currently have open (Cannot search through your dataset) +- _All open documents_: Searches all open documents (Cannot search through your dataset) +- _Entire model_: Searches the TOM Explorer for matches in your dataset. + - Allows for searching within the individual parts of your dataset such as Names, Expressions, Annotations etc. + - You can also search using Dynamic LINQ in this mode to, for example, find all columns that do not have summarize set to none. + +> [!TIP] +> You can also use the search field in the TOM Explorer to search your dataset instead of the Find dialog + +## Replace + +The Replace dialog allows you in the same way as Find to search for an expression and then replace it with a different expression. + +The Replace dialog does not require anything in the _Replace with_ field, but leaving it empty will replace your searched for expression with an empty expression. +You have the same options as in the Find dialog to determine search criteria, but the _Look in_ functionality is only for documents, i.e. you cannot search and replace within your dataset objects. + +
    + Replace Dialog Box
    Figure 3: Replace window in Tabular Editor. Ctrl+F opens the dialog box
    +
    + +> [!TIP] +> If you are trying to rename variables in a DAX statement (Expression or Script), Ctrl+R will let you refactor a selected variable \ No newline at end of file diff --git a/content/localization/zh/gdpr-delete_zh.md b/content/localization/zh/gdpr-delete_zh.md new file mode 100644 index 00000000..2e69f7af --- /dev/null +++ b/content/localization/zh/gdpr-delete_zh.md @@ -0,0 +1,3 @@ +# User Data Deletion + +In order to request a complete data deletion of all user records, please send an e-mail to gdpr@tabulareditor.com. diff --git a/content/localization/zh/general-introduction_zh.md b/content/localization/zh/general-introduction_zh.md new file mode 100644 index 00000000..9f4af82e --- /dev/null +++ b/content/localization/zh/general-introduction_zh.md @@ -0,0 +1,115 @@ +--- +uid: general-introduction +title: General introduction and architecture +author: Daniel Otykier +updated: 2021-09-30 +--- + +# General introduction and architecture + +Tabular Editor is a Windows desktop application for developing tabular models. Specifically, the tool lets you edit the Tabular Object Model (TOM) metadata. The tool can load the TOM metadata from a file or from an existing Analysis Services database, and it can also deploy updated TOM metadata to Analysis Services. + +> [!NOTE] +> We use the term **tabular model** to represent both Analysis Services Tabular models as well as Power BI datasets, since Analysis Services Tabular is the data model engine used by Power BI. Similarly, when we use term **Analysis Services**, we mean "any instance of Analysis Services", which could be SQL Server Analysis Services, Power BI Desktop or the Power BI Service XMLA Endpoint. + +## Tabular Object Model (TOM) metadata + +A data model is made up by a number of tables. Each table has one or more columns, and a table may also contain measures and hierarchies. Typically, the data model also defines relationships between tables, data sources containing connection details and table partitions containing data source expressions (SQL or M queries) for loading data, etc. All of this information is collectively called the **model metadata**, and it is stored in a JSON based format known as the **Tabular Object Model (TOM)**. + +- When a tabular model is created using Visual Studio, the JSON representing the TOM metadata is stored in a file called **Model.bim**. +- When a data model is created using Power BI Desktop, the TOM metadata is embedded within the .pbix or .pbit file (since this file format also contains a lot of other details, such as definitions of visuals, bookmarks, etc., which is not related to the data model itself). + +Using a client library called [AMO/TOM](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions), Tabular Editor is able to load and save metadata to and from this JSON based format. In addition, the client library allows Tabular Editor to connect directly to any instance of Analysis Services, in order to obtain the model metadata from an existing database. This is illustrated in the figure below. + +![Architecture](~/content/assets/images/architecture.png) + +> [!NOTE] +> In the paragraph above, we used the term **database** to represent a model that has been deployed to Analysis Services. Within the Power BI Service the term **dataset** is used to represent the same thing, namely a tabular model. + +Tabular Editor can load model metadata from the following sources: + +- [1] Model.bim files +- [2] Database.json files (see @parallel-development for more information) +- [3] .pbit files (Power BI Template) +- [4] A database on SQL Server Analysis Services (Tabular) +- [5] A database on Azure Analysis Services +- [6] A dataset in a Power BI Premium\* Workspace +- [7] A Power BI Desktop report in Import/DirectQuery mode + +\*Power BI Premium/Embedded Capacity or Power BI Premium-Per-User is required in order to enable the [XMLA Endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools). The XMLA Endpoint must be enabled for any third party tool to connect to Power BI datasets. + +> [!IMPORTANT] +> Tabular Editor 2.x supports all sources 1-7 above. Tabular Editor 3 supports only some sources depending on which [edition of Tabular Editor 3](xref:editions) you are using. + +Once the model metadata has been loaded in Tabular Editor, the user is free to add/edit/remove **objects** and change **object properties**. Modifications are not saved back to the source until the user explicitly saves the model, either by choosing **File > Save** or by hitting CTRL+S. If the model metadata was loaded from a file source (sources 1-3 above), that file will then be updated. If the model metadata was loaded from Analysis Services (sources 4-7 above), then the changes are saved back to Analysis Services. Note that certain changes may cause objects to enter a state where they can no longer be queried by end-users. For example, if you add a column to a table, you will need to [refresh the table](xref:refresh-preview-query#refreshing-data) before users can query the contents of that table or any measures that dependent on the table. + +> [!WARNING] +> Certain limitations apply when saving model metadata changes back to Power BI Desktop (source 7 above). See @desktop-limitations for more information. + +### TOM objects and properties + +The TOM metadata is made up of **objects** and **properties**. + +Examples of TOM **objects**: + +- Data Sources +- Tables +- Partitions +- Measures +- KPIs +- Columns +- Model Roles + +Examples of TOM **object properties**: + +- `Name` (text) +- `Display Folder` (text) +- `Description` (text) +- `Hidden` (true/false) +- `Summarize By` (one of: None, Sum, Min, Max, ...) + +Most properties are simple values (text, true/false, one-of-selections aka. enums), but properties can also reference other objects (for example, the `Sort By Column` property should reference a column). Properties can also be arrays of objects, such as the `Members` property on the Model Role object. + +Tabular Editor generally uses the same name for objects and properties as those defind in the [Microsoft.AnalysisServices.Tabular namespace](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular?view=analysisservices-dotnet). If you want to learn more about specific TOM objects or properties, always consult the namespace documentation. For example, to learn what the "Summarize By" column property does, first locate the "Column" class in Microsoft's documentation, then expand "Properties" and scroll to "SummarizeBy". You should then get to [this article](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.column.summarizeby?view=analysisservices-dotnet). + +![SummarizeBy on Microsoft's docs](~/content/assets/images/asdocs-summarizyby.png) + +### Editing property values + +Both versions of Tabular Editor display the object model metadata in a hierarchical view known as the **TOM Explorer** view, which roughly corresponds to the hierarchical structure of the JSON metadata: + +![TOM Explorer](~/content/assets/images/tom-explorer.png) + +In general, Tabular Editor lets you modify object properties by first selecting an object in the TOM Explorer (you can select multiple objects at once by holding down SHIFT or CTRL), and then simply editing the property value within the **Properties view** (see screenshot below). + +![Properties View](~/content/assets/images/properties-view.png) + +Tabular Editor does not perform explicit validation of modified property values, except for some basic rules (for example, object names cannot be empty, measure names have to be unique, etc.). It is your responsibility as a tabular model developer to know which properties to set and what values to use. + +If you make a mistake while editing property values, you can always press CTRL+Z (Edit > Undo) to roll back the last property change. + +## Architecture + +As hinted above, Tabular Editor has two different modes of operation: Metadata from file (aka. **file mode**) and metadata from Analysis Services (aka. **connected mode**). In addition, Tabular Editor 3 introduces a hybrid approach called [**workspace mode**](xref:workspace-mode). + +Before proceeding, it is important to understand the differences between these modes: + +- In **file mode**, Tabular Editor loads and saves all model metadata from and to a file on disk. In this mode, Tabular Editor cannot interact with model **data** (that is, table previews, DAX queries, Pivot Grids, and data refresh operations are not enabled). This mode can be used entirely offline, even when no instance of Analysis Services is available. The supported file formats for model metadata are: + - Model.bim (same format used by Visual Studio) + - Database.json (folder structure only used by Tabular Editor) + - .pbit (Power BI Template) +- In **connected mode**, Tabular Editor loads and saves model metadata from and to Analysis Services. In this mode, it is possible to interact with model **data** using Tabular Editor 3 (table previews, DAX queries, Pivot Grids and data refresh). This mode requires connectivity to an instance of Analysis Services. +- In **workspace mode**, Tabular Editor 3 loads model metadata from a file on disk AND deploys the metadata to Analysis Services. On subsequent saves (CTRL+S), updates are saved both to disk and to the connected instance of Analysis Services. It is possible to interact with model **data** similar to **connected mode**. + +### Metadata synchronization + +One of the major benefits of Tabular Editor over the standard tools (Visual Studio, Power BI Desktop), is that model metadata is only saved upon request. In other words, you can make multiple changes to objects and properties without having to wait for any Analysis Services instance to become synchronized between each change. The synchronization of the Analysis Services database is an operation that may take several seconds to complete, depending on the size and complexity of the data model. In Power BI Desktop, this synchronization happens every time the notorious "Working on it" spinner appears on the screen. In Tabular Editor, this only happens when you explicitly save your changes (CTRL+S). + +The downside is, of course, that you have to remember to explicitly save your changes, before you can test the impact of any metadata modifications that were made. + +## Next steps + +- @installation-activation-basic +- @migrate-from-vs +- @migrate-from-desktop +- @migrate-from-te2 \ No newline at end of file diff --git a/content/localization/zh/getting-started_zh.md b/content/localization/zh/getting-started_zh.md new file mode 100644 index 00000000..fa3ecebf --- /dev/null +++ b/content/localization/zh/getting-started_zh.md @@ -0,0 +1,138 @@ +--- +uid: getting-started +title: Getting Started +author: Morten Lønskov +updated: 2025-09-23 +--- + +# Getting Started + +## Installation + +Download the latest version of Tabular Editor 3 from our [downloads page](xref:downloads). + +## Prerequisites + +None. + +## System requirements + +- **Operating system:** Windows 10, Windows 11, Windows Server 2016, Windows Server 2019 or newer +- **Architecture:** x64, ARM64 (native from 3.23.0) +- **.NET Runtime:** [.NET Desktop Runtime 8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) + +See the .NET supported OS policy for current Windows versions supported by each runtime. + +## Activating your installation + +Tabular Editor 3 is commercial software. Visit our [home page](https://tabulareditor.com) for pricing details and purchase options. If you haven't previously used Tabular Editor 3 you are eligible to a free 30-day trial. + +The first time you launch Tabular Editor 3 on a new machine, you are prompted to activate the product. + +![Product activation](~/content/assets/images/product-activation.png) + +### Activating using an existing license key + +Once you purchase a license for Tabular Editor 3, you should receive an e-mail with a 25-character string which is your license key. When prompted, enter the license key and hit "Next >" to activate the product. + +![Enter License Key](~/content/assets/images/enter-license-key.png) + +> [!NOTE] +> For multi-user license types, you will need to enter your e-mail address in addition to the license key. Tabular Editor 3 will prompt you to do so, if the license key you enter represents a multi-user license. + +Note that Tabular Editor 3 installations are activated **per user**. In other words, if multiple users share the same machine, each user will have to activate the product on their Windows user profile. + +### Requesting a trial license + +If you haven't used Tabular Editor 3 before, you are eligible to a free 30-day trial. When choosing this option, you will be prompted for an e-mail address. We use the e-mail address to validate whether or not you have an existing activation of Tabular Editor 3. + +> [!NOTE] +> Tabular Editor ApS will not sent unsolicited e-mails or forward your e-mail address to third parties, when signing up for a 30-day trial license. View our @privacy-policy for more information. + +### Changing a license key + +When Tabular Editor 3 is activated, you may change your license key in the Help menu by choosing "About Tabular Editor". + +![About Te3](~/content/assets/images/about-te3.png) + +In the dialog, select "Change license key". Note that this option is only available if no model is loaded in Tabular Editor. If you already loaded a model you can close it under File > Close model. Once you click "Change license key", Tabular Editor will prompt you whether you want to remove the current license: + +![image](https://user-images.githubusercontent.com/8976200/146754154-e691810b-342d-4311-8278-33da240d8d08.png) + +By accepting this, the current license is removed, and you will have to re-enter a license key to use the product. + +> [!IMPORTANT] +> Once a license key is removed, as described above, the product will not be usable by the current user on that machine until a new license key is entered. + +#### Registry details + +Tabular Editor 3 uses the Windows Registry to store activation details. + +To view the current license key assigned to the machine, run the following command in the Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG QUERY "HKCU\Software\Kapacity\Tabular Editor 3" /v LicenseKey +``` + +You can also use `regedit.exe` (Windows Registry Editor) and navigate to `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` to view and modify the **LicenseKey** and **User** values. + +A system administrator may also proactively assign Tabular Editor 3 licenses to a machine by specifying the **LicenseKey** and **User** values under each user’s `SOFTWARE\Kapacity\Tabular Editor 3` registry key. + +![Registry Editor](~/content/assets/images/registry-editor.png) + +### Changing a license key through the registry + +If, for any reason, you are unable to change the license key using the procedure outlined above, you can always reset the license assigned to Tabular Editor 3 by using the Registry Editor: + +1. Close all instances of Tabular Editor 3. +2. Open the Registry Editor in Windows (Start > Run > regedit.msc). +3. Locate `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` (see screenshot above). +4. Delete all values within this key. +5. Close the Registry Editor and restart Tabular Editor 3. + +Alternatively, run the following command in a Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG DELETE "HKCU\Software\Kapacity\Tabular Editor 3" /va +``` + +The next time you launch Tabular Editor 3, you will be prompted for a license key, just as when the tool was first installed on the machine. + +### Silent installation and license pre-provisioning + +You can deploy Tabular Editor silently and pre-provision the license through the Windows Registry. + +1. **Install silently** (no UI, no reboot): + ```powershell + msiexec /i TabularEditor..x64.Net8.msi /qn /norestart /l*v C:\Temp\TE3_install.log + ``` + +You may also use `/package` instead of `/i`. Replace `` with the actual version string. Use the ARM64 MSI if applicable. + +For details on available MSI command-line options, please refer to the official Microsoft documentation: +[Microsoft Standard Installer command-line options - Win32 apps | Microsoft Learn](https://learn.microsoft.com/windows/win32/msi/command-line-options) + +2. **Write the license to the Registry** **before the first launch** of the application: + + ```bat + REM Per-user license key (HKCU) + REG ADD "HKCU\Software\Kapacity\Tabular Editor 3" /v LicenseKey /t REG_SZ /d YOUR-25-CHAR-KEY /f + ``` + + If you are using an **Enterprise Edition** license key, also set the licensed user’s e‑mail: + + ```bat + REG ADD "HKCU\Software\Kapacity\Tabular Editor 3" /v User /t REG_SZ /d user@example.com /f + ``` + +**Notes** + +- The installer does **not** accept a license parameter; licensing is handled via the Registry entries above. +- Keys are stored under **HKCU** (per-user). Ensure the commands run in the context of the target user (e.g., via logon script or similar) so the values are written to the correct profile. +- For additional keys and values, see the [Registry details](#registry-details). + +## Next steps + +- [Overview of Tabular Editor 3's user interface](xref:user-interface) +- [What's new in Tabular Editor 3](whats-new.md) +- [Tabular Editor 3 Onboarding Guide](xref:onboarding-te3) \ No newline at end of file diff --git a/content/localization/zh/import-tables.partial_zh.md b/content/localization/zh/import-tables.partial_zh.md new file mode 100644 index 00000000..c0497727 --- /dev/null +++ b/content/localization/zh/import-tables.partial_zh.md @@ -0,0 +1,143 @@ +Tabular Editor 3 includes a **Table Import Wizard** that helps you create a data source in your model and import tables/views from relational data sources such as a SQL Server database. + +![Import Tables Wizard](~/content/assets/images/import-tables-wizard.png) + +## Types of TOM Data Sources + +Depending on your version of Analysis Services, there are different ways of defining data sources within the model metadata: + +- **Provider (aka. Legacy)**: Available in every version of Analysis Services and every compatibility level. Supports a limited range of sources, primarily relational through OLE DB/ODBC drivers. Partitions are usually defined using a SQL statement, which is executed natively against the source. Credentials are managed in the Provider Data Source object in the Tabular Object Model and stored and encrypted server-side. +- **Structured (aka. Power Query)**: Available since SQL Server 2017 (compatibility level 1400+). Supports a wider range of data sources than Legacy providers. Partitions are usually defined using M (Power Query) expressions. Credentials are managed in the Structured Data Source object in the Tabular Object Model and need to be specified upon every deployment to Analysis Services. +- **Implicit data sources**: Exclusively used by Power BI semantic models. No explicit Data Source object is created in the model. Instead, the M (Power Query) expression implicitly defines the data source. Credentials are not stored in the Tabular Object Model, but are managed by Power BI Desktop or the Power BI Service. + +> [!NOTE] +> The Table Import Wizard and Update Table Schema feature of Tabular Editor 2.x only supports Legacy data sources with SQL partitions. In other words, there is no support for Power Query partitions. For this reason, Legacy data sources are usually recommended, as they provide the highest level of interoperability between the developer tools. + +## Importing new tables + +When importing tables (Model menu > Import tables...), Tabular Editor presents you with the options mentioned above (for creating a new data source), as well as a list of data sources already present in the model. Avoid creating new data sources if the tables you want to import are available in one of the data sources already specified in the model. + +> [!TIP] +> A Semantic Model is generally regarded as an in-memory optimized semantic cache of a relational data warehouse. For this reason, a model should ideally only contain a single data source, which would point to a SQL-based data warehouse or data mart. + +## Creating a new data source + +If you need to create a new data source, Tabular Editor provides you with a list of supported data sources: + +![Create New Source](~/content/assets/images/create-new-source.png) + +Note that Analysis Services and Power BI in particular supports a much wider range of data sources, however the sources listed in the screenshot above are the ones that Tabular Editor is able to connect for the purpose of automatically importing table metadata (that is, column names and data types). For data sources not on this list, Tabular Editor 3 can still [update table schema by utilising Analysis Services](#updating-table-schema-through-analysis-services). + +Currently, the following data sources are natively supported by Tabular Editor 3: + +- SQL Server databases +- Azure SQL databases +- Azure Synapse Analytics (SQL pool and Serverless SQL pool) +- Oracle +- ODBC +- OLE DB +- Snowflake\* +- Power BI Dataflow\* +- Databricks\* +- Fabric Lakehouse\* +- Fabric Warehouse\* +- Fabric SQL Database\* +- Fabric Mirrored Database\* + +\*=These data sources are only supported as implicit data sources in Power BI data models. They are not available in SSAS / Azure AS. + +> [!TIP] +> For more info about connecting to Azure Databricks, please see [Connecting to Azure Databricks](xref:connecting-to-azure-databricks). + +After choosing one of the data sources on the list, Tabular Editor displays a connection details dialog, allowing you to specify server addresses, credentials, etc., specific to the data source you want to create. The settings that you specify should be those that Tabular Editor should use for establishing a local connection to the source. These settings are saved in your @user-options. + +![Sql Auth](~/content/assets/images/sql-auth.png) + +If you want Analysis Services to use different credentials when connecting, you can specify that by editing the data source properties of the Tabular Object Model after importing the tables. + +## Choosing objects to import + +Once your data source has been defined, you get the option of choosing tables/views from a list, or specifying a native query to be executed against the source. + +![Source Options](~/content/assets/images/source-options.png) + +If you select the first option, Tabular Editor will connect to the source and display a list of tables and views that you can preview on the next page: + +![Choose Source Objects](~/content/assets/images/choose-source-objects.png) + +You can import multiple tables/views at once by checking them on the left side. For each table/view, you may deselect/select columns to import. + +> [!TIP] +> If you are in control of the source, we recommend always creating a view on top of the tables you wish to import. In the view, make sure to correct any names, spellings, etc., to be used in the Semantic Model, and get rid of any columns not needed by the Semantic Model (system columns, timestamps, etc.). +> +> Then, in the model, import all columns from this view (basically generating a `SELECT * FROM ...` statement). This makes maintenance easier, as you only need to run a Schema Update in Tabular Editor to determine if anything was changed in the source. + +![Advanced Import](~/content/assets/images/advanced-import.png) + +If you change the preview mode to "Schema only" using the dropdown in the top left corner, it is possible to change the imported data type and column name for every source column. This may be useful for example if your source using floating-point values, but you want the data to be imported as fixed-decimal. + +![Confirm Selection](~/content/assets/images/confirm-selection.png) + +On the last page, confirm your selection and choose which type of partitions to create. For provider data sources, the default type of partition to be created is `SQL`, whereas for structured data sources, it is `M`. + +![Confirm Selection Direct Lake](~/content/assets/images/confirm-selection-direct-lake.png) + +For Fabric data sources the last page has a drop-down which lets you choose if you want your selection to be created as Direct Lake or Import mode. + +At this point, you should see your tables imported with all columns, data types, and source column mappings applied: + +![Import Complete](~/content/assets/images/import-complete.png) + +# Updating table schema + +If columns are added/changed in the source, or if you recently modified a partition expression or query, you can use Tabular Editor's **Update table schema** feature to update the column metadata in your model. + +![Update Table Schema](~/content/assets/images/update-table-schema.png) + +This menu item can be invoked at the model level, as well as on a collection of tables or even individual table partitions. + +When using this option, Tabular Editor will connect to all the relevant data sources (prompting for credentials as needed), in order to determine if new columns need to be added or existing column modified or removed. + +> [!IMPORTANT] +> If a column that was previously imported to your Semantic Model has been removed or renamed in the source, you must update the table schema in your Semantic Model. Otherwise, data refresh operations may fail. + +![Schema Compare Dialog](~/content/assets/images/schema-compare-dialog.png) + +In the screenshot above, Tabular Editor detected a few new columns, a single data type change, and two columns that were renamed in the source. Note that detection of a column rename only works for simple changes. In other cases, a name change usually results in Tabular Editor detecting a column removal and a column addition, which is the case for the `Tax Amount` column below, which seems to have been renamed to `TaxAmt` in the source. + +To avoid breaking existing DAX formulas that rely on the `[Tax Amount]` column, you can hold down the Ctrl button and click on the two rows in the Schema Change dialog, then right-click in order to combine the column removal and column addition into a single SourceColumn update operation: + +![Combine Sourcecolumn Update](~/content/assets/images/combine-sourcecolumn-update.png) + +If you do not want the name change to be propagated to the imported column (but only want to update the SourceColumn property to reflect the changed name in the data source), you can deselect the `Name` update operation in the dropdown: + +![Deselect Name](~/content/assets/images/deselect-name.png) + +## Updating table schema through Analysis Services + +By default, Tabular Editor 3 attempts to connect directly to the data source for the purposes of updating the imported table schema. Naturally, this only works when the data source is supported by Tabular Editor 3. If you need to update the schema of a table imported from a data source that is not supported by Tabular Editor 3, you can enable the **Use Analysis Services for change detection** option under **Tools > Preferences > Schema Compare**. This also applies when the M expression of a partition or shared expression is too complex for Tabular Editor 3's built-in schema detection feature. For example, the built-in schema detection does not support certain M functions. + +![Update Table Schema Through As](~/content/assets/images/update-table-schema-through-as.png) + +When this option is enabled and Tabular Editor 3 is connected to Analysis Services or the Power BI XMLA endpoint, you can update the schema of tables imported from **any** data source supported by Analysis Services or Power BI. + +> [!NOTE] +> The **Use Analysis Services for change detection** option only works while Tabular Editor 3 is connected to Analysis Services or the Power BI XMLA endpoint. For this reason, we recommend that developers always use the [Workspace Mode](xref:workspace-mode) when developing models. + +When the **Use Analysis Services for change detection** option is enabled, Tabular Editor 3 will use the following technique when a schema update is requested: + +1. A new transaction is created against the connected Analysis Services instance +2. A new temporary table is added to the model. This table uses a Power Query partition expression that returns the schema of the original expression, for which a schema update was requested. This is done using the [`Table.Schema` M function](https://docs.microsoft.com/en-us/powerquery-m/table-schema). +3. The temporary table is refreshed by Analysis Services. Analysis Services takes care of connecting to the data source in order to retrieve the updated schema. +4. Tabular Editor 3 queries the content of the temporary table to obtain the schema metadata. +5. The transaction is rolled back, leaving the Analysis Services database or Power BI Semantic Model in the original state it was in before step 1. +6. Tabular Editor 3 displays the "Apply Schema Changes" dialog as shown above, in case there are any schema changes. + +Using this technique, Tabular Editor 3 makes it possible to import and update tables from data sources that are otherwise not supported, regardless of the complexity and function usage of the M queries behind the tables. + +> [!NOTE] +> If your M expressions combine data from multiple sources, such as through the M [`Table.NestedJoin`](https://learn.microsoft.com/en-us/powerquery-m/table-nestedjoin) function, you may need to change the [**Privacy Level**](https://powerbi.microsoft.com/en-us/blog/privacy-levels-for-cloud-data-sources/) from "Private" to "Organizational" on the Semantic Model in the Power BI service. Otherwise, you may see an error indicating that ` references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.`. This error may also occur even if **Use Analysis Services for change detection** is not enabled, as Tabular Editor 3 will automatically fall back to this detection mechanism when the M expression is too complex for Tabular Editor 3's built-in schema detection. + +### Importing new tables through Analysis Services + +In order to import a table from a data source otherwise not suported, you can simply copy an existing table from that data source, modify the M expression on the partition query of the copied table, then save your changes to the workspace database and update the table schema as described above. diff --git a/content/localization/zh/importing-tables-data-modeling_zh.md b/content/localization/zh/importing-tables-data-modeling_zh.md new file mode 100644 index 00000000..4529882d --- /dev/null +++ b/content/localization/zh/importing-tables-data-modeling_zh.md @@ -0,0 +1,74 @@ +--- +uid: importing-tables-data-modeling +title: Importing tables and data modeling +author: Daniel Otykier +updated: 2021-10-08 +applies_to: + editions: + - edition: Desktop + partial: TE3 Desktop Edition includes this feature. External tools adding/editing tables, columns and relationships against a Power BI Desktop model is not supported by Microsoft, however. + - edition: Business + - edition: Enterprise +--- + +# Importing tables and data modeling + +This article describes how to use the [Table Import Wizard](#table-import-wizard) of Tabular Editor 3, to add new tables to the model. There is also a section on how to [update the table schema](#updating-table-schema) of an existing table. Lastly, we cover how to use the [diagram tool](#working-with-diagrams) to define and edit relationships between tables. + +## Table Import Wizard + +[!include[importing-tables1](~/content/te3/import-tables.partial.md)] + +# Working with diagrams + +In Tabular Editor 3, **diagrams** are documents that can be used to visualize and edit the relationships between tables in the model. You can create as many diagrams as you want to visualize certain areas of your model. A diagram can be saved as a stand alone file. See for more information. + +> [!NOTE] +> We recommend creating multiple smaller diagrams over few large diagrams. When a diagram contains more than 20 or so tables, it quickly becomes overwhelming and difficult to understand. + +After loading a model in Tabular Editor 3, choose the **File > New > Diagram** menu option to create a new diagram. + +## Adding tables + +Add initial tables to the diagram in any of the following ways: + +- (Multi-)select tables in the TOM Explorer, then right-click and choose **Add to diagram**. +- (Multi-)select tables in the TOM Explorer, then drag the tables over to the diagram +- Use the **Diagram > Add tables...** menu option, and (multi-)select the tables you want to add through the dialog box. + ![Diagram Add Tables](~/content/assets/images/diagram-add-tables.png) + +To add additional tables to the diagram, use the technique above again, or right-click on an existing table in the diagram and choose one of the following options: + +- **Add tables that filter this table**: Adds all tables to the diagram which may, directly or indirectly through other tables, filter the currently selected table. Useful when starting from a fact table. +- **Add all related tables**: Adds all tables to the diagram which are directly related to the currently selected table. Useful when starting from a dimension table. + ![Add Related Tables](~/content/assets/images/add-related-tables.png) + +Before proceeding, rearrange and resize the tables in the diagram to suit your preferences, or use the **Diagram > Auto-arrange** feature to have Tabular Editor 3 lay out the tables automatically. + +## Modifying relationships using the diagram + +To add a new relationship between two tables, locate the column on the fact table (many-side) of the relationship, and drag that column over to the corresponding column on the dimension table (one-side). Confirm the settings for the relationship and hit **OK**. + +![Create Relationship](~/content/assets/images/create-relationship.png) + +To edit an existing relationship, right-click on it and choose **Edit relationship**. The right-click menu also contains shortcuts for reversing or deleting a relationship, as shown on the screenshot below. + +![Edit Relationship Diagram](~/content/assets/images/edit-relationship-diagram.png) + +> [!NOTE] +> You can also create relationships without using a diagram, through the TOM Explorer. Locate the column from which the relationship should start (many-side / fact-table side), right-click and choose **Create > Relationship from**. Specify the destination column in the Create Relationship dialog that appears on the screen. + +## Saving a diagram + +To save a diagram, simply use the **File > Save** (CTRL+S) option. Tabular Editor 3 will prompt you to save the diagram if you close the document or the application while the diagram has unsaved changes. + +> [!TIP] +> The same diagram file can be loaded for different data models. Diagrams reference tables by their names. Any tables not present in the model upon diagram load are simply removed from the diagram. + +> [!NOTE] +> Every time you add or modify a relationship, you will have to run a "calculate" refresh on the data model, before the relationships can be used when querying the model. + +# Next steps + +- @refresh-preview-query +- @creating-and-testing-dax \ No newline at end of file diff --git a/content/localization/zh/importing-tables-from-excel_zh.md b/content/localization/zh/importing-tables-from-excel_zh.md new file mode 100644 index 00000000..7d339d97 --- /dev/null +++ b/content/localization/zh/importing-tables-from-excel_zh.md @@ -0,0 +1,63 @@ +--- +uid: importing-tables-from-excel +title: Importing Tables from Excel +author: Daniel Otykier +updated: 2021-11-10 +--- + +# Importing Tables from Excel + +If you need to add Excel worksheets as tables to your tabular model, this is possible with Tabular Editor 2.x and the Excel ODBC driver. + +# Prerequisites + +Tabular Editor 2.x is a 32 bit application, and most people usually have the 64 bit version of Office installed (which includes a 64-bit Excel ODBC driver). Unfortunately, Tabular Editor 2.x can't use the 64-bit driver, and simply downloading and attempting to install the 32-bit driver, will give you an error if you already have a 64-bit version of Office installed. However, it is possible to install the 32 bit Excel ODBC driver next to the 64-bit Office, by using this workaround: + +1. Download the 32-bit version of the driver from here: https://www.microsoft.com/en-us/download/details.aspx?id=54920 +2. Unzip the AccessDatabaseEngine.exe file +3. Inside, you will find the aceredist.msi file, which should be executed through the command line with the /passive switch: + + ```shell + aceredist.msi /passive + ``` + +4. Confirm the installation by looking in the ODBC Data Sources (32-bit) configuration (Windows start button, search for "ODBC", platform should say "32/64 bit", as in the screenshot below): + ![Excel Odbc 32 64](~/content/assets/images/excel-odbc-32-64.png) + +# Setting up an ODBC data source + +After making sure you have the 32-bit ODBC Excel driver installed, as described above, adding a table from an Excel file with Tabular Editor 2.x requires the following steps: + +1. In Tabular Editor, right-click on the model, choose "Import tables…", click "Next" +2. In the Connection Properties dialog, click "Change…". Select the "Microsoft ODBC Data Source" option and click "OK". +3. Select "Use connection string" and hit "Build…". Choose "Excel Files" and hit "OK". + ![Odbc Connection Properties Excel](~/content/assets/images/odbc-connection-properties-excel.png) +4. Locate the Excel file you want to load tables from and hit "OK". That should generate a connection string that looks something like this: + + ```connectionstring + Dsn=Excel Files;dbq=C:\Users\DanielOtykier\Documents\A Beer Dataset Calculation.xlsx;defaultdir=C:\Users\DanielOtykier\Documents;driverid=1046;maxbuffersize=2048;pagetimeout=5 + ``` + +5. After hitting "OK", Tabular Editor should display the list of worksheets and data areas in the Excel file. Unfortunately, the Import Table Wizard can’t preview the data currently, because it generates an invalid SQL statement: + ![Import Tables Excel](~/content/assets/images/import-tables-excel.png) +6. You can, however, still put a checkmark on the table you want to import. Hit "Import" when done, ignore the error message. +7. On the newly added table, locate the partition and modify the SQL to remove the empty bracket and the dot in front of the worksheet name. Apply the change (Hit F5). + ![Fix Partition Expressions Excel](~/content/assets/images/fix-partition-expressions-excel.png) +8. Then, right-click on the partition and choose "Refresh Table Metadata…". Tabular Editor now reads the column metadata from the Excel file through the ODBC driver: + ![Refresh Metadata Excel](~/content/assets/images/refresh-metadata-excel.png) +9. (Optional) If you don’t want to use ODBC for refreshing data into the table, you need to swap out the partition to use an M-based expression that loads the same worksheet data. To do this, add a new Power Query partition to the table (right-click on "Partitions" then choose "New Partition (Power Query")). Delete the legacy partition. Then, set the M expression of the new partition to the following: + + ```M + let + Source = Excel.Workbook(File.Contents(""), null, true), + Customer_Sheet = Source{[Item="",Kind="Sheet"]}[Data], + #"Promoted Headers" = Table.PromoteHeaders(Customer_Sheet, [PromoteAllScalars=true]) + in + #"Promoted Headers" + ``` + +Replace the `` and `` placeholders with their actual values. + +# Conclusion + +Importing tables from Excel files is possible with Tabular Editor 2.x, but it requires the use of the ODBC Excel driver as shown above, which adds some complexity to the process. \ No newline at end of file diff --git a/content/localization/zh/importing-tables_zh.md b/content/localization/zh/importing-tables_zh.md new file mode 100644 index 00000000..36873244 --- /dev/null +++ b/content/localization/zh/importing-tables_zh.md @@ -0,0 +1,15 @@ +--- +uid: importing-tables +title: Importing Tables +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Importing Tables + +[!include[importing-tables](~/content/te3/import-tables.partial.md)] \ No newline at end of file diff --git a/content/localization/zh/incremental-refresh-about_zh.md b/content/localization/zh/incremental-refresh-about_zh.md new file mode 100644 index 00000000..0d131c62 --- /dev/null +++ b/content/localization/zh/incremental-refresh-about_zh.md @@ -0,0 +1,350 @@ +--- +uid: incremental-refresh-about +title: What is a Refresh Policy? +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# What is a Refresh Policy? + +![Incremental Refresh Visual Abstract](~/content/assets/images/incremental-refresh-header.png) + +--- + +Datasets hosted in the Power BI service can have [Incremental Refresh](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview) configured for one or more data tables. **The purpose of Incremental Refresh is to achieve faster, more efficient refreshes by only retrieving recent/changing data, _incrementally refreshing_ the table.** To do this, the table is automatically divided into partitions, such that only recent or changing data is refreshed ("hot" partitions) or even retrieved in real-time (["Direct Query" partitions in "Hybrid Tables"](https://learn.microsoft.com/en-us/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables)) while older, static data is archived ("cold" partitions). + +_Incremental refresh can be easily configured and modified from within Tabular Editor._ + +> [!NOTE] +> Configuring incremental refresh can be beneficial for your data model: +> +> - Reduce refresh time & resource consumption +> - Experience shorter and more dependable scheduled refreshes + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +### How does it work? + +To create the partitions, Power BI uses the `RangeStart` and `RangeEnd` _datetime_ parameters in Power Query. These parameters are used in a filter step of the table partition M Expression, filtering a table datetime column. Columns that are of date, string or integer types can still be filtered while maintaining query folding using functions that convert `RangeStart`, `RangeEnd` or the date column to the appropriate data type. For more information about this, see [here](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#supported-data-sources) + +An example is given below. Incremental Refresh is applied to a table _'Orders'_ upon the _[Order Date]_ column: + +# [Filter Step Only](#tab/filterstep) + +```M +// The filter step should ideally be able to fold back to the data source +// No steps before this should break query folding +#"Incremental Refresh Filter Step" = + Table.SelectRows( + Navigation, + each + [OrderDate] >= #"RangeStart" and + [OrderDate] < #"RangeEnd" + ) +``` + +# [Full M Expression](#tab/fullexp) + +```M +let + // The data source should ideally support Query Folding + Source = Sql.Database(#"ServerParameter", #"DatabaseParameter"), + + Navigation = + Source{ + [ Schema="DW_fact", Item="Internet Sales" ] + } [Data], + + // The filter step should ideally be able to fold back to the data source + // No steps before this should break query folding + #"Incremental Refresh Filter Step" = + Table.SelectRows( + Navigation, + each + [OrderDate] >= #"RangeStart" and + [OrderDate] < #"RangeEnd" + ) +in + #"Incremental Refresh Filter Step" +``` + +# [RangeStart](#tab/rangestart) + +```M +// It does not matter what the initial value is for the RangeStart parameter +// The parameter must be of data type "datetime" +#datetime(2022, 12, 01, 0, 0, 0) + meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ] +``` + +# [RangeEnd](#tab/rangend) + +```M +// It does not matter what the initial value is for the RangeEnd parameter +// The parameter must be of data type "datetime" +#datetime(2022, 12, 31, 0, 0, 0) + meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ] +``` + +*** + +> [!WARNING] +> Incremental refresh is designed for data sources that support [Power Query query folding](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#:~:text=Incremental%20refresh%20is%20designed%20for%20data%20sources%20that%20support%20query%20folding). Ideally, [query folding shouldn't be broken](https://learn.microsoft.com/en-us/power-query/step-folding-indicators) before the filter step is applied. +> There's no explicit requirement for the final query to fold, except when implementing [Hybrid Tables](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#:~:text=However%2C%20if%20the%20incremental%20refresh%20policy%20includes%20getting%20real%2Dtime%20data%20with%20DirectQuery%2C%20non%2Dfolding%20transformations%20can%27t%20be%20used.). + +--- + +### What is a Refresh Policy? + +A _Refresh Policy_ determines how the data is partitioned, and which of these Policy Range Partitions will be updated upon refresh. It consists of a set of table TOM properties which can be setup or changed. + +> [!WARNING] +> **Power BI Desktop limitations:** Configuring incremental refresh when connected to a local Power BI Desktop model is not supported. To configure incremental refresh for a local Power BI Desktop model, use the Power BI Desktop user interface. + +--- + +### Refresh Policy properties + +Properties of Incremental Refresh + +Four different kinds of properties make up a basic Refresh Policy: + +1. **Incremental window** **properties**: The period window wherein data is _kept up-to-date_. +2. **Rolling window** **properties**: The period window wherein data is _archived_. +3. **Source expressions**: Define table schema and Power Query transformations of the table. +4. **Mode**: Whether `Import` or `Hybrid` tables are used. + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-policy-windows.png) + +--- + +#### Comparing to Power BI Desktop + +In Power BI Desktop, these properties are named differently. Below is an overview of how the properties match the Power BI Desktop user interface. + +![Incremental Refresh Policy Windows Properties](~/content/assets/images/incremental-refresh-window-properties.png) + +--- + +#### Advanced Properties + +Depending on the configured properties, Incremental Refresh may function differently. Below is an overview of the different Incremental Refresh configurations: + +# [Standard (Import)](#tab/import) + +In the standard configuration of Incremental Refresh, all partitions are imported in-memory. Partitions in the rolling window are archived, while those in the incremental window are refreshed. + +# [Hybrid](#tab/hybrid) + +In the **_[hybrid](https://learn.microsoft.com/en-us/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables)_** configuration of Incremental Refresh, the latest policy range partition in the incremental window is queried in real time using DirectQuery. + +This is configured with the Mode property when set to Hybrid. + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-mode-pbi-match.png) + +# [Only Refresh Complete Periods](#tab/completeperiods) + +In this configuration, the policy range will not include the current period in the rolling window. + +In the standard configuration of Incremental Refresh, the current period is always in the incremental window. This might not be the desired behavior, as the data will change with each refresh. If the users do not expect to see partial data for a partial day, you can configure 'Only Refresh Complete Periods'. + +This is configured with the IncrementalPeriodsOffset property. In the above example, a value of -1 for an IncrementalGranularity of Day will exclude the current date from the incremental window and thus the data scope; only complete days will be refreshed. + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-period-offset-pbi-match.png) + +# [Detect Data Changes](#tab/datachanges) + +In this configuration, not all records are refreshed in the incremental window. Instead, records are only refreshed if they change. Detect data changes can further optimize refresh performance when using incremental refresh. To identify data changes you use a _Polling Expression_. A Polling Expression is a separate property that expects a valid M Expression to identify a maximum date from a list of dates. + +Typically, you use the Polling Expression on a DateTime column of a table to identify the latest date. If any records match that date, they'll be refreshed. A common example is using a column like [LastUpdateDt] to label records that were updated or added with the current DateTime value. Any records that have values equal to the latest [LastUpdateDt] are refreshed. + +> [!NOTE] +> Records in archived partitions are _not_ refreshed. + +An example of a valid `Polling Expression` property is below. You can use this as a template when configuring _Detect Data Changes_ in your model from Tabular Editor: + +```M +// Retrieves the maximum value of the column [LastUpdateDt] +let + #"maxDateOfLastUpdate" = + List.max( + Orders[LastUpdateDt] + ), + + accountForNu11 = + if #"maxDateOfLastUpdate" = null + then #datetime(1901, 01, 01, 00, 00, 00) + else #"maxDateOfLastUpdate" +in + accountForNu11 +``` + +![Incremental Refresh Policy Windows](~/content/assets/images/incremental-refresh-detect-changes-pbi-match.png) + +*** + +#### Overview of all properties + +_Below is an overview of the TOM Properties in a data model used to configure Incremental Refresh:_ + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . +
    Property NamePower BI Desktop EquivalentDescriptionExpected Value
    EnableRefreshPolicyIncrementally refresh this tableWhether a refresh policy is enabled for the table.

    In Tabular Editor, other Refresh Policy properties will only be visible if this value is set to True.
    True or False.
    IncrementalGranularityIncremental Refresh PeriodThe granularity of the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    Day, Month, Quarter or Year. Must be smaller than or equal to the IncrementalGranularity.
    IncrementalPeriodsNumber of Incremental Refresh PeriodsThe number of periods for the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    An integer of the number of IncrementalGranularity periods. Must define a total period smaller than the RollingWindowPeriods
    IncrementalPeriodsOffsetOnly refresh complete daysThe offset to be applied to IncrementalPeriods.

    Example for:
    IncrementalPeriodsOffset=-1;
    IncrementalPeriods = 30;
    IncrementalGranularity = Day:
    "Only refresh data in the last 30 days, from the day before refresh date.
    An integer of the number of IncrementalGranularity periods to shift the Incremental window.
    ModeGet the latest data in real time with DirectQuerySpecifies whether Incremental Refresh is configured with only import partitions or also a DirectQuery partition, to result in a "Hybrid Table".Import or Hybrid.
    PolicyTypeN/ASpecifies the type of refresh policy.Can only contain a single value: Basic.
    PollingExpression
    (Optional)
    Detect Data ChangesThe M Expression used to detect changes in a specific column such as LastUpdateDate

    In Tabular Editor, the Polling Expression can be viewed and modified from the Expression Editor window by selecting it from the dropdown menu in the top-left.
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Property NamePower BI Desktop EquivalentDescriptionExpected Value
    EnableRefreshPolicyIncrementally refresh this tableWhether a refresh policy is enabled for the table.

    In Tabular Editor, other Refresh Policy properties will only be visible if this value is set to True.
    True or False.
    IncrementalGranularityIncremental Refresh PeriodThe granularity of the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    Day, Month, Quarter or Year. Must be smaller than or equal to the IncrementalGranularity.
    IncrementalPeriodsNumber of Incremental Refresh PeriodsThe number of periods for the incremental window.

    Example:
    "Refresh data in the last 30 days before refresh date."
    An integer of the number of IncrementalGranularity periods. Must define a total period smaller than the RollingWindowPeriods
    IncrementalPeriodsOffsetOnly refresh complete daysThe offset to be applied to IncrementalPeriods.

    Example for:
    IncrementalPeriodsOffset=-1;
    IncrementalPeriods = 30;
    IncrementalGranularity = Day:
    "Only refresh data in the last 30 days, from the day before refresh date.
    An integer of the number of IncrementalGranularity periods to shift the Incremental window.
    ModeGet the latest data in real time with DirectQuerySpecifies whether Incremental Refresh is configured with only import partitions or also a DirectQuery partition, to result in a "Hybrid Table".Import or Hybrid.
    PolicyTypeN/ASpecifies the type of refresh policy.Can only contain a single value: Basic.
    PollingExpression
    (Optional)
    Detect Data ChangesThe M Expression used to detect changes in a specific column such as LastUpdateDate

    In Tabular Editor, the Polling Expression can be viewed and modified from the Expression Editor window by selecting it from the dropdown menu in the top-left.
    A valid M Expression that returns a scalar value of the latest date in a column. All records in incremental window hot partitions containing that value for the column will be refreshed.

    Records in archived partitions are not refreshed.
    RollingWindowGranularityArchive Data PeriodThe granularity of the rolling window.

    Example:
    "Archive data starting 3 years before refresh date."
    Day, Month, Quarter or Year. Must be larger than or equal to the IncrementalGranularity.
    RollingWindowPeriodsNumber of Archive Data PeriodsThe number of periods for the rolling window.

    Example:
    "Archive data starting 3 years before refresh date."
    An integer of the number of RollingWindowGranularity periods. Must define a total period larger than the IncrementalPeriods
    SourceExpressionPower Query Source ExpressionThe M Expression for the table data source. This is where the original table M Expression is, and where any existing Power Query transformations would be modified.

    In Tabular Editor, the Source Expression can be viewed and modified from the Expression Editor by selecting it from the dropdown menu in the top-left.
    A valid M Expression containing a filter step appropriately using RangeStart and RangeEnd.
    + \ No newline at end of file diff --git a/content/localization/zh/incremental-refresh-modify_zh.md b/content/localization/zh/incremental-refresh-modify_zh.md new file mode 100644 index 00000000..18fa34a6 --- /dev/null +++ b/content/localization/zh/incremental-refresh-modify_zh.md @@ -0,0 +1,199 @@ +--- +uid: incremental-refresh-modify +title: Modify an Existing Refresh Policy +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Modifying Incremental Refresh + +![Incremental Refresh Visual Abstract](~/content/assets/images/incremental-refresh-modify-a-refresh-policy.png) + +--- + +**Incremental Refresh is changed by adjusting the Refresh Policy properties.** Depending on what you want to change, you will adjust a different property. A full overview of these properties is [here](xref:incremental-refresh-about#overview-of-all-properties). + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +## Change Incremental Refresh + +Below is a general description of how you modify an existing Refresh Policy: + +1. **Connect:** Connect to the model. + +2. **Select the Table:** Select the table already configured for Incremental Refresh. + +3. **Find 'Refresh Policy' properties:** In the _Properties_ window, go to the _Refresh Policy_ section. + + Properties of Incremental Refresh + +4. **Change the property:** Change the **Property** specified in the below sections, depending on what you want to change. For an overview of all Refresh Policy properties and what they do, see [here](xref:incremental-refresh-about#overview-of-all-properties). + +5. **Apply Changes:** Deploy the model changes. + +6. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. + + Apply Refresh Policy + +7. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + + Refresh All Partitions + +--- + +Below is an overview of common changes one might make to an existing Refresh Policy: + +### Extend or Reduce the Window for Archived Data + +**Purpose:** Add or reduce the amount of data in the model. + +**Property:** _RollingWindowPeriods_. Increase to extend the window (more data); decrease to reduce the window (less data). + +**Note:** You can also change the _RollingWindowGranularity_ to make a more fine-grain selection, i.e. from 3 Years to 36 Months. + +

    + +--- + +

    + +### Extend or Reduce the Window for Refreshed Data + +**Purpose:** Add or reduce the amount of data being refreshed in a scheduled refresh operation. + +**Property:** _IncrementalWindowPeriods_. Increase to extend the window (more data); decrease to reduce the window (less data). + +**Note:** You can also change the _IncrementalWindowGranularity_ to make a more fine-grain selection, i.e. from 3 Years to 36 Months. + +

    + +--- + +

    + +### Only Refresh Complete Periods + +**Purpose:** Exclude partial (incomplete) periods from the Rolling Window + +**Property:** _IncrementalWindowPeriodsOffset_. Set the value to `-1` to offset the period by 1, excluding the current period. + +**Note:** You can further offset this window to refresh i.e. only the periods behind the most recent complete period. + +

    + +--- + +

    + +### Change Incremental Refresh Mode + +**Purpose:** To change from `Import` to `Hybrid` tables, or vice-versa. + +**Property:** _Mode_ + +**Note:** Follow the below process to change Incremental Refresh Mode: + +1. Change _Mode_ to the desired value `Import` or `Hybrid` +2. Right-click the table and select _Apply Refresh Policy_ +3. Deploy the model changes +4. Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +> [!NOTE] +> It is recommended to check that the Rolling Window is appropriately set for the selected _Mode_. When switching from `Import` to `Hybrid` Mode, the latest Policy Range Partition will become the DirectQuery partition. You may wish to opt for a more fine-grain window, to limit the amount of data queried with DirectQuery. + +

    + +--- + +

    + +### Configure 'Detect Data Changes' + +**Purpose:** To configure that archived data will refresh if the value of a date column (i.e. _LastUpdate_) changes. + +**Property:** _PollingExpression_. Add a valid M Expression which returns a maximum date value for a column. All records containing that date will be refreshed, irrespective of their partition. + +**Note:** Follow the below process to configure 'Detect Data Changes': + +1. When the table is selected, in the _Expression Editor_ window, select _Polling Expression_ from the top-left dropdown +2. Copy in the below M Expression, replacing _LastUpdate_ with your desired column name. + +```M +// Retrieves the maximum value of the column [LastUpdate] +// Replace LastUpdate with your own column name +// The data will refresh for any records where the value in this column +// equals the maximum value in the column across the entire table +let + #"maxLastUpdate" = + List.Max( + // Replace the below with your column and table name + Orders[LastUpdate] + ), + + accountForNu11 = + if #"maxLastUpdate" = null + then #datetime(1901, 01, 01, 00, 00, 00) + else #"maxLastUpdate" +in + accountForNu11 +``` + +3. Right-click the table and select _Apply Refresh Policy_ +4. Deploy the model changes +5. Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +> [!WARNING] +> Any records will update if the value equals the maximum value in the column. It does not necessarily update explicitly because the value has changed, or if the value equals the refresh date. + +

    + +--- + +

    + +### Applying refresh policies with `EffectiveDate` + +If you want to generate partitions while overriding the current date (for purposes of generating different rolling window ranges), you can use a small script in Tabular Editor to apply the refresh policy with the [EffectiveDate](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#optional-parameters) parameter. + +With the incremental refresh table selected, run the following script in Tabular Editor's _'New C# Script'_ pane instead of applying the refresh policy by right-clicking the table. + +```csharp +// Todo: replace with your effective date +var effectiveDate = new DateTime(2020, 1, 1); +Selected.Table.ApplyRefreshPolicy(effectiveDate); +``` + +

    + +Effective Date + +

    + +--- + +

    + +### Disabling Incremental Refresh + +**Purpose:** To disable a refresh policy because it is not needed or the use-case no longer fits. + +**Property:** _EnableRefreshPolicy_ + +**Note:** To disable Incremental Refresh, follow the below steps: + +1. **Copy the _Source Expression_:** With the table selected, in the _Expression Editor_ window, select _Source Expression_ from the top-left dropdown. Copy the _Source Expression_ to a separate text editor window. +2. **Disable the Refresh Policy:** Change _EnableRefreshPolicy_ to `False` +3. **Remove all Policy Range partitions:** Select and delete all of the Policy Range partitions +4. **Create a new M Partition:** Right-click the table and select _Create > New Partition_. Set the partition _kind_ property to `M`. +5. **Paste the _Source Expression_:** Copy the _Source Expression_ from **Step 6** into the _Expression Editor_ as the _M Expression_ when selecting the new partition. +6. **Apply Changes:** Deploy the model changes. +7. **Refresh the Table:** Select and right-click the table. Select _Refresh > Full refresh (table)_. You can right-click the table and select _'Preview data'_ to see the result. diff --git a/content/localization/zh/incremental-refresh-schema_zh.md b/content/localization/zh/incremental-refresh-schema_zh.md new file mode 100644 index 00000000..f0863a30 --- /dev/null +++ b/content/localization/zh/incremental-refresh-schema_zh.md @@ -0,0 +1,138 @@ +--- +uid: incremental-refresh-schema +title: Add or Remove Columns in a Table that uses Incremental Refresh +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Modifying Incremental Refresh Table Schemas + +![Incremental Refresh Workspace Mode Visual Abstract](~/content/assets/images/incremental-refresh-update-schema-header.png) + +--- + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +**When adding or removing columns from a table configured with Incremental Refresh, you must update the table schema.** Generally, this follows the same protocol as updating table schemas for single-partition tables. Tabular Editor can detect and update the schema for you, automatically: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. + + Update Table Schema + +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. + + Apply Refresh Policy + +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + + Refresh All Partitions + +--- + +### Schema Update Considerations with Incremental Refresh + +- For Incremental Refresh, the main consideration is that **all partitions must be refreshed**.
    To do this, **select and right-click all partitions. Select _Refresh > Full refresh (partition)_**. + +- A second consideration is **the _Source Expression_ and _Polling Expression_ may need to be updated to reflect schema changes**. Not updating these M Expressions may result in refresh errors. Examples: + - `Table.TransformColumnTypes` step refers to a column that will be removed in the updated schema. + - `Table.SelectColumns` step lists columns to be kept; the new column is not added to this list. + +
    +
    CHECK M EXPRESSIONS BEFORE UPDATING THE TABLE SCHEMA
    +

    If schema changes arise from the Data Source, you may still need to apply changes to your Power Query Source Expression or Polling Expression. It is recommended that you carefully check these expressions before using 'Update table schema...'

    +
    + +--- + +### Removing Columns + +Depending on where the column is removed, you may follow a slightly different protocol: + +# [Supported Data Source](#tab/removingfromsource) + +For columns removed in the **data source** (i.e. removed from the view accessed by Power BI), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Power Query](#tab/removingfrompq) + +For columns removed via **Power Query** (i.e. using `Table.RemoveColumns`), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Unsupported Data Source](#tab/removingfromunsupportedsource) + +If you are **unable to automatically update the table schema** using _'Update table schema...'_ from the table context menu, follow the below steps. These steps are the same for both columns removed in the data source or in Power Query. + +1. **Select the Source Expression:** With the table selected, in the _Expression Editor_ window, select _Source Expression_ from the top-left dropdown. +2. **Update the Power Query Expressions:** Check and remove any named references to the removed column, if applicable. If the column is being excluded via Power Query, you can make the appropriate changes, here. +3. **Manually update the schema:** Delete the data column object from the table. +4. **Apply changes:** Deploy the model changes. +5. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +6. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +*** + +
    +
    DELETED COLUMN OBJECTS MAY STILL BE QUERIED
    +

    Deleting column objects from the model does not prevent them from being queried if they still exist in the source and are not removed in the Native Query or Source Expression. Columns queried but not used can have a negative impact on refresh time and resource usage. It is recommended that you remove columns from both metadata and either data sources (i.e. views) or in the Source Expression.

    +
    + +--- + +### Adding Columns + +Depending on where the column is added, you may follow a slightly different protocol: + +# [Supported Data Source](#tab/addingfromsource) + +For columns removed in the **data source** (i.e. added to the view accessed by Power BI), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Power Query](#tab/addingfrompq) + +For columns removed via **Power Query** (i.e. using `Table.AddColumns`), follow the below steps: + +1. **Detect schema changes:** Right-click the table and select _'Update table schema...'_. +2. **Apply detected schema changes:** In the _'Apply Schema Changes'_ dialogue, confirm the desired schema changes. +3. **Apply changes:** Deploy the model changes. +4. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +5. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +# [Unsupported Data Source](#tab/addingfromunsupportedsource) + +If you are **unable to automatically update the table schema** using _'Update table schema...'_ from the table context menu, follow the below steps. These steps are the same for both columns removed in the data source or in Power Query. + +1. **Select the Source Expression:** With the table selected, in the _Expression Editor_ window, select _Source Expression_ from the top-left dropdown. +2. **Update the Power Query Expressions:** Check and remove any named references to the removed column, if applicable. If the column is being excluded via Power Query, you can make the appropriate changes, here. +3. **Manually update the schema:** Right-click the table and select _Create > Data column_. Name the column appropriately. +4. **Configure the new column:** Set the column's `data type` property, appropriately. Set the `Source Column` property such that it matches the source. Any additional properties can also be configured (i.e. `Format String`, `SummarizeBy`, `Data Category`...) and the column can be added to the appropriate display folder. +5. **Apply changes:** Deploy the model changes. +6. **Apply Refresh Policy:** Right-click the table and select _Apply Refresh Policy_. +7. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + +*** \ No newline at end of file diff --git a/content/localization/zh/incremental-refresh-setup_zh.md b/content/localization/zh/incremental-refresh-setup_zh.md new file mode 100644 index 00000000..e24832f2 --- /dev/null +++ b/content/localization/zh/incremental-refresh-setup_zh.md @@ -0,0 +1,259 @@ +--- +uid: incremental-refresh-setup +title: Set Up a New Refresh Policy +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Setting up Incremental Refresh + +![Incremental Refresh Setup Visual Abstract](~/content/assets/images/incremental-refresh-setup-refresh-policy.png) + +--- + +To set up Incremental Refresh, you must configure a new Refresh Policy for the table. This is easily done by configuring the Refresh Policy properties once _EnableRefreshPolicy_ is set to `True`: + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. +> For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +### Configure a New Refresh Policy + +1. **Connect to the model:** Connect to the Power BI XMLA endpoint of your workspace, and open the dataset upon which you want to configure Incremental Refresh. +2. **Create the `RangeStart` and `RangeEnd` Parameters:** Incremental refresh requires the `RangeStart` and `RangeEnd` parameters to be created ([more information](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-configure#create-parameters)). Add two new Shared Expressions in Tabular Editor: + +Apply Refresh Policy + +3. **Configure the `RangeStart` and `RangeEnd` Parameters:** Name them `RangeStart` and `RangeEnd` respectively, set their `Kind` property to "M" and set their expression to the following (the actual date/time value you specify doesn't matter, as it will be set by Power BI Service when starting the data refresh): + +```M +#datetime(2021, 6, 9, 0, 0, 0) + meta + [ + IsParameterQuery=true, + Type="DateTime", + IsParameterQueryRequired=true + ] +``` + +Apply Refresh Policy + +4. **Copy Partition M Code**: Navigate to the table for which you want to configure incremental refresh. Fold it out and select your partition containing your Power Query M Expression. Copy your code to Notepad, you will need it in step 6. + +5. **Enable the Table Refresh Policy:** In the _'Properties'_ window, set the `EnableRefreshPolicy` property on the table to `True`: + +Apply Refresh Policy + +6. **Configure the Table Refresh:** Next, select the table for which you want to configure incremental refresh. In the **Expression Editor** window, Select **'Source Expression'** from the dropdown, insert your Power Query M Expression from step 4 and alter the Power Query M Expression such that there is a filter step on the date column for which you will enable incremental refresh. + + _An example of one such valid filter step is below:_ + +```M +// The filter step must be able to fold back to the data source +// No steps before this should break query folding +#"Incremental Refresh Filter Step" = + Table.SelectRows( + Navigation, + each + [OrderDate] >= #"RangeStart" and + [OrderDate] < #"RangeEnd" + ) +``` + +Columns that are of date, string or integer types can still be filtered while maintaining query folding using functions that convert `RangeStart` or `RangeEnd` to the appropriate data type. For more information about this, see [here](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview#supported-data-sources) + +7. **Configure Refresh Policy:** Configure the remaining properties according to the incremental refresh policy you need. Remember to specify an M expression for the `SourceExpression` property (this is the expression that will be added to partitions created by the incremental refresh policy, which should use the `RangeStart` and `RangeEnd` parameters to filter the data in the source). The = operator should only be applied to either RangeStart or RangeEnd, but not both, as data may be duplicated. + + - **Source Expression:** The M Expression that be added to partitions created by the Refresh Policy. + - **IncrementalWindowGranularity:** The granularity of the incremental (refresh) window. + - **IncrementalWindowPeriods:** # periods (of granularity specified above) wherein data should be refreshed. + - **IncrementalWindowPeriodsOffset:** Set to `-1` to set _'Only Refresh Complete Periods'_ + - **RollingWindowGranularity:** The granularity of the rolling (archive) window. + - **RollingWindowPeriods:** # periods (of granularity specified above) wherein data should be archived. + - **Mode:** Whether it is standard `Import` Refresh Policy or `Hybrid`, where the last partition is DirectQuery. + - **PollingExpression:** A valid M Expression configured to detect data changes. For more information about _Polling Expression_ or other Refresh Policy properties, see [here](xref:incremental-refresh-about#overview-of-all-properties). +8. **Apply Model Changes:** Save your model (Ctrl+S). +9. **Apply Refresh Policy:** Right-click on the table and choose "Apply Refresh Policy". + +Apply Refresh Policy + +**That's it!** At this point, you should see that the Power BI service has automatically generated the partitions on your table, based on the policy you specified. All that's left is to refresh all the partitions. + +Refresh All Partitions + +10. **Refresh all partitions:** Shift-click to select all partitions. Right-click and select _Refresh > Full refresh (partition)_. You can right-click the table and select _'Preview data'_ to see the result. + + Refresh All Partitions + +Finally, you can configure the scheduled refresh in Power BI Service. Power BI will automatically handle the partitioning of your table. You can always connect to the remote model to view and validate the partitions, i.e. using the VertiPaq Analyzer. + +------------- + +### Incremental Refresh with Integer Date Keys + +If your date column is Integer data type, use the below in the place of the filter Step 4, above: + +1. **Create the custom function:** Create a Shared Expression named `ConvertDatetimeToInt`: + +```M + // A custom M function which will return a DateTime value as a YYYYMMDD integer + (DateValue as datetime) => + Date.Year(DateValue) * 10000 + Date.Month(DateValue) * 100 + Date.Day(DateValue) +``` + +2. **Create the filter step:** Use the custom function to convert `RangeStart` and `RangeEnd` in-line to Integer. The filter step is otherwise identical to if the Date column would be a DateTime column: + +```M +let + // Connect to your data source + Source = + Sql.Database(#"SqlEndpoint", #"Database"), + +// Load the table data + Data = + Source{ [Schema="Factview", Item="Orders"] }[Data], + + // Make any transformations that should fold back to the data source + #"Remove Unnecessary Columns" = + Table.RemoveColumns ( + Data, + { + "DWCreatedDate", + "Net Invoice Cost" + } + ), + + // Add incremental refresh filter step + // The filter step must be able to fold back to the data source + // No steps before this should break query folding + #"Incremental Refresh" = + Table.SelectRows( + #"Remove Unnecessary Columns", + each [OrderDateKey] >= ConvertDatetimeToInt(#"RangeStart") + and [OrderDateKey] < ConvertDatetimeToInt(#"RangeEnd") + ) +in + #"Incremental Refresh" +``` + +3. **Proceed as normal with the next steps:** You can then proceed with configuring and applying the refresh policy with _'Apply refresh policy'_ and finally refreshing all partitions. Preview the data of the table after the refresh operations complete to see the result. + +------------- + +### Incremental Refresh with String Date Keys + +If your date column is of String data type, you should configure your filter step to parse the Date column without breaking query folding. This will vary depending on your source and how the date is formatted. Below is a hypothetical example for an Order Date formatted 'YYYY-MM-DD': + +```M +let + // Connect to your data source + Source = + Sql.Database(#"SqlEndpoint", #"Database"), + + // Load the table data + Data = + Source{ [Schema="Factview", Item="Orders"] }[Data], + + // Make any transformations that should fold back to the data source + #"Remove Unnecessary Columns" = + Table.RemoveColumns ( + Data, + { + "DWCreatedDate", + "Net Invoice Cost" + } + ), + + // Add incremental refresh filter step + // The filter step must be able to fold back to the data source + // No steps before this should break query folding + #"Incremental Refresh" = + Table.SelectRows( + #"Remove Unnecessary Columns", + each + + // Converts "2022-01-09" to DateTime, for example + DateTime.From( + Date.FromText( + [OrderDate], + [Format="yyyy-MM-dd"] + ) + ) >= #"RangeStart" + + and + + DateTime.From( + Date.FromText( + [OrderDate], + [Format="yyyy-MM-dd"] + ) + ) < #"RangeEnd" + ) +in + #"Incremental Refresh" +``` + +See also the documentation for the `Date.FromText` function in Power Query [here](https://learn.microsoft.com/en-us/powerquery-m/date-fromtext). Should it not be possible to convert the Date column in-line while preserving query folding, it is also possible to configure incremental refresh with a native query, as described in the section, below. + +------------- + +### Incremental Refresh with Native Queries + +If you have configured a native query, it may still be possible to configure and use incremental refresh, depending on your data source. To try this for yourself, you need to follow the following steps in the place of Step 4, above: + +1. **Author and Save the Native Query:** Write your native query in SQL Server Management Studio or Azure Data Studio. Include a placeholder `WHERE` clause which filters >= a DateTime parameter, and < another DateTime parameter. + + Refresh All Partitions + +2. **Replace the Native Query String in the Source Expression:** Copy the query and replace the existing query, which will be full of characters like (lf) (line feed), (cr) (carraige return) and (n) (new line). Doing this makes the query actually readable and editable without resorting to the Native Query user interface of Power BI Desktop. + +Refresh All Partitions + +Replace the above text in the `Query` parameter to the below, for example: + +Refresh All Partitions + +3. **Add `RangeStart` and `RangeEnd`:** Concatenate "RangeStart" and "RangeEnd" inside of the `WHERE` clause, replacing the placeholder fields and converting the parameters to date with `Date.From` and to string data types using `Date.ToText` with the `Format` option set to `"yyyy-MM-dd`. Don't forget to include single quotes `'` on either side of the concatenation. Below is an example of what the final query would look like: + +```M +// Example of a full native query that folds and works with Incremental Refresh +let + Source = Sql.Database("yoursql.database.windows.net", "YourDatabaseName", + [Query=" + +SELECT + [OrderDateKey] + ,[DueDateKey] + ,SUM([OrderQuantity]) AS 'TotalOrderQuantity' + ,SUM([SalesAmount] ) AS 'TotalSalesAmount' + ,[CustomerKey] + ,[ProductKey] +FROM [DW_fact].[Internet Sales] +WHERE + CONVERT(DATE, CONVERT(VARCHAR(8), [OrderDateKey])) + >= CONVERT(DATE, '" & Date.ToText(Date.From(#"RangeStart"), [Format="yyyy-MM-dd"]) & "') + AND + CONVERT(DATE, CONVERT(VARCHAR(8), [OrderDateKey])) + < CONVERT(DATE, '" & Date.ToText(Date.From(#"RangeEnd"), [Format="yyyy-MM-dd"]) & "') +GROUP BY + [OrderDateKey] + ,[DueDateKey] + ,[CustomerKey] + ,[ProductKey] + +"]) +in + Source +``` + +4. **Validate the new M Expression:** You can attempt to save the changes to the table M Expression prior to enabling the refresh policy, to see if you get the expected results when setting the `RangeStart` and `RangeEnd` to specific values. If so, you can proceed as normal; Power BI will be able to handle the partitioning as expected if you configured the steps in Power Query. + + It may not be necessary, but depending on the transformations in the native query, you may also try adding the parameter `[EnableFolding = True]` as described in [this article by Chris Webb](https://blog.crossjoin.co.uk/2021/02/21/query-folding-on-sql-queries-in-power-query-using-value-nativequery-and-enablefoldingtrue/). + +5. **Proceed as normal with the next steps:** You can then proceed with configuring and applying the refresh policy with _'Apply refresh policy'_ and finally refreshing all partitions. Preview the data of the table after the refresh operations complete to see the result. diff --git a/content/localization/zh/incremental-refresh-workspace-mode_zh.md b/content/localization/zh/incremental-refresh-workspace-mode_zh.md new file mode 100644 index 00000000..d04ec253 --- /dev/null +++ b/content/localization/zh/incremental-refresh-workspace-mode_zh.md @@ -0,0 +1,51 @@ +--- +uid: incremental-refresh-workspace-mode +title: Using Workspace Mode on a Model with Incremental Refresh +author: Kurt Buhler +updated: 2023-01-09 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise + versions: + - version: 2.X + - version: 3.4.2 and earlier +--- + +# Workspace mode and incremental refresh + +> [!IMPORTANT] +> This article only applies to versions 3.4.2 and earlier of Tabular Editor. +> Since the 3.5.0 update, _Workspace Mode_ will not overwrite deployed Refresh Policy partitions from scheduled refreshes. +> Refresh policy partitions will also not be serialized in source control. You can change this setting in _'Tools > Preferences... > Save-to-Folder'_. + +--- + +![Incremental Refresh Workspace Mode Visual Abstract](~/content/assets/images/incremental-refresh-workspace-mode.png) + +--- + +Incremental Refresh creates new partitions upon the first scheduled refresh in a day. As a result, any local metadata (i.e. `.bim` or `database.json`) will be out-of-sync with the remote model metadata after the refresh. As a result, **when working with a model that has tables configured with Incremental Refresh, _Workspace Mode_ is not recommended**. + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services, custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +--- + +### Workspace Mode is not Recommended + +The reason is because _Workspace Mode_ will overwrite the remote model metadata with local metadata files; any out-of-sync changes (like to Policy Range partitions) will be lost. When working with _Workspace Mode_ on these models, you would need to _Apply refresh policy_ for tables using incremental refresh before saving changes every day. + +![Workspace mode can get out of sync with local metadata.](~/content/assets/images/incremental-refresh-workspace-mode-out-of-sync.png) + +### Recommendation: Develop & Deploy from Local Metadata + +**Instead, it is recommended to develop the model from the local metadata files.** Changes can be deployed excluding partitions governed by a Refresh Policy, so there is no risk of overwriting the policies created by Power BI. A second read/refresh instance of Tabular Editor can be connected to the remote model for testing purposes. + +To deploy the model, go _Model > Deploy..._ which opens the Deployment Wizard. Here you can select whether you want to include partitions governed by Incremental Refresh policies: + +![Deploy partitions, avoiding partitions with refresh policies.](~/content/assets/images/incremental-refresh-deploy-partitions.png) + +By deploying the model without these Policy Range partitions, you are mitigating any potential impact due to out-of-sync incremental refresh partitions between the metadata and remote model. \ No newline at end of file diff --git a/content/localization/zh/incremental-refresh_zh.md b/content/localization/zh/incremental-refresh_zh.md new file mode 100644 index 00000000..549bb3c7 --- /dev/null +++ b/content/localization/zh/incremental-refresh_zh.md @@ -0,0 +1,90 @@ +--- +uid: incremental-refresh-policy +title: Incremental Refresh +author: Daniel Otykier +updated: 2021-02-15 +--- + +# Incremental Refresh + +Datasets hosted in the Power BI service can have [Incremental Refresh](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview) set up on one or more tables. To configure or modify Incremental Refresh on a Power BI dataset, you can either use the [XMLA endpoint of the Power BI service directly](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla), or you can use Tabular Editor connected to the XMLA endpoint, as described below: + +> [!IMPORTANT] +> Setting up Incremental Refresh with Tabular Editor 3 is limited to dataset hosted in the Power BI Datasets service. For Analysis Services custom [partitioning](https://learn.microsoft.com/en-us/analysis-services/tabular-models/partitions-ssas-tabular?view=asallproducts-allversions) is required. + +## Setting up Incremental Refresh from scratch with Tabular Editor + +1. Connect to the Power BI XMLA R/W endpoint of your workspace, and open the dataset on which you want to configure Incremental Refresh. +2. Incremental refresh requires the `RangeStart` and `RangeEnd` parameters to be created ([more information](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-configure#create-parameters)), so let's start by adding two new Shared Expressions in Tabular Editor: + ![Add shared expressions](https://user-images.githubusercontent.com/8976200/121341006-8906e900-c920-11eb-97af-ee683ff40609.png) +3. Name them `RangeStart` and `RangeEnd` respectively, set their `Kind` property to "M" and set their expression to the following (the actual date/time value you specify doesn't matter, as it will be set by the PBI service when starting the data refresh): + + ```M + #datetime(2021, 6, 9, 0, 0, 0) meta [IsParameterQuery=true, Type="DateTime", IsParameterQueryRequired=true] + ``` + +![Set kind property](https://user-images.githubusercontent.com/8976200/121342389-dc2d6b80-c921-11eb-8848-b67950e55e36.png) +4. Next, select the table on which you want to enable incremental refresh +5. Set the `EnableRefreshPolicy` property on the table to "true": +![Enable Refresh Policy](https://user-images.githubusercontent.com/8976200/121339872-3842c080-c91f-11eb-8e63-a051b34fb36f.png) +6. Configure the remaining properties according to the incremental refresh policy you need. Remember to specify an M expression for the `SourceExpression` property (this is the expression that will be added to partitions created by the incremental refresh policy, which should use the `RangeStart` and `RangeEnd` parameters to filter the data in the source). The = operator should only be applied to either RangeStart or RangeEnd, but not both, as data may be duplicated. +![Configure Properties](https://user-images.githubusercontent.com/45298358/170603450-8232ad55-0b4a-4ead-b113-786a781f94ad.png) +7. Save your model (Ctrl+S). +8. Right-click on the table and choose "Apply Refresh Policy". +![Apply Refresh Policy](https://user-images.githubusercontent.com/8976200/121342947-78577280-c922-11eb-82b5-a517fbe86c3e.png) + +That's it! At this point, you should see that the Power BI service has automatically generated the partitions on your table, based on the policy you specified. + +![Generated Partitions](https://user-images.githubusercontent.com/8976200/121343417-eef47000-c922-11eb-8731-1ac4dde916ef.png) + +The next step is to refresh the data in the partitions. You can use the Power BI service for that, or you can refresh the partitions in batches using [XMLA/TMSL through SQL Server Management Studio](https://docs.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla#refresh-management-with-sql-server-management-studio-ssms), or even using [Tabular Editor's scripting](https://www.elegantbi.com/post/datarefreshintabulareditor). + +### Full refresh with incremental refresh policy applied + +If you have applied a refresh policy to your table and wish to perform a full refresh, you must ensure that you set [applyRefreshPolicy to false](https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-xmla#override-incremental-refresh-behavior) in your script. This will ensure that you perform a full refresh of all the partitions in your table. +The TMSL Command would in our example look like this: + + ``` + { + "refresh": { + "type": "full", + "applyRefreshPolicy": false + "objects": [ + { + "database": "AdventureWorks", + "table": "Internet Sales" + } + ] + } + } + ``` + +## Modifying existing refresh policies + +You can also use Tabular Editor to modify existing refresh policies that has been set up using Power BI Desktop. Simply follow step 6-8 above in this case. + +## Applying refresh policies with `EffectiveDate` + +If you want to generate partitions while overriding the current date (for purposes of generating different rolling window ranges), you can use a small script in Tabular Editor to apply the refresh policy with the [EffectiveDate](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#optional-parameters) parameter. + +With the incremental refresh table selected, run the following script in Tabular Editor's "Advanced Scripting" pane, in place of step 8 above: + +```csharp +var effectiveDate = new DateTime(2020, 1, 1); // Todo: replace with your effective date +Selected.Table.ApplyRefreshPolicy(effectiveDate); +``` + +![Use scripts to apply refresh policy](https://user-images.githubusercontent.com/8976200/121344362-f9633980-c923-11eb-916c-44a35cf03a36.png) + +## Removing Incremental Refresh using Tabular Editor + +You may need to remove the incremental refresh policy from a table. + +1. Select the table in the TOM view and get the M code from the SourceExpression property and save it somewhere. +2. Change the EnableRefreshPolicy value from TRUE to FALSE. +3. Right-click on the table and create a new M partition. +4. Paste in the M code from step 1 above as the partition's expression. +5. Edit the M code to remove the step that contains the Table.SelectRows() function for the RangeStart/RangeEnd parameters. +6. Delete all of the historical partitions. They have a SourceType of "Policy Range". +7. Refresh the table (Tabular Editor 3) or in the service refresh the dataset to repopulate the table. +8. Optionally delete the RangeStart/RangeEnd shared expressions if there are no other tables in the model with an Incremental Refresh policy set. diff --git a/content/localization/zh/index_zh.md b/content/localization/zh/index_zh.md new file mode 100644 index 00000000..8d7df9b3 --- /dev/null +++ b/content/localization/zh/index_zh.md @@ -0,0 +1,95 @@ +--- +title: Tabular Editor 3 +author: Daniel Otykier +--- + +# Tabular Editor 3 + +This is the documentation site for Tabular Editor 3 - the ultimate productivity tool for Analysis Services and Power BI data models. + +Use the menu on the left side to navigate between topics. + +## Installation + +Download the latest version of Tabular Editor 3 from our [downloads page](xref:downloads). + +## Prerequisites + +None. + +## System requirements + +- **Operating system:** Windows 7, Windows 8, Windows 10, Windows Server 2016, Windows Server 2019 or newer +- **.NET Framework:** [4.7.2](https://dotnet.microsoft.com/download/dotnet-framework) + +## Activating your installation + +Tabular Editor 3 is commercial software. Visit our [home page](https://tabulareditor.com) for pricing details and purchase options. If you haven't previously used Tabular Editor 3 you are eligible to a free 30-day trial. + +The first time you launch Tabular Editor 3 on a new machine, you are prompted to activate the product. + +![Product activation](~/content/assets/images/product-activation.png) + +### Activating using an existing license key + +Once you purchase a license for Tabular Editor 3, you should receive an e-mail with a 25-character string which is your license key. When prompted, enter the license key and hit "Next >" to activate the product. + +![Enter License Key](~/content/assets/images/enter-license-key.png) + +> [!NOTE] +> For multi-user license types, you will need to enter your e-mail address in addition to the license key. Tabular Editor 3 will prompt you to do so, if the license key you enter represents a multi-user license. + +### Requesting a trial license + +If you haven't used Tabular Editor 3 before, you are eligible to a free 30-day trial. When choosing this option, you will be prompted for an e-mail address. We use the e-mail address to validate whether or not you have an existing activation of Tabular Editor 3. + +> [!NOTE] +> Tabular Editor ApS will not sent unsolicited e-mails or forward your e-mail address to third parties, when signing up for a 30-day trial license. View our @privacy-policy for more information. + +### Changing a license key + +When Tabular Editor 3 is activated, you may change your license key in the Help menu by choosing "About Tabular Editor". + +![About Te3](~/content/assets/images/about-te3.png) + +In the dialog, select "Change license key". Note that this option is only available if no model is loaded in Tabular Editor. IF you already loaded a model you can close it under File > Close model. + +#### Registry details + +Tabular Editor 3 uses the Windows Registry to store activation details. + +To view the current license key assigned to the machine, run the following command in the Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG QUERY "HKCU\Software\Kapacity\Tabular Editor 3" /v LicenseKey +``` + +You can also use `regedit.exe` (Windows Registry Editor) and navigate to `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` to view and modify the **LicenseKey** and **User** values. + +A system administrator may also proactively assign Tabular Editor 3 licenses to a machine by specifying the **LicenseKey** and **User** values under each user’s `SOFTWARE\Kapacity\Tabular Editor 3` registry key. + +![Registry Editor](~/content/assets/images/registry-editor.png) + +### Changing a license key through the registry + +If, for any reason, you are unable to change the license key using the procedure outlined above, you can always reset the license assigned to Tabular Editor 3 by using the Registry Editor: + +1. Close all instances of Tabular Editor 3. +2. Open the Registry Editor in Windows (Start > Run > regedit.msc). +3. Locate `HKEY_CURRENT_USER\SOFTWARE\Kapacity\Tabular Editor 3` (see screenshot above). +4. Delete all values within this key. +5. Close the Registry Editor and restart Tabular Editor 3. + +Alternatively, run the following command in a Windows Command Prompt (Start > Run > cmd.exe): + +```cmd +REG DELETE "HKCU\Software\Kapacity\Tabular Editor 3" /va +``` + +The next time you launch Tabular Editor 3, you will be prompted for a license key, just as when the tool was first installed on the machine. + +## Next steps + +- [Overview of Tabular Editor 3's user interface](xref:user-interface) +- [What's new in Tabular Editor 3](whats-new.md) +- [Tabular Editor 3 Onboarding Guide](xref:onboarding-te3) \ No newline at end of file diff --git a/content/localization/zh/installation_zh.md b/content/localization/zh/installation_zh.md new file mode 100644 index 00000000..ae418cba --- /dev/null +++ b/content/localization/zh/installation_zh.md @@ -0,0 +1,99 @@ +--- +uid: installation-activation-basic +title: Installation, activation and basic configuration +author: Daniel Otykier +updated: 2021-09-30 +--- + +## Installation + +In order to install Tabular Editor 3, download the latest version from our [downloads page](xref:downloads). + +We recommend downloading the MSI 64-bit installer, which is suitable in most scenarios. Once downloaded, doubleclick the MSI file and go through the installation pages. + +![Install](~/content/assets/images/install.png) + +## Activating your installation + +The first time you launch Tabular Editor 3 on a new machine, you are prompted to activate the product. + +![Product activation](~/content/assets/images/product-activation.png) + +### Activating using an existing license key + +Once you purchase a license for Tabular Editor 3, you should receive an e-mail with a 25-character string which is your license key. When prompted, enter the license key and hit "Next >" to activate the product. + +![Enter License Key](~/content/assets/images/enter-license-key.png) + +> [!NOTE] +> For multi-user license types, you will need to enter your e-mail address in addition to the license key. Tabular Editor 3 will prompt you to do so, if the license key you enter represents a multi-user license. + +#### Manual Activation (No Internet) + +If you do not have access to the internet e.g., due to a proxy Tabular Editor will prompt you to do a manual activation. + +![Manual Activation Prompt](~/content/assets/images/Activation_manual_firstprompt.png) + +After entering your email, a dialog box appears with a link to an activation key. +Copy the URL and open it in a web-browser that is connected to the internet. + +The URL returns a JSON object: + +![Manual Activation JSON Object](~/content/assets/images/activation_manual_jsonobject.png) + +Copy the full JSON object and paste the full JSON object given into the dialog box. +Your manual activation dialog should end up looking like below. + +![Manual Activation Filled In](~/content/assets/images/activation_manual_dialogbox_filled.png) + +Your Tabular Editor 3 license will thereby be verified. + +### Changing a license key + +When Tabular Editor 3 is activated, you may change your license key in the Help menu by choosing "About Tabular Editor". + +![About Te3](~/content/assets/images/about-te3.png) + +In the dialog, select "Change license key". Note that this option is only available if no model is loaded in Tabular Editor. IF you already loaded a model you can close it under File > Close model. + +For more details on managing the license keys, see [Registry details](xref:getting-started#registry-details). + +## Basic configuration + +After Tabular Editor 3 is activated, we recommend spending a few minutes familiarizing yourself with the [basic interface](xref:user-interface). In addition, Tabular Editor 3 provides many different configuration options. The default settings are sufficient for most development scenarios, but there are a few important configuration options that you should always review. + +### Check for updates on start-up + +By default, whenever Tabular Editor 3 is launched, the tool will check online to see if a newer version is available. You can control how this update check is performed under **Tools > Preferences > Updates and Feedback**. + +> [!NOTE] +> We recommend always using the latest version of Tabular Editor 3. Our support team will generally assume that you are always using the latest version before submitting a bug report. + +### Opting out of telemetry collection + +Tabular Editor 3 collects anonymous usage data and telemetry, which helps us improve the product. You can opt out at any time by launching Tabular Editor 3 and navigating to **Tools > Preferences > Updates and Feedback**. Uncheck the **Help improve Tabular Editor by collecting anonymous usage data** checkbox to opt out. + +![Collect Telemetry](~/content/assets/images/collect-telemetry.png) + +### Proxy settings + +If you are on a network with limited Internet connectivity, you can specify the address, username and password of a proxy server under **Tools > Preferences > Proxy Settings**. This is required before Tabular Editor 3 can use any features that rely on outgoing web requests. Specifically, these are: + +- Update checks +- Product activation +- DAX Formatting +- Download of Best Practice Rules from external URLs + +> [!TIP] +> The proxy settings can at times interfere with authentication dialog boxes or other external prompts. +> Try to switch the proxy setting between "System" and "None", close and reopen Tabular Editor 3 to verify. + +### Other preferences + +In addition to the settings mentioned above, Tabular Editor 3 contains many other settings for controlling various application behavior, allowing you to closely tailor the tool to your needs. To learn more about other these settings, see @preferences. + +## Next steps + +- @migrate-from-vs +- @migrate-from-desktop +- @migrate-from-te2 \ No newline at end of file diff --git a/content/localization/zh/locale-not-supported_zh.md b/content/localization/zh/locale-not-supported_zh.md new file mode 100644 index 00000000..756e7db2 --- /dev/null +++ b/content/localization/zh/locale-not-supported_zh.md @@ -0,0 +1,59 @@ +--- +uid: locale-not-supported +title: Locale Not Supported +author: Morten Lønskov +updated: 2025-09-02 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +You may encounter the warning message: + +```plaintext +The XXXX locale is not supported +``` + +in the Tabular Editor 3 Message view. + +![Locale not supported message](~/content/assets/images/troubleshooting/locale-not-supported-message-view.png) + +This issue usually occurs when your local machine uses a **regional configuration not supported by the Analysis Services (SSAS) engine**. +In most cases, the error is triggered by another underlying issue or warning, but this message is shown as a result. + +--- + +## Scenarios and Solutions + +### 1. Connecting to a Local SSAS Instance + +If you are running SQL Server Analysis Services (SSAS) locally on your machine: + +- **Solution:** Change the **service account** used by the SSAS instance. + Updating the account often resolves unsupported locale mismatches. + +--- + +### 2. Connecting to a Remote SSAS, Azure AS, or Power BI + +When connecting to a remote instance, you have two possible solutions: + +#### Option A: Specify Locale in the Connection String + +Explicitly set a supported locale (e.g., English – 1033) by adding `LocaleIdentifier=1033` to your connection string. + +**Example (Azure AS):** + +```plaintext +Data Source=asazure://westeurope.asazure.windows.net/instance-name;LocaleIdentifier=1033 +``` + +#### Option B: Change Regional Settings on Your Machine + +Adjust your local system’s regional and language settings to match a supported locale. + +- **Recommended settings:** + - **Regional format:** English (United States) + - **Windows Display Language:** English (United States) diff --git a/content/localization/zh/log4j_zh.md b/content/localization/zh/log4j_zh.md new file mode 100644 index 00000000..d3167c24 --- /dev/null +++ b/content/localization/zh/log4j_zh.md @@ -0,0 +1,19 @@ +--- +uid: log4j +title: Log4j vulnerability +author: Daniel Otykier +updated: 2021-12-15 +--- + +# Log4j vulnerability + +On December 9, 2021, the [Log4j vulnerability](https://logging.apache.org/log4j/2.x/security.html) was uncovered. Naturally, IT organizations worldwide took steps to ensure that affected software was patched immediately. + +For anyone seeking information about whether Tabular Editor is affected by this vulnerability, we hereby state the following: + +> [!IMPORTANT] +> Tabular Editor 2 and Tabular Editor 3 are **not** affected by the Log4j vulnerability. + +No version of Tabular Editor is affected by this vulnerability, since the application itself is a .NET application that does not rely on any Java components. This applies to all versions of Tabular Editor 2 (current and historic major and minor updates), as well as all versions of Tabular Editor 3 (current and historic major and minor updates). + +Should you have any concerns or questions, please reach out to [sales@tabulareditor.com](mailto:sales@tabulareditor.com). \ No newline at end of file diff --git a/content/localization/zh/macros-view_zh.md b/content/localization/zh/macros-view_zh.md new file mode 100644 index 00000000..a257b090 --- /dev/null +++ b/content/localization/zh/macros-view_zh.md @@ -0,0 +1,39 @@ +--- +uid: macros-view +title: Macros view +author: Morten Lønskov +updated: 2023-03-22 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Macros view + +Macros are a powerful feature of Tabular Editor that allow you to automate repetitive tasks or create custom actions for your models. A macro is a script written in C# that can access and manipulate the Tabular Object Model (TOM). + +You can create, edit, run and manage macros from the Macros menu in Tabular Editor. + +> [!TIP] +> You can nest your macros in folders by prefixing your macro name in the following pattern `FolderName\MacroName` + +
    + Macro Window
    Figure 1: Macro window in Tabular Editor. Provides an overview of all your saved Macros
    +
    + +> [!NOTE] +> The macros view displays a list of all macros currently saved in your `%localappdata%\TabularEditor3\MacroActions.json` file. + +- You can delete a macro by clicking on the "X" button at the top left corner of the view. +- You can edit a macro by double-clicking on the list item. This will bring up a [C# script document](xref:csharp-scripts) containing the code that will be executed when the macro is invoked. To save your changes to the macro, click the "Edit Macro..." toolbar button (see screenshot below) or use the **C# Script > Edit Macro...** menu item. +- To create a new macro, start by creating a new [C# script](xref:csharp-scripts), then save it as a macro using the **C# Script > Save as Macro...** menu item. + +
    + Edit Macro Button
    Figure 2: When you have a Macro open you can save it back by choosing "Edit Macro..."
    +
    + +## Next steps + +- @creating-macros diff --git a/content/localization/zh/messages-view_zh.md b/content/localization/zh/messages-view_zh.md new file mode 100644 index 00000000..5d117c87 --- /dev/null +++ b/content/localization/zh/messages-view_zh.md @@ -0,0 +1,42 @@ +--- +uid: messages-view +title: Messages view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Messages view + +The Messages view in Tabular Editor 3 is a tool window that displays various types of messages related to the current dataset. + +> [!TIP] +> You can double-click on a message to jump to the source of the error in the model tree or script editor. + +
    + Message View
    Figure 1: Messages window in Tabular Editor. Provides an overview of all warnings and errors in your dataset
    +
    + +The Messages view will tell you the Source and the object from which the message is being generated. + +There are two types of messages displayed Errors and Warnings + +- Errors: This tab shows any errors that prevent your model from being deployed or saved. For example, if you have an invalid expression in a calculation item or a circular dependency in a relationship. +- Warnings: This tab shows any warnings that does not concur with standards but does not prevent your model from being usable. This is for example having fully qualified measure references. +- + +## Copying Messages + +The message view allows for copying out the error message using Ctrl+C. + +From Tabular Editor 3.23.0 Ctrl+C copies the selected cell by default. Use Ctrl+Shift+C (or Copy Row in right-click menu) for row-level copy. + +> [!TIP] +> Right-click a cell to choose Copy Cell / Copy Row. + +![Message View Copy](~/content/assets/images/messages-view-copy.png) + diff --git a/content/localization/zh/metadata-translation-editor_zh.md b/content/localization/zh/metadata-translation-editor_zh.md new file mode 100644 index 00000000..61bd0938 --- /dev/null +++ b/content/localization/zh/metadata-translation-editor_zh.md @@ -0,0 +1,35 @@ +--- +uid: metadata-translation-editor +title: Metadata Translation Editor +author: Šarūnas Jučius +updated: 2023-04-18 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Metadata Translation Editor + +The **Metadata Translation Editor** provides an overview of the translated names, descriptions and display folders of translatable objects in the model. You can launch the Metadata Translation Editor through the **View** menu. Alternatively, if you only need to edit certain translations, select them in the **TOM Explorer** (hold down CTRL or SHIFT to multi-select), then right-click and choose **Show in metadata translation editor**. + +![Metadata Translation Editor](~/content/assets/images/metadata-translation-editor.png) + +Use the input fields in the metadata translation editor to quickly add/remove or edit translations of object names, descriptions and display folder names for the corresponding language. The first three columns in the editor allow you to change the default names, descriptions and display folder names of objects. You can use Undo (Ctrl+Z) and Redo (Ctrl+Y) the usual way. + +## Metadata Translation Editor toolbar + +While the Metadata Translation Editor is active, the accompanying toolbar provides the following options: + +- ![Metadata Translation Editor New Translation](~/content/assets/images/metadata-translation-editor-add-translation.png) **New translation**: This button adds a new translation to the model. The translation will be displayed in the Metadata Translation Editor. +- ![Metadata Translation Editor Hide Members](~/content/assets/images/perspective-editor-hide-members.png) **Show/Hide hidden objects**: Enable this option if you want to see all objects in the Metadata Translation Editor, including hidden objects. +- ![Metadata Translation Editor Hide Names](~/content/assets/images/metadata-translation-editor-name.png) **Show/Hide names**: Disable this option if you don't want to see the name translation columns in Metadata Translation Editor. +- ![Metadata Translation Editor Hide Descriptions](~/content/assets/images/metadata-translation-editor-description.png) **Show/Hide descriptions**: Disable this option if you don't want to see the description translation columns in Metadata Translation Editor +- ![Metadata Translation Editor Hide Display Folders](~/content/assets/images/perspective-editor-folder.png) **Show/Hide display folders**: Disable this option if you don't want to see the display folder translation columns in Metadata Translation Editor + +## Working with many translations + +If you're working on a model with many translations, it may be impractical to display all of them at once. You can rearrange the display order of translations in the Metadata Translation Editor, by dragging the column headers around, making it easier to compare translations side-by-side. Moreover, you can add/remove translations from the editor at any time, through the right-click context menu: + +![Metadata Translation Editor Columns](~/content/assets/images/metadata-translation-editor-columns-bands.png) \ No newline at end of file diff --git a/content/localization/zh/migrate-from-desktop_zh.md b/content/localization/zh/migrate-from-desktop_zh.md new file mode 100644 index 00000000..a0c50756 --- /dev/null +++ b/content/localization/zh/migrate-from-desktop_zh.md @@ -0,0 +1,236 @@ +--- +uid: migrate-from-desktop +title: Migrating from Power BI Desktop +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Migrating from Power BI Desktop + +If you are already familiar with data modeling concepts in Power BI Desktop, this article is intended to help you migrate your data modeling over to Tabular Editor. Thus, we assume you have a solid understanding of concepts such as the Power Query Editor, imported vs. calculated tables, calculated columns, measures, etc. + +## Power BI and Tabular Editor + +Historically, Tabular Editor was designed as a tool for SQL Server Analysis Services (Tabular) and Azure Analysis Services developer. When Power BI first launched, there was no supported way for third party tools to access the Analysis Services instance hosting the Power BI data model, and so the only way to create and edit a Power BI dataset, was through Power BI Desktop. + +This changed in March 2020, when [Microsoft announced the read/write XMLA endpoint in Power BI Premium](https://powerbi.microsoft.com/en-us/blog/announcing-read-write-xmla-endpoints-in-power-bi-premium-public-preview/). A few months later, it even became possible to use third party tools in conjunction with Power BI Desktop, with the [announcement of the External Tools feature](https://powerbi.microsoft.com/en-us/blog/announcing-public-preview-of-external-tools-in-power-bi-desktop/). + +The availability of the XMLA endpoint in Power BI Premium allows data model developers to leverage their existing skills and tools, and it is not a secret that Microsoft is investing heavily in making [Power BI Premium a superset of Analysis Services](https://community.powerbi.com/t5/Webinars-and-Video-Gallery/Power-BI-Premium-as-a-superset-of-Analysis-Services-the-XMLA/m-p/1434121). In other words, the integration of third party tools, community as well as commercial, with Power BI is something that is here to stay. In fact, Amir Netz, CTO of Microsoft Analytics, made a [joint statement](https://powerbi.microsoft.com/en-us/blog/community-tools-for-enterprise-powerbi-and-analysisservices/) with Marco Russo, founder of SQLBI, to affirm this point. + +Here at Tabular Editor ApS, we firmly believe that Tabular Editor 3 is the best tabular data modeling tool available right now, and thanks to the integrations mentioned above, the tool is no longer reserved for SQL Server or Azure Analysis Services developers. + +Before proceeding, it is important to understand that Tabular Editor can be used in conjunction with Power BI in two very different scenarios: + +- **Scenario 1:** Tabular Editor as an External Tool for Power BI Desktop. +- **Scenario 2:** Tabular Editor with the Power BI Premium XMLA Endpoint. + +> [!IMPORTANT] +> You cannot use Tabular Editor to directly load a .pbix file. For more information, see . + +### Scenario 1: Tabular Editor as an External Tool for Power BI Desktop + +Generally, this scenario is intended for self-service analysts and Power BI Desktop users without access to Power BI Premium, to make certain data modeling operations easier (for example, adding and editing measures), and to unlock advanced modeling options not otherwise available (calculation groups, perspectives and metadata translations). + +External tools connect to the Analysis Services model hosted by Power BI Desktop. This allows the tool to make certain changes to the data model. Currently, however, not all types of data modeling operations are supported by Power BI Desktop. It is important to understand this limitation and how Tabular Editor behaves when used as an external tool for Power BI Desktop. See for more information about this. + +The typical workflow in this scenario, is the following: + +1. Open a .pbit or .pbix file in Power BI Desktop +2. Launch Tabular Editor through the External Tools ribbon +3. Switch back and forth between Tabular Editor and Power BI Desktop, depending on what type of change you need to make. For example, you can add and edit measures through Tabular Editor, but you must use Power BI Desktop if you need to add a new table to the model. +4. Whenever you make a change in Tabular Editor, use **File > Save** (CTRL+S) to write the changes back to Power BI Desktop. +5. When you are done making changes, close Tabular Editor. Then, publish or save the report as usual from within Power BI Desktop. + +> [!NOTE] +> As of October 2021, there is a bug in Power BI Desktop that sometimes prevents Desktop from automatically refreshing the field list and visuals to reflect changes made through external tools. When this happens, saving the .pbix file and reopening it, or manually refreshing a table within the model, usually causes the field list and all visuals to update correctly. + +The [modeling limitations](xref:desktop-limitations) that apply to External Tools are only relevant regarding write operations/model modifications. You can still use Tabular Editor 3's connected features to browse the data within the model through table data previews, Pivot Grids or DAX queries, as described later in this guide. + +### Scenario 2: Tabular Editor with the Power BI Premium XMLA Endpoint + +This scenario is for BI professionals in organizations that use Power BI Premium Capacity or Power BI Premium-Per-User workspaces, who intend to replace Power BI Desktop altogether for purposes of dataset development. + +Essentially, the Power BI Premium XMLA Endpoint exposes an instance of Analysis Services (Tabular). In this scenario, Tabular Editor behaves no different than it would when connected to Azure Analysis Services or SQL Server Analysis Services (Tabular). + +The typical workflow in this scenario, is the following: + +1. When first migrating to Tabular Editor, use the XMLA endpoint to open a Power BI dataset in Tabular Editor, then save the model metadata as a file (Model.bim) or folder (Database.json). See @parallel-development for more information. +2. Going forward, open the model metadata in Tabular Editor from the file or folder you saved in step 1. Optionally use [workspace mode](xref:workspace-mode). +3. Apply changes using Tabular Editor. +4. If using workspace mode, changes should be immediately visible in the Power BI service every time you hit Save (CTRL+S) in Tabular Editor. +5. If not using workspace mode or when done making changes, use Tabular Editor's **Model > Deploy...** option to publish the changes to the Power BI service. + +As the model metadata "source of truth" in this scenario, is the file or folder structure stored on disk, this scenario not only enables parallel development with version control integration, but also continuous integration/continuous deployment (CI/CD) using an automated build server such as Azure DevOps. See for more information. + +> [!WARNING] +> As soon as you apply changes to a Power BI dataset through the Power BI service XMLA endpoint, that dataset can no longer be downloaded as a .pbix file. See [Dataset connectivity with the XMLA endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#power-bi-desktop-authored-datasets) for more information. + +When using Tabular Editor to connect to the dataset through the XMLA endpoint, there are no limitations to the types of write operations/model modifications that can be made. + +The remainder of this article focuses on differences between Power BI Desktop and Tabular Editor for data model development. Some sections only apply to scenario 2, due to the [modeling limitations](xref:desktop-limitations) that apply when using Tabular Editor as an external tool for Power BI Desktop (scenario 1). + +## Tabular Editor 3 user interface + +If you are new to Tabular Editor, we recommend reading through the following resources to understand Tabular Editor 3's user interface: + +- [Getting to know Tabular Editor 3's User Interface](xref:user-interface) +- [TOM Explorer view](xref:tom-explorer-view) +- [Properties view](xref:properties-view) +- [DAX editor](xref:dax-editor) + +## Tabular Editor 3 how-tos + +What follows is a quick walkthrough of how to achieve common tasks in Tabular Editor 3. + +### How to add a measure + +To add a new measure to your model, right-click on the table in the **TOM Explorer** on which you want the new measure to reside, then choose **Create > Measure** (shortcut ALT+1). After the measure is added, you can immediately type the name of the measure. + +![Add Measure](~/content/assets/images/add-measure.png) + +### How to rename a measure + +If you need to edit the name of the measure (or any other object), simply select the measure and hit F2 (or double-click the measure name). If multiple objects are selected, you will see the Batch rename dialog, that makes it easy to rename multiple objects in one go. + +![Batch Rename](~/content/assets/images/batch-rename.png) + +> [!WARNING] +> Changing object names in the data model may cause report visuals to stop working, if the visuals relies on one or more of the objects being renamed. External tools cannot access information about Power BI visuals, so Tabular Editor is not able to warn you before an object that is used in a visual is renamed or deleted. + +### How to create a copy of a measure + +In Tabular Editor 3, you can use the familiar Cut (CTRL+X), Copy (CTRL+C) and Paste (CTRL+V) operations to quickly move around and make copies of objects. You can also drag objects between tables and display folders using the **TOM Explorer**. If you make a mistake along the way, you can use the Undo (CTRL+Z) and Redo (CTRL+Y) options (repeatedly) to navigate back and forth through the history of changes applied. + +### How to modify the DAX expression of a measure + +Locate the measure you want to modify in the **TOM Explorer** and select it. You can toggle the display of hidden objects (CTRL+6) and display folders (CTRL+5) using the toolbar buttons near the top of the TOM Explorer. You may also type the partial name of the measure in the search box, to filter the **TOM explorer**. + +Once the measure is selected, you should see the DAX expression of the measure in the **Expression Editor** and various properties such as `Description`, `Format String`, `Hidden`, etc. in the **Properties** grid. + +![Modify Measure](~/content/assets/images/modify-measure.png) + +To modify the DAX expression, simply place the cursor in the **Expression Editor** and update the DAX code. Hit F6 to automatically format the code. If you select a different object in the TOM Explorer or click the green checkmark button **Expression > Accept** (F5), the expression change is stored locally in Tabular Editor. You can also cancel the modification you made by hitting the red "X", **Expression > Cancel**. If you accidentally hit **Accept**, you can always undo the change by using the **Edit > Undo** (CTRL+Z) option. + +To save your changes back to Power BI Desktop, the Power BI XMLA endpoint, or the file on disk from which the model was loaded, hit **File > Save** (CTRL+S). + +To learn more about the capabilities of the Expression Editor, when writing DAX code, see . + +### How to visualize dependencies between measures + +While a measure is selected in the **TOM Explorer** use the **Measure > Show dependencies** (SHIFT+F12) option. This causes a new window to pop up, visualizing the dependency tree of the DAX expression for that measure. You can switch between viewing both upstream and downstream dependencies. + +![Show Dependencies](~/content/assets/images/show-dependencies.png) + +Double-clicking on an item in the dependencies view navigate to that object in the **TOM Explorer**. + +### How to change the format string of a measure + +Locate the measure you want to modify in the **TOM Explorer** and select it. You can toggle the display of hidden objects (CTRL+6) and display folders (CTRL+5) using the toolbar buttons near the top of the TOM Explorer. You may also type the partial name of the measure in the search box, to filter the **TOM explorer**. + +Once the measure is selected, locate the `Format String` property in the **Properties** grid, expand it, and set the format string properties according to your preferences. Note the dropdown button at the right of the `Format` property. You may also freely enter a format string in the `Format String` property itself. + +![Format String](~/content/assets/images/format-string.png) + +### How to modify the DAX expression of multiple measures + +Tabular Editor 3 allows you to select multiple measures in order to create a **DAX Script**, which lets you modify the DAX expression and various properties of all selected measures at once. + +To create a DAX script based on existing measures, simply select the measures in the **TOM Explorer** (hold down the CTLR key to select multiple objects or hold down the SHIFT key to select a range of objects). Then, right click and hit **Script DAX**. + +![Script Dax](~/content/assets/images/script-dax.png) + +You can add or modify properties such as `Description`, `FormatString`, `Visible`, `DetailRows` and more directly in the script. + +Hit F5 to apply the script to the data model. Note that unlike the **Expression Editor**, navigating to a different object will not automatically apply any changes made to the script. You can still use the **Edit > Undo** (CTRL+Z) option to roll back any changes applied by a DAX script. + +See @dax-script-introduction for more information. + +### How to preview data in a table + +To view the contents of a table (similar to the Data Tab in Power BI Desktop), simply right-click on a table and choose "Preview data". This will open a new tab containing a preview of the table content. You can scroll through all rows of the table, as well as apply sorting or filtering to columns. Unlike Power BI Desktop, you can open as many of these preview tabs as you like and arrange them next to each other in the user interface. The preview also works for tables in [DirectQuery mode](https://docs.microsoft.com/en-us/power-bi/connect-data/desktop-use-directquery) (although the preview will be limited to the first 100 records). + +![Preview Data](~/content/assets/images/preview-data.png) + +> [!NOTE] +> The **Preview data** feature is only available when Tabular Editor is connected to Power BI Desktop or a dataset in the Power BI XMLA endpoint. + +See @refresh-preview-query for more information. + +### How to add a calculation group + +[Calculation Groups](https://docs.microsoft.com/en-us/analysis-services/tabular-models/calculation-groups?view=asallproducts-allversions) are useful for defining and reusing a modified DAX filter context or other type of business logic across all model measures. To add a calculation group using Tabular Editor, simply use the **Model > New Calculation Group** (ALT+7) option. + +![Add Calculation Group](~/content/assets/images/add-calc-group.png) + +Give the calculation group a name, then, while the Calculation Group is selected in the **TOM Explorer**, add new Calculation Items by using the **Calculation Group Table > Create > Calculation Item** option. You can copy (CTRL+C) and paste (CTRL+V) calculation items to speed up this process for additional items. + +![Add Calc Item](~/content/assets/images/add-calc-item.png) + +### How to add a new table + +To add a new table to a model, use the **Model > Import tables...** option. Tabular Editor's [Import Table Wizard](xref:importing-tables) will guide you through the process. + +> [!NOTE] +> Tabular Editor 3 does not support every data source otherwise supported by Power BI. If your model uses a data source not supported by Tabular Editor, the easiest way to import a new table from the same source is to copy an existing table in Tabular Editor (CTRL+C / CTRL+V), and then modify the partition expression and update the table schema as shown below. For this to work, make sure that the **Tools > Preferences > Schema Compare > Use Analysis Services for change detection** option is enabled. See for more information. + +> [!IMPORTANT] +> This option is not available by default when using Tabular Editor as an external tool, since adding/editing tables through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +See @importing-tables-data-modeling for more information. + +### How to modify a Power Query expression on a table + +Power Query (M) expressions that define what is loaded into each table reside in the corresponding table's **Partition**. The partitions can be located in the **TOM Explorer**. When selecting a partition, Tabular Editor displays the M expression for that partition in the **Expression Editor**, allowing you to edit it. After editing and accepting the expression change, you can right-click on the partition in the **TOM Explorer** and choose the **Update table schema...** option in order to detect if the columns imported on the table should be changed, based on the updated Power Query expression. + +![Power Query Update Schema](~/content/assets/images/power-query-update-schema.png) + +> [!NOTE] +> Currently, Tabular Editor 3 does not perform any validation of the partition expression. For Power Query (M) expressions, this is planned for a later update of Tabular Editor 3. + +> [!IMPORTANT] +> Partition expressions are read-only by default when using Tabular Editor as an external tool, since editing partitions through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +If the Power Query expression changes gives rise to any changes on the imported table columns, a dialog that lets you review these changes will show: + +![Apply schema changes](~/content/assets/images/combine-sourcecolumn-update.png) + +### How to modify a shared Power Query expression + +Shared Expressions are M queries that are not directly used to load data into a table. For example, when you create a Power Query parameter in Power BI Desktop, the M expression for this parameter is stored as a Shared Expression. In Tabular Editor, These can be accessed through the Shared Expressions folder of the **TOM Explorer** and edited just like M queries on partitions. + +![Shared Expression](~/content/assets/images/shared-expression.png) + +> [!IMPORTANT] +> Shared expressions are read-only by default when using Tabular Editor as an external tool, since editing partitions through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +### How to add relationships between tables + +The easiest way to add relationships between two tables is to create a new diagram, add the two tables to the diagram, and then visually dragging a column from one table to another, to indicate the columns that should participate in the relationship. This is similar to how you would create a relationship in Power BI Desktop. + +1. To create a new diagram use the **File > New > Diagram** option. +2. To add tables to the diagram, either drag and drop the tables from the **TOM Explorer** or use the **Diagram > Add tables...** option. +3. Once the tables are added, locate the column on the (many-side) fact table, and drag it over to the corresponding column on the (one-side) dimension table. +4. Confirm the relationship settings and hit "OK". + +![Shared Expression](~/content/assets/images/create-relationship-through-diagram.gif) + +See [Working with diagrams](xref:importing-tables-data-modeling#working-with-diagrams) for more information. + +> [!IMPORTANT] +> Relationships cannot be modified when using Tabular Editor as an external tool, since editing relationships through external tools is [not supported by Power BI Desktop](xref:desktop-limitations). + +### How to publish to the Power BI Service + +To publish or update a dataset in the Power BI Service, use the **Model > Deploy...** option and use the XMLA endpoint of the workspace, in which you want to publish the dataset. + +If you loaded the model metadata directly from the XMLA Endpoint, you only need to hit **File > Save** (CTRL+S), to update the dataset that was loaded in Tabular Editor. + +> [!NOTE] +> The **Model > Deploy...** option is **not** available in Tabular Editor 3 Desktop Edition, as this edition is only intended to be used as an External Tool for Power BI Desktop. [More information](xref:editions). + +## Next steps + +- +- @parallel-development +- @boosting-productivity-te3 +- \ No newline at end of file diff --git a/content/localization/zh/migrate-from-te2_zh.md b/content/localization/zh/migrate-from-te2_zh.md new file mode 100644 index 00000000..8dd21802 --- /dev/null +++ b/content/localization/zh/migrate-from-te2_zh.md @@ -0,0 +1,140 @@ +--- +uid: migrate-from-te2 +title: Migrating from Tabular Editor 2.x +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Migrating from Tabular Editor 2.x + +This article is intended for developers who already have some experience using Tabular Editor 2.x for Power BI Dataset or Analysis Services Tabular development. The article highlights similarities and important feature additions of Tabular Editor 3, to get you quickly up to speed. + +## Installation side-by-side + +Tabular Editor 3 has a different product code than Tabular Editor 2.x. This means that you can install both tools side-by-side without issues. In fact, the tools are installed into separate program folders and their settings are also kept in separate folders. In other words, the term "upgrade" or "downgrade" between Tabular Editor 2.x and Tabular Editor 3 does not apply. It is better to think of Tabular Editor 3 as an entirely different product. + +## Feature comparison + +In terms of features, Tabular Editor 3 is essentially a superset of Tabular Editor 2.x, with few exceptions. The table below compares all major features of the two tools: + +| | Tabular Editor 2.x | Tabular Editor 3 | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | --------------------------------------------------------- | +| Edit all TOM objects and properties | | | +| Batch editing and renaming | | | +| Copy/paste and drag/drop support | | | +| Undo/redo data modeling operations | | | +| Load/save model metadata to disk | | \* | +| Save-to-folder | | \* | +| [daxformatter.com](https://daxformatter.com) integration | | | +| Advanced data modeling (OLS, Perspectives, Calculation Groups, Metadata Translations, etc.) | | \* | +| Syntax highlighting and automatic formula fixup | | | +| View DAX dependencies between objects | | | +| Import Table Wizard | | | +| Deployment Wizard | | \* | +| Best Practice Analyzer | | | +| C# scripting and automation | | | +| Use as External Tool for Power BI Desktop | | | +| Connect to SSAS/Azure AS/Power BI Premium | | \* | +| Command-line interface | | _[Coming soon](xref:roadmap)_ | +| Premium, customizable user-interface with high-DPI, multi-monitor and theming support | | | +| World-class DAX editor with IntelliSenseTM-like features | | | +| Offline DAX syntax checking and column/data type inference | | | +| Improved Table Import Wizard and Table Schema Update check with Power Query support | | | +| DAX querying, table preview and Pivot Grids | | | +| Create diagrams for visualizing and editing table relationships | | | +| Execute data refresh operations in the background | | \* | +| C# macro recorder | | | +| Edit multiple DAX expressions in a single document using DAX scripting | | | +| [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/) integration | | | + +\***Note:** Limitations apply depending on which [edition](xref:editions) of Tabular Editor 3 you are using. + +## Feature differences + +Below is a summary of important feature differences. + +### User interface + +The first thing you will notice when launching Tabular Editor 3, is the new Visual Studio Shell-like interface. This interface is fully customizable, supports high-DPI, multiple monitors and even allows you to change the theming. All interface elements can be moved to different locations, so if you prefer the interface layout of Tabular Editor 2.x, immediately choose **Classic layout** from the **Window** menu. + +In general, though, interface elements that exist in Tabular Editor 2.x have the same name in Tabular Editor 3, so it should be relatively easy to navigate the new interface. A few important differences are listed below: + +- The **Advanced Scripting** tab in Tabular Editor 2.x is gone. In Tabular Editor 3, you instead create _C# Scripts_\* using the **File > New** menu. You are not limited to working on a single script at a time. In addition, **Custom actions** have been renamed to **Macros**. +- **Dynamic LINQ filtering** is not currently available within the TOM Explorer. Instead, if you want to find objects using [Dynamic LINQ](https://dynamic-linq.net/expression-language) you have to bring up the **Find and replace** dialog by pressing CTRL+F. +- If you close the **Expression Editor** you can bring it back by doubleclicking on the icon of an object in the **TOM Explorer**, or by choosing the **View > Expression Editor** menu option. +- When using the default layout in Tabular Editor 3, the **Best Practice Analyzer** will be located as a tab next to the **TOM Explorer**. Here, you will also find the new **Data Refresh** view (which lets you view the queue of background refresh operations) and the **Macros** view (which lets you manage any macros that was previously saved from C# scripts). +- Tabular Editor 3 displays all DAX syntax and semantic errors in the new **Messages View**. In the default layout, this is located at the bottom left of the interface. +- In addition, Tabular Editor 3 includes **VertiPaq Analyzer** (which you may be familiar with from [DAX Studio](https://daxstudio.org/)). +- As a final note, Tabular Editor 3 introduces the concept of **documents**, which is just a generic term for C# scripts, DAX scripts, DAX Queries, Diagrams, Data Previews and Pivot Grids. + +For more information, see . + +### New DAX editor and semantic capabilities + +Tabular Editor 3 features its very own DAX parsing engine (aka. the "semantic analyzer"), which means that the tool now understands the semantics of any DAX code in your model. This engine is also used to power our DAX editor (codename "Daxscilla"), to enable features such as syntax highligting, automatic formatting, code completion, calltips, refactoring and much more. Of course the editor is highly configurable, allowing you to tweak it to match your preferred DAX coding style. + +To learn more about the new DAX editor, see . + +In addition, the semantic analyzer continuously reports any DAX syntax or semantic errors across all objects in your model. This works even if not connected to Analysis Services and is lightning fast. The semantic analyzer also enabled Tabular Editor 3 to automatically infer data types from DAX expressions. In other words, Tabular Editor 3 automatically detects which columns would result from a calculated table expression. This is a big improvement over Tabular Editor 2.x, where you would have to manually map columns on a calculated table, or rely on Analysis Services to return the column metadata. + +### Table Import and Schema Update with Power Query support + +Another major advantage of Tabular Editor 3 over Tabular Editor 2.x is its support for structured data sources and Power Query (M) partitions. Specifically, the "Schema Update" feature now works for these types of data sources and partitions, and the Table Import Wizard can generate the necessary M code when importing new tables. + +The schema compare dialog itself also has a number of improvements, for example allowing you to easily map a column delete+column insert operation to a single column rename operation (and vice versa). There are also options for controlling how floating and decimal data types should be treated (for example, sometimes your data source may be using a floating point data type, but you may still want to import it always as a decimal type). + +To learn more, see . + +### Workspace mode + +Tabular Editor 3 introduces the concept of **workspace mode**, in which model metadata is loaded from disk (Model.bim or Database.json), and then immediately deployed to an Analysis Services instance of your choice. Whenever you hit Save (CTRL+S), the workspace database is synchronized and updated model metadata is saved back to the disk. The advantage of this approach, is that Tabular Editor is connected to Analysis Services, thus enabling the [connected features](#connected-features) listed below, while also making it easy to update the source files on disk. With Tabular Editor 2.x, you had to open a model from a database, and then remember to manually save to disk once in a while. + +This approach is ideal to enable [parallel development](xref:parallel-development) and model metadata integration with version control systems. + +For more information, see . + +### Connected features + +Tabular Editor 3 includes a number of new connected features, allowing you to use it as a client tool for Analysis Services. These features are enabled whenever Tabular Editor 3 is connected to Analysis Services, either directly or when using the [workspace mode](#workspace-mode) feature. + +The new connected features are: + +- Table data previewing +- PivotGrids +- DAX Querying +- Data refresh operations +- VertiPaq Analyzer + +### Diagrams + +One highly requested feature of Tabular Editor 2.x, was the ability to better visualize relationships between tables. With Tabular Editor 3, you can now create model diagrams. Each diagram is a simple JSON file that holds the names and coordinates of tables to be included in the diagram. Tabular Editor 3 then renders the tables and relationships and provides features for easily editing relationships, adding additional tables to the diagram based on existing relationships, etc. + +![Easily add related tables](~/content/assets/images/diagram-menu.png) + +See [Working with diagrams](xref:importing-tables-data-modeling#working-with-diagrams) for more information. + +### C# Scripts and Macro recorder + +The **Advanced Scripting** feature of Tabular Editor 2.x has carried over to Tabular Editor 3 as **C# Scripts**. One important difference in Tabular Editor 3 is that you are no longer limited to working with a single script. Instead, using the **File > New > C# Script** option, you can create and work with as many C# scripts as you need. Similar to Tabular Editor 2.x, these scripts can be saved as reusable actions that are integrated directly into the right-click context menu of the TOM Explorer. In Tabular Editor 3, we call these actions **Macros**, and you can even create your own menus and toolbars to which you can add macros. + +Most importantly, Tabular Editor 3 features a **Macro recorder** that you can use to automatically generate C# code from user interactions. + +To learn more, see @cs-scripts-and-macros. + +### DAX Scripting + +The last important feature you need to know about, when coming from Tabular Editor 2.x, is **DAX Scripting**. With this feature, you can create documents that allow you to edit the DAX expression and basic properties of several calculated objects at once. Calculated objects are measures, calculated columns, calculated tables, etc. + +This is very convenient when authoring complex business logic across several objects. By (multi)selecting objects in the TOM Explorer, right-clicking and choosing the **Script DAX** option, you get a new DAX script containing the definitions of all selected objects. The DAX script editor of course has all of the same DAX capabilities of the Expression Editor and the DAX query editor. + +When working in **connected** or **workspace** mode, DAX scripting is an incredibly powerful tool to quickly modify and test updated business logic, for example when using it in conjunction with a Pivot Grid as shown in the screenshot below. Simply hitting SHIFT+F5 causes the database to be updated based on the DAX expressions in the script, after which the Pivot Grid will immediately update. + +![Dax Scripting And Pivot](~/content/assets/images/dax-scripting-and-pivot.png) + +To learn more, see @dax-script-introduction. + +## Next steps + +- @migrate-from-vs +- @parallel-development +- @boosting-productivity-te3 diff --git a/content/localization/zh/migrate-from-vs_zh.md b/content/localization/zh/migrate-from-vs_zh.md new file mode 100644 index 00000000..c1d91379 --- /dev/null +++ b/content/localization/zh/migrate-from-vs_zh.md @@ -0,0 +1,211 @@ +--- +uid: migrate-from-vs +title: Migrating from Visual Studio +author: Daniel Otykier +updated: 2021-09-30 +--- + +# Migrating from Visual Studio / SQL Server Data Tools + +This article assumes that you are familiar with Tabular model development using [Analysis Services Projects for Visual Studio](https://marketplace.visualstudio.com/items?itemName=ProBITools.MicrosoftAnalysisServicesModelingProjects) (formerly known as SQL Server Data Tools). This is common among developers using SQL Server Analysis Services (Tabular) or Azure Analysis Services. + +- If you have never used Visual Studio for Tabular model development, you can safely skip this topic. +- If you previously used Tabular Editor 2.x for Tabular model development, we recommend you skip directly to the @migrate-from-te2 article. + +## Partial migration + +Tabular Editor 3 contains features that allow you to completely migrate away from Visual Studio for tabular model development. This is in contrast to Tabular Editor 2.x, where some users still preferred using Visual Studio for things like table import, visualization of relationships and preview of data. + +However, as you familiarize yourself with Tabular Editor 3, you might still find it useful to open your tabular models in Visual Studio from time to time. This is possible at any time, since Tabular Editor 3 does not modify the **Model.bim** file format (aka. the [TOM JSON](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions)) used by Visual Studio, thus ensuring compatibility with Visual Studio. + +The only exception is, if you decide to use Tabular Editor's [Save-to-folder](xref:parallel-development#what-is-save-to-folder) feature, as this file format is not supported by Visual Studio. However, you can easily recreate a Model.bim file for use with Visual Studio, using the **File > Save As...** option in Tabular Editor. The opposite conversion can also be performed by loading a Model.bim file in Tabular Editor and then using the **File > Save to Folder...** option. + +### Automating file format conversion + +If you often face the need to convert back and forth between Tabular Editor's (database.json) folder-based format and Visual Studio's (model.bim) file format, consider writing a small Windows command script using [Tabular Editor 2.x CLI](xref:command-line-options) to automate the conversion process. + +# [Model.bim to folder](#tab/frombim) + +To convert from model.bim to database.json (folder-based format): + +```cmd +tabulareditor.exe model.bim -F database.json +``` + +# [Folder to model.bim](#tab/fromfolder) + +To convert from database.json (folder-based format) to model.bim: + +```cmd +tabulareditor.exe database.json -B model.bim +``` + +*** + +> [!NOTE] +> The command line script above assumes you have [Tabular Editor 2.x](xref:getting-started-te2) installed. The installation location of Tabular Editor 2.x should also be specified as part of your [PATH environment variable](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/path). + +## Integrated Workspace server + +When starting a new Analysis Services (Tabular) project in Visual Studio, you are prompted to choose if you want to use Visual Studio's Integrated workspace server or provide your own instance of Analysis Services. In addition, you must decide the compatibility level of the tabular model (see screenshot below). + +![VS New Project](~/content/assets/images/vs-new-project.png) + +In contrast, when creating a new model in Tabular Editor, using a workspace server is completely optional (but recommended - see [workspace mode](xref:workspace-mode)). + +Below is the dialog box shown when creating a new model in Tabular Editor 3: + +![New model dialog](~/content/assets/images/new-model.png) + +If you enable the **Use workspace database** option, Tabular Editor will prompt you for an Analysis Services instance and database name that will be used as as workspace database while working on the model. If you do not enable this option, you will be able to create and work on your model in "offline" mode, which still allows you to add tables, relationships, author DAX expressions, etc. However, you will have to deploy your offline model to an instance of Analysis Services before you can refresh, preview and query the data in the model. + +> [!IMPORTANT] +> Tabular Editor 3 does not provide a feature equivalent to the **Integrated workspace** option of Visual Studio. Essentially, the integrated workspace is an Analysis Services instance managed by Visual Studio. Since Analysis Services is proprietary software from Microsoft, we cannot ship it alongside Tabular Editor 3. Instead, if you would like to run a local instance of Analysis Services for use with Tabular Editor, we recommend that you install [SQL Server Developer Edition](https://www.microsoft.com/en-us/sql-server/sql-server-downloads). + +### Compatibility level requirements + +Tabular Editor lets you choose the following compatibility levels for creating Analysis Services databases: + +- 1200 (Azure Analysis Services / SQL Server 2016+) +- 1400 (Azure Analysis Services / SQL Server 2017+) +- 1500 (Azure Analysis Services / SQL Server 2019+) + +In addition, Tabular Editor lets you choose compatibility levels suitable for Power BI datasets that will be deployed to the Power BI service through the [XMLA endpoint](xref:powerbi-xmla). + +> [!NOTE] +> Tabular Editor does not support compatibility levels below 1200, as these do not use the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) metadata format. If you plan on migrating development from Visual Studio to Tabular Editor for a model in compatibility level 1100 or 1103, **you must upgrade the compatibility level to at least 1200** before migrating to Tabular Editor. By doing so, you will no longer be able to deploy the model to SQL Server 2014 Analysis Services. + +## Visual Studio projects + +When creating an Analysis Services (Tabular) project in Visual Studio, a number of files are created in the project folder next to the Model.bim file. These files contain project- and user-specific information which is not related to the Tabular Object Model (TOM). The screenshot below shows the files resulting from creating a new tabular project in Visual Studio. + +![VS Project File Structure](~/content/assets/images/vs-file-structure.png) + +When migrating to Tabular Editor, you only need to bring the Model.bim file, as the concept of "project" does not exist here. Instead, Tabular Editor simply loads the model metadata directly from the Model.bim file. In some cases, a file called the [Tabular Model User Options (tmuo) file](xref:user-options) is created next to the Model.bim file. This file is used by Tabular Editor to store user- and model specific settings, such as whether or not to use a workspace database, (encrypted) user credentials for data sources, etc. + +To keep the "project" directory clean, we therefore recommend to copy the Model.bim file created by Visual Studio into a new directory, before loading the file in Tabular Editor. + +![Te File Structure](~/content/assets/images/te-file-structure.png) + +If you want to use the [Save-to-folder](xref:parallel-development#what-is-save-to-folder) feature, which is recommended for parallel development and integration with version control systems, now is the time to save the model as a folder from within Tabular Editor (**File > Save To Folder...**). + +![Te Folder Structure](~/content/assets/images/te-folder-structure.png) + +## Version control + +Tabular Editor does not have any integrated version control of model metadata. However, since all model metadata is stored as simple text (JSON) files on the disk, it is straightforward to include the tabular model metadata in any type of version control system. For this reason, most Tabular Editor users prefer to still keep Visual Studio installed, in order to have access to the [Visual Studio Team Explorer](https://docs.microsoft.com/en-us/azure/devops/user-guide/work-team-explorer?view=azure-devops) or, specifically for git, the new [Git Changes window](https://docs.microsoft.com/en-us/visualstudio/version-control/git-with-visual-studio?view=vs-2019) of Visual Studio 2019. + +> [!NOTE] +> These days, it seems that [git](https://git-scm.com/) is the preferred version control system by most developers. Git integration in Tabular Editor 3 is planned for a future update. + +Once you migrate to Tabular Editor, you do not need to keep the original Tabular model project and supporting files created by Visual Studio. You can still use the Visual Studio Team Explorer or Git Changes window to look at code changes, manage version control branches, perform code check-ins, merges, etc. + +Of course, most version control systems also have their own set of tools that you can use without relying on Visual Studio. For example, git has its command line and many popular tools that integrate directly with the Windows Explorer, such as [TortoiseGit](https://tortoisegit.org/). + +### Save-to-folder and version control + +The main advantage of using the [Save-to-folder](xref:parallel-development#what-is-save-to-folder) option, is that the model metadata is broken out into multiple small files, instead of storing everything in a large JSON document. Many properties in the TOM are arrays of objects (for example tables, measures and columns). Since all such objects have explicit names, their order in the array does not matter. Sometimes it happens that the order is changed during serialization to JSON, and this causes most version control system to indicate that a change was made to the file. However, since this ordering does not have any semantic meaning, we should not bother handling merge conflicts that may arise from this type of change. + +With Save-to-folder serialization, the number of arrays used in the JSON files are greatly reduced, as objects that would otherwise be stored as arrays, are now broken out into individual files stored within a subfolder. When Tabular Editor loads the model metadata from disk, it traverses all these subfolders to ensure all objects are deserialized correctly into the TOM. + +As such, Save-to-folder serialization greatly reduces the chance that merge conflicts are ever encountered, when two or more developers make parallel changes to the same tabular model. + +## UI differences + +This section lists the most important differences between the user interfaces of Tabular Editor 3 and Visual Studio for tabular model development. If you are an avid Visual Studio user, you should feel quite comfortable with Tabular Editor 3's user interface. If you would like a more detailed walkthrough, please see . + +### Tabular Model Explorer vs. TOM Explorer + +In Visual Studio, a hierarchical overview of the model metadata can be found in the **Tabular Model Explorer**. + +![Vs Tom Explorer](~/content/assets/images/vs-tom-explorer.png) + +In Tabular Editor, this is called the **TOM Explorer** view. In Tabular Editor, all data modeling generally revolves around locating the relevant objects in the TOM Explorer and then performing certain actions by invoking the right-click context menu, by navigating to the main menu, or by editing object properties in the **Properties** view. In Tabular Editor, you can use intuitive operations such as multi-select, drag-drop, copy-paste and undo-redo for all data modeling operations. + +![Vs Tom Explorer](~/content/assets/images/tom-explorer.png) + +The TOM Explorer in Tabular Editor also has shortcut options for showing/hiding certain types of objects, hidden objects, display folders, and for quickly searching and filtering the metadata hierarchy. + +See @tom-explorer-view for more information. + +### Property Grid + +Both Visual Studio and Tabular Editor include a property grid that allows you to edit most object properties of whatever object is currently selected. Below is a comparison between the Visual Studio property grid (left) and the Tabular Editor property grid (right) for the same measure: + +![Property grid in Visual Studio and Tabular Editor](~/content/assets/images/property-grid-vs-te.png) + +The two generally work the same way, except that Tabular Editor uses property names that are closely aligned with the TOM object properties. Tabular Editor also adds a number of properties that are not found in the TOM, to make certain modeling operations easier. For example, by expanding the **Translated Names** property, you can compare and edit object name translations across all model cultures. + +### Editing DAX expressions + +In Visual Studio, you can use the formula bar or open a DAX editor window by right-clicking on a measure in the Tabular Model Explorer and choosing "Edit formula". + +Tabular Editor works quite similar, with the formula bar being replaced by the **Expression Editor** view. In addition, if you want to edit the DAX expressions for one or more objects in a standalone document, you can right-click on those objects (measures, calculated columns, calculated tables), and choose **Script DAX**. + +The DAX code editor in Tabular Editor 3 is one of the main reasons for using the tool. You can read more about it [here](xref:dax-editor). + +### Error List vs. Messages View + +In Visual Studio, DAX syntax errors are shown as warnings within the **Error List** (see screenshot below). In addition, measures that have errors are indicated with a warning triangle in the measures grid. + +![Vs Error List](~/content/assets/images/vs-error-list.png) + +In Tabular Editor, we use the Messages View to consolidate all error, warning and informational messages posted by different sources during model development. Specifically for DAX syntax errors, these are shown as errors in the Messages View, and any measures that have an error are indicated with a red dot in the TOM Explorer (see screenshot below). + +![Te Messages](~/content/assets/images/te-messages.png) + +In the screenshot above, notice how there are three different message-posting sources: + +- **Analysis Services**: When metadata changes are saved to a connected instance of Analysis Services, the server updates the TOM metadata to indicate if any objects are in an erroneous state. Specifically, the [State](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.measure.state?view=analysisservices-dotnet#Microsoft_AnalysisServices_Tabular_Measure_State) and [ErrorMessage](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.measure.errormessage?view=analysisservices-dotnet#Microsoft_AnalysisServices_Tabular_Measure_ErrorMessage) properties are updated. Tabular Editor displays these error messages in the Messages View. These messages are not shown when Tabular Editor is used offline (i.e. without a connection to Analysis Services). +- **Tabular Editor Semantic Analysis**: In addition, Tabular Editor 3 performs its own semantic analysis of all DAX expressions in the model. Any syntax or semantic errors encountered are reported here. +- **Expression Editor**: Lastly, if any documents are open in Tabular Editor 3, such as the Expression Editor, any DAX syntax or semantic errors encountered in the document are reported here. + +### Previewing table data + +In Visual Studio, tables and their content are displayed in a tabbed view once you load the Model.bim file. In Tabular Editor 3, you can preview table data by right-clicking on a table in the TOM Explorer, and chooseing **Preview Data**. This opens a new document tab that lets you scroll through all rows of the table, as well as filter and sort the columns. It even works for model using DirectQuery! + +Also, you can freely rearrange the documents, to view the content of several tables at once (see screenshot below). + +![Te3 Table Preview](~/content/assets/images/te3-table-preview.png) + +### Importing tables + +To import new tables with Tabular Editor 3, use the **Model > Import tables...** option. This launches Tabular Editor 3's Import Table Wizard, which guides you through the process of connecting to a data source and selecting tables to import. The process is relatively similar to the legacy table import in Visual Studio. + +One important difference is that Tabular Editor 3 does not include a visual Power Query Editor. You can still edit Power Query (M) expressions as text, but if your model relies heavily on complex data transformation expressed as Power Query queries, you should consider to keep using Visual Studio for purposes of editing the Power Query queries. + +> [!NOTE] +> Performing complex data transformations using Power Query is generally not recommended for enterprise data modeling, due to the increased overhead of data refresh operations. Instead, prepare your data into a star schema using other ETL tools, and store the star schema data in a relational database, such as SQL Server or Azure SQL Database. Then, import tables to your tabular model from that database. + +#### Editing partitions and updating table schema + +In Tabular Editor 3, you can update the schema of a table without forcing a table refresh. Partitions are displayed in the TOM Explorer as individual objects. Click on a partition to edit its expression (M or SQL) in the Expression Editor. + +Once a partition expression has been updated, Tabular Editor can automatically detect if the table schema resulting from the updated expression, is different from the set of columns defined in the model. To perform a schema update, right-click on the partition or table in the TOM Explorer and choose **Update table schema...**. + +For more information about table import and schema updates, see @importing-tables. + +### Visualizing relationships + +Visual Studio includes a diagram tool that lets you visualize and create relationships between tables. + +Tabular Editor 3 also includes a diagram tool, that can be accessed using **File > New > Diagram**. A new diagram document tab will be created, at which point you can add tables from the TOM Explorer by dragging and dropping, or from the **Diagram > Add tables...** menu. + +Once tables have been added to the diagram, you can create relationship between columns simply by dragging from one column to another. + +![Te3 Diagram View](~/content/assets/images/te3-diagram-view.png) + +> [!NOTE] +> For performance reasons, the diagram tool does not inspect the data of the model, nor does it validate the uniqueness or directionality of any relationships you create. It is up to you to ensure that relationships are created correctly. If a relationship has been incorrectly defined, Analysis Services will return an error state which is shown in the **Messages View**. + +### Model deployment + +Tabular Editor lets you easily deploy the model metadata to any instance of Analysis Services. You can invoke Tabular Editor's Deployment Wizard under **Model > Deploy...** or by hitting CTRL+SHIFT+D. + +For more information, see . + +## Next steps + +- @migrate-from-te2 +- @parallel-development +- @boosting-productivity-te3 \ No newline at end of file diff --git a/content/localization/zh/new-as-model_zh.md b/content/localization/zh/new-as-model_zh.md new file mode 100644 index 00000000..1108e338 --- /dev/null +++ b/content/localization/zh/new-as-model_zh.md @@ -0,0 +1,125 @@ +--- +uid: new-as-model +title: Create an Analysis Services Model +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Creating your first Analysis Services Model + +This page walks you through the process of creating a new Analysis Services tabular model from scratch using Tabular Editor 3. + +> [!NOTE] +> Tabular Editor 3 Business Edition is limited to [SQL Server Standard Edition](https://docs.microsoft.com/en-us/analysis-services/analysis-services-features-supported-by-the-editions-of-sql-server-2016?view=asallproducts-allversions#tabular-models) and [Azure Analysis Services Basic Tier](https://docs.microsoft.com/en-us/azure/analysis-services/analysis-services-overview#basic-tier). Note that certain modeling features are not supported at these tiers. + +##### Creating a new model + +- From the File menu, choose New > Model... or hit `CTRL+N` + +![New model](https://user-images.githubusercontent.com/8976200/116813646-02a6fc80-ab55-11eb-89b0-8909b768ce7e.png) + +- Provide a name for your model or use the default value. Then, choose the compatibility level depending on which version of Analysis Services you are targetting. Your options are the following: + - 1200 (Works with SQL Server 2016 or newer, and Azure Analysis Services) + - 1400 (Works with SQL Server 2017 or newer, and Azure Analysis Services) + - 1500 (Works with SQL Server 2019 or Azure Analysis Services) +- For the best development experience, check the "Use workspace database" option. This requires that you have an instance of Analysis Services available on which your workspace database will be deployed. This could be a local or a remote instance of SQL Server Analysis Services or it could be an instance of Azure Analysis Services. When you click OK, you will be prompted to enter the connection string for the Analysis Services instance in which you want the workspace database created. + + [Learn more about workspace databases](xref:workspace-mode). + +> [!NOTE] +> With a workspace database, you can validate Power Query (M expressions) and import table schema from Power Query expressions. You can also refresh and query data in the workspace database, making it easier to debug and test your DAX expressions. + +Once your model is created, the next step is to add a data source and some tables. + +#### Adding a data source and tables + +Before you can import data to your tabular model, you have to set up one or more data sources. Locate the TOM Explorer, right-click on the "Data Sources" folder and choose "Create". For a model that uses compatibility level 1400 or higher, we have two options: Legacy and Power Query data sources. To learn more about th differences between these two types of data sources, [consult the Microsoft Analysis Services blog](https://docs.microsoft.com/en-us/archive/blogs/analysisservices/using-legacy-data-sources-in-tabular-1400). + +![Add data source](https://user-images.githubusercontent.com/8976200/124598010-72db4280-de64-11eb-818a-e5793f061185.png) + +In this example, we will create a Power Query data source, which we will use to import a few tables from a SQL Server relational database. Once the data source is created, hit F2 to rename it and configure the data source using the Propery Grid as seen in the screenshot below: + +![Set data source properties](https://user-images.githubusercontent.com/8976200/124599856-71ab1500-de66-11eb-8ede-3a6272872734.png) + +In our example, we set the following properties: + +| Property | Value | +| ------------------ | ---------------------- | +| Name | `AdventureWorks` | +| Protocol | `tds` | +| Database | `AdventureWorksDW2017` | +| Server | `localhost` | +| AuthenticationKind | `ServiceAccount` | + +Hit Save (Ctrl+S). You will be prompted to provide a path and file name for the Model.bim file which will hold the model metadata that you have created so far. You may also save the model as a folder structure instead (File > Save to folder...), which is recommended if you plan to integrate your model metadata into a version controlled environment. If you are using a Workspace Database, Tabular Editor 3 will also synchronize the metadata to the connected instance of Analysis Services. + +Next, add a new table to the model by right-clicking on the "Tables" folder and choosing "Create > Table" (you can also hit Alt+5). Give the table a name, in our example `Internet Sales`. Expand the table, locate the partition on the table and provide the following M query as the partition expression, in order to populate the table with data: + +```M +let + Source = #"AdventureWorks", + Data = Source{[Schema="dbo",Item="FactInternetSales"]}[Data] +in + Data +``` + +This assumes that the relational SQL Server database contains a table named "FactInternetSales" within the "dbo" schema. + +![M partition expression](https://user-images.githubusercontent.com/8976200/124601212-dd41b200-de67-11eb-9720-3890d7d746ba.png) + +Next, right-click on the newly created table and choose "Update table schema...". This allows Tabular Editor to automatically populate the table columns based on the partition query. + +> [!NOTE] +> If you are not using a Workspace Database, this operation is only available in Tabular Editor version 3.1.0 or newer. + +![Schema compare](https://user-images.githubusercontent.com/8976200/124601333-0104f800-de68-11eb-94f7-654c9e8ff206.png) + +Hit "OK" to add the columns to the table. Hit Save again (Ctrl+S). If you are using a Workspace Database, you may refresh the table on the server and browse the data in the table once the refresh operation is complete. To do so, right-click the table and choose "Refresh table > Automatic (table)". Wait for the operation on the "Data Refresh" tab to complete, then right-click the table and choose "Preview" (you can do so from the TOM Explorer as well), to view the actual data within the table: + +![Data refresh](https://user-images.githubusercontent.com/8976200/124602234-f0a14d00-de68-11eb-8886-dc7e0d255f9a.png) + +If the table you imported is a dimension table, we recommend setting the "Key" property of the primary key column on the table, to "true". This makes it easier to define relationships between this and other tables, as we shall see later. + +Repeat this process for any table you wish to import to your Tabular model. You don't have to refresh the data in each table one by one - instead, you can run the refresh operation at the model level. + +#### Defining relationships + +Once you have imported a number of tables, the easiest way to define the relationships between them with Tabular Editor 3, is to create a new diagram. Choose "File > New > Diagram". Then, multi-select and drag the tables into the diagram view or right-click on the tables and choose "Add to diagram": + +![Add to diagram](https://user-images.githubusercontent.com/8976200/124602823-8a68fa00-de69-11eb-9332-09ad42c4f1b3.png) + +To create a relationship between two tables, locate the foreign key column on the fact table and "drag" that column to the primary key column on the dimension table. Hit "OK" to confirm the relationship settings in the dialog that appears. + +![Diagram view](https://user-images.githubusercontent.com/8976200/124604764-8f2ead80-de6b-11eb-88d0-c9cebbca57d0.png) + +Close the diagram view (no need to save it, as you can always reconstruct the diagram later). Hit Ctrl+S once again to save the model. Now it's time to add some business logic. If you're using a Workspace Database, now is a good time to execute a refresh (automatic or calculate) at the model level, to ensure that the supporting structures for the relationships are created on the server, thus bringing the model into a queryable state. + +#### Adding measures + +Select one of the tables in the TOM Explorer and hit Alt+1 (or choose Create > New Measure) to add a measure to that table. Give the measure a name and provide a DAX expression for the measure. + +![Add measure](https://user-images.githubusercontent.com/8976200/124605349-19771180-de6c-11eb-94be-7baf8b5e0ee9.png) + +Hit Ctrl+S to save the model metadata. + +If you're using a Workspace Database, you can now test your new measure directly inside Tabular Editor 3. The easiest way to test it is by using a Pivot Grid. Choose File > New > Pivot Grid, then drag the newly created measure from the TOM Explorer into the grid. You can also drag columns and hierarchies from the TOM Explorer into the Filter, Row or Column area of the Pivot Grid, to slice your measure by different dimension attributes: + +![Pivot Grid](https://user-images.githubusercontent.com/8976200/124605906-ae7a0a80-de6c-11eb-985d-6fd580ed81d1.png) + +If you didn't use a Workspace Database, you will have to deploy your model to an instance of Analysis Services, before you can perform data refreshes and query the model. + +#### Deploying the data model + +To deploy the model metadata to any instance of Analysis Services, click on the "Model" menu and choose "Deploy...". This brings up the Tabular Editor 3 Deployment Wizard which is similar to the Deployment Wizard of Tabular Editor 2.X. Follow the instructions on the various pages of the wizard, to deploy the model metadata to an instance of Analysis Services. You can also use the Deployment Wizard to generate a TMSL/XMLA script, that can be handed over to an Analysis Services server administrator for manual deployment. + +![Deployment](https://user-images.githubusercontent.com/8976200/124607262-f5b4cb00-de6d-11eb-8139-4f74b5ae19bf.png) + +To refresh and test the deployed database, you can use the standard management and client tools provided by Microsoft, or you can use another instance of Tabular Editor 3 (assuming you have administrative access on the instance of Analysis Services where the deployed model resides). + +The paragraph above provides a good reason for using the Workspace Database approach described above. When connected to a workspace database, you will be able to perform all development operations, including data refresh and testing of business logic within the same instance of Tabular Editor 3, without having to rely on other tools. diff --git a/content/localization/zh/new-pbi-model_zh.md b/content/localization/zh/new-pbi-model_zh.md new file mode 100644 index 00000000..0b085310 --- /dev/null +++ b/content/localization/zh/new-pbi-model_zh.md @@ -0,0 +1,35 @@ +--- +uid: new-pbi-model +title: Create a Power BI Semantic Model +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# (Tutorial) Creating your first Power BI semantic model + +This page walks you through the process of creating a new Power BI semantic model from scratch using Tabular Editor 3. + +> [!IMPORTANT] +> Tabular Editor 3 Business Edition is limited to [Power BI Premium Per User](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-per-user-faq). For Power BI Premium or Embedded capacity, you must upgrade to Tabular Editor 3 Enterprise Edition. In either case, the Power BI workspace in which the semantic model is to be deployed, must have its [XMLA read/write endpoint enabled](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#enable-xmla-read-write). +> +> Tabular Editor 3 Desktop Edition does not have any support for Power BI semantic models. +> +> [More information](xref:editions). + +##### Creating a new semantic model + +1. From the File menu, choose New > Model... or hit `CTRL+N` + +![New model](~/content/assets/images/new-pbi-model.png) + +- Provide a name for your model or use the default value. Then, set the compatibility level to "1609 (Power BI / Fabric)". +- For the best development experience, check the "Use workspace database" option. This requires that you have a development workspace available in Power BI, with XMLA read/write enabled. When you click OK, you will be prompted to enter the connection string for the Power BI workspace in which you want the workspace database created. + +> [!NOTE] +> With a workspace database, you can validate Power Query (M expressions) and import table schema from Power Query expressions. You can also refresh and query data in the workspace database, making it easier to debug and test your DAX expressions. diff --git a/content/localization/zh/optimizing-workflow-workspace-mode_zh.md b/content/localization/zh/optimizing-workflow-workspace-mode_zh.md new file mode 100644 index 00000000..cd7bc408 --- /dev/null +++ b/content/localization/zh/optimizing-workflow-workspace-mode_zh.md @@ -0,0 +1,22 @@ +--- +uid: optimizing-workflow-workspace-mode +title: Optimizing development workflow using Workspace Mode +author: Daniel Otykier +updated: 2021-10-05 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Optimizing development workflow using Workspace Mode + +[!include[workspace-mode](~/content/te3/workspace-mode.partial.md)] + +# Next steps + +- @powerbi-cicd +- @as-cicd +- @boosting-productivity-te3 \ No newline at end of file diff --git a/content/localization/zh/parallel-development_zh.md b/content/localization/zh/parallel-development_zh.md new file mode 100644 index 00000000..4ca33fa4 --- /dev/null +++ b/content/localization/zh/parallel-development_zh.md @@ -0,0 +1,187 @@ +--- +uid: parallel-development +title: Enabling parallel development using Git and Save to Folder +author: Daniel Otykier +updated: 2021-09-30 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Enabling parallel development using Git and Save to Folder + +
    + +This article describes the principles of parallel model development (that is, the ability for multiple developers to work in parallel on the same data model) and the role of Tabular Editor in this regard. + +# Prerequisites + +- The destination of your data model must be one of the following: + - SQL Server 2016 (or newer) Analysis Services Tabular + - Azure Analysis Services + - Power BI Premium Capacity/Power BI Premium-per-user with [XMLA read/write enabled](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#enable-xmla-read-write) +- Git repository accessible by all team members (on-premises or hosted in Azure DevOps, GitHub, etc.) + +# TOM as source code + +Parallel development has traditionally been difficult to implement on Analysis Services tabular models and Power BI datasets (in this article, we will call both types of models "tabular models" for brevity). With the introduction of the JSON-based model metadata used by the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions), integrating model metadata in version control has certainly become easier. + +The use of a text-based file format makes it possible to handle conflicting changes in a graceful way, by using various diff tools that are often included with the version control system. This type of change conflict resolution is very common in traditional software development, where all of the source code resides in a large number of small text files. For this reason, most popular version control systems are optimized for these types of files, for purposes of change detection and (automatic) conflict resolution. + +For tabular model development, the "source code" is our JSON-based TOM metadata. When developing tabular models with earlier versions of Visual Studio, the Model.bim JSON file was augmented with information about who modified what and when. This information was simply stored as additional properties on the JSON objects throughout the file. This was problematic, because not only was the information redundant (since the file itself also has metadata that describes who the last person to edit it was, and when the last edit happened), but from a version control perspective, this metadata does not hold any _semantic meaning_. In other words, if you were to remove all of the modification metadata from the file, you would still end up with a perfectly valid TOM JSON-file, that you could deploy to Analysis Services or publish to Power BI, without affecting the functionality and business logic of the model. + +Just like source code for traditional software development, we do not want this kind of information to "contaminate" our model metadata. Indeed, a version control system gives a much more detailed view of the changes that were made, who made them, when and why, so there is no reason to include it as part of the files being versioned. + +When Tabular Editor was first created, there was no option to get rid of this information from the Model.bim file created by Visual Studio, but that has luckily changed in more recent versions. However, we still need to deal with a single, monolithic file (the Model.bim file) containing all of the "source code" that defines the model. + +Power BI dataset developers have it much worse, since they do not even have access to a text-based file containing the model metadata. The best they can do is export their Power BI report as a [Power BI Template (.pbit) file](https://docs.microsoft.com/en-us/power-bi/create-reports/desktop-templates#creating-report-templates) which is basically a zip file containing the report pages, the data model definitions and the query definitions. From the perspective of a version control system, a zip file is a binary file, and binary files cannot be diff'ed, compared and merged, the same way text files can. This forces Power BI developers to use 3rd party tools or come up with elaborate scripts or processes for properly versioning their data models - especially, if they want to be able to merge parallel tracks of development within the same file. + +Tabular Editor aims to simplify this process by providing an easy way to extract only the semantically meaningful metadata from the Tabular Object Model, regardless of whether that model is an Analysis Services tabular model or a Power BI dataset. Moreover, Tabular Editor can split up this metadata into several smaller files using its Save to Folder feature. + +# What is Save to Folder? + +As mentioned above, the model metadata for a tabular model is traditionally stored in a single, monolithic JSON file, typically named **Model.bim**, which is not well suited for version control integration. Since the JSON in this file represents the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions), it turns out that there is a straight forward way to break the file down into smaller pieces: The TOM contains arrays of objects at almost all levels, such as the list of tables within a model, the list of measures within a table, the list of annotations within a measure, etc. When using Tabular Editor's **Save to Folder** feature, these arrays are simply removed from the JSON, and instead, a subfolder is generated containing one file for each object in the original array. This process can be nested. The result is a folder structure, where each folder contains a set of smaller JSON files and subfolders, which semantically contains exactly the same information as the original Model.bim file: + +![Save To Folder](~/content/assets/images/save-to-folder.png) + +The names of each of the files representing individual TOM objects are simply based on the `Name` property of the object itself. The name of the "root" file is **Database.json**, which is why we sometimes refer to the folder-based storage format as simply **Database.json**. + +## Pros of using Save to Folder + +Below are some of the advantages of storing the tabular model metadata in this folder based format: + +- **Multiple smaller files work better with many version control systems than few large files.** For example, git stores snapshots of modified files. For this reason alone, it makes sense why representing the model as multiple smaller files is better than storing it as a single, large file. +- **Avoid conflicts when arrays are reordered.** Lists of tables, measures, columns, etc., are represented as arrays in the Model.bim JSON. However, the order of objects within the array does not matter. It is not uncommon for objects to be reordered during model development, for example due to cut/paste operations, etc. With Save to Folder, array objects are stored as individual files, so the arrays are no longer change tracked, reducing the risk of merge conflicts. +- **Different developers rarely change the same file.** As long as developers work on separate parts of the data model, they will rarely make changes to the same files, reducing the risk of merge conflicts. + +## Cons of using Save to Folder + +As it stands, the only disadvantage of storing the tabular model metadata in the folder based format, is that this format is used exclusively by Tabular Editor. In other words, you can not directly load the model metadata into Visual Studio from the folder based format. Instead, you would have to temporarily convert the folder based format to the Model.bim format, which can of course be done using Tabular Editor. + +## Configuring Save to Folder + +One size rarely fits all. Tabular Editor has a few configuration options that affect how a model is serialized into the folder structure. In Tabular Editor 3, you can find the general settings under **Tools > Preferences > Save-to-folder**. Once a model is loaded in Tabular Editor, you can find the specific settings that apply to that model under **Model > Serialization options...**. The settings that apply to a specific model are stored as an annotation within the model itself, to ensure that the same settings are used regardless of which user loads and saves the model. + +![Configuring Save To Folder](~/content/assets/images/configuring-save-to-folder.png) + +### Serialization settings + +- **Use recommended settings**: (Default: checked) When this is checked, Tabular Editor uses the default settings when saving a model as a folder structure for the first time. +- **Serialize relationships on from-tables**: (Default: unchecked) When this is checked, Tabular Editor stores relationships as an annotation on the table at the "from-side" (typically the fact table) of the relationship, instead of storing them at the model level. This is useful when in the early development phase of a model, where table names are still subject to change quite often. +- **Serialize perspective membership info on objects**: (Default: unchecked) When this is checked, Tabular Editor stores information about which perspectives an object (table, column, hierarchy, measure) belongs to, as an annotation on that object, instead of storing the information at the perspective level. This is useful when object names are subject to change, but perspective names are finalised. +- **Serialize translations on translated objects**: (Default: unchecked) When this is checked, Tabular Editor stores metadata translations as an annotation on each translatable object (table, column, hierarchy, level, measure, etc.), instead of storing the translations at the culture level. This is useful when object names are subject to change. +- **Prefix file names sequentially**: (Default: unchecked) In cases where you want to retain the metadata ordering of array members (such as the order of columns in a table), you can check this to have Tabular Editor prefix the filenames with a sequential integer based on the object's index in the array. This is useful if you use the default drillthrough feature in Excel, and would like [columns to appear in a certain order in the drillthrough](https://github.com/TabularEditor/TabularEditor/issues/46#issuecomment-297932090). + +> [!NOTE] +> The main purpose of the settings described above, is to reduce the number of merge conflicts encountered during model development, by adjusting how and where certain model metadata is stored. In the early phases of model development, it is not uncommon for objects to be renamed often. If a model already has metadata translations specified, every object rename would cause at least two changes: One change on the object being renamed, and one change for every culture that defines a translation on that object. When **Serialize translations on translated objects** is checked, there would only be a change on the object being renamed, as that object also includes the translated values (since this information would be stored as an annotation). + +### Serialization depth + +The checklist allows you to specify which objects will be serialized as individual files. Note that some options (perspectives, translations, relationships) may not be available, depending on the settings specified above. + +In most cases, it is recommended to always serialize objects to the lowest level. However, there may be special cases where this level of detail is not needed. + +# Power BI and version control + +As mentioned above, integrating a Power BI report (.pbix) or Power BI template (.pbit) file in version control, does not enable parallel development or conflict resolution, due to these files using a binary file format. At the same time, we have to be aware of the current limitations of using Tabular Editor (or other third party tools) with Power BI Desktop or the Power BI XMLA endpoint respectively. + +These limitations are: + +- When using Tabular Editor as an external tool for Power BI Desktop, [not all modeling operations are supported](xref:desktop-limitations). +- Tabular Editor can extract model metadata from a .pbix file loaded in Power BI Desktop, or directly from a .pbit file on disk, but there is **no supported way to update model metadata in a .pbix or .pbit file outside of Power BI Desktop**. +- Once any changes are made to a Power BI dataset through the XMLA endpoint, [that dataset can no longer be downloaded as a .pbix file](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#power-bi-desktop-authored-datasets). + +To enable parallel development, we must be able to store the model metadata in one of the text-based (JSON) formats mentioned above (Model.bim or Database.json). There is no way to "recreate" a .pbix or .pbit file from the text-based format, so **once we decide to go this route, we will no longer be able to use Power BI Desktop for editing the data model**. Instead, we will have to rely on tools that can use the JSON-based format, which is exactly the purpose of Tabular Editor. + +> [!WARNING] +> If you do not have access to a Power BI Premium workspace (either Premium capacity or Premium-Per-User), you will not be able to publish the model metadata stored in the JSON files, since this operation requires access to the [XMLA endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools). + +> [!NOTE] +> Power BI Desktop is still needed for purpose of creating the visual part of the report. It is a [best practice to always separate reports from models](https://docs.microsoft.com/en-us/power-bi/guidance/report-separate-from-model). In case you have an existing Power BI file that contains both, [this blog post](https://powerbi.tips/2020/06/split-an-existing-power-bi-file-into-a-model-and-report/) ([video](https://www.youtube.com/watch?v=PlrtBm9YN_Q)) describes how to split it into a model file and a report file. + +# Tabular Editor and git + +Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. It is the most popular version control system right now, and it is available through multiple hosted options, such as [Azure DevOps](https://azure.microsoft.com/en-us/services/devops/repos/), [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/) and others. + +A detailed description of git is outside the scope of this article. There are, however, many resources available online if you want to learn more. We recommend the [Pro Git](https://git-scm.com/book/en/v2) book for reference. + +> [!NOTE] +> Tabular Editor 3 does not currently have any integration with git or other version control systems. To manage your git repository, commit code changes, create branches, etc., you will have to use the git command line or another tool, such as the [Visual Studio Team Explorer](https://docs.microsoft.com/en-us/azure/devops/user-guide/work-team-explorer?view=azure-devops#git-version-control-and-repository) or [TortoiseGit](https://tortoisegit.org/). + +As mentioned earlier, we recommend using Tabular Editor's [Save to Folder](#what-is-save-to-folder) option when saving model metadata to a git code repository. + +## Branching strategy + +What follows is a discussion of branching strategies to employ when developing tabular models. + +The branching strategy will dictate what the daily development workflow will be like, and in many cases, branches will tie directly into the project methods used by your team. For example, using the [agile process within Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/boards/work-items/guidance/agile-process-workflow?view=azure-devops), your backlog would consist of **Epics**, **Features**, **User Stories**, **Tasks** and **Bugs**. + +In the agile terminology, a **User Story** is a deliverable, testable piece of work. The User Story may consist of several **Tasks**, that are smaller pieces of work that need to be performed, typically by a developer, before the User Story may be delivered. In the ideal world, all User Stories have been broken down into manageable tasks, each taking only a couple of hours to complete, adding up to no more than a handful of days for the entire User Story. This would make a User Story an ideal candidate for a so-called Topic Branch, where the developer could make one or more commits for each of the tasks within the User Story. Once all tasks are done, you want to deliver the User Story to the client, at which time the topic branch is merged into a delivery branch (for example, a "Test" branch), and the code deployed to a testing environment. + +Determining a suitable branching strategy depends on many different factors. In general, Microsoft recommends the [Trunk-based Development](https://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance?view=azure-devops) ([video](https://youtu.be/t_4lLR6F_yk?t=232)) strategy, for agile and continuous delivery of small increments. The main idea is to create branches off the "Main" branch for every new feature or bugfix (see image below). Code review processes are enforced through pull requests from feature branches into Main, and using the Branch Policy feature of Azure DevOps, we can set up rules that require code to build cleanly before a pull request can be completed. + +![Trunk Based Development](~/content/assets/images/trunk-based-development.png) + +### Trunk-based Development + +However, such a strategy might not be feasible in a Business Intelligence development teams, for a number of reasons: + +- New features often require prolonged testing and validation by business users, which may take several weeks to complete. As such, you will likely need a user-faced test environment. +- BI solutions are multi-tiered, typically consisting of a Data Warehouse tier with ETL, a Master Data Management tier, a semantic layer and reports. Dependencies exist between these layers, that further complicate testing and deployment. +- The BI team may be responsible for developing and maintaining several different semantic models, serving different areas of business (Sales, Inventory, Logistics, Finance, HR, etc.), at different maturity stages and at varying development pace. +- The most important aspect of a BI solution is the data! As a BI developer, you don not have the luxury of simply checking out the code from source control, hitting F5 and having a full solution up and running in the few minutes it takes to compile the code. Your solution needs data, and that data has to be loaded, ETL'ed or processed across several layers to make it to the end user. Including data in your DevOps workflows could blow up build and deployment times from minutes to hours or even days. In some scenarios, it might not even be possible, due to ressource or economy constraints. + +There is no doubt that a BI team would benefit from a branching strategy that supports parallel development on any of the layers in the full BI solution, in a way that lets them mix and match features that are ready for testing. But especially due to the last bullet point above, we need to think carefully about how we are going to handle the data. If we add a new attribute to a dimension, for example, do we want to automatically load the dimension as part of our build and deployment pipelines? If it only takes a few minutes to load such a dimension, that would probably be fine, but what if we are adding a new column to a multi-billion row fact table? And if developers are working on new features in parallel, should each developer have their own development database, or how do we otherwise prevent them from stepping on each others toes in a shared database? + +There is no easy answer to the questions above - especially when considering all the tiers of a BI solution, and the different constellations and prefered workflows of BI teams across the planet. Also, when we dive into actual build, deployment and test automation, we are going to focus mostly on Analysis Services. The ETL- and database tiers have their own challenges from a DevOps perspective, which are outside the scope of this article. But before we move on, let us take a look at another branching strategy, and how it could potentially be adopted to BI workflows. + +### GitFlow branching and deployment environments + +The strategy described below is based on [GitFlow by Vincent Driessen](https://nvie.com/posts/a-successful-git-branching-model/). + +![Gitflow](~/content/assets/images/gitflow.png) + +Implementing a branching strategy similar to this, can help solve some of the DevOps problems typically encountered by BI teams, provided you put some thought into how the branches correlate to your deployment environments. In an ideal world, you would need at least 4 different environments to fully support GitFlow: + +- The **production** environment, which should always contain the code at the HEAD of the master branch. +- A **canary** environment, which should always contain the code at the HEAD of the develop branch. This is where you typically schedule nightly deployments and run your integration testing, to make sure that the features going into the next release to production play nicely together. +- One or more **UAT** environments where you and your business users test and validate new features. Deployment happens directly from the feature branch containing the code that needs to be tested. You will need multiple test environments if you want to test multiple new features in parallel. With some coordination effort, a single test environment is usually enough, as long as you carefully consider the dependencies between your BI tiers. +- One or more **sandbox** environments where you and your team can develop new features, without impacting any of the environments above. As with the test environment, it is usually enough to have a single, shared, sandbox environment. + +We must emphasize that there is really no "one-size-fits-all" solution to these considerations. Maybe you are not building your solution in the Cloud, and therefore do not have the scalability or flexibility to spin up new resources in seconds or minutes. Or maybe your data volumes are very large, making it impractical to replicate environments due to resource/economy/time constraints. Before moving on, also make sure to ask yourself the question of whether you truly need to support parallel development and testing. This is rarely the case for small teams with only a few stakeholders, in which case you can still benefit from CI/CD, but where GitFlow branching might be overkill. + +Even if you do need to support parallel development, you may find that multiple developers can easily share the same development or sandbox environment, without encountering too much trouble. Specifically for tabular models, though, we recommend that developers still use individual [workspace databases](xref:workspace-mode) to avoid "stepping over each others toes". + +## Common workflow + +Assuming you already have a git repository set up and aligned to your branching strategy, adding your tabular model "source code" to the repository is simply a matter of using Tabular Editor to save the metadata to a new branch in a local repository. Then, you stage and commit the new files, push your branch to the remote repository and create a pull request to get your branch merged into the main branch. + +The exact workflow depends on your branching strategy and how your git repositories have been set up. In general, the workflow would look something like this: + +1. Before starting work on a new feature, create a new feature branch in git. In a trunk-based development scenario, you would need the following git commands to checkout the main branch, get the latest version of the code, and create the feature branch from there: + ```cmd + git checkout main + git pull + git checkout -b "feature\AddTaxCalculation" + ``` +2. Open your model metadata from the local git repository in Tabular Editor. Ideally, use a [workspace database](xref:workspace-mode), to make it easier to test and debug DAX code. +3. Make the necessary changes to your model using Tabular Editor. Continuously save the changes (CTRL+S). Regularly commit code changes to git after you save, to avoid losing work and to keep a full history of all changes that were made: + ```cmd + git add . + git commit -m "Description of what was changed and why since last commit" + git push + ``` +4. If you are not using a workspace database, use Tabular Editor's **Model > Deploy...** option to deploy to a sandbox/development environment, in order to test the changes made to the model metadata. +5. When done, and all code has been committed and pushed to the remote repository, you submit a pull request in order to get your code integrated with the main branch. If a merge conflict is encountered, you will have to resolve it locally, using for example the Visual Studio Team Explorer or by simply opening the .json files in a text editor to resolve the conflicts (git inserts conflict markers to indicate which part of the code has conflicts). +6. Once all conflicts are resolved, there may be a process of code review, automated build/test execution based on branch policies, etc. to get the pull request completed. This, however, depends on your branching strategy and overall setup. + +We present more details about how to configure git branch policies, set up automated build and deployment pipelines, etc. using Azure DevOps in the following articles. Similar techniques can be used in other automated build and git hosting environments, such as TeamCity, GitHub, etc. + +# Next steps + +- @powerbi-cicd +- @as-cicd +- @optimizing-workflow-workspace-mode \ No newline at end of file diff --git a/content/localization/zh/personalizing-te3_zh.md b/content/localization/zh/personalizing-te3_zh.md new file mode 100644 index 00000000..0827d748 --- /dev/null +++ b/content/localization/zh/personalizing-te3_zh.md @@ -0,0 +1,252 @@ +--- +uid: personalizing-te3 +title: Personalizing and configuring Tabular Editor 3 to suit your needs +author: Daniel Otykier +updated: 2021-09-28 +--- + +# Personalizing and configuring Tabular Editor 3 to suit your needs + +Tabular Editor 3 provides a wide range of configuration options, that allow you to tweak the tool to your specific needs and preferred workflow. In this article, we will guide you through the settings that are most commonly adjusted by individual model developers. + +Most of the settings covered in this article are accessed through the **Tools > Preferences** menu option. Throughout the article, we will list individual settings in the following style, for easy reference: + +**_Name of setting_ (default value)**
    Description of setting. + +# General features + +The first page you will encounter within the **Preferences** dialog is the **Tabular Editor > Features** page (see screenshot below). Below is a short description of the features on this page, and what they are commonly used for: + +![Pref General Features](~/content/assets/images/pref-general-features.png) + +## Power BI + +These settings are mostly useful for developers who use Tabular Editor 3 as an [External Tool for Power BI Desktop](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools). + +##### _Allow unsupported modeling operations_ (disabled) + +External Tools for Power BI Desktop have some [limitations](xref:desktop-limitations). By default, Tabular Editor 3 will prevent the user from making unsupported changes to the data model. There may be some advanced modeling features which work well, even though they are not supported cf. the previous link. To unlock all Tabular Object Model objects and properties, enable this setting. + +##### _Hide auto date/time warnings_ (disabled) + +When the "Auto date/time" setting in Power BI Desktop is enabled, a number of calculated tables are created automatically. Unfortunately, these tables contain DAX code which trigger a warning message by Tabular Editor 3's built-in DAX analyzer. To hide these warnings, enable this setting. + +##### _Line break on first line of DAX_ (disabled) + +In Power BI Desktop it is common to insert a line break on the first line of a DAX expression, due to the way the formula bar displays the DAX code. If you often switch back and forth between Tabular Editor and Power BI Desktop, consider enabling this option to have Tabular Editor 3 insert the line break automatically, whenever a DAX expression is edited through the tool. + +## Metadata Synchronization + +These settings controls the behavior of Tabular Editor 3, when model metadata is loaded from a database on an instance of Analysis Services. The settings specify how Tabular Editor 3 should deal with metadata changes applied to the database from outside the application, such as when another user makes a change to the database, or when you make a change to the model through Power BI Desktop while Tabular Editor 3 is used as an external tool. + +##### _Warn when local metadata is out-of-sync with deployed model_ (enabled) + +When this is checked, Tabular Editor displays a warning message when you attempt to save changes, while another user or process has made a change to the database since the model metadata was loaded into your instance of Tabular Editor. + +##### _Track external model changes_ (enabled) + +This option is only relevant for local instances of Analysis Services (i.e. msmdsrv.exe processes running on the same machine as Tabular Editor). When checked, Tabular Editor starts a trace on Analysis Services and notifies you if external changes are made. + +##### _Refresh local Tabular Object Model metadata automatically_ (enabled) + +When the tracing mechanism as described above is enabled, this option allows Tabular Editor to automatically refresh the model metadata when an external change is detected. This is useful if you often switch back and forth between Power BI Desktop and Tabular Editor 3, as this ensures that changes made in Power BI Desktop are automatically sync'ed to Tabular Editor. + +##### _Cleanup orphaned Tabular Editor traces_ + +Normally, Tabular Editor 3 should automatically stop and remove any AS traces started due to the settings above. However, if the application was shut down prematurely, the traces may never be stopped. By clicking this button, all AS traces started by any instance of Tabular Editor, on the current instance of Analysis Services, will be removed. + +> [!NOTE] +> The cleanup button is only available when Tabular Editor is connected to an instance of Analysis Services. + +# TOM Explorer settings + +The settings below control various aspects of the TOM Explorer. You can find these settings under **Tabular Editor > TOM Explorer**: + +![Tom Explorer Settings](~/content/assets/images/tom-explorer-settings.png) + +##### _Show full branch_ (disabled) + +When filtering the TOM Explorer, by default Tabular Editor 3 shows all items in the hierarchy that matches the filter string, including their parents. If you want to see all child items as well (even though these might not match the filter string), enable this option. + +##### _Always show delete warnings_ (disabled) + +If you prefer Tabular Editor 3 to prompt you to confirm all object deletions, enable this setting. Otherwise, Tabular Editor 3 will only prompt you to confirm multi-object deletions, or deletions of objects that are referenced by other objects. + +> [!NOTE] +> All delete operations in Tabular Editor 3 can be undone by hitting CTRL+Z. + +# DAX editor general settings + +Tabular Editor 3's DAX editor is highly configurable, and it is easy to get overwhelmed by the many settings available. This section highlights the most common and important settings. Locate the general settings under **Text Editors > DAX Editor > General**: + +![Dax Editor General](~/content/assets/images/dax-editor-general.png) + +## General + +The _Line numbers_, _Code folding_, _Visible whitespace_ and _Indentation guides_ settings can be used to toggle various visual feature of the editor. In the screenshot below, all four options have been enabled: + +![Visible Whitespace](~/content/assets/images/visible-whitespace.png) + +##### _Use tabs_ (disabled) + +When this is checked, a tab character (`\t`) is inserted whenever the TAB button is hit. Otherwise, a number of spaces corresponding to the _Indent width_ setting is inserted. + +##### _Comment style_ (slashes) + +DAX supports line comments that use slashes (`//`) or hyphens (`--`). This setting determines which style of comment is used when Tabular Editor 3 generates DAX code, such as when using the DAX script feature. + +## DAX Settings + +These settings determine certain behavior of the DAX code analyzer. The _Locale_ setting is simply a matter of preference. All other settings are relevant only when Tabular Editor 3 cannot determine the version of Analysis Services used, as is the case for example when a Model.bim file is loaded directly. In this case, Tabular Editor tries to guess which version the model will be deployed to, based on the compatibility level specified in the model, but depending on the actual version of the deployment target, there may be various DAX language differences, which Tabular Editor cannot determine. If Tabular Editor reports incorrect semantic/syntax errors, you may need to tweak these settings. + +# Auto Formatting + +On the **Text Editors > DAX Editor > Auto Formatting** page, you can find a wide range of settings for controlling how your DAX code is formatted. + +![Auto Formatting Settings](~/content/assets/images/auto-formatting-settings.png) + +##### _Auto format code as you type_ (enabled) + +This option will automatically apply certain formatting rules whenever certain keystrokes occur. For example, when a parenthesis is closed, this feature will ensure that everything within the parentheses is formatted according to the other settings on this page. + +##### _Auto-format function calls_ (enabled) + +This option specifically controls whether automatic formatting of function calls (that is, spacing between arguments and parentheses), should happen when a parenthesis is closed. + +##### _Auto-indent_ (enabled) + +This option automatically indents function arguments when a line break is inserted within a function call. + +##### _Auto-brace_ (enabled) + +This option automatically inserts the closing brace or quote whenever an opening brace or quote is entered. + +##### _Wrap selection_ (enabled) + +When enabled, this option automatically wraps the current selection with the closing brace, when an opening brace is entered. + +## Formatting rules + +These settings control how DAX code whitespace is formatted, both when auto-formatting occurs, but also when code is manually formatted (using the **Format DAX** menu options). + +##### _Space after functions_ (disabled) + +# [Enabled](#tab/tab1) + +```DAX +SUM ( 'Sales'[Amount] ) +``` + +# [Disabled](#tab/tab2) + +```DAX +SUM( 'Sales'[Amount] ) +``` + +*** + +##### _Newline after functions_ (disabled) + +Applies only when a function call needs to be broken across multiple lines. + +# [Enabled](#tab/tab3) + +```DAX +SUM +( + 'Sales'[Amount] +) +``` + +# [Disabled](#tab/tab4) + +```DAX +SUM( + 'Sales'[Amount] +) +``` + +*** + +##### _Newline before operator_ (enabled) + +Applies only when a binary operation needs to be broken across multiple lines. + +# [Enabled](#tab/tab5) + +```DAX +[Internet Total Sales] + + [Reseller Total Sales] +``` + +# [Disabled](#tab/tab6) + +```DAX +[Internet Total Sales] + + [Reseller Total Sales] +``` + +*** + +##### _Pad parentheses_ (enabled) + +# [Enabled](#tab/tab7) + +```DAX +SUM( Sales[Amount] ) +``` + +# [Disabled](#tab/tab8) + +```DAX +SUM(Sales[Amount]) +``` + +*** + +##### _Long format line limit_ (120) + +The maximal number of characters to keep on a single line before an expression is broken across multiple lines, when using the **Format DAX (long lines)** option. + +##### _Short format line limit_ (60) + +The maximal number of characters to keep on a single line before an expression is broken across multiple lines, when using the **Format DAX (short lines)** option. + +> [!NOTE] +> Most settings above are only in effect when using the (default) built-in DAX formatter. + +## Casings and quotes + +In addition to formatting the DAX code whitespace, Tabular Editor 3 can also fix object references and function/keyword casings. + +##### _Fix measure/column qualifiers_ (enabled) + +When this is checked, table prefixes are automatically removed from measure references, and automatically inserted on column references. + +##### _Preferred keyword casing_ (default = UPPER) + +This setting allows you to change the casing used for keywords, such as `ORDER BY`, `VAR`, `EVALUATE`, etc. This also applies when a keyword is inserted through the auto-complete feature. + +##### _Preferred function casing_ (default = UPPER) + +This setting allows oyu to change the casing used for functions, such as `CALCULATE(...)`, `SUM(...)`, etc. This also applies when a function is inserted through the auto-complete feature. + +##### _Fix keyword/function casing_ (enabled) + +When this is checked, casing of keywords and functions is automatically corrected whenever code is auto-formatted or manually formatted. + +##### _Fix object reference casing_ (enabled) + +DAX is a case-insensitive language. When this is enabled, references to tables, columns and measures are automatically corrected such that the casing matches the physical name of the referenced objects. This fixup happens whenever code is auto-formatted or manually formatted. + +##### _Always quote tables_ (disabled) + +Referencing certain table names do not require surrounding single quotes in DAX. However, if you prefer table references to always be quoted, regardless of the table name, you can check this option. + +##### _Always prefix extension columns_ (disabled) + +Extension columns can be defined without a table name. When this is checked, the DAX editor will always add the table prefix to an extension column, even if the table name is blank. In that case, the column reference will look like `''[Extension Column]`. + +# Next steps + +- @boosting-productivity-te3 \ No newline at end of file diff --git a/content/localization/zh/perspective-editor_zh.md b/content/localization/zh/perspective-editor_zh.md new file mode 100644 index 00000000..8ba5ae03 --- /dev/null +++ b/content/localization/zh/perspective-editor_zh.md @@ -0,0 +1,36 @@ +--- +uid: perspective-editor +title: Perspective Editor +author: Šarūnas Jučius +updated: 2022-03-16 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Perspective Editor + +> [!NOTE] +> In order to add perspectives to models running on SSAS or Azure AS, you will need a Tabular Editor 3 Enterprise Edition license. + +The **Perspective Editor** provides a quick overview of the perspective assignment of objects in the model (tables, columns, hierarchies and measures). You can launch the Perspective Editor through the **View** menu. Alternatively, if you only need to edit certain perspectives, select them in the **TOM Explorer** (hold down CTRL or SHIFT to multi-select), then right-click and choose **Show in Perspective Editor**. + +![Perspective Editor](~/content/assets/images/perspective-editor.png) + +Use the checkboxes in the perspective editor to quickly add/remove multiple objects from a perspective. You can use Undo (Ctrl+Z) and Redo (Ctrl+Y) the usual way. Note that the changes made through the perspective editor are immediately applied to the TOM, although you will still have to save (Ctrl+S) or deploy your model for the changes to apply in Analysis Services / Power BI. + +## Perspective Editor toolbar + +While the Perspective Editor is active, the accompanying toolbar provides the following options: + +- ![Perspective Editor Add Perspective](~/content/assets/images/perspective-editor-add-perspective.png) **New perspective**: This button adds a new perspective to the model. The perspective will be displayed in the Perspective Editor. +- ![Perspective Editor Hide Members](~/content/assets/images/perspective-editor-hide-members.png) **Show/Hide hidden options**: Enable this option if you want to see all objects in the Perspective Editor, including hidden objects. +- ![Perspective Editor Folder](~/content/assets/images/perspective-editor-folder.png) **Show/Hide display folders**: Enable this toggle button if you want the Perspective Editor to group table objects (measures, hierarchies, columns) by Display Folders. + +## Working with many perspectives + +If you're working on a model with many perspectives, it may be impractical to display all of them at once. You can rearrange the display order of perspectives in the Perspective Editor, by dragging the column headers around, making it easier to compare perspectives side-by-side. Moreover, you can add/remove perspectives from the editor at any time, through the right-click context menu: + +![Perspective Editor Columns](~/content/assets/images/perspective-editor-columns.png) \ No newline at end of file diff --git a/content/localization/zh/pivot-grid_zh.md b/content/localization/zh/pivot-grid_zh.md new file mode 100644 index 00000000..419aebc4 --- /dev/null +++ b/content/localization/zh/pivot-grid_zh.md @@ -0,0 +1,162 @@ +--- +uid: pivot-grid +title: Pivot Grids +author: Daniel Otykier +updated: 2024-05-28 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Pivot Grids + +> [!NOTE] +> Information in this article relates to Tabular Editor 3.16.0 or newer. Please make sure you are using the latest version of Tabular Editor 3 to take advantage of the new features and improvements. + +While developing semantic models, you may often want to test that your DAX expressions return the expected values. Traditionally, this was done using client tools such as Excel or Power BI. With Tabular Editor 3, you can use **Pivot Grids** which behave much like the widely known PivotTables in Excel. The Pivot Grid lets you quickly create summarized views of the data in your model, allowing you to test the behavior of your DAX measures when filtering and slicing by various columns and hierarchies. + +![Pivot Grid Example](images/pivot-grid-example.png) + +The screenshot above shows a Pivot Grid containing two measures, `[Total Net Order Value]` and `[Net Orders]`, which is sliced horizontally by Year, filtered to 2021 and 2022, and vertically by the Product Hierarchy. Tabular Editor 3 users can use this feature to ensure that DAX expressions behind the measures are working as expected and to quickly validate the data in the model. + +By default, the Pivot Grid auto-updates every time you save changes to the semantic model (Ctrl+S). Thus, you can quickly iterate on your DAX expressions and see the results in the Pivot Grid without having to wait for the model to refresh by changing your measures, saving the model, and directly seeing the new measure definition reflected in the Pivot Grid. A good workflow is to open the Pivot Grid in a separate window while working on DAX expressions in the **Expression Editor** or using a **DAX Script**. + +> [!TIP] +> Some clarifications on terminology: +> +> - **Fields** refers to model measures, KPIs, columns and hierarchies. In other words, anything that can be dragged into the Pivot Grid. +> - **KPIs** are a special type of measure that can be created in Tabular Editor. They are displayed in the Pivot Grid just like measures, but with a special icon to indicate that they are KPIs. Each KPI can have up to 3 different values (target, trend, and status), which are displayed separately in the Pivot Grid. +> - **Columns** in the Pivot Grid (such as in the term "Column Area") should not be confused with columns in the model. In the Pivot Grid, columns are used to slice the data horizontally, while rows are used to slice the data vertically. +> - **Cells** in the Pivot Grid are the individual data points where a row and a column intersect. Each cell contains a single value, which is the result of the DAX expression of the specific measure, evaluated under the filter context produced by values in the _Row Area_ and _Column Area_, in combination with any filters applied to fields in the _Filter Area_. + +> [!NOTE] +> Developers with a multidimensional background may be more familiar with the terms _Dimensions_ and _Attributes_. In semantic models, _Dimensions_ are represented by model _tables_, and _Attributes_ are represented by model _columns_. _Hierarchies_ in a semantic model, is just a way to group columns together, such as in a calendar hierarchy: Year > Quarter > Month > Day. Such hierarchies used to be called _Attribute Hierarchies_ or _User-Defined Hierarchies_ in multidimensional models. + +## Creating a Pivot Grid + +You can create a new, empty Pivot Grid through the **File > New > New Pivot Grid** menu option. Alternatively, select one or more measures in the **TOM Explorer**, right-click or go to the **Measure** menu and select **Add to Pivot Grid**, to create a new Pivot Grid with the selected measures. + +![Create Pivot Grid From TOM Explorer](images/create-pivot-grid-from-TOM-Explorer.png) + +You can create as many Pivot Grids as you like. + +> [!IMPORTANT] +> The option to create a Pivot Grid is only available while Tabular Editor 3 is connected to an instance of Analysis Services or the Power BI / Fabric XMLA endpoint. + +## Pivot Grid layout + +The Pivot Grid is divided into 4 areas: **Filter Area**, **Column Area**, **Row Area**, and **Data Area**. You can drag fields from the **Field List** or the **TOM Explorer** into these areas to create a Pivot Grid layout. The **Data Area** area is where you place measures or KPIs, while the **Row Area** and **Column Area** are used to slice the data by hierarchies and columns. The **Filter Area** is used to filter the data based on values in columns or hierarchies. + +![Empty Pivot Grid Highlighted](images/empty-pivot-grid-highlighted.png) + +The screenshot above shows an empty Pivot Grid layout. The 4 empty boxes at the bottom of the Field List represent the 4 areas of the Pivot Grid. You can drag fields from the Field List into these listboxes to create a Pivot Grid layout. Alternatively, you can drag fields directly into the Pivot Grid. + +## Pivot Grid menu and toolbar + +By default, when a Pivot Grid is the active window in Tabular Editor 3, a **Pivot Grid** menu and toolbar are available. The menu contains the same actions as the toolbar. + +![Pivot Grid Toolbar](images/pivot-grid-toolbar.png) + +![Pivot Grid Menu](images/pivot-grid-menu.png) + +These actions are: + +- **Impersonation...**: Displays a dialog that allows you to specify a role or user to impersonate through the Pivot Grid. This is useful when you want to test the behavior of your model for different users or roles, such as when [RLS or OLS](xref:data-security-about) has been applied to the model. +- **Refresh**: Re-execute the query generated by the Pivot Grid. This is useful when auto-refresh is disabled, or if changes have been made to the model outside of Tabular Editor 3. +- **Auto Refresh**: Toggles auto-refresh on or off. When auto-refresh is enabled, the Pivot Grid will automatically refresh every time you save changes to the model, or when a [Data Refresh operation](xref:data-refresh-view) completes. +- **Clear filters**: Clears all filters from the Pivot Grid. +- **Clear**: Removes all fields from the Pivot Grid. +- **Show empty values on columns**: Toggles whether empty values should be shown in the Pivot Grid, for fields that are added to the Pivot Grids Column Area. +- **Show empty values on rows**: Toggles whether empty values should be shown in the Pivot Grid, for fields that are added to the Pivot Grids Row Area. +- **Show fields**: Display and move focus to the Field List. + +## Field List + +By default, the Field List is displayed on the right side of the Pivot Grid. The Field List contains all the fields (measures, KPIs, columns, and hierarchies) that are available in the model. You can drag fields from the Field List into the Pivot Grid to create a layout. You can also drag fields between the different areas of the Pivot Grid to rearrange the layout. + +The Field List itself can be docked to the left or right side of the Pivot Grid, above or below, it can be hidden, or it can be undocked so that it "floats" as a separate window. If you have multiple Pivot Grids open, each Pivot Grid has its own Field List. + +If you would like the Field List to not be shown by default, uncheck the **Always show field list** option under **Tools > Preferences > Data Browsing > Pivot Grid > Field List**. + +You can change the default layout of the Field List under **Tools > Preferences > Data Browsing > Pivot Grid > Field List > Layout**. You can also change the layout of any field lists, by right-clicking in an empty area of the Field List and choosing the desired layout from the context menu. + +![Field List Settings](images/field-list-settings.png) + +By default, any field you add to the Pivot Grid remains visible in the Field List. If you would like to hide fields that are added to the Pivot Grid, you can uncheck the **Keep fields visible** option under **Tools > Preferences > Data Browsing > Pivot Grid > Field List** (this behavior is similar to how Pivot Grid worked prior to Tabular Editor v. 3.16.0). + +If you are working on a large, complex model, and you are expecting measures used in the Pivot Grid to be relatively slow, you can check the **Defer Layout Update** option at the bottom of the Field List. This will prevent the Pivot Grid from updating the layout every time you add or remove a field, which can be useful, if you intend to make multiple changes to the Pivot Grid layout before updating it. Hit the **Update** button to apply the changes to the Pivot Grid. + +> [!IMPORTANT] +> Columns without an attribute hierarchy (IsAvailableIn MDX = false) cannot be used in the Pivot Grid and are not shown in the Field list. + +## Customizing Pivot Grids + +### Adding fields + +There are several ways to add a field to a Pivot Grid: + +**From the TOM Explorer:** + +- Right-click on one or more _measures_ and choose **Add to Pivot Grid**. +- Right-click on a _column_ or _hierarchy_ and choose any of the **Add to pivot**-options (choose between rows, columns, or filters). +- If a measure, column or hierarchy is already shown in the Pivot Grid, the right-click options will allow you to **Remove from Pivot Grid**. in addition, you will see options to move columns or hierarchies between the different areas of the Pivot Grid. +- All of the options above are also available through the **Measure**, **Column**, and **Hierarchy** menus (respectively), when one or more such objects are selected in the TOM Explorer. +- In addition to the above, you can also drag one or more measures, columns, or hierarchies from the TOM Explorer into the Pivot Grid areas. + +![Add hierarchy to Pivot Grid through TOM Explorer](images/add-through-tom-explorer.png) + +**From the Field List:** + +- Drag a field from the Field List into the Pivot Grid. +- Drag a field from the Field List into the area listboxes at the bottom of the Field List to add it to the Pivot Grid. +- Right-click on a field in the Field List for options to add it to the Pivot Grid. +- If a field is already showing in the Pivot Grid, the right-click context menu will also have an option to remove the field, or move it to a different area (column/hierarchy fields only). +- Double-clicking on a field will immediately add it to the Pivot Grid. Measures/KPIs are added to the Data Area, while columns and hierarchies are added to the Filter Area. + +![Add Through Field List](images/add-through-field-list.png) + +### Adjusting fields + +After fields have been added to the Pivot Grid, you can adjust the width of columns to better accommodate their content. Double-clicking on a column header separator will automatically adjust the column width to fit the content of the column. You can also drag the column header separator to manually adjust the column width. Lastly, you can use the **Best Fit** or **Set width...** context menu options by right-clicking on the column header. + +![Best Fit Columns 2](images/best-fit-columns-2.png) + +To apply a "Best Fit" or set a specific pixel width for all columns in the Pivot Grid simultaneously, right-click on the "Values" header and select the desired option from the context menu. + +By default, field headers will expand vertically to fit the content of the field name. If you would like to limit the height of field headers to one row, you can disable the **Word wrap field headers**-option under **Tools > Preferences > Pivot Grid > Field Headers**. + +To change the order of fields in the Pivot Grid, you can drag fields between the different areas of the Pivot Grid. You can also drag fields within the same area to change their order. To remove a field from the Pivot Grid, drag it back to the Field List or right-click on the field and choose **Remove from Pivot Grid** from the context menu. + +If you want measures to be displayed on rows rather than on columns, drag the "Values" field from the Column Area to the Row Area. + +### Visualization rules + +You can add visualization rules to cells in the Pivot Grids, which is useful for highlighting cells based on their values, for example in order to better spot outliers. To add visualization rules, right-click on any Data Area cell in the Pivot Grid, and choose which rules to apply from the context menu (see screenshot below). + +![Customizing Pivot Grids](images/customizing-pivot-grids.png) + +## Persisting Pivot Grid layouts + +When you close a Pivot Grid, Tabular Editor will prompt you to save the layout of the Pivot Grid. If you choose to save the layout, the next time you open the Pivot Grid, it will be restored to the same layout as when you closed it. You can also save the layout of a Pivot Grid manually by hitting (Ctrl+S) or using the **File > Save** option, while the Pivot Grid is the active window. + +The file extension used for saving Pivot Grid layouts is `.te3pivot`. This is a simple json file that specifies which model objects are shown in the Pivot Grid, and in which areas they are placed. Objects are referenced by name and lineage tag (if present), so the Pivot Grid layout can generally be restored even if the model has been modified since the layout was saved. + +> [!NOTE] +> It is possible to open a Pivot Grid layout that was created in a different model, but be aware that the fields in the layout may not exist in the model you are currently connected to. In such cases, the Pivot Grid will show a warning message, and any fields that do not exist in the model will be removed from the layout. The warning message may be toggled off under **Tools > Preferences > Data Browsing > Pivot Grid > Show warning if Pivot Grid doesn't match model**. + +## Additional features + +The Pivot Grid has a few more features that are useful to know about: + +- If you right-click on a field, you will have the option to **Go to** that field. This brings the TOM Explorer into focus, with the equivalent model object selected. For measures and calculated columns, the **Expression Editor** will be brought into focus, with the DAX expression of the measure displayed. +- If you right-click on a cell in the Pivot Grid, you can select the option to **Debug this value**. This will launch the [**DAX Debugger**](xref:dax-debugger) starting from the specific measure and filter context that produced the value in the cell. + +## Limitations and known issues + +Below is a list of known limitations and issues with Pivot Grids in Tabular Editor 3.16.0, which we are working to address in future releases: + +- Format rules (such as icon sets, data bars, etc.) are not properly persisted when saving a Pivot Grid layout as a `.te3pivot` file. +- The .te3pivot file does not currently store the state of the "Show empty values on columns" and "Show empty values on rows" options. +- If you open a .te3pivot file on a model different from the one the layout was saved from, fields that do not exist in the current model will be removed from the layout. Hitting Save (Ctrl+S) will save the layout with the removed fields removed. We may change this behavior in a future release so that the .te3pivot file is not overwritten without explicit confirmation. \ No newline at end of file diff --git a/content/localization/zh/policies_zh.md b/content/localization/zh/policies_zh.md new file mode 100644 index 00000000..c83152d3 --- /dev/null +++ b/content/localization/zh/policies_zh.md @@ -0,0 +1,41 @@ +--- +uid: policies +title: Policies +author: Daniel Otykier +updated: 2024-10-30 +--- + +# Policies + +Some IT organisations may wish to limit certain features of Tabular Editor. This is possible through the use of group policies, by setting certain values in the Windows registry. + +> [!NOTE] +> This functionality requires the following versions of Tabular Editor: +> +> - Tabular Editor 2 version [2.17.0](https://github.com/TabularEditor/TabularEditor/releases/tag/2.17.0) or newer +> - Tabular Editor 3 version [3.3.5](https://github.com/TabularEditor/TabularEditor3/releases/tag/3.3.5) or newer. + +Below is a listing of the policies that can be controlled. To enforce one or more of these policies, add a non-zero DWORD value to the registry key. The name of the value specifies which policy to enforce. + +**Registry key:** HKEY_CURRENT_USER\Software\Policies\Kapacity\Tabular Editor\ + +| Value | When enforced... | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DisableUpdates | Tabular Editor will not check if newer versions are available online. Moreover, users cannot manually check if new updates are available through the tool. | +| DisableCSharpScripts | Tabular Editor will not let users create and execute C# scripts. | +| DisableMacros | Tabular Editor will not let users save or run macros. Moreover, macros defined in the %LocalAppData% folder will not be loaded and compiled upon application startup. | +| DisableBpaDownload | Tabular Editor will not allow Best Practice Analyzer rules to be downloaded from the web. | +| DisableWebDaxFormatter | Tabular Editor will disable the DAX code formatter, which performs a webrequest to daxformatter.com. (TE3 will still allow formatting code through the built-in DAX formatter) | +| DisableErrorReports | **(TE3 Only)** Tabular Editor will not allow users to send error/crash reports to the Tabular Editor 3 support team. | +| DisableTelemetry | **(TE3 Only)** Tabular Editor will not collect and send anonymous usage data to the Tabular Editor 3 support team. | +| DisableDaxOptimizer | **(TE3 Only)** The DAX Optimizer integration feature will not be available | +| DisableDaxOptimizerUpload | **(TE3 Only)** Users will not be allowed to upload VPAX files through the DAX Optimizer integration feature. Implicitly enforced when `DisableDaxOptimizer` is enforced. | +| RequireDaxOptimizerObfuscation | **(TE3 Only)** Users will not be allowed to upload un-obfuscated (clear text) VPAX files through the DAX Optimizer integration feature. Implicitly enforced when `DisableDaxOptimizer` or `DisableDaxOptimizerUpload` is enforced. | + +## Disabling web communications + +If you want to ensure that Tabular Editor does not perform web requests, specify the `DisableUpdates`, `DisableBpaDownload`, `DisableWebDaxFormatter`, `DisableErrorReports`, `DisableTelemetry`, ànd `DisableDaxOptimizer` policies. + +## Disabling custom scripts + +If you want to ensure that Tabular Editor does not allow users to execute arbitrary code, specify the `DisableCSharpScripts` and `DisableMacros` policies. diff --git a/content/localization/zh/powerbi-cicd_zh.md b/content/localization/zh/powerbi-cicd_zh.md new file mode 100644 index 00000000..04266dfb --- /dev/null +++ b/content/localization/zh/powerbi-cicd_zh.md @@ -0,0 +1,10 @@ +--- +uid: powerbi-cicd +title: Power BI CI/CD with Azure DevOps and Tabular Editor +author: Daniel Otykier +updated: 2021-10-04 +--- + +# Power BI CI/CD with Azure DevOps and Tabular Editor + +(WIP) \ No newline at end of file diff --git a/content/localization/zh/powerbi-xmla-pbix-workaround_zh.md b/content/localization/zh/powerbi-xmla-pbix-workaround_zh.md new file mode 100644 index 00000000..7f54228c --- /dev/null +++ b/content/localization/zh/powerbi-xmla-pbix-workaround_zh.md @@ -0,0 +1,98 @@ +--- +uid: powerbi-xmla-pbix-workaround +title: Creating PBIX File from XMLA Endpoint. +author: Morten Lønskov +updated: 2023-10-18 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + partial: Tabular Editor 3 Business Edition only allows connecting to the XMLA endpoint of Premium-Per-User (PPU) workspaces. + - edition: Enterprise +--- + +# Downloading a Power BI dataset to a .pbix using the XMLA endpoint + +Once a change is made to a Power BI semantic model through the XMLA endpoint, it's not possible to download the model as a .pbix file from the Power BI service. + +However, with the Power BI Project file, it's possible to create a .pbix file from the remote model by following the three-step process, which is described as follows. + +![XLMA to PBIX Overview](~/content/assets/images/power-bi/create-pbix-from-xmla-overview.png) + +> [!NOTE] +> The described workaround isn't officially supported by Microsoft. There's no guarantee that it works for every model. Specifically, if you've added custom partitions or other objects [listed here](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations), Power BI Desktop may not be able to correctly open the file following this approach. See below for a script to handle incremental refresh partitions. + +## Step 1: Create and save an empty Power BI projects (.pbip) file + +The first step is to create a new Power BI report and save it as an empty Power BI Project (.pbip) file, as depicted in the following diagram. + +![Save PBIP file](~/content/assets/images/power-bi/save-pbip-file.png) + +This creates a folder structure that contains an empty _model_ file. This _model_ file contains the model metadata. You'll overwrite this metadata in the next step with the metadata of the published model that you want to save to .pbix. + +![PBIP with Model file](~/content/assets/images/power-bi/pbip-file-bim-model.png) + +Close Power BI desktop, and proceed with the next step in Tabular Editor. + +## Step 2: Open XMLA model with Tabular Editor + +With Tabular Editor open, connect to the Fabric workspace via the XMLA endpoint. Load the Power BI semantic model you want to convert to a .pbix. + +## Step 3: Save XMLA model into .pbip + +In Tabular Editor using _File > Save as..._, navigate to the Power BI Project folder. Overwrite the _model.bim_ file shown in the previous diagram. + +This will save the remote model into the Power BI Project that will now contain the model metadata. + +If the .pbip folder is configured to store the model as [TMDL](xref:tmdl) files, you will need to use the Save To Folder option in Tabular Editor instead. Then navigate to the Power BI project folder for the semantic model (ModelName.SemanticModel), open the 'definition' folder and save your model there. + +> [!NOTE] +> To enable TMDL go to **Tools > Preferences > File Formats > Save-to-folder**, and select "TMDL" in the **Serialization mode** dropdown. See [TMDL documentation for more information](xref:tmdl) + +## Step 3.1: Remove incremental refresh partitions and create new (Optional) + +Use the Convert Incremental Refresh script below to delete incremental refresh partitions and create a single partition for each table containing the expression used in the incremental refresh expression. + +## Step 4: Save to .pbix and open this file in Power BI Desktop + +![PBIP with Tables](~/content/assets/images/power-bi/pbip-includes-tables.png) + +Open the .pbip and the Power BI report will now contain the XMLA endpoint semantic model. + +Save it to a .pbix using _File > Save As..._ in Power BI Desktop. + +## Re-hydrate .pbix + +The .pbix now contains the model that was published to the Fabric workspace. When you open the .pbix, you can _re-hydrate_ the file, meaning that you load the data based on the connections specified in the model. + +## Convert Incremental Refresh partitions + +The above step 4 will fail if the semantic model has incremental refresh enabled as a Power BI desktop model cannot contain multiple partitions. +In this case the following script should be run against the model to convert incremental refresh partitions into single partitions + +```csharp +foreach (var t in Model.Tables) +{ + if(t.EnableRefreshPolicy) + { + //We will collect the SourceExpression from the Incremental Refresh Source Expression of the table + string m_expression = t.SourceExpression.ToString(); + + //We will generate a new partition name + string partition_name = t.Name + "-" + Guid.NewGuid(); + + //Now we will create a new partition + var partition = t.AddMPartition(partition_name, m_expression); + partition.Mode = ModeType.Import; + + //Next we will delete all the incremental refresh partitions of the table + foreach (var p in t.Partitions.OfType().ToList()) + { + p.Delete(); + } + } +}; +``` + +Thank you to [Micah Dail](https://twitter.com/MicahDail) for creating the script and suggesting it to be included in this document. diff --git a/content/localization/zh/powerbi-xmla_zh.md b/content/localization/zh/powerbi-xmla_zh.md new file mode 100644 index 00000000..d4bb1390 --- /dev/null +++ b/content/localization/zh/powerbi-xmla_zh.md @@ -0,0 +1,52 @@ +--- +uid: powerbi-xmla +title: Editing through XMLA endpoint +author: Daniel Otykier +updated: 2021-10-01 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + partial: Tabular Editor 3 Business Edition only allows connecting to the XMLA endpoint of Premium-Per-User (PPU) workspaces. + - edition: Enterprise +--- + +# Editing a Power BI dataset through the XMLA endpoint + +You can use Tabular Editor 3 to connect to a Power BI dataset published to the Power BI service through the [XMLA endpoint](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools). The XMLA endpoint is available for Power BI Premium Capacity workspaces (i.e. workspaces assigned to a Px, Ax or EMx SKU), or Power BI Premium-Per-User (PPU) workspaces. + +> [!NOTE] +> Power BI Pro licenses are not sufficient for accessing Power BI datasets in a shared workspace. Premium/Embedded capacity or Premium-Per-User Power BI licensing is required for XMLA access. + +## Prerequisites + +Tabular Editor requires the XMLA endpoint to allow both read/write access. This setting is controlled by [your capacity admin](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#enable-xmla-read-write). + +> [!IMPORTANT] +> If using Tabular Editor 3 be aware of the [license limitations](xref:editions) for connecting to the Power BI XMLA endpoint. You need at least Tabular Editor 3 Business or Enterprise Edition depending on the type of Power BI Workspace used. + +## Limitations + +When connecting to a dataset through the XMLA endpoint, all data modeling operations supported by the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) are available for editing. In other words, the [Power BI Desktop Limitations](xref:desktop-limitations) do not apply when editing a dataset through the XMLA endpoint of the Power BI Service. + +> [!WARNING] +> Once a change is made to a Power BI dataset through the XMLA endpoint, it will not be possible to download the dataset as a .pbix file. [More information](https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools#power-bi-desktop-authored-datasets). +> Please see [Creating PBIX File from XMLA Endoint](xref:powerbi-xmla-pbix-workaround) for a workaround + +## Workflow + +The Power BI XMLA endpoint essentially exposes an instance of Analysis Services that Tabular Editor can connect to. As such, you can treat the Power BI workspace as the Analysis Services **server** with each Power BI dataset in the workspace corresponding to an Analysis Services **database**. All of Tabular Editor's modeling and management features are available when connecting to the XMLA endpoint. If you decide to use Tabular Editor to build and maintain your Power BI datasets, you should also consider some kind of version control system for your model metadata. + +The workflow is then: + +1. Create a new data model in Tabular Editor or connect to an existing dataset through the Power BI XMLA endpoint +2. Save this model as a **Model.bim** file or use Tabular Editor's [Save to folder](xref:save-to-folder) option. +3. Whenever you want to make changes to the model, load the file/folder you saved in step 2. The first time you do this, decide whether you want to use a [workspace database](xref:workspace-mode) or not. +4. Once you are ready to publish your changes to the Power BI service, perform a deployment through Tabular Editor (**Model > Deploy...**), thus creating a new or overwriting an existing dataset in a Power BI workspace. + +## Next steps + +- @new-pbi-model +- @workspace-mode +- @importing-tables \ No newline at end of file diff --git a/content/localization/zh/preferences_zh.md b/content/localization/zh/preferences_zh.md new file mode 100644 index 00000000..006c62c8 --- /dev/null +++ b/content/localization/zh/preferences_zh.md @@ -0,0 +1,77 @@ +--- +uid: preferences +title: Controlling preferences +author: Daniel Otykier +updated: 2021-09-08 +--- + +# Tabular Editor 3 Preferences + +Tabular data model development processes and workflows differ greatly from organization to organization. To ensure that the tool can fit into as many of these workflows as possible, Tabular Editor 3 is highly customizable - not just in terms of the user interface's look and feel, but also on more advanced topics such as web proxies, updates and feedback, row limits, timeouts, schema compare preferences, etc. + +This article describes the Tabular Editor 3 Preferences dialogs and the settings that you can control through it. + +To access the preferences dialog, go to **Tools > Preferences**. + +> [!NOTE] +> All Tabular Editor preferences are stored for each Windows user profile, in the `%localappdata%\TabularEditor3` folder. It is possible to migrate your settings to another machine by simply copying the contents of this folder. + +## Tabular Editor > Features + +![image](https://user-images.githubusercontent.com/8976200/104600495-5ad6f300-5679-11eb-9572-af99f0895859.png) + +### Power BI + +- **Allow unsupported editing**: This option is only relevant when Tabular Editor 3 is used as an external tool for Power BI Desktop. When checked, all TOM data modeling properties are available for editing when connected to an instance of Power BI Desktop. It's generally recommended to leave this unchecked, to make sure that you do not accidentally make changes to your Power BI file, [that are not supported by Power BI Desktop](xref:desktop-limitations). + +### Metadata Synchronization + +- **Warn when local metadata is out-of-sync with deployed model**: When checked, an information bar is displayed inside Tabular Editor, whenever you have made local changes to the model that have not yet been saved to Analysis Services. For example, if you're wondering why a DAX query or a Pivot Grid does not produce the expected result, this could be due to a measure expression being changed in Tabular Editor without saving the change to Analysis Services. The bar disappears when you hit save (Ctrl+S). Uncheck this if you get tired of seeing the information bar. +- **Track external model changes**: Just like Power BI Desktop can detect when an external tool makes a change to the data model, so too can Tabular Editor. In other words, when this is checked, and another user or application makes a change to the model _on a local instance of Analysis Services_, Tabular Editor will receive a notification. + - **Refresh local Tabular Object Model metadata automatically**: Check this if you want the notification from above to actually trigger a refresh of the metadata inside Tabular Editor. + +### Best Practice Analyzer + +- **Scan for Best Practice violations in the background** If unchecked, you will have to explicitly run a Best Practice Analysis from inside the Best Practice Analyzer tool window, to view if there are any violations. If checked, the scan happens continuously on a background thread whenever changes are made. For very large models, or models with very complex Best Practice rules, this may cause issues. + +## Tabular Editor > Updates and Feedback + +![image](https://user-images.githubusercontent.com/8976200/104601469-92926a80-567a-11eb-9499-1d1c8d967c72.png) + +- **Check for updates on start-up**: Pretty self-explanatory. Update notifications will not be sent during the public preview period, and the "Check for updates" button below also does not work at the moment. +- **Help improve Tabular Editor by collecting anonymous usage data**: Data does not contain any personally identifiable information, nor any information about the structure or content of your data models. If you would still like to opt out of telemetry, uncheck this. +- **Send error reports**: In cases of crashes, Tabular Editor displays an option for sending a crash report when this is checked. Crash reports are very helpful when debugging, so please leave this checked if you don't mind! + +## Tabular Editor > Keyboard + +![image](~/content/assets/images/keyboard-mappings.png) + +## Data Browsing > Pivot Grid / DAX Query + +![image](https://user-images.githubusercontent.com/8976200/104601874-0df41c00-567b-11eb-8ba1-41a992e5664f.png) + +More configuration options will certainly follow at some point, but this setting allows you to indicate whether new Pivot Grids or DAX Query windows will automatically be refreshed, by default, when model changes are saved to Analysis Services. You can change this behavior on a per-window basis by toggling the "Auto-execute" button as seen on the screenshot below: + +![image](https://user-images.githubusercontent.com/8976200/104602109-56abd500-567b-11eb-9e8f-32ab58390449.png) + +This feature is super-useful when debugging a measure for example: Update the measure expression in one window, while having a Pivot Grid or a DAX query that uses that measure open in another window. Whenever you hit CTRL+S, the Pivot Grids or DAX Queries are automatically refreshed to immediately show the impact of the change you made. + +## DAX Editor > General + +![image](https://user-images.githubusercontent.com/8976200/104602381-a7233280-567b-11eb-8151-cf810b7cb748.png) + +Now we're starting to get to the good stuff! This page provides a number of settings for general configuration of the DAX editor. Make sure you try out the "Code folding" feature! + +- **DAX function documentation**: Use this setting to specify which URL to launch in the default web browser, whenever you hit F12 while the cursor is on a DAX function. I recommend using https://dax.guide but some people tend to like Microsoft's official documentation (which is available in the drop down). + +## DAX Editor > Auto Formatting + +![image](https://user-images.githubusercontent.com/8976200/104602767-084b0600-567c-11eb-88ea-018e3d436f68.png) + +As can be seen from the screenshot above, the new DAX Editor is **very** powerful and helps you produce beautiful, readable DAX code, as you type. Feel free to experiment with these settings to figure out what editor behavior works best for you, and don't forget to provide [feedback](https://github.com/TabularEditor3/PublicPreview/issues/new) if something does not work as you expect, or if you have any ideas for additional improvements. + +## DAX Editor > Code Assist + +![image](https://user-images.githubusercontent.com/8976200/104603313-90311000-567c-11eb-853d-6ca6e0f0ed07.png) + +On this page, you can configure the two most important Code Assist features, namely calltips (aka. "parameter info") and auto-complete. The settings mostly control under what circumstances the calltips and auto-complete box appears on the screen. However, for the auto-complete, there are a number of features for controlling which items are suggested, whether table names should always be quoted, incremental search, etc. diff --git a/content/localization/zh/privacy-policy_zh.md b/content/localization/zh/privacy-policy_zh.md new file mode 100644 index 00000000..bb3d9958 --- /dev/null +++ b/content/localization/zh/privacy-policy_zh.md @@ -0,0 +1,171 @@ +--- +uid: privacy-policy +title: Privacy Policy +author: Søren Toft Joensen +updated: 2021-09-08 +--- + +# Privacy Policy + +Tabular Editor ApS ("we," "our," or "us") is committed to protecting your privacy. This Privacy Policy explains how your personal information is collected, used, and disclosed by Tabular Editor ApS. + +This Privacy Policy applies to our website, and its associated subdomains (collectively, our "Service") alongside our application, Tabular Editor 3. By accessing or using our Service, you signify that you have read, understood, and agree to our collection, storage, use, and disclosure of your personal information as described in this Privacy Policy and our Terms of Service. + +#### Definitions and key terms + +To help explain things as clearly as possible in this Privacy Policy, every time any of these terms are referenced, they are defined as follows: + +- _Cookie_: small amount of data generated by a website and saved by your web browser. It is used to identify your browser, provide analytics, remember information about you such as your language preference or login information. +- _Company_: when this policy mentions "Company," "we," "us," or "our," it refers to Tabular Editor ApS, (Gærtorvet 3, 2. floor, 1799 Copenhagen V, Denmark) that is responsible for your information under this Privacy Policy. +- _Country_: where Tabular Editor ApS or the owners/founders of Tabular Editor ApS are based, in this case is Denmark +- _Customer_: refers to the company, organization or person that purchases a subscription for Tabular Editor 3. +- _Device_: any internet connected device such as a phone, tablet, computer or any other device that can be used to visit tabulareditor.com and/or use the Tabular Editor 3 product. +- _IP address_: Every device connected to the Internet is assigned a number known as an Internet protocol (IP) address. These numbers are usually assigned in geographic blocks. An IP address can often be used to identify the location from which a device is connecting to the Internet. +- _Personnel_: refers to those individuals who are employed by Tabular Editor ApS or are under contract to perform a service on behalf of one of the parties. +- _Personal Data_: any information that directly, indirectly, or in connection with other information — including a personal identification number — allows for the identification or identifiability of a natural person. +- _Service_: refers to the service provided by Tabular Editor ApS as described in the relative terms (if available) and on this platform. +- _Third-party service_: refers to advertisers, contest sponsors, promotional and marketing partners, and others who provide our content or whose products or services we think may interest you. +- _Website_: Tabular Editor ApS’ site, which can be accessed via this URL: https://tabulareditor.com. + +#### What Information Do We Collect? + +We collect the following information from you when you visit our website, register on our site, place an order, subscribe to our newsletter, respond to a survey or fill out a form: + +- Name +- Email Addresses +- Billing Addresses +- Other personal information that you may submit to us + +#### How Do We Use The Information We Collect? + +Any of the information we collect from you may be used in one of the following ways: + +- To personalize your experience (your information helps us to better respond to your individual needs). +- To improve our website (we continually strive to improve our website/app offerings based on the information and feedback we receive from you). +- To improve customer service (your information helps us to more effectively respond to your customer service requests and support needs). +- To process transactions. +- To send periodic emails. + +#### What is the legal basis for our processing of your personal data? + +Our legal bases for the processing of your personal data for the above purposes are: + +- Fulfilment of contract for the purchase of products or services (the GDPR art. 6 (1) (b)). +- Fulfilment of contract for the provision of services (the GDPR art. 6 (1) (b)). +- Our legal obligations as data controller (the GDPR art. 6 (1) (c)). +- Consent to newsletter send-out and other direct marketing (the GDPR art. 6 (1) (a)). +- Legitimate interest in being able to send out service messages (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to facilitate communications and respond to your comments questions and requests (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to send out customer satisfaction surveys (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to establish, exercise or defence legal claims (the GDPR art. 6 (1) (f) and the GDPR art. 9 (2) (f)). +- Legitimate interest in being able to collect, and administrate your data, also based on your click behaviour in relation to marketing send outs and via cookies on our website (the GDPR art. 6 (1) (f)). +- Legitimate interest in being able to personalize and improve our Services and provide tailored content or features for marketing purposes (the GDPR art. 6 (1) (f)). + +#### Do we share the information we collect with third parties? + +Data processors: + +We do not share the information that we collect with third parties, with the following exceptions: + +We may engage trusted third party service providers acting as data processors to perform functions and provide services to us, such as hosting and maintaining our servers and the website/app, database storage and management, e-mail management, storage marketing, credit card processing, customer service and fulfilling orders for products and services you may purchase through the website/app. We will likely share your personal information, and possibly some non-personal information, with these third parties to enable them to perform these services for us and for you. + +The data processors will not review, share, distribute, or reference any collected information except to the extent they are so instructed by us. All data processors have implemented security measures to protect against unauthorized access, loss, use or alteration of the information. Further, data processing agreements have been entered into with all data processors. + +Currently we use the following data processors:. + +| Name | Location | Purpose of sub-data processing | Which data? | +| ----------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| Chargebee Inc. | AWS EU Data centre in Frankfurt, Germany | Subscription management, including handling of invoicing. | E-mail addresses, name of contact person, billing address and billing information. | +| Amazon.com Inc. | As above | Hosting of the above- mentioned information on behalf of Chargebee Inc. | As above | +| Microsoft | Azure West EU Data Center, Amsterdam, Netherlands | License management | E-mail address and name of contact person/license administrator | + +Other third parties: + +We may share portions of our log file data, including IP addresses, for analytics purposes with third parties such as web analytics partners, application developers, and ad networks. If your IP address is shared, it may be used to estimate general location and other technographics such as connection speed, whether you have visited the website/app in a shared location, and type of the device used to visit the website/app. They may aggregate information about our advertising and what you see on the website/app and then provide auditing, research and reporting for us and our advertisers. + +We may also disclose personal and non-personal information about you to government or law enforcement officials or private parties as we, in our sole discretion, believe necessary or appropriate in order to respond to claims, legal process (including subpoenas), to protect our rights and interests or those of a third party, the safety of the public or any person, to prevent or stop any illegal, unethical, or legally actionable activity, or to otherwise comply with applicable court orders, laws, rules and regulations. + +#### How Do We Use Your Email Address? + +By submitting your email address on this website/app, you agree to receive emails from us. You can cancel your participation in any of these email lists at any time by clicking on the opt-out link or other unsubscribe option that is included in the respective email. We only send emails to people who have authorized us to contact them, either directly, or through a third party. We do not send unsolicited commercial emails, because we hate spam as much as you do. Email addresses submitted only through the order processing page will be used for the sole purpose of sending you information and updates pertaining to your order. If, however, you have provided the same email to us through another method, we may use it for any of the purposes stated in this Policy. + +Note: If at any time you would like to unsubscribe from receiving future emails, we include detailed unsubscribe instructions at the bottom of each email. + +#### How Long Do We Keep Your Information? + +We keep your information only so long as we need it to provide Tabular Editor 3 to you and/or fulfil the purposes described in this policy. This is also the case for anyone that we share your information with and who carries out services on our behalf. When we no longer need to use your information and there is no need for us to keep it to comply with our legal or regulatory obligations, we’ll either remove it from our systems or depersonalize it so that we can’t identify you. + +#### How Do We Protect Your Information? + +We implement a variety of security measures to maintain the safety of your personal information when you place an order or enter, submit, or access your personal information. We offer the use of a secure server. All supplied sensitive/credit information is transmitted via Secure Socket Layer (SSL) technology and then encrypted into our Payment gateway providers database only to be accessible by those authorized with special access rights to such systems, and are required to keep the information confidential. After a transaction, your private information (credit cards, social security numbers, financials, etc.) is never kept on file. We cannot, however, ensure or warrant the absolute security of any information you transmit to Tabular Editor ApS or guarantee that your information on the Service may not be accessed, disclosed, altered, or destroyed by a breach of any of our physical, technical, or managerial safeguards. + +Credit Card information is collected and processed only by our payment/subscription partner, which currently is Chargebee.com. Tabular Editor ApS does not collect or store Credit Card information. + +#### Could my information be transferred to other countries? + +Tabular Editor ApS is incorporated in Denmark. Information collected via our website, through direct interactions with you, or from use of our help services may be transferred from time to time to our offices or personnel, or to third parties within the EU/EEA. We do not transfer your information to unsecure third countries, i.e. countries outside of EU/EEA that have not been considered by the Commission to have an adequate level of data protection. + +#### Is the information collected through the Tabular Editor Service secure? + +We take precautions to protect the security of your information. We have physical, electronic, and managerial procedures to help safeguard, prevent unauthorized access, maintain data security, and correctly use your information. However, neither people nor security systems are fool proof, including encryption systems. In addition, people can commit intentional crimes, make mistakes or fail to follow policies. Therefore, while we use reasonable efforts to protect your personal information, we cannot guarantee its absolute security. If applicable law imposes any non-disclaimable duty to protect your personal information, you agree that intentional misconduct will be the standards used to measure our compliance with that duty. + +#### Can I update or correct my information and which other rights to I have? + +Customers and users of our website have the right to request the restriction of certain uses and disclosures of personally identifiable information as follows: You can contact us in order to (1) receive information about which personal data we are processing about you and for what purposes, (2) to have personal information that we are processing about you transferred to another service provider (data portability), if applicable, (3) update or correct your personally identifiable information, (4) change your preferences with respect to communications and other information you receive from us, or (5) delete the personally identifiable information maintained about you on our systems (subject to the following paragraph), by cancelling your account. + +Such updates, corrections, changes and deletions will have no effect on other information that we maintain, or information that we have provided to third parties in accordance with this Privacy Policy prior to such update, correction, change or deletion. + +To protect your privacy and security, we may take reasonable steps (such as requesting a unique password) to verify your identity before granting you profile access or making corrections. You are responsible for maintaining the secrecy of your unique password and account information at all times. + +Promptly after receiving your request, all personal information stored in databases we actively use, and other readily searchable media will be updated, corrected, changed or deleted, as appropriate, as soon as and to the extent reasonably and technically practicable. + +If you are an end user and wish to update, delete, or receive any information we have about you, you may do so by contacting at the following e-mail address: [contact@tabulareditor.com](mailto:contact@tabulareditor.com). + +You may also use this mail address to withdraw any consents to our processing of your personal data. + +#### Sale of Business + +We reserve the right to transfer information to a third party in the event of a sale, merger or other transfer of all or substantially all of the assets of Tabular Editor or any of its Corporate Affiliates (as defined herein), or that portion of Tabular Editor or any of its Corporate Affiliates to which the Service relates, or in the event that we discontinue our business or file a petition or have filed against us a petition in bankruptcy, reorganization or similar proceeding, provided that the third party agrees to adhere to the terms of this Privacy Policy. + +#### Governing Law + +This Privacy Policy is governed by the laws of Denmark without regard to its conflict of laws provision. +The laws of Denmark, excluding its conflicts of law rules, shall govern any contracts we enter with you and your use of the website/app. Your use of the website/app may also be subject to other local, state, national, or international laws. + +#### Acceptance of this Privacy Policy + +By using Tabular Editor or contacting us directly, you signify your acceptance of this Privacy Policy. If you do not agree to this Privacy Policy, you should not engage with our website, or use our services. Continued use of the website, direct engagement with us, or following the posting of changes to this Privacy Policy that do not significantly affect the use or disclosure of your personal information will mean that you accept those changes. + +We’ve updated our Privacy Policy to provide you with complete transparency into what is being set when you visit our site and how it’s being used. By using our website/app, registering an account, or making a purchase, you hereby consent to our Privacy Policy and agree to its terms. + +#### Links to Other Websites + +This Privacy Policy applies only to the Services. The Services may contain links to other websites not operated or controlled by Tabular Editor. We are not responsible for the content, accuracy or opinions expressed in such websites, and such websites are not investigated, monitored or checked for accuracy or completeness by us. Please remember that when you use a link to go from the Services to another website, our Privacy Policy is no longer in effect. Your browsing and interaction on any other website, including those that have a link on our platform, is subject to that website’s own rules and policies. Such third parties may use their own cookies or other methods to collect information about you. + +\####Cookies +tabulareditor.com uses "Cookies" to identify the areas of our website that you have visited. We use Cookies to enhance the performance and functionality of our website/app but are non-essential to their use. However, without these cookies, certain functionality like videos may become unavailable or you would be required to enter your login details every time you visit the website/app as we would not be able to remember that you had logged in previously. Most web browsers can be set to disable the use of Cookies. However, if you disable Cookies, you may not be able to access functionality on our website correctly or at all. We never place Personally Identifiable Information in Cookies. + +You should also be aware that you may also lose some saved information (e.g. saved login details, site preferences) if you block cookies on your browser. Different browsers make different controls available to you. Disabling a cookie or category of cookie does not delete the cookie from your browser, you will need to do this yourself from within your browser, you should visit your browser’s help menu for more information. + +#### Payment Details + +In respect to any credit card or other payment processing details you have provided us, we commit that this confidential information will be stored in the most secure manner possible. + +#### Kids’ Privacy + +We do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 13 without verification of parental consent, We take steps to remove that information from Our servers. + +#### Changes To Our Privacy Policy + +We may change our Service and policies, and we may need to make changes to this Privacy Policy so that they accurately reflect our Service and policies. Unless otherwise required by law, we will notify you (for example, through our Service) before we make changes to this Privacy Policy and give you an opportunity to review them before they go into effect. Then, if you continue to use the Service, you will be bound by the updated Privacy Policy. If you do not want to agree to this or any updated Privacy Policy, you can delete your account. + +#### Contact Us + +Don’t hesitate to contact us if you have any questions. + +- Via Email: contact@tabulareditor.com +- Via this Link: https://tabulareditor.com/contact + +#### Complaints + +If you wish to complain about the processing of your personal data, please contact us at [contact@tabulareditor.com](mailto:contact@tabulareditor.com). You may also contact the Data Protection Agency, Borgergade 28, 5., 1300 Copenhagen K. diff --git a/content/localization/zh/properties-view_zh.md b/content/localization/zh/properties-view_zh.md new file mode 100644 index 00000000..380903ff --- /dev/null +++ b/content/localization/zh/properties-view_zh.md @@ -0,0 +1,34 @@ +--- +uid: properties-view +title: Properties view +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Using the Properties grid in Tabular Editor 3 + +The Properties view in Tabular Editor 3 allows you to inspect and modify the properties of any object in your tabular model. +You access the properties view by selecting an object in the TOM Explorer. You will then see a list of properties that are relevant for the selected object type, such as name, description, data type, format string, etc. +You can also access advanced properties that are not available in other tools like Visual Studio or Power BI Desktop. + +
    + Properties View
    Figure 1: Example of Properties for a table. Each object has different properties depending on its type
    +
    + +The Properties view helps you to: + +- View and modify the properties of any object in the model, such as tables, columns, measures, hierarchies, relationships, partitions, roles and perspectives. +- Filter and sort the properties by name or category using the search box and the buttons at the top of the view. +- Copy and paste property values between different objects using Ctrl+C and Ctrl+V shortcuts. +- Undo and redo property changes using Ctrl+Z and Ctrl+Y shortcuts. +- You can use keyboard shortcuts to quickly navigate and edit your properties. For example, you can press Ctrl+Up or Ctrl+Down to move between different properties; press Enter or F2 to edit a property value; press Esc to cancel editing; press Ctrl+S to save changes; + +> [!TIP] +> You can multi-select objects to see the properties they have in common and edit them in bulk. This can be useful for setting Format Strings, for example. + +The Properties view is by default in the bottom right corner, but you can also open it by pressing F4 on your keyboard. You can also dock it to any side of the main window or undock it as a separate window. diff --git a/content/localization/zh/proxy-settings_zh.md b/content/localization/zh/proxy-settings_zh.md new file mode 100644 index 00000000..13661a65 --- /dev/null +++ b/content/localization/zh/proxy-settings_zh.md @@ -0,0 +1,99 @@ +--- +uid: proxy-settings +title: Proxy settings +author: Daniel Otykier +updated: 2024-11-07 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Proxy settings + +Due to different proxy behavior between .NET Core (used by Tabular Editor 3) and .NET Framework (used by Tabular Editor 2 and DAX Studio), you may experience issues with connecting to external services, such as the Power BI service, when using Tabular Editor 3 behind a proxy server. + +For example, you might see the following error message when trying to connect to the Power BI service: + +![No such host is known-error](~/content/assets/images/proxy-error.png) + +Typical error messages you would see, are: + +**Title:** `Could not connect to server` + +**Message:** + +- `No such host is known. (login.microsoftonline.com:443)` +- `Unable to obtain authentication token using the credentials provided` +- `The requested address is not valid in its context. (login.microsoftonline.com:443)` + +When this happens, the first thing you should try is to change the proxy settings in Tabular Editor 3. You can find these settings under **Tools > Preferences > Proxy Settings**: + +![Proxy settings in Tabular Editor 3](~/content/assets/images/proxy-settings.png) + +In most cases, changing the **Proxy Type** from `None` to `System` will resolve the issue. This setting tells Tabular Editor 3 to use the system-wide proxy settings configured in Windows. If you are still experiencing issues, you can try setting the **Proxy Type** to `Custom` and enter the proxy server address and port manually. + +> [!IMPORTANT] +> After changing the proxy settings, you must restart Tabular Editor 3 for the changes to take effect. + +# .NET Core vs. .NET Framework proxy handling + +If the suggestion above does not solve the problem, starting with version 3.21.0 of Tabular Editor, you can try the following alternative solution: + +> [!NOTE] +> The solutions outlined below require Tabular Editor 3.21.0 or newer, because the AS configuration options are only available in the AMO/TOM client library v. [19.94.1.1](https://www.nuget.org/packages/Microsoft.AnalysisServices/19.94.1.1). Previous versions of Tabular Editor 3 use an older version of this client library, which ignores these configuration options. + +Create a file called **AnalysisServices.AppSettings.json** and put it in the installation folder for Tabular Editor 3 (i.e. the same folder that TabularEditor3.exe resides in). Add the following content to the file: + +```json +{ + "asConfiguration": { + "authentication": { + "msalConnectivityMode": "external" + } + } +} +``` + +To turn on external MSAL proxy support for all .NET core applications on your machine, you can also set the following environment variable rather than using the AppSettings file as described above: + +| Environment variable name | Environment variable value | +| -------------------------------------------------------------------- | -------------------------- | +| MS_AS_MsalConnectivityMode | 1 | + +# Enabling diagnostics + +If you're still not able to connect after attempting the solutions outlined above, it may help to turn on advanced diagnostics logging. You can do that, either by modifying the **AnalysisServices.AppSettings.json** file to look like the following: + +```json +{ + "asConfiguration": { + "authentication": { + "msalConnectivityMode": "external" + }, + "diagnostics": { + "authenticationTrace": { + "isEnabled": true, + "traceLevel": 4, + "fileName": "" + } + } + } +} +``` + +or if using Environment Variables, by setting the following: + +| Environment variable name | Environment variable value | +| ---------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| MS_AS_AADAUTHENTICATOR_LOG | 1 | +| MS_AS_AADAUTHENTICATOR_LOGLEVEL | 4 | +| MS_AS_AADAUTHENTICATOR_LOGFILE | \ | + +`` must point to a file in a directory that exists. I.e. if you want the file to be written to `c:\temp\logs\as-auth.log`, you must ensure that the directory `c:\temp\logs` exists. + +The contents of this trace file is useful when contacting Microsoft support. + +> [!IMPORTANT] +> You must restart Tabular Editor 3 after making changes to the **AnalysisServices.AppSettings.json** file, or after modifying environment variables. \ No newline at end of file diff --git a/content/localization/zh/refresh-preview-query_zh.md b/content/localization/zh/refresh-preview-query_zh.md new file mode 100644 index 00000000..ba295b87 --- /dev/null +++ b/content/localization/zh/refresh-preview-query_zh.md @@ -0,0 +1,163 @@ +--- +uid: refresh-preview-query +title: Refreshing, previewing and querying data +author: Daniel Otykier +updated: 2021-09-30 +applies_to: + editions: + - edition: Desktop + partial: Refreshing tables through external tools is currently not supported by Power BI Desktop, even though Tabular Editor 3 Desktop Edition allows this operation. Querying data is fully supported. + - edition: Business + - edition: Enterprise +--- + +# Refreshing, previewing and querying data + +When Tabular Editor 3 is connected to an instance of Analysis Services, a number of additional **connected features** are available, allowing you to use Tabular Editor 3 as a client tool for Analysis Services. + +> [!NOTE] +> The phrase "connected to an instance of Analysis Services" means any one of the following: +> +> - Loading a model in [**workspace mode**](xref:workspace-mode) +> - Loading a model directly from SQL Server Analysis Services, Azure Analysis Services or the Power BI XMLA endpoint +> - Using Tabular Editor 3 as an external tool for Power BI Desktop + +In summary, these connected features are: + +- Data refresh operations +- Table data previewing +- PivotGrids +- DAX Querying +- VertiPaq Analyzer + +# Refreshing data + +Tabular Editor does not automatically trigger refresh operations in Analysis Services when changes are made to the data model. This is by design, to ensure that saving metadata changes to Analysis Services does not take too long. Potentially, a refresh operation can take a long time to complete, during which no additional metadata may be updated on the server. Of course, the drawback of this, is that you can make changes using Tabular Editor, which causes the model to enter a state where it is only partly queryable or not queryable at all. Depending on what type of data model change was made, different levels of refresh may be needed. + +In general, the following changes require a full refresh, before the mentioned object can be queried (that is, a data refresh followed by a calculate refresh): + +- Adding a new table to the model +- Adding a new column to a table + +In general, the following changes require a calculate refresh: + +- Changing the DAX expression of a calculated table or calculated column +- Adding or modifying a relationship +- Adding, renaming or removing a calculation item from a calculation group + +Notably, adding, modifying or removing measures from a model does not require any type of refresh (unless the measure is referenced by a calculated column, in which case the table in which that column resides has to be recalculated). + +To initiate a refresh using Tabular Editor, simply right click on the Table or Partition you wish to refresh, navigate to **Refresh table** or **Refresh partition**, and then choose the type of refresh you want to perform. + +![Refresh Table](~/content/assets/images/refresh-table.png) + +You may also initiate a refresh at the model level through the **Model > Refresh model** menu. Once the refresh operation starts, you will see the text "Data refresh started... View refresh queue". Click on the link or locate the **Data refresh** view through the **View > Data refresh** menu option. This will display a list of all refresh operations (both present and current), displaying the status message returned from Analysis Services including progress counters and duration, and allowing you to cancel an unintended refresh. + +![Data Refresh View2](~/content/assets/images/data-refresh-view2.png) + +While a refresh is in progress you can continue work on your data model, querying and previewing data or queueing new data refresh operations according to this article. However, you will not be able to save model changes to Analysis Services until the all data refresh operations complete. + +> [!NOTE] +> Currently, [Power BI Desktop does not support refresh operations triggered from external tools](https://docs.microsoft.com/en-us/power-bi/transform-model/desktop-external-tools#data-modeling-operations). For this reason, Tabular Editor 3 hides these options when connected to an instance of Power BI Desktop. You can override this behavior by enabling **Tools > Preferences > Allow unsupported modeling operations**. + +## Supported refresh operations + +Tabular Editor 3 supports refresh operations on different object types. The supported refresh types are shown below: + +- **Model** (Automatic, calculate, full) +- **(Imported) Table** (Automatic, calculate, data only, full) +- **Partition** (Full) +- **Calculated Table** (Calculate) +- **Calculation Group** (Calculate) + +See [Refresh Types](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#request) for more information about the types of refresh operations supported by Analysis Services / Power BI. + +# Previewing table data + +At certain points during DAX authoring and data model development, you may need to inspect the contents of your tables on a row-by-row basis. Of course, you could write a DAX query to achieve this, but Tabular Editor 3 makes that even easier by allowing you to preview table data directly. To do this, right-click on a table and choose the **Preview data** option. + +![Preview Data](~/content/assets/images/preview-data-big.png) + +You can open multiple such table previews and arrange them anyway you like in the user interface. In addition, you can sort or filter individual columns. There is no practical limit to the number of rows that can be previewed. Tabular Editor simply executes a [`TOPNSKIP`](https://dax.guide/topnskip) DAX query against the model, to return just a small number of records suitable to fill the current view. + +If one or more calculated columns are in an invalid state, those columns contain the text _(Calculation needed)_. You can recalculate the table by right-clicking on the column and choosing the **Recalculate table...** option. + +![Recalculate Table](~/content/assets/images/recalculate-table.png) + +# Pivot Grids + +After adding or editing DAX measures in a model, it is common for model developers to test these measures. Traditionally, this was typically done using client tools such as Excel or Power BI. With Tabular Editor 3, you can now use **Pivot Grids** which behave much like the famous PivotTables of Excel. The Pivot Grid lets you quickly create summarized views of the data in your model, allowing you test the behavior of your DAX measures when filtering and slicing by various columns and hierarchies. + +To create a new Pivot Grid, use the **File > New > Pivot Grid** option. From here, you can either drag measures, columns and hierarchies from the TOM Explorer into the grid, or you can use the **Pivot Grid > Show fields** menu option to display a popup list of all fields that can be dragged into the Pivot Grid (see screenshot below). + +![Show Fields Pivot](~/content/assets/images/show-fields-pivot.png) + +As fields are dragged into the Pivot Grid, Tabular Editor generates MDX queries that are sent to Analysis Services, to display the resulting data. In this regard, the behavior is very similar to Pivot Tables in Excel. You can rearrange fields in the Pivot Grid by dragging and dropping, and there are various right-click menu options available for customizing how the data is displayed. + +![Customizing Pivot Grids](~/content/assets/images/customizing-pivot-grids.png) + +The Pivot Grid is automatically refreshed when a change is made to the model or a refresh operation finishes. You can toggle this auto-refresh capability within the **Pivot Grid** menu. + +# DAX Queries + +A more direct way to query the data in your model, is to write a DAX query. Use the **File > New > DAX Query** menu option to create a new DAX query document. You can have multiple DAX query documents open at the same time. + +DAX queries can be saved and loaded to and from standalone files using the `.dax` or `.msdax` file extension. See @supported-files for more information. + +Type your DAX `EVALUATE` query into the editor and hit **Query > Execute** (F5) to send the query to Analysis Services and see the result. By default, Tabular Editor 3 limits the number of rows returned from Analysis Services to 1000, but this can be changed under **Tools > Preferences > Data Browsing > DAX Query**. If a query exceeds this limit, Tabular Editor 3 displays a shortcut that lets you retrieve all records (see screenshot below). + +![Query Rowset Limit](~/content/assets/images/query-rowset-limit.png) + +> [!WARNING] +> Displaying a large number of records in the query result window could take a while and drastically increase the memory consumed by Tabular Editor 3. + +Tabular Editor 3 uses the same DAX code editor for query editing as for defining DAX expressions on objects. As such, all the features regarding code-completion, auto-formatting, etc. are available. See @dax-editor for more information. In addition, since a DAX query has a slightly different syntax than object expressions, the DAX query editor provides a few more options for common tasks. + +For example, if you right-click on a measure reference, there is an option to **Define measure** as seen on the screenshot below. This option will add a `DEFINE MEASURE` statement at the top of your DAX query, allowing you to easily modify the DAX expression of that measure within the scope of the query. + +![Dax Query Features](~/content/assets/images/dax-query-features.png) + +In addition, a DAX query can contain multiple `EVALUATE` statements. When that is the case, Tabular Editor 3 displays the result from each such statement on a separate, numbered tab. If you only want to execute a single `EVALUATE` statement, even though your document contains multiple, you can place the cursor somewhere within the statement you want to execute, and then use the **Query > Execute selection** (SHIFT+F5) option. + +A DAX query in Tabular Editor 3 is automatically refreshed when a change is made to the model or a refresh operation finishes. You can toggle this auto-refresh capability within the **Query** menu. + +# Impersonation + +When querying the data in the model, it is sometimes useful to be able to impersonate a specific user or a combination of roles, to see what the behavior of the model from an end user perspective would be. Tabular Editor 3 allows you to impersonate a specific user or one or more roles, by clicking on the **Impersonate...** button. This applies to [Table previews](#previewing-table-data), [Pivot Grids](#pivot-grids) and [DAX queries](#dax-queries). + +> [!NOTE] +> To impersonate a user, Tabular Editor adds the [`EffectiveUserName` property](https://docs.microsoft.com/en-us/analysis-services/instances/connection-string-properties-analysis-services?view=asallproducts-allversions#effectiveusername) to the connection string, when connecting to Analysis Services. To impersonate a role, Tabular Editor adds the [`Roles` property](https://docs.microsoft.com/en-us/analysis-services/instances/connection-string-properties-analysis-services?view=asallproducts-allversions#roles) to the connection string. This only applies to the data view (i.e. the DAX query, the Pivot Grid or the Table Preview) where the impersonation is specified. + +When clicking on the **Impersonation..** button (which can also be found through the **Query**, **Pivot Grid** or **Table Preview** menu, depending on which type of data view is active), a popup allows you to specify either a user, or select one or more roles. + +![Select Impersonation](~/content/assets/images/select-impersonation.png) + +Once the impersonation is enabled, the **Impersonation..** button is checked, and the impersonation will be applied to the current data view. By clicking on the small arrow next to the **Impersonation..** button, you can view and quickly switch between the 10 most recent impersonations used. + +![Impersonation Dropdown](~/content/assets/images/impersonation-dropdown.png) + +When auto-refresh is enabled on a data view, changing the impersonation will immediately refresh the view. + +# VertiPaq Analyzer + +Tabular Editor 3 includes a version of the open-source [VertiPaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer/) tool, created by [SQLBI](https://sqlbi.com). VertiPaq Analyzer is useful to analyze VertiPaq storage structures for your Power BI or Tabular data model. + +With Tabular Editor 3, you can collect VertiPaq Analyzer statistics while you are connected to any instance of Analysis Services. You can also export the statistics as a [.vpax file](https://www.youtube.com/watch?v=zRa9y01Ub30), or import statistics from a .vpax file. + +To collect statistics, simply hit the **Collect stats** button in the **VertiPaq Analyzer** view. + +![Vertipaq Analyzer Collect Stats](~/content/assets/images/vertipaq-analyzer-collect-stats.png) + +Once statistics are collected, VertiPaq Analyzer displays a summary of the model size, number of tables, etc. You can find more detailed statistics on the **Tables**, **Columns**, **Relationships** and **Partitions** tabs. + +Additionally, whenever statistics have been loaded, Tabular Editor 3 will display cardinality and size information as a tooltip when hovering the mouse cursor over objects in the TOM Explorer: + +![Vertipaq Analyzer Stats in TOM Explorer](~/content/assets/images/vertipaq-analyzer-stats.png) + +...or when hovering the mouse cursor over object references in DAX expressions: + +![Vertipaq Analyzer Stats in a DAX expression](~/content/assets/images/vertipaq-analyzer-stats-dax.png) + +# Next steps + +- @creating-and-testing-dax \ No newline at end of file diff --git a/content/localization/zh/release-history_zh.md b/content/localization/zh/release-history_zh.md new file mode 100644 index 00000000..4ea941a1 --- /dev/null +++ b/content/localization/zh/release-history_zh.md @@ -0,0 +1,346 @@ +# Full release history + +- 2025-09-15 **Tabular Editor 3.23.1** (_[Release notes](release-notes/3_23_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.1.ARM64.Net8.msi) +- 2025-08-28 **Tabular Editor 3.23.0** (_[Release notes](release-notes/3_23_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.x64.Net8.exe), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.Installer.ARM64.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.zip), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.x64.Net8.msi), [ARM64](https://cdn.tabulareditor.com/files/TabularEditor.3.23.0.ARM64.Net8.msi) +- 2025-06-28 **Tabular Editor 3.22.1** (_[Release notes](release-notes/3_22_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.1.x86.Net8.msi) +- 2025-06-19 **Tabular Editor 3.22.0** (_[Release notes](release-notes/3_22_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.22.0.x86.Net8.msi) +- 2025-04-25 **Tabular Editor 3.21.0** (_[Release notes](release-notes/3_21_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.21.0.x86.Net8.msi) +- 2025-04-11 **Tabular Editor 3.20.1** (_[Release notes](release-notes/3_20_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.1.x86.msi) +- 2025-02-21 **Tabular Editor 3.20.0** (_[Release notes](release-notes/3_20_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.20.0.x86.msi) +- 2024-12-19 **Tabular Editor 3.19.0** (_[Release notes](release-notes/3_19_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.19.0.x86.msi) +- 2024-11-14 **Tabular Editor 3.18.2** (_[Release notes](release-notes/3_18_2.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.2.x86.msi) +- 2024-11-11 **Tabular Editor 3.18.1** (_[Release notes](release-notes/3_18_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.1.x86.msi) +- 2024-10-31 **Tabular Editor 3.18.0** (_[Release notes](release-notes/3_18_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.18.0.x86.msi) +- 2024-08-22 **Tabular Editor 3.17.1** (_[Release notes](release-notes/3_17_1.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.1.x86.msi) +- 2024-08-14 **Tabular Editor 3.17.0** (_[Release notes](release-notes/3_17_0.md)_) + - .NET 8 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.Net8.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.Net8.exe) + - .NET 8 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.zip) + - .NET 8 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.Net8.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.Net8.msi) + - .NET 6 installer (.exe): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x64.exe), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.Installer.x86.exe) + - .NET 6 portable (.zip): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.zip), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.zip) + - .NET 6 installer (.msi): [x64](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x64.msi), [x86](https://cdn.tabulareditor.com/files/TabularEditor.3.17.0.x86.msi) +- 2024-06-19 **Tabular Editor 3.16.2** (_[Release notes](release-notes/3_16_2.md)_) + - [TabularEditor.3.16.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x64.exe) + - [TabularEditor.3.16.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.Installer.x86.exe) + - [TabularEditor.3.16.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.zip) + - [TabularEditor.3.16.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.zip) + - [TabularEditor.3.16.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x64.msi) + - [TabularEditor.3.16.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.2.x86.msi) +- 2024-06-17 **Tabular Editor 3.16.1** (_[Release notes](release-notes/3_16_1.md)_) + - [TabularEditor.3.16.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x64.exe) + - [TabularEditor.3.16.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.Installer.x86.exe) + - [TabularEditor.3.16.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.zip) + - [TabularEditor.3.16.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.zip) + - [TabularEditor.3.16.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x64.msi) + - [TabularEditor.3.16.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.1.x86.msi) +- 2024-06-10 **Tabular Editor 3.16.0** (_[Release notes](release-notes/3_16_0.md)_) + - [TabularEditor.3.16.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x64.exe) + - [TabularEditor.3.16.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.Installer.x86.exe) + - [TabularEditor.3.16.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.zip) + - [TabularEditor.3.16.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.zip) + - [TabularEditor.3.16.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x64.msi) + - [TabularEditor.3.16.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.16.0.x86.msi) +- 2024-04-17 **Tabular Editor 3.15.0** (_[Release notes](release-notes/3_15_0.md)_) + - [TabularEditor.3.15.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x64.exe) + - [TabularEditor.3.15.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.Installer.x86.exe) + - [TabularEditor.3.15.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.zip) + - [TabularEditor.3.15.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.zip) + - [TabularEditor.3.15.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x64.msi) + - [TabularEditor.3.15.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.15.0.x86.msi) +- 2024-02-20 **Tabular Editor 3.14.0** (_[Release notes](release-notes/3_14_0.md)_) + - [TabularEditor.3.14.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x64.exe) + - [TabularEditor.3.14.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.Installer.x86.exe) + - [TabularEditor.3.14.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.zip) + - [TabularEditor.3.14.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.zip) + - [TabularEditor.3.14.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x64.msi) + - [TabularEditor.3.14.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.14.0.x86.msi) +- 2023-12-15 **Tabular Editor 3.13.0** (_[Release notes](release-notes/3_13_0.md)_) + - [TabularEditor.3.13.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x64.exe) + - [TabularEditor.3.13.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.Installer.x86.exe) + - [TabularEditor.3.13.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.zip) + - [TabularEditor.3.13.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.zip) + - [TabularEditor.3.13.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x64.msi) + - [TabularEditor.3.13.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.13.0.x86.msi) +- 2023-12-01 **Tabular Editor 3.12.1** (_[Release notes](release-notes/3_12_1.md)_) + - [TabularEditor.3.12.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x64.exe) + - [TabularEditor.3.12.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.Installer.x86.exe) + - [TabularEditor.3.12.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.zip) + - [TabularEditor.3.12.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.zip) + - [TabularEditor.3.12.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x64.msi) + - [TabularEditor.3.12.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.1.x86.msi) +- 2023-11-27 **Tabular Editor 3.12.0** (_[Release notes](release-notes/3_12_0.md)_) + - [TabularEditor.3.12.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x64.exe) + - [TabularEditor.3.12.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.Installer.x86.exe) + - [TabularEditor.3.12.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.zip) + - [TabularEditor.3.12.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.zip) + - [TabularEditor.3.12.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x64.msi) + - [TabularEditor.3.12.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.12.0.x86.msi) +- 2023-09-25 **Tabular Editor 3.11.0** (_[Release notes](release-notes/3_11_0.md)_) + - [TabularEditor.3.11.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x64.exe) + - [TabularEditor.3.11.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.Installer.x86.exe) + - [TabularEditor.3.11.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.zip) + - [TabularEditor.3.11.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.zip) + - [TabularEditor.3.11.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x64.msi) + - [TabularEditor.3.11.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.11.0.x86.msi) +- 2023-08-30 **Tabular Editor 3.10.1** (_[Release notes](release-notes/3_10_1.md)_) + - [TabularEditor.3.10.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x64.exe) + - [TabularEditor.3.10.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.Installer.x86.exe) + - [TabularEditor.3.10.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.zip) + - [TabularEditor.3.10.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.zip) + - [TabularEditor.3.10.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x64.msi) + - [TabularEditor.3.10.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.1.x86.msi) +- 2023-08-24 **Tabular Editor 3.10.0** (_[Release notes](release-notes/3_10_0.md)_) + - [TabularEditor.3.10.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x64.exe) + - [TabularEditor.3.10.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.Installer.x86.exe) + - [TabularEditor.3.10.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.zip) + - [TabularEditor.3.10.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.zip) + - [TabularEditor.3.10.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x64.msi) + - [TabularEditor.3.10.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.10.0.x86.msi) +- 2023-07-20 **Tabular Editor 3.9.0** (_[Release notes](release-notes/3_9_0.md)_) + - [TabularEditor.3.9.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x64.exe) + - [TabularEditor.3.9.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.Installer.x86.exe) + - [TabularEditor.3.9.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.zip) + - [TabularEditor.3.9.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.zip) + - [TabularEditor.3.9.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x64.msi) + - [TabularEditor.3.9.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.9.0.x86.msi) +- 2023-06-23 **Tabular Editor 3.8.0** (_[Release notes](release-notes/3_7_1.md)_) + - [TabularEditor.3.8.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x64.exe) + - [TabularEditor.3.8.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.Installer.x86.exe) + - [TabularEditor.3.8.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.zip) + - [TabularEditor.3.8.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.zip) + - [TabularEditor.3.8.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x64.msi) + - [TabularEditor.3.8.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.8.0.x86.msi) +- 2023-05-22 **Tabular Editor 3.7.1** (_[Release notes](release-notes/3_7_1.md)_) + - [TabularEditor.3.7.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x64.exe) + - [TabularEditor.3.7.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.Installer.x86.exe) + - [TabularEditor.3.7.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.zip) + - [TabularEditor.3.7.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.zip) + - [TabularEditor.3.7.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x64.msi) + - [TabularEditor.3.7.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.1.x86.msi) +- 2023-05-17 **Tabular Editor 3.7.0** (_[Release notes](release-notes/3_7_0.md)_) + - [TabularEditor.3.7.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x64.exe) + - [TabularEditor.3.7.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.Installer.x86.exe) + - [TabularEditor.3.7.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.zip) + - [TabularEditor.3.7.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.zip) + - [TabularEditor.3.7.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x64.msi) + - [TabularEditor.3.7.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.7.0.x86.msi) +- 2023-04-19 **Tabular Editor 3.6.0** (_[Release notes](release-notes/3_6_0.md)_) + - [TabularEditor.3.6.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x64.exe) + - [TabularEditor.3.6.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.Installer.x86.exe) + - [TabularEditor.3.6.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.zip) + - [TabularEditor.3.6.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.zip) + - [TabularEditor.3.6.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x64.msi) + - [TabularEditor.3.6.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.6.0.x86.msi) +- 2023-03-28 **Tabular Editor 3.5.1** (_[Release notes](release-notes/3_5_1.md)_) + - [TabularEditor.3.5.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x64.exe) + - [TabularEditor.3.5.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.Installer.x86.exe) + - [TabularEditor.3.5.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.zip) + - [TabularEditor.3.5.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.zip) + - [TabularEditor.3.5.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x64.msi) + - [TabularEditor.3.5.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.1.x86.msi) +- 2023-03-15 **Tabular Editor 3.5.0** (_[Release notes](release-notes/3_5_0.md)_) + - [TabularEditor.3.5.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x64.exe) + - [TabularEditor.3.5.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.Installer.x86.exe) + - [TabularEditor.3.5.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.zip) + - [TabularEditor.3.5.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.zip) + - [TabularEditor.3.5.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x64.msi) + - [TabularEditor.3.5.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.5.0.x86.msi) +- 2023-02-09 **Tabular Editor 3.4.2** (_[Release notes](release-notes/3_4_2.md)_): + - [TabularEditor.3.4.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x64.exe) + - [TabularEditor.3.4.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.Installer.x86.exe) + - [TabularEditor.3.4.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.zip) + - [TabularEditor.3.4.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.zip) + - [TabularEditor.3.4.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x64.msi) + - [TabularEditor.3.4.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.2.x86.msi) +- 2023-02-03 **Tabular Editor 3.4.1** (_[Release notes](release-notes/3_4_1.md)_): + - _Not recommended - use [3.4.2](release-notes/3_4_2.md) instead._ + - [TabularEditor.3.4.1.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x64.exe) + - [TabularEditor.3.4.1.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.Installer.x86.exe) + - [TabularEditor.3.4.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.zip) + - [TabularEditor.3.4.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.zip) + - [TabularEditor.3.4.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x64.msi) + - [TabularEditor.3.4.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.1.x86.msi) +- 2022-12-13 **Tabular Editor 3.4.0** (_[Release notes](release-notes/3_4_0.md)_): + - [TabularEditor.3.4.0.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x64.exe) + - [TabularEditor.3.4.0.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.Installer.x86.exe) + - [TabularEditor.3.4.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.zip) + - [TabularEditor.3.4.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.zip) + - [TabularEditor.3.4.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x64.msi) + - [TabularEditor.3.4.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.4.0.x86.msi) +- 2022-11-11 **Tabular Editor 3.3.6** (_[Release notes](release-notes/3_3_6.md)_): + - [TabularEditor.3.3.6.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x64.exe) + - [TabularEditor.3.3.6.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.Installer.x86.exe) + - [TabularEditor.3.3.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.zip) + - [TabularEditor.3.3.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.zip) + - [TabularEditor.3.3.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x64.msi) + - [TabularEditor.3.3.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.6.x86.msi) +- 2022-09-06 **Tabular Editor 3.3.5** (_[Release notes](release-notes/3_3_5.md)_): + - [TabularEditor.3.3.5.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x64.exe) + - [TabularEditor.3.3.5.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.Installer.x86.exe) + - [TabularEditor.3.3.5.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.zip) + - [TabularEditor.3.3.5.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.zip) + - [TabularEditor.3.3.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x64.msi) + - [TabularEditor.3.3.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.5.x86.msi) +- 2022-08-10 **Tabular Editor 3.3.4** (_[Release notes](release-notes/3_3_4.md)_): + - [TabularEditor.3.3.4.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x64.exe) + - [TabularEditor.3.3.4.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.Installer.x86.exe) + - [TabularEditor.3.3.4.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.zip) + - [TabularEditor.3.3.4.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.zip) + - [TabularEditor.3.3.4.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x64.msi) + - [TabularEditor.3.3.4.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.4.x86.msi) +- 2022-07-17 **Tabular Editor 3.3.3** (_[Release notes](release-notes/3_3_3.md)_): + - [TabularEditor.3.3.3.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x64.exe) + - [TabularEditor.3.3.3.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.Installer.x86.exe) + - [TabularEditor.3.3.3.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.zip) + - [TabularEditor.3.3.3.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.zip) + - [TabularEditor.3.3.3.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x64.msi) + - [TabularEditor.3.3.3.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.3.x86.msi) +- 2022-06-28 **Tabular Editor 3.3.2** (_[Release notes](release-notes/3_3_2.md)_): + - [TabularEditor.3.3.2.Installer.x64.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x64.exe) + - [TabularEditor.3.3.2.Installer.x86.exe](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.Installer.x86.exe) + - [TabularEditor.3.3.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x64.zip) + - [TabularEditor.3.3.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.2.x86.zip) +- 2022-06-16 **Tabular Editor 3.3.0** (_[Release notes](release-notes/3_3_0.md)_): + - [TabularEditor.3.3.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.msi) + - [TabularEditor.3.3.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.msi) + - [TabularEditor.3.3.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x64.zip) + - [TabularEditor.3.3.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.3.0.x86.zip) +- 2022-04-07 **Tabular Editor 3.2.3** (_[Release notes](release-notes/3_2_3.md)_): + - [TabularEditor.3.2.3.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.msi) + - [TabularEditor.3.2.3.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.msi) + - [TabularEditor.3.2.3.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x64.zip) + - [TabularEditor.3.2.3.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.3.x86.zip) +- 2022-02-16 **Tabular Editor 3.2.2** (_[Release notes](release-notes/3_2_2.md)_): + - [TabularEditor.3.2.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.msi) + - [TabularEditor.3.2.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.msi) + - [TabularEditor.3.2.2.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x64.zip) + - [TabularEditor.3.2.2.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.2.x86.zip) +- 2022-01-28 **Tabular Editor 3.2.1** (_[Release notes](release-notes/3_2_1.md)_): + - [TabularEditor.3.2.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.msi) + - [TabularEditor.3.2.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.msi) + - [TabularEditor.3.2.1.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x64.zip) + - [TabularEditor.3.2.1.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.1.x86.zip) +- 2022-01-20 **Tabular Editor 3.2.0** (_[Release notes](release-notes/3_2_0.md)_): + - [TabularEditor.3.2.0.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.msi) + - [TabularEditor.3.2.0.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.msi) + - [TabularEditor.3.2.0.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x64.zip) + - [TabularEditor.3.2.0.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.2.0.x86.zip) +- 2021-12-16 **Tabular Editor 3.1.7** (_[Release notes](release-notes/3_1_7.md)_): + - [TabularEditor.3.1.7.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.msi) + - [TabularEditor.3.1.7.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.msi) + - [TabularEditor.3.1.7.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x64.zip) + - [TabularEditor.3.1.7.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.7.x86.zip) +- 2021-11-23 **Tabular Editor 3.1.6** (_[Release notes](release-notes/3_1_6.md)_): + - [TabularEditor.3.1.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.msi) + - [TabularEditor.3.1.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.msi) + - [TabularEditor.3.1.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x64.zip) + - [TabularEditor.3.1.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.6.x86.zip) +- 2021-11-02 **Tabular Editor 3.1.5** (_[Release notes](release-notes/3_1_5.md)_): + - [TabularEditor.3.1.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.msi) + - [TabularEditor.3.1.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.msi) + - [TabularEditor.3.1.5.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x64.zip) + - [TabularEditor.3.1.5.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.5.x86.zip) +- 2021-10-07 **Tabular Editor 3.1.4** (_[Release notes](release-notes/3_1_4.md)_): + - [TabularEditor.3.1.4.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.msi) + - [TabularEditor.3.1.4.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.msi) + - [TabularEditor.3.1.4.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x64.zip) + - [TabularEditor.3.1.4.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.4.x86.zip) +- 2021-09-30 **Tabular Editor 3.1.3** (_[Release notes](release-notes/3_1_3.md)_): + - [TabularEditor.3.1.3.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.msi) + - [TabularEditor.3.1.3.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.msi) + - [TabularEditor.3.1.3.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x64.zip) + - [TabularEditor.3.1.3.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.1.3.x86.zip) +- 2021-08-10 **Tabular Editor 3.0.10** (_[Release notes](release-notes/3_0_10.md)_): + - [TabularEditor.3.0.10.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.msi) + - [TabularEditor.3.0.10.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.msi) + - [TabularEditor.3.0.10.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x64.zip) + - [TabularEditor.3.0.10.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.10.x86.zip) +- 2021-08-07 **Tabular Editor 3.0.9** (_[Release notes](release-notes/3_0_9.md)_): + - [TabularEditor.3.0.9.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.msi) + - [TabularEditor.3.0.9.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.msi) + - [TabularEditor.3.0.9.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x64.zip) + - [TabularEditor.3.0.9.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.9.x86.zip) +- 2021-08-06 **Tabular Editor 3.0.8** (_[Release notes](release-notes/3_0_8.md)_): + - [TabularEditor.3.0.8.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.msi) + - [TabularEditor.3.0.8.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.msi) + - [TabularEditor.3.0.8.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x64.zip) + - [TabularEditor.3.0.8.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.8.x86.zip) +- 2021-06-30 **Tabular Editor 3.0.7** (_[Release notes](release-notes/3_0_7.md)_): + - [TabularEditor.3.0.7.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.msi) + - [TabularEditor.3.0.7.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.msi) + - [TabularEditor.3.0.7.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x64.zip) + - [TabularEditor.3.0.7.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.7.x86.zip) +- 2021-06-17 **Tabular Editor 3.0.6** (_[Release notes](release-notes/3_0_6.md)_): + - [TabularEditor.3.0.6.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.msi) + - [TabularEditor.3.0.6.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.msi) + - [TabularEditor.3.0.6.x64.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x64.zip) + - [TabularEditor.3.0.6.x86.zip](https://cdn.tabulareditor.com/files/TabularEditor.3.0.6.x86.zip) +- 2021-06-10 **Tabular Editor 3.0.5** (_[Release notes](release-notes/3_0_5.md)_): + - [TabularEditor.3.0.5.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x64.msi) + - [TabularEditor.3.0.5.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.5.x86.msi) +- 2021-06-08 **Tabular Editor 3.0.4** (_[Release notes](release-notes/3_0_4.md)_): + - [TabularEditor.3.0.4.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x64.msi) + - [TabularEditor.3.0.4.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.4.x86.msi) +- 2021-06-03 **Tabular Editor 3.0.2** (_[Release notes](release-notes/3_0_2.md)_): + - [TabularEditor.3.0.2.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x64.msi) + - [TabularEditor.3.0.2.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.2.x86.msi) +- 2021-06-01 **Tabular Editor 3.0.1** (_[Release notes](release-notes/3_0_1.md)_): + - [TabularEditor.3.0.1.x64.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x64.msi) + - [TabularEditor.3.0.1.x86.msi](https://cdn.tabulareditor.com/files/TabularEditor.3.0.1.x86.msi) \ No newline at end of file diff --git a/content/localization/zh/roadmap_zh.md b/content/localization/zh/roadmap_zh.md new file mode 100644 index 00000000..2b4471c4 --- /dev/null +++ b/content/localization/zh/roadmap_zh.md @@ -0,0 +1,121 @@ +--- +uid: roadmap +title: Roadmap +author: Morten Lønskov +updated: 2024-04-23 +--- + +# Tabular Editor 3 Roadmap + +Below is an overview of major new features to be shipped with Tabular Editor 3 updates in the short- to long term: + +# [Planned 2025](#tab/Planned2025) + +- Direct Lake on One Lake support + +- Day zero support for DAX User Defined Functions + +- Support for Calendars + +- Adding more Code Actions + +- Built in Best Practice Rules + +- Built in Macros + +- Power Query (M) Auto-Formatting + +## Shipped in 2025 + +✅ New Code Actions + Knowledge Base for all Code Actions +✅ C# Editor Improvements +✅ Copy TMDL Scripts from TOM Explorer + +# [Future Features](#tab/FutureFeatures) + +## Up Next + +- Localization +- Power Query (M) Editing Enchantments +- Macro Actions improvements such as automatic application across model and preferences for which to apply. +- TOM Properties shown as TMDL and TMSL Scripts. + +## Non Planned Features + +- Standalone CLI application +- Git integration +- DAX Debugger Filter Context visualizer +- Configurable Daxscilla autocomplete code snippets +- Configurable theming for code editors (syntax highlighting colors) +- Incremental deployment (a la [ALM Toolkit](http://alm-toolkit.com/)) + +# [Shipped](#tab/shipped) + +## Shipped in 2024 + +✅ DAX Debugger Locals Enhancement + +✅ Full Direct Lake Integration + +✅ DAX Optimizer Integration (Preview) + +✅ .Net 8 migration + +✅ Pivot Grid Enhancement + +✅ DAX Query Enhancement + +✅ TMDL GA Support + +✅ Code Actions + +✅ GA of DAX Optimizer Integration + +✅ Data Refresh View Improvements + +✅ Power Query (M) Highlighting + +## Shipped in 2023 + +✅ TMDL Support as standard Save to Folder file format. (Depending on release of TMDL by Microsoft) + +✅ Import Table Wizard support for Databricks (pending availability of REST endpoint for fetching metadata/schema) + +✅ Metadata Translation Editor (view that can be opened when selecting one or more cultures, similar to the Tabular Translator tool) + +✅ Perspective Editor (view that can be opened when selecting one or more perspectives, allowing you to check/uncheck objects visible in those perspectives) + +✅ Improved Support for Oracle Databases + +✅ Import Table Wizard support for Power BI datamarts (Use Datamart SQL Endpoint) + +## Shipped in 2022 + +✅ DAX Debugger + +✅ .NET 6 migration + +✅ C# code assist (autocomplete, calltips, etc.) + +✅ Import Table Wizard support for Snowflake + +✅ Import Table Wizard support for Power BI dataflows + +✅ Configurable hotkeys + +✅ Support for DAX window functions + +✅ Git integration (private preview) + +## Shipped in 2021 + +✅ Import Table Wizard + +✅ Portable Version + +✅ Pivot Grid, Table Preview and DAX Query impersonation of a specific role or user, making it easy to test RLS/OLS + +✅ DAX Script support for calculation groups and calculation items + +✅ Offline DAX formatting + diff --git a/content/localization/zh/save-to-folder_zh.md b/content/localization/zh/save-to-folder_zh.md new file mode 100644 index 00000000..59423951 --- /dev/null +++ b/content/localization/zh/save-to-folder_zh.md @@ -0,0 +1,59 @@ +--- +uid: save-to-folder +title: Save to folder +author: Morten Lønskov +updated: 2023-08-08 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Save to folder + +Save to Folder allows you to store your model metadata as individual files, which can be easily managed by version control systems. Instead of having a single file (.bim or .pbix) that contains all the objects of your data model, such as tables, measures, relationships, etc., you can split them into separate files and store them in a folder. This way, you can use source control tools to track the changes, compare versions, and collaborate with other developers on your data model. + +> [!NOTE] +> ou can save your data model to a folder using two different formats: JSON or [TMDL](tmdl-common.md). + +To save your model to folder, follow these steps: + +1. Click on File > Save To Folder +2. Choose a folder where you want to save your model files. +3. Click on Save. Tabular Editor will create or update the files in the selected folder, using the JSON or TMDL format as specified in the serialization settings. +4. You can now use the files in the folder for version control, deployment, or backup purposes. + +## Serialization settings + +The serialization settings defines how the model objects are split into separate files. In these settings you can also define if you wish to use JSON or TMDL formats. + +> [!NOTE] +> SON is the default format as TMDL is currently in preview. + +### [Tabular Editor 2 Preferences](#tab/TE2Preferences) + +Serialization settings are found under File > Preferences > Serialization

    +![TE2 Preferences](~/content/assets/images/common/TE2SaveToFolderSerializationSettings.png) + +The settings shown above are those set as default when using Tabular Editor 3, but are not those that are set per default by Tabular Editor 2.X + +### [Tabular Editor 3 Preferences](#tab/TE3Preferences) + +Serialization settings are found under Tools > Preferences > File Formats +The tabs General and Save-to-folder contains settings regarding the serialization of the model.

    +![TE3 Preferences](~/content/assets/images/common/TE3SaveToFolderSerializationSettings.png) + +Tabular Editor 3 has a default setting for JSON serialization and you must actively choose a different setting in serialization mode, which is also where you change to the TMDL format. + +*** + +### Serialization Model Annotation + +Tabular Editor saves the serialization settings on your model so that they will always stay the same no matter who is working on the model. This ensures that a developer's local preferences do not overwrite model's setting and lead to a unmanageable merge in your source control. You can find these annotations in the TOM Explorer properties of the Model > Annotations > TabularEditor_SerializeOptions

    +![TE3 Preferences](~/content/assets/images/common/SaveToFolderModelAnnotation.png) + +#### Overwriting Model Serialization + +The model's annotation can be overwritten if so desired. First set up the serialization preferences inside Tabular Editor and go to File > Save to Folder. +This open up Windows Explorer and here the ticket button needs to be unselected.

    +![TE3 Preferences](~/content/assets/images/common/SaveToFolderOverwriteModelAnnotation.png) diff --git a/content/localization/zh/script-add-databricks-metadata-descriptions_zh.md b/content/localization/zh/script-add-databricks-metadata-descriptions_zh.md new file mode 100644 index 00000000..6761d276 --- /dev/null +++ b/content/localization/zh/script-add-databricks-metadata-descriptions_zh.md @@ -0,0 +1,576 @@ +--- +uid: script-add-databricks-metadata-descriptions +title: 添加Databricks元数据描述 +author: Johnny Winter +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# 添加Databricks元数据描述 + +## 脚本目的 + +此脚本是Tabular Editor x Databricks系列的一部分。 在Unity Catalog中,可以为表和列提供描述性注释。 此脚本可以重复使用此信息,自动填充语义模型中的表和列描述。

    + +> [!NOTE] +> 此脚本需要安装Simba Spark ODBC驱动程序(从https://www.databricks.com/spark/odbc-drivers-download下载) +> 脚本的每次运行都会提示用户输入Databricks个人访问令牌。 这是向Databricks进行身份验证所必需的。 +> 该脚本使用Unity Catalog中的information_schema表来检索关系信息,因此您可能需要与Databricks管理员进行双重检查,以确保您有权查询这些表。

    + +## 脚本 + +### 添加Databricks元数据描述 + +```csharp +/* + * Title: Add Databricks Metadata descriptions + * Author: Johnny Winter, greyskullanalytics.com + * + * This script, when executed, will loop through the currently selected tables and send a query to Databricks to see if each table has metadata descriptions defined in Unity Catalog. + * Where a description exists, this will be added to the semantic model description. + * Step 1: Select one or more tables in the model + * Step 2: Run this script + * Step 3: Enter your Databricks Personal Access Token when prompted + * Step 4: The script will connect to Databricks and update the table and column descriptions where they exist. + * For each table processed, a message box will display the number of descriptions updated. + * Click OK to continue to the next table. + * Notes: + * - This script requires the Simba Spark ODBC Driver to be installed (download from https://www.databricks.com/spark/odbc-drivers-download) + * - Each run of the script will prompt the user for a Databricks Personal Access Token + */ +#r "Microsoft.VisualBasic" +using System; +using System.Data.Odbc; +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using Microsoft.VisualBasic; +using sysData = System.Data; + +//code to create a masked input box for Databricks PAT token +public partial class PasswordInputForm : Form +{ + public string Password { get; private set; } + + private TextBox passwordTextBox; + private Button okButton; + private Button cancelButton; + private Label promptLabel; + + public PasswordInputForm(string prompt, string title) + { + InitializeComponent(prompt, title); + } + + private void InitializeComponent(string prompt, string title) + { + this.Text = title; + this.Size = new System.Drawing.Size(4000, 1500); + this.StartPosition = FormStartPosition.WindowsDefaultLocation; + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + + // Prompt label + promptLabel = new Label(); + promptLabel.Text = prompt; + promptLabel.Location = new System.Drawing.Point(12, 15); + promptLabel.Size = new System.Drawing.Size(360, 40); + promptLabel.AutoSize = false; + this.Controls.Add(promptLabel); + + // Password textbox + passwordTextBox = new TextBox(); + passwordTextBox.Location = new System.Drawing.Point(12, 55); + passwordTextBox.Size = new System.Drawing.Size(360, 20); + passwordTextBox.UseSystemPasswordChar = true; // This masks the input + passwordTextBox.KeyPress += (s, e) => + { + if (e.KeyChar == (char)Keys.Return) + { + OkButton_Click(null, null); + e.Handled = true; + } + }; + this.Controls.Add(passwordTextBox); + + // OK button + okButton = new Button(); + okButton.Text = "OK"; + okButton.Location = new System.Drawing.Point(216, 85); + okButton.Size = new System.Drawing.Size(150, 50); + okButton.Click += OkButton_Click; + this.Controls.Add(okButton); + + // Cancel button + cancelButton = new Button(); + cancelButton.Text = "Cancel"; + cancelButton.Location = new System.Drawing.Point(297, 85); + cancelButton.Size = new System.Drawing.Size(150, 50); + cancelButton.Click += CancelButton_Click; + this.Controls.Add(cancelButton); + + // Set default and cancel buttons + this.AcceptButton = okButton; + this.CancelButton = cancelButton; + + // Focus on textbox when form loads + this.Load += (s, e) => passwordTextBox.Focus(); + } + + private void OkButton_Click(object sender, EventArgs e) + { + Password = passwordTextBox.Text; + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void CancelButton_Click(object sender, EventArgs e) + { + Password = string.Empty; + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + public static string ShowDialog(string prompt, string title) + { + using (var form = new PasswordInputForm(prompt, title)) + { + if (form.ShowDialog() == DialogResult.OK) + return form.Password; + return string.Empty; + } + } +} + +public static class MaskedInputHelper +{ + public static string GetMaskedInput(string prompt, string title, string defaultValue = "") + { + using (var form = new Form()) + { + form.Text = title; + form.Size = new System.Drawing.Size(1000, 500); + form.StartPosition = FormStartPosition.CenterScreen; + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + + var label = new Label() + { + Left = 12, + Top = 15, + Size = new System.Drawing.Size(900, 100), + Text = prompt, + }; + var textBox = new TextBox() + { + Left = 12, + Top = 150, + Size = new System.Drawing.Size(900, 100), + UseSystemPasswordChar = true, + Text = defaultValue, + }; + var buttonOk = new Button() + { + Text = "OK", + Size = new System.Drawing.Size(150, 50), + Left = 12, + Width = 150, + Top = 200, + DialogResult = DialogResult.OK, + }; + var buttonCancel = new Button() + { + Text = "Cancel", + Size = new System.Drawing.Size(150, 50), + Left = 175, + Width = 150, + Top = 200, + DialogResult = DialogResult.Cancel, + }; + + buttonOk.Click += (sender, e) => + { + form.Close(); + }; + form.Controls.Add(label); + form.Controls.Add(textBox); + form.Controls.Add(buttonOk); + form.Controls.Add(buttonCancel); + form.AcceptButton = buttonOk; + form.CancelButton = buttonCancel; + + return form.ShowDialog() == DialogResult.OK ? textBox.Text : string.Empty; + } + } +} + +//Code to retrieve Databricks Connection information from the M Query in a table partition +public class DatabricksConnectionInfo +{ + public string ServerHostname { get; set; } + public string HttpPath { get; set; } + public string DatabaseName { get; set; } + public string SchemaName { get; set; } + public string TableName { get; set; } + + public override string ToString() + { + return $"Server: {ServerHostname}\n" + + $"HTTP Path: {HttpPath}\n" + + $"Database: {DatabaseName}\n" + + $"Schema: {SchemaName}\n" + + $"Table: {TableName}"; + } +} + +public class PowerQueryMParser +{ + public static DatabricksConnectionInfo ParseMQuery(string mQuery) + { + if (string.IsNullOrWhiteSpace(mQuery)) + throw new ArgumentException("M query cannot be null or empty"); + + var connectionInfo = new DatabricksConnectionInfo(); + + try + { + // Parse Source line to extract server hostname and HTTP path + ParseSourceLine(mQuery, connectionInfo); + + // Parse Database line to extract database name + ParseDatabaseLine(mQuery, connectionInfo); + + // Parse Schema line to extract schema name + ParseSchemaLine(mQuery, connectionInfo); + + // Parse Data line to extract table name + ParseDataLine(mQuery, connectionInfo); + + return connectionInfo; + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error parsing M query: {ex.Message}", ex); + } + } + + private static void ParseSourceLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match both: + // Source = DatabricksMultiCloud.Catalogs("hostname", "httppath", null), + // Source = Databricks.Catalogs("hostname", "httppath", null), + var sourcePattern = + @"Source\s*=\s*Databricks(?:MultiCloud)?\.Catalogs\s*\(\s*""([^""]+)""\s*,\s*""([^""]+)""\s*,\s*null\s*\)"; + var sourceMatch = Regex.Match( + mQuery, + sourcePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!sourceMatch.Success) + throw new FormatException( + "Could not find valid Source definition in M query (supports both Databricks and DatabricksMultiCloud connectors)" + ); + + connectionInfo.ServerHostname = sourceMatch.Groups[1].Value; + connectionInfo.HttpPath = sourceMatch.Groups[2].Value; + } + + private static void ParseDatabaseLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Database = Source{[Name="databasename",Kind="Database"]}[Data], + var databasePattern = + @"Database\s*=\s*Source\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Database""\s*\]\s*}\s*\[\s*Data\s*\]"; + var databaseMatch = Regex.Match( + mQuery, + databasePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!databaseMatch.Success) + throw new FormatException("Could not find valid Database definition in M query"); + + connectionInfo.DatabaseName = databaseMatch.Groups[1].Value; + } + + private static void ParseSchemaLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Schema = Database{[Name="schemaname",Kind="Schema"]}[Data], + var schemaPattern = + @"Schema\s*=\s*Database\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Schema""\s*\]\s*}\s*\[\s*Data\s*\]"; + var schemaMatch = Regex.Match( + mQuery, + schemaPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!schemaMatch.Success) + throw new FormatException("Could not find valid Schema definition in M query"); + + connectionInfo.SchemaName = schemaMatch.Groups[1].Value; + } + + private static void ParseDataLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Data = Schema{[Name="tablename",Kind="Table"]}[Data] + var dataPattern = + @"Data\s*=\s*Schema\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Table""\s*\]\s*}\s*\[\s*Data\s*\]"; + var dataMatch = Regex.Match( + mQuery, + dataPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!dataMatch.Success) + throw new FormatException("Could not find valid Data definition in M query"); + + connectionInfo.TableName = dataMatch.Groups[1].Value; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//main script + + + +//check that user has a table selected +if (Selected.Tables.Count == 0) +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox("Select one or more tables", MsgBoxStyle.Critical, "Table Required"); + return; +} + +//prompt for personal access token - required to authenticate to Databricks +string dbxPAT; +do +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + dbxPAT = MaskedInputHelper.GetMaskedInput( + "Please enter your Databricks Personal Access Token (needed to connect to the SQL Endpoint)", + "Personal Access Token" + ); + + if (string.IsNullOrEmpty(dbxPAT)) + { + return; // User cancelled + } + + if (string.IsNullOrWhiteSpace(dbxPAT)) + { + MessageBox.Show( + "Personal Access Token required", + "Personal Access Token required", + MessageBoxButtons.OK, + MessageBoxIcon.Warning + ); + } +} while (string.IsNullOrWhiteSpace(dbxPAT)); + +// toggle the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = true; + +//for each selected table, get the Databricks connection info from the partition info +foreach (var t in Selected.Tables) +{ + string mQuery = t.Partitions[t.Name].Expression; + var connectionInfo = PowerQueryMParser.ParseMQuery(mQuery); + var columnDescriptions = 0; + var tableDescriptions = 0; + // Access individual components + string serverHostname = connectionInfo.ServerHostname; + string httpPath = connectionInfo.HttpPath; + string databaseName = connectionInfo.DatabaseName; + string schemaName = connectionInfo.SchemaName; + string tableName = connectionInfo.TableName; + //set DBX connection string + var odbcConnStr = + @"DSN=Simba Spark;driver=C:\Program Files\Simba Spark ODBC Driver;host=" + + serverHostname + + ";port=443;httppath=" + + httpPath + + ";thrifttransport=2;ssl=1;authmech=3;uid=token;pwd=" + + dbxPAT; + + //test connection + OdbcConnection conn = new OdbcConnection(odbcConnStr); + try + { + conn.Open(); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Please check the following prequisites: + +- you must have the Simba Spark ODBC Driver installed +(download from https://www.databricks.com/spark/odbc-drivers-download) + +- the ODBC driver must be installed in the path C:\Program Files\Simba Spark ODBC Driver + +- check that the Databricks server name " + + serverHostname + + @" is correct + +- check that the Databricks SQL endpoint / HTTP Path " + + httpPath + + @" is correct + +- check that you have used a valid Personal Access Token", + MsgBoxStyle.Critical, + "Connection Error" + ); + return; + } + + //get table metadata + var tableQuery = + "SELECT comment FROM " + + databaseName + + ".information_schema.tables WHERE table_schema = '" + + schemaName + + "' AND table_name = '" + + tableName + + "'"; + OdbcDataAdapter td = new OdbcDataAdapter(tableQuery, conn); + var dbxTable = new sysData.DataTable(); + + try + { + td.Fill(dbxTable); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Either: + - the table " + + schemaName + + "." + + tableName + + " does not exist" + + @" + + - you do not have permissions to query this table + + - the connection timed out. Please check that the SQL Endpoint cluster is running", + MsgBoxStyle.Critical, + "Connection Error - Table Metadata" + ); + return; + } + string tableUpdate = ""; + foreach (sysData.DataRow row in dbxTable.Rows) + { + if (t.Description != row["comment"].ToString()) + { + t.Description = row["comment"].ToString(); + tableUpdate = t.Name + " table description updated."; + } + } + + //get column metadata + var columnsQuery = @"DESCRIBE " + databaseName + "." + schemaName + "." + tableName; + OdbcDataAdapter da = new OdbcDataAdapter(columnsQuery, conn); + var dbxColumns = new sysData.DataTable(); + + try + { + da.Fill(dbxColumns); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Either: + - the table " + + schemaName + + "." + + tableName + + " does not exist" + + @" + + - you do not have permissions to query this table + + - the connection timed out. Please check that the SQL Endpoint cluster is running", + MsgBoxStyle.Critical, + "Connection Error - Column Metadata" + ); + return; + } + + //update column descriptions + int counter = 0; + foreach (sysData.DataRow row in dbxColumns.Rows) + { + string sourceColumn = row["col_name"].ToString(); + if (sourceColumn.Length != 0) + { + foreach (var c in t.DataColumns) + { + if (c.SourceColumn == sourceColumn && c.Description != row["comment"].ToString()) + { + c.Description = row["comment"].ToString(); + counter = counter + 1; + } + } + } + } + string msg; + if (tableUpdate.Length > 0) + { + msg = + tableUpdate + + @" + +" + + counter + + " descriptions updated on " + + t.Name; + } + else + { + msg = counter + " descriptions updated on " + t.Name; + } + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox(msg, MsgBoxStyle.Information, "Update Metadata Descriptions"); + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = true; + conn.Close(); +} +``` + +### 说明 + +脚本使用WinForms提示输入Databricks个人访问令牌,用于向Databricks进行身份验证。 对于每个选定的表,脚本从选定表分区中的M查询中检索Databricks连接字符串信息以及架构和表名。 然后使用Spark ODBC驱动程序,它向Databricks发送SQL查询,查询information_schema表以返回在Unity Catalog中定义的表描述。 然后在语义模型中的表描述上进行更新。 还发送第二个使用DESCRIBE命令的SQL查询到选定的表以获取列描述。 将这些结果循环通过,在模型中添加描述。 脚本在每个选定的表上运行后,会显示一个对话框,显示更新的描述数量。 + +## 示例输出 + +
    + Prompt for Databricks personal access token
    图1:脚本将提示您输入Databricks个人访问令牌,以便它可以向Databricks进行身份验证。
    +
    + +
    + The number of descriptions updated
    图2:脚本为每个选定的表运行后,将显示更新的描述数量。
    +
    + + + diff --git a/content/localization/zh/script-convert-dlsql-to-dlol_zh.md b/content/localization/zh/script-convert-dlsql-to-dlol_zh.md new file mode 100644 index 00000000..f954590a --- /dev/null +++ b/content/localization/zh/script-convert-dlsql-to-dlol_zh.md @@ -0,0 +1,153 @@ +--- +uid: script-convert-dlsql-to-dlol +title: 将 Direct Lake on SQL 转换为 OneLake +author: Daniel Otykier +updated: 2025-06-20 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# 将 Direct Lake on SQL 转换为 OneLake + +## 脚本用途 + +此脚本将使用 Direct Lake on SQL (DL/SQL) 的模型转换为 Direct Lake on OneLake (DL/OL)。 如 [Direct Lake 指南文章](xref:direct-lake-guidance)中所述,这只需更新模型上 Direct Lake 分区使用的共享表达式上的 M 查询,以使用 [`AzureStorage.DataLake`](https://learn.microsoft.com/en-us/powerquery-m/azurestorage-datalake) 连接器替代 [`Sql.Database`](https://learn.microsoft.com/en-us/powerquery-m/sql-database) 连接器。 + +## 先决条件 + +您需要 **工作区 ID** 以及 Fabric 仓库或湖屋的**资源 ID**。 两者都是 GUID,是在 Fabric 门户中导航到仓库或湖屋时 URL 的一部分: + +![Lakehouse Warehouse URL](~/content/assets/images/lakehouse-warehouse-url.png) + +在上面的屏幕截图中,湖屋的**工作区 ID** 用蓝色突出显示,而**资源 ID** 用绿色突出显示。 + +## 脚本 + +### 将 Direct Lake on SQL 转换为 OneLake + +```csharp +// ================================================================== +// 将 Direct Lake on SQL 转换为 OneLake +// ------------------------------------- +// +// 此脚本检测当前模型是否使用 Direct Lake on SQL +// 并建议将模型升级到 Direct Lake on OneLake。 +// +// 您需要工作区 ID 和 Fabric 仓库 +// 或湖屋的 ID(两者都是 GUID)。 +// ================================================================== + +// 查找模型上 EntityPartitions 使用的共享表达式: +using System.Windows.Forms; +using System.Drawing; + +var partition = Model.AllPartitions.OfType() + .FirstOrDefault(e => e.Mode == ModeType.DirectLake && e.ExpressionSource != null); +var expressionSource = partition == null ? null : partition.ExpressionSource; + +if (expressionSource == null) +{ + Warning("您的模型似乎不包含任何 Direct Lake 模式的表。"); + return; +} + +if (!expressionSource.Expression.Contains("Sql.Database")) +{ + Warning("此模型未配置为通过 SQL 的 Direct Lake。"); + return; +} + +WaitFormVisible = false; +Application.UseWaitCursor = false; +var promptDialog = new UrlNameDialog(); +if(promptDialog.ShowDialog() == DialogResult.Cancel) return; + +const string mTemplate = @"let + Source = AzureStorage.DataLake(""https://onelake.dfs.fabric.microsoft.com/%workspaceId%/%resourceId%"", [HierarchicalNavigation=true]) +in + Source"; + +expressionSource.Expression = mTemplate.Replace("%workspaceId%", promptDialog.WorkspaceId.Text).Replace("%resourceId%", promptDialog.ResourceId.Text); + +if(!string.IsNullOrEmpty(Model.Collation)) +{ + Model.Collation = null; + Info("模型已成功转换为 Direct Lake on OneLake。由于修改了模型排序规则,您可能需要将其部署为新的语义模型。"); +} +else + Info("模型已成功转换为 Direct Lake on OneLake。"); + +// UI 代码在下面: +public class UrlNameDialog : Form +{ + public TextBox WorkspaceId { get; private set; } + public TextBox ResourceId { get; private set; } + private Button okButton; + + public UrlNameDialog() + { + Text = "将 Direct Lake on SQL 转换为 OneLake"; + AutoSize = true; + AutoSizeMode = AutoSizeMode.GrowAndShrink; + StartPosition = FormStartPosition.CenterParent; + Padding = new Padding(20); + + var mainLayout = new TableLayoutPanel + { + ColumnCount = 1, + RowCount = 3, + Dock = DockStyle.Fill, + AutoSize = true, + AutoSizeMode = AutoSizeMode.GrowAndShrink + }; + Controls.Add(mainLayout); + + // 工作区 ID + mainLayout.Controls.Add(new Label { Text = "工作区 ID (GUID):", AutoSize = true }); + WorkspaceId = new TextBox { Width = 1000 }; + mainLayout.Controls.Add(WorkspaceId); + + // 资源 ID + mainLayout.Controls.Add(new Label { Text = "Fabric 仓库/湖屋 ID (GUID):", AutoSize = true, Padding = new Padding(0, 20, 0, 0) }); + ResourceId = new TextBox { Width = 1000 }; + mainLayout.Controls.Add(ResourceId); + + // 按钮 + var buttonPanel = new FlowLayoutPanel + { + Padding = new Padding(0, 20, 0, 0), + FlowDirection = FlowDirection.RightToLeft, + Dock = DockStyle.Fill, + AutoSize = true + }; + + okButton = new Button { Text = "确定", DialogResult = DialogResult.OK, AutoSize = true, Enabled = false }; + var cancelButton = new Button { Text = "取消", DialogResult = DialogResult.Cancel, AutoSize = true }; + buttonPanel.Controls.Add(okButton); + buttonPanel.Controls.Add(cancelButton); + + AcceptButton = okButton; + CancelButton = cancelButton; + mainLayout.Controls.Add(buttonPanel); + + WorkspaceId.TextChanged += Validate; + ResourceId.TextChanged += Validate; + } + + private void Validate(object sender, EventArgs e) + { + Guid g; + okButton.Enabled = Guid.TryParse(WorkspaceId.Text, out g) && Guid.TryParse(ResourceId.Text, out g); + } +} +``` + +### 说明 + +脚本首先尝试查找配置为 Direct Lake 模式且具有表达式源(对共享表达式的引用)的 EntityPartition。 如果未找到这样的分区,它会显示警告消息并退出。 此外,引用的共享表达式必须指定 `Sql.Database` 连接器,这表明模型当前使用的是 Direct Lake on SQL。 + +脚本确认模型使用 Direct Lake on SQL 后,它会提示用户输入 Fabric 仓库或湖屋的**工作区 ID** 和**资源 ID**。 然后脚本用 `AzureStorage.DataLake` 连接器替换共享表达式中的 `Sql.Database` 连接器,并使用提供的 ID。 + +最后,如果模型设置了排序规则,脚本会清除它,因为此更改需要新的排序规则。 脚本然后通知用户模型已成功转换为 Direct Lake on OneLake。 \ No newline at end of file diff --git a/content/localization/zh/script-convert-import-to-dlol_zh.md b/content/localization/zh/script-convert-import-to-dlol_zh.md new file mode 100644 index 00000000..c599eb78 --- /dev/null +++ b/content/localization/zh/script-convert-import-to-dlol_zh.md @@ -0,0 +1,203 @@ +--- +uid: script-convert-import-to-dlol +title: 将导入转换为 OneLake 上的直接湖 +author: Daniel Otykier +updated: 2025-06-20 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# 将导入转换为 OneLake 上的直接湖 + +## 脚本用途 + +此脚本将导入模式表转换为 OneLake 上的直接湖 (DL/OL)。 如 [Direct Lake 指南文章](xref:direct-lake-guidance) 中所述,我们需要用单个 [EntityPartition](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.entitypartitionsource?view=analysisservices-dotnet) 替换此类表上的分区,该分区指定 Fabric Lakehouse 或 Warehouse 中表/物化视图的名称和架构,同时引用使用 [`AzureStorage.DataLake`](https://learn.microsoft.com/en-us/powerquery-m/azurestorage-datalake) (OneLake) 连接器的共享表达式。 + +## 先决条件 + +您将需要 **工作区 ID** 以及 Fabric Warehouse 或 Lakehouse 的 **资源 ID**。 两者都是 GUID,是在 Fabric 门户中导航到 Warehouse 或 Lakehouse 时 URL 的一部分: + +![Lakehouse Warehouse URL](~/content/assets/images/lakehouse-warehouse-url.png) + +在上面的屏幕截图中,lakehouse 的 **工作区 ID** 以蓝色突出显示,而 **资源 ID** 以绿色突出显示。 + +如果您连接到支持架构的 Fabric Warehouse 或 Lakehouse,您还需要了解要连接的表/物化视图的 **架构**。 + +> [!WARNING] +> 导入模式下的表可以在其分区内定义转换(使用 SQL 或 M 表达)。 转换为 OneLake 直接湖模式时,这些转换将丢失,因为直接湖分区必须包含源表/物化视图中列的 1:1 映射。 因此,在运行此脚本之前,请确保源表/物化视图在 Fabric Warehouse 或 Lakehouse 中的名称与在语义模型中的名称相同,并且列映射正确。 + +## 脚本 + +### 将导入模式表转换为 OneLake 上的直接湖 + +```csharp +// ================================================================== +// 将导入转换为 OneLake 上的直接湖 +// ---------------------------------------- +// +// 此脚本将选定的(导入)表或模型中的所有表 +// 转换为 OneLake 上的直接湖表(如果未选择任何内容)。 +// +// 警告:脚本假设表在 Fabric Warehouse 或 Lakehouse +// 中的名称与在语义模型中的名称相同。 +// 此外,导入分区中的任何转换(基于 M 或 SQL)都将丢失, +// 因为直接湖模式表必须包含与源表/物化视图完全相同的列。 +// +// 您将需要工作区 ID 和 Fabric Warehouse +// 或 Lakehouse 的 ID(两者都是 GUID)。 +// ================================================================== + +// 查找模型上的 EntityPartitions 使用的共享表达式: +using System.Windows.Forms; +using System.Drawing; +using System.Data; + +IEnumerable tableSource = Selected.Context.HasFlag(Context.Tables) ? (IEnumerable
    )Selected.Tables : Model.Tables; +var importTables = tableSource.Where(t => t.Partitions.All(p => + (p.SourceType == PartitionSourceType.Query || p.SourceType == PartitionSourceType.M) && + (p.Mode == ModeType.Import || (p.Mode == ModeType.Default && Model.DefaultMode == ModeType.Import)))) + .ToList(); + +WaitFormVisible = false; +Application.UseWaitCursor = false; + +if(importTables.Count == 0) +{ + Warning("模型或选择不包含任何导入模式的表"); + return; +} +else +{ + var result = MessageBox.Show("以下表将被转换:\r\n\r\n" + string.Join("\r\n", importTables.Select(t => " - " + t.Name)) + + "\r\n\r\n继续?", + "确认转换?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); + if (result == DialogResult.Cancel) return; +} + +string workspaceId = string.Empty; +string resourceId = string.Empty; +var sharedExpression = Model.Expressions.FirstOrDefault(e => e.Expression.Contains("AzureStorage.DataLake")); +if(sharedExpression != null) +{ + // 提取现有的工作区 ID 和资源 ID + var ix = sharedExpression.Expression.IndexOf("onelake.dfs.fabric.microsoft.com"); + var url = sharedExpression.Expression.Substring(ix + 33, 73); + var guids = url.Split('/'); + Guid g; + if(Guid.TryParse(guids[0], out g) && Guid.TryParse(guids[1], out g)) + { + workspaceId = guids[0]; + resourceId = guids[1]; + } +} + +var promptDialog = new UrlNameDialog(workspaceId, resourceId); +if(promptDialog.ShowDialog() == DialogResult.Cancel) return; + +const string mTemplate = @"let + Source = AzureStorage.DataLake(""https://onelake.dfs.fabric.microsoft.com/%workspaceId%/%resourceId%"", [HierarchicalNavigation=true]) +in + Source"; + +if(promptDialog.WorkspaceId.Text != workspaceId || promptDialog.ResourceId.Text != resourceId) +{ + if (sharedExpression == null) sharedExpression = Model.AddExpression("DatabaseQuery"); + sharedExpression.Expression = mTemplate.Replace("%workspaceId%", promptDialog.WorkspaceId.Text).Replace("%resourceId%", promptDialog.ResourceId.Text); +} + +foreach(var table in importTables) +{ + var ep = table.AddEntityPartition(); + ep.EntityName = table.Name; + ep.ExpressionSource = sharedExpression; + ep.SchemaName = promptDialog.Schema.Text; + ep.Mode = ModeType.DirectLake; + foreach(var p in table.Partitions.ToList()) if(p != ep) p.Delete(); + ep.Name = table.Name; +} + +Info("表已转换为 OneLake 上的直接湖模式。"); + +public class UrlNameDialog : Form +{ + public TextBox WorkspaceId { get; private set; } + public TextBox ResourceId { get; private set; } + public TextBox Schema { get; private set; } + private Button okButton; + + public UrlNameDialog(string workspaceId, string resourceId) + { + Text = "将直接湖从 SQL 转换为 OneLake"; + AutoSize = true; + AutoSizeMode = AutoSizeMode.GrowAndShrink; + StartPosition = FormStartPosition.CenterParent; + Padding = new Padding(20); + + var mainLayout = new TableLayoutPanel + { + ColumnCount = 1, + RowCount = 3, + Dock = DockStyle.Fill, + AutoSize = true, + AutoSizeMode = AutoSizeMode.GrowAndShrink + }; + Controls.Add(mainLayout); + + // 工作区 ID + mainLayout.Controls.Add(new Label { Text = "工作区 ID (GUID):", AutoSize = true }); + WorkspaceId = new TextBox { Width = 1000, Text = workspaceId }; + mainLayout.Controls.Add(WorkspaceId); + + // 资源 ID + mainLayout.Controls.Add(new Label { Text = "Fabric Warehouse / Lakehouse ID (GUID):", AutoSize = true, Padding = new Padding(0, 20, 0, 0) }); + ResourceId = new TextBox { Width = 1000, Text = resourceId }; + mainLayout.Controls.Add(ResourceId); + + // 架构 + mainLayout.Controls.Add(new Label { Text = "架构(可选):", AutoSize = true, Padding = new Padding(0, 20, 0, 0) }); + Schema = new TextBox { Width = 1000 }; + mainLayout.Controls.Add(Schema); + + + // 按钮 + var buttonPanel = new FlowLayoutPanel + { + Padding = new Padding(0, 20, 0, 0), + FlowDirection = FlowDirection.RightToLeft, + Dock = DockStyle.Fill, + AutoSize = true + }; + + okButton = new Button { Text = "确定", DialogResult = DialogResult.OK, AutoSize = true, Enabled = false }; + var cancelButton = new Button { Text = "取消", DialogResult = DialogResult.Cancel, AutoSize = true }; + buttonPanel.Controls.Add(okButton); + buttonPanel.Controls.Add(cancelButton); + + AcceptButton = okButton; + CancelButton = cancelButton; + mainLayout.Controls.Add(buttonPanel); + + WorkspaceId.TextChanged += Validate; + ResourceId.TextChanged += Validate; + this.Shown += Validate; + } + + private void Validate(object sender, EventArgs e) + { + Guid g; + okButton.Enabled = Guid.TryParse(WorkspaceId.Text, out g) && Guid.TryParse(ResourceId.Text, out g); + } +} +``` + +### 说明 + +脚本首先确定是转换模型中的所有导入模式表还是仅转换用户选择的表。 然后检查是否存在任何此类表,并在继续之前提示用户确认。 + +脚本然后尝试定位使用 `AzureStorage.DataLake` 连接器的共享表达式。 如果存在这样的表达式,它从其表达式中提取工作区 ID 和资源 ID。 如果找不到这样的表达式,它会创建一个新的。 + +然后提示用户输入 Fabric Warehouse 或 Lakehouse 的工作区 ID 和资源 ID,以及可选的架构名称。 如果更改了现有的共享表达式,脚本会用使用提供的 ID 的新表达式替换它。 + +最后,对于每个导入模式表,脚本创建一个具有指定名称和架构的新 EntityPartition,引用共享表达式。 然后它删除该表上不是新创建的 EntityPartition 的任何现有分区。 \ No newline at end of file diff --git a/content/localization/zh/script-count-rows_zh.md b/content/localization/zh/script-count-rows_zh.md new file mode 100644 index 00000000..2a3ea68f --- /dev/null +++ b/content/localization/zh/script-count-rows_zh.md @@ -0,0 +1,54 @@ +--- +uid: script-count-rows +title: Count Table Rows +author: Kurt Buhler +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Count Rows in a Table + +## Script Purpose + +If you want to see how many rows are loaded to a table, or quickly check if the table has been loaded, at all. +This script requires connection to a remote model or connection via Workspace Mode. + +## Script + +### Count the rows in the selected table + +```csharp +// This script counts rows in a selected table and displays the result in a pop-up info box. +// It does not write any changes to this model. +// +// Use this script when you want to check whether a table was loaded or how many rows it has. +// +// Get table name +string _TableName = + Selected.Table.DaxObjectFullName; + +// Count table rows +string _dax = + "{ FORMAT( COUNTROWS (" + _TableName + "), \"#,##0\" ) }"; + +// Evaluate DAX +string _TableRows = + Convert.ToString(EvaluateDax( _dax )); + +// Return output in pop-up +Info ( "Number of rows in " + _TableName + ": " + _TableRows); +``` + +### Explanation + +This snippet goes through the model and counts the different object types, displaying them in a hierarchical "node and tree" format that is manually constructed. +You can comment out + +## Example Output + +
    + Example of the dialog pop-up that informs the user of how many rows are in the selected table upon running the script.
    Figure 1: An example of the Info box that appears to inform the user of how many rows are in the selected table, upon running this script.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-count-things_zh.md b/content/localization/zh/script-count-things_zh.md new file mode 100644 index 00000000..83ce6973 --- /dev/null +++ b/content/localization/zh/script-count-things_zh.md @@ -0,0 +1,204 @@ +--- +uid: script-count-things +title: Count Model Objects +author: Kurt Buhler +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Count Things in the Model + +## Script Purpose + +If you want to get an overview of what's in a model and how many objects there are: + +- How many measures are in a model. +- How many columns & calculated columns are in a model. +- How many tables & calculated tables are in a model. +- How many relationships, inactive relationships, etc. + +## Script + +### Count the number of model objects by Type + +```csharp +// This script counts objects in your model and displays them in a pop-up info box. +// It does not write any changes to this model. +// +// Use this script when you open a new model and need a 'helicopter view' on the contents. +// +// Count calculation groups & calculation items +int _calcgroups = 0; +int _calcitems = 0; +foreach ( var _calcgroup in Model.CalculationGroups ) +{ + _calcgroups = _calcgroups + 1; +  foreach ( var _item in _calcgroup.CalculationItems ) +  { +  _calcitems = _calcitems + 1; +   } +} + +// Count partitions and DAX parameters +int _partitions = 0; +int _whatifparameters = 0; +int _fieldparameters = 0; +foreach ( var _table in Model.Tables ) +{ +  foreach ( var _partition in _table.Partitions ) +  { + string _type = Convert.ToString(_partition.SourceType); + string _exp = Convert.ToString(_partition.Expression); + if ( _type == "M" ) +  { + _partitions = _partitions + 1; + } + else if ( _type == "Calculated" && _exp.Contains("NAMEOF") ) + { + _fieldparameters = _fieldparameters + 1; + } + else if ( _type == "Calculated" && _exp.Contains("GENERATESERIES") ) + { + _whatifparameters = _whatifparameters + 1; + } + +   } +} + +// Average measure length +decimal _numLines = 0; +decimal _numChars = 0; +int _measures = Model.AllMeasures.Count(); +foreach ( var _measure in Model.AllMeasures ) +{ + _numLines = _numLines + _measure.Expression.Split("\n").Length; + _numChars = _numChars + _measure.Expression.Length; +} +_numLines = Math.Round(_numLines / _measures, 1); +_numChars = Math.Round(_numChars / _measures, 1); + + +// Return the pop-up +Info ( "In the model, we see the below objects:\n\n" + + + "-----------------------------------------\n" + + "Data Objects\n" + + "-----------------------------------------\n" + + " ├─ PQ Expressions: " + Convert.ToString(Model.Expressions.Count()) + "\n" + + " │\n" + + " └─ Tables: " + Convert.ToString(Model.Tables.Count()) + "\n" + + " ├─ Incremental Refresh Tables: " + + Convert.ToString(Model.Tables.Where( + _ir => + Convert.ToString(_ir.EnableRefreshPolicy) + == + "True").Count()) + "\n" + + + " │\n" + + " ├─ Calculated Tables: " + + Convert.ToString( + Model.Tables.Where( + _tables => + Convert.ToString(_tables.Columns[0].Type) + == + "CalculatedTableColumn").Count()) + "\n" + + + " │ ├─ What if parameters: " + + Convert.ToString(_whatifparameters) + "\n" + + " │ └─ Field parameters: " + + Convert.ToString(_fieldparameters) + "\n" + + " │\n" + + " ├─ M Partitions: " + + Convert.ToString(_partitions) + "\n" + + " │\n" + + " └─ Total Table Columns: " + + Convert.ToString(Model.AllColumns.Count()) + "\n\n" + + + "-----------------------------------------\n" + + "DAX Objects\n" + + "-----------------------------------------\n" + + " ├─ Relationships: " + + Convert.ToString(Model.Relationships.Count()) + "\n" + + " │ ├─ Bi-directional: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.CrossFilteringBehavior) + == + "BothDirections").Count()) + "\n" + + + " │ ├─ Many-to-Many: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.FromCardinality) + == + "Many" + && + Convert.ToString(_relationships.ToCardinality) + == + "Many").Count()) + "\n" + + + " │ ├─ One-to-One: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.FromCardinality) + == + "One" + && + Convert.ToString(_relationships.ToCardinality) + == + "One").Count()) + "\n" + + + " │ └─ Inactive: " + + Convert.ToString(Model.Relationships.Where( + _relationships => + Convert.ToString(_relationships.IsActive) + == + "False").Count()) + "\n" + + + " │\n" + + " ├─ Calculation Groups: " + + Convert.ToString(_calcgroups) + "\n" + + " │ └─ Calculation Items: " + + Convert.ToString(_calcitems) + "\n" + + " │\n" + + " ├─ Calculated Columns: " + + Convert.ToString(Model.AllColumns.Where( + _columns => + Convert.ToString(_columns.Type) + == + "Calculated").Count()) + "\n" + + + " │\n" + + " └─ Measures: " + + Convert.ToString(_measures) + "\n" + + " └─ Avg. Lines of DAX: " + + Convert.ToString(_numLines) + " Lines \n" + + " └─ Avg. Chars of DAX: " + + Convert.ToString(_numChars) + " Characters \n\n" + + + "-----------------------------------------\n" + + "Other Objects\n" + + "-----------------------------------------\n" + + " ├─ Data Security Roles: " + + Convert.ToString(Model.Roles.Count()) + "\n" + + " ├─ Explicit Data Sources: " + + Convert.ToString(Model.DataSources.Count()) + "\n" + + " ├─ Perspectives: " + + Convert.ToString(Model.Perspectives.Count()) + "\n" + + " └─ Translations: " + + Convert.ToString(Model.Cultures.Count())); +``` + +### Explanation + +This snippet goes through the model and counts the different object types, displaying them in a hierarchical "node and tree" format that is manually constructed. +You can comment out the parts that you do not need for your purposes. + +## Example Output + +
    + Example of the dialog pop-up that informs the user of how many rows are in the selected table upon running the script.
    Figure 1: An example of the Info box output, that informs the user about the number of objects in the model upon script execution. If particular objects are not of interest, the user can comment them out or remove them from the script, and re-run it.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-create-and-replace-M-parameter_zh.md b/content/localization/zh/script-create-and-replace-M-parameter_zh.md new file mode 100644 index 00000000..c5ce6c11 --- /dev/null +++ b/content/localization/zh/script-create-and-replace-M-parameter_zh.md @@ -0,0 +1,200 @@ +--- +uid: script-create-and-replace-parameter +title: Create M Parameter (Auto-Replace) +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 3.x +--- + +# Create New M Parameter and Add it to Existing M Partitions + +## Script Purpose + +If you want to replace a string in model M Partitions (i.e. connection string, filter condition, column name, etc.) with a parameter value.

    + +> [!NOTE] +> This script only works with parameters of `string` data type. +> For other data types, please modify the variable types & parameter value appropriately.

    + +## Script + +### Create New M Parameter and Add it to Existing M Partitions + +```csharp +// This script creates a new M Parameter as a 'Shared Expression'. +// It will also find the default value in all M partitions and replace them with the parameter object name. +//#r "System.Drawing" + +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Initialize variables +string _ParameterName = "New Parameter"; +string _ParameterValue = "ParameterValue"; + +// WinForms prompt to get Parameter Name / Value input +using (Form prompt = new Form()) +{ + Font formFont = new Font("Segoe UI", 11); + + // Prompt config + prompt.AutoSize = true; + prompt.MinimumSize = new Size(380, 120); + prompt.Text = "Create New M Parameter"; + prompt.StartPosition = FormStartPosition.CenterScreen; + + // Find: label + Label parameterNameLabel = new Label() { Text = "Enter Name:" }; + parameterNameLabel.Location = new Point(20, 20); + parameterNameLabel.AutoSize = true; + parameterNameLabel.Font = formFont; + + // Textbox for inputing the substring text + TextBox parameterNameBox = new TextBox(); + parameterNameBox.Width = 200; + parameterNameBox.Location = new Point(parameterNameLabel.Location.X + parameterNameLabel.Width + 20, parameterNameLabel.Location.Y - 4); + parameterNameBox.SelectedText = "New Parameter"; + parameterNameBox.Font = formFont; + + // Replace: label + Label parameterValueLabel = new Label() { Text = "Enter Value:" }; + parameterValueLabel.Location = new Point(parameterNameLabel.Location.X, parameterNameLabel.Location.Y + parameterNameLabel.Height + 20); + parameterValueLabel.AutoSize = true; + parameterValueLabel.Font = formFont; + + // Textbox for inputting the substring text + TextBox parameterValueBox = new TextBox() { Left = parameterValueLabel.Right + 20, Top = parameterValueLabel.Location.Y - 4, Width = parameterNameBox.Width }; + parameterValueBox.SelectedText = "Parameter Value"; + parameterValueBox.Font = formFont; + + // OK Button + Button okButton = new Button() { Text = "Create", Left = 20, Width = 75, Top = parameterValueBox.Location.Y + parameterValueBox.Height + 20 }; + okButton.MinimumSize = new Size(75, 25); + okButton.AutoSize = true; + okButton.Font = formFont; + + // Cancel Button + Button cancelButton = new Button() { Text = "Cancel", Left = okButton.Location.X + okButton.Width + 10, Top = okButton.Location.Y }; + cancelButton.MinimumSize = new Size(75, 25); + cancelButton.AutoSize = true; + cancelButton.Font = formFont; + + // Button actions + okButton.Click += (sender, e) => { _ParameterName = parameterNameBox.Text; _ParameterValue = parameterValueBox.Text; prompt.DialogResult = DialogResult.OK; }; + cancelButton.Click += (sender, e) => { prompt.DialogResult = DialogResult.Cancel; }; + + prompt.AcceptButton = okButton; + prompt.CancelButton = cancelButton; + + prompt.Controls.Add(parameterNameLabel); + prompt.Controls.Add(parameterNameBox); + prompt.Controls.Add(parameterValueLabel); + prompt.Controls.Add(parameterValueBox); + prompt.Controls.Add(okButton); + prompt.Controls.Add(cancelButton); + + // The user clicked OK, so perform the find-and-replace logic + if (prompt.ShowDialog() == DialogResult.OK) + { + + // Creates the parameter + Model.AddExpression( + _ParameterName, + @" + """ + _ParameterValue + + @""" meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type text + ]" + ); + + + // Informs the user that the parameter was successfully created + Info ( + "Successfully created a new parameter: " + @"""" + + _ParameterName + @"""" + + "\nDefault value: " + @"""" + + _ParameterValue + @""""); + + + // Finds the parameter default value in M Partitions & replaces with the parameter name + string _Find = @"""" + _ParameterValue + @""""; + string _Replace = @"#""" + _ParameterName + @""""; + + int _NrMPartitions = 0; + int _NrReplacements = 0; + var _ReplacementsList = new List(); + + foreach ( var _Tables in Model.Tables ) + { + foreach ( var _p in _Tables.Partitions ) + { + if ( _p.SourceType == PartitionSourceType.M ) + { + if ( _p.Expression != _p.Expression.Replace( _Find, _Replace ) ) + { + _p.Expression = _p.Expression.Replace( _Find, _Replace ); + + // Tracks which M partitions were replaced (and how many) + _NrReplacements = _NrReplacements + 1; + _ReplacementsList.Add( _p.Name ); + } + + // Counts the total # M Partitions + _NrMPartitions = _NrMPartitions + 1; + } + } + } + + + // Makes a bulleted list of all the M partitions that were replaced + string _ReplacedPartitions = " • " + String.Join("\n • ", _ReplacementsList ); + + + // Informs + // - Whether the Find & Replace was successful + // - How many M partitions were replaced + // - Which M partitions had the Find & Replace done + Info ( + "Successfully replaced\n\n " + + _Find + + "\n\n with: \n\n" + + _Replace + + "\n\n in " + + Convert.ToString(_NrReplacements) + + " of " + + Convert.ToString(_NrMPartitions) + + " M Partitions:\n" + + _ReplacedPartitions + ); + + } + else + { + Error ( "Cancelled input! Ended script without changes."); + } +} +``` + +### Explanation + +This snippet opens a dialogue box for the user to enter the parameter name and value, then creates the parameter as a 'Shared Expression' in the model. +It will then search all M partitions for the default value, replacing them with the `#"ParameterName"`. + +## Example Output + +
    + Data Security Create Role
    Figure 1: The pop-up dialog that appears when running the script, prompting for the parameter name and value.
    +
    + +
    + Data Security Create Role
    Figure 2: Confirmation dialog illustrating that the parameter has been created, and the corresponding value substring has been replaced in all M Partition expressions. For parameters of other types, adjust the C# code, appropriately.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-create-databricks-relationships_zh.md b/content/localization/zh/script-create-databricks-relationships_zh.md new file mode 100644 index 00000000..7d282e02 --- /dev/null +++ b/content/localization/zh/script-create-databricks-relationships_zh.md @@ -0,0 +1,610 @@ +--- +uid: script-create-databricks-relationships +title: Create Databricks Relationships +author: Johnny Winter +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create Databricks Relationships + +## Script Purpose + +This script was created as part of the Tabular Editor x Databricks series. In Unity Catalog it is possible to define primary and foreign key relationships between tables. This script can re-use this information to automatically detect and create relationships in Tabular Editor. Whilst importing the relationships, the script will also hide primary and foreign keys and set IsAvailableInMDX to false (with the exception of DateTime type primary keys). Primary keys are also marked as IsKey = TRUE in the semantic model.

    + +> [!NOTE] +> This script requires the Simba Spark ODBC Driver to be installed (download from https://www.databricks.com/spark/odbc-drivers-download) +> Each run of the script will prompt the user for a Databricks Personal Access Token. This is required to authenticate to Databricks. +> The script utilises the information_schema tables in Unity Catalog to retrieve relationship information, so you may need to double check with your Databricks administrator to make sure you have permission to query these tables.

    + +## Script + +### Create Databricks Relationships + +```csharp +/* + * Title: Create Databricks Relationships + * Author: Johnny Winter, greyskullanalytics.com + * + * This script, when executed, will loop through the currently selected tables and send a query to the Databricks Information Schema tables to see if any foreign keys + * have been defined. Where foreign keys are identified, the script will create relationships between the tables in the semantic model. + * With the exception of dimension columns that are datetime type, key columns will be hidden once relationshsips are created, with primary keys marked as primary keys and IsAvailableInMDX set to false. + * Step 1: Select one or more tables in the model. These should be tables which have a foreign key relationship defined in Unity Catalog + (typically fact tables, but they could also be bridge tables or outrigger dimensions). + * Step 2: Run this script + * Step 3: Enter your Databricks Personal Access Token when prompted + * Step 4: The script will connect to Databricks and detect where foreign keys exist on the selected table. + If the relationship does not already exist in the semantic model, it will be created. + If a relationship already exists between the two tables, the new relationship will be created as inactive + For each table processed, a message box will display the number of relationships created. + * Click OK to continue to the next table. + * Notes: + * - This script requires the Simba Spark ODBC Driver to be installed (download from https://www.databricks.com/spark/odbc-drivers-download) + * - Each run of the script will prompt the user for a Databricks Personal Access Token + */ +#r "Microsoft.VisualBasic" +using System; +using System.Data.Odbc; +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using Microsoft.VisualBasic; +using sysData = System.Data; + +//code to create a masked input box for Databricks PAT token +public partial class PasswordInputForm : Form +{ + public string Password { get; private set; } + + private TextBox passwordTextBox; + private Button okButton; + private Button cancelButton; + private Label promptLabel; + + public PasswordInputForm(string prompt, string title) + { + InitializeComponent(prompt, title); + } + + private void InitializeComponent(string prompt, string title) + { + this.Text = title; + this.Size = new System.Drawing.Size(4000, 1500); + this.StartPosition = FormStartPosition.WindowsDefaultLocation; + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + + // Prompt label + promptLabel = new Label(); + promptLabel.Text = prompt; + promptLabel.Location = new System.Drawing.Point(12, 15); + promptLabel.Size = new System.Drawing.Size(360, 40); + promptLabel.AutoSize = false; + this.Controls.Add(promptLabel); + + // Password textbox + passwordTextBox = new TextBox(); + passwordTextBox.Location = new System.Drawing.Point(12, 55); + passwordTextBox.Size = new System.Drawing.Size(360, 20); + passwordTextBox.UseSystemPasswordChar = true; // This masks the input + passwordTextBox.KeyPress += (s, e) => + { + if (e.KeyChar == (char)Keys.Return) + { + OkButton_Click(null, null); + e.Handled = true; + } + }; + this.Controls.Add(passwordTextBox); + + // OK button + okButton = new Button(); + okButton.Text = "OK"; + okButton.Location = new System.Drawing.Point(216, 85); + okButton.Size = new System.Drawing.Size(150, 50); + okButton.Click += OkButton_Click; + this.Controls.Add(okButton); + + // Cancel button + cancelButton = new Button(); + cancelButton.Text = "Cancel"; + cancelButton.Location = new System.Drawing.Point(297, 85); + cancelButton.Size = new System.Drawing.Size(150, 50); + cancelButton.Click += CancelButton_Click; + this.Controls.Add(cancelButton); + + // Set default and cancel buttons + this.AcceptButton = okButton; + this.CancelButton = cancelButton; + + // Focus on textbox when form loads + this.Load += (s, e) => passwordTextBox.Focus(); + } + + private void OkButton_Click(object sender, EventArgs e) + { + Password = passwordTextBox.Text; + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void CancelButton_Click(object sender, EventArgs e) + { + Password = string.Empty; + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + public static string ShowDialog(string prompt, string title) + { + using (var form = new PasswordInputForm(prompt, title)) + { + if (form.ShowDialog() == DialogResult.OK) + return form.Password; + return string.Empty; + } + } +} + +public static class MaskedInputHelper +{ + public static string GetMaskedInput(string prompt, string title, string defaultValue = "") + { + using (var form = new Form()) + { + form.Text = title; + form.Size = new System.Drawing.Size(1000, 500); + form.StartPosition = FormStartPosition.CenterScreen; + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + + var label = new Label() + { + Left = 12, + Top = 15, + Size = new System.Drawing.Size(900, 100), + Text = prompt, + }; + var textBox = new TextBox() + { + Left = 12, + Top = 150, + Size = new System.Drawing.Size(900, 100), + UseSystemPasswordChar = true, + Text = defaultValue, + }; + var buttonOk = new Button() + { + Text = "OK", + Size = new System.Drawing.Size(150, 50), + Left = 12, + Width = 150, + Top = 200, + DialogResult = DialogResult.OK, + }; + var buttonCancel = new Button() + { + Text = "Cancel", + Size = new System.Drawing.Size(150, 50), + Left = 175, + Width = 150, + Top = 200, + DialogResult = DialogResult.Cancel, + }; + + buttonOk.Click += (sender, e) => + { + form.Close(); + }; + form.Controls.Add(label); + form.Controls.Add(textBox); + form.Controls.Add(buttonOk); + form.Controls.Add(buttonCancel); + form.AcceptButton = buttonOk; + form.CancelButton = buttonCancel; + + return form.ShowDialog() == DialogResult.OK ? textBox.Text : string.Empty; + } + } +} + +//Code to retrieve Databricks Connection information from the M Query in a table partition +public class DatabricksConnectionInfo +{ + public string ServerHostname { get; set; } + public string HttpPath { get; set; } + public string DatabaseName { get; set; } + public string SchemaName { get; set; } + public string TableName { get; set; } + + public override string ToString() + { + return $"Server: {ServerHostname}\n" + + $"HTTP Path: {HttpPath}\n" + + $"Database: {DatabaseName}\n" + + $"Schema: {SchemaName}\n" + + $"Table: {TableName}"; + } +} + +public class PowerQueryMParser +{ + public static DatabricksConnectionInfo ParseMQuery(string mQuery) + { + if (string.IsNullOrWhiteSpace(mQuery)) + throw new ArgumentException("M query cannot be null or empty"); + + var connectionInfo = new DatabricksConnectionInfo(); + + try + { + // Parse Source line to extract server hostname and HTTP path + ParseSourceLine(mQuery, connectionInfo); + + // Parse Database line to extract database name + ParseDatabaseLine(mQuery, connectionInfo); + + // Parse Schema line to extract schema name + ParseSchemaLine(mQuery, connectionInfo); + + // Parse Data line to extract table name + ParseDataLine(mQuery, connectionInfo); + + return connectionInfo; + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error parsing M query: {ex.Message}", ex); + } + } + + private static void ParseSourceLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match both: + // Source = DatabricksMultiCloud.Catalogs("hostname", "httppath", null), + // Source = Databricks.Catalogs("hostname", "httppath", null), + var sourcePattern = + @"Source\s*=\s*Databricks(?:MultiCloud)?\.Catalogs\s*\(\s*""([^""]+)""\s*,\s*""([^""]+)""\s*,\s*null\s*\)"; + var sourceMatch = Regex.Match( + mQuery, + sourcePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!sourceMatch.Success) + throw new FormatException( + "Could not find valid Source definition in M query (supports both Databricks and DatabricksMultiCloud connectors)" + ); + + connectionInfo.ServerHostname = sourceMatch.Groups[1].Value; + connectionInfo.HttpPath = sourceMatch.Groups[2].Value; + } + + private static void ParseDatabaseLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Database = Source{[Name="databasename",Kind="Database"]}[Data], + var databasePattern = + @"Database\s*=\s*Source\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Database""\s*\]\s*}\s*\[\s*Data\s*\]"; + var databaseMatch = Regex.Match( + mQuery, + databasePattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!databaseMatch.Success) + throw new FormatException("Could not find valid Database definition in M query"); + + connectionInfo.DatabaseName = databaseMatch.Groups[1].Value; + } + + private static void ParseSchemaLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Schema = Database{[Name="schemaname",Kind="Schema"]}[Data], + var schemaPattern = + @"Schema\s*=\s*Database\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Schema""\s*\]\s*}\s*\[\s*Data\s*\]"; + var schemaMatch = Regex.Match( + mQuery, + schemaPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!schemaMatch.Success) + throw new FormatException("Could not find valid Schema definition in M query"); + + connectionInfo.SchemaName = schemaMatch.Groups[1].Value; + } + + private static void ParseDataLine(string mQuery, DatabricksConnectionInfo connectionInfo) + { + // Pattern to match: Data = Schema{[Name="tablename",Kind="Table"]}[Data] + var dataPattern = + @"Data\s*=\s*Schema\s*{\s*\[\s*Name\s*=\s*""([^""]+)""\s*,\s*Kind\s*=\s*""Table""\s*\]\s*}\s*\[\s*Data\s*\]"; + var dataMatch = Regex.Match( + mQuery, + dataPattern, + RegexOptions.IgnoreCase | RegexOptions.Multiline + ); + + if (!dataMatch.Success) + throw new FormatException("Could not find valid Data definition in M query"); + + connectionInfo.TableName = dataMatch.Groups[1].Value; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//main script + + + +//check that user has a table selected +if (Selected.Tables.Count == 0) +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox("Select one or more tables", MsgBoxStyle.Critical, "Table Required"); + return; +} + +//prompt for personal access token - required to authenticate to Databricks +string dbxPAT; +do +{ + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + dbxPAT = MaskedInputHelper.GetMaskedInput( + "Please enter your Databricks Personal Access Token (needed to connect to the SQL Endpoint)", + "Personal Access Token" + ); + + if (string.IsNullOrEmpty(dbxPAT)) + { + return; // User cancelled + } + + if (string.IsNullOrWhiteSpace(dbxPAT)) + { + MessageBox.Show( + "Personal Access Token required", + "Personal Access Token required", + MessageBoxButtons.OK, + MessageBoxIcon.Warning + ); + } +} while (string.IsNullOrWhiteSpace(dbxPAT)); + +// toggle the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = true; + +//for each selected table, get the Databricks connection info from the partition info +foreach (var t in Selected.Tables) +{ + string mQuery = t.Partitions[t.Name].Expression; + var connectionInfo = PowerQueryMParser.ParseMQuery(mQuery); + var rels = 0; + // Access individual components + string serverHostname = connectionInfo.ServerHostname; + string httpPath = connectionInfo.HttpPath; + string databaseName = connectionInfo.DatabaseName; + string schemaName = connectionInfo.SchemaName; + string tableName = connectionInfo.TableName; + + //use this query to see if any primary/foreign key relationships have been defined in Unity Catalog + var query = + @" + SELECT + fk.table_catalog AS fk_table_catalog, + fk.table_schema AS fk_table_schema, + fk.table_name AS fk_table_name, + fk.column_name AS fk_column, + pk.table_catalog AS pk_table_catalog, + pk. table_schema AS pk_table_schema, + pk.table_name AS pk_table_name, + pk.column_name AS pk_column + FROM + " + + databaseName + + @".information_schema.key_column_usage fk + INNER JOIN " + + databaseName + + @".information_schema.referential_constraints rc + ON fk.constraint_catalog = rc.constraint_catalog + AND fk.constraint_schema = rc.constraint_schema + AND fk.constraint_name = rc.constraint_name + INNER JOIN " + + databaseName + + @".information_schema.key_column_usage pk + ON rc.unique_constraint_catalog = pk.constraint_catalog + AND rc.unique_constraint_schema = pk.constraint_schema + AND rc.unique_constraint_name = pk.constraint_name + WHERE + fk.table_schema = '" + + schemaName + + @"' + AND fk.table_name = '" + + tableName + + @"' + AND fk.position_in_unique_constraint = 1 +"; + + //set DBX connection string + var odbcConnStr = + @"DSN=Simba Spark;driver=C:\Program Files\Simba Spark ODBC Driver;host=" + + serverHostname + + ";port=443;httppath=" + + httpPath + + ";thrifttransport=2;ssl=1;authmech=3;uid=token;pwd=" + + dbxPAT; + + //test connection + OdbcConnection conn = new OdbcConnection(odbcConnStr); + try + { + conn.Open(); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + +Please check the following prequisites: + +- you must have the Simba Spark ODBC Driver installed +(download from https://www.databricks.com/spark/odbc-drivers-download) + +- the ODBC driver must be installed in the path C:\Program Files\Simba Spark ODBC Driver + +- check that the Databricks server name " + + serverHostname + + @" is correct + +- check that the Databricks SQL endpoint / HTTP Path " + + httpPath + + @" is correct + +- check that you have used a valid Personal Access Token", + MsgBoxStyle.Critical, + "Connection Error" + ); + return; + } + + //send query + OdbcDataAdapter da = new OdbcDataAdapter(query, conn); + var dbxRelationships = new sysData.DataTable(); + + try + { + da.Fill(dbxRelationships); + } + catch + { + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + @"Connection failed + + Either: + - the table " + + schemaName + + "." + + tableName + + " does not exist" + + @" + + - you do not have permissions to query this table + + - the connection timed out. Please check that the SQL Endpoint cluster is running", + MsgBoxStyle.Critical, + "Connection Error" + ); + return; + } + + //for every table in the model, see if it matches a row in the Databricks query + foreach (var dt in Model.Tables) + { + //get the source table information + string sourceMQuery = dt.Partitions[dt.Name].Expression; + var sourceConnectionInfo = PowerQueryMParser.ParseMQuery(sourceMQuery); + // Access individual components + string sourceSchemaName = sourceConnectionInfo.SchemaName; + string sourceTableName = sourceConnectionInfo.TableName; + + foreach (sysData.DataRow row in dbxRelationships.Rows) + { + if ( + string.Equals( + sourceSchemaName + "." + sourceTableName, + row["pk_table_schema"].ToString() + "." + row["pk_table_name"].ToString(), + StringComparison.OrdinalIgnoreCase + ) + ) + { + var dimTable = dt; + foreach (var dc in dt.DataColumns) + if (dc.SourceColumn == row["pk_column"].ToString()) + { + var dimColumn = dc; + + foreach (var fc in t.DataColumns) + if (fc.SourceColumn == row["fk_column"].ToString()) + { + var factColumn = fc; + + // Check whether a relationship already exists between the two columns: + if ( + !Model.Relationships.Any(r => + r.FromColumn == factColumn && r.ToColumn == dimColumn + ) + ) + { + // If relationships already exists between the two tables, new relationships will be created as inactive: + var makeInactive = Model.Relationships.Any(r => + r.FromTable == t && r.ToTable == dimTable + ); + + // Add the new relationship: + var rel = Model.AddRelationship(); + rel.FromColumn = factColumn; + rel.ToColumn = dimColumn; + factColumn.IsHidden = true; + factColumn.IsAvailableInMDX = false; + dimColumn.IsKey = true; + if (dc.DataType != DataType.DateTime) + { + dimColumn.IsHidden = true; + dimColumn.IsAvailableInMDX = false; + } + + if (makeInactive) + rel.IsActive = false; + rels = rels + 1; + } + } + } + } + } + } + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = false; + Interaction.MsgBox( + rels + " relationships added to " + t.Name, + MsgBoxStyle.Information, + "Add relationships" + ); + // toggle the 'Running Macro' spinbox + ScriptHelper.WaitFormVisible = true; + conn.Close(); +} +``` + +### Explanation + +The script uses WinForms to prompt for a Databricks personal access token, used to authenticate to Databricks. For each selected table, the script retrieves the Databricks connection string information and schema and table name from the M query in the selected table's partition. Using the Spark ODBC driver it then sends a SQL query to Databricks that queries the information_schema tables to find any foreign key relationships for the table that are defined in Unity Catalog. For each row returned in the SQL query, the script looks for matching table and column names in the model and where a relationship does not already exist, a new one is created. For role playing dimensions, where the same table might have multiple foreign keys relating to a single table, the first relationship detected will be the active one, and all other subsequent relationships are created as inactive. The script will also hide primary and foreign keys and set IsAvailableInMDX to false (with the exception of DateTime type primary keys). Primary keys are also marked as IsKey = TRUE in the semantic model. After the script has run for each selected table, a dialogue box will appear showing how many new relationships were created. + +## Example Output + +
    + Table relationships before running the script
    Figure 1: Before running the script, no relationships are defined.
    +
    + +
    + Prompt for Databricks personal access token
    Figure 2: The script will prompt you for a Databricks personal access token so it can authenticate to Databricks.
    +
    + +
    + The number of new relationships created
    Figure 3: After the script has run for each selected table, the number of new relationships created is displayed.
    +
    + +
    + Table relationships after running the script
    Figure 4: Table relationships after running the script.
    +
    + diff --git a/content/localization/zh/script-create-date-table_zh.md b/content/localization/zh/script-create-date-table_zh.md new file mode 100644 index 00000000..5adf0519 --- /dev/null +++ b/content/localization/zh/script-create-date-table_zh.md @@ -0,0 +1,541 @@ +--- +uid: script-create-date-table +title: Create Date Table +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create a Date Table + +## Script Purpose + +You can use this script to create a new, organized and configured date table based on 1-2 selected date columns in the model. +The first selected column should be the earliest date and the second selected column should be the latest date. Both should be selected before running the script / macro. + +This script will create the below objects in the model: + +1. A measure `[RefDate]`, which will have the latest date in the model scope; i.e. last day of sales. You can adjust this measure manually and re-process the date table to re-generate it based on a different reference date (i.e. if you want to change it to TODAY() or add a filter) +2. The `'Date'` table - The table can be configured in a separate DAX Query window and copied back into the script if you have other requirements. + - All columns will be organized in display folders + - Column properties like Sort By will be set + +This script does not yet create model relationships between the created date table and date fields in your model. + +## Script + +### Create Date Table + +```csharp +// To use this C# Script: +// +// 1. Run the script +// 2. Select the column that has the earliest date +// 3. Select the column that has the latest date + +// List of all DateTime columns in the model +var _dateColumns = Model.AllColumns.Where(c => c.DataType == DataType.DateTime ).ToList(); + +// Select the column with the earliest date in the model +try +{ + string _EarliestDate = + SelectColumn( + _dateColumns, + null, + "Select the Column with the Earliest Date:" + ).DaxObjectFullName; + + try + { + // Select the column with the latest date in the model + string _LatestDate = + SelectColumn( + _dateColumns, + null, + "Select the Column with the Latest Date:" + ).DaxObjectFullName; + + + // Create measure for reference date + var _RefDateMeasure = _dateColumns[0].Table.AddMeasure( + "RefDate", + "CALCULATE ( MAX ( " + _LatestDate + " ), REMOVEFILTERS ( ) )" + ); + + + // Formatted date table DAX + // Based on date table from https://www.sqlbi.com/topics/date-table/ + // To adjust, copy everything after the @" into a DAX query window & replace + + var _DateDaxExpression = @"-- Reference date for the latest date in the report + -- Until when the business wants to see data in reports + VAR _Refdate_Measure = [RefDate] + VAR _Today = TODAY ( ) + + -- Replace with ""Today"" if [RefDate] evaluates blank + VAR _Refdate = IF ( ISBLANK ( _Refdate_Measure ), _Today, _Refdate_Measure ) + VAR _RefYear = YEAR ( _Refdate ) + VAR _RefQuarter = _RefYear * 100 + QUARTER(_Refdate) + VAR _RefMonth = _RefYear * 100 + MONTH(_Refdate) + VAR _RefWeek_EU = _RefYear * 100 + WEEKNUM(_Refdate, 2) + + -- Earliest date in the model scope + VAR _EarliestDate = DATE ( YEAR ( MIN ( " + _EarliestDate + @" ) ) - 2, 1, 1 ) + VAR _EarliestDate_Safe = MIN ( _EarliestDate, DATE ( YEAR ( _Today ) + 1, 1, 1 ) ) + + -- Latest date in the model scope + VAR _LatestDate_Safe = DATE ( YEAR ( _Refdate ) + 2, 12, 1 ) + + ------------------------------------------ + -- Base calendar table + VAR _Base_Calendar = CALENDAR ( _EarliestDate_Safe, _LatestDate_Safe ) + ------------------------------------------ + + + + ------------------------------------------ + VAR _IntermediateResult = + ADDCOLUMNS ( _Base_Calendar, + + ------------------------------------------ + ""Calendar Year Number (ie 2021)"", --| + YEAR ([Date]), --|-- Year + --| + ""Calendar Year (ie 2021)"", --| + FORMAT ([Date], ""YYYY""), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Quarter Year (ie Q1 2021)"", --| + ""Q"" & --|-- Quarter + CONVERT(QUARTER([Date]), STRING) & --| + "" "" & --| + CONVERT(YEAR([Date]), STRING), --| + --| + ""Calendar Year Quarter (ie 202101)"", --| + YEAR([Date]) * 100 + QUARTER([Date]), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Month Year (ie Jan 21)"", --| + FORMAT ( [Date], ""MMM YY"" ), --|-- Month + --| + ""Calendar Year Month (ie 202101)"", --| + YEAR([Date]) * 100 + MONTH([Date]), --| + --| + ""Calendar Month (ie Jan)"", --| + FORMAT ( [Date], ""MMM"" ), --| + --| + ""Calendar Month # (ie 1)"", --| + MONTH ( [Date] ), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Week EU (ie WK25)"", --| + ""WK"" & WEEKNUM( [Date], 2 ), --|-- Week + --| + ""Calendar Week Number EU (ie 25)"", --| + WEEKNUM( [Date], 2 ), --| + --| + ""Calendar Year Week Number EU (ie 202125)"", --| + YEAR ( [Date] ) * 100 --| + + --| + WEEKNUM( [Date], 2 ), --| + --| + ""Calendar Week US (ie WK25)"", --| + ""WK"" & WEEKNUM( [Date], 1 ), --| + --| + ""Calendar Week Number US (ie 25)"", --| + WEEKNUM( [Date], 1 ), --| + --| + ""Calendar Year Week Number US (ie 202125)"", --| + YEAR ( [Date] ) * 100 --| + + --| + WEEKNUM( [Date], 1 ), --| + --| + ""Calendar Week ISO (ie WK25)"", --| + ""WK"" & WEEKNUM( [Date], 21 ), --| + --| + ""Calendar Week Number ISO (ie 25)"", --| + WEEKNUM( [Date], 21 ), --| + --| + ""Calendar Year Week Number ISO (ie 202125)"",--| + YEAR ( [Date] ) * 100 --| + + --| + WEEKNUM( [Date], 21 ), --| + ------------------------------------------ + + ------------------------------------------ + ""Weekday Short (i.e. Mon)"", --| + FORMAT ( [Date], ""DDD"" ), --|-- Weekday + --| + ""Weekday Name (i.e. Monday)"", --| + FORMAT ( [Date], ""DDDD"" ), --| + --| + ""Weekday Number EU (i.e. 1)"", --| + WEEKDAY ( [Date], 2 ), --| + ------------------------------------------ + + ------------------------------------------ + ""Calendar Month Day (i.e. Jan 05)"", --| + FORMAT ( [Date], ""MMM DD"" ), --|-- Day + --| + ""Calendar Month Day (i.e. 0105)"", --| + MONTH([Date]) * 100 --| + + --| + DAY([Date]), --| + --| + ""YYYYMMDD"", --| + YEAR ( [Date] ) * 10000 --| + + --| + MONTH ( [Date] ) * 100 --| + + --| + DAY ( [Date] ), --| + ------------------------------------------ + + + ------------------------------------------ + ""IsDateInScope"", --| + [Date] <= _Refdate --|-- Boolean + && --| + YEAR([Date]) > YEAR(_EarliestDate), --| + --| + ""IsBeforeThisMonth"", --| + [Date] <= EOMONTH ( _Refdate, -1 ), --| + --| + ""IsLastMonth"", --| + [Date] <= EOMONTH ( _Refdate, 0 ) --| + && --| + [Date] > EOMONTH ( _Refdate, -1 ), --| + --| + ""IsYTD"", --| + MONTH([Date]) --| + <= --| + MONTH(EOMONTH ( _Refdate, 0 )), --| + --| + ""IsActualToday"", --| + [Date] = _Today, --| + --| + ""IsRefDate"", --| + [Date] = _Refdate, --| + --| + ""IsHoliday"", --| + MONTH([Date]) * 100 --| + + --| + DAY([Date]) --| + IN {0101, 0501, 1111, 1225}, --| + --| + ""IsWeekday"", --| + WEEKDAY([Date], 2) --| + IN {1, 2, 3, 4, 5}) --| + ------------------------------------------ + + VAR _Result = + + -------------------------------------------- + ADDCOLUMNS ( --| + _IntermediateResult, --|-- Boolean #2 + ""IsThisYear"", --| + [Calendar Year Number (ie 2021)] --| + = _RefYear, --| + --| + ""IsThisMonth"", --| + [Calendar Year Month (ie 202101)] --| + = _RefMonth, --| + --| + ""IsThisQuarter"", --| + [Calendar Year Quarter (ie 202101)] --| + = _RefQuarter, --| + --| + ""IsThisWeek"", --| + [Calendar Year Week Number EU (ie 202125)]--| + = _RefWeek_EU --| + ) --| + -------------------------------------------- + + RETURN + _Result"; + + // Create date table + var _date = Model.AddCalculatedTable( + "Date", + _DateDaxExpression + ); + + //-------------------------------------------------------------------------------------------// + + // Sort by... + + // Sort Weekdays + (_date.Columns["Weekday Name (i.e. Monday)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Weekday Number EU (i.e. 1)"] as CalculatedTableColumn); + (_date.Columns["Weekday Short (i.e. Mon)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Weekday Number EU (i.e. 1)"] as CalculatedTableColumn); + + // Sort Weeks + (_date.Columns["Calendar Week EU (ie WK25)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Week Number EU (ie 25)"] as CalculatedTableColumn); + (_date.Columns["Calendar Week ISO (ie WK25)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Week Number ISO (ie 25)"] as CalculatedTableColumn); + (_date.Columns["Calendar Week US (ie WK25)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Week Number US (ie 25)"] as CalculatedTableColumn); + + // Sort Months + (_date.Columns["Calendar Month (ie Jan)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Month # (ie 1)"] as CalculatedTableColumn); + (_date.Columns["Calendar Month Day (i.e. Jan 05)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Month Day (i.e. 0105)"] as CalculatedTableColumn); + (_date.Columns["Calendar Month Year (ie Jan 21)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Year Month (ie 202101)"] as CalculatedTableColumn); + + // Sort Quarters + (_date.Columns["Calendar Quarter Year (ie Q1 2021)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Year Quarter (ie 202101)"] as CalculatedTableColumn); + + // Sort Years + (_date.Columns["Calendar Year (ie 2021)"] as CalculatedTableColumn).SortByColumn = (_date.Columns["Calendar Year Number (ie 2021)"] as CalculatedTableColumn); + + + //-------------------------------------------------------------------------------------------// + + + // For all the columns in the date table: + foreach (var c in _date.Columns ) + { + c.DisplayFolder = "7. Boolean Fields"; + c.IsHidden = true; + + // Organize the date table into folders + if ( ( c.DataType == DataType.DateTime & c.Name.Contains("Date") ) ) + { + c.DisplayFolder = "6. Calendar Date"; + c.IsHidden = false; + c.IsKey = true; + } + + if ( c.Name == "YYMMDDDD" ) + { + c.DisplayFolder = "6. Calendar Date"; + c.IsHidden = true; + } + + if ( c.Name.Contains("Year") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "1. Year"; + c.IsHidden = false; + } + + if ( c.Name.Contains("Week") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "4. Week"; + c.IsHidden = true; + } + + if ( c.Name.Contains("day") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "5. Weekday / Workday\\Weekday"; + c.IsHidden = false; + } + + if ( c.Name.Contains("Month") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "3. Month"; + c.IsHidden = false; + } + + if ( c.Name.Contains("Quarter") & c.DataType != DataType.Boolean ) + { + c.DisplayFolder = "2. Quarter"; + c.IsHidden = false; + } + + } + + // Mark as date table + _date.DataCategory = "Time"; + + + //-------------------------------------------------------------------------------------------// + + + // Create Workdays MTD, QTD, YTD logic + // (separate into measures & calc. column to be easier to maintain) + // + // Add calculated columns for Workdays MTD, QTD, YTD + + string _WorkdaysDax = @"VAR _Holidays = + CALCULATETABLE ( + DISTINCT ('Date'[Date]), + 'Date'[IsHoliday] <> TRUE + ) + VAR _WeekdayName = CALCULATE ( SELECTEDVALUE ( 'Date'[Weekday Short (i.e. Mon)] ) ) + VAR _WeekendDays = SWITCH ( + _WeekdayName, + ""Sat"", 2, + ""Sun"", 3, + 0 + ) + VAR _WorkdaysMTD = + CALCULATE ( + NETWORKDAYS ( + CALCULATE ( + MIN ('Date'[Date]), + ALLEXCEPT ('Date', 'Date'[Calendar Month Year (ie Jan 21)]) + ), + CALCULATE (MAX ('Date'[Date]) - _WeekendDays), + 1, + _Holidays + ) + ) + + 1 + RETURN + IF (_WorkdaysMTD < 1, 1, _WorkdaysMTD)"; + + _date.AddCalculatedColumn( + "Workdays MTD", + _WorkdaysDax, + "5. Weekday / Workday\\Workdays" + ); + + _date.AddCalculatedColumn( + "Workdays QTD", + _WorkdaysDax.Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Quarter Year (ie Q1 2021)]"), + "5. Weekday / Workday\\Workdays" + ); + + _date.AddCalculatedColumn( + "Workdays YTD", + _WorkdaysDax.Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Year (ie 2021)]"), + "5. Weekday / Workday\\Workdays" + ); + + + //-------------------------------------------------------------------------------------------// + + + // Create measures for showing how many workdays passed + _WorkdaysDax = @"CALCULATE( + MAX( 'Date'[Workdays MTD] ), + 'Date'[IsDateInScope] = TRUE + )"; + + _date.AddMeasure( + "# Workdays MTD", + _WorkdaysDax, + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays QTD", + _WorkdaysDax.Replace("MTD", "QTD"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays YTD", + _WorkdaysDax.Replace("MTD", "YTD"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + // Create measures showing how many workdays are in the selected period + + _WorkdaysDax = @"IF ( + HASONEVALUE ('Date'[Calendar Month Year (ie Jan 21)]), + CALCULATE ( + MAX ('Date'[Workdays MTD]), + VALUES ('Date'[Calendar Month Year (ie Jan 21)]) + ) + )"; + + _date.AddMeasure( + "# Workdays in Selected Month", + _WorkdaysDax, + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays in Selected Quarter", + _WorkdaysDax.Replace("MTD", "QTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Quarter Year (ie Q1 2021)]"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "# Workdays in Selected Year", + _WorkdaysDax.Replace("MTD", "YTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Year (ie 2021)]"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + + // Create measures showing how many workdays passed as a % + + _WorkdaysDax = @"IF ( + HASONEVALUE ('Date'[Calendar Month Year (ie Jan 21)]), + MROUND ( + DIVIDE ([# Workdays MTD], [# Workdays in Selected Month]), + 0.01 + ) + )"; + + _date.AddMeasure( + "% Workdays MTD", + _WorkdaysDax, + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "% Workdays QTD", + _WorkdaysDax.Replace("MTD", "QTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Quarter Year (ie Q1 2021)]").Replace("Month", "Quarter"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + _date.AddMeasure( + "% Workdays YTD", + _WorkdaysDax.Replace("MTD", "YTD").Replace("'Date'[Calendar Month Year (ie Jan 21)]", "'Date'[Calendar Year (ie 2021)]").Replace("Month", "Year"), + "5. Weekday / Workday\\Measures\\# Workdays" + ); + + + //-------------------------------------------------------------------------------------------// + + + // Move the reference measure to the newly created 'Date' table. + _RefDateMeasure.Delete(); + _RefDateMeasure = Model.Tables["Date"].AddMeasure( + "RefDate", + "CALCULATE ( MAX ( " + _LatestDate + " ), REMOVEFILTERS ( ) )", + "0. Measures" + ); + + _RefDateMeasure.IsHidden = true; + + Info ( "Created a new, organized 'Date' table based on the template in the C# Script.\nThe Earliest Date is taken from " + _EarliestDate + "\nThe Latest Date is taken from " + _LatestDate ); + + } + catch + { + Error( "Latest column not selected! Ending script without making changes." ); + } +} +catch +{ + Error( "Earliest column not selected! Ending script without making changes." ); +} + +``` + +### Explanation + +This snippet takes the selected columns and creates a measure to highlight the maximum date for reporting. It then creates a formatted Date table with common columns used for reporting. The date table only contains calendar dates and not fiscal periods. + +## Example Output + +
    + Select Earliest date dialog
    Figure 1: When running the script, a dialog will appear which prompts you to select a DateTime column from the model that contains the earliest date for which you want to configure your Date table.
    +
    + +
    + Select Latest date dialog
    Figure 2: Once selecting the earliest date, a dialog will appear which prompts you to select a DateTime column from the model that contains the latest date for which you want to configure your Date table.
    +
    + +
    + Confirmation of the date table being created
    Figure 3: A confirmation dialog will inform you that the Date table was configured successfully based on the two selected dates.
    +
    + +
    + Resulting Date Table Template
    Figure 4: An example of an organized, configured date table created with a single click using this script.
    +
    diff --git a/content/localization/zh/script-create-field-parameter_zh.md b/content/localization/zh/script-create-field-parameter_zh.md new file mode 100644 index 00000000..0dc9ebdf --- /dev/null +++ b/content/localization/zh/script-create-field-parameter_zh.md @@ -0,0 +1,72 @@ +--- +uid: create-field-parameter +title: Create Field Parameter +author: Daniel Otykier +updated: 2024-01-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create Field Parameters in + +## Script Purpose + +If you want to create field parameters in a Power BI model using Tabular Editor or in a Direct Lake model. + +> [!TIP] +> Want to see the script in action, check out this [Guy in a Cube video](https://www.youtube.com/watch?v=Cg6zRhwF-Ro) where Patrick LeBlanc explains how to use it step by step. + +## Script + +### Select Columns or Measures to create a field parameter table + +```csharp +// Before running the script, select the measures or columns that you +// would like to use as field parameters (hold down CTRL to select multiple +// objects). Also, you may change the name of the field parameter table +// below. NOTE: If used against Power BI Desktop, you must enable unsupported +// features under File > Preferences (TE2) or Tools > Preferences (TE3). +var name = "Parameter"; + +if(Selected.Columns.Count == 0 && Selected.Measures.Count == 0) throw new Exception("No columns or measures selected!"); + +// Construct the DAX for the calculated table based on the current selection: +var objects = Selected.Columns.Any() ? Selected.Columns.Cast() : Selected.Measures; +var dax = "{\n " + string.Join(",\n ", objects.Select((c,i) => string.Format("(\"{0}\", NAMEOF('{1}'[{0}]), {2})", c.Name, c.Table.Name, i))) + "\n}"; + +// Add the calculated table to the model: +var table = Model.AddCalculatedTable(name, dax); + +// In TE2 columns are not created automatically from a DAX expression, so +// we will have to add them manually: +var te2 = table.Columns.Count == 0; +var nameColumn = te2 ? table.AddCalculatedTableColumn(name, "[Value1]") : table.Columns["Value1"] as CalculatedTableColumn; +var fieldColumn = te2 ? table.AddCalculatedTableColumn(name + " Fields", "[Value2]") : table.Columns["Value2"] as CalculatedTableColumn; +var orderColumn = te2 ? table.AddCalculatedTableColumn(name + " Order", "[Value3]") : table.Columns["Value3"] as CalculatedTableColumn; + +if(!te2) { + // Rename the columns that were added automatically in TE3: + nameColumn.IsNameInferred = false; + nameColumn.Name = name; + fieldColumn.IsNameInferred = false; + fieldColumn.Name = name + " Fields"; + orderColumn.IsNameInferred = false; + orderColumn.Name = name + " Order"; +} +// Set remaining properties for field parameters to work +// See: https://twitter.com/markbdi/status/1526558841172893696 +nameColumn.SortByColumn = orderColumn; +nameColumn.GroupByColumns.Add(fieldColumn); +fieldColumn.SortByColumn = orderColumn; +fieldColumn.SetExtendedProperty("ParameterMetadata", "{\"version\":3,\"kind\":2}", ExtendedPropertyType.Json); +fieldColumn.IsHidden = true; +orderColumn.IsHidden = true; +``` + +### Explanation + +Before running the script the user has to select the measures or columns in the TOM Explorer they wish to have in their field parameter table. +The selected objects are then inserted into a calculated table which is then configured as a field parameter table automatically. + diff --git a/content/localization/zh/script-create-m-parameter_zh.md b/content/localization/zh/script-create-m-parameter_zh.md new file mode 100644 index 00000000..0f0643b8 --- /dev/null +++ b/content/localization/zh/script-create-m-parameter_zh.md @@ -0,0 +1,56 @@ +--- +uid: script-create-m-parameter +title: Create M Parameter +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create M Partition + +## Script Purpose + +If you want to create a new dynamic M Parameter to use in Power Query queries (M Partitions or Shared Expressions). + +## Script + +### Create a new M Partition + +```csharp +// This script creates a new M parameter in the 'Shared Expressions' of a model. +// +// Create a new shared expression called "New Parameter" +Model.AddExpression( + "New Parameter", + @" +""Parameter Text"" meta +[ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type text +]" +); + +// Provides an output informing how to configure and use the parameter +Info ( + "Created a new Shared Expression called 'New Parameter', which is an M Parameter template." + + "\n------------------------------------------------------\n" + + "To configure:" + + "\n------------------------------------------------------\n " + + "1. Replace the text 'New Parameter' with the desired parameter value\n " + + "2. Set the data type appropriately\n " + + "3. Replace any values found in the M partitions with the parameter reference." ); +``` + +### Explanation + +This snippet creates a new M parameter in 'Shared Expressions' which you can refer to from within your M Partitions Power Query. + +## Example Output + +
    + An example of the Info box that appears to inform the user that the M Parameter was successfully created, and recommending next steps to configure / use it in the M Partitions.
    Figure 1: An example of the Info box that appears to inform the user that the M Parameter was successfully created, and recommending next steps to configure / use it in the M Partitions.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-create-measure-table_zh.md b/content/localization/zh/script-create-measure-table_zh.md new file mode 100644 index 00000000..23ac09a5 --- /dev/null +++ b/content/localization/zh/script-create-measure-table_zh.md @@ -0,0 +1,26 @@ +--- +uid: script-create-measure-table +title: Create Measure Table +author: Morten Lønskov +updated: 2023-11-29 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create Measure Table + +## Script Purpose + +The scripts creates a hidden measure table containing one hidden column + +## Script + +### Create Measure Table + +```csharp +// Create a calculated table with a single column which is hidden: +var table = Model.AddCalculatedTable("Model Measures", "{0}"); +table.Columns[0].IsHidden = true; +``` \ No newline at end of file diff --git a/content/localization/zh/script-create-sum-measures-from-columns_zh.md b/content/localization/zh/script-create-sum-measures-from-columns_zh.md new file mode 100644 index 00000000..d8e4b79e --- /dev/null +++ b/content/localization/zh/script-create-sum-measures-from-columns_zh.md @@ -0,0 +1,51 @@ +--- +uid: script-create-sum-measures-from-columns +title: Create SUM Measure from Column +author: Morten Lønskov +updated: 2023-02-22 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Create SUM Measure from Column + +## Script Purpose + +If you want to quickly create a number of measures that SUM over the columns that you select then this script with do it for you. + +## Script + +### Create measures from columns + +```csharp +// Creates a SUM measure for every currently selected column and hide the column. +foreach(var c in Selected.Columns) +{ + var newMeasure = c.Table.AddMeasure( + "Sum of " + c.Name, // Name + "SUM(" + c.DaxObjectFullName + ")", // DAX expression + c.DisplayFolder // Display Folder + ); + + // Set the format string on the new measure: + newMeasure.FormatString = "0.00"; + + // Provide some documentation: + newMeasure.Description = "This measure is the sum of column " + c.DaxObjectFullName; + + // Hide the base column: + c.IsHidden = true; +} +``` + +### Explanation + +This snippet uses the `
    .AddMeasure(, , )` function to create a new measure on the table. We use the `DaxObjectFullName` property to get the fully qualified name of the column for use in the DAX expression: `'TableName'[ColumnName]`. + +## Example Output + +
    + Example of measures created with the script
    Figure 1: An example of measures created with this script.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-create-table-groups_zh.md b/content/localization/zh/script-create-table-groups_zh.md new file mode 100644 index 00000000..9e8527c2 --- /dev/null +++ b/content/localization/zh/script-create-table-groups_zh.md @@ -0,0 +1,60 @@ +--- +uid: script-create-table-groups +title: Create Table Groups +author: Morten Lønskov +updated: 2023-11-29 +applies_to: + versions: + - version: 3.x +--- + +# Create Table Groups + +## Script Purpose + +This script creates default table groups within Tabular Editor 3. + +## Script + +### Script Title + +```csharp +// Loop through all tables: +foreach(var table in Model.Tables) +{ + if (table is CalculationGroupTable) + { + table.TableGroup = "Calculation Groups"; + } + else if (!table.UsedInRelationships.Any() && table.Measures.Any(m => m.IsVisible)) + { + // Tables containing visible measures, but no relationships to other tables + table.TableGroup = "Measure Groups"; + } + else if (table.UsedInRelationships.All(r => r.FromTable == table) && table.UsedInRelationships.Any()) + { + // Tables exclusively on the "many" side of relationships: + table.TableGroup = "Facts"; + } + else if (!table.UsedInRelationships.Any() && table is CalculatedTable && !table.Measures.Any()) + { + // Tables without any relationships, that are Calculated Tables and do not have measures: + table.TableGroup = "Parameter Tables"; + } + else if (table.UsedInRelationships.Any(r => r.ToTable == table)) + { + // Tables on the "one" side of relationships: + table.TableGroup = "Dimensions"; + } + else + { + // All other tables: + table.TableGroup = "Misc"; + } +} +``` + +### Explanation + +The scripts loops through all tables in the model assigning a table group according to specific properties. + diff --git a/content/localization/zh/script-databricks-semantic-model-set-up_zh.md b/content/localization/zh/script-databricks-semantic-model-set-up_zh.md new file mode 100644 index 00000000..a18ae557 --- /dev/null +++ b/content/localization/zh/script-databricks-semantic-model-set-up_zh.md @@ -0,0 +1,100 @@ +--- +uid: script-databricks-semantic-model-set-up +title: Databricks Semantic Model Set-Up +author: Johnny Winter +updated: 2025-09-04 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Databricks Semantic Model Set-Up + +## Script Purpose + +This script was created as part of the Tabular Editor x Databricks series. In Databricks Unity Catalog it is not possible to use capital letters in table names. A common way to make tables names more readable without using capital letters is to adopt snake_case. Also, whilst column names can contain spaces, it is often advised against as these can be cumbersome to work with, meaning data engineers most often use snake_case, camelCase or PascalCase. + +However, we want users of our Semantic Model to see business friendly names in our model. + +The following script will loop through all tables in the model and make sure friendly, Proper Case formatting is applied. + +Whilst doing this, it will also apply some best practice recommendations, setting default summarisation for all columns to none and also setting format strings for DateTime type fields (this script is set up to use format ‘yyyy-mm-dd' but you can alter the script at line 61 if you prefer)

    + +> [!NOTE] +> This script is not strictly for use with only Databricks – use it with any model you like, regardless of data source, but it has been built with some of the limitations of Databricks in mind.

    + +## Script + +### Databricks Semantic Model Set-Up + +```csharp +/* + * Title: Databricks Semantic Model Set-Up + * Author: Johnny Winter, greyskullanalytics.com + * + * This script, when executed, will loop through all tables and columns in the model and rename with friendly names. + * Names in snake_case, camelCase or PascalCase will all be converted to Proper Case. + * No table selections are required as all tables in the model will be processed, simply run the script. + * Whilst looping though columns it also sets default summarization to none and sets a format string for all DateTime type fields + * (currently it sets format 'yyyy-mm-dd' but you can change this on line 61 if you wish). + * + */ +using System; +using System.Globalization; + +//create script as class so it can be reused +class p { + + public static void ConvertCase(dynamic obj) + { + TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo; + //replace underscores with a space + var oldName = obj.Name.Replace("_", " "); + var newName = new System.Text.StringBuilder(); + for(int i = 0; i < oldName.Length; i++) { + // First letter should always be capitalized: + if(i == 0) newName.Append(Char.ToUpper(oldName[i])); + + // A sequence of two uppercase letters followed by a lowercase letter should have a space inserted + // after the first letter: + else if(i + 2 < oldName.Length && char.IsLower(oldName[i + 2]) && char.IsUpper(oldName[i + 1]) && char.IsUpper(oldName[i])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + + // All other sequences of a lowercase letter followed by an uppercase letter, should have a space + // inserted after the first letter: + else if(i + 1 < oldName.Length && char.IsLower(oldName[i]) && char.IsUpper(oldName[i+1])) + { + newName.Append(oldName[i]); + newName.Append(" "); + } + else + { + newName.Append(oldName[i]); + } + } + //apply Proper Case where this has not already been taken care of above + obj.Name = textInfo.ToTitleCase(newName.ToString()); + } +} + +foreach(var t in Model.Tables) { +//convert table names + p.ConvertCase(t); +//convert column names + foreach(var c in t.Columns) { + p.ConvertCase(c); + c.SummarizeBy = AggregateFunction.None; + if (c.DataType == DataType.DateTime) + {c.FormatString = "yyyy-mm-dd";} + } +} +``` + +### Explanation + +This script, when executed, will loop through all tables and columns in the model and rename with friendly names. Names in snake_case, camelCase or PascalCase will all be converted to Proper Case. No table selections are required as all tables in the model will be processed, simply run the script. Whilst looping though columns it also sets default summarization to none and sets a format string for all DateTime type fields. + diff --git a/content/localization/zh/script-display-unique-column-values_zh.md b/content/localization/zh/script-display-unique-column-values_zh.md new file mode 100644 index 00000000..48c6e743 --- /dev/null +++ b/content/localization/zh/script-display-unique-column-values_zh.md @@ -0,0 +1,39 @@ +--- +uid: script-display-unique-column-values +title: Distinct Column Values +author: Morten Lønskov +updated: 2024-05-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Distinct Column Values + +## Script Purpose + +Display the distinct values in a column for quick data profiling and access. +Save as a Macro on the column level to have it quickly available. + +

    + +## Script + +### Script Title + +```csharp +// Construct the DAX expression to get all distinct column values, from the selected column: +var dax = string.Format("ALL({0})", Selected.Column.DaxObjectFullName); + +// Evaluate the DAX expression against the connected model: +var result = EvaluateDax(dax); + +// Output the DataTable containing the result of the DAX expression: +Output(result); +``` + +### Explanation + +The script uses the ALL() DAX function against the selected columns and display the result in an output dialog box. + diff --git a/content/localization/zh/script-edit-hidden-partitions_zh.md b/content/localization/zh/script-edit-hidden-partitions_zh.md new file mode 100644 index 00000000..b50faf85 --- /dev/null +++ b/content/localization/zh/script-edit-hidden-partitions_zh.md @@ -0,0 +1,28 @@ +--- +uid: script-edit-hidden-partitions +title: Edit Hidden Partitions +author: Morten Lønskov +updated: 2023-02-21 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Edit Hidden Partitions + +## Script Purpose + +Calculated Tables, Calculation Groups and Field Parameters do not have partitions displayed in Tabular Editor. This is on purpose as these should/can not generally be edited. The partition's properties can however still be accessed and edited with below script snippet. + +## Script + +```csharp +Selected.Table.Partitions[0].Output(); +``` + +### Example Output + +
    + An example of the output box that appears, letting the user view and edit hidden partitions in the model.
    Figure 1: An example of the output box that appears, letting the user view and edit hidden partitions in the model.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-find-replace-selected-measures_zh.md b/content/localization/zh/script-find-replace-selected-measures_zh.md new file mode 100644 index 00000000..3037f97b --- /dev/null +++ b/content/localization/zh/script-find-replace-selected-measures_zh.md @@ -0,0 +1,167 @@ +--- +uid: script-find-replace +title: Find/Replace Measure DAX +author: Kurt Buhler +updated: 2023-03-01 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Find & Replace Substring in Measures + +## Script Purpose + +Will find & replace a substring in the model's measures DAX expression. I.e. if you want to replace `'Customers'[Key Account]` with `'Products'[Type]` in many measures. +An input box lets the user enter the text to find and a subsequent input lets the user define the replacement text. + +## Script + +```csharp +#r "System.Drawing" + +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Replace Selected.Measures with Model.AllMeasures to scan all measures +var _measures = Model.AllMeasures; + // Optional: Replace _m.Expression with _m.Name to find & replace in names. + +// Initialize _find and _replace string variables +string _find = "Find"; +string _replace = "Replace"; + +// WinForms prompt to get Find & Replace input +using (Form prompt = new Form()) +{ + Font formFont = new Font("Segoe UI", 11); + + // Prompt config + prompt.AutoSize = true; + prompt.MinimumSize = new Size(350, 120); + prompt.Text = "Find and Replace Dialog"; + prompt.StartPosition = FormStartPosition.CenterScreen; + + // Set the AutoScaleMode property to Dpi + prompt.AutoScaleMode = AutoScaleMode.Dpi; + + // Find: label + Label findLabel = new Label() { Text = "Find:" }; + findLabel.Location = new Point(20, 20); + findLabel.Width = 80; + findLabel.Font = formFont; + + // Textbox for inputing the substring text + TextBox findBox = new TextBox(); + findBox.Width = 200; + findBox.Location = new Point(findLabel.Location.X + findLabel.Width + 20, findLabel.Location.Y - 4); + findBox.SelectedText = "Find this Text"; + findBox.Font = formFont; + + // Replace: label + Label replaceLabel = new Label() { Left = 20, Top = 60, Text = "Replace:" }; + replaceLabel.Width = 80; + replaceLabel.Font = formFont; + + // Textbox for inputting the substring text + TextBox replaceBox = new TextBox() { Left = replaceLabel.Right + 20, Top = replaceLabel.Location.Y - 4, Width = findBox.Width }; + replaceBox.SelectedText = "Replace with this Text"; + replaceBox.Font = formFont; + + // OK Button + Button okButton = new Button() { Text = "OK", Left = 20, Width = 75, Top = replaceBox.Location.Y + replaceBox.Height + 20 }; + okButton.MinimumSize = new Size(75, 25); + okButton.AutoSize = true; + okButton.Font = formFont; + + // Cancel Button + Button cancelButton = new Button() { Text = "Cancel", Left = okButton.Location.X + okButton.Width + 10, Top = okButton.Location.Y }; + cancelButton.MinimumSize = new Size(75, 25); + cancelButton.AutoSize = true; + cancelButton.Font = formFont; + + // Button actions + okButton.Click += (sender, e) => { _find = findBox.Text; _replace = replaceBox.Text; prompt.DialogResult = DialogResult.OK; }; + cancelButton.Click += (sender, e) => { prompt.DialogResult = DialogResult.Cancel; }; + + prompt.AcceptButton = okButton; + prompt.CancelButton = cancelButton; + + prompt.Controls.Add(findLabel); + prompt.Controls.Add(findBox); + prompt.Controls.Add(replaceLabel); + prompt.Controls.Add(replaceBox); + prompt.Controls.Add(okButton); + prompt.Controls.Add(cancelButton); + + // The user clicked OK, so perform the find-and-replace logic + if (prompt.ShowDialog() == DialogResult.OK) + { + + int _occurrences = 0; + var _ReplacedList = new List(); + + foreach (var _m in _measures) + { + if (_m.Expression != _m.Expression.Replace(_find, _replace)) + { + try + { + // Count number of occurrences of _find substring in the string + string _pattern = Regex.Escape(_find); + _occurrences = Regex.Matches(_m.Expression, _pattern).Count; + } + catch + { + // If it's not found there are 0 occurrences + _occurrences = 0; + } + + // Perform the Find/Replace + _m.Expression = _m.Expression.Replace(_find, _replace); + _ReplacedList.Add(_m.DaxObjectName); + } + } + + // Create a list of all the measures replaced + string _Replaced = _ReplacedList.Count > 0 + ? "\n\nMeasures with Replacements:\n • " + string.Join("\n • ", _ReplacedList) + : ""; + + // Return a success Info box pop-up + Info( + "Replaced " + + _occurrences + + " occurrences of '" + + _find + + "' with '" + + _replace + + "'" + + _Replaced); + } + else + { + Error("Find/Replace cancelled!"); + } +} + +``` + +### Explanation + +This snippet will create a pop-up dialogue with WinForms that will let you input a substring to search the selected measures and replace with a different substring. A success box dialogue will inform you that the find/replace was successful. + +### Example Output + +
    + An example of the pop-up Find/Replace dialog that allows the user to enter the sub-strings to be searched / replaced.
    Figure 1: An example of the pop-up Find/Replace dialog that allows the user to enter the sub-strings to be searched / replaced.
    +
    + +
    + An example of the info box dialog which informs the user that the Find/Replace was successful, and how many / which measures were affected by the script.
    Figure 2: An example of the info box dialog which informs the user that the Find/Replace was successful, and how many / which measures were affected by the script.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-format-numeric-measures_zh.md b/content/localization/zh/script-format-numeric-measures_zh.md new file mode 100644 index 00000000..377eec8a --- /dev/null +++ b/content/localization/zh/script-format-numeric-measures_zh.md @@ -0,0 +1,48 @@ +--- +uid: script-format-numeric-measures +title: Format Numeric Measures +author: Morten Lønskov +updated: 2023-11-29 +applies_to: + versions: + - version: 3.x +--- + +# Format Numeric Measures + +## Script Purpose + +Allows you to quickly set default format strings on the measures selected. + +

    + +> [!NOTE] +> The script uses certain naming standards so you might wish to adjust it to suit yours.

    + +## Script + +### Script Title + +```csharp +// This script is meant to format all measures with a default formatstring +foreach (var ms in Selected.Measures) { +//Don't set format string on hidden measures + if (ms.IsHidden) continue; +// If the format string is empty continue. + if (!string.IsNullOrWhiteSpace(ms.FormatString)) continue; +//If the data type is int set a whole number format string + if (ms.DataType == DataType.Int64) ms.FormatString = "#,##0"; +//If the datatype is double or decimal + if (ms.DataType == DataType.Double || ms.DataType == DataType.Decimal) { + //and the name contains # or QTY then set the format string to a whole number + if (ms.Name.Contains("#") + || ms.Name.IndexOf("QTY", StringComparison.OrdinalIgnoreCase) >= 0) ms.FormatString = "#,##0"; + //otherwise set it a decimal format string. + else ms.FormatString = "#,##0.00"; + } +} +``` + +### Explanation + +The script takes each of the selected measures and loops through them to set a default format string according to various conditions. \ No newline at end of file diff --git a/content/localization/zh/script-format-power-query_zh.md b/content/localization/zh/script-format-power-query_zh.md new file mode 100644 index 00000000..d06da782 --- /dev/null +++ b/content/localization/zh/script-format-power-query_zh.md @@ -0,0 +1,124 @@ +--- +uid: script-format-power-query +title: Format Power Query +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 3.x +--- + +# Format Power Query + +## Script Purpose + +If you want to format complex Power Query to make it more readable and easy to change.

    + +> [!NOTE] +> This script will send your Power Query M Code to the Power Query Formatter API. +> Please ensure responsible use and compliance when using this script to format your Power Query code.

    + +## Script + +### Format Power Query + +```csharp +// This script formats the Power Query (M Code) of any selected M Partition (not Shared Expression or Source Expression). +// It will send an HTTPS POST request of the expression to the Power Query Formatter API and replace the code with the result. +// +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +// URL of the powerqueryformatter.com API +string powerqueryformatterAPI = "https://m-formatter.azurewebsites.net/api/v2"; + +// HttpClient method to initiate the API call POST method for the URL +HttpClient client = new HttpClient(); +HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, powerqueryformatterAPI); + +// Get the M Expression of the selected partition +string partitionExpression = Selected.Partition.Expression; + +// Serialize the request body as a JSON object +var requestBody = JsonConvert.SerializeObject( + new { + code = partitionExpression, + resultType = "text", + lineWidth = 40, + alignLineCommentsToPosition = true, + includeComments = true + }); + +// Set the "Content-Type" header of the request to "application/json" and the encoding to UTF-8 +var content = new StringContent(requestBody, Encoding.UTF8, "application/json"); +content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + +// Retrieve the response +var response = client.PostAsync(powerqueryformatterAPI, content).Result; + +// If the response is successful +if (response.IsSuccessStatusCode) +{ + // Get the result of the response + var result = response.Content.ReadAsStringAsync().Result; + + // Parse the response JSON object from the string + JObject data = JObject.Parse(result.ToString()); + + // Get the formatted Power Query response + string formattedPowerQuery = (string)data["result"]; + + /////////////////////////////////////////////////////////////////////// + // OPTIONAL MANUAL FORMATTING + // Manually add a new line and comment to each step + var replace = new Dictionary + { + { " //", "\n\n//" }, + { "\n #", "\n\n // Step\n #" }, + { "\n Source", "\n\n // Data Source\n Source" }, + { "\n Dataflow", "\n\n // Dataflow Connection Info\n Dataflow" }, + {"\n Data =", "\n\n // Step\n Data ="}, + {"\n Navigation =", "\n\n // Step\n Navigation ="}, + {"in\n\n // Step\n #", "in\n #"}, + {"\nin", "\n\n// Result\nin"} + }; + + // Replace the first string in the dictionary with the second + var manuallyformattedPowerQuery = replace.Aggregate( + formattedPowerQuery, + (before, after) => before.Replace(after.Key, after.Value)); + + // Replace the auto-formatted code with the manually formatted version + formattedPowerQuery = manuallyformattedPowerQuery; + //////////////////////////////////////////////////////////////////////// + + // Replace the unformatted M expression with the formatted expression + Selected.Partition.Expression = formattedPowerQuery; + + // Pop-up to inform of completion + Info("Formatted " + Selected.Partition.Name); +} + +// Otherwise return an error message +else +{ +Info( + "API call unsuccessful." + + "\nCheck that you are selecting a partition with a valid M Expression." + ); +} +``` + +### Explanation + +This snippet creates an HTTP POST request of the Power Query in the M Partition and sends it to the [Power Query Formatter](https://www.powerqueryformatter.com/). +Some manual formatting is done to make the code further readable. + +## Example Output + +
    + Format Power Query example
    Figure 1: An illustration of the script formatting Power Query code.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-helper-methods_zh.md b/content/localization/zh/script-helper-methods_zh.md new file mode 100644 index 00000000..9001ed95 --- /dev/null +++ b/content/localization/zh/script-helper-methods_zh.md @@ -0,0 +1,51 @@ +--- +uid: script-helper-methods +title: C# Script Helper Methods +updated: 2023-02-27 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + + + +# C# Script Helper Methods + +When writing C# scripts in Tabular Editor, a number of global methods (i.e. methods that can be called without prefixing a class or object name) are available. + +The full list of these can be found in the [API documentation](xref:TabularEditor.Shared.Scripting.ScriptHost#methods). + +Below is a summary of these methods. Click on a method name to browse the API documentation for that method. + +|
    Method
    | Purpose | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`CallDaxFormatter`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CallDaxFormatter_System_Nullable_System_Boolean__System_Nullable_System_Boolean__) | Format all DAX expressions on objects currently flagged for formatting. | +| [`CollectVertiPaqAnalyzerStats`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CollectVertiPaqAnalyzerStats) | Collects VertiPaq Analyzer statistics for the currently loaded model. | +| [`ConvertDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ConvertDax_System_String_System_Boolean_) | Changes the character used for decimals and list separators in a DAX expression. | +| [`CustomAction`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CustomAction_System_String_) (+2) | Invoke the custom action (aka. macro) with the given name. | +| [`Error`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Error_System_String_) | Displays an error message in a popup dialog. When the script is running in the CLI, an error message is written to the console. | +| [`EvaluateDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_EvaluateDax_System_String_) | Evaluates the specified DAX expression against the connected database and returns a data table or scalar value containing the result. | +| [`ExecuteCommand`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExecuteCommand_System_String_System_Boolean_) | Executes the specified TMSL or XMLA command. | +| [`ExecuteDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExecuteDax_System_String_) | Executes the specified DAX query. | +| [`ExecuteReader`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExecuteReader_System_String_) | Executes the specified DAX query. | +| [`ExportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExportProperties_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_ITabularNamedObject__System_String_) | Export properties of the specified set of objects to a TSV (tab-separated) string.
    Use [`ImportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ImportProperties_System_String_) to import properties from a TSV string. | +| [`FormatDax`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_FormatDax_TabularEditor_TOMWrapper_IDaxDependantObject_) (+2) | Flags the specified object for formatting after script execution or the next time [`CallDaxFormatter`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_CallDaxFormatter_System_Nullable_System_Boolean__System_Nullable_System_Boolean__) is called. | +| [`GetObjectPath`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_GetObjectPath_TabularEditor_TOMWrapper_TabularObject_) | Returns a string representation that uniquely identifies the specified object within the model. | +| [`ImportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ImportProperties_System_String_) | Applies properties to objects based on a string representation (tab separated format) of property values to assign,
    such as obtained by [`ExportProperties`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ExportProperties_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_ITabularNamedObject__System_String_) . | +| [`Info`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Info_System_String_) | Displays an informational message in a popup dialog. When the script is running in the CLI, an information message is written to the console. | +| [`LineBreakFirstChar`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_LineBreakFirstChar_System_String_System_Boolean_) | Ensures that a DAX expression starts with a line break. | +| [`Model`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Model) | The currently loaded [`Model`](xref:TabularEditor.TOMWrapper.Model) . | +| [`Output`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Output_System_Object_) | Displays detailed information about the specified object or collection of objects in a popup dialog. When executed through the UI, the user has an option to ignore additional popups. When the script is running in the CLI, the information is written to the console. | +| [`ReadFile`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ReadFile_System_String_) | Read the specified file as text | +| [`ResolveObjectPath`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_ResolveObjectPath_System_String_) | Resolves an object within the model based on a string such as the one obtained by [`GetObjectPath`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_GetObjectPath_TabularEditor_TOMWrapper_TabularObject_) . | +| [`SaveFile`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SaveFile_System_String_System_String_System_Text_Encoding_) | Saves the specified text to a file | +| [`SelectColumn`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectColumn_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_Column__TabularEditor_TOMWrapper_Column_System_String_) (+1) | Displays a dialog that allows the user to select a column from the specified list of columns. | +| [`Selected`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Selected) | An object that represents the current selection in the TOM Explorer. | +| [`SelectMeasure`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectMeasure_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_Measure__TabularEditor_TOMWrapper_Measure_System_String_) (+3) | Displays a dialog that allows the user to select a measure from the specified list of measures. | +| [`SelectObject`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectObject__1_System_Collections_Generic_IEnumerable___0____0_System_String_) | Displays a dialog that allows the user to select a model object from a list of objects. | +| [`SelectObjects`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectObjects__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_IEnumerable___0__System_String_) | Displays a dialog that allows the user to select one or more model objects from a list of objects. | +| [`SelectTable`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SelectTable_System_Collections_Generic_IEnumerable_TabularEditor_TOMWrapper_Table__TabularEditor_TOMWrapper_Table_System_String_) (+2) | Displays a dialog that allows the user to select a table from the specified list of tables. | +| [`SuspendWaitForm`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_SuspendWaitForm_System_Action_) (+1) | Hides the "Please wait" spinner while performing the specified action. Useful if the action displays custom dialogs / UI to the end user. | +| [`WaitFormVisible`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_WaitFormVisible) | Toggle the "Please wait" spinner on/off. Useful if you want to display custom dialogs / UI to the end user. | +| [`Warning`](xref:TabularEditor.Shared.Scripting.ScriptHost#TabularEditor_Shared_Scripting_ScriptHost_Warning_System_String_) | Displays a warning message in a popup dialog. When the script is running in the CLI, a warning message is written to the console. | diff --git a/content/localization/zh/script-implement-incremental-refresh_zh.md b/content/localization/zh/script-implement-incremental-refresh_zh.md new file mode 100644 index 00000000..a4415aea --- /dev/null +++ b/content/localization/zh/script-implement-incremental-refresh_zh.md @@ -0,0 +1,493 @@ +--- +uid: script-implement-incremental-refresh +title: Setup Incremental Refresh +author: Kurt Buhler +updated: 2023-03-01 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Configure Incremental Refresh + +## Script Purpose + +If you want to configure Incremental Refresh for an import table based on a specific date field. +This script will work for `datetime`, `date`, or `integer` date columns for which you want to configure incremental refresh. + +To use the script, select the date column in the table for which you want to configure incremental refresh, then run the script. The script will only run if you don't already have a #"RangeStart" and #"RangeEnd" parameter, and the selected table doesn't already have a Refresh Policy configured. + +> [!NOTE] +> This script will automatically modify the M partition of the table to add the filter step. +> Be sure to check that this was done correctly. +> +> If you have many steps you must be sure to move this step to a point when it will fold to the data source. +> Make sure you adjust all the \`#"Step References" in Power Query + +> [!NOTE] +> This script uses user input to generate the refresh policy. +> Make sure you enter the correct values in the user input dialogue box. + +## Script + +### Implement Incremental Refresh for Selected Column + +```csharp +// This script will automatically generate an Incremental Refresh policy for a selected table +// It is generated based on the selected column +// It requires input from the user with a dialogue pop-up box. +// This script will automatically generate an Incremental Refresh policy for a selected table +// It is generated based on the selected column +// It requires input from the user with a dialogue pop-up box. +using System.Drawing; +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Initialize Variables +Table _Table = Model.Tables[0]; +string _MExpression = ""; +Column _Column = Model.AllColumns.ToList()[0]; +string _ColumnName = ""; +DataType _ColumnDataType = DataType.DateTime; + +try + { + // Select a Table for which you will configure Incremental Refresh. + // The Refresh Policy will be enabled and configured for this table. + _Table = + Model.Tables.Where( + + // Exclude tables that already have a refresh policy + t => + t.EnableRefreshPolicy != true && + + // Include only 'Table' objects + t.ObjectType == ObjectType.Table && + + // Exclude Calculated Tables + t.Columns[0].Type != ColumnType.CalculatedTableColumn && + + // Only include tables that have a column on the "From" side of the relationship + (Model.Relationships.Count() > 0 ? + t.Columns.Any(c => Model.Relationships.Any(r => r.FromColumn == c) ) : true) && + + // Exclude tables that don't have a DateTime or Integer column + ( + t.Columns.Any(c => c.DataType == DataType.DateTime) || + t.Columns.Any(c => c.DataType == DataType.Int64) + ) + ).SelectTable(null,"Select a Table for which you will configure Incremental Refresh:"); + + _MExpression = _Table.Partitions[0].Expression; + + try + { + // Select the column to apply the Refresh Policy. + // The M Expression will be modified using the name of this column. + _Column = + _Table.Columns.Where( + + // Include only DateTime or Int columns + c => + c.DataType == DataType.DateTime || + c.DataType == DataType.Int64 + + ).SelectColumn(null, "Select a DateTime or DateKey (Int) Column to apply the Refresh Policy."); + + _ColumnName = _Column.DaxObjectName; + _ColumnDataType = _Column.DataType; + + try + { // Test if 'RangeStart' exists + Model.Expressions.Contains(Model.Expressions["RangeStart"]); + Info ("RangeStart already exists!"); + } + catch + { + // Add RangeStart parameter + Model.AddExpression( + "RangeStart", + @" + #datetime(2023, 01, 01, 0, 0, 0) meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ]" + ); + + // Success message for adding 'RangeStart' + Info ( "Created 'RangeStart' M Parameter!" ); + } + + // Test if the RangeEnd parameter exists + try + { // Test if 'RangeEnd' exists + Model.Expressions.Contains(Model.Expressions["RangeEnd"]); + Info ("RangeEnd already exists!"); + } + catch + { + // Add RangeEnd parameter + Model.AddExpression( + "RangeEnd", + @" + #datetime(2023, 31, 01, 0, 0, 0) meta + [ + IsParameterQuery = true, + IsParameterQueryRequired = true, + Type = type datetime + ]" + ); + + // Success message for adding 'RangeEnd' + Info ( "Created 'RangeEnd' M Parameter!" ); + + } + + // Incremental Refresh Configuration + // Input box config + Font _fontConfig = new Font("Segoe UI", 11); + + // Label for how long data should be stored + var storeDataLabel = new Label(); + storeDataLabel.Text = "Store data in the last:"; + storeDataLabel.Location = new Point(20, 20); + storeDataLabel.AutoSize = true; + storeDataLabel.Font = _fontConfig; + + // User input for how long data should be stored + var storeDataTextBox = new TextBox(); + storeDataTextBox.Location = new Point(storeDataLabel.Location.X + TextRenderer.MeasureText(storeDataLabel.Text, storeDataLabel.Font).Width + 20, storeDataLabel.Location.Y); + storeDataTextBox.Size = new Size(100, 20); + storeDataTextBox.Text = "3"; + storeDataTextBox.Font = _fontConfig; + + // User selection for how long data should be stored (granularity) + var storeDataComboBox = new ComboBox(); + storeDataComboBox.Location = new Point(storeDataTextBox.Location.X + storeDataTextBox.Width + 20, storeDataLabel.Location.Y); + storeDataComboBox.Size = new Size(100, 20); + storeDataComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + storeDataComboBox.Items.AddRange(new object[] { "days", "months", "quarters", "years" }); + storeDataComboBox.SelectedIndex = 3; + storeDataComboBox.Font = _fontConfig; + + // Label for how much data should be refreshed + var refreshDataLabel = new Label(); + refreshDataLabel.Text = "Refresh data in the last:"; + refreshDataLabel.Location = new Point(20, storeDataLabel.Location.Y + storeDataLabel.Height + 15); + refreshDataLabel.AutoSize = true; + refreshDataLabel.Font = _fontConfig; + + // User input for how much data should be refreshed + var refreshDataTextBox = new TextBox(); + refreshDataTextBox.Location = new Point(storeDataTextBox.Location.X, refreshDataLabel.Location.Y); + refreshDataTextBox.Size = new Size(100, 20); + refreshDataTextBox.Text = "30"; + refreshDataTextBox.Font = _fontConfig; + + // User selection for how much data should be refreshed (Period) + var refreshDataComboBox = new ComboBox(); + refreshDataComboBox.Location = new Point(storeDataComboBox.Location.X, refreshDataLabel.Location.Y); + refreshDataComboBox.Size = new Size(100, 20); + refreshDataComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + refreshDataComboBox.Items.AddRange(new object[] { "days", "months", "quarters", "years" }); + refreshDataComboBox.SelectedIndex = 0; + refreshDataComboBox.Font = _fontConfig; + + // User input to refresh full periods or not + var fullPeriodsCheckBox = new CheckBox(); + fullPeriodsCheckBox.Text = "Refresh only full periods"; + fullPeriodsCheckBox.Location = new Point(storeDataLabel.Location.X + 3, refreshDataLabel.Location.Y + refreshDataLabel.Height + 15); + fullPeriodsCheckBox.AutoSize = true; + fullPeriodsCheckBox.Font = _fontConfig; + + // Form OK button + var okButton = new Button(); + okButton.Text = "OK"; + okButton.Location = new Point(storeDataLabel.Location.X, fullPeriodsCheckBox.Location.Y + fullPeriodsCheckBox.Height + 15); + okButton.MinimumSize = new Size(80, 25); + okButton.AutoSize = true; + okButton.DialogResult = DialogResult.OK; + okButton.Font = _fontConfig; + + // Form cancel button + var cancelButton = new Button(); + cancelButton.Text = "Cancel"; + cancelButton.Location = new Point(okButton.Location.X + okButton.Width + 10, okButton.Location.Y); + cancelButton.MinimumSize = new Size(80, 25); + cancelButton.AutoSize = true; + cancelButton.DialogResult = DialogResult.Cancel; + cancelButton.Font = _fontConfig; + + // Adjust the Location of the storeDataLabel to align with the storeDataTextBox + storeDataLabel.Location = new Point(storeDataLabel.Location.X, storeDataLabel.Location.Y + 4); + refreshDataLabel.Location = new Point(refreshDataLabel.Location.X, refreshDataLabel.Location.Y + 4); + + // Form config + var form = new Form(); + form.Text = "Incremental Refresh configuration:"; + form.AutoSize = true; + form.MinimumSize = new Size(450, 0); + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + + // Open the dialogue in the center of the screen + form.StartPosition = FormStartPosition.CenterScreen; + + // Set the AutoScaleMode property to Dpi + form.AutoScaleMode = AutoScaleMode.Dpi; + + // Add controls to form specified above + form.Controls.Add(storeDataLabel); + form.Controls.Add(storeDataTextBox); + form.Controls.Add(storeDataComboBox); + form.Controls.Add(refreshDataLabel); + form.Controls.Add(refreshDataTextBox); + form.Controls.Add(refreshDataComboBox); + form.Controls.Add(fullPeriodsCheckBox); + form.Controls.Add(okButton); + form.Controls.Add(cancelButton); + + // Draw the form + var result = form.ShowDialog(); + + // Get the values of the user input if entered + if (result == DialogResult.OK) + { + // Enables the refresh policy + _Table.EnableRefreshPolicy = true; + + var storeDataValue = storeDataTextBox.Text; + var storeDataComboBoxValue = storeDataComboBox.SelectedItem.ToString(); + var refreshDataValue = refreshDataTextBox.Text; + var refreshDataComboBoxValue = refreshDataComboBox.SelectedItem.ToString(); + var fullPeriodsChecked = fullPeriodsCheckBox.Checked; + + // Display the input values in a message box + var message = string.Format( + "Store data in the last: {0} {1}" + + "\nRefresh data in the last: {2} {3}" + + "\nRefresh only full periods: {4}", + storeDataTextBox.Text, + storeDataComboBox.SelectedItem.ToString(), + refreshDataTextBox.Text, + refreshDataComboBox.SelectedItem.ToString(), + fullPeriodsCheckBox.Checked); + + Info(message); + + // Convert StoreDataGranularity to correct TOM Property + RefreshGranularityType StoreDataGranularity = RefreshGranularityType.Day; + switch (storeDataComboBox.SelectedItem.ToString()) + { + case "years": + StoreDataGranularity = RefreshGranularityType.Year; + break; + + case "quarters": + StoreDataGranularity = RefreshGranularityType.Quarter; + break; + + case "months": + StoreDataGranularity = RefreshGranularityType.Month; + break; + + case "days": + StoreDataGranularity = RefreshGranularityType.Day; + break; + + default: + Error("Bad selection for Incremental Granularity."); + break; + } + + + // Convert IncrementalGranularity to correct TOM Property + RefreshGranularityType IncrementalPeriodGranularity = RefreshGranularityType.Year; + switch (refreshDataComboBox.SelectedItem.ToString()) + { + case "years": + IncrementalPeriodGranularity = RefreshGranularityType.Year; + break; + + case "quarters": + IncrementalPeriodGranularity = RefreshGranularityType.Quarter; + break; + + case "months": + IncrementalPeriodGranularity = RefreshGranularityType.Month; + break; + + case "days": + IncrementalPeriodGranularity = RefreshGranularityType.Day; + break; + + default: + Error ( "Bad selection for Incremental Granularity." ); + break; + } + + // Convert RefreshCompletePeriods checkbox to correct TOM property + int RefreshCompletePeriods; + if ( fullPeriodsCheckBox.Checked == true ) + { + RefreshCompletePeriods = -1; + } + else + { + RefreshCompletePeriods = 0; + } + + // Set incremental window: period to be refreshed + _Table.IncrementalGranularity = IncrementalPeriodGranularity; + + // Default: 30 days - change # if you want + _Table.IncrementalPeriods = Convert.ToInt16(refreshDataTextBox.Text); + + // Only refresh complete days. Change to 0 if you don't want. + _Table.IncrementalPeriodsOffset = RefreshCompletePeriods; + + // Set rolling window: period to be archived + // Granularity = day, can change to month, quarter, year... + _Table.RollingWindowGranularity = StoreDataGranularity; + + // Keep data for 1 year. Includes 1 full year and current partial year + // i.e. if it is Nov 2023, keeps data from Jan 1, 2022. + // On Jan 1, 2024, it will drop 2022 automatically. + _Table.RollingWindowPeriods = Convert.ToInt16(storeDataTextBox.Text); + + // If the selected date column is an integer of type YYYYMMDD... + if ( _ColumnDataType == DataType.Int64 ) + { + // Add DateTimeToInt Function + var _DateTimeToInt = + Model.AddExpression( + "fxDateTimeToInt", + @"(x as datetime) => Date.Year(x) * 10000 + Date.Month(x) * 100 + Date.Day(x)" + ); + + _DateTimeToInt.SetAnnotation("PBI_ResultType", "Function"); + _DateTimeToInt.Kind = ExpressionKind.M; + + // Source expression obtained from the original M partition + _Table.SourceExpression = + + // Gets expression before final "in" keyword + _MExpression.Split("\nin")[0].TrimEnd() + + + // Adds comma and newline + ",\n" + + + // Adds step called "Incremental Refresh" for filtering + @" #""Incremental Refresh"" = Table.SelectRows( " + + + // Gets name of last step (after "in" keyword) + _MExpression.Split("\nin")[1].TrimStart() + + + // Adds 'each' keyword + @", each " + + + // Bases incremental refresh on current column name + _ColumnName + + + // Greater than or equal to RangeStart + @" >= fxDateTimeToInt ( #""RangeStart"" ) and " + + + // and + _ColumnName + + + // Less than RangeEnd + @" < fxDateTimeToInt ( #""RangeEnd"" ) )" + + + // re-add 'in' keyword + "\nin\n" + + + // Reference final step just added + @" #""Incremental Refresh"""; + } + + + // Otherwise treat it like a normal date/datetime column + else + { + // Source expression obtained from the original M partition + _Table.SourceExpression = + // Gets expression before final "in" keyword + _MExpression.Split("\nin")[0].TrimEnd() + + + // Adds comma and newline + ",\n" + + + // Adds step called "Incremental Refresh" for filtering + @" #""Incremental Refresh"" = Table.SelectRows( " + + + // Gets name of last step (after "in" keyword) + _MExpression.Split("\nin")[1].TrimStart() + + + // Adds 'each' keyword + @", each " + + + // Bases incremental refresh on current column name + _ColumnName + + + // Greater than or equal to RangeStart + @" >= Date.From ( #""RangeStart"" ) and " + + + // and + _ColumnName + + + // Less than RangeEnd + @" < Date.From ( #""RangeEnd"" ) )" + + + // re-add 'in' keyword + "\nin\n" + + + // Reference final step just added + @" #""Incremental Refresh"""; + } + + // Success message for Refresh Policy configuration + Info ( + "Successfully configured the Incremental Refresh policy.\n" + + "\nSelect the table and right-click on 'Apply Refresh Policy...'" + + "\nSelect & peform a 'Full Refresh' of all new policy partitons that are created." + ); + } + else if (result == DialogResult.Cancel) + { + // if the user clicks the Cancel button, close the form and exit the script + form.Close(); + Error ( "Cancelled configuration! Ending script without changes." ); + return; + } + } + catch + { + Error( "No valid column selected! Ending script without changes." ); + } + +} +catch +{ + Error( "No valid table selected! Ending script without changes." ); +} +``` + +### Explanation + +This snippet will configure incremental refresh in the selected table based on a selected date column. + +## Example Output + +
    + The prompt that helps you configure incremental refresh based on selected columns
    Figure 1: When running the script, you are prompted to select the Table you want to configure, and the DateTime or Int column the policy will be configured for. Then, the dialog in this image will appear to let you enter the Refresh Policy parameters.
    +
    + +
    + A confirmation dialog that acknowledges you have configured the refresh policy
    Figure 2: A confirmation dialog will inform you about the success of the Refresh Policy configuration, explaining it back to you in plain words.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-output-things_zh.md b/content/localization/zh/script-output-things_zh.md new file mode 100644 index 00000000..52cb88c3 --- /dev/null +++ b/content/localization/zh/script-output-things_zh.md @@ -0,0 +1,68 @@ +--- +uid: script-output-things +title: Output Object Details in a Grid +author: Daniel Otykier +updated: 2024-12-13 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Output Object Details in a Grid + +## Script Purpose + +Another way to get an overview of objects in the model, and how they are configured, is to output them in a grid using the C# [`DataTable`](https://learn.microsoft.com/en-us/dotnet/api/system.data.datatable?view=net-8.0) class. This is a very flexible technique, as you can add only the information you are interested in, as columns of the `DataTable`. Moreover, when passing a `DataTable` to the `Output()` method, Tabular Editor will automatically display it in a grid view, which is very convenient for inspecting the data. + +## Script + +### Show measure complexity details + +```csharp +// This script displays a grid with details about each measure in the model. +using System.Data; + +var result = new DataTable(); +result.Columns.Add("Name"); +result.Columns.Add("Table"); +result.Columns.Add("Expression token count", typeof(int)); +result.Columns.Add("Expression line count", typeof(int)); +result.Columns.Add("Description line count", typeof(int)); +result.Columns.Add("Format String"); + +foreach(var m in Model.AllMeasures) +{ + var row = new object[] + { + m.DaxObjectName, // Name + m.Table.Name, // Table + m.Tokenize().Count, // Token count + m.Expression.Split(new []{'\n'}, StringSplitOptions.RemoveEmptyEntries).Length, + m.Description.Split(new []{'\n'}, StringSplitOptions.RemoveEmptyEntries).Length, + m.FormatStringExpression ?? m.FormatString + }; + result.Rows.Add(row); +} + +Output(result); +``` + +### Explanation + +This snippet first configures a `DataTable` object with the columns we want to display in the grid. We explicitly specify the `typeof(int)` for some of the columns, to ensure that sorting works correctly. We then iterate over all measures in the model, and for each measure, we create a new row in the `DataTable` with the desired information. Finally, we pass the `DataTable` to the `Output()` method, which will display the grid. + +The columns displayed are: + +- **Name**: The name of the measure. +- **Table**: The name of the table the measure belongs to. +- **Expression token count**: The number of tokens in the measure expression. This is a rough measure of DAX complexity. +- **Expression line count**: The number of lines in the measure expression, not counting empty lines. +- **Description line count**: The number of lines in the measure description, not counting empty lines. +- **Format String**: The measure's format string expresssion or format string, if any. + +## Example Output + +
    + Example of the dialog pop-up that displays the grid.
    Figure 1: Example of the dialog pop-up that displays the grid. Both Tabular Editor 2 and Tabular Editor 3 will let you sort the grid columns as well as copy the output to the clipboard. However, Tabular Editor 3 also has additional features for grouping, filtering, and searching within the grid.
    +
    \ No newline at end of file diff --git a/content/localization/zh/script-remove-measures-with-error_zh.md b/content/localization/zh/script-remove-measures-with-error_zh.md new file mode 100644 index 00000000..8fe9c842 --- /dev/null +++ b/content/localization/zh/script-remove-measures-with-error_zh.md @@ -0,0 +1,126 @@ +--- +uid: script-remove-measures-with-error +title: View/Remove Measures with Errors +author: Kurt Buhler +updated: 2023-02-28 +applies_to: + versions: + - version: 3.x +--- + +# View/Remove Measures with Errors + +## Script Purpose + +If you want to see all the measures that have errors and have the option to delete them from the model, saving a back-up .tsv of the deleted measures to a selected directory (in case you want to re-add them, later). + +## Script + +### View & Remove Measures with Errors + +```csharp +// This script scans the model and shows all measures with errors, giving the option to remove them. +// +// .GetCachedSemantics(...) method is only available in TE3 +using System.Windows.Forms; + +// Hide the 'Running Macro' spinbox +ScriptHelper.WaitFormVisible = false; + +// Get all the measures that have errors +var measuresWithError = Model.AllMeasures.Where(m => m.GetCachedSemantics(ExpressionProperty.Expression).HasError).ToList(); +//Prior to Tabular Editor 3.12.0 the GetSemantics method must be used. +//var measuresWithError = Model.AllMeasures.Where(m => m.GetSemantics(ExpressionProperty.Expression).HasError).ToList(); + +// If no measures with errors, end script with error. +if ( measuresWithError.Count == 0 ) +{ +Info ( "No measures with errors! 👍" ); +} + +// Handle erroneous measures +else +{ + +// View the list of measures with an error +measuresWithError.Output(); + +// From the list, you can select 1 or more measures to delete +var _ToDelete = SelectObjects(measuresWithError, measuresWithError, "Select measures to delete.\nYou will be able to export a back-up, later."); + + // Delete the selected measures + try + { + foreach ( var _m in _ToDelete ) + { + _m.Delete(); + } + + Info ( + "Deleted " + + Convert.ToString(_ToDelete.Count()) + + " measures with errors." + ); + + // Create an instance of the FolderBrowserDialog class + FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); + + // Set the title of the dialog box + folderBrowserDialog.Description = "Select a directory to output a backup of the deleted measures."; + + // Set the root folder of the dialog box + folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer; + + // Show the dialog box and get the result + DialogResult result = folderBrowserDialog.ShowDialog(); + + // Check if the user clicked the OK button and get the selected path + if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(folderBrowserDialog.SelectedPath)) + { + // Get the output path as a string + string _outputPath = folderBrowserDialog.SelectedPath; + + // Get the properties of the deleted measures + var _backup = ExportProperties( _ToDelete ); + + // Save a backup of the deleted measures + SaveFile( _outputPath + "/DeletedMeasures-" + Model.Name + DateTime.Today.ToString("-yyyy-MM-dd") + ".tsv", _backup); + + Info ( + "Exported a backup of " + + Convert.ToString(_ToDelete.Count()) + + " Measures to " + + _outputPath + ); + } + } + catch + // Display an info box if no measure was selected + { + Info ( "No measure selected." ); + } +} + +``` + +### Explanation + +This snippet gets all the measures that have errors according to the Tabular Editor Semantic Analysis. It then will display them in an output box where you can manually browse them or make changes. Thereafter, measures can be selected for removal. The removed measures can be saved as a back-up .tsv file in case you want to import them, later. + +## Example Output + +
    + An output dialog that lets the user view and edit any measures with errors in Tabular Editor
    Figure 1: An output dialog allows you to view and also edit any measures that currently have 'errors' according to the analysis services semantic analysis.
    +
    + +
    + A selection dialog that lets the user select measures to delete
    Figure 2: Measures with errors can be selected for deletion.
    +
    + +
    + A confirmation dialog that informs the user the deletion was successful
    Figure 3: A confirmation dialog will inform you deletion of the measures was successful.
    +
    + +
    + A dialog that lets the user select a directory to save a .tsv back-up of the deleted measure metadata
    Figure 4: An optional .tsv backup of the measure properties and definitions can be saved to a local directory, in case they need to be re-added, later.
    +
    diff --git a/content/localization/zh/script-show-data-source-dependencies_zh.md b/content/localization/zh/script-show-data-source-dependencies_zh.md new file mode 100644 index 00000000..41a4491b --- /dev/null +++ b/content/localization/zh/script-show-data-source-dependencies_zh.md @@ -0,0 +1,59 @@ +--- +uid: script-show-data-source-dependencies +title: Show Data Source Dependencies +author: David Bojsen +updated: 2023-09-12 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +# Show Data Source Dependencies + +## Script Purpose + +The script outputs the tables that reference the selected explicit (legacy) data source. This will make it easier to determine where a selected data source is used. + +## Script + +### Show Data Source Dependencies + +```csharp +//The script outputs the tables that reference the selected explicit (legacy) data source. +if (Model.DataSources.Count == 0) +{ + Info("This model doesn't contain any data sources, it is either empty or using implicit datasources"); + return; +} +// Checks that a data source is selected +DataSource selectedDatasource = null; + +if (Selected.DataSources.Count == 1) + selectedDatasource = Selected.DataSource; +else + selectedDatasource = SelectObject(Model.DataSources, null, "Select which datasource to see dependencies for"); + +// Legacy sources +var legacyTables = Model.Tables.Where(t => t.Source == selectedDatasource.Name).ToList(); + +// M sources +var mTables = Model.Tables.Where(t => t.Partitions.Any(p => p.Expression.Contains($"= #\"{selectedDatasource.Name}\","))).ToList(); + +// join arrays +var allTables = legacyTables.Union(mTables).OrderBy(t => t.Name); + +// Present result +var tableString = string.Join("\r\n", allTables.Select(t => t.Name)); +Info($"Datasource {selectedDatasource.Name} is referenced from the following tables:\r\n" + tableString); +``` + +### Explanation + +This snippet takes the selected data source and goes through the model to collect the partitions where that data source is used. + +## Example Output + +
    + Example of the dialog pop-up that informs the user which tables use the selected data source
    Figure 1: Example of the dialog pop-up that informs the user which tables use the selected data source.
    +
    \ No newline at end of file diff --git a/content/localization/zh/security-privacy_zh.md b/content/localization/zh/security-privacy_zh.md new file mode 100644 index 00000000..c62d5f4d --- /dev/null +++ b/content/localization/zh/security-privacy_zh.md @@ -0,0 +1,86 @@ +--- +uid: security-privacy +title: Security overview +author: Daniel Otykier +updated: 2024-10-30 +--- + +# Tabular Editor 3 Security and Privacy + +This document describes the security and privacy considerations of Tabular Editor 3 and its use. In the following, the phrase "Tabular Editor" can mean both the commercial tool Tabular Editor 3, as well as the open-source tool Tabular Editor 2.X. Whenever something considers only one of the tools, we will use their explicit names "Tabular Editor 3" or "Tabular Editor 2.X". + +## Microsoft advice on third-party tools such as Tabular Editor + +Microsoft supports the use of community third-party tools as communicated here: [Community and third-party tools for developing enterprise-level Power BI and Analysis Services models](https://powerbi.microsoft.com/en-us/blog/community-tools-for-enterprise-powerbi-and-analysisservices) + +Microsoft's Power BI implementation planning documentation specifically includes Tabular Editor in advanced data modeling scenarios and enterprise development: [Power BI usage scenarios: Advanced data model management](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-usage-scenario-advanced-data-model-management#tabular-editor) + +## Trust Center + +At Tabular Editor, we are committed to transparency and strong security practices. Visit our [Trust Center](https://trust.tabulareditor.com/) to find details about our SOC 2 audit report, key policy documents, license terms, and our approach to infrastructure and organizational security. You’ll also find information about our sub-processors and how we work to keep your data safe. + +## Metadata and Data Privacy + +Tabular Editor is primarily an offline tool, meaning that all data and metadata reside locally in the client machine on which Tabular Editor is installed, and all user interactions are performed locally as well. An Internet connection is not required to run and use Tabular Editor. + +That being said, there are scenarios in which Tabular Editor connects to remote services for various purposes. These are described in the following: + +### Analysis Services XMLA Protocol + +All communication with Analysis Services instances or Power BI Premium workspaces happens through the use of the [Microsoft Analysis Management Objects (AMO)](https://docs.microsoft.com/en-us/analysis-services/amo/developing-with-analysis-management-objects-amo?view=asallproducts-allversions) client libraries, or more specifically, the [Tabular Object Model (TOM) extension for AMO](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions). These client libraries are provided by Microsoft for redistribution in 3rd party applications such as Tabular Editor. For licensing details, please refer to the [AMO EULA](https://go.microsoft.com/fwlink/?linkid=852989). + +When Tabular Editor connects to an instance of Analysis Services (local network or cloud) or a Power BI Premium workspace (cloud), this connection is performed through the client libraries mentioned above. By design, the AMO library handles the authentication and authorization of the user. Only users with administrative privileges on the Analysis Services instance or Power BI Premium workspace, are allowed to connect. This is no different than when using Microsoft tools such as SQL Server Management Studio or SQL Server Data Tools (which use the same client libraries for connectivity). + +### Tabular Object Model metadata + +Once the AMO/TOM client library establishes connection, Tabular Editor will request the full Tabular Object Model (TOM) metadata for the specific Analysis Services database or Power BI dataset that the user wants to connect to. The AMO/TOM client library then serves this metadata to the client application (Tabular Editor) in a programmatic approach, allowing the application to apply metadata changes, such as renaming an object, adding a description, modifying a DAX expression, etc. In addition, the AMO/TOM client library provides methods for serializing the TOM metadata into a JSON-based format. Tabular Editor uses this technique to allow users to save the model metadata as a local JSON file, for purposes of version control of the data model structure. **Note: The JSON file produced this way contains no actual data records. The file contains only model metadata, that is, information about the structure of the model in terms of tables, columns, measures, DAX expressions, etc.** While model metadata is generally not considered confidential information, it is the responsibility of the user of Tabular Editor to handle any file produced this way with the required confidentiality (i.e. not sharing the file with 3rd parties, etc.). + +**Tabular Editor does not collect, publish, share, transfer or otherwise make public any model metadata obtained through the AMO/TOM client library unless the user specifically initiates an action to do so** (for example by saving the model metadata JSON file to a shared network location, or deploying the model metadata to another instance of Analysis Services or Power BI workspace). + +### Model data content + +In the following, "model data" refers to the actual data records stored within the Analysis Services database or Power BI dataset. Depending on the source database or dataset, it is very likely that the model data is confidential. + +Because of the requirement for a user to have administrative privileges on the instance of Analysis Services or Power BI workspace that they are connecting to, the user will, by definition, also have access to all data content of the Analysis Services database or Power BI dataset. Tabular Editor only allows retrieval of data through the AMO client library mentioned above. Tabular Editor 3 provides features for browsing and querying model data. Regardless of which technique is used to access the data **Tabular Editor only stores retrieved data in local memory. Tabular Editor does not collect, publish, share, transfer or otherwise make public any model data obtained through the tool**. If a user chooses to copy or export query results obtained through Tabular Editor, it is their responsibility to treat the copied or exported data according to the confidentiality of the data. This is no different than a user connecting to the Analysis Services database or Power BI dataset using client tools such as Excel or Power BI, in which case they will also have the option to copy query results. + +### Web requests + +Tabular Editor may perform requests to online resources (web URLs) only in the following cases: + +- **License activation\*.** When Tabular Editor 3 is first launched, and at periodic intervals thereafter, the tool may perform a request to our licensing service. This request contains encrypted information about the license key entered by the user, the e-mail address of the user (if provided), the local machine name and a one-way encoded hash identifying the current installation. No other data is transmitted in this request. The purpose of this request, is to activate and validate the license key used by the installation, enforce trial limitations, as well as allowing the user to manage their installations of Tabular Editor 3 through our licensing service. +- **Upgrade checks\*.** Each time Tabular Editor 3 is launched, it may perform a request to our application service, in order to determine if a newer version of Tabular Editor 3 is available. This request does not contain any data. +- **Usage telemetry\*.** By default, Tabular Editor 3 collects and transmits anonymous usage data as users interact with the tool. This data includes information about which UI objects a user interacts with and the timing of each. It also contains high-level information about the Tabular data model being edited through the tool. This information only relates to high-level properties like compatibility level and mode, number of tables, type of server (Analysis Services vs. Power BI vs. Power BI Desktop), etc. **No personally identifyable data is collected this way**, neither do we collect any information about names of objects or DAX expressions in the Tabular Object Model itself. A user may opt out of sending telemetry data to us at any point. +- **Error reports\*.** When an unexpected error occurs, we transmit the stack trace and (anonymized) error message, along with an optional description provided by the user. If a user opts out of sending telemetry data, error reports will also not be sent. +- **Using the DAX formatter.** (Tabular Editor 2.x only) A DAX expression may be formatted by clicking a button in Tabular Editor. In this case, the DAX expression (and nothing else) is sent to the www.daxformatter.com webservice. The first time a user clicks this button, an explicit warning message is shown, asking them to confirm their intent. Tabular Editor 3 does not perform web requests when formatting DAX code. +- **DAX Optimizer**. If a user has a [Tabular Tools account](https://tabulartools.com) with a [DAX Optimizer](https://daxoptimizer.com) subscription, they will be able to browse their DAX Optimizer workspace, view issues and suggestions, and upload new VPAX files directly from within Tabular Editor 3. VPAX files contains model metadata and statistics, but no actual model _data_. The DAX Optimizer Integration feature in Tabular Editor 3 causes various requests to one or more of the below endpoints (depending on authentication type and region specified when the Tabular Tools account was created).
    + For more information, please consult the [DAX Optimizer documentation](https://docs.daxoptimizer.com/legal/data-processing).
    + Endpoints used: + - https://account.tabulartools.com + - https://licensing.api.daxoptimizer.com/api + - https://australiaeast.api.daxoptimizer.com/api + - https://eastus.api.daxoptimizer.com/api + - https://westeurope.api.daxoptimizer.com/api +- **Importing Best Practice Rules.** Tabular Editor has a feature that allows a user to specify an URL from which to retrieve a list of Best Practice rules in a JSON based format. This type of request only downloads the JSON data from the URL - no data is transmitted to the URL. +- **Using C# scripts.** Tabular Editor allows users to write and execute code written in C#, for purposes of automation. Such a script may potentially connect to online resources, using C# language features and the .NET runtime. The user is always responsible for ensuring that executed code does not cause any unintended sharing of data. Tabular Editor ApS cannot be held liable for any damages, losses or leaks caused by the use of the C# scripting feature in general. Tabular Editor will never execute C# scripts without the explicit action of the user. + +\***Any information we obtain through the license activation service, the usage telemetry or the error reports, is kept confidential. We will not share, publish or distribute the data collected in any way, shape or form.** + +**Firewall allowlist / acceptlist** +To allow traffic to the above mentioned web requests, you'll have to whitelist: + +- License activation / upgrade checks: **https://api.tabulareditor.com** +- Usage telemetry / Error reports: **https://\*.in.applicationinsights.azure.com** +- DAX Formatter (Tabular Editor 2.x only): **https://www.daxformatter.com** +- Import Best Practice Rules / C# Scripts: Depends on the context +- DAX Optimizer: Endpoints listed above. + +> [!NOTE] +> A system administrator may enforce certain [policies](xref:policies), which can be used to disable some or all of the features shown on the list above. + +## Application Security + +Tabular Editor does not require any elevated privileges on the Windows machine in which it is installed, neither does it access any restricted resources on the machine. One exception from this rule, is if using the Tabular Editor installer file (.msi), in which case the executable and support files required by the tool, are by default copied to the `Program Files` folder, which typically requires elevated permission. Both the Tabular Editor binary files as well as the installer file, have been signed with a code signing certificate issued to Kapacity A/S, which is your guarantee that the code has not been tampered with by any 3rd party. + +When the application is executing, all access to external resources are performed through the AMO/TOM client library or the web requests mentioned above. + +The C# script feature allows Tabular Editor to execute arbitrary C# code within the .NET runtime. Such code is only compiled and executed on the explicit request of the user. C# scripts may also be saved as "macros", which makes it easier for the user to manage and execute multiple different scripts. The code is stored to the users own `%localappdata%` folder, ensuring that only they or a local machine administrator, can access the scripts. The user is always responsible for ensuring that executed code does not cause any unintended sideeffects. Under no circumstance can Tabular Editor ApS be held liable for any damages, losses or leaks caused by the use of the C# scripting or custom actions/macros features. diff --git a/content/localization/zh/semantic-model-types_zh.md b/content/localization/zh/semantic-model-types_zh.md new file mode 100644 index 00000000..d9059226 --- /dev/null +++ b/content/localization/zh/semantic-model-types_zh.md @@ -0,0 +1,71 @@ +--- +uid: semantic-model-types +title: Power BI Semantic model Types +author: Morten Lønskov +updated: 2025-06-19 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Semantic Model Types + +Tabular Editor can work with several different model types. Below is an overview of which model types work with Tabular Editor and the capabilities that can be used with each model type. + +|Model Type|Import|Direct Query|Direct Lake on OneLake|Direct Lake on SQL|.pbix|.pbip| +\|---|---|---|---|---| +|Connect in Tabular Editor|✔️|✔️|✔️|✔️|✔️| +|Create new model|✔️|✔️|✔️|✔️|✔️|✔️| +|Write Measures|✔️|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Tables|✔️|✔️|✔️[1](#DirectLake)|✔️[1](#DirectLake)|✔️|✔️| +|Create & Edit Partitions|✔️|✔️|✔️[1](#DirectLake)|✔️[1](#DirectLake)|✔️|✔️| +|Create & Edit Columns|✔️|✔️|✔️[1](#DirectLake)|✔️[1](#DirectLake)|✔️|✔️| +|Create & Edit Calculated Tables|✔️|✔️|✔️[2](#DirectLakeCalculated)|✔️|✔️|✔️| +|Create & Edit Calculated Columns|✔️|✔️|✔️[2](#DirectLakeCalculated)|✔️|✔️|✔️| +|Create & Edit Calculation Groups|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Relationships|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Roles|✔️|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Perspectives|✔️|✔️|✔️|✔️|✔️|✔️| +|Create & Edit Translations|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Best Practice Analyzer|✔️|✔️|✔️|✔️|✔️| +|Edit All TOM properties|✔️|✔️|✔️|✔️|✔️|✔️| +|Create Diagrams[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Preview Data[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Pivot Grids[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use DAX Queries[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use DAX Debugger[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Use Vertipac Analyzer[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Process Model and Tables[3](#TE3Prem)|✔️|✔️|✔️|✔️|✔️|✔️| +|Delete Objects|✔️|✔️|✔️|✔️| + +**Legend:** + +- ✔️: Supported +- ❌: Unsupported + +1 - The table partition must be an Entity Partition to work correctly and Direct Lake models can only have one partition. 2 - Calculated Tables and Columns cannot refer to Direct Lake on OneLake tables or columns. + +3 - Tabular Editor 3 features only. Operations performed through the XMLA endpoint requires a Business or Enterprise license. [More information](xref:editions). + +> [!NOTE] +> The June 2025 Release of Power BI Desktop all modeling limitations for third party tools where lifted. Prior to that various modeling operations where not supported. See [Power BI Desktop Limitations](xref:desktop-limitations) + +> [!TIP] +> For further details on restrictions on Direct Lake models refer to Microsoft's [Direct Lake documentation](https://learn.microsoft.com/en-us/fabric/fundamentals/direct-lake-overview) + +## Unsupported Semantic Model types + +The following semantic model types are unsupported, as they don't support XMLA write operations. + +- Reports based on a live connection to an Azure Analysis Services or SQL Server Analysis Services model. +- Reports based on a live connection to a Power BI dataset. +- Models with Push data. +- Models stored in Power BI My Workspace. +- Models stored in Power BI Pro Workspace. +- Direct Lake Default Semantic Models. (It is possible to connect to a default dataset, but it is not possible to change it through the XMLA endpoint) +- Excel workbook Semantic Models. \ No newline at end of file diff --git a/content/localization/zh/shortcuts_zh.md b/content/localization/zh/shortcuts_zh.md new file mode 100644 index 00000000..ab73de05 --- /dev/null +++ b/content/localization/zh/shortcuts_zh.md @@ -0,0 +1,158 @@ +--- +uid: shortcuts +title: Keyboard shortcuts +author: Daniel Otykier +updated: 2021-09-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Keyboard shortcuts + +## General + +| Command | Shortcut | +| -------------------------- | ------------ | +| New model | Ctrl+N | +| Open file | Ctrl+O | +| Load model from a database | Ctrl+Shift+O | +| Save current item | Ctrl+S | +| Save all | Ctrl+Shift+S | +| Exit | Alt+F4 | +| Deployment wizard | Ctrl+Shift+D | + +## Edit + +| Command | Shortcut | +| ---------- | -------- | +| Select All | Ctrl+A | +| Copy | Ctrl+C | +| Cut | Ctrl+X | +| Paste | Ctrl+V | +| Undo | Ctrl+Z | +| Redo | Ctrl+Y | +| Find | Ctrl+F | +| Replace | Ctrl+H | + +## Data modelling + +| Command | Shortcut | +| ------------------------------- | --------- | +| Properties | F4 | +| Edit object name / batch rename | F2 | +| Batch rename children | Shift+F2 | +| View dependencies | Shift+F12 | +| Make invisible | Ctrl+I | +| Make visible | Ctrl+U | +| Create measure | Alt+1 | +| Create calculated column | Alt+2 | +| Create hierarchy | Alt+3 | +| Create data column | Alt+4 | +| Create table | Alt+5 | +| Create calculated table | Alt+6 | +| Create calculation group | Alt+7 | +| Accept expression change | F5 | + +## TOM Explorer + +| Command | Shortcut | +| ----------------------------------------------- | ----------------------------- | +| Navigate up or down | Up / Down arrow | +| Expand / collapse current node | Right / Left arrow | +| Expand / collapse current node and all subnodes | Ctrl+Right / Left arrow | +| Expand / collapse entire tree | Ctrl+Shift+Right / Left arrow | +| Toggle measures | Ctrl+1 | +| Toggle columns | Ctrl+2 | +| Toggle hierarchies | Ctrl+3 | +| Toggle partitions | Ctrl+4 | +| Toggle display folders | Ctrl+5 | +| Toggle hidden objects | Ctrl+6 | +| Toggle info columns | Ctrl+7 | +| Navigate back | Alt+Left arrow | +| Navigate forward | Alt+Right arrow | + +## Text/code editing (general) + +| Command | Shortcut | +| --------------- | -------------- | +| Cut line | Ctrl+L | +| Delete line | Ctrl+Shift+L | +| Copy line | Ctrl+Shift+T | +| Transpose lines | Ctrl+T | +| Duplicate line | Ctrl+D | +| Lowercase line | Ctrl+U | +| Uppercase line | Ctrl+Shift+U | +| Move lines up | Alt+Up arrow | +| Move lines down | Alt+Down arrow | + +## DAX code + +| Command | Shortcut | +| ------------------------------------------- | -------------------------------------- | +| Go to definition | F12 | +| Peek definition | Alt+F12] | +| Refactor | Ctrl+R | +| Show auto-complete | Ctrl+Space | +| Show calltip | Ctrl+Shift+Space | +| Format DAX | F6 | +| Format DAX (Short lines) | Ctrl+F6 | +| Comment lines | Ctrl+K | +| Uncomment lines | Ctrl+U | +| Toggle comments | Ctrl+/ | +| Collapse all foldable regions | Ctrl+Alt+[ | +| Expand all foldable regions | Ctrl+Alt+] | +| Toggle all foldable regions state | Ctrl+Alt+; | +| Collapse foldable region | Ctrl+Shift+[ | +| Expand foldable region | Ctrl+Shift+] | +| Toggle foldable region state | Ctrl+Shift+; | +| Delete reference or words | Ctrl+Backspace or Ctrl+Delete | +| Expand Selection | Ctrl+Shift+E | + +## DAX Query + +| Command | Shortcut | +| ----------------- | -------- | +| Execute query | F5 | +| Execute selection | Shift+F5 | + +## DAX Script + +| Command | Shortcut | +| ------------------------------ | -------- | +| Apply script | F5 | +| Apply selection | F8 | +| Apply script and save model | Shift+F5 | +| Apply selection and save model | Shift+F8 | + +## DAX Debugger + +| Command | Shortcut | +| ------------------------------------------------------- | --------- | +| Step over | F10 | +| Step back | Shift+F10 | +| Step in | F11 | +| Step out | Shift+F11 | +| Next row (innermost row context) | F9 | +| Previous row (innermost row context) | Shift+F9 | + +## C# Script + +| Command | Shortcut | +| ---------- | -------- | +| Run script | F5 | + +# Customizing Shortcuts + +Tabular Editor 3 allows for the customization of shortcuts by rebinding existing or adding new shortcuts. + +Setting shortcuts can be done through **Tools -> Preferences -> Keyboard** and locating the command that should have a shortcut binding and setting the binding in the menu. +Shortcuts can be set for many different parts of Tabular Editor 3 including [Macros](xref:creating-macros) to have C# scripts available at the fingertips. + +![Dax Script](~/content/assets/images/SetShortcuts.png) + +1. Keyboard Menu in Preferences +2. Find command that should have a shortcut +3. Set shortcut by holding desired shortcuts key and use "Assign Shortcut" \ No newline at end of file diff --git a/content/localization/zh/supported-files_zh.md b/content/localization/zh/supported-files_zh.md new file mode 100644 index 00000000..6fbb4f93 --- /dev/null +++ b/content/localization/zh/supported-files_zh.md @@ -0,0 +1,233 @@ +--- +uid: supported-files +title: Supported file types +author: Morten Lønskov +updated: 2023-10-17 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Supported file types + +Tabular Editor 3 uses a number of different file formats and document types, some of which are not used by Analysis Services or Power BI. This article provides an overview and a description of each of these file types. + +![Supported File Types](~/content/assets/images/file-types/te3-supported-file-types.png) + +Example files are available for each several file type, based on the [learn.tabulareditor.com](https://tabulareditor.com/learn) course 2 Business Case. + +## Dataset file types + +Tabular Editor supports four file types for semantic models: .bim, Power BI files (.pbit and.pbip), .json and .tmdl. Each file type has different features and limitations, which are explained below. + +> [!NOTE] +> Since **Tabular Editor 3 Desktop Edition** is only intended to be used as an External Tool for Power BI Desktop, this edition does not allow loading and saving semantic model files. You may however still use Tabular Editor 2.x for this purpose. See to learn more about the difference between the Tabular Editor 3 editions. + +### [Tabular Model Files (.bim)](#tab/BIM) + +A .bim file is a single file consisting of nested JSON that is known as TMSL. + +It's the original format for a semantic model that Microsoft supports. + +However, it has a large drawback: as it's a single large file, it's difficult to track changes and use good team development practices such as git source control. + +#### .bim file in a folder + +![Supported File Types BIM](~/content/assets/images/file-types/te3-supported-file-bim.png) + +[Download example .bim file ](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/bim-file-example.bim) + +### [Power BI](#tab/PowerBI) + +Tabular Editor can handle two types of Power BI storage formats: + +- Power BI Template files (.pbit) +- Power BI Project folders (.pbip) + +#### Power BI Project folders (.pbip ) _(Preview)_ + +Power BI Project folders were introduced in June 2023 and is available in Power BI Desktop as a preview feature (also known as "Developer Mode"). The storage format is an alternative way to store the contents of a .pbix file, in a format that is more friendly to version control and 3rd party reading/editing of the content. + +> [!WARNING] +> Just like a .pbix file, a Power BI Project folder may contain model **data** in addition to **metadata**, so the folder should be treated as sensitive in the same way as a .pbix file should be. + +At the root of the Power BI Project folders sits a .pbip file. The file is essentially a pointer to a Power BI report definition file, which may then in turn point to a Power BI dataset, either locally in the same folder structure (stored as a model.bim file), or a dataset published to the Power BI service (in this case, the report is said to be in _Live connect_ mode). If a dataset (model.bim file) is present in the Power BI Project folder, Tabular Editor will be able to load this model metadata when opening the .pbip file. + +To learn more about Power BI Project folders, please read [this official blog post from Microsoft](https://powerbi.microsoft.com/en-us/blog/deep-dive-into-power-bi-desktop-developer-mode-preview/). + +> [!IMPORTANT] +> Power BI Project file is the recommended format when using Power BI with Tabular Editor, as it supports the [widest range of modeling operations](https://learn.microsoft.com/en-us/power-bi/developer/projects/projects-overview#model-authoring). Making other types of changes to the model metadata than those listed, may cause your model to become unloadable in Power BI Desktop, and in this case, Microsoft Support will not be able to help you. + +#### Power BI Template file (.pbit) + +Power BI Template files are similar to .pbix files, with the exception that they do not contain any model **data** - only model **metadata**. As such, this model metadata can be opened and edited in Tabular Editor. + +> [!WARNING] +> Even though it's technically possible to load and save model metadata to and from a .pbit file, this approach is unsupported by Power BI Desktop. Tabular Editor will show a warning and block changes by default. Use Power BI Project folders instead, if you intend to make changes to your Power BI model through Tabular Editor. + +### [Tabular Model Folder (.json)](#tab/JSON) + +Tabular Editor allows you to save your dataset objects as separate JSON files, which is a custom serialization format. + +This format preserves the structure and properties of your objects, such as tables, columns, measures, and relationships. + +This format has been supported in Tabular Editor from the early days and is a proven, though by Microsoft unsupported, method for storing your dataset objects as individual files. Thereby enabling developers to track changes in source control and collaborate on building semantic models. + +There is full compatibility between Tabular Editor 2 and 3 with regards to the the JSON file structure. + +In order to save a semantic model to JSON you must use the 'Save to Folder' option when saving the first time. Subsequent saves to a model loaded from a JSON structured model maintains the setting. it's always possible to convert a model that is in JSON to a .bim file using 'File > Save As' + +![Supported File Types JSON](~/content/assets/images/file-types/te3-supported-file-json.png) + +1. The overall model has a database json and each TOM headline has its own folder +2. In tables, each table exist in its own folder +3. An individual table as a TableName json file with folders for measures, columns and partitions +4. The measures on the table each have their own json file. + +The depth of which json objects that will be created are handled by the serialization settings. + +A single JSON file for a measure contains all the properties of that measure: + +![Supported File Types JSON File](~/content/assets/images/file-types/te3-supported-file-json-measure.png) + +For more information on Save to Folder and serialization settings please refer to: [Save to Folder](xref:save-to-folder) + +[Download example JSON Folder Structure](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/json-model-example.zip) + +### [TMDL](#tab/TMDL) + +TMDL stands for Tabular Model Definition Language and it's a new format for defining and managing datasets in a human readable format using YAML like syntax. + +Microsoft introduced TMDL as a preview feature in April 2023, aiming to provide a unified and consistent way of working with datasets across different platforms and tools. + +TMDL is designed to support dataset source control, enabling users to track changes, collaborate, and automate workflows with semantic models. + +> [!Note] +> TMDL is in preview, which means that it's not fully stable and may have some limitations or issues. + +![Supported File Types TMDL](~/content/assets/images/file-types/te3-supported-file-tmdl.png) + +1. The overall serialization is on the top object level from the TOM +2. Each table is a single file +3. The TMDL file consist of a YAML like indentation with each column and measure inside the file. + +For further reading please see: [TMDL](xref:tmdl) + +[Download example TMDL Folder Structure](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/tmdl-model-example.zip) + +*** + +## Tabular Editor Supporting files + +Supporting files are files which are not used by Analysis Services or Power BI. Instead, these files all support different kinds of development workflow in Tabular Editor 3 and other tools. + +All supporting files can be saved individually using either Ctrl+S or 'File > Save' while having the corresponding document or window open and focused. + +### Diagram file (.te3diag) + +A .te3diag file is a file format that stores the diagram of a model created with TE3. + +These file can be useful for documenting the model structure and logic for other developers who work on the same project. A .te3diag file can be saved in the same folder as the model file for easy access and reference. + +Diagram files are actually JSON that is stored in a Tabular Editor 3 extension. + +[Download example Diagram File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/te3-diagram.te3diag) + +### DAX query files (.dax or .msdax) + +DAX queries are expressions that can be used to manipulate and analyze data in semantic models. A DAX file is a text file that contains one or more DAX queries. + +You can save a DAX file in Tabular Editor 3 and use it later to run the queries again. You can also open a DAX file in other tools that support DAX, such as [DAX Studio](https://daxstudio.org). + +[Download example DAX File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/dax-query-example.dax) + +These files can only be opened while Tabular Editor 3 is connected to an instance of Analysis Services or the Power BI / Fabric XMLA endpoint. + +### Pivot Grid layouts (.te3pivot) + +These files contain the layout of a Pivot Grid in Tabular Editor 3. They are simple JSON files specifying which fields (measures, columns, hierarchies) are displayed in the Pivot Grid, and how they are arranged. + +These files can only be opened while Tabular Editor 3 is connected to an instance of Analysis Services or the Power BI / Fabric XMLA endpoint. + +### DAX Scripts (.te3daxs) + +These files are saved DAX scripts (not queries) which are used in Tabular Editor to manipulate many DAX objects at once. For example, modifying multiple measures in a semantic model. + +### C# Scripts (.csx) + +Creating and editing C# Scripts is one of Tabular Editor's biggest productivity features. + +These scripts can be saved as files with the .csc extension and loaded into Tabular Editor as well as saved as Macros. A [MacroActions.json local setting file](xref:supported-files#macroactionsjson) is maintained by Tabular Editor. + +This way, scripts can be reused without having to write them from scratch every time. The [script library](xref:csharp-script-library) is a good place investigate and reuse various examples of scripts as they demonstrate different features and functionalities of C#. + +[Download example C# Script File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/create-sum-measures-csharp.csx) + +### Vertipaq Analyzer Files (.vpax) + +With Tabular Editor, you can export and import .vpax files using the Vertipaq Analyzer feature. A .vpax file is a compressed file that contains information about the size and structure of your semantic model, but not the actual data. + +You can use this file to analyze and optimize your model performance, without exposing sensitive data. For example, you can use the [DAX optimizer](https://www.daxoptimizer.com/) tool to get suggestions on how to improve your DAX formulas based on the .vpax file. + +[Download example DAX Script File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/dax-script-example.te3daxs) + +Unlike other supporting file types creating a .vpax file is done within the Vertipaq Analyzer window using the 'Import' and 'Export' buttons. + +![VPAX](~/content/assets/images/file-types/te3-supported-file-vpax.png) + +[Download example VPAX file](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/vpaq-example.vpax) + +> [!WARNING] +> If your model metadata is confidential, a .vpax file should also be considered confidential and only shared with that in mind. If you are concerned about protecting IP, Tabular Editor 3 has an option to obfuscate VPAX files. + +#### Obfuscation + +If you need to hand off the VPAX file to a 3rd party, such as a consultant or a tool vendor, you can obfuscate the file to hide the model metadata. This is done by selecting the 'Obfuscated Export...' option under the drop-down button next to the 'Export' button in the Vertipaq Analyzer window. + +An obfuscated VPAX file uses the .ovpax file extension. + +![Export obfuscated VPAX](~/content/assets/images/obfuscated-vpax.png) + +For more documentation on Vertipaq Analyzer please see: [sqlbi Vertipaq Analyzer](https://www.sqlbi.com/tools/vertipaq-analyzer) and [sqlbi Docs: Vertipaq Analyzer](https://docs.sqlbi.com/vertipaq-analyzer/) + +For more information about obfuscation of VPAX files, please see: [VPAX Obfuscator](https://www.sqlbi.com/blog/marco/2024/03/15/vpax-obfuscator-a-library-to-obfuscate-vpax-files/) + +## Local Setting Files + +Tabular Editor maintains several local files in the "%localappdata%\TabularEditor3" folder. These files are functionally relevant for Tabular Editor 3 and are useful to know. + +It can be helpful to share these files across a team so that all developers have the same Macros and BPA rules. + +> [!TIP] +> A windows native way of syncing a version controlled file into the "%localappdata%\TabularEditor3" folder is to use [SymLink](https://www.howtogeek.com/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/). +> +> Store the required files in Git or OneDrive and create a Symlink to the "%localappdata%\TabularEditor3" folder, but be aware that this could end up with synchronization issues, if multiple users update the same file version. +> However, this is not supported by Tabular Editor directly, so implement it at your own discretion. + +### MacroActions.json + +This file stores all the macros that you have created or imported. It can be useful to share this file with your colleagues or backup it in a version control system and can also be configured to sync with a remote repository that contains macros (See tip above). + +This file contains the index of each macro that is used in the software. If you need to change the order or the name of any macro, you can edit this file manually with a text editor. However, be careful not to introduce any errors or inconsistencies in the file thereby corrupting so make sure to create a backup. + +[Download example MacroActions File](https://raw.githubusercontent.com/TabularEditor/TabularEditorDocs/main/content/assets/file-types/MacroActions.json) + +### BPARules.json + +The file contains the [Best Practice Analyzer rules](xref:using-bpa) and fix expressions. The only place to add and edit fix expressions is inside this JSON file. +It is recommended to store the PBA rule file in version control, which also enables the possibility of running the BPA rules against the semantic model before deployment. + +You can download the official Microsoft BPA rules here: [PBA Rules](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json) + +### RecentServers.json + +Contains all the servers a user has been connected to. It can be advisable to edit it manually to 'forget' past servers no longer relevant. + +### Layouts.json + +The Layouts file is automatically generated by Tabular Editor when starting the application. It contains all information to how Tabular Editor 3's UI layout is configured. + +> [!TIP] +> Deleting this file will reset Tabular Editor's layout. If the Tabular Editor layout does not behave as expected a good first step is to backup this file somewhere else, delete the original and restart Tabular Editor 3. diff --git a/content/localization/zh/table-groups_zh.md b/content/localization/zh/table-groups_zh.md new file mode 100644 index 00000000..5e2814e7 --- /dev/null +++ b/content/localization/zh/table-groups_zh.md @@ -0,0 +1,81 @@ +--- +uid: table-groups +title: Table Groups +author: Daniel Otykier +updated: 2023-03-08 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Table Groups + +Table Groups is a new feature, available in Tabular Editor 3 starting from [version 3.5.0](xref:release-3-5-0). The feature lets you quickly organise tables into folders, making it easier than ever to manage and navigate large, complex models, in Tabular Editor 3's [TOM Explorer](xref:tom-explorer-view). + +![Table groups](~/content/assets/images/user-interface/table-groups.png) + +You can set up Table Groups either by right-clicking on a table and choosing the **Create > Table group** menu option, or by specifying a name for the Table Group in the **Properties View**, while selecting one or more tables. + +Tables can be moved around between Table Groups by dragging and dropping in the TOM Explorer. Note that, unlike Display Folders for measures, columns and hierarchies, Table Groups cannot be nested. + +Right-clicking on a Table Group in the TOM Explorer, gives you the same context menu options, as if you had selected the table(s) within that Table Group. + +> [!NOTE] +> Table Groups is a Tabular Editor-exclusive feature. Client tools (such as Excel, Power BI Desktop, etc.) will not observe Table Groups, as the [CSDL format](https://learn.microsoft.com/en-us/ef/ef6/modeling/designer/advanced/edmx/csdl-spec), which specifies the conceptual schema of the data model, does not support Table Groups. + +## Metadata and scripting + +Tabular Editor uses an annotation on each table, to specify which Table Group that table belongs to. The name of the annotation is `TabularEditor_TableGroup`. However, when scripting changes to the model using C# scripts, you can modify the Table Group directly through the new `Table.TableGroup` (string) property. + +Below is an example of a C# script, that loops through all tables of a model, organizing them into Table Groups based on their type and usage: + +```csharp +// Loop through all tables: +foreach(var table in Model.Tables) +{ + if (table is CalculationGroupTable) + { + table.TableGroup = "Calculation Groups"; + } + else if (!table.UsedInRelationships.Any() && table.Measures.Any(m => m.IsVisible)) + { + // Tables containing visible measures, but no relationships to other tables + table.TableGroup = "Measure Groups"; + } + else if (table.UsedInRelationships.All(r => r.FromTable == table) && table.UsedInRelationships.Any()) + { + // Tables exclusively on the "many" side of relationships: + table.TableGroup = "Facts"; + } + else if (!table.UsedInRelationships.Any() && table is CalculatedTable && !table.Measures.Any()) + { + // Tables without any relationships, that are Calculated Tables and do not have measures: + table.TableGroup = "Parameter Tables"; + } + else if (table.UsedInRelationships.Any(r => r.ToTable == table)) + { + // Tables on the "one" side of relationships: + table.TableGroup = "Dimensions"; + } + else + { + // All other tables: + table.TableGroup = "Misc"; + } +} +``` + +## Hiding Table Groups + +If you prefer to always see the full, ungrouped list of tables in the TOM Explorer, but you're collaborating with others on a model containing table group annotations, you can still disable table groups altogether, for your Tabular Editor 3 installation. This is done through the **Tools > Preferences** dialog. Navigate to the **TOM Explorer** page, then uncheck **Use table groups** under **Display and filtering**: + +![Table Groups Disable](~/content/assets/images/table-groups-disable.png) + +> [!NOTE] +> Even though you have disabled table groups as described above, tables in your model may still have the `TabularEditor_TableGroup` annotation assigned. If you wish to clear all such annotations from the model, you can use the following C# script: +> +> ```csharp +> foreach(var table in Model.Tables) table.TableGroup = null; +> ``` \ No newline at end of file diff --git a/content/localization/zh/te3-eula_zh.md b/content/localization/zh/te3-eula_zh.md new file mode 100644 index 00000000..e24eb96e --- /dev/null +++ b/content/localization/zh/te3-eula_zh.md @@ -0,0 +1,10 @@ +--- +uid: te3-eula +title: Standard License Terms +author: Søren Toft Joensen +updated: 2021-07-10 +--- + +# Tabular Editor 3 Standard License Terms + +The latest version of our license terms is always available on https://tabulareditor.com/license-terms diff --git a/content/localization/zh/third-party-notices_zh.md b/content/localization/zh/third-party-notices_zh.md new file mode 100644 index 00000000..db486bd1 --- /dev/null +++ b/content/localization/zh/third-party-notices_zh.md @@ -0,0 +1,902 @@ +--- +uid: third-party-notices +title: Third Party Notices +author: Daniel Otykier +updated: 2021-06-01 +--- + +# Tabular Editor 3 Third Party Notices + +This product incorporates third party components from the projects +listed below. The original copyright notices and the licenses under +which Tabular Editor ApS received such third party components are set +forth below for informational purposes. Tabular Editor ApS licenses +these third party components to you under the Tabular Editor 3 software +licensing terms; however, any third party components received under +open source licenses that require such components to remain under their +original license are provided to you by Tabular Editor ApS under their +original license. Tabular Editor ApS reserves all other rights not +expressly granted herein, whether by implication, estoppel or +otherwise. + +For third party components licensed under open source licenses with +source code availability obligations, you may obtain the source code +from us, if and as required under the relevant open source licenses, +by sending an e-mail to licensing@tabulareditor.com. Please write +"Third party open source code" in the subject line. We may also make +a copy of the source code available at: + +https://github.com/TabularEditor/TabularEditor3. + +----------------------------------------------------------------- + +## License for Lexilla, Scintilla, and SciTE + +Copyright 1998-2021 by Neil Hodgson neilh@scintilla.org + +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. + +NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. + +----------------------------------------------------------------- + +## License for Scintilla.NET + +The MIT License (MIT) + +Copyright (c) 2017, Jacob Slusser, https://github.com/jacobslusser + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for ANTLR + +The "BSD 3-clause license" +Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +\===== + +MIT License for codepointat.js from https://git.io/codepointat +MIT License for fromcodepoint.js from https://git.io/vDW1m + +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------------------------------------------------------------- + +## License for Newtonsoft.Json + +The MIT License (MIT) + +Copyright (c) 2007 James Newton-King + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +----------------------------------------------------------------- + +## License for Dax.Formatter + +MIT License + +Copyright (c) SQLBI Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Roslyn + +https://github.com/dotnet/roslyn/blob/main/License.txt + +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Windows-API-CodePack-NET + +https://github.com/Wagnerp/Windows-API-CodePack-NET/blob/main/LICENSE + +MIT License + +Copyright (c) 2009 - 2010 Microsoft Corporation, then modifications by Jacob Slusser 2014, Peter William Wagner 2017 - 2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Tulpep.ActiveDirectoryObjectPicker + +https://github.com/Tulpep/Active-Directory-Object-Picker/blob/master/LICENSE + +Microsoft Public License (MS-PL) + +The initial project was originally created by Armand du Plessis +in 2004 and now is extended and maintained by Tulpep. + +This license governs use of the accompanying software. If you use the software, you +accept this license. If you do not accept the license, do not use the software. + +1. Definitions + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the + same meaning here as under U.S. copyright law. + A "contribution" is the original software, or any additions or changes to the software. + A "contributor" is any person that distributes its contribution under this license. + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions + and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free + copyright license to reproduce its contribution, prepare derivative works of its contribution, and + distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and + limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free + license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or + otherwise dispose of its contribution in the software or derivative works of the contribution + in the software. + +3. Conditions and Limitations + (A) No Trademark License- This license does not grant you rights to use any contributors' name, + logo, or trademarks. + (B) If you bring a patent claim against any contributor over patents that you claim are infringed + by the software, your patent license from such contributor to the software ends automatically. + (C) If you distribute any portion of the software, you must retain all copyright, patent, + trademark, and attribution notices that are present in the software. + (D) If you distribute any portion of the software in source code form, you may do so only + under this license by including a complete copy of this license with your distribution. If + you distribute any portion of the software in compiled or object code form, you may only do + so under a license that complies with this license. + (E) The software is licensed "as-is." You bear the risk of using it. The contributors give + no express warranties, guarantees or conditions. You may have additional consumer rights + under your local laws which this license cannot change. To the extent permitted under your + local laws, the contributors exclude the implied warranties of merchantability, fitness for + a particular purpose and non-infringement. + +----------------------------------------------------------------- + +## License for dotNetCore.Data.OracleClient + +https://github.com/ericmend/oracleClientCore-2.0/blob/master/LICENSE + +MIT License + +Copyright (c) 2018 Eric Azevedo Mendonça + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Ninject + +https://github.com/ninject/Ninject?tab=License-1-ov-file#readme + +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you +accept this license. If you do not accept the license, do not use the software. + +1. Definitions + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the + same meaning here as under U.S. copyright law. + A "contribution" is the original software, or any additions or changes to the software. + A "contributor" is any person that distributes its contribution under this license. + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and + limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free + copyright license to reproduce its contribution, prepare derivative works of its contribution, + and distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations + in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under + its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose + of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, + or trademarks. + (B) If you bring a patent claim against any contributor over patents that you claim are infringed by + the software, your patent license from such contributor to the software ends automatically. + (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, + and attribution notices that are present in the software. + (D) If you distribute any portion of the software in source code form, you may do so only under this + license by including a complete copy of this license with your distribution. If you distribute + any portion of the software in compiled or object code form, you may only do so under a license + that complies with this license. + (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express + warranties, guarantees or conditions. You may have additional consumer rights under your local laws + which this license cannot change. To the extent permitted under your local laws, the contributors + exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + +----------------------------------------------------------------- + +## License for Snowflake.Data + + ``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + ``` + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2017 Snowflake Computing Inc. All right reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + ``` + http://www.apache.org/licenses/LICENSE-2.0 + ``` + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------- + +## License for Dynamic-LINQ.net + + ``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + ``` + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [2016] [Stef Heyenrath] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + ``` + http://www.apache.org/licenses/LICENSE-2.0 + ``` + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------- + +## License for VertiPaq-Analyzer + +MIT License + +Copyright (c) 2019 SQLBI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for CliWrap + +MIT License + +Copyright (c) 2017-2024 Oleksii Holub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for TOMWrapper (Tabular Editor Open Source version) + +MIT License + +Copyright (c) 2016 otykier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------------------------------------------------------------- + +## License for Microsoft.ApplicationInsights client libraries + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of Microsoft.ApplicationInsights (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +MICROSOFT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------------------------------------------------------------- + +## License for MICROSOFT ANALYSIS MANAGEMENT OBJECTS (AMO) + +Please view the updated EULA at: https://go.microsoft.com/fwlink/?linkid=852989 + +----------------------------------------------------------------- + +## License for DevExpress WinForms Controls + +End-User License Agreement + +Please view the updated EULA at: https://www.devexpress.com/Support/EULAs/winforms-controls.xml \ No newline at end of file diff --git a/content/localization/zh/tmdl-common_zh.md b/content/localization/zh/tmdl-common_zh.md new file mode 100644 index 00000000..2848a76a --- /dev/null +++ b/content/localization/zh/tmdl-common_zh.md @@ -0,0 +1,12 @@ +--- +uid: tmdl-common +title: Tabular Model Definition Language (TMDL) +author: Daniel Otykier +updated: 2023-05-22 +applies_to: + versions: + - version: 2.x + - version: 3.x +--- + +[!include[tmdl](~/content/te3/features/tmdl.md)] \ No newline at end of file diff --git a/content/localization/zh/tmdl_zh.md b/content/localization/zh/tmdl_zh.md new file mode 100644 index 00000000..3c889417 --- /dev/null +++ b/content/localization/zh/tmdl_zh.md @@ -0,0 +1,36 @@ +--- +uid: tmdl +title: Tabular Model Definition Language (TMDL) +author: Daniel Otykier +updated: 2023-05-22 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# Tabular Model Definition Language (TMDL) + +**TMDL** is a model metadata file format [announced by Microsoft in April 2023](https://powerbi.microsoft.com/en-ie/blog/announcing-public-preview-of-the-tabular-model-definition-language-tmdl/). It aims to provide a human-readable, text-based alternative to the JSON-based model.bim file format. TMDL is inspired by YAML, and as such, is easy to read and write, with minimal use of string quotes and escape characters. It also serializes a model as several smaller files in a folder structure, and is therefore also better suited for version control integration. + +## Enabling TMDL in Tabular Editor 3 + +To enable TMDL in Tabular Editor 3, go to **Tools > Preferences > File Formats > Save-to-folder**, and select "TMDL" in the **Serialization mode** dropdown. The legacy "save-to-folder" functionality will continue to exist side by side with TMDL, but is not a Microsoft supported format. + +After doing so, Tabular Editor 3 will use the TMDL format when saving a model as a folder (**File > Save to folder...**). + +> [!NOTE] +> When you load a model from a legacy Tabular Editor folder structure, it will still get saved into that same format when using **File > Save** (Ctrl+S). Only when you explicitly use the **File > Save to folder...** command, will the model be saved in the new TMDL format. + +## New models + +When saving a new model for the first time, Tabular Editor (since v. 3.7.0), will now provide an option for saving the model as TMDL, even when the default serialization mode is not set to TMDL, as described in the previous section. + +![New Model Tmdl](~/content/assets/images/new-model-tmdl.png) + +# Next steps + +- [TMDL overview (Microsoft Learn)](https://learn.microsoft.com/en-us/analysis-services/tmdl/tmdl-overview). +- [Get started with TMDL (Microsoft Learn)](https://learn.microsoft.com/en-us/analysis-services/tmdl/tmdl-how-to) diff --git a/content/localization/zh/toc_zh.md b/content/localization/zh/toc_zh.md new file mode 100644 index 00000000..8a871b16 --- /dev/null +++ b/content/localization/zh/toc_zh.md @@ -0,0 +1,147 @@ +# Introduction + +## @getting-started + +## @whats-new + +## @editions + +## @desktop-limitations-te3 + +## Power BI XMLA Endpoint + +### @powerbi-xmla + +### @powerbi-xmla-pbix-workaround + +## @proxy-settings + +# Documentation + +## User interface + +### @user-interface + +### @tom-explorer-view + +### @bpa-view + +### @messages-view + +### @data-refresh-view + +### @macros-view + +### @find-replace + +## Features + +### @csharp-scripts + +### @dax-debugger + +### @dax-editor + +### @dax-optimizer-integration + +### @dax-scripts + +### @dax-query + +### @diagram-view + +### @metadata-translation-editor + +### @perspective-editor + +### @pivot-grid + +### @table-groups + +### @code-actions + +## Files formats + +### @supported-files + +### @tmdl + +## @preferences + +## @shortcuts + +## @user-options + +## @security-privacy + +# Tutorials and walkthroughs + +## Connect to a Model + +### @workspace-mode + +## Create a New Model + +### @new-as-model + +### @new-pbi-model + +### @direct-lake-guidance + +## Adding Tables & Data Sources + +### @importing-tables + +### @connecting-to-azure-databricks + +## Configuring Data Security + +### @data-security-about + +### @data-security-setup-rls + +### @data-security-setup-ols + +### @data-security-testing + +## Incremental Refresh + +### @incremental-refresh-about + +### @incremental-refresh-modify + +### @incremental-refresh-setup + +### @incremental-refresh-schema + +### @incremental-refresh-workspace-mode + +## Advanced Modelling + +### @udfs + +### @calendars + +## Automation with C# Scripting + +### @creating-macros + +### @csharp-script-library + +# Troubleshooting + +## @locale-not-supported + +# Other resources + +## @downloads + +## @roadmap + +# Legal + +## @te3-eula + +## @third-party-notices + +## @privacy-policy diff --git a/content/localization/zh/tom-explorer-view_zh.md b/content/localization/zh/tom-explorer-view_zh.md new file mode 100644 index 00000000..a3741022 --- /dev/null +++ b/content/localization/zh/tom-explorer-view_zh.md @@ -0,0 +1,132 @@ +--- +uid: tom-explorer-view +title: TOM Explorer view +author: Morten Lønskov +updated: 2023-02-21 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# Using the TOM Explorer in Tabular Editor 3 + +The TOM Explorer is your main window for interacting with the objects of your data mode. Objects such has tables, columns, measures, security groups etc. are all displayed in a hierarchical structure. A Tabular data model is represented by the so called [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) and it is the metadata of your TOM that is displayed in the TOM Explorer. + +The TOM Explorer consists of two main areas, firstly the data model objects and secondly the menu bar that allows for filtering and changing what is presented in the main window. + +![Tom Explorer](~/content/assets/images/user-interface/TOMExplorer.png) + +

    + +## Data Model Objects + +You can fold out objects in the TOM Explorer to see their children and follow the hierarchy of objects downwards. And if you right click on any object you will be given a list of options to interact with that specific object. As you can see below there are several options that you can use with a table. It is with this menu that you for example can easily refresh your tables and see the status of that refresh in the @data-refresh-view + +![Tom Explorer Interaction](~/content/assets/images/user-interface/TomExplorerRightClick.png) + +The right click menu has the following items some of which can be expanded for more actions. The menu depends on the object type chosen (Table, partition, measure, column etc.) and the list below is not exhaustive for all types of objects but contains those most used. + +### Options in Right-click menu + +- **Update table schema...**: + Checks for structural changes in the external data source and updates the table’s schema accordingly. This is useful when columns have been added, renamed, or removed in the source. + +- **Script DAX**: + Generates a DAX script for the selected table and its objects. Opens a new script editor window where you can review or edit DAX definitions collectively. + +- **Preview data**: + Opens the data preview pane displaying a sample of the data loaded into the selected table. Useful for validation or debugging. Only exists when right clicking tables. + +- **Refresh**: + Expands to a selection of possible refresh operation for the selected table. This is available only if the model is connected to live model either stand alone or in workspace mode. This option is only available on tables and partitions. + +- **Create**: + Expands to a submenu allowing the creation of new measures, columns, hierarchies, display folders or calculation items under the selected object. The available options depends on the object type selected. + +- **Move to group**: + Allows you to organize the table into a Table group within the TOM Explorer for easier model navigation. This option is only available for tables. + +- **Make invisible**: + Marks the object as not visible in client tools. The table remains part of the model but is hidden from report authors. Alternative use the shortcut `Ctrl+I` to hide the object. + +- **Shown in perspectives**: + Enables or disables the table’s inclusion in one or more perspectives. Perspectives limit what end-users can see in tools like Power BI. + +- **Batch rename**: When selecting more than one object you can batch rename those objects using string replacement or regex. The shortcut for batch rename is `F2`. + +- **Batch rename children...**: + Enables bulk renaming of all child objects under the table or display folder using regex or string replacement rules. Can also be accessed with the shortcut `Shift+F2`. + +- **Duplicate**: + Creates a copy of the selected table, including all its columns, measures, and partitions. Also exists for all other objects in the TOM Explorer. + +- **Mark as date table...**: + Marks the table as a date table, enabling time intelligence features. Requires that the table contains a valid date column. + +- **Show dependencies**: + Visualizes dependencies between the selected table and other model objects. Can also be accessed via shortcut `Shift+F12`. + +- **Export script**: + Exports the selected object as a TMSL or TMDL script for use in deployment or source control. + +- **Macro Menus**: + Macros can be placed into folders and run against the selected object. In the example above the user has a Modelling and Analysis folder for Macro scripts on table objects. + +- **Cut / Copy / Paste / Delete**: + Standard clipboard operations. Use these to move, duplicate, or remove model objects. + +- **Properties**: + Opens the Properties pane for the selected object. Shortcut: `Alt+Enter`. Used to inspect and edit metadata, expressions, formatting, and visibility settings. + +> [!IMPORTANT] +> In Tabular Editor 3 Desktop Edition some options are disabled and greyed-out. This is due to the limitations of using Tabular Editor has an external tool. For more information see @desktop-limitations + +### Show Info Columns + +The TOM Explorer allows for toggling on additional info columns about the data model objects. This can be done with the short cut `CTRL+7` +These extra info also exists in the property window, but allow for a quick view of the Object Type, Format String, Data Type, Expression and Description. +![Tom Explorer Show Hide Coloumns](~/content/assets/images/user-interface/TOMExplorerInfoColumns.png) + +## TOM Explorer Toolbar + +The toolbar allow you to show and hide different types of objects, toggling perspectives and languages ans well as searching for specific objects in the data model. +![Tom Explorer Toolbar](~/content/assets/images/user-interface/TOMExplorerToolbar.png) + +1. **Show/Hide Measures** + Toggle the visibility of measures within tables. + **Shortcut:** `Ctrl+1` + +2. **Show/Hide Columns** + Toggle the visibility of columns within tables. + **Shortcut:** `Ctrl+2` + +3. **Show/Hide Hierarchies** + Toggle whether hierarchies are shown in the TOM Explorer. + **Shortcut:** `Ctrl+3` + +4. **Show/Hide Partitions** + Controls whether partitions are visible for tables. + **Shortcut:** `Ctrl+4` + +5. **Show/Hide Display Folders** + Enables or disables the display of folder organization within tables. + **Shortcut:** `Ctrl+5` + +6. **Show/Hide Hidden Objects** + Toggles whether hidden objects are shown. + **Shortcut:** `Ctrl+6` + +7. **Show/Hide Info Columns** + Shows or hides metadata columns, such as data types or object status. + **Shortcut:** `Ctrl+7` + +8. **Perspective Selector** + Drop-down to choose a specific perspective. Only objects in the selected perspective will be shown in the TOM Explorer. + +9. **Language Selector** + Allows switching between different languages for model metadata localization. + +10. **Search Bar** + Provides real-time filtering and navigation within the TOM Explorer. Type to search across all visible model objects. diff --git a/content/localization/zh/udfs_zh.md b/content/localization/zh/udfs_zh.md new file mode 100644 index 00000000..c8bfebb5 --- /dev/null +++ b/content/localization/zh/udfs_zh.md @@ -0,0 +1,296 @@ +--- +uid: udfs +title: DAX User-Defined Functions +author: Daniel Otykier +updated: 2025-09-15 +applies_to: + editions: + - edition: Desktop + - edition: Business + - edition: Enterprise +--- + +# DAX User-Defined Functions + +DAX User-Defined Functions (UDFs) is a new capability of semantic models introduced in Power BI Desktop with the September 2025 update. + +The feature lets you create reusable DAX functions that you can invoke from within any DAX expression of your model, even other functions. This powerful feature helps you maintain consistency, reduce code duplication, and create more maintainable DAX expressions. + +Tabular Editor 3 supports UDFs starting from version 3.23.0, although we recommend using [3.23.1](xref:release-3-23-1) (or newer) to benefit from various bug fixes and improvements. + +For a more detailed introduction to UDFs in Tabular Editor 3, check out [this blog post](https://tabulareditor.com/blog/how-to-get-started-using-udfs-in-tabular-editor-3). + +## Understanding UDFs + +UDFs can be thought of as custom DAX functions that you define once and can use throughout your model. You define which parameters the function accepts, which can be both scalar- or table-valued, or even references to objects, and then you provide the DAX expression that uses those parameters to compute a result, which can also be scalar- or table-valued. + +To learn more about how DAX UDFs work, we recommend [this article by SQLBI](https://www.sqlbi.com/articles/introducing-user-defined-functions-in-dax/). + +## Prerequisites + +Before you can create and use UDFs in Tabular Editor 3, ensure that: + +- Your model compatibility level is **1702 or higher** + +## Creating Your First UDF + +### Step 1: Set Up the Model + +First, verify your model's compatibility level is appropriate for UDFs: + +1. Open your model in Tabular Editor 3 +2. Select the root node ("Model") in the **TOM Explorer** +3. In the **Properties** panel, expand the **Database** property, then check that the **Compatibility Level** is set to **1702** or higher +4. If needed, update the compatibility level and save your model + +![Setting Compatibility Level](~/content/assets/images/udfs-cl1702.png) + +### Step 2: Add a New Function + +1. In the **TOM Explorer**, locate the **Functions** folder under your model +2. Right-click on the **Functions** folder +3. Select **Create > User-Defined Function** +4. Give your function a descriptive name (spaces and special characters are not allowed; underscores and periods are permitted) + +![Creating a UDF](~/content/assets/images/new-udf.png) + +You can also add a UDFs through the **Model > Add User-Defined Function** menu option. + +Alternatively, you can create UDFs directly from the **DEFINE** section of a DAX query, by hitting F7 (Apply) or using the **Query > Apply** menu option. If your query contains multiple query-scoped definitions, you can also select just a subset of them and hit F8 (Apply Selection). + +![Creating a UDF from DAX Query](~/content/assets/images/udf-from-query.png) + +### Step 3: Define Your Function + +In the **Expression Editor**, define your function using proper UDF syntax. + +Here's a basic example that adds two numbers together: + +```dax +// Adds two numbers together +( + x, // The first number + y // The second number +) +=> x + y +``` + +> [!TIP] +> Use the **"Use correct UDF syntax"** code action in the Expression Editor if you need help with the proper syntax structure. + +## UDF Syntax and Structure + +### Basic Syntax + +UDFs follow this general structure: + +```dax +FUNCTION FunctionName = + // Optional comment describing the function + ( + parameter1, // Parameter description + parameter2, // Parameter description + // ... more parameters + ) + => expression_using_parameters +``` + +### Parameter Evaluation Mode + +A key aspect of UDFs is that parameters can be defined in one of two modes, **pass-by-value** and **pass-by-reference**. By default, and unless you specify otherwise, a parameter will by **pass-by-value**. This essentially means that the parameter behaves just like a DAX variable (i.e. one that is defined using the `VAR` keyword) inside the UDF expression. In other words, when the UDF is called, the parameter values are "copied" into the function and any reference to that parameter inside the function will always return the same value. + +In contrast, **pass-by-reference** parameters behave more like measures. That is, the result of evaluating the parameter _inside the function_ may differ depending on the evaluation context. + +To specify the evaluation mode, include a parameter specification after the parameter name, separated by a colon (`:`). The specification can be either `VAL` or `EXPR` for "pass-by-value" and "pass-by-reference", respectively. As mentioned above, "pass-by-value" is the default, so `VAL` is implicit if not specified. For example: + +```dax +( + x: VAL, // Pass-by-value parameter - the DAX expression is evaluated once when the function is called, and the result is "copied" into the function + y: EXPR // Pass-by-reference parameter - can be any DAX expression which will observe whatever context the parameter is later referenced under +) +=> +ROW( + "x", x, + "x modified", CALCULATE(x, Product[Color] = "Red"), + "y", y, + "y modified", CALCULATE(y, Product[Color] = "Red") +) +``` + +Calling the above function with a measure reference for each parameter, e.g. `MyFunction([Some Measure], [Some Measure])`, will yield different results for the `y` parameter depending on the current filter context, as shown in the screenshot below: + +![Pass-by-value vs Pass-by-reference](~/content/assets/images/udf-pass-by-ref.png) + +In addition to specifying the evaluation mode, you can also constrain the parameter type by specifying a data type before the evaluation mode, e.g. `x: INT64 VAL` or `y: TABLE EXPR`. + +These type specifications are optional, but if specified they will perform an implicit type conversion on arguments passed to the function, and will also affect the autocomplete suggestions in Tabular Editor 3 when writing DAX code that calls the function. + +Check the [Microsoft specification for UDFs](https://learn.microsoft.com/en-us/dax/best-practices/dax-user-defined-functions) for the complete list of available constraints. + +## Using UDFs in Your Model + +### In Object Expressions + +Once you've created a UDF, you can use it in any DAX expression throughout your model. Tabular Editor 3's autocomplete will suggest your UDFs as you type. + +### In DAX Scripts + +UDFs are also available when working with DAX Scripts: + +```dax +-- Function: MyFuncRenamed +FUNCTION MyFuncRenamed = + // Adds two numbers together + ( + x: INT64, // The first number + y: INT64 // The second number + ) + => x + y + +-- Measure: [New Measure] +MEASURE 'Date'[New Measure] = MyFuncRenamed(1,2) +``` + +### In DAX Queries + +Tabular Editor 3 adds powerful new features for working with UDFs in DAX queries. We already mentioned above how you can "apply" a UDF from the **DEFINE** section of a DAX query, to have it become a permanent part of your model. In addition, if using a UDF inside a DAX query, you can right-click on the function invocation and choose **Define Function** to automatically generate the function definition in the **DEFINE** section of your query: + +![Define Function from Query](~/content/assets/images/udf-define.png) + +As can be seen from the screen above, the following options are available when right-clicking on a UDF invocation: + +- **Peek Definition** (Alt+F12): Opens a nested, read-only editor below the current cursor position, showing you the function definition +- **Go To Definition** (F12): Navigates to the function definition in the **Functions** folder of your model, or, if the function is defined in the current query or script, to the function definition inside the editor +- **Inline Function**: Replaces the function invocation with the actual function definition, substituting parameters with the actual arguments passed to the function +- **Define Function** (DAX scripts or DAX queries only): Generates the function definition in the **DEFINE** section of your query, if it doesn't already exist there +- **Define Function with dependencies** (DAX scripts or DAX queries only): Similar to the above, but also generates definitions for any other UDFs that the function depends on + +## Advanced Features + +### Formula Fixup + +When you rename a UDF, Tabular Editor 3 automatically updates all references throughout your model, just like with measures and other objects. + +### Peek Definition + +The **Peek Definition** feature works with UDFs, allowing you to quickly view the function's implementation without navigating away from your current context. + +![Peek Definition for UDFs](~/content/assets/images/udf-peek-definition.png) + +### Dependencies View + +UDFs appear in the **DAX Dependencies** (Shift+F12) view, showing both: + +- **Objects that depend on the function**: Which measures, columns, etc. use the UDF +- **Objects the function depends on**: Which measures, columns, etc. the UDF references + +## Best Practices + +### Naming Conventions + +- Use descriptive names that clearly indicate the function's purpose +- Consider prefixing UDFs with your organization's initials (e.g., `ACME.CalculateDiscount`) +- Avoid generic names that might conflict with future DAX functions + +### Documentation + +- Always include comments describing what the function does +- Document each parameter's purpose and expected data type +- Include usage examples in your comments + +```dax +// Calculates the percentage change between two values +// Usage: PercentChange(100, 110) returns 0.10 (10% increase) +( + oldValue: DOUBLE, // The original value + newValue: DOUBLE // The new value to compare against +) +=> DIVIDE(newValue - oldValue, oldValue) +``` + +Tabular Editor 3 automatically picks up any comments and displays them appropriately in autocomplete suggestions and tooltips. + +![UDF Autocomplete with Comments](~/content/assets/images/udf-comment-tooltips.png) + +## Common Use Cases + +### Mathematical Operations + +```dax +// Calculate compound interest +( + principal: DOUBLE, + rate: DOUBLE, + periods: INT64 +) +=> principal * POWER(1 + rate, periods) +``` + +### String Manipulation + +```dax +// Format a full name from first and last name components +( + firstName: STRING, + lastName: STRING +) +=> TRIM(firstName) & " " & TRIM(lastName) +``` + +### Date Calculations + +```dax +// Get the fiscal year based on a date (fiscal year starts July 1) +( + inputDate: DATETIME +) +=> IF(MONTH(inputDate) >= 7, YEAR(inputDate) + 1, YEAR(inputDate)) +``` + +### Business Logic + +```dax +// Apply tiered discount based on quantity +( + quantity: INT64 +) +=> SWITCH( + TRUE(), + quantity >= 100, 0.15, + quantity >= 50, 0.10, + quantity >= 25, 0.05, + 0 +) +``` + +## Troubleshooting + +### Common Issues + +**Function not appearing in autocomplete** + +- Verify the function was saved successfully +- Check that there are no syntax errors in the function definition +- Ensure you're using the function in a compatible context + +**Parameter constraint errors** + +- Review the parameter types you've specified +- Make sure you're passing compatible values to the function +- Check the Microsoft documentation for supported constraint types + +**Function not working after deployment** + +- Verify your target environment supports UDFs (compatibility level 1702+). As of September 16th, 2025, the Power BI Service does not yet support UDFs, nor does Azure Analysis Services or SQL Server Analysis Services. + +## Limitations + +- UDFs are currently a preview feature and may have limitations in certain deployment scenarios +- Not all Power BI environments support UDFs (requires specific builds) +- UDFs cannot be recursive (call themselves) +- UDFs do not support optional parameters, parameters with default values, or parameter overloading +- While Power BI supports visual calculation expressions in UDFs, our DAX parser currently does not, which may cause Tabular Editor 3 to show false error messages, when using visual calculation-specific functions (such as [`RUNNINGSUM`](https://dax.guide/runningsum)) in UDFs. + +--- + +UDFs in Tabular Editor 3 provide a powerful way to create reusable, maintainable DAX code. By following these guidelines and best practices, you can build a library of functions that will improve your model's consistency and reduce development time. \ No newline at end of file diff --git a/content/localization/zh/user-interface_zh.md b/content/localization/zh/user-interface_zh.md new file mode 100644 index 00000000..245edc82 --- /dev/null +++ b/content/localization/zh/user-interface_zh.md @@ -0,0 +1,229 @@ +--- +uid: user-interface +title: Basic user interface +author: Daniel Otykier +updated: 2021-09-08 +--- + +# Getting to know Tabular Editor 3's User Interface + +This article describes the user interface of Tabular Editor 3. + +## Basic user interface elements + +The first time you launch Tabular Editor 3 and load a Semantic Model, you will be presented with an interface, as shown in the screenshot below. + +![Basic user interface](~/content/assets/images/basic-ui.png) + +1. **Title bar**: This shows the name or the currently loaded file and Analysis Services database or Power BI dataset if connected. +2. **Menu bar**: The menu bar provides access to all of the various features of Tabular Editor 3. See [Menus](#menus) for a detailed walkthrough of all menu items. +3. **Toolbars**: The toolbars provide quick access to the most commonly used features. All features accessible through the toolbar can also be accessed through the menus. You may customize the toolbars and their buttons under **Tools > Customize...** +4. **TOM Explorer view**: A hierarchical view of your data model, with all objects available . of the metadata from the [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) metadata that represents your data model. The toggle buttons at the top allow you to filter which objects are displayed. The search box allows you to filter objects by names. +5. **Expression Editor**: The expression editor provides a quick way to edit any DAX, SQL or M expressions of the currently selected object in the TOM Explorer. If you close the expression editor, you can bring it back up by double-clicking on an object in the TOM Explorer. The dropdown at the top allows you to switch between different expression properties, in case the currently selected object has more than one such property (for example, KPIs have Target Expressions, Status Expressions and Trend Expressions, which are 3 different DAX expressions belonging to the same KPI object). +6. **Properties view**: A detailed view of all TOM properties available on the currently selected object(s) in the TOM Explorer. Most properties can be edited through the grid, even when multiple objects are selected. Some properties (such as "Format String", "Connection String", "Role Members") have popup dialogs or collection editors that can be brought up by clicking on the ellipsis button within the property value cell. +7. **Messages view**: Tabular Editor 3 continuously analyzes the DAX expressions on your model for semantic errors. Any such errors are outputted here. In addition, messages shown in this view, can originate from C# scripts or from error messages reported by Analysis Services. +8. **Status bar**: The status bar provides various contextual information about the current selection, Best Practice Analyzer findings, etc. + +There are a number of additional views available, serving various purposes. More information in the [View menu](#view) section. + +# Customizing the user interface + +All UI elements may be resized and/or rearranged to fit your needs. You can even drag individual views out of the main view, thus splitting up an instance of Tabular Editor 3 across multiple monitors. Tabular Editor 3 will save the customization when the application is closed, and reload it automatically upon next launch. + +### Choosing a different layout + +To reset the application to the default layout, choose the **Window > Default layout** option. Users of Tabular Editor 2.x may prefer the **Window > Classic layout** option which places the TOM Explorer on the left side of the screen, and the Properties view below the Expression Editor. + +Use the \*\*Window > Capture current layout..." option to save a customized layout such that it will become available as a new layout option within the Window menu, allowing you to quickly switch back and forth between different layouts. Use the **Window > Manage layouts...** option to bring up a list of all available layouts, allowing you to rename, save, delete layouts, etc. When saving a layout to disk, the result is an .xml file which you can share with other users of Tabular Editor 3. + +![Manage Layouts](~/content/assets/images/manage-layouts.png) + +### Changing themes and palettes + +The visual appearance of Tabular Editor 3 can be changed by choosing a different theme and/or palette. Tabular Editor 3 ships with five different themes (sometimes called "skins"), available through the **Window > Themes** menu: + +- Basic and Bezier (vector based, works well on high-DPI displays) +- Blue, Dark and Light (raster based, not recommended for high-DIP Displays) + +For the vector based themes (Basic and Bezier), use the **Window > Palette** menu item to change the colors used by the theme. + +![Palettes](~/content/assets/images/palettes.png) + +# Menus + +The following section describes the menus in Tabular Editor 3 in more details. + +We use the term **Active document** in the following section, to mean that the cursor is placed within a document such as the Expression Editor or the "DAX Script 1" tab in the screenshot below. Some keyboard shortcuts and menu items behave differently depending on whether there is an active document or not, and what type of document is active. + +> [!NOTE] +> Menus and toolbars are locked in place by default, preventing accidental repositioning. To unlock them, go to **Tools > Customize... > Options** and uncheck the **Lock menus and toolbars** option + +![Active Document](~/content/assets/images/active-document.png) + +## File + +The **File** menu primarily contains menu items for dealing with loading and saving model metadata and supporting files and documents. + +![File Menu](~/content/assets/images/file-menu.png) + +- **New**: Opens a submenu that allows you to create a new blank data model (Ctrl+N), or create various [supporting files](xref:supported-files#supported-file-types) such as a new DAX Query or DAX Script (text files) or a data model diagram (JSON file). Supporting files (with the exception of C# scripts), can be created only when a model is already loaded in Tabular Editor. + + ![File Menu New](~/content/assets/images/file-menu-new.png) + +> [!IMPORTANT] +> The **New > Model...** option is not available in Tabular Editor 3 Desktop Edition, as this edition may only be used as an External Tool for Poewr BI Desktop. [More information](xref:editions). + +- **Open**: Opens a submenu with options for loading a data model from various sources, as well as on option for loading any other type of file. The submenu items are: + + ![File Menu Open](~/content/assets/images/file-menu-open.png) + + - **Model from file...** Open model metadata from a file such as a .bim or .pbit file. + - **Model from DB...** Specify Analysis Services or Power BI XMLA connection details, or connect to a local instance of Analysis Services (such as Visual Studio's Integrated Workspace server or Power BI Desktop), in order to load model metadata from a tabular model that has already been deployed. + - **Model from folder...** Open model metadata from a folder structure which was previously saved using any version of Tabular Editor. + - **File...** displays a dialog that lets you open any type of file supported by Tabular Editor 3, based on the file name extension. See [Supported file types](xref:supported-files) for more information. + + ![Supported File Types](~/content/assets/images/supported-file-types.png) + +> [!IMPORTANT] +> In Tabular Editor 3 Desktop Edition the **Open > Model from file...** and **Open > Model from folder...** options are not available and the **Open > File...** dialog only allows opening [supporting files](xref:supported-files#supported-file-types), not files containing metadata. + +- **Revert**: This option lets you reload the model metadata from the source, discarding any changes that are made in Tabular Editor, which have not yet been saved. This option is useful when Tabular Editor 3 is used as an External Tool for Power BI Desktop, and a change is made in Power BI Desktop while Tabular Editor 3 is connected. By choosing **Revert**, Tabular Editor 3 can reload the model metadata from Power BI Desktop without having to reconnect. +- **Close**: This closes the active document (for example a DAX Query, a C# script or a data model diagram). If the document has unsaved changes, Tabular Editor will prompt you to save the changes before closing. +- **Close model**: This unloads the currently loaded model metadata from Tabular Editor. If you made changes to the metadata, Tabular Editor will prompt you to save the changes before closing. +- **Save**: This saves the active document back to the source file. If no document is active, this saves the model metadata back to the source, which could be a Model.bim file, a Database.json (folder structure) or a connected instance of Analysis Services (including Power BI Desktop) or the Power BI XMLA endpoint. +- **Save as...** This allows you to save the active document as a new file. If no document is active, this allows you to save the model metadata as a new file, using the .bim (JSON-based) file. +- **Save to folder...** This allows you to save the model metadata as a [folder structure](xref:save-to-folder). +- **Save all**: Saves all unsaved documents and model metadata at once. +- **Recent files**: Displays a list of recently used supporting files allowing you to quickly reopen them. +- **Recent tabular models**: Displays a list of recently used model metadata files or folders, allowing you to quickly reload model metadata from one of these. + +> [!IMPORTANT] +> In Tabular Editor 3 Desktop Edition the **Save to folder** and **Recent tabular models** options are disabled. In addition, the **Save as** option is only enabled for [supporting files](xref:supported-files#supported-file-types). + +- **Exit**: Shuts down the Tabular Editor 3 application. You are prompted to save any unsaved files or model metadata before the application is shut down. + +## Edit + +The **Edit** menu contains standard Windows application menu items for editing a document or making changes to the currently loaded model metadata. + +![Edit Menu](~/content/assets/images/edit-menu.png) + +- **Undo**: This option undoes the last change made to the model metadata. When there is no active document, the familiar CTRL+Z shortcut maps to this option. +- **Redo**: This option undoes the last undo against the model metadata. When there is no active document, the familiar CTRL+Y shortcut maps to this option. +- **Undo typing**: Undoes the last text change in the currently active document. When there is no active document, this option is not available. +- **Redo typing**: Undoes the last undo within the currently active document. When there is no active document, this option is not available. +- **Find**: Displays the "Find and replace" dialog with the "Find" tab selected. [More information](xref:find-replace#find). +- **Replace**: Displays the "Find and replace" dialog with the "Replace" tab selected. [More information](xref:find-replace#replace). +- **Cut / Copy / Paste**: These are the familiar Windows editing operations. If there is an active document, then these apply to the text selection within that document. Otherwise, these options may be used to manipulate objects in the TOM Explorer. For example, you can duplicate multiple measures by holding down the SHIFT or CTRL key while selecting the measures in the TOM Explorer, then hitting CTRL+C followed by CTRL+V. +- **Delete**: Deletes the selected text in the active document, or the currently selected object(s) in the TOM Explorer if there is no active document. + +> [!NOTE] +> Tabular Editor generally only prompts for object deletion when multiple objects are selected, or when there are dependencies to the object(s) being deleted. Object deletion can be undone by using the **Undo** option (CTRL+Z). + +- **Select all**: Selects all text in the currently active document, or all objects belonging to the same parent within the TOM Explorer. +- **Code assist**: This option is available when editing DAX code. It provides a shortcut to various code assist features relevant for editing DAX code. See [DAX editor](xref:dax-editor#code-assist-features) for more information. + +## View + +The **View** menu lets you navigate between the different views of the Tabular Editor 3 UI. If a view has been hidden, click on the view title in this menu will unhide the view and bring it into focus. Note that documents are not shown in the View menu. To navigate between documents, use the [Window menu](#window). + +![View Menu](~/content/assets/images/view-menu.png) + +- **TOM Explorer**: The TOM Explorer presents a hierarchical view of the entire [Tabular Object Model (TOM)](https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) of the currently loaded model metadata. See @tom-explorer-view for more information. +- **Best Practice Analyzer**: The Best Practice Analyzer helps improve the quality of your model by letting you specify rules for best practice validation. See @bpa-view for more information. +- **Messages**: The Messages view displays errors, warnings and informational messages from various sources, such as the Tabular Editor 3 Semantic Analyzer. See @messages-view for more information. +- **Data Refresh**: The Data Refresh view allows you to track data refresh operations that are running in the background. See @data-refresh-view for more information. +- **Macros**: The Macros view allows you to manage any macros you have created. Macros can be created from @csharp-scripts. See @creating-macros for more information. +- **VertiPaq Analyzer**: The VertiPaq Analyzer view allows you to collect, import and export detailed statistics about the data in your model, to help improve and debug DAX performance. VertiPaq Analyzer is created and maintained by [Marco Russo](https://twitter.com/marcorus) of [SQLBI](https://sqlbi.com) under MIT license. More information on the [GitHub project page](https://github.com/sql-bi/VertiPaq-Analyzer). +- **Expression Editor**: This is the "quick editor" that lets you edit DAX, M or SQL expressions on whichever object is currently selected in the TOM Explorer. See @dax-editor for more information. + +## Model + +The **Model** menu displays actions that can be performed at the level of the Model object (the root object of the TOM Explorer). + +![View Menu](~/content/assets/images/model-menu.png) + +- **Deploy...**: Launches the Tabular Editor Deployment wizard. For more information, see @deployment. + +> [!IMPORTANT] +> The **Deploy** option is not available in Tabular Editor 3 Desktop Edition. For more information see @editions. + +- **Import tables...** Launches the Tabular Editor 3 Import Table Wizard. For more information, see @importing-tables. +- **Update table schema...** Detects schema changes in the data source(s) for the currently selected table(s) or partition(s) compared to the currently imported columns. See @importing-tables#updating-table-schema for more information. +- **Script DAX**: Generates a DAX script for the currently selected object(s) (or all DAX objects in the model, if nothing is selected). See @dax-scripts for more information. +- **Refresh model**: When Tabular Editor is connected to an instance of Analysis Services, this submenu contains options for starting a background refresh operation at the model level. The submenu has the options below. For more information, see [Refresh command (TMSL)](https://docs.microsoft.com/en-us/analysis-services/tmsl/refresh-command-tmsl?view=asallproducts-allversions#request). + - **Automatic (model)**: Analysis Services determines which objects to refresh (only objects that are not in the "Ready" state). + - **Full refresh (model)**: Analysis Services performs a full refresh of the model. + - **Calculate (model)**: Analysis Services performs a re-calculation of all calculated tables, calculated columns, calculation groups and relationships. No data is read from the data sources. +- **Create [object type]**: The remaining shortcuts in the **Model** menu lets you create new types of model child objects (tables, data sources, perspectives, etc.). + +## Tools + +The **Tools** menu contains options for controlling Tabular Editor 3 preferences and customizations. + +![View Menu](~/content/assets/images/tools-menu.png) + +- **Customize...** Launches the Tabular Editor 3 User Interface Layout customization dialog, which lets you create new toolbars, rearrange and edit menus and toolbar buttons, etc. +- **Preferences...** Launches the Tabular Editor 3 Preferences dialog, which is a central hub for managing all other aspects of Tabular Editor and its features, such as update checks, proxy settings, query row limits, request timeouts, etc. See @preferences for more information. + +## Window + +The **Window** menu provides shortcuts for managing and navigating between the various views and documents (collectively known as _windows_) of the application. It also has menu items for controlling the theming and color palettes as described [above](#changing-themes-and-palettes). + +![View Menu](~/content/assets/images/window-menu.png) + +- **New...** this submenu provides a shortcut for creating new [supporting files](xref:supported-files#supported-file-types). The options here are identical to those under **File > New**. + +- **Float** undocks the current view or document into a floating window. + +- **Pin tab** pins a tab. When a tab is pinned, it is shown at the left-most side of the document tabs, and when right-clicking on the tabs, shortcuts are available for closing only unpinned tabs. + + ![View Menu](~/content/assets/images/tab-context-menu.png) + +- **New Horizontal/Vertical Tab Group**: This option lets you divide the main document area into multiple sections (aka. "tab groups), in order to have multiple documents displayed simultaneously side-by-side or top-by-bottom. + +- **Close All Documents**: Closes all document tabs. You are prompted to save unsaved changes, if any. + +- **Reset Window Layout**: Resets all customization applied to the main document area. + +- **1..N [document]**: The first 10 open documents are listed here, allowing you to navigate between them. You can also use the CTLR+Tab shortcut to quickly switch between open documents and views, such as shown in the screenshot below: + + ![View Menu](~/content/assets/images/ctrl-tab.png) + +- **Windows...**: Opens a dialog listing ALL open documents, allowing you to switch between them or close them individually. + + ![View Menu](~/content/assets/images/windows-manager.png) + +- **Capture current layout** / **Manage layouts...** / **Default layout** / **Classic layout**: These menu items were discussed [earlier in this article](#choosing-a-different-layout). + +- **Theme** / **Default palette**: These menu items were discussed [earlier in this article](#changing-themes-and-palettes). + +## Help + +The **Help** menu provides shortcuts for online resources and more. + +![View Menu](~/content/assets/images/help-menu.png) + +- **Getting Started**: This menu item links to [this article](xref:getting-started). +- **Tabular Editor 3 Docs**: This menu item links to [docs.tabulareditor.com](https://docs.tabulareditor.com/te3). +- **Community Support**: This menu item links to our [public community support site](https://github.com/TabularEditor/TabularEditor3). +- **Dedicated Support**: This menu item lets you send an e-mail directly to our dedicated support hotline. + +> [!NOTE] +> Dedicated support is reserved for Tabular Editor 3 Enterprise Edition customers. All other customers should reach out on the [public community support site](https://github.com/TabularEditor/TabularEditor3) for any technical issues, questions or other product-specific questions. + +- **About Tabular Editor**: Launches a dialog that shows detailed information about the version of Tabular Editor being used as well installation and licensing details. The dialog also lets you change your license key. + +## Dynamic menus (context dependent) + +In addition to the menus mentioned above, other menus may appear at certain times, depending on which UI element currently has focus and which object is currently selected in the TOM Explorer. For example, if you select a Table-object, a **Table** menu will appear, holding the same context-specific shortcut items as when you right-click on that object in the TOM Explorer. + +If you switch the input focus between different types of documents (i.e. DAX queries, Pivot Grids, diagrams, etc.), you should also see a menu representing the type of document currently in focus. That menu will hold items relevant for the current document. For example, when a diagram currently has focus, there will be a **Diagram** menu which has an item for adding tables to the diagram, among others. + +You can change the behavior of these dynamic menus under **Tools > Preferences > User interface**. + +# Next steps + +- [Using the TOM Explorer in Tabular Editor 3](xref:tom-explorer-view) +- @supported-files +- @preferences \ No newline at end of file diff --git a/content/localization/zh/user-options_zh.md b/content/localization/zh/user-options_zh.md new file mode 100644 index 00000000..d0cb0f6a --- /dev/null +++ b/content/localization/zh/user-options_zh.md @@ -0,0 +1,63 @@ +--- +uid: user-options +title: User options (.tmuo) file +author: Daniel Otykier +updated: 2021-09-27 +--- + +# Tabular Model User Options (.tmuo) File + +Tabular Editor 3 introduces a new JSON based file, to store developer- and model-specific preferences. This file is called the **Tabular Model User Options** file and uses the **.tmuo** file extension. + +When you open a Model.bim or Database.json file in Tabular Editor 3, the file will be created using the name of the file you loaded and your Windows user name. For example, if a user opens a file called `AdventureWorks.bim`, the user options file will be saved as `AdventureWorks..tmuo`, where `` is the Windows user name of the current user. Tabular Editor searches for a file with such a name every time a model is loaded from disk. + +> [!IMPORTANT] +> The **.tmuo** file contains user-specific preferences, and as such it should not be included in a shared version control environment. If you're using Git for version control, make sure to include the `.tmuo` extension in your `.gitignore` file. + +## File content + +Below is an example of the file content: + +```json +{ + "UseWorkspace": true, + "WorkspaceConnection": "provider=MSOLAP;data source=localhost", + "WorkspaceDatabase": "WorkspaceDB_DanielOtykier_20210904_222118", + "DataSourceOverrides": { + "SQLDW": { + "ConnectionString": { + "Encryption": "UserKey", + "EncryptedString": "..." + }, + "PrivacySetting": "NA" + } + }, + "TableImportSettings": { + "SQLDW": { + "ServerType": "Sql", + "UserId": "sqladmin", + "Password": { + "Encryption": "UserKey", + "EncryptedString": "..." + }, + "Server": "localhost", + "Database": "AdventureWorksDW2019", + "Authentication": 0 + } + } +} +``` + +In this example, the JSON properties shown have the following meaning: + +- `UseWorkspace`: Indicates whether Tabular Editor should connect to a workspace database upon loading the model. The workspace database will be overwritten with the metadata of the loaded file/folder structure. When this value is not present, Tabular Editor will prompt the user for whether they want to use a workspace database or not, upon model load. +- `WorkspaceConnection`: Server name of the Analysis Services instance or Power BI XMLA Endpoint to which the workspace database will be deployed. +- `WorkspaceDatabase`: Name of the workspace database to deploy. This should ideally be unique for each developer and model. +- `DataSourceOverrides`: This structure may be used to specify alternative data source properties and credentials which will be used every time the workspace database is deployed. This is useful if the Model.bim file contains data source connection details that you want to override for your workspace database, such as when you want Analysis Services to refresh data from a different source than what is specified in the Model.bim file. +- `TableImportSettings`: This structure is used whenever Tabular Editor's [Import Table or Schema Update](xref:importing-tables) feature is used. The credentials and settings specified here, are used by Tabular Editor when establishing a connection to the source for purposes of browsing available tables/views and updating the imported table schema, when changes have been made to the source. + +All credentials and connection strings in the .tmuo file are encrypted with the Windows User Key. In other words, a .tmuo file containing encrypted data cannot be shared between multiple users. + +## Next steps + +- @workspace-mode \ No newline at end of file diff --git a/content/localization/zh/using-bpa-sample-rules-expressions_zh.md b/content/localization/zh/using-bpa-sample-rules-expressions_zh.md new file mode 100644 index 00000000..56191f11 --- /dev/null +++ b/content/localization/zh/using-bpa-sample-rules-expressions_zh.md @@ -0,0 +1,118 @@ +--- +uid: using-bpa-sample-rules-expressions +title: BPA Sample Rules Expression +author: Morten Lønskov +updated: 2023-02-21 +--- + +# Rule Expression Samples + +In this section, you'll see some examples of Dynamic LINQ expressions that can be used to define rules. The expression that is entered in the Rule Expression Editor, will be evaluated whenever focus leaves the textbox, and any syntax errors will be shown on top of the screen: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380170/9f01634e-29af-11e7-952e-e10a1f28df32.png) + +Your rule expressions may access any public properties on the objects in the TOM. If you try to access a property that does not exist on that type of object, an error will also be shown: + +![image](https://cloud.githubusercontent.com/assets/8976200/25381302/798bab98-29b3-11e7-931e-789e5286fc45.png) + +"Expression" does not exist on the "Column" object, but if we switch the dropdown to "Calculated Columns", the statement above works fine: + +![image](https://cloud.githubusercontent.com/assets/8976200/25380451/87b160da-29b0-11e7-8e2e-c4e47593007d.png) + +Dynamic LINQ supports all the standard arithmetic, logical and comparison operators, and using the "."-notation, you can access subproperties and -methods of all objects. + +``` +String.IsNullOrWhitespace(Expression) and not Name.StartsWith("Dummy") +``` + +The above statement, applied to Calculated Columns, Calculated Tables or Measures, flags those that have an empty DAX expression unless the object's name starts with the text "Dummy". + +Using LINQ, we can also work with collections of objects. The following expression, applied to tables, will find those that have more than 10 columns which are not organized in Display Folders: + +``` +Columns.Count(DisplayFolder = "") > 10 +``` + +Whenever we use a LINQ method to iterate over a collection, the expression used as an argument to the LINQ method is evaluated on the items in the collection. Indeed, DisplayFolder is a property on columns that does not exist at the Table level. + +Here, we see this rule in action on the Adventure Works tabular model. Note how the "Reseller" table shows up as being in violation, while the "Reseller Sales" does not show up (columns in the latter have been organized in Display Folders): + +![image](https://cloud.githubusercontent.com/assets/8976200/25380809/d9d1c3a4-29b1-11e7-839e-29450ad39c8a.png) + +To refer to the parent object inside a LINQ method, use the special "outerIt" syntax. This rule, applied to tables, will find those that contain columns whose name does not start with the table name: + +``` +Columns.Any(not Name.StartsWith(outerIt.Name)) +``` + +It would probably make more sense to apply this rule to Columns directly, in which case it should be written as: + +``` +not Name.StartsWith(Table.Name) +``` + +To compare against enumeration properties, simply pass the enumerated value as a string. This rule, will find all columns whose name end with the word "Key" or "ID", but where the SummarizeBy property has not been set to "None": + +``` +(Name.EndsWith("Key") or Name.EndsWith("ID")) and SummarizeBy <> "None" +``` + +## Finding unused objects + +When building Tabular Models it is important to avoid high-cardinality columns at all costs. Typical culprits are system timestamps, technical keys, etc. that have been imported to the model by mistake. In general, we should make sure that the model only contains columns that are actually needed. Wouldn't it be nice if the Best Practice Analyzer could tell us which columns are likely not needed at all? + +The following rule will report columns that: + +- ...are hidden (or whose parent table is hidden) +- ...are not referenced by any DAX expressions (considers all DAX expressions in the model - even drillthrough and RLS filter expressions) +- ...do not participate in any relationships +- ...are not used as the "Sort By"-column of any other column +- ...are not used as levels of a hierarchy. + +The Dynamic LINQ expression for this BPA rule is: + +``` +(IsHidden or Table.IsHidden) +and ReferencedBy.Count = 0 +and (not UsedInRelationships.Any()) +and (not UsedInSortBy.Any()) +and (not UsedInHierarchies.Any()) +``` + +The same technique can be used to find unused measures. It's a little simpler, since measures can't participate in relationships, etc. So instead, let's spice things up a bit, by also considering whether any downstream objects that reference a given measure, are visible or not. That is, if measure [A] is referenced by measure [B], and both measure [A] and [B] are hidden, and no other DAX expressions refer to these two measures, we should let the developer know that it is safe to remove both of them: + +``` +(IsHidden or Table.IsHidden) +and not ReferencedBy.AllMeasures.Any(not IsHidden) +and not ReferencedBy.AllColumns.Any(not IsHidden) +and not ReferencedBy.AllTables.Any(not IsHidden) +and not ReferencedBy.Roles.Any() +``` + +## Fixing objects + +In some cases, it is possible to automatically fix the issues on objects satisfying the criteria of a rule. For example when it's just a matter of setting a simple property on the object. Take a closer look at the JSON behind the following rule: + +```json +{ + "ID": "FKCOLUMNS_HIDDEN", + "Name": "Hide foreign key columns", + "Category": null, + "Description": "Columns used on the Many side of a relationship should be hidden.", + "Severity": 1, + "Scope": "Column", + "Expression": "Model.Relationships.Any(FromColumn = outerIt) and not IsHidden and not Table.IsHidden", + "FixExpression": "IsHidden = true", + "Compatibility": [ + 1200, + 1400 + ], + "IsValid": false +} +``` + +This rule finds all columns that are used in a relationship (on the "Many"/"From" side), but where the column or its parent table are not hidden. It is recommended that such columns are never shown, as users should filter data using the related (dimension) table instead. So the fix in this case, would be to set the columns IsHidden property to true, which is exactly what the "FixExpression" string above does. To see this in action, right-click any objects that violate the rule, and choose "Generate Fix Script". This puts a small script into the clipboard, which can be pasted into the Advanced Script Editor, from where you can easily review the code and execute it: + +![image](https://cloud.githubusercontent.com/assets/8976200/25298489/9035bab6-26f5-11e7-8134-8502daaf4132.png) + +Remember that you can always undo (CTRL+Z) changes done to a model after script execution. diff --git a/content/localization/zh/using-bpa_zh.md b/content/localization/zh/using-bpa_zh.md new file mode 100644 index 00000000..23a76481 --- /dev/null +++ b/content/localization/zh/using-bpa_zh.md @@ -0,0 +1,104 @@ +--- +uid: using-bpa +title: Using the Best Practice Analyzer +author: Morten Lønskov +updated: 2023-02-09 +--- + +# Best Practice Analyzer + +The Best Practice Analyzer (BPA) lets you define rules on the metadata of your model, to encourage certain conventions and best practices while developing your Power BI or Analysis Services Model. + +## PBA Overview + +The BPA overview shows you all the rules defined in your model that are currently being broken: + +![BPA Overview](~/content/assets/images/common/BPAOverview.png) + +And you will always be able to see in the main UI how many rules you are currently being broken. + +![BPA Overview Line](~/content/assets/images/common/PBAOverviewMenuLine.png) + +Clicking the link (or pressing F10), brings up the full BPA window. + +> [!NOTE]> If you are more into a video walk through then PowerBI.tips has a video with our own Daniel Otykier showing the Best Practice Analyzer in detail here: +> > [!Video https://www.youtube.com/embed/5WnN0NG2nBk] + +### Functionality + +Whenever a change is made to the model, the Best Practice Analyzer scans your model for issues in the background. You can disable this feature under File > Preferences. + +The BPA Window in both TE2 and TE3 allows you to dock the window on one side of your desktop, while keeping the main window in the other side, allowing you to work with your model while you can see BPA issues. + +The Best Practice Analyzer window continuously lists all the **effective rules** on your model as well as the objects that are in violation of each rule. Right-clicking anywhere inside the list or using the toolbar buttons at the top of the window, let's you perform the following actions: + +- **Manage rules...**: This opens the Manage Rules UI, which we will cover below. This UI can also be accessed through the "Tools > Manage BPA Rules..." menu of the main UI. +- **Go to object...**: Choosing this option or double-clicking on an object in the list, takes you to the same object in the main UI. +- **Ignore item/items**: Selecting one or more objects in the list and choosing this option, will apply an annotation to the chosen objects indicating that the Best Practice Analyzer should ignore the objects going forward. If you ignored an object by mistake, toggle the "Show ignored" button at the top of the screen. This will let you unignore an object that was previously ignored. +- **Ignore rule**: If you've selected one or more rules in the list, this option will put an annotation at the model level that indicates, that the selected rule should always be ignored. Again, by toggling the "Show ignored" button, you can unignore rules as well. +- **Generate fix script**: Rules that have an easy fix (meaning the issue can be resolved simply by setting a single property on the object), will have this option enabled. By clicking, you will get a C# script copied into your clipboard. This script can then be subsequently pasted into the [Advanced Scripting](/Advanced-Scripting) area of Tabular Editor, where you can review it before executing it to apply the fix. +- **Apply fix**: This option is also available for rules than have an easy fix, as mentioned above. Instead of copying the script to the clipboard, it will be executed immediately. + +## Managing Best Practice Rules + +If you need to add, remove or modify the rules applying to your model, there's a specific UI for that. You can bring it up by clicking the top-left button on the Best Practice Analyzer window, or by using the "Tools > Manage BPA Rules..." menu item in the main window. + +![BPA Manage Rules](~/content/assets/images/common/BPAOverviewManageRules.png) + +The Manage BPA rules window contains two lists: The top list represents the **collections** of rules that are currently loaded. Selecting a collection in this list, will display all the rules that are defined within this collection in the bottom list. + +![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUp.png) + +### Rule Collections + +By default, three rule collections will show up: + +### [Tabular Editor 3](#tab/TE3Rules) + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%AppData%\..\Local\TabularEditor3\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor3\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +### [Tabular Editor 2](#tab/TE2Rules) + +- **Rules within the current model**: As the name indicates, this is the collection of rules that have been defined within the current model. The rule definitions are stored as an annotation on the Model object. +- **Rules for the local user**: These are rules that are stored in your `%AppData%\..\Local\TabularEditor\BPARules.json` file. These rules will apply to all models that are loaded in Tabular Editor by the currently logged in Windows user. +- **Rules on the local machine**: These rules are stored in the `%ProgramData%\TabularEditor\BPARules.json`. These rules will apply to all models that are loaded in Tabular Editor on the current machine. + +*** + +#### Rule Precedence + +If the same rule (by ID) is located in more than one collection, the order of precedence is from top to bottom, meaning a rule defined within the model takes precedence over a rule, with the same ID, defined on the local machine. This allows you to override existing rules, for example to take model specific conventions into account. + +##### Effective Rules + +At the top of the list, you'll see a special collection called **(Effective rules)**. Selecting this collection will show you the list of rules that actually apply to the currently loaded model, respecting the precedence of rules with identical ID's, as mentioned above. The lower list will indicate which collection a rule belongs to. Also, you will notice that a rule will have its name striked out, if a rule with a similar ID exists in a collection of higher precedence: + +![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUpHigherPrecedence.png) + +#### Adding additional collections + +Tabular Editor provides the possibility of including rules from other sources on a model. If, for example, you have a rules file located on a network share, you can now include that file as a rule collection in the current model. If you have write access to the location of the file, you'll also be able to add/modify/remove rules from the file. Rule collections that are added this way take precedence over rules that are defined within the model. If you add multiple such collections, you can shift them up and down to control their mutual precedence. + +Click the "Add..." button to add a new rule collection to the model. This provides the following options: + +![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUpCreateNewRuleFile.png) + +- **Create new Rule File**: This will create a new, empty, .json file at the specified location, which you can subsequently add rules to. When choosing the file, notice that there is an option for using relative file paths. This is useful when you want to store the rule file in the same code repository as the current model. However, please be aware that a relative rule file reference only works, when the model has been loaded from disk (since there is no working directory when loading a model from an instance of Analysis Services). +- **Include local Rule File**: Use this option if you already have a .json file containing rules, that you want to include in your model. Again, you have the option of using relative file paths, which may be beneficial if the file is located close to the model metadata. If the file is located on a network share (or generally, on a drive different than where the currently loaded model metadata resides), you can only include it using an absolute path. +- **Include Rule File from URL**: This option lets you specify an HTTP/HTTPS URL, that should return a valid rule definition (json). This is useful if you want to include rules from an online source, for example the [Microsoft standard BPA rules](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json) from the [BestPracticeRules GitHub site](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules). Note that rule collections added from online sources will be read-only. + +#### Modifying rules within a collection + +The lower part of the screen will let you add, edit, clone and delete rules within the currently selected collection, provided you have write access to the location where the collection is stored. Also, the "Move to..." button allows you to move or copy the selected rule to another collection, making it easy to manage multiple collections of rules. Please see our article with [samples of rule expressions ](/common/using-bpa-sample-rules-expressions.md) for more information on how to use that. + +#### Rule Description Placeholders + +You can use placeholder values within the Best Practice Rule's description. This provides more customizable descriptions that will appear as tooltips in the Best Practice UI: + +- `%object%` returns a fully qualified DAX reference (if applicable) to the current object +- `%objectname%` returns only the name of the current object +- `%objecttype%` returns the type of the current object + +![BPA Manage Rules UI](~/content/assets/images/common/BPAOverviewRuleDescriptionPlaceHolders.png) diff --git a/content/localization/zh/whats-new_zh.md b/content/localization/zh/whats-new_zh.md new file mode 100644 index 00000000..d38185c5 --- /dev/null +++ b/content/localization/zh/whats-new_zh.md @@ -0,0 +1,15 @@ +--- +uid: whats-new +title: What's new +author: Morten Lønskov +updated: 2023-10-11 +--- + + + + diff --git a/content/localization/zh/workspace-mode.partial_zh.md b/content/localization/zh/workspace-mode.partial_zh.md new file mode 100644 index 00000000..a32bed81 --- /dev/null +++ b/content/localization/zh/workspace-mode.partial_zh.md @@ -0,0 +1,91 @@ +Tabular Editor 3 introduces the concept of **workspace mode** when creating a new model inside the tool, or when loading a Model.bim or Database.json file of an existing model. + +Using workspace mode, Tabular Editor will synchronize your model metadata changes to a **workspace database**, whenever you hit Save (Ctrl+S), while also saving the metadata changes to the file(s) on disk. + +Ideally, each model developer should use their own workspace database to avoid conflicts while developing. + +> [!WARNING] +> Do not enable Git integration on the Fabric workspace that you use to host your Tabular Editor workspace databases. This is to avoid Git conflicts as you develop the model, since Tabular Editor makes changes to the workspace database through the XMLA endpoint, and these changes will not be in sync with any underlying Git branch. + +> [!NOTE] +> For models at compatibility level 1200, 1400 or 1500, we recommend using a local instance of Analysis Services to host the workspace database, such as the one included with [SQL Server Developer Edition 2019](https://www.microsoft.com/en-us/sql-server/sql-server-downloads). + +# Creating a new model + +When you create a new model in Tabular Editor, the "Use workspace database" option is checked by default: + +![New Model](~/content/assets/images/new-model.png) + +Leaving this checked, you will be prompted to connect to an instance of Analysis Services after hitting "OK". This is the instance of Analysis Services to which your workspace database will be deployed. + +> [!IMPORTANT] +> If you plan to deploy your workspace database to the Power BI Service XMLA endpoint, make sure you choose Compatibility Level 1609 (Power BI / Fabric) in the dialog above. + +After entering the Analysis Services server details and (optional) credentials, you are shown a list of all databases currently reciding on the server (or for a Power BI workspace, the list of datasets deployed to the workspace): + +![Select Workspace Database](~/content/assets/images/select-workspace-database.png) + +Tabular Editor suggests a new unique name for your workspace database, based on your Windows user name and the current date and time, but you are free to change this to a more meaningful name. + +After hitting OK, your new model is created and the workspace database is deployed and connected. At this point, hit save (Ctrl+S) to save your model as a Model.bim file. You may also choose the File > Save to Folder... menu item if you intend to store the model metadata in a version control system such as Git. + +![Save New To Folder](~/content/assets/images/save-new-to-folder.png) + +At this point, you are ready to define data sources and add new tables to your model. Every time you subsequently hit Save (Ctrl+S), the workspace database is updated with the changes, and the file/folder you chose previously will be updated as well. + +Information about the workspace database tied to this model is stored in a Tabular Model User Options (.tmuo) file next to the model metadata file. See @user-options for more information. + +# Opening a Model.bim or Database.json file + +If you open an existing Model.bim or Database.json file, Tabular Editor 3 will prompt you whether you want to initiate a workspace database for that file. + +![Connect To Workspace database](~/content/assets/images/connect-to-wsdb.png) + +Your options are: + +- **Yes**: Connect to an instance of Analysis Services and choose an existing workspace database or create a new one. The next time you load the same Model.bim or Database.json file, Tabular Editor will connect to the same workspace database. Tabular Editor will perform a deployment of the Model.bim or Database.json file onto the selected workspace database. +- **No**: Tabular Editor will load the metadata in the file offline with no connectivity to Analysis Services. +- **Don't ask again**: Same as above, but Tabular Editor will no longer ask you to connect to a workspace database the next time you open the same Model.bim or Database.json file. +- **Cancel**: The file is not loaded at all. + +Information about whether to connect to a workspace database for a given model, and which workspace server and database to use is stored in the [Tabular Model User Options (.tmuo) file](xref:user-options). + +> [!WARNING] +> When choosing a workspace database, Tabular Editor 3 will deploy the loaded model metadata onto that workspace database. For this reason, you should never use a production database as your workspace database. Moreover, we recommend using a separate Analysis Services instance/Power BI workspace for your workspace databases. + +# Advantages of workspace mode + +The main advantage of workspace mode, is that it allows Tabular Editor to stay connected to an instance of Analysis Services. In other words, Tabular Editor 3's new [connected features](xref:migrate-from-te2#connected-features) are enabled. But even if you choose not to use these features, it is much easier to synchronize an instance of Analysis Services for purposes of testing your changes. All you have to do is hit Save (CTRL+S). This is similar to when Tabular Editor opens model metadata directly from an instance of Analysis Services, but with workspace mode, the model metadata is simultaneously saved to disk. + +> [!NOTE] +> When a refresh operation is in progress, Tabular Editor cannot synchronize the Analysis Services instance (refresh operations block other write operations). However, hitting Save (CTRL+S) while such an operation is under way will still save the model metadata to disk, while using workspace mode. + +# Disable Workspace Mode for a Model + +If you prefer to _disable workspace mode_ and edit a model file entirely offline, choose one of the methods below. + +## Permanently disable Workspace Mode + +1. Locate the model’s `.tmuo` workspace file (it sits next to your `.bim`, `.tmdl`, or `.json` file) in your File Explorer. + +2. Do **either** of the following: + - **Delete** the `.tmuo` file, **or** + - Open it in a text editor and set: + + ```json + { + "UseWorkspaceDatabase": false + } + ``` + +3. Open the model from the `.bim`, `.tmdl`, or `.json` file as usual. + +Tabular Editor will now stay offline every time you load this model. + +## Disable Workspace Mode for the current session only + +1. In the **Open Semantic Model** dialog, check **Load without workspace database**. + +![Load without Workspace database](~/content/assets/images/load-without-wsdb.png) + +The model loads offline for this session; next time you open it, Workspace Mode is re-enabled unless you repeat these steps. diff --git a/content/localization/zh/workspace-mode_zh.md b/content/localization/zh/workspace-mode_zh.md new file mode 100644 index 00000000..00250f63 --- /dev/null +++ b/content/localization/zh/workspace-mode_zh.md @@ -0,0 +1,16 @@ +--- +uid: workspace-mode +title: Workspace Mode +author: Daniel Otykier +updated: 2021-09-06 +applies_to: + editions: + - edition: Desktop + none: x + - edition: Business + - edition: Enterprise +--- + +# (Walkthrough) Workspace Mode + +[!include[workspace-mode](~/content/te3/workspace-mode.partial.md)] \ No newline at end of file diff --git a/content/localization/zh/xmla-as-connectivity_zh.md b/content/localization/zh/xmla-as-connectivity_zh.md new file mode 100644 index 00000000..748fa175 --- /dev/null +++ b/content/localization/zh/xmla-as-connectivity_zh.md @@ -0,0 +1,189 @@ +--- +uid: xmla-as-connectivity +title: XMLA / Analysis Services connectivity +author: Daniel Otykier +updated: 2024-05-01 +applies_to: + versions: + - version: 2.x + - version: 3.x + editions: + - edition: Business + - edition: Enterprise +--- + +# XMLA / Analysis Services connectivity + +Tabular Editor uses the [AMO client library](https://learn.microsoft.com/en-us/analysis-services/amo/developing-with-analysis-management-objects-amo?view=asallproducts-allversions) to connect to the Power BI / Fabric XMLA endpoint or instances of SQL Server or Azure Analysis Services (Tabular). Authentication and authorization is handled by the AMO client library, which means that Tabular Editor does not store any credentials or tokens. Moreover, users will need sufficient permissions to connect to the XMLA endpoint or Analysis Services instance. In most cases, the user must be a member of the Analysis Services server administrator role or have administrative permissions in the Power BI workspace. + +In the following article, we will use the term "semantic model server" to mean the service accessed through the Power BI / Fabric XMLA endpoint or any instance of SQL Server Analysis Services Tabular (SSAS) or Azure Analysis Services (AAS). + +## Connection dialog + +To connect to the semantic model server, go to **File** > **Open** > **Model from DB...**, or press **Ctrl+Shift+O**. + +This will open the **Load Semantic Model from Database** dialog, where you can specify the server name, an XMLA connection string or pick a local SSAS instance from a dropdown. Moreover, you can specify the type of authentication to use. + +> [!NOTE] +> In Tabular Editor 2.x, the **Advanced Options** (for specifying read/write mode and a custom status bar color) are not available. + +![Connect Dialog](~/content/assets/images/connect-dialog.png) + +## Select database + +After you click "OK", Tabular Editor will connect to the semantic model server and retrieve a list of databases that you have access to. Select the database you want to work with, and click "OK". + +## Advanced Connection String Properties + +In all versions of Tabular Editor, you can specify an OLAP connection string in the **Server** textbox, rather than just the server name. + +A typical OLAP connection string looks like this: + +``` +Provider=MSOLAP;Data Source=servername;Initial Catalog=databasename;Integrated Security=SSPI; +``` + +> [!NOTE] +> If the `Initial Catalog` property is specified in the connection string, the **Select Database** dialog will not be shown, and Tabular Editor will connect directly to the specified database. + +OLAP connection strings support many properties in addition to the ones shown above. For a full list of properties, see the [Microsoft documentation](https://learn.microsoft.com/en-us/analysis-services/instances/connection-string-properties-analysis-services?view=asallproducts-allversions). + +In addition to the properties listed in the documentation, AMO connection strings also supports the following properties: + +### Locale Identifier + +You can specify the language to use for the connection by setting the `Locale Identifier` property. The value is a number that corresponds to a specific language. For example, `1033` corresponds to English (United States). + +``` +Provider=MSOLAP;Data Source=servername;Initial Catalog=databasename;Integrated Security=SSPI;Locale Identifier=1033; +``` + +This is useful if you want error messages and other server messages to be in a specific language. If the `Locale Identifier` property is not specified, the language of the client operating system is used. + +Most Analysis Services instances support several languages. See [this page for a full list of locale identifiers (LCID)](https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-fulltext-languages-transact-sql?view=sql-server-ver16). + +## Fabric/Power BI XMLA Settings + +Two admin settings must be switched on to enable the XMLA endpoint in Fabric/Power BI. + +### Enable Tennant XMLA Endpoint + +In the Fabric/Power BI admin portal, the integration setting "Allow XMLA endpoints and Analyze in Excel with on-premises semantic models" must be enabled + +At the tenant level, the setting may be restricted to only certain users. If the setting is restricted in your organization, ensure all required users are allowed to use the XMLA endpoint at the tenant level. + +![Tennant Admin Setting](~/content/assets/images/common/XMLASettings/TennantAdminSetting.png) + +### Enable XMLA Read Write on Capacity + +To use the XMLA endpoint, the workspace that hosts a semantic model must be assigned to a capacity (FSku or Power BI Premium Per User), and the capacity must have XMLA ["Read Write" enabled in the capacity settings.](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#enable-xmla-read-write) + +![Tennant Admin Setting](~/content/assets/images/common/XMLASettings/CapacityAdminSetting.png) + +Read Write is enabled in the Admin Portal by navigating to + +1. Capacity Settings +2. Choosing the type of capacity +3. Selecting the relevant Capacity +4. Navigating to Power BI Workloads and scrolling down to find the XMLA Endpoint setting choosing "Read Write" + +### Workspace Level User Rights + +To edit models using the XMLA endpoint the user's account needs to have access to the workspace as either **Contributor**, **Member** or **Admin**. In the workspace choose 'Manage Access' and add the user account or a Entra ID group that the user belongs to with the required role. For more information on roles in workspaces please see Microsoft's Documentation: [Roles in Workspaces](https://learn.microsoft.com/en-us/fabric/fundamentals/roles-workspaces) + +### Read/Write on Semantic Model + +Ensure that the user's account has Write permission to the semantic model. This can be required even if the user is an admin on the workspace as mentioned above. + +To check that your account has the necessary permissions start by locating the model in the Fabric/Power BI workspace and first click on the hamburger symbol (3 vertical dots) and go to the "Manage permissions" page. + +![Manage Permissions on Semantic Model](~/content/assets/images/common/XMLASettings/ManagePermissionsonSemanticModel.png) + +Validate or give the user's account or the Entra ID group that they belong to either **Workspace Admin**, **Workspace Contributor**, or **Write permission** on the semantic model. For example, in the screenshot below, only the 3 users highlighted in Blue would be able to access the model through Tabular Editor: + +![User Permissions on Semantic Model](~/content/assets/images/common/XMLASettings/UserPermissionsonSemanticModel.png) + +### Set workspace to large semantic models + +To ensure the best experience while editing models using the XMLA endpoint the workspace should have its semantic storage format set to **Large Semantic model storage format**. Go to 'Workspace Settings' in the top right corner of the Fabric/Power BI workspace. First navigate to the 'License info', secondly validate if the storage format is set to large and if not choose 'Edit' to change the storage format. + +![Large Semantic Model Storage Format](~/content/assets/images/common/XMLASettings/LargeSemanticModelStorageFormat.png) + +## Additional Fabric/Power BI settings. + +### Disable Package Refresh + +If another user, other than the semantic model's owner, needs to edit the model through the XMLA endpoint, the security admin setting in Fabric/Power BI called "Block republish and disable package refresh" must be disabled. + +![Tennant Admin Setting](~/content/assets/images/common/XMLASettings/DisablePackageRefresh.png) + +## Unsupported model types + +Several types of models do not support XMLA connections, [listed below](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#unsupported-semantic-models). + +The following semantic models aren't accessible by using the XMLA endpoint. These semantic models won't appear under the workspace in Tabular Editor or any other tool. + +- Semantic models based on a live connection to an Azure Analysis Services or SQL Server Analysis Services model. +- Semantic models based on a live connection to a Power BI semantic model in another workspace. +- Semantic models with Push data by using the REST API. +- Semantic models in My Workspace. +- Excel workbook semantic models + +In Fabric, the default semantic model of a lakehouse or warehouse can be opened/connected to in Tabular Editor, but [not edited](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#considerations-and-limitations). Moreover, some operations that require read access to certain [DMVs](https://learn.microsoft.com/en-us/analysis-services/instances/use-dynamic-management-views-dmvs-to-monitor-analysis-services?view=asallproducts-allversions), such as collecting VertiPaq Analyzer statistics, may not be supported on default semantic models. + +## Troubleshooting XMLA connections + +### Testing a simple connection + +These steps show how to most reliably connect to a Fabric/Power BI semantic model from Tabular Editor. + +1. Connecting to a semantic model in Fabric is through the 'File' > 'Open' > 'Model from DB' (default shortcut Ctrl+Shift+O) + +2. You'll be presented with a dialogue (see below), and you need to put the Power BI connection string into the text box labeled 'Server'. Leave the rest of the options as configured in the screenshot (these are defaults). The connection string is in the form shown below. You can find this connection string in the Service (more details here in this [Microsoft doc in the sections 'Connecting to a Premium Workspace' and 'To get the workspace connection URL'](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#connecting-to-a-premium-workspace) + +![Load Model From Database](~/content/assets/images/common/XMLASettings/LoadModelFromDatabase.png) + +Please copy and paste the connection string directly from the workspace rather than copying from somewhere/someone else or modifying it in any way. + +3. Depending on your machine (if your Windows login is linked to Entra ID or your identity provider) you may be prompted to log in. It's important that the account you use is the one with permission to the workspace. If your organization has multiple tenants or if you have multiple logins, this might not match your Windows login. You should use the exact credential that is shown in the Fabric web UI for your user. + +![Authenticate to FabricPowerBI](~/content/assets/images/common/XMLASettings/AuthenticateToFabricPowerBI.png) + +4. After successful authentication, you'll be presented with a 'Choose database' dialog. Select one and click 'Ok'. + +![Choose Database](~/content/assets/images/common/XMLASettings/ChooseDatabase.png) + +### Set Authentication Type to Microsoft Entra ID + +In some cases the 'Integrated' security option could be different from the user account that should be used for authenticating against the Fabric/Power BI service. The next step to take is to choose the **Microsoft Entra MFA** option in the open model dialog box. + +![Microsoft Entra MFA](~/content/assets/images/common/XMLASettings/LoadModelFromDatabaseMicrosoftEntraID.png) + +Choosing the 'Microsoft Entra MFA' option forces the multifactor authentication and allows for choosing the specific account that is needed to connect to the workspace. + +### Multiple tenants + +If you've double-checked the user name and connection string as above and are still having issues, the next thing to check is whether adding the tenant GUID to the connection string helps. This might be an issue if you belong to multiple tenants. + +The tenant ID can be found directly in Power BI by clicking the top-right question mark and selecting 'About Power BI'. The tenant ID is shown as part of the 'Tenant URL'. Be careful, as the text box is typically too small to display the whole thing in the window in Power BI. Double-click on the URL shown, which will highlight the entire thing, that you can copy and paste. + +The whole URL is not the tenant ID. The tenant ID is the GUID at the end of the string, after "ctid=". So in the screenshot below, my tenant ID starts with "ddec", but yours will be different. Once you have the tenant ID, you can change the connection string that you used above: replace the part of the path that says "myorg" with your tenant ID. + +An example is below. Your tenant ID and your workspace name will be different than those shown. + +- Old: `powerbi://api.powerbi.com/v1.0/myorg/WorkspaceName` +- New: `powerbi://api.powerbi.com/v1.0/eeds65sv-kl25-4d12-990a-770ca3eb6226/WorkspaceName` + +You can also use the tenant name (e.g. `fabrikam.com`) as shown in [this article](https://learn.microsoft.com/en-us/fabric/enterprise/powerbi/service-premium-connect-tools#connecting-to-a-premium-workspace). + +Then, attempt connecting precisely as the instructions in the [Testing a simple connection section](#testing-a-simple-connection) + +### Duplicate names + +There can be issues connecting to a model if the workspace name is a duplicate of another workspace or if the model name is a duplicate name of another model. + +If there are duplicate names, please refer to Microsoft's documentation in the sections ["Duplicate workspace names" and "Duplicate semantic model name"](https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-connect-tools#duplicate-workspace-names) to learn how to modify the connection string to address these issues + +### Proxy handling + +Another common cause of connectivity issues is proxies. For more information about this, please review [this article](xref:proxy-settings).