功率查询自定义函数可一次重命名表中的所有列

功率查询自定义函数可一次重命名表中的所有列

过去几天,我参与了辽宁体育彩票 双开发。我从各种系统以不同格式(包括Excel,CSV和OData)导出了一些数据。 CSV文件是来自ERP系统的数据导出转储。使用ERP系统可能非常耗时,尤其是当您不这样做时’您无权访问数据模型,您会以CSV文件的原始格式获取数据。具有挑战性,因为在ERP系统中,表名和列名根本不是用户友好的,这是有道理的。 ERP系统正在各种环境中用于具有不同要求的许多不同客户。因此,如果可以使用基础数据模型,则会看到配置表保留了列名。一些专栏是自定义构建的,以满足特定需求。这些表可能有许多列,这些列不一定对分析有用。因此,对底层实体模型有一个很好的理解是非常关键的。无论如何,我不’不想走题。

问题

所以,这是我的情况。我收到了大约10个文件,其中包括15个表。有些桌子很小,所以我没有’麻烦了。但是其中有些真的很宽,例如具有150到208列之间。真好!

从列名来看,它们很难比它们更难读,并且我有多个这样的表。因此,我必须将这些列重命名为更具可读性的内容,稍后再进行介绍。

背景

我通过电子邮件发送给我的客户,要求他们的帮助。幸运的是,他们有一位非常出色的数据专家,他也了解他们的ERP系统以及底层实体模型。我通过电子邮件将当前的所有列名称发送给他,并询问他是否可以提供更多用户友好的名称。他用Excel中的映射表回复了我。这是显示 列名称映射 表:

列名称映射

我对映射表感到非常满意。现在,下一步是根据映射表重命名所有列。哎哟!我差不多 800 要重命名的列。从字面上看这是脖子上的疼痛,并且没有’听起来很正确,因为要刻录项目时间来重命名800列。

但是,等等,编写自动重命名过程又如何呢?就像编写自定义函数来一次重命名所有列一样?我记得我读了一篇很棒的博客文章,内容是 重命名辽宁体育彩票 Query中的多个列吉尔伯特·奎瓦维耶(Gilbert Quevauvilliers) 写于2018年。我绝对建议看一下他的博客文章。因此,我必须做与吉尔伯特相似的事情。创建一个获取原始列名称并带回新名称的自定义函数。然后,我在每个表中使用自定义函数来重命名列。简单!

继续阅读 “辽宁体育彩票 Query自定义函数可一次重命名表中的所有列”

快速提示:辽宁体育彩票 Query中的OData Feed Analyzer定制功能

辽宁体育彩票 双和Excel的辽宁体育彩票 Query中的OData Feed Analyzer自定义功能

It’s been a while 那 I am working with 数据 data source in 辽宁体育彩票 双. One challenge 那 I almost always do not have a good understanding of the underlying data model. It can be really hard and time consuming if there is no one in the business 那 understands the underlying data model. I know, we can use $metadata to get the metadata schema from the 数据 feed, but let’不去那里。我不是OData专家,但是这里是像我这样的人的事,我使用的数据源不一定是专家,但我需要了解实体是什么,它们如何连接等…那如果我没有任何中小型企业(S对象 M东北黑钙土 Expert)谁可以帮助我?

因此,参与更多OData选项,让’s get into it.

The custom function below accepts an 数据 URL then it discovers all tables, their column count, their row count (more on this later), number and list of related tables, number and list of columns of type text, type number and Decimal.Type.

// fnODataFeedAnalyser
(ODataFeed as text) => 
  let
    Source = OData.Feed(ODataFeed),
    SourceToTable = Table.RenameColumns(
        Table.DemoteHeaders(Table.FromValue(Source)), 
        {{"柱1", "Name"}, {"柱2", "数据"}}
      ),
    FilterTables = Table.SelectRows(
        SourceToTable, 
        each Type.Is(Value.Type([Data]), Table.Type) = true
      ),
    SchemaAdded = Table.AddColumn(FilterTables, "Schema", each Table.Schema([Data])),
    TableColumnCountAdded = Table.AddColumn(
        SchemaAdded, 
        "Table 柱 Count", 
        each Table.ColumnCount([Data]), 
        Int64.Type
      ),
    TableCountRowsAdded = Table.AddColumn(
        TableColumnCountAdded, 
        "Table Row Count", 
        each Table.RowCount([Data]), 
        Int64.Type
      ),
    NumberOfRelatedTablesAdded = Table.AddColumn(
        TableCountRowsAdded, 
        "Number of Related Tables", 
        each List.Count(Table.ColumnsOfType([Data], {Table.Type}))
      ),
    ListOfRelatedTables = Table.AddColumn(
        NumberOfRelatedTablesAdded, 
        "List of Related Tables", 
        each 
          if [Number of Related Tables] = 0 then 
            null
          else 
            Table.ColumnsOfType([Data], {Table.Type}), 
        List.Type
      ),
    NumberOfTextColumnsAdded = Table.AddColumn(
        ListOfRelatedTables, 
        "Number of Text 柱s", 
        each List.Count(Table.SelectRows([Schema], each Text.Contains([Kind], "text"))[Name]), 
        Int64.Type
      ),
    ListOfTextColunmsAdded = Table.AddColumn(
        NumberOfTextColumnsAdded, 
        "List of Text 柱s", 
        each 
          if [Number of Text 柱s] = 0 then 
            null
          else 
            Table.SelectRows([Schema], each Text.Contains([Kind], "text"))[Name]
      ),
    NumberOfNumericColumnsAdded = Table.AddColumn(
        ListOfTextColunmsAdded, 
        "Number of Numeric 柱s", 
        each List.Count(Table.SelectRows([Schema], each Text.Contains([Kind], "number"))[Name]), 
        Int64.Type
      ),
    ListOfNumericColunmsAdded = Table.AddColumn(
        NumberOfNumericColumnsAdded, 
        "List of Numeric 柱s", 
        each 
          if [Number of Numeric 柱s] = 0 then 
            null
          else 
            Table.SelectRows([Schema], each Text.Contains([Kind], "number"))[Name]
      ),
    NumberOfDecimalColumnsAdded = Table.AddColumn(
        ListOfNumericColunmsAdded, 
        "Number of Decimal 柱s", 
        each List.Count(
            Table.SelectRows([Schema], each Text.Contains([TypeName], "Decimal.Type"))[Name]
          ), 
        Int64.Type
      ),
    ListOfDcimalColunmsAdded = Table.AddColumn(
        NumberOfDecimalColumnsAdded, 
        "List of Decimal 柱s", 
        each 
          if [Number of Decimal 柱s] = 0 then 
            null
          else 
            Table.SelectRows([Schema], each Text.Contains([TypeName], "Decimal.Type"))[Name]
      ),
    #"Removed Other 柱s" = Table.SelectColumns(
        ListOfDcimalColunmsAdded, 
        {
          "Name", 
          "Table 柱 Count", 
          "Table Row Count", 
          "Number of Related Tables", 
          "List of Related Tables", 
          "Number of Text 柱s", 
          "List of Text 柱s", 
          "Number of Numeric 柱s", 
          "List of Numeric 柱s", 
          "Number of Decimal 柱s", 
          "List of Decimal 柱s"
        }
      )
  in
    #"Removed Other 柱s"
继续阅读 “快速提示:辽宁体育彩票 Query中的OData Feed Analyzer定制功能”

辽宁体育彩票 双治理,良好实践,第2部分:使用OneDrive,团队和SharePoint Online进行版本控制

辽宁体育彩票 双治理,商业用OneDrive,Microsoft Teams和SharePoint Online的版本控制

软件开发生命周期中最重要的方面之一是控制解决方案的不同版本,尤其是在一个项目中,有多个开发人员参与实施的项目中。就像通常在Visual Studio中创建项目并将更改提交回GitHub或Azure DevOps之类的源代码控制系统一样,’建议保留辽宁体育彩票 双报告不同版本的历史记录。我们对源代码控制解决方案的期望是,在开发项目时始终跟踪源代码中发生的所有更改。因此,您可以根据需要轻松地回滚到以前的状态。 

拥有源代码控制流程的另一个好处是,当多个开发人员在一个项目上工作时。它们中的每一个都对源代码进行更改,然后将所有更改提交到源代码控制服务器中,而不会相互覆盖’ work. 

但是使用辽宁体育彩票 双会有些不同。 辽宁体育彩票 双报告文件是以二进制格式存储的PBIX文件(嗯,PBIX基本上是一个zip文件吗?),在撰写本文时,尚无官方方法来实施辽宁体育彩票 双 源代码控制 在任何源代码控制解决方案中,如GitHub或Azure DevOps(YET)。 

微软上周(6/05/2020)宣布了一项名为“部署管道”的功能完全可以满足我们的需求,但目前是预览功能,仅适用于具有辽宁体育彩票 双 Premium的组织。因此,对于我们大多数人来说,这是不可行的。

话虽如此,仍然存在一种方法来保留PBIX文件不同版本的形状变化的历史记录。这就是所谓的 版本控制.

开发报告时,有几种方法可以启用对PBIX文件的版本控制。无论版本控制平台是什么,您都需要考虑拥有多个环境以及谁可以访问它们以执行操作。

环境可访问描述
发展历程开发者数据建模人员和报表编写者出于开发目的而访问此环境。 
用户验收测试 (UAT)开发人员,中小企业,技术主管,辽宁体育彩票 双管理员开发完成后,开发人员将解决方案部署到UAT环境。然后,该解决方案将由SME(主题专家)进行测试,以确保满足业务要求。
预生产 (可选,但推荐)辽宁体育彩票 双管理员技术主管解决方案通过所有UAT测试方案后,技术主管或辽宁体育彩票 双管理员将其部署到Pro-prod中进行最终检查,以确保所有数据源正确指向生产数据源,并且所有报告和仪表板均按预期工作。 
生产技术主管,辽宁体育彩票 双管理员,最终用户产品前检查完成后,技术主管或辽宁体育彩票 双管理员将解决方案部署到生产环境中,然后供最终用户使用。

版本控制选项

如果您的组织没有高级能力,则“Deployment Pipelines”该功能对您不可用。因此,您需要提出一个解决方案。在本节中,我列出了一些可用的版本控制选项

  • 商业用OneDrive
  • 微软团队 / 的SharePoint在线
继续阅读 “辽宁体育彩票 双治理,良好实践,第2部分:使用OneDrive,团队和SharePoint Online进行版本控制”

在辽宁体育彩票 双中使用SWITCH()和ISINSCOPE()DAX函数突出显示每个层次结构平均销售额以下

在辽宁体育彩票 双中使用SWITCH()和ISINSCOPE()DAX函数突出显示每个层次结构平均销售额以下

不久前,我在一个项目上工作,客户对柱形图有条件格式要求。
他们希望根据基于您所处的层次结构的平均值,有条件地对图表中的列设置格式。
在这种情况下,我的日历层次结构如下:

  • 日历层次结构:
    • 学期
    • 25美分硬币

我用“Adventure Works DW2017,互联网销售”Excel作为辽宁体育彩票 双 Desktop中的源。如果我想形象化“Total Sales” over the above “Calendar Hierarchy”我得到这样的东西:

Line Chart in 辽宁体育彩票 双, 总销售额 by 年

现在我激活“Average Line” from “Analytics”折线图标签。

Adding 平均线 to Line Chart in 辽宁体育彩票 双

当我在折线图中向下钻取时,“平均”线显示了我所在的特定层次结构级别的平均值。’m in code free.

辽宁体育彩票 双,折线图中的钻井

容易吧?

现在,要求是在一个“柱形图”(是的!用柱形图可视化时间序列,’则是客户的期望值),然后用橙色突出显示值低于平均值的列,其余的保留为默认主题颜色。

因此,我需要创建度量以有条件地格式化柱形图。我还需要在以下方面增加一些智能:

  • 检测我所在的层次结构级别
  • 计算该特定层次结构级别的平均销售额
  • 更改低于平均值的列的颜色

让’s get it done!

使用ISINSCOPE()DAX函数检测层次结构级别

微软介绍 ISINSCOPE() 达克斯功能 2018年11月版本 辽宁体育彩票 双桌面。宣布后不久“Kasper de Jonge” wrote a concise 博客文章 关于它。

因此,我尝试使其尽可能简单。这是工作原理,ISINSCOPE()函数返回“True”当指定的列在层次结构级别中时。如前所述,我们有一个“Calendar Hierarchy”包括以下5个级别:

  • 学期
  • 25美分硬币

因此,要确定我们是否处于上述每个层次结构级别中,我们只需要创建如下的DAX度量即可:

ISINSCOPE年		=	ISINSCOPE('Date'[Year])
ISINSCOPE 学期	=	ISINSCOPE('Date'[Semester])
ISINSCOPE 25美分硬币	=	ISINSCOPE('Date'[Quarter])
ISINSCOPE 月		=	ISINSCOPE('Date'[Month])
ISINSCOPE 天		=	ISINSCOPE('Date'[Day])

现在让’做一个简单的实验。

  • 在画布上放置一个矩阵
  • 放在“Calendar Hierarchy” to “Rows”
  • 采取上述措施“Values”
Detecting 年, 学期, 25美分硬币, 月 and 天 hierarchy levels with ISINSCOPE in 辽宁体育彩票 双桌面

如你所见“ISINSCOPE 年” shows “True” for the “Year” level. 让’扩展到下一个级别,并查看其他度量如何工作:

继续阅读 “在辽宁体育彩票 双中使用SWITCH()和ISINSCOPE()DAX函数突出显示每个层次结构平均销售额以下”