一、概述
1.1 适用场景
在PB中如果需要大量创建度量值,并对度量值的格式进行各种设置。
如果一个个进行操作,则耗时耗力。
解决方法是将度量值的写在csv或者是txt文件中。
然后读取文件,完成度量值的编写。
1.2 关键节点
- 编写大量度量值(我用Python,循环同一类形成度量值)
- 正则表达式的编写,可以在这个网站测试:https://regex101.com/
- C#的编写
1.3 基本信息
用到的工具
- Power BI Desktop 2.126.1261.0 64-bit
- Python 3.11.8
- Tabular Editor 2.23.1
1.4 原始数据
上面的数据被我放在了: E:\pbi\d01_省份表.csv
二、编写度量值
编写度量值的方式很多,可以手动编写,也可以借助软件完成。
但是用各种软件编写时,可能存在看不见的字符。
如果在csv中编写,建议用txt打开看一下,txt可以看到csv中一些见不到的字符。
2.1 Python 初步编写度量值
import pandas as pdfile_path_origen = r'E:\pbi\d01_省份表.csv' data_path = r'E:\pbi\measure_date.csv' data_path2 = r'E:\pbi\measure_date.txt'df = pd.read_csv(filepath_or_buffer=file_path_origen)def get_expression(province):expression = "CALCULATE([0001_销售金额_单位_D_],'d01_省份表'[F_04_省简称]=\"" + province + "\")"return expressiondef get_measurename(province):measure_name = province + "销售金额"return measure_namedf["Expression"] = df['F_04_省简称'].map(get_expression) df['MeasureName'] = df['F_04_省简称'].map(get_measurename) df["TableName"] = 'measure_text' df["folder"] = "text" df["format"] = "#,0" df.to_csv(path_or_buf=data_path, columns=['TableName','MeasureName','Expression','folder','format'], index=False,sep=',', quotechar='"', encoding="utf-8") # 如果是汉字,必须用utf-8格式,否则会出现乱码。 df.to_csv(path_or_buf=data_path2, columns=['TableName','MeasureName','Expression','folder','format'], index=False,sep=',', quotechar='"', encoding="utf-8")
-
encoding="utf-8"必须是utf-8 否则后面编写度量值的时候,会出现乱码。
-
此时生成的csv文件打开可能是乱码,不用担心。如果想核实导出文件是否正确,可以在导出一个文件,将encoding= "gbk"。
2.2 Python 结果展示
- 可以看到csv文件出现了乱码,不用担心。后面C#读取的时候,是没有问题的。
- csv中相对于txt少了不可见的字符 双引号 "
三、C# 完成 度量值编写
3.1 c# 代码展示
// 读取的文件位置 string csvPath = "E:/pbi/measure_date.csv"; var lines = System.IO.File.ReadAllLines(csvPath).Skip(1); // Skip(1) 第一行是标题,跳过foreach (var line in lines) {var pattern = "\".*[\\)]\"|\"[^\"]*\"|[^,]+"; // 正则表达式的规则 var matches = System.Text.RegularExpressions.Regex.Matches(line, pattern); // 调用正则表达式if (matches.Count != 5) continue;var tableName = matches[0].Value.Trim('\"'); var measureName = matches[1].Value.Trim('\"'); var formula = matches[2].Value.Trim('\"').Replace("\"\"", "\""); var folder = matches[3].Value.Trim('\"'); var format = matches[4].Value.Trim('\"');var table = Model.Tables[tableName];if (table == null) continue;try{var NewMeasure = table.AddMeasure(measureName, formula); // 创建度量值NewMeasure.DisplayFolder = folder; // 度量值所在的folderNewMeasure.FormatString = format; // 度量的格式 }catch{ } } ; Model.AllMeasures.FormatDax(); // 格式化所有度量值的公式,不仅仅包括已经创建的度量值。
- tableName 必须是已经存在的,如果不存在,可以先建一个表
- measureName 如果不存在,则会创建,如果存在,则也会创建,名称在原有的基础上加上数字1,如果再次创建,在会是2,以此类推
- folder 可以存在,也可以不存在,不存在则创建。
- c# 中对 小括号) 进行转义的时候,要根据情况,确定是否使用两个 \\ 。对应上面代码中的pattern 。
3.2 c# 结果展示
四、PB中展示