diff --git a/content/features/code-actions.md b/content/features/code-actions.md index b7513e1a..a531b54b 100644 --- a/content/features/code-actions.md +++ b/content/features/code-actions.md @@ -121,7 +121,7 @@ The Code Actions below will appear with teal green dots under the first two char | 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 }` | +| 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 diff --git a/localizedContent/es/content/_ui-strings.json b/localizedContent/es/content/_ui-strings.json index 589764cb..5b6b37c6 100644 --- a/localizedContent/es/content/_ui-strings.json +++ b/localizedContent/es/content/_ui-strings.json @@ -35,5 +35,14 @@ "themeAuto": "Automático", "changeTheme": "Cambiar tema", "copy": "Copiar", - "downloadPdf": "Descargar PDF" + "downloadPdf": "Descargar PDF", + "search": "Buscar documentación", + "note": "Nota", + "warning": "Advertencia", + "tip": "Consejo", + "important": "Importante", + "caution": "Precaución", + "tableOfContents": "Tabla de contenidos", + "selectLanguage": "Seleccionar idioma", + "copyCode": "Copiar código" } diff --git a/localizedContent/es/content/features/CSharpScripts/Advanced/script-create-and-replace-M-parameter.md b/localizedContent/es/content/features/CSharpScripts/Advanced/script-create-and-replace-M-parameter.md index fc77810b..50acc819 100644 --- a/localizedContent/es/content/features/CSharpScripts/Advanced/script-create-and-replace-M-parameter.md +++ b/localizedContent/es/content/features/CSharpScripts/Advanced/script-create-and-replace-M-parameter.md @@ -26,69 +26,69 @@ Si quieres reemplazar una cadena en las particiones M del modelo (por ejemplo, l ### Crear un nuevo parámetro M y agregarlo a las particiones M existentes ```csharp -// Este script crea un nuevo parámetro M como una 'expresión compartida'. -// También buscará el valor predeterminado en todas las particiones M y lo reemplazará por el nombre del objeto del parámetro. +// 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; -// Ocultar el control giratorio de 'Running Macro' +// Hide the 'Running Macro' spinbox ScriptHelper.WaitFormVisible = false; -// Inicializar variables +// Initialize variables string _ParameterName = "New Parameter"; string _ParameterValue = "ParameterValue"; -// Cuadro de diálogo de WinForms para obtener el nombre/valor del parámetro +// WinForms prompt to get Parameter Name / Value input using (Form prompt = new Form()) { Font formFont = new Font("Segoe UI", 11); - // Configuración del cuadro de diálogo + // Prompt config prompt.AutoSize = true; prompt.MinimumSize = new Size(380, 120); - prompt.Text = "Crear nuevo parámetro M"; + prompt.Text = "Create New M Parameter"; prompt.StartPosition = FormStartPosition.CenterScreen; - // Buscar: etiqueta - Label parameterNameLabel = new Label() { Text = "Escribe el nombre:" }; + // Find: label + Label parameterNameLabel = new Label() { Text = "Enter Name:" }; parameterNameLabel.Location = new Point(20, 20); parameterNameLabel.AutoSize = true; parameterNameLabel.Font = formFont; - // Cuadro de texto para introducir el texto de la subcadena + // 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; - // Reemplazar: etiqueta - Label parameterValueLabel = new Label() { Text = "Escribe el valor:" }; + // 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; - // Cuadro de texto para introducir el texto de la subcadena + // 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; - // Botón Aceptar - Button okButton = new Button() { Text = "Crear", Left = 20, Width = 75, Top = parameterValueBox.Location.Y + parameterValueBox.Height + 20 }; + // 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; - // Botón Cancelar - Button cancelButton = new Button() { Text = "Cancelar", Left = okButton.Location.X + okButton.Width + 10, Top = okButton.Location.Y }; + // 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; - // Acciones de los botones + // Button actions okButton.Click += (sender, e) => { _ParameterName = parameterNameBox.Text; _ParameterValue = parameterValueBox.Text; prompt.DialogResult = DialogResult.OK; }; cancelButton.Click += (sender, e) => { prompt.DialogResult = DialogResult.Cancel; }; @@ -102,11 +102,11 @@ using (Form prompt = new Form()) prompt.Controls.Add(okButton); prompt.Controls.Add(cancelButton); - // El usuario hizo clic en Aceptar, así que se ejecuta la lógica de buscar y reemplazar + // The user clicked OK, so perform the find-and-replace logic if (prompt.ShowDialog() == DialogResult.OK) { - // Crea el parámetro + // Creates the parameter Model.AddExpression( _ParameterName, @" @@ -120,21 +120,21 @@ using (Form prompt = new Form()) ); - // Informa al usuario de que el parámetro se creó correctamente + // Informs the user that the parameter was successfully created Info ( - "Se creó correctamente un nuevo parámetro: " + @"""" + + "Successfully created a new parameter: " + @"""" + _ParameterName + @"""" + - "\nValor predeterminado: " + @"""" + + "\nDefault value: " + @"""" + _ParameterValue + @""""); - // Busca el valor predeterminado del parámetro en las particiones M y lo reemplaza por el nombre del parámetro + // 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(); + var _ReplacementsList = new List<0>(); foreach ( var _Tables in Model.Tables ) { @@ -146,43 +146,43 @@ using (Form prompt = new Form()) { _p.Expression = _p.Expression.Replace( _Find, _Replace ); - // Lleva el control de qué particiones M se reemplazaron (y cuántas) + // Tracks which M partitions were replaced (and how many) _NrReplacements = _NrReplacements + 1; _ReplacementsList.Add( _p.Name ); } - // Cuenta el total de particiones M + // Counts the total # M Partitions _NrMPartitions = _NrMPartitions + 1; } } } - // Crea una lista con viñetas de todas las particiones M que se reemplazaron + // Makes a bulleted list of all the M partitions that were replaced string _ReplacedPartitions = " • " + String.Join("\n • ", _ReplacementsList ); - // Informa - // - Si la búsqueda y el reemplazo se realizaron correctamente - // - Cuántas particiones M se reemplazaron - // - En qué particiones M se aplicó la búsqueda y el reemplazo + // Informs + // - Whether the Find & Replace was successful + // - How many M partitions were replaced + // - Which M partitions had the Find & Replace done Info ( - "Se reemplazó correctamente\n\n " + + "Successfully replaced\n\n " + _Find + - "\n\n por: \n\n" + + "\n\n with: \n\n" + _Replace + - "\n\n en " + + "\n\n in " + Convert.ToString(_NrReplacements) + - " de " + + " of " + Convert.ToString(_NrMPartitions) + - " particiones M:\n" + + " M Partitions:\n" + _ReplacedPartitions ); } else { - Error ( "Entrada cancelada. El script finalizó sin cambios."); + Error ( "Cancelled input! Ended script without changes."); } } ``` @@ -199,6 +199,5 @@ Luego buscará el valor predeterminado en todas las particiones M y lo reemplaza
- Data Security Create Role
Figura 2: Cuadro de diálogo de confirmación que muestra que se ha creado el parámetro y que la subcadena de valor correspondiente se ha reemplazado en todas las expresiones de las particiones M. Para parámetros de otros tipos, ajusta el código C# según corresponda.
- Para parámetros de otros tipos, ajusta el código C# según corresponda. + Data Security Create Role
Figura 2: Cuadro de diálogo de confirmación que muestra que se ha creado el parámetro y que la subcadena de valor correspondiente se ha reemplazado en todas las expresiones de las particiones M. Para parámetros de otros tipos, ajusta el código C# según corresponda.
Para parámetros de otros tipos, ajusta el código C# según corresponda.
\ No newline at end of file diff --git a/localizedContent/es/content/features/CSharpScripts/Advanced/script-implement-incremental-refresh.md b/localizedContent/es/content/features/CSharpScripts/Advanced/script-implement-incremental-refresh.md index fda0e357..939c94b2 100644 --- a/localizedContent/es/content/features/CSharpScripts/Advanced/script-implement-incremental-refresh.md +++ b/localizedContent/es/content/features/CSharpScripts/Advanced/script-implement-incremental-refresh.md @@ -25,7 +25,7 @@ Para usar el script, selecciona la columna de fecha de la tabla para la que quie > Asegúrate de comprobar que se ha hecho correctamente. > > Si tienes muchos pasos, asegúrate de mover este paso a un punto en el que pueda plegarse hasta la fuente de datos. -> Asegúrate de ajustar todas las \\`#"Step References" en Power Query +> Asegúrate de ajustar todas las \`#"Step References" en Power Query > [!NOTE] > Este script usa la entrada del usuario para generar la política de actualización. diff --git a/localizedContent/es/content/features/CSharpScripts/csharp-script-library.md b/localizedContent/es/content/features/CSharpScripts/csharp-script-library.md index d9a434ff..6d321d86 100644 --- a/localizedContent/es/content/features/CSharpScripts/csharp-script-library.md +++ b/localizedContent/es/content/features/CSharpScripts/csharp-script-library.md @@ -5,7 +5,7 @@ author: Morten Lønskov updated: 2023-02-23 --- -# Biblioteca de scripts de C\\# +# Biblioteca de scripts de C\# ![Biblioteca de scripts de C#](~/content/assets/images/Cscripts/script-library-header.png) diff --git a/localizedContent/es/content/features/Command-line-Options.md b/localizedContent/es/content/features/Command-line-Options.md index fc316315..f2c08b32 100644 --- a/localizedContent/es/content/features/Command-line-Options.md +++ b/localizedContent/es/content/features/Command-line-Options.md @@ -42,63 +42,63 @@ TABULAREDITOR ( file | server database | -L [name] ) [-S script1 [script2] [...] [-P [-Y]] [-S] [-R [-M]]] [-X xmla_script]] [-W] [-E]] -file Ruta de acceso completa al archivo Model.bim o a la carpeta del modelo database.json que se va a cargar. -server Nombre de servidor\instancia o cadena de conexión desde la que se cargará el modelo -database ID de la base de datos del modelo que se va a cargar. Si se deja en blanco (""), selecciona la primera +file Ruta completa del archivo Model.bim o de la carpeta del modelo database.json que se va a cargar. +server Nombre del servidor\instancia o cadena de conexión desde la que se cargará el modelo. +database Id de la base de datos del modelo que se va a cargar. Si se deja en blanco (\"), se selecciona la primera base de datos disponible en el servidor. --L / -LOCAL Se conecta a una instancia (local) de Analysis Services de Power BI Desktop. Si no se especifica un - nombre, se supone que se está ejecutando exactamente 1 instancia. En caso contrario, +-L / -LOCAL Se conecta a una instancia (local) de Analysis Services de Power BI Desktop. Si no se + especifica ningún nombre, se asume que hay exactamente 1 instancia en ejecución. En caso contrario, el nombre debe coincidir con el nombre del archivo .pbix cargado en Power BI Desktop. -S / -SCRIPT Ejecuta el script especificado en el modelo después de cargarlo. - scriptN Ruta de acceso completa a uno o varios archivos que contienen un C# Script que se va a ejecutar o un + scriptN Ruta completa de uno o varios archivos que contienen un C# Script para ejecutar o un script en línea. --SC / -SCHEMACHECK Intenta conectarse a todos los orígenes de datos del proveedor para detectar cambios en el esquema de la tabla. - Genera... - ...advertencias para tipos de datos no coincidentes y columnas de origen no asignadas - ...errores para columnas del modelo no asignadas. +-SC / -SCHEMACHECK Intenta conectarse a todos los orígenes de datos del proveedor para detectar cambios en el esquema + de las tablas. Genera... + ...advertencias por tipos de datos no coincidentes y columnas de origen no asignadas + ...errores por columnas del modelo no asignadas. -A / -ANALYZE Ejecuta Best Practice Analyzer y muestra el resultado en la consola. - rules Ruta opcional de un archivo o una URL con reglas BPA adicionales que se van a analizar. Si se - especifica, el modelo no se analiza con reglas locales del usuario o del equipo, + rules Ruta opcional de un archivo o la URL de reglas BPA adicionales que se van a analizar. Si + se especifica, el modelo no se analiza con las reglas del usuario local ni de la máquina local, pero las reglas definidas dentro del modelo se siguen aplicando. -AX / -ANALYZEX Igual que -A / -ANALYZE, pero excluye las reglas especificadas en las anotaciones del modelo. -B / -BIM / -BUILD Guarda el modelo (después de la ejecución opcional del script) como un archivo Model.bim. - output Ruta de acceso completa del archivo Model.bim donde se guardará. - id ID/nombre opcional que se asignará al objeto Database al guardar. + output Ruta completa del archivo Model.bim donde se guardará. + id Id/nombre opcional que se asignará al objeto Database al guardar. -F / -FOLDER Guarda el modelo (después de la ejecución opcional del script) como una estructura de carpetas. - output Ruta de acceso completa de la carpeta donde se guardará. La carpeta se crea si no existe. - id ID/nombre opcional que se asignará al objeto Database al guardar. + output Ruta completa de la carpeta donde se guardará. La carpeta se crea si no existe. + id Id/nombre opcional que se asignará al objeto Database al guardar. -TMDL Guarda el modelo (después de la ejecución opcional del script) como una estructura de carpetas TMDL. - output Ruta de acceso completa de la carpeta TMDL donde se guardará. La carpeta se crea si no existe. - id ID/nombre opcional que se asignará al objeto Database al guardar. + output Ruta completa de la carpeta TMDL donde se guardará. La carpeta se crea si no existe. + id Id/nombre opcional que se asignará al objeto Database al guardar. -V / -VSTS Genera comandos de registro de Visual Studio Team Services. --G / -GITHUB Genera comandos de flujo de trabajo de GitHub Actions. --T / -TRX Genera un archivo VSTEST (trx) con detalles sobre la ejecución. - resultsfile Nombre de archivo del XML de VSTEST. --D / -DEPLOY Implementación desde la línea de comandos +-G / -GITHUB Genera comandos de flujo de trabajo para GitHub Actions. +-T / -TRX Genera un archivo VSTEST (trx) con detalles de la ejecución. + resultsfile Nombre del archivo XML de VSTEST. +-D / -DEPLOY Despliegue desde la línea de comandos Si no se especifican parámetros adicionales, este modificador guardará los metadatos del modelo de nuevo en el origen (archivo o base de datos). - server Nombre del servidor en el que implementar o cadena de conexión a Analysis Services. - database ID de la base de datos que se va a implementar (crear/sobrescribir). - -L / -LOGIN Deshabilita la seguridad integrada al conectarse al servidor. Especifica: - user Nombre de usuario (debe ser un usuario con permisos de administrador en el servidor) + server Nombre del servidor donde se realizará el despliegue o cadena de conexión a Analysis Services. + database Id de la base de datos que se va a desplegar (crear/sobrescribir). + -L / -LOGIN Desactiva la seguridad integrada al conectarse al servidor. Especifica: + user Nombre de usuario (debe ser un usuario con derechos de administrador en el servidor) pass Contraseña - -F / -FULL Implementa todos los metadatos del modelo, permitiendo sobrescribir una base de datos existente. - -O / -OVERWRITE Permite implementar (sobrescribir) una base de datos existente. - -C / -CONNECTIONS Implementa (sobrescribe) los Data source existentes en el modelo. Después del modificador -C, puedes - (opcionalmente) especificar cualquier número de pares marcador de posición-valor. Al hacerlo, + -F / -FULL Despliega todos los metadatos del modelo, permitiendo sobrescribir una base de datos existente. + -O / -OVERWRITE Permite desplegar (sobrescribir) una base de datos existente. + -C / -CONNECTIONS Despliega (sobrescribe) los Data sources existentes en el modelo. Después del modificador -C, + puedes especificar, opcionalmente, cualquier cantidad de pares marcador de posición/valor. Al hacerlo, se reemplazará cualquier aparición de los marcadores de posición especificados (plch1, plch2, ...) en las cadenas de conexión de cada Data source del modelo por los valores especificados (value1, value2, ...). - -P / -PARTITIONS Implementa (sobrescribe) las particiones de tabla existentes del modelo. - -Y / -SKIPPOLICY No sobrescribe particiones que tengan definidas políticas de actualización incremental. - -S / -SHARED Implementa (sobrescribe) expresiones compartidas. - -R / -ROLES Implementa roles. - -M / -MEMBERS Implementa miembros del rol. - -X / -XMLA Sin implementación. En su lugar, genera un script XMLA/TMSL para una implementación posterior. - xmla_script Nombre de archivo del nuevo script de salida XMLA/TMSL. - -W / -WARN Muestra, como advertencias, información sobre objetos no procesados. - -E / -ERR Devuelve un código de salida distinto de cero si Analysis Services devuelve algunos mensajes de error después de que - los metadatos se hayan implementado/actualizado. + -P / -PARTITIONS Despliega (sobrescribe) las particiones de tabla existentes en el modelo. + -Y / -SKIPPOLICY No sobrescribe las particiones que tengan definidas políticas de actualización incremental. + -S / -SHARED Despliega (sobrescribe) expresiones compartidas. + -R / -ROLES Despliega roles. + -M / -MEMBERS Despliega miembros del rol. + -X / -XMLA No realiza ningún despliegue. En su lugar, genera un script XMLA/TMSL para desplegarlo más tarde. + xmla_script Nombre del archivo de salida del nuevo script XMLA/TMSL. + -W / -WARN Muestra información sobre objetos sin procesar en forma de advertencias. + -E / -ERR Devuelve un código de salida distinto de cero si Analysis Services devuelve mensajes de error después de que + se hayan desplegado o actualizado los metadatos. ``` > [!WARNING] @@ -164,8 +164,8 @@ Durante el despliegue, quieres modificar la cadena para que apunte a una base de Coloca el siguiente script en un archivo llamado "ClearConnectionStrings.cs" o similar: ```csharp -// Esto reemplazará la cadena de conexión de todos los orígenes de datos de proveedor (heredados) del modelo -// por un marcador de posición basado en el nombre del origen de datos. Por ejemplo, si tu origen de datos se llama +// Esto reemplazará la cadena de conexión de todos los orígenes de datos del proveedor (heredados) del modelo +// por un marcador de posición basado en el nombre del Data source. Por ejemplo, si tu Data source se llama // "SQLDW", la cadena de conexión después de ejecutar este script sería "SQLDW": foreach(var ds in Model.DataSources.OfType()) @@ -241,7 +241,7 @@ variables: steps: - script: TabularEditor.exe "Model.bim" -S "UpdateModel.csx" -D "$(serverName)" "MyDatabase" -O -V -E -W - displayName: 'Deploy with Script Parameters' + displayName: 'Despliegue con parámetros de script' env: DEPLOY_ENV: $(deployEnv) SERVER_NAME: $(serverName) @@ -251,7 +251,7 @@ steps: ```yaml - task: PowerShell@2 - displayName: 'Run Tabular Editor Script' + displayName: 'Ejecutar script de Tabular Editor' env: DEPLOY_ENV: 'UAT' CONNECTION_STRING: $(sqldwConnectionString) @@ -269,9 +269,9 @@ steps: var deployEnv = Environment.GetEnvironmentVariable("DEPLOY_ENV"); var serverName = Environment.GetEnvironmentVariable("SERVER_NAME"); -Info($"Configuring model for {deployEnv} environment on {serverName}"); +Info($"Configurando el modelo para el entorno {deployEnv} en {serverName}"); -// Apply environment-specific changes +// Aplicar cambios específicos del entorno foreach(var ds in Model.DataSources.OfType()) { ds.ConnectionString = ds.ConnectionString.Replace("{SERVER}", serverName); @@ -316,9 +316,9 @@ La línea de comandos proporciona varios detalles, en función de los parámetro | Error | -ANALYZE | No se encontró el archivo de reglas: ... | | | Error | -ANALYZE | Archivo de reglas no válido: ... | El archivo de reglas de BPA especificado está dañado o no contiene un JSON válido. | | Información | -ANALYZE | ... viola la regla ... | Resultados del Best Practice Analyzer para reglas con un nivel de gravedad de 1 o inferior. | -| Advertencia | -ANALYZE | ... ¡La implementación falló! | Resultados del Best Practice Analyzer para reglas con un nivel de gravedad de 2. | +| Advertencia | -ANALYZE | ... viola la regla ... | Resultados del Best Practice Analyzer para reglas con un nivel de gravedad de 2. | | Error | -ANALYZE | ... viola la regla ... | Resultados del Best Practice Analyzer para reglas con un nivel de gravedad de 3 o superior. | -| Error | -DEPLOY | viola la regla ... ... | Motivo del fallo devuelto directamente por la instancia de Analysis Service (por ejemplo: base de datos no encontrada, no se permite sobrescribir la base de datos, etc.) | +| Error | -DEPLOY | ¡La implementación falló! ... | Motivo del fallo devuelto directamente por la instancia de Analysis Service (por ejemplo: base de datos no encontrada, no se permite sobrescribir la base de datos, etc.) | | Información | -DEPLOY | Objeto sin procesar: ... | Objetos que están en el estado "NoData" o "CalculationNeeded" tras una implementación correcta. Utilice el modificador -W para tratarlos como Nivel=Advertencia. | | Advertencia | -DEPLOY | El objeto no está en estado "Ready": ... | Objetos que se encuentran en estado "DependencyError", "EvaluationError" o "SemanticError" después de un despliegue correcto. Si usa la opción -W, también incluye los objetos en estado "NoData" o "CalculationNeeded". | | Advertencia | -DEPLOY | Error en X:... | Objetos que contienen DAX no válido después de un despliegue correcto (medidas, columnas calculadas, tablas calculadas, roles). Use la opción -E para tratarlos como Level=Error. | diff --git a/localizedContent/es/content/features/Useful-script-snippets.md b/localizedContent/es/content/features/Useful-script-snippets.md index e9f4ef4b..a6fb8d61 100644 --- a/localizedContent/es/content/features/Useful-script-snippets.md +++ b/localizedContent/es/content/features/Useful-script-snippets.md @@ -27,22 +27,22 @@ Además, asegúrate de echar un vistazo a nuestra biblioteca de scripts @csharp- ## Crear medidas a partir de columnas ```csharp -// Crea una medida SUM para cada columna seleccionada actualmente y oculta la columna. +// Creates a SUM measure for every currently selected column and hide the column. foreach(var c in Selected.Columns) { var newMeasure = c.Table.AddMeasure( - "Suma de " + c.Name, // Nombre - "SUM(" + c.DaxObjectFullName + ")", // Expresión DAX - c.DisplayFolder // Carpeta de visualización + "Sum of " + c.Name, // Name + "SUM(" + c.DaxObjectFullName + ")", // DAX expression + c.DisplayFolder // Display Folder ); - // Establece la cadena de formato en la nueva medida: + // Set the format string on the new measure: newMeasure.FormatString = "0.00"; - // Añade algo de documentación: - newMeasure.Description = "Esta medida es la suma de la columna " + c.DaxObjectFullName; + // Provide some documentation: + newMeasure.Description = "This measure is the sum of column " + c.DaxObjectFullName; - // Oculta la columna base: + // Hide the base column: c.IsHidden = true; } ``` @@ -56,12 +56,12 @@ Este fragmento usa la función `.AddMeasure(, , " -S "" -B "" +start /wait TabularEditor.exe "<0>" -S "<1>" -B "<2>" ``` por ejemplo: @@ -701,7 +701,7 @@ foreach(var col in aggTable.Columns) Después de ejecutar el script, deberías ver que la propiedad `AlternateOf` se ha asignado a todas las columnas de tu tabla de agregación (consulta la captura de pantalla a continuación). Ten en cuenta que la partición de la tabla base debe usar DirectQuery para que las agregaciones funcionen. -![image](https://user-images.githubusercontent.com/8976200/85851134-6ed70800-b7ae-11ea-82eb-37fcaa2ca9c4.png) +![imagen](https://user-images.githubusercontent.com/8976200/85851134-6ed70800-b7ae-11ea-82eb-37fcaa2ca9c4.png) *** @@ -715,7 +715,7 @@ Están disponibles los siguientes métodos: | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `void ExecuteCommand(string tmslOrXmla, bool isXmla = false)` | Este método envía el script TMSL o XMLA especificado a la instancia conectada de Analysis Services. Esto resulta útil cuando desea actualizar datos de una tabla en la instancia de AS. Tenga en cuenta que, si utiliza este método para realizar cambios de metadatos en su modelo, los metadatos del modelo local quedarán desincronizados respecto a los metadatos de la instancia de AS, y es posible que reciba una advertencia de conflicto de versiones la próxima vez que intente guardar los metadatos del modelo. Establezca el parámetro `isXmla` en `true` si envía un script XMLA. | | `IDataReader ExecuteReader(string dax)` | Ejecuta la _consulta_ DAX especificada contra la base de datos de AS conectada y devuelve el objeto [AmoDataReader](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.amodatareader?view=analysisservices-dotnet) resultante. Una consulta DAX contiene una o varias instrucciones [`EVALUATE`](https://dax.guide/EVALUATE). Tenga en cuenta que no puede tener varios lectores de datos abiertos al mismo tiempo. Tabular Editor los cerrará automáticamente en caso de que olvide cerrar o liberar el lector de forma explícita. | -| `DataSet ExecuteDax(string dax)` | Ejecuta la _consulta_ DAX especificada contra la base de datos de AS conectada y devuelve un objeto [Dataset](https://docs.microsoft.com/en-us/dotnet/api/system.data.dataset?view=netframework-4.6) que contiene los datos devueltos por la consulta. Una consulta DAX contiene una o varias instrucciones [`EVALUATE`](https://dax.guide/EVALUATE). El objeto Dataset resultante contiene una DataTable por cada instrucción `EVALUATE`. No se recomienda devolver tablas de datos muy grandes, ya que pueden provocar errores de falta de memoria u otros errores de estabilidad. | +| `Dataset ExecuteDax(string dax)` | Ejecuta la _consulta_ DAX especificada contra la base de datos de AS conectada y devuelve un objeto [Dataset](https://docs.microsoft.com/en-us/dotnet/api/system.data.dataset?view=netframework-4.6) que contiene los datos devueltos por la consulta. Una consulta DAX contiene una o varias instrucciones [`EVALUATE`](https://dax.guide/EVALUATE). El objeto Dataset resultante contiene una DataTable por cada instrucción `EVALUATE`. No se recomienda devolver tablas de datos muy grandes, ya que pueden provocar errores de falta de memoria u otros errores de estabilidad. | | `object EvaluateDax(string dax)` | Ejecuta la _expresión_ DAX especificada contra la base de datos de AS conectada y devuelve un objeto que representa el resultado. Si la expresión DAX es escalar, se devuelve un objeto del tipo correspondiente (string, long, decimal, double, DateTime). Si la expresión DAX es de tipo tabla, se devuelve un [DataTable](https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable?view=netframework-4.6). | Los métodos están acotados al objeto `Model.Database`, pero también se pueden ejecutar directamente sin ningún prefijo. @@ -741,11 +741,11 @@ ExecuteCommand(tmsl); A partir de Tabular Editor 2.16.6 o Tabular Editor 3.2.3, puede usar la siguiente sintaxis para enviar comandos XMLA sin procesar a Analysis Services. El siguiente ejemplo muestra cómo se puede usar para vaciar la caché del motor de AS: ```csharp -var clearCacheXmla = string.Format(@" - - {0} - -", Model.Database.ID); +var clearCacheXmla = string.Format(@"<0> + <1> + <2>{0} + +", Model.Database.ID); ExecuteCommand(clearCacheXmla, isXmla: true); ``` @@ -760,7 +760,7 @@ 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) +![imagen](https://user-images.githubusercontent.com/8976200/91638299-bbd59580-ea0e-11ea-882b-55bff73c30fb.png) ...o, si desea devolver el valor de la medida seleccionada actualmente: @@ -768,7 +768,7 @@ EvaluateDax("{ (1, 2, 3) }").Output(); // A table EvaluateDax(Selected.Measure.DaxObjectFullName).Output(); ``` -![image](https://user-images.githubusercontent.com/8976200/91638367-6f3e8a00-ea0f-11ea-90cd-7d2e4cff6e31.png) +![imagen](https://user-images.githubusercontent.com/8976200/91638367-6f3e8a00-ea0f-11ea-90cd-7d2e4cff6e31.png) Y aquí tiene un ejemplo más avanzado que permite seleccionar y evaluar varias medidas a la vez: @@ -777,7 +777,7 @@ var dax = "ROW(" + string.Join(",", Selected.Measures.Select(m => "\"" + m.Name EvaluateDax(dax).Output(); ``` -![image](https://user-images.githubusercontent.com/8976200/91638356-546c1580-ea0f-11ea-8302-3e40829e00dd.png) +![imagen](https://user-images.githubusercontent.com/8976200/91638356-546c1580-ea0f-11ea-8302-3e40829e00dd.png) Si ya está en un nivel avanzado, puede usar SUMMARIZECOLUMNS u otra función DAX para visualizar la medida seleccionada desglosada por alguna columna: @@ -786,11 +786,11 @@ var dax = "SUMMARIZECOLUMNS('Product'[Color], " + string.Join(",", Selected.Meas EvaluateDax(dax).Output(); ``` -![image](https://user-images.githubusercontent.com/8976200/91638389-9b5a0b00-ea0f-11ea-819f-d3eee3ddfa71.png) +![imagen](https://user-images.githubusercontent.com/8976200/91638389-9b5a0b00-ea0f-11ea-819f-d3eee3ddfa71.png) Recuerde que puede guardar estos scripts como Acciones personalizadas haciendo clic en el icono "+" justo encima del editor de scripts. De este modo, obtienes una colección de consultas DAX fácilmente reutilizable que puedes ejecutar y visualizar directamente desde el menú contextual de Tabular Editor: -![image](https://user-images.githubusercontent.com/8976200/91638790-305e0380-ea12-11ea-9d84-313f4388496f.png) +![imagen](https://user-images.githubusercontent.com/8976200/91638790-305e0380-ea12-11ea-9d84-313f4388496f.png) ### Exportación de datos diff --git a/localizedContent/es/content/features/code-actions.md b/localizedContent/es/content/features/code-actions.md index 25e50eee..25bfa782 100644 --- a/localizedContent/es/content/features/code-actions.md +++ b/localizedContent/es/content/features/code-actions.md @@ -107,22 +107,22 @@ Las acciones de código siguientes aparecerán con puntos naranjas debajo de los Las acciones de código siguientes aparecerán con puntos verde azulado debajo de los dos primeros caracteres del código correspondiente y con un icono de destornillador en el margen izquierdo cuando el cursor se sitúe sobre uno de los segmentos de código -| ID | Nombre | Descripción | | | | | | | -| ----- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | ---------------------------------------------------------------------------------------------- | - | ----- | - | --------------------------------- | -| DR001 | [Convertir a predicado escalar](xref:DR001) | Un filtro de columna puede escribirse de forma más concisa como un predicado escalar sin usar explícitamente la función [`FILTER`](https://dax.guide/FILTER). Ejemplos:
`FILTER(ALL(Products[Color]), Products[Color] = "Red")` -> `Products[Color] = "Red"`
`FILTER(VALUES(Products[Color]), Products[Color] = "Red")` -> `KEEPFILTERS(Products[Color] = "Red")` | | | | | | | -| DR002 | [Usar una función de agregación en lugar de una función iteradora](xref:DR002) | Use una función de agregación en lugar de una función iteradora, cuando sea posible, para simplificar el código. Ejemplo:
`SUMX(Products, Products[SalesAmount])` -> `SUM(Products[SalesAmount])` | | | | | | | -| DR003 | [Usar VALUES en lugar de SUMMARIZE](xref:DR003) | Cuando [`SUMMARIZE`](https://dax.guide/SUMMARIZE) especifica solo una columna y esa columna pertenece a la tabla indicada en el primer argumento, el código puede escribirse de forma más concisa mediante [`VALUES`](https://dax.guide/VALUES). Ejemplo:
`SUMMARIZE(Products, Products[Color])` -> `VALUES(Products[Color])` | | | | | | | -| DR004 | [Añadir prefijo a la variable](xref:DR004) | Las variables deben seguir una convención de nomenclatura coherente. Se recomienda usar un prefijo, como un guion bajo. Puede configurar qué prefijo usar para que coincida con el estilo que prefiera. Ejemplo:
`VAR totalSales = SUM(Sales[SalesAmount])` -> `VAR _totalSales = SUM(Sales[SalesAmount])` | | | | | | | -| DR005 | [Añadir prefijo a las columnas temporales](xref:DR005) | Se recomienda usar un prefijo uniforme para las columnas temporales para distinguirlas más fácilmente de las columnas base o las medidas. Puede configurar qué prefijo usar para que se ajuste a su estilo preferido. Ejemplo:
`ADDCOLUMNS(Product, "SalesByProd", [Sales])` -> `ADDCOLUMNS(Product, "@SalesByProd", [Sales])` | | | | | | | -| DR006 | [Mover la agregación constante a una variable](xref:DR006) | Cuando se usa una función de agregación dentro de un iterador o un predicado escalar, la agregación produce el mismo resultado para cada fila de la iteración. Por tanto, la agregación se podría mover a una variable de DAX fuera de la iteración. Ejemplo:
`CALCULATE(..., 'Date'[Date] = MAX('Date'[Date]))` ->
`VAR _maxDate = MAX('Date'[Date]) RETURN CALCULATE(..., 'Date'[Date] = _maxDate)` | | | | | | | -| DR007 | [Simplificar un bloque de 1 variable](xref:DR007) | Un bloque de variables con una sola variable puede simplificarse moviendo la expresión directamente a la parte `RETURN` del bloque. Esto supone que la variable solo se referencia una vez y sin modificadores de contexto. Ejemplo:
`VAR _result = [Sales] * 1.25 RETURN _result` -> `[Sales] * 1.25` | | | | | | | -| DR008 | [Simplificar un bloque de varias variables](xref:DR008) | Un bloque de variables con varias variables en el que cada una sea una referencia simple a una medida y solo se use una vez en la sección `RETURN`, sin modificadores de contexto, debe simplificarse. Ejemplo:
`VAR _sales = [Sales] VAR _cost = [Cost] RETURN _sales - _cost` -> `[Sales] - [Cost]` | | | | | | | -| DR009 | [Reescribir usando DISTINCTCOUNT](xref:DR009) | En lugar de usar `COUNTROWS(DISTINCT(T[c])` para contar el número de valores distintos de una columna, usa la función [`DISTINCTCOUNT`](https://dax.guide/DISTINCTCOUNT). | | | | | | | -| DR010 | [Reescribir usando COALESCE](xref:DR010) | En lugar de usar `IF` para devolver el primer valor no en blanco de una lista de expresiones, usa la función [`COALESCE`](https://dax.guide/COALESCE). Ejemplo:
`IF(ISBLANK([Sales]), [Sales2], [Sales])` -> `COALESCE([Sales], [Sales2])` | | | | | | | -| DR011 | [Reescribir con ISBLANK](xref:DR011) | En lugar de comparar una expresión con [`BLANK()`](https://dax.guide/BLANK), usa la función [`ISBLANK`](https://dax.guide/ISBLANK). Ejemplo:
`IF([Sales] = BLANK(), [Budget], [Sales])` -> `IF(ISBLANK([Sales], [Budget], [Sales])` | | | | | | | -| DR012 | [Eliminar BLANK innecesario](xref:DR012) | Algunas funciones de DAX, como [`IF`](https://dax.guide/IF) y [`SWITCH`](https://dax.guide/SWITCH), ya devuelven `BLANK()` cuando la condición es falsa, así que no hace falta especificar `BLANK()` explícitamente. Ejemplo:
`IF(a > b, a, BLANK())` -> `IF(a > b, a)` | | | | | | | -| DR013 | [Simplificar la lógica negada](xref:DR013) | Cuando se niega una expresión lógica, suele ser más legible reescribirla usando el operador negado. Ejemplo:
`NOT(a = b)` -> `a <> b` | | | | | | | -| DR014 | [Simplificar con IN](xref:DR014) | Reescribe los predicados compuestos (comparaciones de igualdad de la misma expresión combinadas con [`OR`](https://dax.guide/OR) o [\\` | | `](https://dax.guide/op/or/)) con el operador [`IN`](https://dax.guide/IN). Ejemplo:
`a = 1 | | a = 2 | | a = 100`->`a IN { 1, 2, 100 }\\` | +| ID | Nombre | Descripción | | | | | | | +| ----- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | ---------------------------------------------------------------------------------------------- | - | ----- | - | ----------------------------------- | +| DR001 | [Convertir a predicado escalar](xref:DR001) | Un filtro de columna puede escribirse de forma más concisa como un predicado escalar sin usar explícitamente la función [`FILTER`](https://dax.guide/FILTER). Ejemplos:
`FILTER(ALL(Products[Color]), Products[Color] = "Red")` -> `Products[Color] = "Red"`
`FILTER(VALUES(Products[Color]), Products[Color] = "Red")` -> `KEEPFILTERS(Products[Color] = "Red")` | | | | | | | +| DR002 | [Usar una función de agregación en lugar de una función iteradora](xref:DR002) | Use una función de agregación en lugar de una función iteradora, cuando sea posible, para simplificar el código. Ejemplo:
`SUMX(Products, Products[SalesAmount])` -> `SUM(Products[SalesAmount])` | | | | | | | +| DR003 | [Usar VALUES en lugar de SUMMARIZE](xref:DR003) | Cuando [`SUMMARIZE`](https://dax.guide/SUMMARIZE) especifica solo una columna y esa columna pertenece a la tabla indicada en el primer argumento, el código puede escribirse de forma más concisa mediante [`VALUES`](https://dax.guide/VALUES). Ejemplo:
`SUMMARIZE(Products, Products[Color])` -> `VALUES(Products[Color])` | | | | | | | +| DR004 | [Añadir prefijo a la variable](xref:DR004) | Las variables deben seguir una convención de nomenclatura coherente. Se recomienda usar un prefijo, como un guion bajo. Puede configurar qué prefijo usar para que coincida con el estilo que prefiera. Ejemplo:
`VAR totalSales = SUM(Sales[SalesAmount])` -> `VAR _totalSales = SUM(Sales[SalesAmount])` | | | | | | | +| DR005 | [Añadir prefijo a las columnas temporales](xref:DR005) | Se recomienda usar un prefijo uniforme para las columnas temporales para distinguirlas más fácilmente de las columnas base o las medidas. Puede configurar qué prefijo usar para que se ajuste a su estilo preferido. Ejemplo:
`ADDCOLUMNS(Product, "SalesByProd", [Sales])` -> `ADDCOLUMNS(Product, "@SalesByProd", [Sales])` | | | | | | | +| DR006 | [Mover la agregación constante a una variable](xref:DR006) | Cuando se usa una función de agregación dentro de un iterador o un predicado escalar, la agregación produce el mismo resultado para cada fila de la iteración. Por tanto, la agregación se podría mover a una variable de DAX fuera de la iteración. Ejemplo:
`CALCULATE(..., 'Date'[Date] = MAX('Date'[Date]))` ->
`VAR _maxDate = MAX('Date'[Date]) RETURN CALCULATE(..., 'Date'[Date] = _maxDate)` | | | | | | | +| DR007 | [Simplificar un bloque de 1 variable](xref:DR007) | Un bloque de variables con una sola variable puede simplificarse moviendo la expresión directamente a la parte `RETURN` del bloque. Esto supone que la variable solo se referencia una vez y sin modificadores de contexto. Ejemplo:
`VAR _result = [Sales] * 1.25 RETURN _result` -> `[Sales] * 1.25` | | | | | | | +| DR008 | [Simplificar un bloque de varias variables](xref:DR008) | Un bloque de variables con varias variables en el que cada una sea una referencia simple a una medida y solo se use una vez en la sección `RETURN`, sin modificadores de contexto, debe simplificarse. Ejemplo:
`VAR _sales = [Sales] VAR _cost = [Cost] RETURN _sales - _cost` -> `[Sales] - [Cost]` | | | | | | | +| DR009 | [Reescribir usando DISTINCTCOUNT](xref:DR009) | En lugar de usar `COUNTROWS(DISTINCT(T[c])` para contar el número de valores distintos de una columna, usa la función [`DISTINCTCOUNT`](https://dax.guide/DISTINCTCOUNT). | | | | | | | +| DR010 | [Reescribir usando COALESCE](xref:DR010) | En lugar de usar `IF` para devolver el primer valor no en blanco de una lista de expresiones, usa la función [`COALESCE`](https://dax.guide/COALESCE). Ejemplo:
`IF(ISBLANK([Sales]), [Sales2], [Sales])` -> `COALESCE([Sales], [Sales2])` | | | | | | | +| DR011 | [Reescribir con ISBLANK](xref:DR011) | En lugar de comparar una expresión con [`BLANK()`](https://dax.guide/BLANK), usa la función [`ISBLANK`](https://dax.guide/ISBLANK). Ejemplo:
`IF([Sales] = BLANK(), [Budget], [Sales])` -> `IF(ISBLANK([Sales], [Budget], [Sales])` | | | | | | | +| DR012 | [Eliminar BLANK innecesario](xref:DR012) | Algunas funciones de DAX, como [`IF`](https://dax.guide/IF) y [`SWITCH`](https://dax.guide/SWITCH), ya devuelven `BLANK()` cuando la condición es falsa, así que no hace falta especificar `BLANK()` explícitamente. Ejemplo:
`IF(a > b, a, BLANK())` -> `IF(a > b, a)` | | | | | | | +| DR013 | [Simplificar la lógica negada](xref:DR013) | Cuando se niega una expresión lógica, suele ser más legible reescribirla usando el operador negado. Ejemplo:
`NOT(a = b)` -> `a <> b` | | | | | | | +| DR014 | [Simplificar con IN](xref:DR014) | Reescribe los predicados compuestos (comparaciones de igualdad de la misma expresión combinadas con [`OR`](https://dax.guide/OR) o [\` | | `](https://dax.guide/op/or/)) con el operador [`IN`](https://dax.guide/IN). Ejemplo:
`a = 1 | | a = 2 | | a = 100`->`a IN { 1, 2, 100 }\\\` | ### Reescrituras diff --git a/localizedContent/es/content/features/dax-editor.md b/localizedContent/es/content/features/dax-editor.md index 959e1cb3..9274e9c5 100644 --- a/localizedContent/es/content/features/dax-editor.md +++ b/localizedContent/es/content/features/dax-editor.md @@ -43,11 +43,11 @@ Estas funciones también se pueden activar desde el menú contextual del editor. Los calltips de DAX se actualizan al alternar entre las opciones de sintaxis con las flechas Arriba/Abajo. -![Dax Code Assist](~/content/assets/images/dax-code-assist.png) +![Code Assist de Dax](~/content/assets/images/dax-code-assist.png) La mayoría de los aspectos de Code Assist se pueden configurar en [**Herramientas > Preferencias > Editores de texto > Editor de DAX > Code Assist**](xref:preferences#dax-editor--code-assist). -## Ver la definición +## Ver definición Con el cursor sobre una referencia a un objeto, como una variable o una referencia a una medida, pulsa [Alt+F12] para mostrar un editor en línea con la definición de ese objeto, debajo del cursor. Esto resulta útil cuando desea ver el código DAX de un objeto al que se hace referencia sin salir de la posición actual del documento. diff --git a/localizedContent/es/content/features/perspective-editor.md b/localizedContent/es/content/features/perspective-editor.md index 83d20e34..69aa18b4 100644 --- a/localizedContent/es/content/features/perspective-editor.md +++ b/localizedContent/es/content/features/perspective-editor.md @@ -1,6 +1,6 @@ --- uid: perspective-editor -title: Editor de perspectiva +title: Editor de perspectivas author: Šarūnas Jučius updated: 2022-03-16 applies_to: @@ -17,27 +17,27 @@ applies_to: full: true --- -# Editor de perspectiva +# Editor de perspectivas > [!NOTE] -> Para poder agregar perspectivas a modelos que se ejecutan en SSAS o Azure AS, necesitarás una licencia de la edición Enterprise de Tabular Editor 3. +> Para agregar perspectivas a modelos que se ejecuten en SSAS o Azure AS, necesitarás una licencia de la Edición Enterprise de Tabular Editor 3. -El **Editor de perspectiva** ofrece una vista rápida de la asignación de perspectivas de los objetos del modelo (tablas, columnas, jerarquías y medidas). Puede abrir el Editor de perspectiva desde el menú **Ver**. Como alternativa, si solo necesita editar ciertas perspectivas, selecciónelas en el **Explorador TOM** (mantenga pulsadas las teclas CTRL o SHIFT para seleccionar varias) y, a continuación, haga clic con el botón derecho y elija **Mostrar en el Editor de perspectiva**. +El **Editor de perspectivas** ofrece una vista rápida de la asignación de perspectivas a los objetos del modelo (tablas, columnas, jerarquías y medidas). Puedes abrir el Editor de perspectiva desde el menú **Ver**. Como alternativa, si solo necesitas editar ciertas perspectivas, selecciónalas en el **Explorador TOM** (mantén pulsadas las teclas CTRL o SHIFT para seleccionar varias) y, a continuación, haz clic con el botón derecho y elige **Mostrar en el Editor de perspectiva**. -![Editor de perspectiva](~/content/assets/images/perspective-editor.png) +![Editor de perspectivas](~/content/assets/images/perspective-editor.png) -Utilice las casillas de verificación del Editor de perspectiva para agregar o quitar rápidamente varios objetos de una perspectiva. Puede usar Deshacer (Ctrl+Z) y Rehacer (Ctrl+Y) de la forma habitual. Tenga en cuenta que los cambios realizados a través del Editor de perspectiva se aplican inmediatamente al TOM, aunque aún deberá guardar (Ctrl+S) o implementar su modelo para que los cambios se apliquen en Analysis Services / Power BI. +Usa las casillas de verificación del Editor de perspectiva para agregar o quitar rápidamente varios objetos de una perspectiva. Puedes usar Deshacer (Ctrl+Z) y Rehacer (Ctrl+Y) de la forma habitual. Ten en cuenta que los cambios realizados a través del Editor de perspectiva se aplican de inmediato al TOM, aunque aún tendrás que guardar (Ctrl+S) o implementar el modelo para que los cambios se reflejen en Analysis Services / Power BI. -## Barra de herramientas del Editor de perspectiva +## Barra de herramientas del Editor de perspectivas -Mientras el Editor de perspectiva está activo, la barra de herramientas que lo acompaña ofrece las siguientes opciones: +Mientras el Editor de perspectivas está activo, la barra de herramientas que lo acompaña ofrece las siguientes opciones: -- ![Perspective Editor Add Perspective](~/content/assets/images/perspective-editor-add-perspective.png) **Nueva perspectiva**: Este botón agrega una nueva perspectiva al modelo. La perspectiva se mostrará en el Editor de perspectiva. -- ![Perspective Editor Hide Members](~/content/assets/images/perspective-editor-hide-members.png) **Mostrar/ocultar opciones ocultas**: Active esta opción si desea ver todos los objetos en el Editor de perspectiva, incluidos los objetos ocultos. -- ![Perspective Editor Folder](~/content/assets/images/perspective-editor-folder.png) **Mostrar/ocultar carpetas de visualización**: Active este botón de conmutación si desea que el Editor de perspectiva agrupe los objetos de las tablas (medidas, jerarquías, columnas) por carpetas de visualización. +- ![Editor de perspectiva: Agregar perspectiva](~/content/assets/images/perspective-editor-add-perspective.png) **Nueva perspectiva**: Este botón agrega una nueva perspectiva al modelo. La perspectiva se mostrará en el Editor de perspectivas. +- ![Editor de perspectiva: Mostrar u ocultar opciones ocultas](~/content/assets/images/perspective-editor-hide-members.png) **Mostrar/ocultar opciones ocultas**: Activa esta opción si quieres ver todos los objetos en el Editor de perspectiva, incluidos los objetos ocultos. +- ![Editor de perspectiva: Carpetas de visualización](~/content/assets/images/perspective-editor-folder.png) **Mostrar/ocultar carpetas de visualización**: Activa este botón de alternancia si quieres que el Editor de perspectiva agrupe los objetos de las tablas (medidas, jerarquías, columnas) por carpetas de visualización. ## Trabajar con varias perspectivas -Si trabajas en un modelo con muchas perspectivas, puede que no sea práctico mostrarlas todas a la vez. Puedes reorganizar el orden de visualización de las perspectivas en el Editor de perspectivas arrastrando los encabezados de las columnas, lo que facilita comparar perspectivas una junto a otra. Además, puedes añadir o quitar perspectivas del editor en cualquier momento desde el menú contextual con clic derecho: +Si estás trabajando en un modelo con muchas perspectivas, puede resultar poco práctico mostrarlas todas a la vez. Puedes reorganizar el orden de visualización de las perspectivas en el Editor de perspectivas arrastrando los encabezados de las columnas; así, será más fácil comparar las perspectivas una junto a otra. Además, puedes añadir o quitar perspectivas del editor en cualquier momento desde el menú contextual al hacer clic con el botón derecho: -![Columnas del Editor de perspectivas](~/content/assets/images/perspective-editor-columns.png) \ No newline at end of file +![Columnas en el Editor de perspectivas](~/content/assets/images/perspective-editor-columns.png) \ No newline at end of file diff --git a/localizedContent/es/content/features/semantic-bridge.md b/localizedContent/es/content/features/semantic-bridge.md index 26cea134..361d41b2 100644 --- a/localizedContent/es/content/features/semantic-bridge.md +++ b/localizedContent/es/content/features/semantic-bridge.md @@ -167,7 +167,7 @@ Las Metric Views proporcionan una capa estructurada sobre expresiones SQL, por l El MVP no se conecta a ninguna plataforma aparte de Tabular, sino que funciona completamente con archivos locales. Debe crear su YAML de Metric View por su cuenta y luego colocarlo donde Tabular Editor pueda verlo. -### API de C\\# +### API de C\# La interfaz de C# se ha diseñado para optimizar el flujo de trabajo de traducción automática. Por ello, hay pocas opciones para interactuar con la Metric View cargada actualmente, y ciertos tipos de operaciones resultan torpes. diff --git a/localizedContent/es/content/features/using-bpa.md b/localizedContent/es/content/features/using-bpa.md index 684704ab..d48ade93 100644 --- a/localizedContent/es/content/features/using-bpa.md +++ b/localizedContent/es/content/features/using-bpa.md @@ -28,11 +28,11 @@ El Best Practice Analyzer (BPA) le permite definir reglas sobre los metadatos de La descripción general de BPA le muestra todas las reglas definidas en su modelo que actualmente se están incumpliendo: -![BPA Overview](~/content/assets/images/common/BPAOverview.png) +![Descripción general de BPA](~/content/assets/images/common/BPAOverview.png) Y siempre podrá ver en la interfaz principal cuántas reglas está infringiendo actualmente. -![BPA Overview Line](~/content/assets/images/common/PBAOverviewMenuLine.png) +![Línea de descripción general de BPA](~/content/assets/images/common/PBAOverviewMenuLine.png) Al hacer clic en el enlace (o pulsar F10) se abre la ventana completa de BPA. @@ -60,8 +60,8 @@ La ventana del Best Practice Analyzer enumera continuamente todas las **reglas e Si necesitas agregar, quitar o modificar las reglas que se aplican a tu modelo, hay una interfaz específica para ello. Puedes abrirla haciendo clic en el botón de la esquina superior izquierda de la ventana de Best Practice Analyzer, o usando la opción de menú "Herramientas > Administrar reglas de BPA..." en la ventana principal. -![BPA Manage Rules](~/content/assets/images/common/BPAOverviewManageRules.png) +![Administrar reglas de BPA](~/content/assets/images/common/BPAOverviewManageRules.png) La ventana Administrar reglas de BPA contiene dos listas: la lista superior representa las **colecciones** de reglas que están cargadas actualmente. Al seleccionar una colección en esta lista, se mostrarán todas las reglas definidas dentro de esa colección en la lista inferior. -![BPA Manage Rules UI](~/content/assets/images/common/PBAOverviewManageRulesPopUp.png) \ No newline at end of file +![Interfaz de Administrar reglas de BPA](~/content/assets/images/common/PBAOverviewManageRulesPopUp.png) \ No newline at end of file diff --git a/localizedContent/es/content/features/views/tom-explorer-view.md b/localizedContent/es/content/features/views/tom-explorer-view.md index b2b07c66..cdbf86e9 100644 --- a/localizedContent/es/content/features/views/tom-explorer-view.md +++ b/localizedContent/es/content/features/views/tom-explorer-view.md @@ -36,55 +36,55 @@ El menú del botón derecho incluye los siguientes elementos, algunos de los cua ### Opciones del menú contextual de clic derecho -- **Update table schema...**: - Checks for structural changes in the external data source and updates the table's schema accordingly. Esto es útil cuando se han agregado, cambiado de nombre o quitado columnas en el origen. +- **Actualizar el esquema de la tabla...**: + Comprueba si hay cambios estructurales en el Data source externo y actualiza el esquema de la tabla en consecuencia. Esto es útil cuando se han agregado, cambiado de nombre o quitado columnas en el origen. - **Script DAX**: - Generates a DAX script for the selected table and its objects. Abre una nueva ventana del editor de scripts donde puede revisar o editar en conjunto las definiciones de DAX. + Genera un script DAX para la tabla seleccionada y sus objetos. Abre una nueva ventana del editor de scripts donde puede revisar o editar en conjunto las definiciones de DAX. -- **Preview data**: - Opens the data preview pane displaying a sample of the data loaded into the selected table. Útil para validar o depurar. Solo existe al hacer clic con el botón derecho en las tablas. +- **Vista previa de datos**: + Abre el panel de vista previa de datos y muestra un ejemplo de los datos cargados en la tabla seleccionada. Útil para la validación o la depuración. Solo existe al hacer clic con el botón derecho en las tablas. -- **Refresh**: - Expands to a selection of possible refresh operation for the selected table. Esto solo está disponible si el modelo está conectado a un modelo en vivo, ya sea de forma independiente o en modo del área de trabajo. Esta opción solo está disponible para tablas y particiones. +- **Actualizar**: + Despliega una selección de posibles operaciones de actualización para la tabla seleccionada. Esto solo está disponible si el modelo está conectado a un modelo en vivo, ya sea de forma independiente o en modo del área de trabajo. Esta opción solo está disponible para tablas y particiones. -- **Create**: - Expands to a submenu allowing the creation of new measures, columns, hierarchies, display folders or calculation items under the selected object. Las opciones disponibles dependen del tipo de objeto seleccionado. +- **Crear**: + Muestra un submenú que permite crear nuevas medidas, columnas, jerarquías, carpetas de visualización o elementos de cálculo bajo el objeto seleccionado. Las opciones disponibles dependen del tipo de objeto seleccionado. -- **Move to group**: - Allows you to organize the table into a Table group within the TOM Explorer for easier model navigation. Esta opción solo está disponible para tablas. +- **Mover a un grupo**: + Te permite organizar la tabla en un grupo de tablas dentro del Explorador TOM para navegar por el modelo con más facilidad. Esta opción solo está disponible para tablas. -- **Make invisible**: - Marks the object as not visible in client tools. La tabla sigue formando parte del modelo, pero está oculta para los autores de informes. Como alternativa, usa el atajo **Ctrl+I** para ocultar el objeto. +- **Hacer invisible**: + Marca el objeto como no visible en las herramientas cliente. La tabla sigue formando parte del modelo, pero está oculta para los autores de informes. Como alternativa, puedes usar el atajo **Ctrl+I** para ocultar el objeto. -- **Shown in perspectives**: - Enables or disables the table's inclusion in one or more perspectives. Las perspectivas limitan lo que los usuarios finales pueden ver en herramientas como Power BI. +- **Mostrar en perspectivas**: + Activa o desactiva la inclusión de la tabla en una o varias perspectivas. Las perspectivas limitan lo que los usuarios finales pueden ver en herramientas como Power BI. - **Cambio de nombre por lotes**: Al seleccionar más de un objeto, puede cambiarles el nombre por lotes mediante sustitución de cadenas o expresiones regulares. El atajo para renombrar por lotes es **F2**. -- **Batch rename children...**: - Enables bulk renaming of all child objects under the table or display folder using regex or string replacement rules. También se puede acceder mediante el atajo **Shift+F2**. +- **Renombrar objetos secundarios por lotes...**: + Permite renombrar en bloque todos los objetos secundarios de la tabla o la carpeta de visualización mediante expresiones regulares o reglas de reemplazo de cadenas. También puedes acceder con el atajo **Shift+F2**. -- **Duplicate**: - Creates a copy of the selected table, including all its columns, measures and partitions. También existe para todos los demás objetos del Explorador TOM. +- **Duplicar**: + Crea una copia de la tabla seleccionada, incluidas todas sus columnas, medidas y particiones. También existe para todos los demás objetos del Explorador TOM. -- **Mark as date table...**: - Marks the table as a date table, enabling time intelligence features. Requiere que la tabla contenga una columna de fecha válida. +- **Marcar como tabla de fechas...**: + Marca la tabla como una tabla de fechas, habilitando las funciones de inteligencia temporal. Requiere que la tabla contenga una columna de fecha válida. -- **Show dependencies**: - Visualizes dependencies between the selected table and other model objects. También se puede acceder mediante el atajo **Shift+F12**. +- **Mostrar dependencias**: + Visualiza las dependencias entre la tabla seleccionada y otros objetos del modelo. También se puede acceder mediante el atajo **Shift+F12**. -- **Export script**: - Exports the selected objects as a TMSL or TMDL script for use in deployment or source control. +- **Exportar script**: + Exporta los objetos seleccionados como un script TMSL o TMDL para usarlo en la implementación o el control de código fuente. -- **Macro Menus**: - Macros can be placed into folders and run against the selected object. En el ejemplo anterior, el usuario tiene una carpeta de Modelado y análisis para scripts de macros aplicados a objetos de tabla. +- **Menús de macros**: + Las macros se pueden colocar en carpetas y ejecutarse en el objeto seleccionado. En el ejemplo anterior, el usuario tiene una carpeta de Modelado y análisis para scripts de macros aplicados a objetos de tabla. -- **Cut / Copy / Paste / Delete**: - Standard clipboard operations. Úsalas para mover, duplicar o quitar objetos del modelo. +- **Cortar / Copiar / Pegar / Eliminar**: + Operaciones estándar del portapapeles. Úsalas para mover, duplicar o quitar objetos del modelo. -- **Properties**: - Opens the Properties pane for the selected object. Atajo: **Alt+Enter**. Úsalo para inspeccionar y editar metadatos, expresiones, formato y configuración de visibilidad. +- **Propiedades**: + Abre el panel de Propiedades del objeto seleccionado. Atajo: **Alt+Enter**. Sirve para inspeccionar y editar metadatos, expresiones, formato y configuración de visibilidad. ### Mostrar columnas de información diff --git a/localizedContent/es/content/getting-started/Getting-Started-te2.md b/localizedContent/es/content/getting-started/Getting-Started-te2.md index d2563515..69f44808 100644 --- a/localizedContent/es/content/getting-started/Getting-Started-te2.md +++ b/localizedContent/es/content/getting-started/Getting-Started-te2.md @@ -97,7 +97,7 @@ De forma predeterminada, las particiones, los Data source y los roles no se sobr Puedes encontrar más información sobre las opciones de la línea de comandos [aquí](../features/Command-line-Options.md). > [!NOTE] -> Como TabularEditor.exe es una aplicación de Windows Forms, al ejecutarla desde la línea de comandos se hará en un subproceso distinto, devolviendo el control al proceso que la invocó de inmediato. Si tienes estos problemas, usa `start /wait` para que TabularEditor termine su trabajo antes de devolver el control al proceso que lo invocó: Esto puede causar problemas al ejecutar despliegues como parte de un trabajo por lotes, cuando necesitas esperar a que el despliegue se complete correctamente antes de continuar con la tarea. +> Como TabularEditor.exe es una aplicación de Windows Forms, al ejecutarla desde la línea de comandos se hará en un subproceso distinto, devolviendo el control al proceso que la invocó de inmediato. Si tienes estos problemas, usa `start /wait` para que TabularEditor termine su trabajo antes de devolver el control al proceso que lo invocó: Si tienes estos problemas, usa `start /wait` para que TabularEditor termine su trabajo antes de devolver el control al proceso que lo invocó: > > `start /wait TabularEditor.exe c:\Projects\Model.bim -deploy localhost AdventureWorks` diff --git a/localizedContent/es/content/getting-started/importing-tables-data-modeling.md b/localizedContent/es/content/getting-started/importing-tables-data-modeling.md index eac23d3a..5782049e 100644 --- a/localizedContent/es/content/getting-started/importing-tables-data-modeling.md +++ b/localizedContent/es/content/getting-started/importing-tables-data-modeling.md @@ -31,7 +31,7 @@ Este artículo describe cómo usar el [Asistente de importación de tablas](#tab # Trabajar con diagramas -En Tabular Editor 3, los **diagramas** son documentos que puedes usar para visualizar y editar las relaciones entre las tablas del modelo. Puedes crear tantos diagramas como quieras para visualizar áreas concretas de tu modelo. Consulta para obtener más información. Un diagrama se puede guardar como un archivo independiente. +En Tabular Editor 3, los **diagramas** son documentos que puedes usar para visualizar y editar las relaciones entre las tablas del modelo. Puedes crear tantos diagramas como quieras para visualizar áreas concretas de tu modelo. Un diagrama se puede guardar como un archivo independiente. Consulta para obtener más información. > [!NOTE] > Recomendamos crear varios diagramas pequeños en lugar de unos pocos diagramas grandes. Cuando un diagrama contiene más de unas 20 tablas, enseguida se vuelve abrumador y difícil de entender. diff --git a/localizedContent/es/content/getting-started/index.md b/localizedContent/es/content/getting-started/index.md index 96a2633e..a5f74f37 100644 --- a/localizedContent/es/content/getting-started/index.md +++ b/localizedContent/es/content/getting-started/index.md @@ -38,24 +38,24 @@ Como este material de formación se centra en el producto Tabular Editor, asumim - @user-interface - @bpa-view - - @vista de actualización de datos - - @buscar y reemplazar - - @vista de macros - - @vista de mensajes - - @vista de propiedades + - @data-refresh-view + - @find-replace + - @macros-view + - @messages-view + - @properties-view - @tom-explorer-view - - @vista del diagrama + - @diagram-view -- @desarrollo en paralelo - - @optimizar el flujo de trabajo con el modo de área de trabajo +- @parallel-development + - @optimizing-workflow-workspace-mode - @boosting-productivity-te3 - @importing-tables-data-modeling - - @actualizar, previsualizar y consultar + - @refresh-preview-query - @creating-and-testing-dax - @dax-script-introduction - @bpa - - @scripts de C# y macros + - @cs-scripts-and-macros - @personalizing-te3 **Recursos adicionales:** diff --git a/localizedContent/es/content/getting-started/migrate-from-te2.md b/localizedContent/es/content/getting-started/migrate-from-te2.md index b815e0f3..f4b2b414 100644 --- a/localizedContent/es/content/getting-started/migrate-from-te2.md +++ b/localizedContent/es/content/getting-started/migrate-from-te2.md @@ -83,7 +83,7 @@ Para más información, consulta . ### Nuevo editor de DAX y capacidades semánticas -Tabular Editor 3 incorpora su propio motor de análisis sintáctico de DAX (también conocido como el "analizador semántico"), lo que significa que la herramienta ahora entiende la semántica de cualquier código DAX de tu modelo. Por supuesto, el editor es altamente configurable, lo que te permite ajustarlo para que se adapte a tu estilo de programación de DAX. Este motor también se usa para impulsar nuestro editor de DAX (nombre en clave "Daxscilla"), y para habilitar funciones como el resaltado de sintaxis, el formato automático, el autocompletado de código, los calltips, la refactorización y mucho más. +Tabular Editor 3 incorpora su propio motor de análisis sintáctico de DAX (también conocido como el "analizador semántico"), lo que significa que la herramienta ahora entiende la semántica de cualquier código DAX de tu modelo. Este motor también se usa para impulsar nuestro editor de DAX (nombre en clave "Daxscilla"), y para habilitar funciones como el resaltado de sintaxis, el formato automático, el autocompletado de código, los calltips, la refactorización y mucho más. Por supuesto, el editor es altamente configurable, lo que te permite ajustarlo para que se adapte a tu estilo de programación de DAX. Para obtener más información sobre el nuevo editor de DAX, consulta . @@ -152,5 +152,5 @@ Para obtener más información, consulta @dax-script-introduction. ## Siguientes pasos - @migrate-from-vs -- @desarrollo-en-paralelo -- @aumento-de-la-productividad-te3 +- @parallel-development +- @boosting-productivity-te3 diff --git a/localizedContent/es/content/how-tos/undo-redo.md b/localizedContent/es/content/how-tos/undo-redo.md index c74bf705..8526c2b3 100644 --- a/localizedContent/es/content/how-tos/undo-redo.md +++ b/localizedContent/es/content/how-tos/undo-redo.md @@ -13,4 +13,4 @@ applies_to: Cualquier cambio que hagas en Tabular Editor se puede deshacer con CTRL+Z y, a continuación, rehacer con CTRL+Y. No hay límite en el número de operaciones que se pueden deshacer, pero la pila se restablece cuando abres un archivo Model.bim o cargas un modelo desde una base de datos. -Si cometes un error, puedes usar la función Deshacer para restaurar el objeto eliminado, lo que también restaurará cualquier traducción, perspectiva o relación eliminada. Al eliminar objetos del modelo, todas las traducciones, perspectivas y relaciones que hagan referencia a los objetos eliminados también se eliminan automáticamente (mientras que Visual Studio normalmente muestra un mensaje de error indicando que el objeto no se puede eliminar). Ten en cuenta que, aunque Tabular Editor puede detectar [dependencias de fórmulas DAX](xref:formula-fix-up-dependencies), Tabular Editor no te avisará si eliminas una medida o una columna que se usa en la expresión DAX de otra medida o columna calculada. \ No newline at end of file +Al eliminar objetos del modelo, todas las traducciones, perspectivas y relaciones que hagan referencia a los objetos eliminados también se eliminan automáticamente (mientras que Visual Studio normalmente muestra un mensaje de error indicando que el objeto no se puede eliminar). Si cometes un error, puedes usar la función Deshacer para restaurar el objeto eliminado, lo que también restaurará cualquier traducción, perspectiva o relación eliminada. Ten en cuenta que, aunque Tabular Editor puede detectar [dependencias de fórmulas DAX](xref:formula-fix-up-dependencies), Tabular Editor no te avisará si eliminas una medida o una columna que se usa en la expresión DAX de otra medida o columna calculada. \ No newline at end of file diff --git a/localizedContent/es/content/references/preferences.md b/localizedContent/es/content/references/preferences.md index 0c5ceeca..5094a425 100644 --- a/localizedContent/es/content/references/preferences.md +++ b/localizedContent/es/content/references/preferences.md @@ -176,7 +176,7 @@ Crea una copia de seguridad del modelo al guardar cambios localmente. Esto te of ##### _Ubicación para guardar la copia de seguridad_ -Especifica la carpeta donde se almacenan las copias de seguridad creadas al guardar. De forma predeterminada, no se crean copias de seguridad a menos que se especifique una ubicación. +Especifica la carpeta donde se almacenan las copias de seguridad de los despliegues. De forma predeterminada, no se crean copias de seguridad a menos que se especifique una ubicación. ##### _Copia de seguridad al implementar_ (habilitado) @@ -184,7 +184,7 @@ Crea una copia de seguridad del modelo de destino antes de implementar los cambi ##### _Ubicación de copia de seguridad_ -Especifica la carpeta donde se almacenan las copias de seguridad de los despliegues. De forma predeterminada, no se crean copias de seguridad a menos que se especifique una ubicación. +De forma predeterminada, no se crean copias de seguridad a menos que se especifique una ubicación. Especifica la carpeta donde se almacenan las copias de seguridad creadas al guardar. ## Tabular Editor > Valores predeterminados @@ -714,7 +714,7 @@ Define prefijos aceptables para nombres de variables (p. ej., `_`, `__`, `var_`, Define prefijos aceptables para nombres de columnas temporales (p. ej., `@`, `_`, `x`, `x_`). Las acciones de código sugerirán añadir estos prefijos a los nombres de columnas temporales que no sigan la convención. -## Editor SQL / Editor M / Editor de C\\# +## Editor SQL / Editor M / Editor de C\# ![Marcador de posición: captura de pantalla de las páginas de preferencias de los editores SQL/M/C#] diff --git a/localizedContent/es/content/security/security-privacy.md b/localizedContent/es/content/security/security-privacy.md index 792f6d55..02462c0e 100644 --- a/localizedContent/es/content/security/security-privacy.md +++ b/localizedContent/es/content/security/security-privacy.md @@ -86,7 +86,7 @@ Tabular Editor puede realizar solicitudes a recursos en línea (URL web) solo en - **Activación de licencia\*.** Cuando Tabular Editor 3 se inicia por primera vez y, posteriormente, a intervalos periódicos, la herramienta puede realizar una solicitud a nuestro servicio de licencias. Esta solicitud contiene información cifrada sobre la clave de licencia introducida por el usuario, la dirección de correo electrónico del usuario (si se proporciona), el nombre del equipo local y un hash codificado unidireccional que identifica la instalación actual. No se transmite ningún otro dato en esta solicitud. El propósito de esta solicitud es activar y validar la clave de licencia utilizada por la instalación, aplicar las limitaciones de la versión de prueba y permitir que el usuario gestione sus instalaciones de Tabular Editor 3 a través de nuestro servicio de licencias. - **Comprobaciones de actualización\*.** Cada vez que se inicia Tabular Editor 3, puede realizar una solicitud a nuestro servicio de aplicaciones para determinar si hay disponible una versión más reciente de Tabular Editor 3. Esta solicitud no contiene ningún dato. -- **Telemetría de uso\*.** De forma predeterminada, Tabular Editor 3 recopila y transmite datos de uso anónimos a medida que los usuarios interactúan con la herramienta. Estos datos incluyen información sobre los objetos de la interfaz de usuario con los que interactúa un usuario y el momento de cada interacción. También contiene información de alto nivel sobre el Data model tabular que se está editando con la herramienta. Esta información solo se refiere a propiedades de alto nivel como el nivel de compatibilidad y el modo, el número de tablas, el tipo de servidor (Analysis Services vs. Power BI vs. Power BI Desktop), etc. **No se recopilan datos personales identificables de esta manera**, ni recopilamos información sobre los nombres de los objetos o las expresiones DAX en el propio Tabular Object Model. Un usuario puede optar por no enviarnos datos de telemetría en cualquier momento. +- **Telemetría de uso\*.** De forma predeterminada, Tabular Editor 3 recopila y transmite datos de uso anónimos a medida que los usuarios interactúan con la herramienta. Estos datos incluyen información sobre los objetos de la interfaz de usuario con los que interactúa un usuario y el momento de cada interacción. También contiene información de alto nivel sobre el Data model tabular que se está editando con la herramienta. Un usuario puede optar por no enviarnos datos de telemetría en cualquier momento. Esta información solo se refiere a propiedades de alto nivel como el nivel de compatibilidad y el modo, el número de tablas, el tipo de servidor (Analysis Services vs. Power BI vs. Power BI Desktop), etc. **No se recopilan datos personales identificables de esta manera**, ni recopilamos información sobre los nombres de los objetos o las expresiones DAX en el propio Tabular Object Model. - **Reports de error\*.** Cuando se produce un error inesperado, transmitimos la traza de la pila y los mensajes de error (anonimizados), junto con una descripción opcional proporcionada por el usuario. Si un usuario decide no enviar datos de telemetría, tampoco se enviarán los Reports de error. - **Uso del formateador de DAX.** (Solo Tabular Editor 2.x) Se puede dar formato a una expresión DAX haciendo clic en un botón en Tabular Editor. En este caso, la expresión DAX (y nada más) se envía al servicio web www.daxformatter.com. La primera vez que un usuario hace clic en este botón, se muestra un mensaje de advertencia explícito para que confirme su intención. Tabular Editor 3 no realiza solicitudes web al dar formato al código DAX. - **Optimizador de DAX**. Si un usuario tiene una [cuenta de Tabular Tools](https://tabulartools.com) con una suscripción a [Optimizador de DAX](https://daxoptimizer.com), podrá explorar su Workspace del Optimizador de DAX, ver incidencias y sugerencias, y cargar nuevos archivos VPAX directamente desde Tabular Editor 3. Los archivos VPAX contienen metadatos y estadísticas del modelo, pero no _datos_ reales del modelo. La función de integración del Optimizador de DAX en Tabular Editor 3 realiza varias solicitudes a uno o varios de los endpoints indicados a continuación (en función del tipo de autenticación y de la región especificados al crear la cuenta de Tabular Tools).
diff --git a/localizedContent/es/content/tutorials/incremental-refresh/incremental-refresh-about.md b/localizedContent/es/content/tutorials/incremental-refresh/incremental-refresh-about.md index abc0e42a..02787629 100644 --- a/localizedContent/es/content/tutorials/incremental-refresh/incremental-refresh-about.md +++ b/localizedContent/es/content/tutorials/incremental-refresh/incremental-refresh-about.md @@ -297,31 +297,31 @@ _A continuación se muestra un resumen de las propiedades de TOM de un Data mode
- + - - + + - - + + - + - + - - + + @@ -333,7 +333,7 @@ _A continuación se muestra un resumen de las propiedades de TOM de un Data mode - + diff --git a/localizedContent/zh/content/_ui-strings.json b/localizedContent/zh/content/_ui-strings.json index 5525fb60..cfffdf19 100644 --- a/localizedContent/zh/content/_ui-strings.json +++ b/localizedContent/zh/content/_ui-strings.json @@ -35,5 +35,14 @@ "themeAuto": "自动", "changeTheme": "切换主题", "copy": "复制", - "downloadPdf": "下载 PDF" + "downloadPdf": "下载 PDF", + "search": "搜索文档", + "note": "注意", + "warning": "警告", + "tip": "提示", + "important": "重要", + "caution": "注意事项", + "tableOfContents": "目录", + "selectLanguage": "选择语言", + "copyCode": "复制代码" } diff --git a/localizedContent/zh/content/api/index.md b/localizedContent/zh/content/api/index.md index 03eab007..b2204853 100644 --- a/localizedContent/zh/content/api/index.md +++ b/localizedContent/zh/content/api/index.md @@ -7,15 +7,15 @@ updated: 2026-01-27 # Tabular Editor API -这是 Tabular Editor 的 C# 脚本编写功能的 API 文档。 +这是 Tabular Editor 的 C# Script 功能的 API 文档。 -具体而言,可用于脚本编写的对象来自 **TOMWrapper.dll**、**TabularEditor3.Shared.dll** 和 **SemanticBridge.dll** 库。 +具体来说,可用于编写脚本的对象来自 **TOMWrapper.dll**、**TabularEditor3.Shared.dll** 和 **SemanticBridge.dll** 库。 -## 入门 +## 开始使用 -在 Tabular Editor 中编写脚本时,最常用的两个对象是 [`Selected`](xref:TabularEditor.Shared.Interaction.Selection),它允许你访问当前在 TOM Explorer 中选中的对象,以及 [`Model`](xref:TabularEditor.TOMWrapper.Model),它允许你访问当前加载的数据模型中的任何对象。 这两个对象都作为全局 [`ScriptHost`](xref:TabularEditor.Shared.Scripting.ScriptHost) 对象的成员属性提供。 +在 Tabular Editor 中编写脚本时,最常用的两个对象是 [`Selected`](xref:TabularEditor.Shared.Interaction.Selection) 和 [`Model`](xref:TabularEditor.TOMWrapper.Model)。前者可让你访问当前在 TOM Explorer 中选中的对象,后者可让你访问当前已加载的 Data model 中的任何对象。 这两个对象都可作为全局 [`ScriptHost`](xref:TabularEditor.Shared.Scripting.ScriptHost) 对象的成员属性使用。 -此外,`ScriptHost` 对象还包含一些静态方法,这些方法会以全局方法的形式暴露给脚本(也就是说,你可以直接调用它们,无需加上 `ScriptHost` 前缀)。 这些方法也称为 @script-helper-methods(脚本帮助方法)。 +此外,`ScriptHost` 对象还包含一些静态方法,这些方法会作为全局方法向脚本公开(也就是说,无需加上 `ScriptHost` 前缀即可调用)。 这些方法也称为 @script-helper-methods。 ## 示例 @@ -23,8 +23,8 @@ updated: 2026-01-27 // 显示一个对话框,提示用户选择一个度量值: var myMeasure = SelectMeasure(); -// 在模型的第一张表上创建一个新度量值,其名称和表达式 -// 与前面选中的度量值相同: +// 在模型的第一张表上创建一个新的度量值,其名称和表达式 +// 与先前选中的度量值相同: Model.Tables.First().AddMeasure(myMeasure.Name + " copy", myMeasure.Expression); ``` diff --git a/localizedContent/zh/content/features/Best-Practice-Analyzer.md b/localizedContent/zh/content/features/Best-Practice-Analyzer.md index 08f08a98..79cf2b36 100644 --- a/localizedContent/zh/content/features/Best-Practice-Analyzer.md +++ b/localizedContent/zh/content/features/Best-Practice-Analyzer.md @@ -1,85 +1,85 @@ --- uid: best-practice-analyzer -title: 最佳实践分析器 +title: Best Practice Analyzer applies_to: products: - product: Tabular Editor 2 full: true - product: Tabular Editor 3 editions: - - edition: Desktop + - edition: 桌面版 full: true - - edition: Business + - edition: 商业版 full: true - - edition: Enterprise + - edition: 企业版 full: true --- -# 最佳实践分析器 +# Best Practice Analyzer -自 [Tabular Editor 2.8.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.8.1) 起,最佳实践分析器已进行了重大改版。 +自 [Tabular Editor 2.8.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.8.1) 起,Best Practice Analyzer 迎来了一次重大改版。 -你首先会注意到,Tabular Editor 现在会在主 UI 中直接显示最佳实践问题的数量: +你首先会注意到,Tabular Editor 现在会在主界面中直接报告最佳实践问题的数量: -![image](https://user-images.githubusercontent.com/8976200/53631987-baee5880-3c0b-11e9-9d66-e906cccce2be.png) +![图片](https://user-images.githubusercontent.com/8976200/53631987-baee5880-3c0b-11e9-9d66-e906cccce2be.png) -每当对模型进行更改时,最佳实践分析器都会在后台扫描你的模型以查找问题。 你可以在“文件 > 偏好设置”中禁用此功能。 +每当模型发生更改时,Best Practice Analyzer 都会在后台扫描你的模型以查找问题。 你可以在“文件 > 偏好设置”中禁用此功能。 -点击该链接(或按 F10),会打开全新升级的最佳实践分析器 UI: +单击该链接(或按 F10)会打开全新改进后的 Best Practice Analyzer 界面: -![image](https://user-images.githubusercontent.com/8976200/53631947-9eeab700-3c0b-11e9-9217-5739d4de2f88.png) +![图片](https://user-images.githubusercontent.com/8976200/53631947-9eeab700-3c0b-11e9-9217-5739d4de2f88.png) -如果你在旧版本中用过最佳实践分析器,你首先会注意到该 UI 已完全重新设计,占用的屏幕空间更小。 这样你就可以将该窗口停靠在桌面一侧,同时将主窗口放在另一侧,从而同时操作两者。 +如果你在早期版本中用过 Best Practice Analyzer,首先会注意到它的界面已被彻底重新设计,占用的屏幕空间更少。 这样一来,你可以将该窗口停靠在屏幕的一侧,同时将主窗口放在另一侧,从而同时使用两者。 -最佳实践分析器窗口会持续列出模型中所有 **生效规则**,以及违反各规则的对象。 在列表中的任意位置右键单击,或使用窗口顶部的工具栏按钮,即可执行以下操作: +Best Practice Analyzer 窗口会持续列出适用于你的模型的所有**有效规则**,以及违反各项规则的对象。 在列表中的任意位置右键单击,或使用窗口顶部工具栏上的按钮,即可执行以下操作: -- **管理规则...**:打开“管理规则”界面,我们将在下文介绍。 你也可以在主界面通过“工具 > 管理 BPA 规则...”菜单打开此界面。 -- **转到对象...**:选择此选项,或在列表中双击某个对象,会在主界面中定位到同一对象。 -- **忽略项(单个/多个)**:在列表中选择一个或多个对象并选择此选项,会为所选对象添加注释,表明 Best Practice Analyzer 今后应忽略这些对象。 如果你误将某个对象设为忽略,请点击屏幕顶部的“显示已忽略”按钮。 这样你就可以取消忽略之前被忽略的对象。 -- **忽略规则**:如果你在列表中选择了一条或多条规则,此选项会在模型级别添加一条注释,用于指示所选规则应始终被忽略。 同样,通过切换“显示已忽略”按钮,你也可以取消忽略这些规则。 -- **生成修复脚本**:对于可轻松修复的规则(即只需在对象上设置一个属性就能解决问题),将启用此选项。 点击后,会将一个 C# Script 复制到剪贴板。 然后,你可以将该脚本粘贴到 Tabular Editor 的 [高级脚本](../how-tos/Advanced-Scripting.md) 区域中,在执行以应用修复之前先进行检查。 -- **应用修复**:如上所述,此选项也适用于可轻松修复的规则。 它不会将脚本复制到剪贴板,而是立即执行。 +- **管理规则...**:这会打开“管理规则”界面,下面会详细介绍。 也可以通过主界面的“工具 > 管理 BPA 规则...”菜单打开此界面。 +- **转到对象...**:选择此选项,或在列表中双击某个对象,都会在主界面中定位到该对象。 +- **忽略项/多项**:在列表中选择一个或多个对象并使用此选项后,系统会为所选对象添加一条注释,指示 Best Practice Analyzer 后续忽略这些对象。 如果你误忽略了某个对象,可以切换窗口顶部的“显示已忽略”按钮。 这样你就可以取消忽略之前已被忽略的对象。 +- **忽略规则**:如果你已在列表中选择了一条或多条规则,此选项会在模型级别添加一条注释,用于指示应始终忽略所选规则。 同样,通过切换“显示已忽略项”按钮,你也可以取消对规则的忽略。 +- **生成修复脚本**:对于可轻松修复的规则(即只需在对象上设置单个属性即可解决问题),将启用此选项。 点击后,会将一段 C# Script 复制到你的剪贴板。 随后,你可以将该脚本粘贴到 Tabular Editor 的 [Advanced Scripting](../how-tos/Advanced-Scripting.md) 区域,在执行以应用修复之前先进行检查。 +- **应用修复**:如上所述,此选项同样适用于可轻松修复的规则。 脚本不会被复制到剪贴板,而是会立即执行。 ## 管理最佳实践规则 -如果你需要添加、删除或修改应用于模型的规则,这里也提供了一套全新的 UI。 你可以通过点击 Best Practice Analyzer 窗口左上角的按钮将其调出,或在主窗口中使用 "Tools > Manage BPA Rules..." 菜单项。 +如果你需要添加、删除或修改应用于模型的规则,这里也提供了一个全新的 UI 来完成这些操作。 你可以通过点击 Best Practice Analyzer 窗口左上角的按钮打开它,也可以在主窗口中使用“Tools > Manage BPA Rules...”菜单项。 -![image](https://user-images.githubusercontent.com/8976200/53632990-2f29fb80-3c0e-11e9-82fe-ee9c921662c7.png) +![图片](https://user-images.githubusercontent.com/8976200/53632990-2f29fb80-3c0e-11e9-82fe-ee9c921662c7.png) -该 UI 包含两个列表:上方列表表示当前已加载的规则的 **集合**。 在此列表中选择一个规则集后,下方列表会显示该规则集中定义的所有规则。 默认会显示三个规则集: +该界面包含两个列表:上方列表显示当前已加载的**规则集**。 在此列表中选择某个规则集后,下方列表会显示该规则集中定义的所有规则。 默认会显示三个规则集: -- **当前模型中的规则**:顾名思义,这是在当前模型中定义的规则集。 规则定义以注释的形式存储在 Model 对象上。 -- **本地用户规则**:这些规则存储在您的 `%AppData%\..\Local\TabularEditor3\BPARules.json` 文件(Tabular Editor 3)或 `%AppData%\..\Local\TabularEditor\BPARules.json` 文件(Tabular Editor 2)中。 这些规则将应用于当前登录的 Windows 用户在 Tabular Editor 中加载的所有模型。 -- **本机上的规则**:这些规则存储在 `%ProgramData%\TabularEditor\BPARules.json` 文件中。 这些规则将应用于当前机器上在 Tabular Editor 中加载的所有模型。 +- **当前模型中的规则**:顾名思义,这是在当前模型内定义的规则集。 这些规则定义作为注释存储在 Model 对象上。 +- **本地用户规则**:这些规则存储在 `%AppData%\\..\\Local\\TabularEditor3\\BPARules.json` 文件(Tabular Editor 3)或 `%AppData%\\..\\Local\\TabularEditor\\BPARules.json` 文件(Tabular Editor 2)中。 这些规则将应用于当前登录的 Windows 用户在 Tabular Editor 中加载的所有模型。 +- **本地计算机上的规则**:这些规则存储在 `%ProgramData%\TabularEditor\BPARules.json` 中。 这些规则将应用于当前计算机上在 Tabular Editor 中加载的所有模型。 -如果同一条规则(按 ID)同时存在于多个规则集中,则优先级从上到下:也就是说,模型中定义的规则会优先于本机上定义的同 ID 规则。 这样你就可以覆盖现有规则,例如以便考虑模型特定的约定。 +如果多个规则集中都包含同一条规则(按 ID),则优先级从上到下。也就是说,模型内定义的规则优先于本地计算机上定义的同 ID 规则。 这样你就可以覆盖现有规则,例如将模型特定的约定考虑在内。 -在列表顶部,你会看到一个名为 **(Effective rules)** 的特殊集合。 选择此规则集后,将显示实际应用于当前加载模型的规则列表,并会遵循上述相同 ID 规则的优先级。 下方列表会标明每条规则属于哪个规则集。 此外,如果在优先级更高的规则集中已存在 ID 相近的规则,你会看到该规则的名称会被划线显示: +在列表顶部,你会看到一个名为 **(Effective rules)** 的特殊集合。 选择此集合后,你将看到实际应用于当前已加载模型的规则列表,并会按前文所述遵循相同 ID 规则的优先级。 下方列表会指明每条规则所属的规则集。 此外,如果在优先级更高的集合中存在 ID 相同的规则,你会注意到该规则的名称会显示为删除线: ![image](https://user-images.githubusercontent.com/8976200/53633831-74e7c380-3c10-11e9-925e-1419987f5a17.png) -### 添加额外规则集 +### 添加更多规则集 -Tabular Editor 2.8.1 的一项新功能是:可以在模型中包含来自其他来源的规则。 例如,如果你有一个存放在网络共享上的规则文件,现在可以将该文件作为规则集包含到当前模型中。 如果你对该文件所在位置有写入权限,还可以在该文件中添加/修改/删除规则。 以这种方式添加的规则集,其优先级高于模型内定义的规则。 如果你添加了多个此类规则集,可以通过上下移动它们来控制彼此之间的优先级。 +Tabular Editor 2.8.1 的一项新功能是,可以在模型中包含来自其他来源的规则。 例如,如果你的某个规则文件位于网络共享上,现在可以将该文件作为规则集包含到当前模型中。 如果你对该文件所在位置具有写入权限,还可以添加/修改/删除该文件中的规则。 以这种方式添加的规则集,其优先级高于模型内定义的规则。 如果你添加了多个此类规则集,可以通过上移和下移来控制它们之间的优先级。 -点击“添加...”按钮,将新的规则集添加到模型中。 这会提供以下选项: +点击“添加...”按钮,将新规则集添加到模型中。 这会提供以下选项: ![image](https://user-images.githubusercontent.com/8976200/53634211-7cf43300-3c11-11e9-8fed-7df113264a6f.png) -- **创建新规则文件**:将在指定位置创建一个新的空的 .json 文件,之后你可以向其中添加规则。 选择文件时请注意:可以使用相对文件路径。 当你希望将规则文件与当前模型存放在同一个代码仓库中时,这会很有用。 不过请注意:相对路径的规则文件引用仅在模型从磁盘加载时才有效(因为从 Analysis Services 实例加载模型时没有工作目录)。 -- **包含本地规则文件**:如果你已经有一个包含规则的 .json 文件,并希望将其包含到模型中,请使用此选项。 同样,你也可以选择使用相对文件路径;如果该文件与模型元数据位置相近,这会更方便。 如果文件位于网络共享上(或更一般地说,位于与当前加载的模型元数据不同的驱动器上),则只能使用绝对路径来包含它。 -- **从 URL 包含规则文件**:使用此选项可指定一个 HTTP/HTTPS URL,该 URL 应返回有效的规则定义(JSON)。 如果你希望从在线来源包含规则,这会很有用。例如,来自 [BestPracticeRules GitHub 站点](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules) 的[标准 BPA 规则](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json)。 注意:从在线来源添加的规则集将是只读的。 +- **创建新规则文件**:这会在指定位置创建一个新的空 .json 文件,之后你可以向其中添加规则。 选择文件时,注意有一个使用相对文件路径的选项。 如果你希望将规则文件存储在与当前模型相同的 repository 中,这会很有用。 但要注意,相对规则文件引用仅在模型从磁盘加载时才有效(因为从 Analysis Services 实例加载模型时不存在工作目录)。 +- **包含本地规则文件**:如果你已经有一个包含规则的 .json 文件,并想把它包含到模型中,就用这个选项。 同样,你也可以使用相对文件路径;如果该文件位于靠近模型元数据的位置,这会更方便。 如果该文件位于网络共享上(或者更一般地说,位于与当前已加载模型元数据所在位置不同的驱动器上),则只能使用绝对路径来包含它。 +- **从 URL 包含规则文件**:此选项允许你指定一个 HTTP/HTTPS URL,该 URL 应返回有效的规则定义(JSON)。 如果你想包含来自在线来源的规则,这会很有用,例如来自 [BestPracticeRules GitHub 站点](https://github.com/microsoft/Analysis-Services/tree/master/BestPracticeRules) 的 [标准 BPA 规则](https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json)。 注意,从在线来源添加的规则集将是只读的。 ### 修改规则集中的规则 -在你对规则集存储位置拥有写入权限的前提下,屏幕下半部分可让你在当前选中的规则集中添加、编辑、克隆和删除规则。 此外,“移动到...”按钮允许你将所选规则移动或复制到另一个规则集,便于管理多个规则集。 +屏幕下半部分允许你在当前选中的规则集中添加、编辑、克隆和删除规则,前提是你对该规则集的存储位置具有写入权限。 此外,“移动到...”按钮允许你将所选规则移动或复制到另一个规则集,从而更轻松地管理多个规则集。 ### 规则说明占位符 -与之前版本相比,有一个小改进:现在你可以在“最佳实践规则”的描述中使用以下占位符值。 这将提供更多可自定义的描述,这些描述会在“最佳实践”界面中以工具提示的形式显示: +相比之前版本有一个小改进:现在你可以在最佳实践规则的说明中使用以下占位符值。 这将提供更多可自定义的说明,并在“最佳实践”界面中以工具提示的形式显示: -- `%object%` 返回对当前对象的完全限定 DAX 引用(如适用) +- `%object%` 返回当前对象的完全限定 DAX 引用(如适用) - `%objectname%` 仅返回当前对象的名称 - `%objecttype%` 返回当前对象的类型 -![image](https://user-images.githubusercontent.com/8976200/53671918-587f7180-3c78-11e9-855f-ed497f2c0c98.png) +![图片](https://user-images.githubusercontent.com/8976200/53671918-587f7180-3c78-11e9-855f-ed497f2c0c98.png) diff --git a/localizedContent/zh/content/features/CSharpScripts/Advanced/script-add-databricks-metadata-descriptions.md b/localizedContent/zh/content/features/CSharpScripts/Advanced/script-add-databricks-metadata-descriptions.md index a1f8c5f5..a06d668c 100644 --- a/localizedContent/zh/content/features/CSharpScripts/Advanced/script-add-databricks-metadata-descriptions.md +++ b/localizedContent/zh/content/features/CSharpScripts/Advanced/script-add-databricks-metadata-descriptions.md @@ -15,12 +15,12 @@ applies_to: ## 脚本用途 -此脚本是 Tabular Editor x Databricks 系列的一部分。 在 Unity Catalog 中,可以为表和列添加描述性注释。 此脚本可以复用这些信息,自动填充语义模型中的表和列描述。

+这个脚本是 Tabular Editor x Databricks 系列的一部分。 在 Unity Catalog 中,可以为表和列添加描述性注释。 此脚本可复用这些信息,自动补全语义模型中的表和列说明。

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

+> 这个脚本需要先安装 Simba Spark ODBC Driver(可从 https://www.databricks.com/spark/odbc-drivers-download 下载) +> 每次运行脚本时,都会提示你输入 Databricks 个人访问令牌。 这是用于向 Databricks 进行身份验证所必需的。 +> 这个脚本使用 Unity Catalog 中的 information_schema 表来检索关系信息,因此你可能需要和你的 Databricks 管理员再确认一下,确保你有权限查询这些表。

## 脚本 @@ -28,20 +28,20 @@ applies_to: ```csharp /* - * Title: Add Databricks Metadata descriptions - * Author: Johnny Winter, greyskullanalytics.com + * 标题:添加 Databricks 元数据说明 + * 作者: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 + * 运行这个脚本时,它会遍历当前选中的表,并向 Databricks 发送查询,检查每个表是否在 Unity Catalog 中定义了元数据说明。 + * 如果有说明,就会把它添加到语义模型的说明中。 + * 步骤 1:在模型中选择一个或多个表 + * 步骤 2:运行这个脚本 + * 步骤 3:在出现提示时输入你的 Databricks 个人访问令牌 + * 步骤 4:脚本会连接到 Databricks,并在表和列存在说明时更新对应说明。 + * 对于处理的每个表,都会显示一个消息框,指出已更新的说明数量。 + * 点击“确定”继续处理下一个表。 + * 备注: + * - 这个脚本需要先安装 Simba Spark ODBC Driver(可从 https://www.databricks.com/spark/odbc-drivers-download 下载) + * - 每次运行脚本时,都会提示你输入 Databricks 个人访问令牌 */ #r "Microsoft.VisualBasic" using System; @@ -52,7 +52,7 @@ using System.Windows.Forms; using Microsoft.VisualBasic; using sysData = System.Data; -//code to create a masked input box for Databricks PAT token +//用于创建 Databricks PAT 令牌掩码输入框的代码 public partial class PasswordInputForm : Form { public string Password { get; private set; } @@ -76,7 +76,7 @@ public partial class PasswordInputForm : Form this.MaximizeBox = false; this.MinimizeBox = false; - // Prompt label + //提示标签 promptLabel = new Label(); promptLabel.Text = prompt; promptLabel.Location = new System.Drawing.Point(12, 15); @@ -84,11 +84,11 @@ public partial class PasswordInputForm : Form 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.UseSystemPasswordChar = true; // 这会隐藏输入内容 passwordTextBox.KeyPress += (s, e) => { if (e.KeyChar == (char)Keys.Return) @@ -99,27 +99,27 @@ public partial class PasswordInputForm : Form }; this.Controls.Add(passwordTextBox); - // OK button + //确定按钮 okButton = new Button(); - okButton.Text = "OK"; + okButton.Text = "确定"; 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.Text = "取消"; 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(); } @@ -178,7 +178,7 @@ public static class MaskedInputHelper }; var buttonOk = new Button() { - Text = "OK", + Text = "确定", Size = new System.Drawing.Size(150, 50), Left = 12, Width = 150, @@ -187,7 +187,7 @@ public static class MaskedInputHelper }; var buttonCancel = new Button() { - Text = "Cancel", + Text = "取消", Size = new System.Drawing.Size(150, 50), Left = 175, Width = 150, @@ -211,7 +211,7 @@ public static class MaskedInputHelper } } -//Code to retrieve Databricks Connection information from the M Query in a table partition +//从表分区中的 M 查询检索 Databricks 连接信息的代码 public class DatabricksConnectionInfo { public string ServerHostname { get; set; } @@ -222,11 +222,11 @@ public class DatabricksConnectionInfo public override string ToString() { - return $"Server: {ServerHostname}\n" - + $"HTTP Path: {HttpPath}\n" - + $"Database: {DatabaseName}\n" - + $"Schema: {SchemaName}\n" - + $"Table: {TableName}"; + return $"服务器:{ServerHostname}\n" + + $"HTTP 路径:{HttpPath}\n" + + $"数据库:{DatabaseName}\n" + + $"架构:{SchemaName}\n" + + $"表:{TableName}"; } } @@ -235,35 +235,35 @@ public class PowerQueryMParser public static DatabricksConnectionInfo ParseMQuery(string mQuery) { if (string.IsNullOrWhiteSpace(mQuery)) - throw new ArgumentException("M query cannot be null or empty"); + throw new ArgumentException("M 查询不能为空或空字符串"); var connectionInfo = new DatabricksConnectionInfo(); try { - // Parse Source line to extract server hostname and HTTP path + //解析 Source 行以提取服务器主机名和 HTTP 路径 ParseSourceLine(mQuery, connectionInfo); - // Parse Database line to extract database name + //解析 Database 行以提取数据库名称 ParseDatabaseLine(mQuery, connectionInfo); - // Parse Schema line to extract schema name + //解析 Schema 行以提取架构名称 ParseSchemaLine(mQuery, connectionInfo); - // Parse Data line to extract table name + //解析 Data 行以提取表名 ParseDataLine(mQuery, connectionInfo); return connectionInfo; } catch (Exception ex) { - throw new InvalidOperationException($"Error parsing M query: {ex.Message}", ex); + throw new InvalidOperationException($"解析 M 查询时出错:{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 = @@ -276,7 +276,7 @@ public class PowerQueryMParser if (!sourceMatch.Success) throw new FormatException( - "Could not find valid Source definition in M query (supports both Databricks and DatabricksMultiCloud connectors)" + "在 M 查询中找不到有效的 Source 定义(同时支持 Databricks 和 DatabricksMultiCloud 连接器)" ); connectionInfo.ServerHostname = sourceMatch.Groups[1].Value; @@ -285,7 +285,7 @@ public class PowerQueryMParser private static void ParseDatabaseLine(string mQuery, DatabricksConnectionInfo connectionInfo) { - // Pattern to match: Database = Source{[Name="databasename",Kind="Database"]}[Data], + //匹配模式: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( @@ -295,14 +295,14 @@ public class PowerQueryMParser ); if (!databaseMatch.Success) - throw new FormatException("Could not find valid Database definition in M query"); + throw new FormatException("在 M 查询中找不到有效的 Database 定义"); connectionInfo.DatabaseName = databaseMatch.Groups[1].Value; } private static void ParseSchemaLine(string mQuery, DatabricksConnectionInfo connectionInfo) { - // Pattern to match: Schema = Database{[Name="schemaname",Kind="Schema"]}[Data], + //匹配模式: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( @@ -312,14 +312,14 @@ public class PowerQueryMParser ); if (!schemaMatch.Success) - throw new FormatException("Could not find valid Schema definition in M query"); + throw new FormatException("在 M 查询中找不到有效的 Schema 定义"); connectionInfo.SchemaName = schemaMatch.Groups[1].Value; } private static void ParseDataLine(string mQuery, DatabricksConnectionInfo connectionInfo) { - // Pattern to match: Data = Schema{[Name="tablename",Kind="Table"]}[Data] + //匹配模式: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( @@ -329,70 +329,70 @@ public class PowerQueryMParser ); if (!dataMatch.Success) - throw new FormatException("Could not find valid Data definition in M query"); + throw new FormatException("在 M 查询中找不到有效的 Data 定义"); 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"); + Interaction.MsgBox("请选择一个或多个表", MsgBoxStyle.Critical, "需要选择表"); return; } -//prompt for personal access token - required to authenticate to Databricks +//提示输入个人访问令牌 - 这是连接 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" + "请输入你的 Databricks 个人访问令牌(连接到 SQL 终结点时需要)", + "个人访问令牌" ); if (string.IsNullOrEmpty(dbxPAT)) { - return; // User cancelled + return; // 你已取消 } 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 +//对每个选中的表,从分区信息中获取 Databricks 连接信息 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 + //设置 DBX 连接字符串 var odbcConnStr = @"DSN=Simba Spark;driver=C:\Program Files\Simba Spark ODBC Driver;host=" + serverHostname @@ -401,7 +401,7 @@ foreach (var t in Selected.Tables) + ";thrifttransport=2;ssl=1;authmech=3;uid=token;pwd=" + dbxPAT; - //test connection + //测试连接 OdbcConnection conn = new OdbcConnection(odbcConnStr); try { @@ -409,34 +409,34 @@ foreach (var t in Selected.Tables) } 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) +- 你需要先安装 Simba Spark ODBC Driver +(可从 https://www.databricks.com/spark/odbc-drivers-download 下载) -- the ODBC driver must be installed in the path C:\Program Files\Simba Spark ODBC Driver +- ODBC 驱动程序必须安装在路径 C:\Program Files\Simba Spark ODBC Driver 中 -- check that the Databricks server name " +- 请检查 Databricks 服务器名称 " + serverHostname - + @" is correct + + @" 是否正确 -- check that the Databricks SQL endpoint / HTTP Path " +- 请检查 Databricks SQL 终结点 / HTTP 路径 " + 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 @@ -454,24 +454,24 @@ Please check the following prequisites: } 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", + - 连接超时。请检查 SQL 终结点群集是否正在运行", MsgBoxStyle.Critical, - "Connection Error - Table Metadata" + "连接错误 - 表元数据" ); return; } @@ -481,11 +481,11 @@ Either: if (t.Description != row["comment"].ToString()) { t.Description = row["comment"].ToString(); - tableUpdate = t.Name + " table description updated."; + tableUpdate = t.Name + " 的表说明已更新。"; } } - //get column metadata + //获取列元数据 var columnsQuery = @"DESCRIBE " + databaseName + "." + schemaName + "." + tableName; OdbcDataAdapter da = new OdbcDataAdapter(columnsQuery, conn); var dbxColumns = new sysData.DataTable(); @@ -496,29 +496,29 @@ Either: } 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", + - 连接超时。请检查 SQL 终结点群集是否正在运行", MsgBoxStyle.Critical, - "Connection Error - Column Metadata" + "连接错误 - 列元数据" ); return; } - //update column descriptions + //更新列说明 int counter = 0; foreach (sysData.DataRow row in dbxColumns.Rows) { @@ -542,19 +542,20 @@ Either: tableUpdate + @" -" +已更新 " + + t.Name + + " 中的 " + counter - + " descriptions updated on " - + t.Name; + + " 个说明"; } else { - msg = counter + " descriptions updated on " + t.Name; + msg = "已更新 " + t.Name + " 中的 " + counter + " 个说明"; } - // toggle the 'Running Macro' spinbox + //切换“正在运行宏”指示器 ScriptHelper.WaitFormVisible = false; - Interaction.MsgBox(msg, MsgBoxStyle.Information, "Update Metadata Descriptions"); - // toggle the 'Running Macro' spinbox + Interaction.MsgBox(msg, MsgBoxStyle.Information, "更新元数据说明"); + //切换“正在运行宏”指示器 ScriptHelper.WaitFormVisible = true; conn.Close(); } @@ -562,16 +563,16 @@ Either: ### 说明 -脚本使用 WinForms 提示输入 Databricks 个人访问令牌,用于对 Databricks 进行身份验证。 对于每个选中的表,脚本会从该表分区的 M 查询中提取 Databricks 连接字符串信息,以及架构名和表名。 然后脚本通过 Spark ODBC 驱动向 Databricks 发送 SQL 查询,查询 information_schema 表,返回在 Unity Catalog 中定义的表描述。 随后会将该描述更新到语义模型中的表描述。 脚本还会对所选表发送第二个使用 DESCRIBE 命令的 SQL 查询,以获取列描述。 这些结果会被循环遍历,并在模型中添加描述。 脚本在每个选定表上运行完成后,会显示一个对话框,告知已更新的描述数量。 +该脚本使用 WinForms 弹窗提示输入 Databricks 个人访问令牌,用于对 Databricks 进行身份验证。 对每个选中的表,脚本都会从其分区中的 M 查询提取 Databricks 连接字符串信息,以及架构名和表名。 随后脚本会通过 Spark ODBC 驱动程序向 Databricks 发送 SQL 查询,查询 information_schema 表,从而获取 Unity Catalog 中定义的表说明。 然后会将其更新到语义模型中的表说明。 还会对所选表再发送一条使用 DESCRIBE 命令的 SQL 查询,以获取列说明。 随后会遍历这些结果,并在模型中补充说明。 脚本在每个选定的表上运行完毕后,会弹出对话框,显示已更新的描述数量。 ## 输出示例
- Prompt for Databricks personal access token
图 1:脚本会提示你输入 Databricks 个人访问令牌,以便向 Databricks 验证身份。
+ Prompt for Databricks personal access token
图 1:脚本会提示你输入 Databricks 个人访问令牌,以便向 Databricks 进行身份验证。
- The number of descriptions updated
图 2:脚本在每个选定表上运行完成后,会显示已更新的描述条数。
+ The number of descriptions updated
图 2:脚本对每个选定的表运行完毕后,会显示已更新的描述数量。
diff --git a/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlol-to-import.md b/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlol-to-import.md index b8e0aaed..4e525ce9 100644 --- a/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlol-to-import.md +++ b/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlol-to-import.md @@ -1,6 +1,6 @@ --- uid: script-convert-dlol-to-import -title: 将 OneLake 上的 Direct Lake 转换为导入模式 +title: 将 OneLake 上的 Direct Lake 表转换为导入模式 author: Morten Lønskov updated: 2025-06-25 applies_to: @@ -15,11 +15,11 @@ applies_to: ## 脚本用途 -此脚本将 OneLake 上的 Direct Lake(DL/OL)转换为导入模式表。 正如 [Direct Lake guidance article](xref:direct-lake-guidance) 中所述,我们需要将这类表上的 [EntityPartition](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.entitypartitionsource?view=analysisservices-dotnet) 替换为导入模式下对应的常规 M 分区。 +此脚本用于将 OneLake 上的 Direct Lake(DL/OL)表转换为导入模式表。 如 [Direct Lake 指南文章](xref:direct-lake-guidance) 中所述,我们需要将此类表上的 [EntityPartition](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.entitypartitionsource?view=analysisservices-dotnet) 替换为导入模式下相应的常规 M 分区。 -## 先决条件 +## 前提条件 -你需要 **SQL Endpoint**,以及 Fabric Warehouse 或 Lakehouse 的 **名称**。 两者都可以在 Fabric 门户中找到。 +你需要 **SQL Endpoint**,以及 Fabric **Warehouse** 或 **Lakehouse** 的 **名称**。 这两项都可以在 Fabric 门户中找到。 你还需要知道要连接的表/物化视图的 **Schema**。 对于 Lakehouse,默认值为 dbo。 @@ -31,8 +31,8 @@ applies_to: // =================================================================================== // 将 OneLake 上的 Direct Lake 表转换回导入模式 // ---------------------------------------- -// 此脚本会将选中的表或所有表从 OneLake 上的 Direct Lake 转换为导入模式 -// 它会添加名为 SQLEndpoint 的共享表达式,并在不再需要时删除现有的 DatabaseQuery +// 此脚本会将选定的表或所有表从 OneLake 上的 Direct Lake 转换为导入模式 +// 它会添加一个名为 SQLEndpoint 的共享表达式,并在不再需要时删除现有的 DatabaseQuery // =================================================================================== using System; using System.Linq; @@ -62,7 +62,7 @@ public class ScopeSelectionDialog : Form Controls.Add(layout); layout.Controls.Add(new Label { - Text = $"你已选择 {selectedCount} 个表,\n模型中共有 {totalCount} 个 Direct Lake 表。", + Text = $"你已选择 {selectedCount} 个表(s),\n并且模型中共有 {totalCount} 个 Direct Lake 表(s)。", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }); @@ -73,7 +73,7 @@ public class ScopeSelectionDialog : Form }; var btnOnly = new Button { - Text = "仅转换所选表", AutoSize = true, + Text = "仅选定的表", AutoSize = true, DialogResult = DialogResult.OK }; btnOnly.Click += (s, e) => SelectedOption = ScopeOption.OnlySelected; @@ -99,7 +99,7 @@ public class ScopeSelectionDialog : Form } // ------------------------------------------------------------------- -// 2) SQL 导入对话框(现在需要 Schema) +// 2) SQL 导入对话框(现需 Schema) // ------------------------------------------------------------------- public class SqlImportDialog : Form { @@ -110,7 +110,7 @@ public class SqlImportDialog : Form public SqlImportDialog(string endpoint, string db, string schema) { - Text = "转换 Direct Lake → 导入"; + Text = "转换 Direct Lake → Import"; AutoSize = true; AutoSizeMode = AutoSizeMode.GrowAndShrink; StartPosition = FormStartPosition.CenterParent; Padding = new Padding(20); @@ -162,7 +162,7 @@ public class SqlImportDialog : Form AcceptButton = okButton; CancelButton = cancel; - // 仅当三个字段都非空时才启用 OK + // 仅当这三个字段都非空时才启用“OK” SqlEndpoint.TextChanged += Validate; DatabaseName.TextChanged += Validate; Schema.TextChanged += Validate; @@ -191,7 +191,7 @@ var allDirectLake = Model.Tables && t.Partitions[0].Mode == ModeType.DirectLake) .ToList(); -// 3.2) 以及你已选择的 Direct Lake 表 +// 3.2) 以及你选中的表 var selectedDirect = Selected.Tables .Cast
EnableRefreshPolicy Actualizar esta tabla de forma incrementalIndica si hay una política de actualización habilitada para la tabla.

En Tabular Editor, otras propiedades de la política de actualización solo serán visibles si este valor se establece en True.
Indica si la tabla tiene habilitada una política de actualización.

En Tabular Editor, el resto de las propiedades de la política de actualización solo se mostrarán si este valor se establece en True.
True o False.
IncrementalGranularity Período de actualización incrementalLa granularidad de la ventana incremental.

Ejemplo:
"Actualice los datos de los últimos 30 días antes de la fecha de actualización."
Day, Month, Quarter o Year. Debe ser menor o igual que el valor de IncrementalGranularity.La granularidad de la ventana incremental.

Ejemplo:
"Actualizar los datos de los últimos 30 días anteriores a la fecha de actualización."
Day, Month, Quarter o Year. Debe ser menor o igual que el IncrementalGranularity.
IncrementalPeriods Número de períodos de actualización incrementalEl número de períodos de la ventana incremental.

Ejemplo:
"Actualice los datos de los últimos 30 días antes de la fecha de actualización."
Un número entero que indica la cantidad de períodos de IncrementalGranularity. Debe definir un período total inferior a RollingWindowPeriodsEl número de períodos de la ventana incremental.

Ejemplo:
"Actualizar los datos de los últimos 30 días antes de la fecha de actualización."
Un número entero que indique el número de períodos de IncrementalGranularity. Debe definir un período total inferior a RollingWindowPeriods
IncrementalPeriodsOffsetActualizar solo los días completosActualizar solo días completos El desplazamiento que se aplicará a IncrementalPeriods.

Ejemplo para:
IncrementalPeriodsOffset=-1;
IncrementalPeriods = 30;
IncrementalGranularity = Day:
"Actualizar solo los datos de los últimos 30 días, desde el día anterior a la fecha de actualización.
Un número entero que indica la cantidad de períodos de IncrementalGranularity para desplazar la ventana incremental.Un número entero con el número de períodos de IncrementalGranularity para desplazar la ventana incremental.
ModeObtener los datos más recientes en tiempo real con DirectQueryEspecifica si la actualización incremental está configurada solo con particiones de importación o también con una partición de DirectQuery, para crear una "tabla híbrida".Obtenga los datos más recientes en tiempo real con DirectQueryEspecifica si la actualización incremental se configura únicamente con particiones de importación o también con una partición de DirectQuery, para dar como resultado una "tabla híbrida". Import o Hybrid.
PollingExpression
(Opcional)
Detectar cambios en los datosLa expresión M utilizada para detectar cambios en una columna específica, como LastUpdateDate.

En Tabular Editor, la Polling Expression se puede ver y modificar desde la ventana del Editor de expresiones seleccionándola en el menú desplegable de la esquina superior izquierda.
Una expresión M válida que devuelve un valor escalar de la fecha más reciente de una columna. Se actualizarán todos los registros de las particiones activas de la ventana incremental que contengan ese valor en la columna.

Los registros de las particiones archivadas no se actualizan.
La expresión M que se usa para detectar cambios en una columna específica, como LastUpdateDate

En Tabular Editor, la PollingExpression se puede ver y modificar desde la ventana del Editor de expresiones seleccionándola en el menú desplegable de la esquina superior izquierda.
Una expresión M válida que devuelve un valor escalar de la fecha más reciente de una columna. Se actualizarán todos los registros de las particiones activas de la ventana incremental que contengan ese valor en la columna.

Los registros de las particiones archivadas no se actualizan.
RollingWindowGranularity
() .Where(t => t.Partitions.Count == 1 @@ -199,7 +199,7 @@ var selectedDirect = Selected.Tables && t.Partitions[0].Mode == ModeType.DirectLake) .ToList(); -// 3.3) 询问范围 +// 3.3) 询问转换范围 var scopeDialog = new ScopeSelectionDialog(selectedDirect.Count, allDirectLake.Count); var dr = scopeDialog.ShowDialog(); if (dr == DialogResult.Cancel || scopeDialog.SelectedOption == ScopeSelectionDialog.ScopeOption.Cancel) @@ -216,11 +216,11 @@ if (tablesToConvert.Count == 0) return; } -// 3.4) 询问连接信息 + Schema +// 3.4) 询问连接信息和 Schema var sqlDialog = new SqlImportDialog("", "", ""); if (sqlDialog.ShowDialog() == DialogResult.Cancel) return; -// 3.5) 新增或更新共享表达式 "SQLEndpoint" +// 3.5) 创建或更新共享表达式 "SQLEndpoint" const string sqlTemplate = @"let endpoint = Sql.Database(""{0}"",""{1}"") in @@ -253,33 +253,33 @@ foreach (var table in tablesToConvert) oldP.Delete(); } -// 3.8) 如果转换的是**整个模型**,删除旧的 DatabaseQuery 表达式 +// 3.8) 如果转换的是**整个模型**,则删除旧的 DatabaseQuery 表达式 if (isAllTables) { var oldDbq = Model.Expressions.FirstOrDefault(e => e.Name == "DatabaseQuery"); if (oldDbq != null) - oldDbq.Delete(); // TE3 API: Expression.Delete() removes it from the model + oldDbq.Delete(); // TE3 API:Expression.Delete() 会将其从模型中移除 } -// 3.9) 确保默认模式为导入模式 +// 3.9) 确保默认模式为 Import Model.DefaultMode = ModeType.Import; -Info("转换完成:Direct Lake → 导入" + - (isAllTables ? " (已删除 DatabaseQuery)" : "") + "。"); +Info("转换完成:Direct Lake → Import" + + (isAllTables ? " (DatabaseQuery 已移除)" : "") + "."); ``` ### 说明 -脚本会先提示你选择转换范围:只转换所选表,或转换模型中的所有表。 然后,它会识别在所选范围内当前处于 Direct Lake 模式的表。 如果没找到符合条件的表,或者你取消了对话框,脚本就会停止运行。 +脚本首先会提示你确定转换范围:是只转换选定的表,还是转换模型中的所有表。 然后,脚本会识别所选范围内当前处于 Direct Lake 模式的表。 如果没找到适用的表,或者你取消了对话框,脚本就会终止。 -接着会提示你输入 SQL analytics endpoint、Lakehouse 或 Warehouse 的名称,以及必填的 Schema 名称。 脚本会确保这三个字段均已填写后,才允许你继续。 +接着,脚本会提示你输入 SQL analytics endpoint、Lakehouse 或 Warehouse 的名称,以及必填的 Schema 名称。 脚本会确保这三个字段都已填写后,才允许你继续。 -接下来,脚本会使用你提供的连接信息创建或更新名为 `SQLEndpoint` 的共享表达式。 该表达式使用 `Sql.Database` 连接器来访问 Lakehouse 或 Warehouse。 +接下来,脚本会使用提供的连接详细信息创建或更新一个名为 `SQLEndpoint` 的共享表达式。 此表达式使用 `Sql.Database` 连接器访问 Lakehouse 或 Warehouse。 -对于每个要转换的表,脚本会创建一个新的导入模式 M 分区:引用 `SQLEndpoint` 表达式,并使用指定的 Schema 和表名。 现有的 Direct Lake 分区会先被重命名,然后删除,最终仅保留新的导入分区。 +对于每个要转换的表,脚本都会创建一个新的导入模式 M 分区,该分区引用 `SQLEndpoint` 表达式,并使用指定的 Schema 和表名。 现有的 Direct Lake 分区会先被重命名,然后被删除,最终只保留新的导入分区。 -最后,如果你选择转换模型中的所有 Direct Lake 表,脚本会检查是否存在名为 `DatabaseQuery` 的共享表达式;若存在则删除。 然后把模型的默认存储模式设置为导入模式,并显示一条确认信息。 +最后,如果你选择转换模型中的所有 Direct Lake 表,脚本会检查是否存在名为 `DatabaseQuery` 的共享表达式;如果存在,就将其删除。 随后,模型的默认存储模式会设置为导入模式,并显示确认信息。 -## AI 使用免责声明 +## AI 使用声明 -此脚本在 LLM 的帮助下创建。 +此脚本在大语言模型的协助下创建。 diff --git a/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlsql-to-dlol.md b/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlsql-to-dlol.md index dc7bb2ae..e0465c83 100644 --- a/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlsql-to-dlol.md +++ b/localizedContent/zh/content/features/CSharpScripts/Advanced/script-convert-dlsql-to-dlol.md @@ -1,6 +1,6 @@ --- uid: script-convert-dlsql-to-dlol -title: 将 Direct Lake on SQL 转换为 OneLake +title: 将 SQL 上的 Direct Lake 转换到 OneLake author: Daniel Otykier updated: 2025-06-20 applies_to: @@ -11,7 +11,7 @@ applies_to: full: true --- -# 将 Direct Lake on SQL 转换为 OneLake +# 将 SQL 上的 Direct Lake 转换到 OneLake ## 脚本用途 diff --git a/localizedContent/zh/content/features/CSharpScripts/csharp-script-library-advanced.md b/localizedContent/zh/content/features/CSharpScripts/csharp-script-library-advanced.md index 3591fe0f..8ac20578 100644 --- a/localizedContent/zh/content/features/CSharpScripts/csharp-script-library-advanced.md +++ b/localizedContent/zh/content/features/CSharpScripts/csharp-script-library-advanced.md @@ -1,6 +1,6 @@ --- uid: script-library-advanced -title: 高级 C# 脚本 +title: 高级 C# Script author: Morten Lønskov updated: 2026-02-20 applies_to: @@ -11,27 +11,27 @@ applies_to: full: true --- -# C# Script 库: 高级脚本 +# C# Script 库:高级脚本 -这些脚本更高级,功能更复杂,需要对 C# 语言和 TOM 有更深入的理解。 它们更难修改,因此建议在你已熟悉 Tabular Editor 中 C# Script 的基础之后再使用。 +这些脚本更加高级,功能也更复杂,需要对 C# 语言和 TOM 有更深入的理解。 这些脚本更难修改,因此建议你在熟悉 Tabular Editor 中的 C# Script 基础后再使用。

-|
脚本名称
| 用途 | 使用场景 | -| ----------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------ | -| [统计模型对象](xref:script-count-things) | 按类型统计模型中各类对象的数量。 | 当你需要概览模型内容,或想按类型统计对象数量时。 | -| [在网格中输出对象详细信息](xref:script-output-things) | 以网格视图输出对象详细信息。 | 当你需要在网格视图中输出对象详细信息以便检查时。 | -| [创建日期表](xref:script-create-date-table) | 基于模型中选定的日期列创建格式化的日期表。 | 当你需要基于模板创建新的日期表时。 | -| [创建 M 参数(自动替换)](xref:script-create-and-replace-parameter) | 创建新的 M 参数,并自动将其添加到 M 分区。 | 当你想用动态 M 参数替换多个分区中的字符串(例如连接字符串)时。 | -| [格式化 Power Query](xref:script-format-power-query) | 使用 powerqueryformatter.com API 格式化所选 M 分区中的 Power Query。 | 当 Power Query 很复杂,需要提高可读性以便阅读或修改时。 | -| [实施增量刷新](xref:script-implement-incremental-refresh) | 通过 UI 对话框中的参数自动配置增量刷新。 | 当你需要实施增量刷新,但不太熟悉表设置中的配置方式时。 | -| [删除包含错误的度量值](xref:script-remove-measures-with-error) | 创建新的 M 参数,并自动将其添加到 M 分区。 | 当你想用动态 M 参数替换多个分区中的字符串(例如连接字符串)时。 | -| [在所选度量值中查找/替换](xref:script-find-replace) | 在所选度量值的 DAX 中搜索子字符串,并替换为另一个子字符串。 | 当你需要在多个 DAX 度量值中快速查找/替换值时(例如 `CALCULATE` 筛选器或失效的对象引用)。 | -| [Databricks 语义模型设置](xref:script-databricks-semantic-model-set-up) | 为表和列指定友好名称,并设置列最佳实践 | 当你需要让 Databricks 对象名称更便于用户理解时。 | -| [创建 Databricks 关系](xref:script-create-databricks-relationships) | 基于 Databricks Unity Catalog 中的主键和外键定义创建关系 | 当你想复用 Unity Catalog 中已定义的 Databricks 关系时。 | -| [添加 Databricks 元数据说明](xref:script-add-databricks-metadata-descriptions) | 基于 Databricks Unity Catalog 更新表和列说明 | 当你想复用 Unity Catalog 中已定义的 Databricks 表和列注释时。 | -| [将 DL/SQL 转换为 DL/OL](xref:script-convert-dlsql-to-dlol) | 将 Direct Lake over SQL 模型的分区更改为 Direct Lake over OneLake | 可用于轻松迁移到 Direct Lake over OneLake | -| [将导入模式转换为 DL/OL](xref:script-convert-import-to-dlol) | 将 Import 模型的分区更改为基于 OneLake 的 Direct Lake | 有助于轻松迁移到基于 OneLake 的 Direct Lake | -| [将 DL/OL 转换为导入模式](xref:script-convert-dlol-to-import) | 将 OneLake 上的 Direct Lake 模型分区切换到导入模式 | 便于从 OneLake 上的 Direct Lake 模式轻松迁移到导入模式 | -| [实现用户定义的聚合](xref:script-implement-user-defined-aggregations) | 自动为所选事实表配置用户定义的聚合。 | 当需要实现用户定义的聚合模式,但又不想手动执行每个配置步骤时。 | \ No newline at end of file +|
脚本名称
| 用途 | 适用场景 | +| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------ | +| [统计模型对象数量](xref:script-count-things) | 统计模型中各类对象的数量。 | 当你需要概览模型内容,或需要按类型统计对象数量时。 | +| [在网格中输出对象详细信息](xref:script-output-things) | 在网格视图中输出对象详细信息。 | 当你需要在网格视图中输出对象详细信息以便检查时。 | +| [创建日期表](xref:script-create-date-table) | 根据模型中选定的日期列创建带格式的日期表。 | 当你需要基于模板创建新的日期表时。 | +| [创建 M 参数(自动替换)](xref:script-create-and-replace-parameter) | 创建新的 M 参数,并自动将其添加到 M 分区中。 | 当你想用动态 M 参数替换多个分区中的字符串(例如连接字符串)时。 | +| [格式化 Power Query](xref:script-format-power-query) | 使用 powerqueryformatter.com API 格式化所选 M 分区的 Power Query。 | 当 Power Query 很复杂,需要让它更便于阅读或修改时。 | +| [实现增量刷新](xref:script-implement-incremental-refresh) | 使用 UI 对话框中的参数自动配置增量刷新。 | 当你需要实现增量刷新,但不太熟悉表设置中的相关配置时。 | +| [删除出错的度量值](xref:script-remove-measures-with-error) | 创建新的 M 参数,并自动将其添加到 M 分区。 | 当你想用动态 M 参数替换多个分区中的字符串(例如连接字符串)时。 | +| [在所选度量值中查找/替换](xref:script-find-replace) | 在所选度量值的 DAX 中搜索子字符串,并将其替换为另一个子字符串。 | 当你需要在多个 DAX 度量值中快速查找/替换值时(例如 `CALCULATE` 筛选器或无效的对象引用)。 | +| [设置 Databricks 语义模型](xref:script-databricks-semantic-model-set-up) | 为表和列设置更友好的名称,并应用列最佳实践 | 当需要让 Databricks 对象名称更友好、更易读时。 | +| [创建 Databricks 关系](xref:script-create-databricks-relationships) | 根据 Databricks Unity Catalog 中的主键和外键定义创建关系 | 当你想复用已在 Unity Catalog 中定义的 Databricks 关系时。 | +| [添加 Databricks 元数据描述](xref:script-add-databricks-metadata-descriptions) | 根据 Databricks Unity Catalog 更新表和列的描述 | 当你想重用已在 Unity Catalog 中定义的 Databricks 表和列注释时。 | +| [将 Direct Lake over SQL 转换为 Direct Lake over OneLake](xref:script-convert-dlsql-to-dlol) | 将 Direct Lake over SQL 模型的分区更改为 Direct Lake over OneLake | 适用于轻松迁移到 Direct Lake over OneLake | +| [将导入模式转换为 DL/OL](xref:script-convert-import-to-dlol) | 将导入模式模型的分区更改为 Direct Lake over OneLake | 便于轻松迁移到 OneLake 上的 Direct Lake | +| [将 DL/OL 转换为导入模式](xref:script-convert-dlol-to-import) | 将 OneLake 上的 Direct Lake 模型分区切换为导入模式 | 便于轻松从 OneLake 上的 Direct Lake 迁移到导入模式 | +| [实现用户自定义聚合](xref:script-implement-user-defined-aggregations) | 自动为所选事实表配置用户自定义聚合。 | 当您希望在不手动执行每个配置步骤的情况下实现用户自定义聚合模式时。 | \ No newline at end of file diff --git a/localizedContent/zh/content/features/Semantic-Model/direct-lake-sql-model.md b/localizedContent/zh/content/features/Semantic-Model/direct-lake-sql-model.md index 9ba53447..66c37b6b 100644 --- a/localizedContent/zh/content/features/Semantic-Model/direct-lake-sql-model.md +++ b/localizedContent/zh/content/features/Semantic-Model/direct-lake-sql-model.md @@ -11,7 +11,7 @@ applies_to: editions: - edition: Desktop none: true - - edition: Business + - edition: 商业版 none: true - edition: Enterprise full: true diff --git a/localizedContent/zh/content/features/Useful-script-snippets.md b/localizedContent/zh/content/features/Useful-script-snippets.md index dc383fb5..1972dfd5 100644 --- a/localizedContent/zh/content/features/Useful-script-snippets.md +++ b/localizedContent/zh/content/features/Useful-script-snippets.md @@ -18,16 +18,16 @@ applies_to: # 实用脚本片段 -这里汇总了一些小脚本片段,帮助你开始使用 Tabular Editor 的 [高级脚本功能](/Advanced-Scripting)。 其中许多脚本都适合保存为 [自定义操作](/Custom-Actions),这样你就能从上下文菜单中轻松重复使用它们。' +这里汇总了一些简短的脚本片段,帮助你快速上手 Tabular Editor 的 [高级脚本功能](/Advanced-Scripting)。 其中很多脚本都适合保存为 [自定义操作](/Custom-Actions),这样你就可以通过上下文菜单轻松复用它们。' -另外,也别忘了看看我们的脚本库 @csharp-script-library,里面有更多贴近实战的示例,展示你可以用 Tabular Editor 的脚本能力做些什么。 +另外,也别忘了看看我们的脚本库 @csharp-script-library,里面有更多贴近实际场景的示例,展示了你可以如何利用 Tabular Editor 的脚本功能。 *** ## 从列创建度量值 ```csharp -// 为每个当前选中的列创建一个 SUM 度量值,并隐藏该列。 +// 为当前选中的每一列创建一个 SUM 度量值,并隐藏该列。 foreach(var c in Selected.Columns) { var newMeasure = c.Table.AddMeasure( @@ -39,21 +39,21 @@ foreach(var c in Selected.Columns) // 为新度量值设置格式字符串: newMeasure.FormatString = "0.00"; - // 提供一些说明文档: - newMeasure.Description = "此度量值是对列求和 " + c.DaxObjectFullName; + // 添加一些说明: + newMeasure.Description = "这个度量值是列 " + c.DaxObjectFullName + " 的总和"; - // 隐藏基础列: + // 隐藏原始列: c.IsHidden = true; } ``` -此片段使用 `
.AddMeasure(, , )` 函数,在表上创建一个新的度量值。 我们使用 `DaxObjectFullName` 属性来获取列的完全限定名称,用于 DAX 表达式:`'TableName'[ColumnName]`。 +这个片段使用 `
.AddMeasure(, , )` 函数,在表中创建一个新的度量值。 我们使用 `DaxObjectFullName` 属性来获取列的完全限定名称,以便在 DAX 表达式中使用:`'TableName'[ColumnName]`。 *** ## 生成时间智能度量值 -首先,为各个时间智能汇总分别创建自定义操作。 例如: +首先,为各个时间智能聚合分别创建自定义操作。 例如: ```csharp // 为每个选中的度量值创建一个 TOTALYTD 度量值。 @@ -66,86 +66,86 @@ foreach(var m in Selected.Measures) { } ``` -这里我们使用 `DaxObjectName` 属性来生成用于 DAX 表达式的非限定引用,因为这是一个度量值:`[MeasureName]`。 将其保存为名为 "Time Intelligence\Create YTD measure" 的自定义操作,并将其应用于度量值。 按同样方式为 MTD、LY,以及你需要的其他项创建操作。 然后,创建下面这个新操作: +这里我们使用 `DaxObjectName` 属性来生成用于 DAX 表达式的不带限定符的引用,因为这是一个度量值:`[MeasureName]`。 将其保存为一个适用于度量值的时间智能自定义操作,命名为 "Time Intelligence\Create YTD measure"。 为 MTD、LY 以及其他你需要的类型创建类似的操作。 然后,新建一个操作,并填入下面的脚本: ```csharp -// 调用所有时间智能自定义操作: -CustomAction(@"Time Intelligence\\Create YTD measure"); -CustomAction(@"Time Intelligence\\Create MTD measure"); -CustomAction(@"Time Intelligence\\Create LY measure"); +// 调用所有时间智能自定义操作: +CustomAction(@"Time Intelligence\Create YTD measure"); +CustomAction(@"Time Intelligence\Create MTD measure"); +CustomAction(@"Time Intelligence\Create LY measure"); ``` -这展示了如何在另一个操作内部执行一个(或多个)自定义操作(注意避免循环引用——这会导致 Tabular Editor 崩溃)。 将其另存为新的自定义操作“时间智能\以上全部”,即可一键生成所有时间智能度量值: +这展示了如何在一个操作中调用另一个操作来执行一个(或多个)自定义操作(注意避免循环引用,否则会导致 Tabular Editor 崩溃)。 将其另存为新的自定义操作“Time Intelligence\\All of the above”,即可通过一次单击轻松生成所有时间智能度量值: ![image](https://user-images.githubusercontent.com/8976200/36632257-5565c8ca-197c-11e8-8498-82667b6e1049.png) -当然,您也可以将所有时间智能计算放入一个脚本中,如下所示: +当然,你也可以将所有时间智能计算放入一个脚本中,如下所示: ```csharp var dateColumn = "'Date'[Date]"; // 为每个所选度量值创建时间智能度量值: foreach(var m in Selected.Measures) { - // Year-to-date: + // 年初至今: m.Table.AddMeasure( - m.Name + " YTD", // Name - "TOTALYTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.Name + " YTD", // 名称 + "TOTALYTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); - // Previous year: + // 上年同期: m.Table.AddMeasure( - m.Name + " PY", // Name - "CALCULATE(" + m.DaxObjectName + ", SAMEPERIODLASTYEAR(" + dateColumn + "))", // DAX expression + m.Name + " PY", // 名称 + "CALCULATE(" + m.DaxObjectName + ", SAMEPERIODLASTYEAR(" + dateColumn + "))", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); - // Year-over-year + // 同比: m.Table.AddMeasure( - m.Name + " YoY", // Name - m.DaxObjectName + " - [" + m.Name + " PY]", // DAX expression + m.Name + " YoY", // 名称 + m.DaxObjectName + " - [" + m.Name + " PY]", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); - // Year-over-year %: + // 同比%: m.Table.AddMeasure( - m.Name + " YoY%", // Name - "DIVIDE([" + m.Name + " YoY], [" + m.Name + " PY])", // DAX expression + m.Name + " YoY%", // 名称 + "DIVIDE([" + m.Name + " YoY], [" + m.Name + " PY])", // DAX 表达式 m.DisplayFolder // 显示文件夹 - ).FormatString = "0.0 %"; // Set format string as percentage + ).FormatString = "0.0 %"; // 将格式字符串设置为百分比 - // Quarter-to-date: + // 季度至今: m.Table.AddMeasure( - m.Name + " QTD", // Name - "TOTALQTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.Name + " QTD", // 名称 + "TOTALQTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); - // Month-to-date: + // 本月至今: m.Table.AddMeasure( - m.Name + " MTD", // Name - "TOTALMTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX expression + m.Name + " MTD", // 名称 + "TOTALMTD(" + m.DaxObjectName + ", " + dateColumn + ")", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); } ``` -### 包含其他属性 +### 包含附加属性 -如果您想为新建的度量值设置其他属性,可以将上述脚本修改如下: +如果你想为新建的度量值设置其他属性,可以将上述脚本修改如下: ```csharp // 为每个所选度量值创建一个 TOTALYTD 度量值。 foreach(var m in Selected.Measures) { var newMeasure = m.Table.AddMeasure( - m.Name + " YTD", // Name - "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX expression + m.Name + " YTD", // 名称 + "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); - newMeasure.FormatString = m.FormatString; // 从原始度量值复制格式字符串 + newMeasure.FormatString = m.FormatString; // 从原度量值复制格式字符串 foreach(var c in Model.Cultures) { - newMeasure.TranslatedNames[c] = m.TranslatedNames[c] + " YTD"; // 为每个区域设置复制翻译名称 - newMeasure.TranslatedDisplayFolders[c] = m.TranslatedDisplayFolders[c]; // 复制翻译后的显示文件夹 + newMeasure.TranslatedNames[c] = m.TranslatedNames[c] + " YTD"; // 为每种区域设置复制已翻译的名称 + newMeasure.TranslatedDisplayFolders[c] = m.TranslatedDisplayFolders[c]; // 复制已翻译的显示文件夹 } } ``` @@ -154,9 +154,9 @@ foreach(var m in Selected.Measures) { ## 设置默认翻译 -有时,为所有(可见的)对象应用默认翻译会很方便。 在这种情况下,默认翻译就是对象的原始名称/说明/显示文件夹。 这样做的一个好处是:以 JSON 格式导出翻译时会包含所有翻译对象,即可用于 [SSAS Tabular Translator](https://www.sqlbi.com/tools/ssas-tabular-translator/)。 +有时,为所有(可见)对象应用默认翻译会很有用。 在这种情况下,默认翻译其实就是对象的原始名称/描述/显示文件夹。 这样做的一个好处是:以 JSON 格式导出翻译时会包含所有翻译对象,例如可用于 [SSAS Tabular Translator](https://www.sqlbi.com/tools/ssas-tabular-translator/)。 -下面的脚本会遍历模型中的所有区域设置;对每个可见对象,如果还没有翻译,就会为其分配默认值: +以下脚本会遍历模型中的所有区域设置;对于每个可见对象,若尚无翻译,则会为其赋予默认值: ```csharp // 将默认翻译应用到模型中所有区域设置下的所有(可见)可翻译对象: @@ -179,13 +179,13 @@ foreach(var culture in Model.Cultures) void ApplyDefaultTranslation(ITranslatableObject obj, Culture culture) { - // 仅在尚不存在翻译时才应用默认翻译: + // 仅当还没有翻译时,才应用默认翻译: if(string.IsNullOrEmpty(obj.TranslatedNames[culture])) { // 默认名称翻译: obj.TranslatedNames[culture] = obj.Name; - // 默认说明翻译: + // 默认描述翻译: var dObj = obj as IDescriptionObject; if(dObj != null && string.IsNullOrEmpty(obj.TranslatedDescriptions[culture]) && !string.IsNullOrEmpty(dObj.Description)) @@ -208,7 +208,7 @@ void ApplyDefaultTranslation(ITranslatableObject obj, Culture culture) ## 处理透视 -度量值、列、层级结构和表都提供 `InPerspective` 属性。该属性会为模型中的每个透视保存一个 True/False 值,用于指示给定对象是否属于该透视。 例如: +度量值、列、层级结构和表都提供 `InPerspective` 属性。该属性会为模型中的每个透视保存一个 True/False 值,用来指示给定对象是否属于该透视。 比如: ```csharp foreach(var measure in Selected.Measures) @@ -218,23 +218,23 @@ foreach(var measure in Selected.Measures) } ``` -上面的脚本确保所有选中的度量值在 "Inventory" 透视中可见,并在 "Reseller Operation" 透视中隐藏。 +上述脚本可确保所有选中的度量值在 "Inventory" 透视中可见,并在 "Reseller Operation" 透视中隐藏。 -除了获取/设置单个透视中的成员关系之外,`InPerspective` 属性还支持以下方法: +除了获取/设置单个透视中的成员关系外,`InPerspective` 属性还支持以下方法: - `<>.InPerspective.None()` - 将对象从所有透视中移除。 -- `<>.InPerspective.All()` - 将对象包含在所有透视中。 -- `<>.CopyFrom(string[] perspectives)` - 将对象包含在所有指定的透视中(包含透视名称的字符串数组)。 +- `<>.InPerspective.All()` - 将对象加入所有透视。 +- `<>.CopyFrom(string[] perspectives)` - 将对象加入所有指定的透视中(包含透视名称的字符串数组)。 - `<>.CopyFrom(perspectiveIndexer perspectives)` - 从另一个 `InPerspective` 属性复制透视包含关系。 -后者可用于将一个对象的透视成员关系复制到另一个对象。 例如,假设你有一个基准度量值 [Reseller Total Sales],并希望确保当前选中的所有度量值都在与该基准度量值相同的透视中可见。 下面的脚本即可实现: +后一种方法可用于将透视成员关系从一个对象复制到另一个对象。 例如,假设你有一个基础度量值 [Reseller Total Sales],并希望确保当前选中的所有度量值在与该基础度量值相同的透视中都可见。 下面的脚本即可实现这一点: ```csharp var baseMeasure = Model.Tables["Reseller Sales"].Measures["Reseller Total Sales"]; foreach(var measure in Selected.Measures) { - /* 如果你希望在 'baseMeasure' 被隐藏的那些透视中,也隐藏 'measure', + /* 如果你希望在 'baseMeasure' 被隐藏的那些透视中,'measure' 也一并隐藏, 请取消注释下面这一行: */ // measure.InPerspective.None(); @@ -242,7 +242,7 @@ foreach(var measure in Selected.Measures) } ``` -在通过代码生成新对象时,也可以使用这种技巧。 例如,如果我们希望确保自动生成的时间智能度量值只在其基础度量值所在的透视中可见,我们可以在上一节脚本的基础上扩展为: +这种技巧也可用于通过代码生成新对象。 例如,如果我们希望确保自动生成的时间智能度量值只在与其基础度量值相同的透视中可见,可以在上一节的脚本基础上扩展如下: ```csharp // 为每个选中的度量值创建一个 TOTALYTD 度量值。 @@ -252,7 +252,7 @@ foreach(var m in Selected.Measures) { "TOTALYTD(" + m.DaxObjectName + ", 'Date'[Date])", // DAX 表达式 m.DisplayFolder // 显示文件夹 ); - newMeasure.InPerspective.CopyFrom(m.InPerspective); // 从基础度量值复制透视设置 + newMeasure.InPerspective.CopyFrom(m.InPerspective); // 应用基础度量值的透视设置 } ``` @@ -260,11 +260,11 @@ foreach(var m in Selected.Measures) { ## 生成分区 -如果你需要为某个表进行自定义分区,C# Script 可以帮助你快速生成大量分区。 基本思路是:在表上添加一个注释,其中包含要作为每个分区模板的 SQL 或 M 查询。 脚本随后会按需替换筛选参数。 例如,使用 SQL 分区时,我们可以添加一个名为 `PartitionTemplateSQL` 的注释,并将其值设置为 `SELECT * FROM fact_ResellerSales WHERE CalendarID BETWEEN {0} AND {1}`。 在生成最终分区时,脚本会用实际值替换 `{0}` 和 `{1}` 占位符。 在这个例子中,`CalendarID` 是一个整数。但一般来说,你需要自行确保最终生成的字符串是有效的 SQL(或 M)查询。 +如果你需要对某个表进行自定义分区,C# Script 可以帮助你快速生成大量分区。 基本思路是:为表添加一个注释,其中包含一个 SQL 或 M 查询,作为每个分区的模板。 然后脚本会根据需要替换筛选参数。 例如,使用 SQL 分区时,你可以添加一个名为 `PartitionTemplateSQL` 的注释,并将其值设置为 `SELECT * FROM fact_ResellerSales WHERE CalendarID BETWEEN {0} AND {1}`。 在生成最终分区时,我们的脚本会替换 `{0}` 和 `{1}` 占位符。 在此例中,`CalendarID` 是整数;但一般来说,你需要确保最终得到的字符串是有效的 SQL(或 M)查询。 ![](https://user-images.githubusercontent.com/8976200/70135273-07c6fa00-168a-11ea-84f6-90f0b3498ed8.png) -这里的示例每月生成一个分区。 选择一个已分配 `PartitionTemplateSQL` 注释的表,然后运行脚本。 +这里的示例会按月生成分区。 选择一个带有 `PartitionTemplateSQL` 注释的表,然后运行该脚本。 ```csharp var firstPartition = new DateTime(2018,1,1); // 第一个分区日期 @@ -276,20 +276,20 @@ if(string.IsNullOrEmpty(templateSql)) throw new Exception("No partition template var currentPartition = firstPartition; while(currentPartition <= lastPartition) { - // 基于 currentPartition 日期,计算起止 CalendarID(整数值): + // 根据 currentPartition 日期计算 CalendarID 的起止值(整数): var calendarIdFrom = currentPartition.ToString("yyyyMMdd"); var calendarIdTo = currentPartition.AddMonths(1).AddDays(-1).ToString("yyyyMMdd"); - // 为分区确定一个唯一名称——因为我们按月分区,所以直接使用 yyyyMM: + // 为分区生成唯一名称——由于按月分区,这里直接使用 yyyyMM: var partitionName = Selected.Table.Name + "_" + currentPartition.ToString("yyyyMM"); - // 将分区模板 SQL 中的占位符值替换为实际值: + // 将分区模板 SQL 中的占位符替换为实际值: var partitionQuery = string.Format(templateSql, calendarIdFrom, calendarIdTo); - // 创建分区(如果你使用的是 M 查询模板而不是 SQL,请改用 .AddMPartition): + // 创建分区(如果使用的是 M 查询模板而非 SQL,请改用 .AddMPartition): Selected.Table.AddPartition(partitionName, partitionQuery); - // 递增到下一个月(如需更多或更少的分区,可改为 .AddDays、.AddYears 等): + // 递增到下一个月(如需更多/更少分区,可改用 .AddDays、.AddYears 等): currentPartition = currentPartition.AddMonths(1); } ``` @@ -298,19 +298,19 @@ while(currentPartition <= lastPartition) ## 将对象属性导出到文件 -在某些工作流中,使用 Excel 批量编辑多个对象属性会很有用。 使用以下代码片段将一组标准属性导出到 .TSV 文件,之后还可以再导入(见下文)。 +在某些工作流中,使用 Excel 批量编辑多个对象的属性可能会很有帮助。 使用以下代码片段可以将一组标准属性导出到 .TSV 文件,之后还可以再将其导入(见下文)。 ```csharp -// 导出当前选中对象的属性: +// 导出当前选中对象的属性: var tsv = ExportProperties(Selected); SaveFile("Exported Properties 1.tsv", tsv); ``` -生成的 .TSV 文件在 Excel 中打开后如下所示: +在 Excel 中打开后,生成的 .TSV 文件如下所示: ![image](https://user-images.githubusercontent.com/8976200/36632472-e8e96ef6-197e-11e8-8285-6816b09ad036.png) -第一列(Object)中的内容是该对象的引用。 如果修改了这一列的内容,后续导入属性时可能无法正常工作。 若要更改对象名称,只需修改第二列(Name)的值。 +第一列(Object)中的内容是对该对象的引用。 如果更改了该列内容,后续导入这些属性时可能无法正常进行。 如果你想修改对象名称,只需更改第二列(Name)中的值。 -默认情况下,文件会保存到与 TabularEditor.exe 所在相同的文件夹。 默认情况下,仅导出以下属性(是否适用取决于导出对象的类型): +默认情况下,文件会保存到 TabularEditor.exe 所在的同一文件夹中。 默认情况下,仅导出以下属性(如适用,具体取决于所导出对象的类型): - 名称 - 描述 @@ -319,15 +319,15 @@ SaveFile("Exported Properties 1.tsv", tsv); - 格式字符串 - 数据类型 -要导出不同的属性,请将要导出的属性名称以逗号分隔,作为 `ExportProperties` 的第二个参数提供: +要导出不同的属性,请提供以逗号分隔的属性名称列表,作为 `ExportProperties` 的第 2 个参数: ```csharp -// 导出当前选中表中所有度量值的名称和明细行表达式: +// 导出当前选定表中所有度量值的名称和明细行表达式: var tsv = ExportProperties(Selected.Table.Measures, "Name,DetailRowsExpression"); SaveFile("Exported Properties 2.tsv", tsv); ``` -可用的属性名称可在 [TOM API 文档](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.aspx) 中查看。 这些名称大多与 Tabular Editor 属性网格中显示的名称一致:采用 CamelCase,并移除了空格(也有少数例外,例如,“Hidden” 属性在 TOM API 中名为 `IsHidden`)。 +可用的属性名称可在 [TOM API 文档](https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.tabular.aspx) 中找到。 这些名称大多与 Tabular Editor 属性网格中显示的名称一致,只是采用 CamelCase 并去掉了空格(少数情况例外,例如,“Hidden” 属性在 TOM API 中称为 `IsHidden`)。 要导入属性,请使用以下代码片段: @@ -339,34 +339,34 @@ ImportProperties(tsv); ### 导出带索引的属性 -从 Tabular Editor 2.11.0 开始,`ExportProperties` 和 `ImportProperties` 方法支持带索引的属性。 带索引的属性是指除了属性名之外,还需要一个键的属性。 例如:`myMeasure.TranslatedNames`。 该属性表示为 `myMeasure` 提供名称翻译的所有字符串集合。 在 C# 中,你可以使用索引运算符访问特定区域设置的译名:`myMeasure.TranslatedNames["da-DK"]`。 +从 Tabular Editor 2.11.0 起,`ExportProperties` 和 `ImportProperties` 方法支持带索引的属性。 带索引的属性是指除了属性名称外,还需要一个键值的属性。 一个示例是 `myMeasure.TranslatedNames`。 该属性表示应用于 `myMeasure` 的所有名称翻译字符串的集合。 在 C# 中,你可以使用索引运算符访问特定区域设置的翻译后的标题:`myMeasure.TranslatedNames["da-DK"]`。 -简而言之,你现在可以导出 Tabular 模型中对象的所有翻译、透视信息、注释、扩展属性,以及行级安全性和对象级安全性信息。 +简而言之,你现在可以导出 Tabular 模型中对象的所有翻译、透视信息、注释、扩展属性,以及行级和对象级安全性信息。 -例如,下面的脚本会生成一个 TSV 文件,包含模型中的所有度量值,以及每个度量值在哪些透视中可见: +例如,以下脚本会生成一个 TSV 文件,其中包含模型中所有度量值以及每个度量值在哪些透视中可见的信息: ```csharp var tsv = ExportProperties(Model.AllMeasures, "Name,InPerspective"); SaveFile(@"c:\Project\MeasurePerspectives.tsv", tsv); ``` -在 Excel 中打开后,这个 TSV 文件如下所示: +在 Excel 中打开后,TSV 文件如下所示: -![image](https://user-images.githubusercontent.com/8976200/85208532-956dec80-b331-11ea-8568-32dbd4cc5516.png) +![图片](https://user-images.githubusercontent.com/8976200/85208532-956dec80-b331-11ea-8568-32dbd4cc5516.png) -如上所示,你可以直接在 Excel 中修改内容,保存后再使用 `ImportProperties` 将更新后的值导入回 Tabular Editor。 +正如上面所示,你可以在 Excel 中进行修改,保存后,再使用 `ImportProperties` 将更新后的值加载回 Tabular Editor。 -如果你只想列出某一个或少数几个特定的透视,可以在调用 `ExportProperties` 时的第二个参数中指定它们: +如果你只想列出某一个或少数几个特定的透视,可以在调用 `ExportProperties` 时在第 2 个参数中指定: ```csharp var tsv = ExportProperties(Model.AllMeasures, "Name,InPerspective[Inventory]"); SaveFile(@"c:\Project\MeasurePerspectiveInventory.tsv", tsv); ``` -同样地,翻译、批注等也是如此。 例如,如果您想查看应用到表、列、层次结构、级别和度量值的所有丹麦语翻译: +同理,翻译、注释等也是如此。 例如,如果你想查看应用于表、列、层次结构、级别和度量值的所有丹麦语翻译: ```csharp -// Construct a list of objects: +// 构造对象列表: var objects = new List(); objects.AddRange(Model.Tables); objects.AddRange(Model.AllColumns); @@ -382,20 +382,20 @@ SaveFile(@"c:\Project\ObjectTranslations.tsv", tsv); ## 生成文档 -上面展示的 `ExportProperties` 方法也可用于记录您的模型的全部或部分内容。 下面的代码片段会从表格模型中的所有可见度量值或列提取一组属性,并将其保存为 TSV 文件: +如果你想为模型的全部或部分内容生成文档,也可以使用上面展示的 `ExportProperties` 方法。 下面的代码片段会从 Tabular 模型中所有可见的度量值或列提取一组属性,并将其保存为 TSV 文件: ```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): +// 以 TSV 格式获取其属性(制表符分隔): var tsv = ExportProperties(objects,"Name,ObjectType,Parent,Description,FormatString,DataType,Expression"); -// (Optional) Output to screen (can then be copy-pasted into Excel): +// (可选)输出到屏幕上(然后可以复制粘贴到 Excel 中): // tsv.Output(); -// ...or save the TSV to a file: +// ……或者将 TSV 保存到文件: SaveFile("documentation.tsv", tsv); ``` @@ -403,13 +403,13 @@ SaveFile("documentation.tsv", tsv); ## 从文件生成度量值 -上述导出/导入属性的技巧,适用于你想要对模型中_已有_对象的属性进行批量编辑的场景。 如果你想导入一份尚不存在的度量值列表呢? +如果你想批量编辑模型中_现有_对象的属性,上述导出/导入属性的方法会很有用。 如果你想导入一个尚不存在的度量值列表,该怎么办? -假设你有一个 TSV(制表符分隔值)文件,其中包含你希望导入到现有表格模型中的度量值名称、说明和 DAX 表达式。 你可以使用下面的脚本读取该文件,将其拆分为行与列,并生成这些度量值。 该脚本还会为每个度量值设置一个特殊注释,以便删除之前通过同一脚本创建的度量值。 +假设你有一个 TSV(制表符分隔值)文件,其中包含要导入到现有 Tabular 模型中的度量值名称、说明和 DAX 表达式。 你可以使用下面的脚本读取该文件,将其拆分为行和列,并生成这些度量值。 该脚本还会为每个度量值分配一个特殊注释,这样它就能删除之前使用同一脚本创建的度量值。 ```csharp -var targetTable = Model.Tables["Program"]; // 应保存度量值的表的名称 -var measureMetadata = ReadFile(@"c:\Test\MyMeasures.tsv"); // c:\Test\MyMeasures.tsv 是一个包含标题行和 3 列:Name、Description、Expression 的制表符分隔文件 +var targetTable = Model.Tables["Program"]; // 用于存放这些度量值的表的名称 +var measureMetadata = ReadFile(@"c:\Test\MyMeasures.tsv"); // c:\Test\MyMeasures.tsv 是一个带标题行的制表符分隔文件,包含 3 列:Name、Description、Expression // 删除目标表中所有带有值为 "1" 的 "AUTOGEN" 注释的度量值: foreach(var m in targetTable.Measures.Where(m => m.GetAnnotation("AUTOGEN") == "1").ToList()) @@ -417,38 +417,38 @@ foreach(var m in targetTable.Measures.Where(m => m.GetAnnotation("AUTOGEN") == " m.Delete(); } -// 按 CR 和 LF 字符将文件拆分为行: +// 按 CR 和 LF 字符将文件拆分为多行: var tsvRows = measureMetadata.Split(new[] {'\r','\n'},StringSplitOptions.RemoveEmptyEntries); // 遍历所有行,但跳过第一行: foreach(var row in tsvRows.Skip(1)) { var tsvColumns = row.Split('\t'); // 假设文件使用制表符作为列分隔符 - var name = tsvColumns[0]; // 第 1 列包含度量值名称 - var description = tsvColumns[1]; // 第 2 列包含度量值说明 - var expression = tsvColumns[2]; // 第 3 列包含度量值表达式 + var name = tsvColumns[0]; // 第 1 列是度量值名称 + var description = tsvColumns[1]; // 第 2 列是度量值说明 + var expression = tsvColumns[2]; // 第 3 列是度量值表达式 - // 这假设模型中尚不存在同名的度量值(如果存在,新度量值将获得一个数字后缀): + // 这里假设模型中还没有同名度量值(如果存在,新度量值会自动加上数字后缀): var measure = targetTable.AddMeasure(name); measure.Description = description; measure.Expression = expression; - measure.SetAnnotation("AUTOGEN", "1"); // 在该度量值上设置一个特殊注释,以便下次执行脚本时找到并删除它。 + measure.SetAnnotation("AUTOGEN", "1"); // 在该度量值上设置一个特殊注释,这样下次执行脚本时就能找到它并将其删除。 } ``` -如果你需要将此流程自动化,请将上面的脚本保存到文件中,然后按如下方式使用 [Tabular Editor CLI](/Command-line-Options): +如果你需要将此流程自动化,可以把上面的脚本保存到文件中,然后按如下方式使用 [Tabular Editor CLI](/Command-line-Options): ```powershell start /wait TabularEditor.exe "" -S "" -B "" ``` -例如: +比如: ```powershell start /wait TabularEditor.exe "c:\Projects\AdventureWorks\Model.bim" -S "c:\Projects\AutogenMeasures.cs" -B "c:\Projects\AdventureWorks\Build\Model.bim" ``` -……或者,如希望针对已部署的数据库运行该脚本: +……或者,如果你想针对已部署的数据库运行该脚本: ```powershell start /wait TabularEditor.exe "localhost" "AdventureWorks" -S "c:\Projects\AutogenMeasures.cs" -D "localhost" "AdventureWorks" -O @@ -456,55 +456,55 @@ start /wait TabularEditor.exe "localhost" "AdventureWorks" -S "c:\Projects\Autog *** -## 从分区源元数据创建数据列 +## 根据分区源元数据创建数据列 > [!NOTE] > 下文所述的 `RefreshDataColumns()` 方法仅在 **Tabular Editor 2** 中可用。 在 Tabular Editor 3 中,请改用 **Import Table...** 功能。 -如果某个表使用基于 OLE DB 提供程序数据源的查询分区,我们可以通过执行以下代码片段自动刷新该表的列元数据: +如果某个表使用基于 OLE DB Provider数据源的查询分区,我们可以通过执行以下代码片段来自动刷新该表的列元数据: ```csharp Model.Tables["Reseller Sales"].RefreshDataColumns(); ``` -这在向模型中添加新表时很有用,可以避免在表上逐个手动创建每个数据列。 上面的代码片段假设可以在本地访问分区源,并使用“Reseller Sales”表分区源的现有连接字符串。 上面的代码片段会从分区查询中提取架构,并为源查询中的每一列在表上添加一个数据列。 +这在向模型添加新表时很有用,可避免需要在表上逐个手动创建数据列。 上述代码片段假定可在本地访问该分区源,并使用“Reseller Sales”表分区源的现有连接字符串。 上述代码片段会从分区查询中提取架构信息,并为源查询中的每一列在表中添加一个数据列。 -如果需要为此操作提供不同的连接字符串,也可以在代码片段中指定: +如果需要为此操作提供另一条连接字符串,也可以在该代码片段中进行设置: ```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 +source.ConnectionString = "..."; // 输入要用于元数据刷新的连接字符串 Model.Tables["Reseller Sales"].RefreshDataColumns(); source.ConnectionString = oldConnectionString; ``` -这假设“Reseller Sales”表的分区使用名为“DWH”的 Provider数据源。 +这里假定“Reseller Sales”表的分区使用名为“DWH”的 Provider数据源。 *** ## 格式化 DAX 表达式 -更多信息请参阅 [FormatDax](/FormatDax)。 +更多信息请参见 [FormatDax](/FormatDax)。 ```csharp -// Works in Tabular Editor version 2.13.0 or newer: +// 适用于 Tabular Editor 2.13.0 或更高版本: Selected.Measures.FormatDax(); ``` -替代语法: +另一种语法: ```csharp -// Works in Tabular Editor version 2.13.0 or newer: +// 适用于 Tabular Editor 2.13.0 或更高版本: foreach(var m in Selected.Measures) m.FormatDax(); ``` *** -## 为表生成源列列表 +## 生成表的源列列表 -以下脚本会为当前选中的表输出一份格式良好的源列列表。 如果你想把使用 `SELECT *` 的分区查询替换为显式列清单,这会很有用。 +下面的脚本会为当前选定的表输出一份格式良好的源列清单。 如果你想将使用 `SELECT *` 的分区查询替换为显式列清单,这会很有用。 ```csharp string.Join(",\r\n", @@ -516,38 +516,38 @@ string.Join(",\r\n", *** -## 自动创建关系 +## 自动生成关系 -如果你的团队始终遵循一套固定的命名规范,你会很快发现脚本能发挥更大的作用。 +如果你的团队一直采用一套固定的命名约定,你很快就会发现脚本的威力会更大。 -以下脚本在一个或多个事实表上执行时,会根据列名自动创建到所有相关维度表的关系。 脚本会查找事实表中名称符合 `xxxyyyKey` 模式的列,其中 xxx 是可选的限定词,用于角色扮演用途,yyy 是维度表名称。 在维度表上,必须存在名为 `yyyKey` 的列,并且其数据类型要与事实表上的对应列相同。 例如,名为“ProductKey”的列会与 Product 表中的“ProductKey”列建立关系。 你可以指定一个不同的列名后缀来替代“Key”。 +在一个或多个事实表上执行以下脚本后,脚本会根据列名自动创建与所有相关维度表的关系。 脚本会查找事实表中名称符合 `xxxyyyKey` 模式的列,其中 xxx 是用于角色扮演维度的可选限定符,yyy 是维度表名称。 在维度表中必须有一列名为 `yyyKey`,且其数据类型必须与事实表上的对应列相同。 例如,名为“ProductKey”的列会与 Product 表中的“ProductKey”列建立关系。 你也可以指定其他列名后缀来替换“Key”。 -如果事实表与维度表之间已存在关系,脚本会将新创建的关系设为非活动状态。 +如果事实表与维度表之间已经存在关系,脚本会将新关系创建为非活动状态。 ```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: + // 遍历当前表中的所有 SK 列: foreach(var factColumn in fact.Columns.Where(c => c.Name.EndsWith(keySuffix))) { - // Find the dimension table corresponding to the current SK column: + // 查找与当前 SK 列对应的维度表: 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; @@ -564,7 +564,7 @@ foreach(var fact in Selected.Tables) ## 创建 DumpFilters 度量值 -受[这篇文章](https://www.sqlbi.com/articles/displaying-filter-context-in-power-bi-tooltips/)启发,下面的脚本会在当前所选表中创建一个名为 [DumpFilters] 的度量值: +受[这篇文章](https://www.sqlbi.com/articles/displaying-filter-context-in-power-bi-tooltips/)启发,下面的脚本会在当前选中的表上创建一个名为 [DumpFilters] 的度量值: ```csharp var dax = "VAR MaxFilters = 3 RETURN "; @@ -575,11 +575,11 @@ var dumpFilterDax = @"IF ( VAR ___t = TOPN ( MaxFilters, ___f, {0} ) VAR ___d = CONCATENATEX ( ___t, {0}, "", "" ) VAR ___x = ""{0} = "" & ___d - & IF(___r > MaxFilters, "", ... ["" & ___r & "" items selected]"") & "" "" + & IF(___r > MaxFilters, "", ... ["" & ___r & "" 个项目已选择]"") & "" "" RETURN ___x & UNICHAR(13) & UNICHAR(10) )"; -// 遍历模型的所有列,构建完整的 DAX 表达式: +// 遍历模型中的所有列,以构建完整的 DAX 表达式: bool first = true; foreach(var column in Model.AllColumns) { @@ -596,30 +596,30 @@ Selected.Table.AddMeasure("DumpFilters", dax); ## 将 CamelCase 转换为 Proper Case -在关系数据库中,列和表常见的一种命名方式是 CamelCase。 也就是说,名称不包含空格,每个单词都以大写字母开头。 在 Tabular 模型中,未隐藏的表和列会对业务用户可见,因此通常更适合采用更“易读”的命名方式。 下面的脚本会将 CamelCase 命名转换为 Proper Case。 连续的大写字母序列会保持原样(缩写)。 例如,该脚本会转换以下内容: +在关系数据库中,列和表的一种常见命名方式是 CamelCase。 也就是说,名称中不含任何空格,且每个单词都以大写字母开头。 在 Tabular 模型中,未隐藏的表和列会对业务用户可见,因此通常更适合使用更“易读”的命名方式。 以下脚本会将 CamelCased 名称转换为 Proper Case。 连续的大写字母会原样保留(作为首字母缩写)。 例如,该脚本会将以下内容转换为: -- `CustomerWorkZipcode` 转为 `Customer Work Zipcode` -- `CustomerAccountID` 转为 `Customer Account ID` -- `NSASecurityID` 转为 `NSA Security ID` +- `CustomerWorkZipcode` 转换为 `Customer Work Zipcode` +- `CustomerAccountID` 转换为 `Customer Account ID` +- `NSASecurityID` 转换为 `NSA Security ID` -强烈建议将此脚本保存为适用于所有对象类型的自定义操作(关系、KPI、表格权限和翻译除外,因为这些对象没有可编辑的“Name”属性): +强烈建议将该脚本保存为适用于所有对象类型的自定义操作(关系、KPI、表格权限和翻译除外,因为这些对象没有可编辑的“Name”属性): ```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++) { - // 首字母始终大写: + // 首字母应始终大写: if(i == 0) newName.Append(Char.ToUpper(oldName[i])); - // 两个大写字母后面紧跟一个小写字母的序列,需要在第一个字母后插入空格: + // 两个大写字母后紧跟一个小写字母时,应在第一个字母后插入空格: 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(" "); } - // 其他所有“小写字母 + 大写字母”的序列,需要在第一个字母后插入空格: + // 其他所有“小写字母 + 大写字母”的情况,也应在第一个字母后插入空格: else if(i + 1 < oldName.Length && char.IsLower(oldName[i]) && char.IsUpper(oldName[i+1])) { newName.Append(oldName[i]); @@ -636,22 +636,22 @@ foreach(var obj in Selected.OfType()) { *** -## 导出表与度量值之间的依赖关系 +## 导出表与度量值的依赖关系 -假设你有一个庞大而复杂的模型,并且想知道哪些度量值可能会受到基础数据变更的影响。 +假设你有一个大型且复杂的模型,并希望了解哪些度量值可能会受到底层数据变更的影响。 -下面的脚本会遍历模型中的所有度量值,并为每个度量值输出它所依赖的表清单——包括直接依赖与间接依赖。 该列表会以制表符分隔的文件形式输出。 +下面的脚本会遍历模型中的所有度量值,并针对每个度量值输出其依赖的表列表——包括直接依赖和间接依赖。 该列表会输出为制表符分隔文件。 ```csharp -string tsv = "Measure\tDependsOnTable"; // TSV 文件表头行 +string tsv = "度量值\tDependsOnTable"; // TSV 文件表头行 // 遍历所有度量值: foreach(var m in Model.AllMeasures) { - // 获取该度量值引用的 ALL 对象列表(既包括直接引用,也包括通过其他度量值间接引用): + // 获取此度量值引用的 ALL 对象列表(既包括直接引用,也包括通过其他度量值间接引用): var allReferences = m.DependsOn.Deep(); - // 将引用列表筛选为仅包含表的引用。对于列引用,获取该列所属的表。 + // 将上面的引用列表筛选为仅包含表的引用。对于列引用,获取每列所属的表。 // 最后,仅保留不重复的表: var allTableReferences = allReferences.OfType
() .Concat(allReferences.OfType().Select(c => c.Table)).Distinct(); @@ -662,33 +662,33 @@ foreach(var m in Model.AllMeasures) { } tsv.Output(); -// SaveFile("c:\\MyProjects\\SSAS\\MeasureTableDependencies.tsv", tsv); // 取消注释此行即可将输出保存到文件 +// SaveFile("c:\\MyProjects\\SSAS\\MeasureTableDependencies.tsv", tsv); // 取消注释这一行即可将输出保存到文件 ``` *** -## 设置聚合(仅限 Power BI Dataset) +## 设置聚合(仅适用于 Power BI Dataset) -自 [Tabular Editor 2.11.3](https://github.com/TabularEditor/TabularEditor/releases/tag/2.11.3) 起,你可以在列上设置 `AlternateOf` 属性,从而在模型中定义聚合表。 该功能可通过 Power BI 服务的 XMLA endpoint 用于 Power BI Dataset(兼容级别 1460 或更高)。 +从 [Tabular Editor 2.11.3](https://github.com/TabularEditor/TabularEditor/releases/tag/2.11.3) 起,你可以在列上设置 `AlternateOf` 属性,从而在模型中定义聚合表。 此功能可通过 Power BI 服务的 XMLA endpoint 在 Power BI Dataset(兼容级别 1460 或更高)中启用。 -选中一组列并运行下面的脚本,以初始化它们的 `AlternateOf` 属性: +选择一组列并运行以下脚本,以初始化这些列的 `AlternateOf` 属性: ```csharp foreach(var col in Selected.Columns) col.AddAlternateOf(); ``` -依次逐列处理,将其映射到基础列,并相应设置汇总方式(Sum/Min/Max/GroupBy)。 或者,如果你想自动化此流程,并且你的聚合表列与基础表列的名称完全相同,可以使用下面的脚本,它会为你自动映射这些列: +接下来逐列处理,将它们映射到基础列,并相应设置汇总方式(Sum/Min/Max/GroupBy)。 或者,如果你想自动化此流程,并且聚合表中的列与基础表中的列名称完全相同,可以使用下面的脚本,它会为你自动映射这些列: ```csharp -// 在树中选择两张表(Ctrl+单击)。假定聚合表是列数最少的那一张。 -// 此脚本会为聚合表上的所有列设置 AlternateOf 属性。要使脚本生效,聚合表列必须 -// 与基础表列同名。 +// 在树中选择两张表(Ctrl+单击)。默认聚合表是列数最少的那张。 +// 这个脚本会为聚合表上的所有列设置 AlternateOf 属性。要让脚本生效,聚合表的列必须 +// 与基础表的列同名。 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) { - // 脚本会将汇总类型设置为 "Group By",除非该列使用的数据类型为 decimal/double: + // 这个脚本会将汇总类型设置为 "Group By",除非该列使用的数据类型是 decimal/double: var summarization = SummarizationType.GroupBy; if(col.DataType == DataType.Double || col.DataType == DataType.Decimal) summarization = SummarizationType.Sum; @@ -697,7 +697,7 @@ foreach(var col in aggTable.Columns) } ``` -运行脚本后,你应该会看到聚合表上的所有列都已分配 `AlternateOf` 属性(见下方屏幕截图)。 请记住,基础表分区必须使用 DirectQuery,聚合才能生效。 +运行脚本后,你应该会看到聚合表上的所有列都已设置了 `AlternateOf` 属性(见下方截图)。 请注意:要让聚合生效,基础表分区必须使用 DirectQuery。 ![image](https://user-images.githubusercontent.com/8976200/85851134-6ed70800-b7ae-11ea-82eb-37fcaa2ca9c4.png) @@ -705,22 +705,22 @@ foreach(var col in aggTable.Columns) ## 查询 Analysis Services -从版本 [2.12.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.12.1) 开始,Tabular Editor 现已提供多种辅助方法,可针对你的模型执行 DAX 查询并对 DAX 表达式求值。 这些方法仅在模型元数据直接从 Analysis Services 实例加载时才适用,例如使用“File > Open > From DB...”选项,或使用 Tabular Editor 的 Power BI 外部工具集成功能时。 +自版本 [2.12.1](https://github.com/TabularEditor/TabularEditor/releases/tag/2.12.1) 起,Tabular Editor 提供了多种辅助方法,用于针对你的模型执行 DAX 查询并对 DAX 表达式求值。 这些方法仅在模型元数据直接从 Analysis Services 实例加载时才适用,例如使用 "File > Open > From DB..." 选项,或使用 Tabular Editor 与 Power BI 外部工具的集成功能时。 -可用的方法如下: +以下方法可用: -| 方法 | 说明 | -| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `void ExecuteCommand(string tmslOrXmla, bool isXmla = false)` | 此方法会将指定的 TMSL 或 XMLA 脚本传递给已连接的 Analysis Services 实例。 当你需要在 AS 实例上刷新某张表的数据时,这个方法很有用。 请注意,如果你使用此方法对模型进行元数据更改,你的本地模型元数据将与 AS 实例上的元数据不同步;下次尝试保存模型元数据时,可能会收到版本冲突警告。 如果要发送 XMLA 脚本,请将 `isXmla` 参数设置为 `true`。 | -| `IDataReader ExecuteReader(string dax)` | 对已连接的 AS 数据库执行指定的 DAX _查询_,并返回生成的 [AmoDataReader](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.amodatareader?view=analysisservices-dotnet) 对象。 DAX 查询包含一个或多个 [`EVALUATE`](https://dax.guide/EVALUATE) 语句。 请注意,你不能同时打开多个数据读取器。 如果你忘记显式关闭或释放读取器,Tabular Editor 会自动将其关闭。 | -| `DataSet ExecuteDax(string dax)` | 对已连接的 AS 数据库执行指定的 DAX _查询_,并返回一个 [DataSet](https://docs.microsoft.com/en-us/dotnet/api/system.data.dataset?view=netframework-4.6) 对象,其中包含查询返回的数据。 DAX 查询包含一个或多个 [`EVALUATE`](https://dax.guide/EVALUATE) 语句。 返回的 DataSet 对象中,每个 `EVALUATE` 语句都会对应一个 DataTable。 不建议返回非常大的数据表,因为它们可能会导致内存不足或其他稳定性错误。 | -| `object EvaluateDax(string dax)` | 针对已连接的 AS 数据库执行指定的 DAX _表达式_,并返回一个表示结果的对象。 如果 DAX 表达式是标量,则会返回相应类型的对象(string、long、decimal、double、DateTime)。 如果 DAX 表达式为表值,则会返回 [DataTable](https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable?view=netframework-4.6)。 | +| 方法 | 描述 | +| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `void ExecuteCommand(string tmslOrXmla, bool isXmla = false)` | 这个方法会将指定的 TMSL 或 XMLA 脚本传递给已连接的 Analysis Services 实例。 当你想要刷新 AS 实例中某个表的数据时,这会很有用。 注意,如果你用这个方法更改模型元数据,本地模型元数据将与 AS 实例上的元数据不同步,并且下次尝试保存模型元数据时,你可能会收到版本冲突警告。 如果要发送 XMLA 脚本,请将 `isXmla` 参数设为 `true`。 | +| `IDataReader ExecuteReader(string dax)` | 在已连接的 AS 数据库上执行指定的 DAX _查询_,并返回得到的 [AmoDataReader](https://docs.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.amodatareader?view=analysisservices-dotnet) 对象。 DAX 查询由一个或多个 [`EVALUATE`](https://dax.guide/EVALUATE) 语句组成。 注意,你不能同时打开多个数据读取器。 如果你忘记显式关闭或释放读取器,Tabular Editor 会自动关闭它们。 | +| `Dataset ExecuteDax(string dax)` | 对已连接的 AS 数据库执行指定的 DAX _查询_,并返回一个 [Dataset](https://docs.microsoft.com/en-us/dotnet/api/system.data.dataset?view=netframework-4.6) 对象,其中包含查询返回的数据。 DAX 查询由一个或多个 [`EVALUATE`](https://dax.guide/EVALUATE) 语句组成。 返回的 Dataset 对象中,每个 `EVALUATE` 语句都会对应一个 DataTable。 不建议返回超大的数据表,因为这可能会导致内存不足或其他稳定性问题。 | +| `object EvaluateDax(string dax)` | 对已连接的 AS 数据库执行指定的 DAX _表达式_,并返回一个表示执行结果的对象。 如果 DAX 表达式是标量,则会返回相应类型的对象(string、long、decimal、double、DateTime)。 如果 DAX 表达式为表值,则会返回一个 [DataTable](https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable?view=netframework-4.6)。 | -这些方法的作用域在 `Model.Database` 对象下,但也可以不加任何前缀直接执行。 +这些方法属于 `Model.Database` 对象,但也可以不加任何前缀直接执行。 -Darren Gosbell 在[这里](https://darren.gosbell.com/2020/08/the-best-way-to-generate-data-driven-measures-in-power-bi-using-tabular-editor/)介绍了一个有趣的用例:使用 `ExecuteDax` 方法生成数据驱动的度量值。 +Darren Gosbell 在 [此处](https://darren.gosbell.com/2020/08/the-best-way-to-generate-data-driven-measures-in-power-bi-using-tabular-editor/) 介绍了一个有趣的用例:如何使用 `ExecuteDax` 方法生成数据驱动的度量值。 -另一种做法是创建一个可复用的脚本,用于刷新某个表。 例如,要执行重新计算,请使用以下代码: +另一种做法是创建一个可复用的脚本,用于刷新某个表。 例如,要执行重新计算,可使用下面的代码: ```csharp var type = "calculate"; @@ -734,9 +734,9 @@ var tmsl = "{ \"refresh\": { \"type\": \"%type%\", \"objects\": [ { \"database\" ExecuteCommand(tmsl); ``` -### 清除 Analysis Services 引擎缓存 +### 清除 Analysis Services 引擎的缓存 -从 Tabular Editor 2.16.6 或 Tabular Editor 3.2.3 开始,你可以使用以下语法向 Analysis Services 发送原始 XMLA 命令。 下面的示例演示了如何使用它来清除 AS 引擎缓存: +从 Tabular Editor 2.16.6 或 Tabular Editor 3.2.3 起,你可以使用以下语法向 Analysis Services 发送原始 XMLA 命令。 下面的示例展示了如何使用它来清除 AS 引擎缓存: ```csharp var clearCacheXmla = string.Format(@" @@ -750,54 +750,54 @@ ExecuteCommand(clearCacheXmla, isXmla: true); ### 可视化查询结果 -也可以使用 `Output` 辅助方法,直接将 `EvaluateDax` 返回的 DAX 表达式结果可视化: +你也可以使用 `Output` 辅助方法,直接将 `EvaluateDax` 返回的 DAX 表达式结果可视化: ```csharp -EvaluateDax("1 + 2").Output(); // An integer -EvaluateDax("\"Hello from AS\"").Output(); // A string -EvaluateDax("{ (1, 2, 3) }").Output(); // A table +EvaluateDax("1 + 2").Output(); // 整数 +EvaluateDax("\"Hello from AS\"").Output(); // 字符串 +EvaluateDax("{ (1, 2, 3) }").Output(); // 表 ``` -![image](https://user-images.githubusercontent.com/8976200/91638299-bbd59580-ea0e-11ea-882b-55bff73c30fb.png) +![图片](https://user-images.githubusercontent.com/8976200/91638299-bbd59580-ea0e-11ea-882b-55bff73c30fb.png) -……或者,如果想返回当前选中度量值的值: +...或者,如果你想返回当前选中度量值的值: ```csharp EvaluateDax(Selected.Measure.DaxObjectFullName).Output(); ``` -![image](https://user-images.githubusercontent.com/8976200/91638367-6f3e8a00-ea0f-11ea-90cd-7d2e4cff6e31.png) +![图片](https://user-images.githubusercontent.com/8976200/91638367-6f3e8a00-ea0f-11ea-90cd-7d2e4cff6e31.png) -下面是一个更高级的示例,可一次选择并对多个度量值求值: +下面是一个更高级的示例,可让你一次选择并对多个度量值求值: ```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) +![图片](https://user-images.githubusercontent.com/8976200/91638356-546c1580-ea0f-11ea-8302-3e40829e00dd.png) -如果确实很熟练,可以使用 SUMMARIZECOLUMNS 或其他 DAX 函数,将选中的度量值按某个列进行切片并可视化: +如果你已经非常熟练,可以使用 SUMMARIZECOLUMNS 或其他 DAX 函数,将选中的度量值按某一列切片并可视化: ```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) +![图片](https://user-images.githubusercontent.com/8976200/91638389-9b5a0b00-ea0f-11ea-819f-d3eee3ddfa71.png) -请记住,你可以点击脚本编辑器正上方的“+”图标,将这些脚本保存为自定义操作。 这样一来,你就能获得一套便于复用的 DAX 查询集合,并且可以直接在 Tabular Editor 的上下文菜单中执行和可视化: +别忘了点击脚本编辑器正上方的“+”图标,将这些脚本保存为自定义操作。 这样,你就能拥有一套易于复用的 DAX 查询集合,可直接在 Tabular Editor 的上下文菜单中执行并可视化: -![image](https://user-images.githubusercontent.com/8976200/91638790-305e0380-ea12-11ea-9d84-313f4388496f.png) +![图片](https://user-images.githubusercontent.com/8976200/91638790-305e0380-ea12-11ea-9d84-313f4388496f.png) -### 导出数据 +### 数据导出 -你可以使用下面的脚本来执行一个 DAX 查询,并将结果流式写入文件(脚本使用制表符分隔格式): +你可以使用下面的脚本通过 EVALUATE 执行一个 DAX 查询,并将结果流式写入文件(脚本使用制表符分隔格式): ```csharp using System.IO; -// 此脚本会执行一个 DAX 查询,并以制表符分隔的格式将结果写入文件: +// 这个脚本会执行一个 DAX 查询,并以制表符分隔格式把结果写入文件: var dax = "EVALUATE 'Customer'"; var file = @"c:\temp\file.csv"; @@ -819,13 +819,13 @@ using(var fileWriter = new StreamWriter(file)) } ``` -如果你想到了这些方法的其他有趣用法,请考虑在[社区脚本 repository](https://github.com/TabularEditor/Scripts)中分享。 谢谢! +如果你想到了这些方法的其他有趣用法,欢迎在[社区脚本 repository](https://github.com/TabularEditor/Scripts)中分享。 谢谢! *** -## 替换 Power Query 服务器和数据库名称 +## 替换 Power Query 的服务器和数据库名称 -从基于 SQL Server 的数据源导入数据的 Power BI Dataset,通常会包含类似下面这样的 M 表达式。 Tabular Editor 很遗憾没有用于“解析”这类表达式的机制。不过,如果我们想在不知道原始值的情况下,将其中的服务器和数据库名称替换为其他内容,可以利用这样一个事实:这些值都被双引号括起来: +从基于 SQL Server 的数据源导入数据的 Power BI Dataset,通常包含如下所示的 M 表达式。 遗憾的是,Tabular Editor 没有任何机制来“解析”这类表达式。不过,如果我们想在不知道原始值的情况下,把这个表达式中的服务器和数据库名称替换成别的内容,可以利用这样一个事实:这些值都被双引号括起来: ```M let @@ -836,15 +836,15 @@ in dbo_DimProduct ``` -下面的脚本会将第一个双引号中的值替换为服务器名称,并将第二个双引号中的值替换为数据库名称。 这两个替换值都从环境变量中读取: +以下脚本会将双引号中第一次出现的值替换为服务器名称,并将双引号中第二次出现的值替换为数据库名称。 这两个替换值都从环境变量中读取: ```csharp -// 此脚本用于将所有 Power Query 分区中的服务器和数据库名称, +// 这个脚本用于将所有 Power Query 分区中的服务器和数据库名称, // 统一替换为通过环境变量提供的值: var server = "\"" + Environment.GetEnvironmentVariable("SQLServerName") + "\""; var database = "\"" + Environment.GetEnvironmentVariable("SQLDatabaseName") + "\""; -// 此函数会从 M 表达式中提取所有被引号括起来的值,并以字符串列表形式返回 +// 这个函数会从 M 表达式中提取所有被引号括起来的值,并以字符串列表形式返回 // (按出现顺序)。但如果某个引号前面紧跟井号(#),则忽略该引号中的值: var split = new Func>(m => { var result = new List(); @@ -856,10 +856,10 @@ var split = new Func>(m => { } return result; }); -var GetServer = new Func(m => split(m)[0]); // 服务器名通常是遇到的第一个字符串 -var GetDatabase = new Func(m => split(m)[1]); // 数据库名通常是遇到的第二个字符串 +var GetServer = new Func(m => split(m)[0]); // 服务器名通常是遇到的第 1 个字符串 +var GetDatabase = new Func(m => split(m)[1]); // 数据库名通常是遇到的第 2 个字符串 -// 遍历模型中的所有分区,将分区里原有的服务器和数据库名称替换为 +// 遍历模型中的所有分区,把分区中的服务器和数据库名称替换为 // 环境变量中指定的值: foreach(var p in Model.AllPartitions.OfType()) { @@ -874,31 +874,31 @@ foreach(var p in Model.AllPartitions.OfType()) *** -## 将 Power Query 数据源和分区替换为 Legacy +## 用 Legacy 替换 Power Query 数据源和分区 -如果你在处理一个基于 Power BI 的模型,并且该模型的分区使用 Power Query(M)表达式来访问基于 SQL Server 的数据源,那么你将无法使用 Tabular Editor 2 的数据导入向导,也无法执行架构检查(即,将导入的列与数据源中的列进行对比)。 +如果你正在处理一个基于 Power BI 的模型,且该模型的分区使用 Power Query(M)表达式来访问基于 SQL Server 的数据源,那么很遗憾,你将无法使用 Tabular Editor 2 的“数据导入”向导,也无法执行架构检查(即比较已导入的列与数据源中的列)。 -要解决这个问题,你可以在模型上运行下面的脚本:它会将 Power Query 分区替换为对应的原生 SQL 查询分区,并在模型上创建一个 Legacy(提供程序)数据源,从而让 Tabular Editor 2 的“导入数据”向导可以正常工作: +要解决这个问题,你可以在模型上运行下面的脚本:它会将 Power Query 分区替换为对应的原生 SQL 查询分区,并在模型中创建一个 Legacy(提供程序)数据源,这样就能使用 Tabular Editor 2 的“数据导入”向导: -脚本有两个版本:第一个版本为创建的 Legacy 数据源使用 MSOLEDBSQL 提供程序,并将凭据硬编码在脚本中。 这对于本地开发很有用。 第二个示例使用 SQLNCLI 提供程序,该提供程序在 Azure DevOps 的 Microsoft 托管构建代理上可用,并从环境变量中读取凭据以及服务器和数据库名称,因此适合集成到 Azure Pipelines 中。 +这个脚本有两个版本:第一个版本会为创建的 Legacy 数据源使用 MSOLEDBSQL 提供程序,并使用硬编码的凭据。 这对本地开发很有用。 第二个脚本使用 SQLNCLI 提供程序。该提供程序在 Azure DevOps 的 Microsoft 托管构建代理上可用,并会从环境变量中读取凭据以及服务器/数据库名称,因此该脚本适合集成到 Azure Pipelines 中。 -MSOLEDBSQL 版本:从 M 分区读取连接信息,并通过 Azure AD 提示输入用户名和密码: +MSOLEDBSQL 版本:从 M 分区读取连接信息,并通过 Azure AD 提示你输入用户名和密码: ```csharp #r "Microsoft.VisualBasic" -// 此脚本会将该模型上的所有 Power Query 分区替换为一个 -// 使用所提供连接字符串、并采用 INTERACTIVE +// 这个脚本会将模型中的所有 Power Query 分区替换为一个 +// 使用提供的连接字符串并采用 INTERACTIVE // AAD 身份验证的 Legacy 分区。脚本假定所有 Power Query 分区 // 都从同一个基于 SQL Server 的数据源加载数据。 -// 请提供以下信息: +// 填入下面的信息: var authMode = "ActiveDirectoryInteractive"; var userId = Microsoft.VisualBasic.Interaction.InputBox("输入你的 AAD 用户名", "用户名", "name@domain.com", 0, 0); if(userId == "") return; -var password = ""; // 使用 ActiveDirectoryInteractive 身份验证时请留空 +var password = ""; // 使用 ActiveDirectoryInteractive 身份验证时留空 -// 此函数会从 M 表达式中提取所有被引号括起来的值,并以字符串列表形式返回 +// 这个函数会从 M 表达式中提取所有被引号括起来的值,并以字符串列表形式返回 // (按出现顺序)。但如果某个引号前面紧跟井号(#),则忽略该引号中的值: var split = new Func>(m => { var result = new List(); @@ -910,10 +910,10 @@ var split = new Func>(m => { } return result; }); -var GetServer = new Func(m => split(m)[0]); // 服务器名通常是遇到的第一个字符串 -var GetDatabase = new Func(m => split(m)[1]); // 数据库名通常是遇到的第二个字符串 -var GetSchema = new Func(m => split(m)[2]); // 架构名通常是遇到的第三个字符串 -var GetTable = new Func(m => split(m)[3]); // 表名通常是遇到的第四个字符串 +var GetServer = new Func(m => split(m)[0]); // 服务器名通常是遇到的第 1 个字符串 +var GetDatabase = new Func(m => split(m)[1]); // 数据库名通常是遇到的第 2 个字符串 +var GetSchema = new Func(m => split(m)[2]); // 架构名通常是遇到的第 3 个字符串 +var GetTable = new Func(m => split(m)[3]); // 表名通常是遇到的第 4 个字符串 var server = GetServer(Model.AllPartitions.OfType().First().Expression); var database = GetDatabase(Model.AllPartitions.OfType().First().Expression); @@ -941,13 +941,12 @@ foreach(var t in Model.Tables.Where(t => t.Partitions.OfType().Any() } ``` -SQLNCLI 版本:从环境变量读取连接信息: +SQLNCLI 版本:从环境变量中读取连接信息: ```csharp -// 此脚本会将此模型中的所有 Power Query 分区替换为 -// 一个传统分区,并从对应的环境变量中读取 SQL Server 名称、数据库名称、用户名 -// 和密码。脚本假定 -// 所有 Power Query 分区都从同一个基于 SQL Server 的 +// 这个脚本会将模型中的所有 Power Query 分区替换为 +// 一个 Legacy 分区,并从对应的环境变量中读取 SQL Server 名称、数据库名称、用户名 +// 和密码。脚本假定所有 Power Query 分区都从同一个基于 SQL Server 的 // 数据源加载数据。 var server = Environment.GetEnvironmentVariable("SQLServerName"); @@ -955,8 +954,8 @@ var database = Environment.GetEnvironmentVariable("SQLDatabaseName"); var userId = Environment.GetEnvironmentVariable("SQLUserName"); var password = Environment.GetEnvironmentVariable("SQLUserPassword"); -// 此函数会从 M 表达式中提取所有加引号的值,返回一个字符串列表。 -// 列表包含提取到的值(按顺序),但会忽略这样的加引号值:引号前紧跟一个井号 (#)。 +// 这个函数会从 M 表达式中提取所有被引号括起来的值,并以字符串列表形式返回 +// (按出现顺序)。但如果某个引号前面紧跟井号(#),则忽略该引号中的值: var split = new Func>(m => { var result = new List(); var i = 0; @@ -967,12 +966,12 @@ var split = new Func>(m => { } return result; }); -var GetServer = new Func(m => split(m)[0]); // 服务器名称通常是第一个匹配到的字符串 -var GetDatabase = new Func(m => split(m)[1]); // 数据库名称通常是第二个匹配到的字符串 -var GetSchema = new Func(m => split(m)[2]); // 架构名称通常是第三个匹配到的字符串 -var GetTable = new Func(m => split(m)[3]); // 表名称通常是第四个匹配到的字符串 +var GetServer = new Func(m => split(m)[0]); // 服务器名通常是遇到的第 1 个字符串 +var GetDatabase = new Func(m => split(m)[1]); // 数据库名通常是遇到的第 2 个字符串 +var GetSchema = new Func(m => split(m)[2]); // 架构名通常是遇到的第 3 个字符串 +var GetTable = new Func(m => split(m)[3]); // 表名通常是遇到的第 4 个字符串 -// 向模型添加一个传统数据源: +// 向模型添加一个 Legacy 数据源: var ds = Model.AddDataSource("AzureSQL"); ds.Provider = "System.Data.SqlClient"; ds.ConnectionString = string.Format( @@ -982,7 +981,7 @@ ds.ConnectionString = string.Format( userId, password); -// 从所有表中删除 Power Query 分区,并用单个传统分区替换: +// 从所有表中移除 Power Query 分区,并将其替换为一个 Legacy 分区: foreach(var t in Model.Tables.Where(t => t.Partitions.OfType().Any())) { var mPartitions = t.Partitions.OfType(); diff --git a/localizedContent/zh/content/features/Workspace-Database.md b/localizedContent/zh/content/features/Workspace-Database.md index c7290b93..d64f5152 100644 --- a/localizedContent/zh/content/features/Workspace-Database.md +++ b/localizedContent/zh/content/features/Workspace-Database.md @@ -1,6 +1,6 @@ --- uid: workspace-databases -title: Workspace 数据库简介 +title: Workspace 数据库介绍 author: Morten Lønskov updated: 2026-03-19 applies_to: @@ -17,33 +17,33 @@ applies_to: full: true --- -## Workspace 数据库简介 +## Workspace 数据库介绍 -Tabular Editor 3.0 支持在同时连接到部署在 Analysis Services 实例上的数据库的情况下,编辑从磁盘加载的模型元数据。 我们将该数据库称为 _工作区数据库_。 今后,这是在 Tabular Editor 中进行表格建模的推荐方式。 +Tabular Editor 3 支持在编辑从磁盘加载的模型元数据时,同时连接到部署在 Analysis Services 实例上的数据库。 我们将该数据库称为 _工作区数据库_。 今后,这是在 Tabular Editor 中进行表格建模的推荐方式。 这会让开发流程简单得多,因为你只需按一次“保存” (Ctrl+S),就能同时将更改保存到磁盘 **并** 更新工作区数据库中的元数据。 这也有一个优势:按下“保存”时,Analysis Services 返回的任何错误信息都会立即在 Tabular Editor 中可见。 在某种程度上,这与 SSDT/Visual Studio 或 Power BI Desktop 的工作方式类似,只是你可以决定何时更新工作区数据库。 -当你从 Model.bim 文件或文件夹结构加载模型时,会看到如下提示: +当你从 Model.bim 文件或文件夹结构加载模型时,会看到以下提示: ![image](https://user-images.githubusercontent.com/8976200/58166683-a65db180-7c8a-11e9-9df3-be9a716b3ad1.png) - **是**:从磁盘加载模型元数据,然后立即部署到某个 Analysis Services 实例。 随后,Tabular Editor 将连接到新部署的数据库。 下次从磁盘加载同一模型时,Tabular Editor 会自动重新部署并连接到该数据库。 -- **否**:照常从磁盘将模型元数据加载到 Tabular Editor,但不连接到任何 Analysis Services 实例。 -- **否,不再询问**:与上面的选项相同,但下次加载同一模型时 Tabular Editor 不会再询问。 +- **否**:模型元数据会像往常一样从磁盘加载到 Tabular Editor 中,不会连接到 Analysis Services 实例。 +- **否,不再询问**:与上述选项相同,但下次加载同一模型时,Tabular Editor 不会再次询问。 -### 设置工作区数据库 +### 设置 Workspace 数据库 当在上面的提示中选择“是”选项时,系统将要求输入 Analysis Services 实例的服务器名称以及(可选的)凭据。 点击“确定”后,将显示该实例上已有的数据库列表。 Tabular Editor 会默认你要部署一个新数据库,并会根据你的 Windows 用户名以及当前日期和时间,为新数据库提供一个默认名称: ![image](https://user-images.githubusercontent.com/8976200/58179509-a10f5f80-7ca8-11e9-9764-4cb76b9d1a8b.png) -如果要将现有数据库用作 Workspace 数据库,只需在列表中选择该数据库即可。 **警告:如果选择现有数据库,该数据库将被从磁盘加载的模型的元数据覆盖。 因此,不建议在生产实例上设置 workspace 数据库!** +如果要将现有数据库用作 Workspace 数据库,只需在列表中选择它即可。 **警告:如果选择现有数据库,该数据库将被从磁盘加载的模型的元数据覆盖。 因此,不建议在生产实例上设置 workspace 数据库!** -### 用户选项文件 (.tmuo) +### 用户选项文件(.tmuo) -为便于在文件系统中跟踪每个模型的 Workspace 设置,Tabular Editor 3.0 引入了一种新的 .tmuo 文件类型(Tabular Model User Options 的简称),它会放在 Model.bim 或 Database.json 文件旁边。 +为跟踪文件系统中每个模型的 Workspace 设置,Tabular Editor 3 引入了一种新的 .tmuo 文件类型(Tabular Model User Options 的缩写),该文件将与 Model.bim 或 Database.json 文件放在同一目录下。 -.tmuo 文件只是一个简单的 JSON 文档,内容如下: +.tmuo 文件只是一个包含以下内容的简单 JSON 文档: ```json { @@ -53,24 +53,24 @@ Tabular Editor 3.0 支持在同时连接到部署在 Analysis Services 实例上 } ``` -从磁盘加载模型元数据时,Tabular Editor 会在已加载的模型文件所在的同一目录中查找是否存在 .tmuo 文件。 .tmuo 文件的名称必须遵循以下模式: +从磁盘加载模型元数据时,Tabular Editor 会在已加载模型文件所在的同一目录中查找 .tmuo 文件。 .tmuo 文件的名称必须遵循以下模式: ``` ..tmuo ``` -文件中包含用户名,是为了避免在并行开发工作流中,多位开发者无意间互相覆盖对方的 Workspace 数据库。 如果该文件存在,并且文件中的 "UseWorkspace" 标志设置为 "true",Tabular Editor 在从磁盘加载模型时将执行以下步骤: +文件中包含用户名,是为了避免在并行开发工作流中,多位开发者无意间互相覆盖对方的 Workspace 数据库。 如果该文件存在,且文件中的 "UseWorkspace" 标志设置为 "true",Tabular Editor 在从磁盘加载模型时将执行以下步骤: 1. 使用 .tmuo 文件中指定的服务器名称和数据库名称,将模型元数据部署到 Workspace 数据库(覆盖现有元数据)。 -2. 以“工作区模式”连接到新部署的数据库。 +2. 以“工作区模式”连接到新部署的 Workspace 数据库。 -在“工作区模式”下,每次你按下保存 (ctrl+s),Tabular Editor 都会同时将模型保存到磁盘,并更新 Workspace 数据库。 这样,你就能快速测试新代码并查看 Analysis Services 提供的错误信息,而无需手动部署数据库或调用“文件 > 另存为……” 或“文件 > 保存到文件夹……” 当你想将模型元数据持久保存到磁盘时 +在“工作区模式”下,每当你点击“保存”(Ctrl+S)时,Tabular Editor 都会同时将模型保存到磁盘并更新 Workspace 数据库。 这样,你就能快速测试新代码并查看 Analysis Services 提供的错误信息,而无需手动部署数据库或调用“文件 > 另存为……” 或 文件 > 保存到文件夹…… 当你希望将模型元数据持久化到磁盘时。 ### 增量刷新表达式变更检测 -当打开使用 Workspace 数据库的模型时,Tabular Editor 会针对每个由 `BasicRefreshPolicy` 管理的表,将本地增量刷新的 `Source Expression` 和 `Polling Expression` 与 Workspace 数据库中的对应表达式进行比较。 +打开包含 Workspace 数据库的模型时,Tabular Editor 会针对每个由 `BasicRefreshPolicy` 管理的表,将本地增量刷新 `Source Expression` 和 `Polling Expression` 与 Workspace 数据库中的对应表达式进行比较。 -如果 Tabular Editor 检测到差异,它会提示你使用本地版本覆盖 Workspace 数据库中的表达式。 这可以防止表达式修改被意外丢失——在通过 Git 协作时尤为重要,因为多个开发者可能会分别独立修改这些表达式。 +如果 Tabular Editor 检测到差异,它会提示你用本地版本覆盖 Workspace 数据库中的表达式。 这可以防止表达式修改被意外丢失——在通过 Git 协作时尤为重要,因为多个开发者可能会分别独立修改这些表达式。 > [!TIP] -> 如果你在团队中工作,并发现此提示频繁出现,请与团队成员协调,确保不要在不同分支中分别独立修改增量刷新表达式。 +> 如果你在团队协作中发现该提示频繁出现,请与团队成员协调,确保不要在不同分支中各自修改增量刷新表达式。 diff --git a/localizedContent/zh/content/features/csharp-scripts.md b/localizedContent/zh/content/features/csharp-scripts.md index 0431323a..7771c128 100644 --- a/localizedContent/zh/content/features/csharp-scripts.md +++ b/localizedContent/zh/content/features/csharp-scripts.md @@ -154,8 +154,8 @@ Selected.Measures | `Selected.Level` | `Selected.Levels` | 层级 | | `Selected.Table` | `Selected.Tables` | 表格 | | `Selected.CalculatedTable` | `Selected.CalculatedTables` | 计算表格 | -| `Selected.分区` | `Selected.Partitions` | 分区 | -| `Selected.角色` | `Selected.Roles` | 模型角色 | +| `Selected.Partition` | `Selected.Partitions` | 分区 | +| `Selected.Role` | `Selected.Roles` | 模型角色 | | `Selected.TablePermission` | `Selected.TablePermissions` | 表格权限 | | `Selected.KPI` | `Selected.KPIs` | KPI | | `Selected.Calendar` | `Selected.Calendars` | 日历 | diff --git a/localizedContent/zh/content/features/views/tom-explorer-view.md b/localizedContent/zh/content/features/views/tom-explorer-view.md index cbb440bb..9239172b 100644 --- a/localizedContent/zh/content/features/views/tom-explorer-view.md +++ b/localizedContent/zh/content/features/views/tom-explorer-view.md @@ -20,123 +20,124 @@ applies_to: # 在 Tabular Editor 3 中使用 TOM Explorer -TOM Explorer 是与 Data model 对象交互的主要窗口。 表、列、度量值、安全组等对象都会以层级结构显示。 表格数据模型由所谓的 [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) 来表示,而在 TOM Explorer 中显示的正是该 TOM 的元数据。 +TOM Explorer 是你与 Data model 对象交互的主窗口。 表、列、度量值、安全组等对象都以分层结构显示。 表格式 Data model 由所谓的 [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) 表示,而 TOM Explorer 中显示的是该 TOM 的元数据。 TOM Explorer 由两个主要区域组成:第一部分是数据模型对象;第二部分是菜单栏,用于筛选并更改主窗口中显示的内容。 -![Tom Explorer](~/content/assets/images/user-interface/TOMExplorer.png) +![TOM Explorer](~/content/assets/images/user-interface/TOMExplorer.png) ## 数据模型对象 -你可以在 TOM Explorer 中展开对象以查看其子对象,并沿着对象层级向下浏览。 如果你在任意对象上右键单击,会看到一组用于与该对象交互的选项。 如下所示,你可以对表使用多种选项。 使用此菜单,例如,您可以轻松刷新表格,并在 @data-refresh-view 视图中查看刷新状态 +你可以在 TOM Explorer 中展开对象来查看其子级,并沿着对象层级向下浏览。 右键单击任意对象,即可看到一组用于与该对象交互的选项。 如下所示,对于表你可以使用多个选项。 例如,你可以通过此菜单轻松刷新表,并在 @data-refresh-view 中查看该刷新操作的状态 -![Tom Explorer Interaction](~/content/assets/images/user-interface/TomExplorerRightClick.png) +![Tom Explorer 交互](~/content/assets/images/user-interface/TomExplorerRightClick.png) -右键菜单包含以下项,其中部分可展开以查看更多操作。 菜单内容取决于所选对象类型(表、分区、度量值、列等) 下方列表并未穷尽所有对象类型,仅包含最常用的几种。 +右键菜单包含以下项目,其中部分项目可展开以执行更多操作。 该菜单会根据所选对象类型而变化(表、分区、度量值、列等) 下面的列表并未涵盖所有对象类型,但包含了最常用的那些。 ### 右键菜单中的选项 - **更新表架构...**: - 检查外部数据源中的结构性更改,并相应更新该表的架构。 当数据源中新增、重命名或删除了列时,这很有用。 + 检查外部数据源的结构变化,并据此更新表的架构。 当源端新增、重命名或删除列时,这会很有用。 -- **生成 DAX 脚本**: - 为所选表及其对象生成 DAX 脚本。 将打开一个新的脚本编辑器窗口,便于你集中查看或编辑 DAX 定义。 +- **编写 DAX 脚本**: + 为所选表及其对象生成 DAX 脚本。 打开一个新的脚本编辑器窗口,你可以在其中集中查看或编辑 DAX 定义。 - **预览数据**: - 打开数据预览窗格,显示加载到所选表中的数据样本。 可用于验证或调试。 仅在右键单击表时才会出现。 + 打开数据预览窗格,显示已加载到所选表中的数据样本。 可用于验证或进行调试。 仅在对表右键单击时才会出现。 - **刷新**: - 展开后会显示可对所选表执行的刷新操作选项。 仅当模型在独立模式或工作区模式下连接到实时模型时才可用。 此选项仅适用于表和分区。 + 展开后会显示可对所选表执行的刷新操作列表。 仅当模型以独立模式或工作区模式连接到实时模型时才可用。 此选项仅适用于表及其分区。 - **创建**: - 展开子菜单,可在所选对象下创建新的度量值、列、层级结构、显示文件夹或计算项。 可用的选项取决于所选对象的类型。 + 展开为子菜单,可在所选对象下新建度量值、列、层级结构、显示文件夹或计算项。 可用选项取决于所选对象的类型。 - **移至组**: - 允许你在 TOM Explorer 中将该表移入某个表格组,便于浏览模型。 此选项仅适用于表。 + 可在 TOM Explorer 中将该表移入某个表格组,便于浏览模型。 此选项仅对表可用。 -- **设为不可见**: - 将对象标记为在客户端工具中不可见。 该表仍是模型的一部分,但会对报表作者隐藏。 也可以使用快捷键 **Ctrl+I** 隐藏对象。 +- **设为不可见** + 将对象标记为在客户端工具中不显示。 该表仍是模型的一部分,但对 Report 作者隐藏。 也可以使用快捷键 **Ctrl+I** 来隐藏该对象。 - **在透视中显示**: - 启用或禁用该表在一个或多个透视中的显示。 透视会限制最终用户在 Power BI 等工具中能看到的内容。 + 控制该表是否包含在一个或多个透视中。 透视会限制最终用户在 Power BI 等工具中可见的内容。 -- **批量重命名**: 选择多个对象时,你可以通过字符串替换或正则表达式批量重命名这些对象。 批量重命名的快捷键是 **F2**。 +- **批量重命名**:选择多个对象时,你可以通过字符串替换或正则表达式批量重命名这些对象。 批量重命名的快捷键为 **F2**。 -- **批量重命名子对象...**: - 使用正则表达式或字符串替换规则,对表或显示文件夹下的所有子对象进行批量重命名。 也可通过快捷键 **Shift+F2** 访问。 +- **批量重命名子对象...** + 允许使用正则表达式或字符串替换规则,对表或显示文件夹下的所有子对象进行批量重命名。 也可以使用快捷键 **Shift+F2** 访问。 -- **复制**: - 创建所选表的副本,包括其所有列、度量值和分区。 TOM Explorer 中的所有其他对象也都有此功能。 +- **复制** + 为所选表创建一个副本,包括其所有列、度量值和分区。 在 TOM Explorer 中的其他所有对象上也同样适用。 - **标记为日期表格...**: - 将该表标记为日期表格,以启用时间智能功能。 要求该表包含有效的日期列。 + 将该表标记为日期表格,从而启用时间智能功能。 要求该表包含一个有效的日期列。 -- **显示依赖项**: - 可视化所选表与其他模型对象之间的依赖关系。 也可通过快捷键 **Shift+F12** 访问。 +- **显示依赖项** + 以可视化方式展示所选表与其他模型对象之间的依赖关系。 也可使用快捷键 **Shift+F12** 访问。 - **导出脚本**: - 将所选对象导出为 TMSL 或 TMDL 脚本,用于部署或源代码管理。 + 将所选对象导出为 TMSL 或 TMDL 脚本,以便用于部署或源代码管理。 - **宏菜单**: - 可以将宏放入文件夹中,并针对所选对象运行。 在上面的示例中,用户有一个名为“建模和分析”的文件夹,用于存放表对象的宏脚本。 + 可将宏放入文件夹中,并对所选对象运行。 在上面的示例中,用户为表对象上的宏脚本创建了一个名为 Modelling 和 Analysis 的文件夹。 -- **剪切 / 复制 / 粘贴 / 删除**: - 标准剪贴板操作。 可用于移动、复制或删除模型对象。 +- **剪切 / 复制 / 粘贴 / 删除** + 常规剪贴板操作。 使用这些命令可移动、复制或删除模型对象。 -- **属性**: - 打开所选对象的“属性”窗格。 快捷键:**Alt+Enter**。 用于查看和编辑元数据、表达式、格式和可见性设置。 +- **属性** + 打开所选对象的“属性”窗格。 快捷键为 **Alt+Enter**。 用于检查和编辑元数据、表达式、格式设置以及可见性设置。 ### 显示信息列 -TOM Explorer 允许你切换显示有关数据模型对象的额外信息列。 可通过快捷键 **Ctrl+7** 实现。 -这些附加信息在属性窗口中也能查看,但在这里可以快速查看对象类型、格式字符串、数据类型、表达式和说明。 -![TOM Explorer 显示/隐藏列](~/content/assets/images/user-interface/TOMExplorerInfoColumns.png) +TOM Explorer 允许切换显示有关数据模型对象的额外信息列。 也可通过快捷键 **Ctrl+7** 完成。 +这些额外信息在属性窗口中也能查看,但在这里可以快速查看对象类型、格式字符串、数据类型、表达式和说明。 +![TOM Explorer Show Hide Columns](~/content/assets/images/user-interface/TOMExplorerInfoColumns.png) ## TOM Explorer 工具栏 -工具栏可让你显示或隐藏不同类型的对象,切换透视和语言,并可在 Data model 中搜索特定对象。 -![TOM Explorer 工具栏](~/content/assets/images/user-interface/TOMExplorerToolbar.png) +工具栏可让你显示或隐藏不同类型的对象,切换透视和语言,并在 Data model 中搜索特定对象。 +![TOM Explorer 工具条](~/content/assets/images/user-interface/TOMExplorerToolbar.png) 1. **显示/隐藏度量值** - 切换表内度量值的可见性。 - **快捷键:** **Ctrl+1** + 切换表中度量值的可见性。 + **快捷方式:** **Ctrl+1** 2. **显示/隐藏列** - 切换表内列的可见性。 - **快捷键:** **Ctrl+2** + 切换表格中列的显示与隐藏。 + **快捷键:** **Ctrl+2** 3. **显示/隐藏层级结构** - 切换是否在 TOM Explorer 中显示层级结构。 - **快捷键:** **Ctrl+3** + 切换 TOM Explorer 中层级结构是否可见。 + **快捷键:** **Ctrl+3** 4. **显示/隐藏分区** - 控制表是否显示分区。 - **快捷键:** **Ctrl+4** + 控制表中分区是否显示。 + **快捷键:** **Ctrl+4** 5. **显示/隐藏日历** - 控制是否显示日历。 - **快捷键:** **Ctrl+8** + 控制日历是否可见。 + **快捷键:** **Ctrl+8** 6. **显示/隐藏显示文件夹** - 启用或禁用表内按文件夹组织的显示方式。 - **快捷键:** **Ctrl+5** + 启用或禁用在表内按显示文件夹进行组织的显示方式。 + **快捷键:** **Ctrl+5** 7. **按命名空间对用户自定义函数分组** 启用后,DAX 用户自定义函数会按 [命名空间](xref:udfs#namespaces) 分层分组显示,而不是以扁平列表显示。 8. **显示/隐藏表格组** - 切换 TOM Explorer 树中表格组的可见性。 无需离开资源管理器,即可快速访问 **Tools > Preferences** 中的相同设置。 + 切换 TOM Explorer 树中表格组是否可见。 无需离开资源管理器,即可快速访问 **工具 > 偏好** 中的相同设置。 -9. **显示/隐藏隐藏对象** - 切换是否显示隐藏对象。 - **快捷键:** **Ctrl+6** +9. **显示/隐藏已隐藏对象** + 切换是否显示已隐藏对象。 + **快捷键:** **Ctrl+6** -10. **显示/隐藏信息列** - 显示或隐藏元数据列,例如数据类型或对象状态。 - **快捷键:** **Ctrl+7** +10. **显示/隐藏信息栏** + 用于显示或隐藏元数据列,例如数据类型或对象状态。 + **快捷键:** **Ctrl+7** 11. **透视选择器** - 用于选择特定透视的下拉列表。 TOM Explorer 中仅显示所选透视中的对象。 + 下拉列表,用于选择特定透视。 **透视选择器**: + 用于选择特定透视的下拉列表。TOM Explorer 中仅显示所选透视中的对象。 12. **语言选择器** 允许在不同语言之间切换,以本地化模型元数据。 @@ -145,4 +146,4 @@ TOM Explorer 允许你切换显示有关数据模型对象的额外信息列。 将 TOM Explorer 树视图中的所有节点全部折叠。 14. **搜索栏** - 在 TOM Explorer 中提供实时筛选与导航功能。 输入即可搜索所有可见的模型对象。 + 在 TOM Explorer 中提供实时筛选和导航。 输入即可在所有可见的模型对象中搜索。