前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Excel催化剂开源第50波-Excel与PowerBIDeskTop互通互联之第四篇

Excel催化剂开源第50波-Excel与PowerBIDeskTop互通互联之第四篇

作者头像
Excel催化剂
发布2021-08-19 15:54:48
4120
发布2021-08-19 15:54:48
举报
文章被收录于专栏:Excel催化剂

答应过的全盘分享,也必承诺到底,此篇PowerBI功能分享的最后一篇,讲述如何导出数据模型的元数据,笔者定义其为模型的数据字典。

此篇对应功能实现出自:第6波-导出PowerbiDesktop模型数据字典https://www.jianshu.com/p/bc26a8dcdfce

关系型数据库有数据字典,分析型数据库更加要有数据字典,DAX建模过程中,若模型的关系复杂,引用的表过多,生成的度量值、计算列过多,单单从PowerBIDeskTop去查看模型关系非常低效。

当然最好的查看方式,在全宇宙里,只能找到Excel了,没有其他敢跟它叫板,所以理所当然地将PowerBIDeskTop模型的元数据,存放到Excel单元格里,结合Excel的排序、筛选、条件格式、单元格格式等友好的操作方式辅助加工查阅模型元数据。

先上代码,同样地此代码也包含了许多Excel的VSTO开发的精髓-使用ListObject对象返回数据。

代码语言:javascript
复制
        public static void OutputDataDic(string cnnString, string dbName, string fileName)
        {

            string shtName = "数据字典_" + fileName;
            shtName = shtName.Length > 31 ? shtName.Substring(0, 31) : shtName;
            Excel.Worksheet wht;
            try
            {
                wht = Common.ExcelApp.ActiveWorkbook.Worksheets[shtName];
                Common.ExcelApp.DisplayAlerts = false;
                wht.Delete();
                Common.ExcelApp.DisplayAlerts = true;
            }
            catch (Exception)
            {

            }
            wht = Common.ExcelApp.Worksheets.Add();
            wht.Name = shtName;
            var vstoSht = Globals.Factory.GetVstoObject(wht);

            ListObject listMeasures = vstoSht.Controls.AddListObject(vstoSht.Range["A1"], "度量值表_" + fileName);
            ListObject listDims = vstoSht.Controls.AddListObject(vstoSht.Range["C1"], "维度表_" + fileName);
            ListObject listRelationShips = vstoSht.Controls.AddListObject(vstoSht.Range["E1"], "关系表_" + fileName);

            using (AMO.Server server = new AMO.Server())
            {
                server.Connect(cnnString);
                AMO.Database pbidDb = server.Databases[dbName];

                ////获取度量值
                GetMeasuresTable(pbidDb, listMeasures);
                //获取列字段
                GetDimsTable(pbidDb, listDims);
                ////获取关系
                GetRelationsTable(pbidDb, listRelationShips);

            };
            vstoSht.Activate();
        }

获取元数据,主要有度量值、维度字段、及表间关系三类元数据。核心代码如下(上方的方法中,最开始是为了访问Sqlserver的SSAS元数据,有区分1200及1100的不同兼容模型版本写了两套代码,因PowerBIDeskTop只会存在1200及以上的兼容模型,故1100的版本已经清除了):

代码语言:javascript
复制
        private static DataSet.DataSet1.MeasuresOfLevel1200DataTable GetMeasuresTableOfLevel1200(AMO.Database tabularDb)
        {
            TOM.Model model = tabularDb.Model;
            DataSet.DataSet1.MeasuresOfLevel1200DataTable measuresTable = new DataSet.DataSet1.MeasuresOfLevel1200DataTable();
            foreach (TOM.Table table in model.Tables)
            {
                foreach (TOM.Measure measure in table.Measures)
                {
                    DataSet.DataSet1.MeasuresOfLevel1200Row dr = measuresTable.NewMeasuresOfLevel1200Row();
                    dr.Measure = $"[{measure.Name}]";
                    dr.TableName = table.Name;
                    dr.DisplayFolder = measure.DisplayFolder;
                    dr.Description = measure.Description;
                    dr.FormatString = measure.FormatString;
                    dr.MeasureExpression = measure.Expression;
                    dr.Visible = !measure.IsHidden;
                    dr.DataType = measure.DataType.ToString();
                    measuresTable.AddMeasuresOfLevel1200Row(dr);
                }
            }

            return measuresTable;
        }
代码语言:javascript
复制
 private static DataTable GetDimsTableOfLevel1200(AMO.Database tabularDb)
        {
            TOM.Model model = tabularDb.Model;
            DataSet.DataSet1.ColumnNamesDataTable dtColumns = new DataSet.DataSet1.ColumnNamesDataTable();
            foreach (TOM.Table table in model.Tables)
            {
                foreach (TOM.Column col in table.Columns)
                {
                    if (!col.Name.Contains("RowNumber"))
                    {
                        TOM.CalculatedColumn calCol = col as TOM.CalculatedColumn;
                        DataSet.DataSet1.ColumnNamesRow dr = dtColumns.NewColumnNamesRow();
                        dr.TableName = table.Name;
                        dr.FieldName = col.Name;
                        dr.FieldType = col.DataType.ToString();
                        if (calCol != null)
                        {
                            dr.DaxExpression = calCol.Expression;
                        }

                        dr.Description = col.Description;
                        dr.Visible = !col.IsHidden;
                        dtColumns.AddColumnNamesRow(dr);
                    }

                }
            }
            return dtColumns.Cast<DataSet.DataSet1.ColumnNamesRow>().Where(s => !s.TableName.StartsWith("LocalDateTable"))
                                                            .Where(s => !s.TableName.StartsWith("DateTableTemplate"))
                                                            .CopyToDataTable<DataSet.DataSet1.ColumnNamesRow>();
        }
代码语言:javascript
复制
        private static DataTable GetRelationsTableOfLevel1200(AMO.Database tabularDb)
        {
            TOM.Model model = tabularDb.Model;
            DataSet.DataSet1.关系表DataTable dt = new DataSet.DataSet1.关系表DataTable();
            foreach (TOM.Relationship relationship in model.Relationships)
            {
                TOM.SingleColumnRelationship singleRelationShip = relationship as TOM.SingleColumnRelationship;
                DataSet.DataSet1.关系表Row dr = dt.New关系表Row();
                dr.ToTable = relationship.ToTable.Name;
                dr.FromTable = relationship.FromTable.Name;
                dr.IsActive = relationship.IsActive;
                if (singleRelationShip != null)
                {
                    dr.FromColumn = singleRelationShip.FromColumn.Name;
                    dr.ToColumn = singleRelationShip.ToColumn.Name;
                    dr.FromCardinality = singleRelationShip.FromCardinality.ToString();
                    dr.ToCardinality = singleRelationShip.ToCardinality.ToString();
                }
                dt.Add关系表Row(dr);
            }
            return dt.Cast<DataSet.DataSet1.关系表Row>().Where(s => !s.ToTable.StartsWith("LocalDateTable")).CopyToDataTable<DataSet.DataSet1.关系表Row>();
        }

结语

连续四篇高质量开源文章,带大家进走Excel催化剂深水区,国际领先的Excel与PowerBIDeskTop互通互联的高级、极高商业价值的核心代码全放送。

最后再次祝愿PowerBI中国社区越来越好,繁荣发展,更多乐于分享的后来者再接再厉。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Excel催化剂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结语
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档