目录
介绍
背景
要解决的问题
使用BI工具元浏览器(BMB)
怎么运行
BMB仪表板
WsUsageDetailForDash
计算值参考(Calc References)
计算值调用(Calc Calls)
有关Tableau与BMB之间差异的特别说明
实现
Program.cs
WorkbookReader
未来的改进
介绍我为用C#编写的Tableau创建了一个工具,该工具减少了完成报告所需的时间。通过为您提供易于浏览的Tableau报表,您可以在保存工作时随时刷新该报表,从而省去了记住已使用的计算字段以及在工作簿中的位置的压力。在这里找到它!https://github.com/mcdean/BiToolMetaBrowser
在仓库上的发布链接下有一个所需的运行时.zip文件。
一个星期五下午晚些时候,我刚刚在我的第一份真实的表格报告里输入了第60个计算字段,我沮丧地举起手来。一长串与层次相关的字段显然已经超过了我能够推理的范围。字段的依存关系树深度很深,许多字段分散在报告中近20到30个工作表和仪表板上。在设计这份报告方面取得任何进展都是不可能的。由于Tableau将您编写的代码隐藏在其视觉设计表面的背后,这已经成为我无法取胜的危险记忆游戏。那时,我认为Tableau需要具有更好的类似IDE的用户体验,尽管我必须自己创建它,但它肯定是缺少的。那个周末,我开始创建一个工具来填补这个用户体验的空白,这是我们开发人员从传统的IDE(如visual studio)中得到的期望,它将帮助我清楚地理解计算字段之间的依赖关系以及它们在我的报告中的使用位置。
要解决的问题例如,下面显示了“总成本计算”字段。可以在以下网站上托管的名为“ Calculated Fields-Table Calculations-Statistics.twbx”的工作簿中找到:http://www.tableaubook.com/v8/workbooks.asp,此工作簿的替代版本,其中添加了许多仪表板在整个Wiki中使用。添加到仪表板的工作表组合并不是特别重要,但是可以作为BMB工具的一个很好的例子。
下图说明了Tableau界面存在的问题。
请注意,有九个依赖项,并且它们甚至都没有在工具提示弹出窗口中列出。而是说“ ...还有1个”。另外,显示的内容实际上不是可点击的。用户也不能从此窗口导航到“总成本”字段定义中使用的“数量”或“单位成本”计算字段的定义。
当然,可以在用户界面的左侧窗格中找到计算字段的完整列表。尽管如此,单击每个按钮以了解所计算的字段使用情况及其定义的全貌是很繁琐且令人痛苦的。此外,Tableau仅允许一次打开一个字段定义。
这是工作簿的其他视图。许多工作表都设置为隐藏,并且其中一个仪表板正在显示——隐藏所有工作表是常用的设置。在这种情况下,Tableau根本不显示计算出的字段列表。
BMB有两个部分:
- 元浏览器提取器(BiToolMetaBrowser.exe)
- 元浏览器工作簿(BiToolMetaBrowser.twb)
提取程序将读取您的Tableau工作簿并创建一组CSV文件,其中包含计算出的字段信息。Meta Browser工作簿使用这些CSV文件作为源数据,以在其仪表板中显示字段信息。
怎么运行提取程序可执行文件可以从批处理文件或命令行运行。这是一个示例批处理文件:
第一个参数是Tableau工作簿的路径。第二个参数是元浏览器工作簿的位置,或您要放置CSV文件的位置。当然,您必须在浏览器工作簿中编辑CSV文件的源位置。
提取程序将弹出一个控制台窗口,并指出要提取哪个文件以及提取了多少次。保存Tableau工作簿并每次执行提取时,提取器都会侦听。
Tableau工作簿的计算字段使用情况和依存关系将显示在元浏览器工作簿内的以下仪表板集合中。
WsUsageDetailForDash第一个称为Dashboards的仪表板显示了仪表板和工作表的摘要以及使用了多少个计算字段。可以单击“仪表板”和“工作表”以在WsUsageDetailForDash下方的右侧显示它们使用的字段定义。
下一个称为“工作表 ”的仪表板是相似的,但不包括“仪表板”类别。
计算值参考(Calc References)计算值参考仪表盘显示如下。它显示了右上角CalcFieldCallers列表中CalcFieldSummary中哪些字段称为所选字段。它还显示哪些工作表包含CalcFieldWsUsers中的选定字段,以及CalcFieldDashUsers中显示相应的包含仪表板。最后,所选字段的定义显示在CalcFieldDetail的右下角。
如下所示的“计算值调用”仪表板在右上方显示CalcFieldUsageByCaller中的字段的定义,这些定义用于左侧CallerSummary中的所选字段。所选字段的定义也显示在右下角的CallerFieldDetail中。
Tableau将(尝试)在工具提示中显示可传递(或下游)依赖性。而BMB仅列出直接依赖关系,但将来可能会进行升级以包括传递依赖关系的完整列表。当前,您只需单击每个直接依赖项即可查看它们。例如,如果在“Calc References”仪表盘中查看“总成本” ,则它依赖于Retail Total和Profit。如果单击“零售总额”,则以下视图将显示“折扣零售”作为调用者字段:
Tableau将在工具提示的依赖项列表中显示Discounted Retail。
实现Tableau文件提取器的实现跨越两个文件:Program.cs和WorkbookReader.cs。
Program.csProgram.cs中的代码包括一种使用FileSystemWatcher的标准文件监视技术,除了它还处理Tableau的一种奇特行为,即每次用户按下用户界面上的save按钮时,它会连续快速保存三次。在Tableau版本2018.1.8(20181.18.1213.2251)中观察到此行为。锁定对象Locker 用于同步对变量isExporting的访问,该变量是由Tableau的第二个和第三个文件保存操作启动的线程访问。500 ms的等待时间应用于第一个保存操作线程的执行,以延长第二个和第三个线程出现的时间。之所以可行,是因为不会期望用户在如此短的时间内保存、编辑然后再次保存。
除了协调Tableau文件的提取和导出之外,该类还负责将日志消息写入标准输出。
internal class Program {
private static int exportCount;
private static string outputPath = string.Empty;
private static string tableauFile = string.Empty;
private static bool isExporting;
private static readonly object Locker = new object();
private static void Main(string[] args) {
tableauFile = args[0];
outputPath = args[1];
Console.WriteLine($"Watching tableau file: {tableauFile}");
Console.WriteLine($"Writing export to path:{outputPath}");
// Create a new FileSystemWatcher and set its properties.
var watcher = new FileSystemWatcher {
Path = Path.GetDirectoryName(tableauFile),
NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName,
Filter = Path.GetFileName(tableauFile)
};
watcher.Changed += OnChanged;
watcher.EnableRaisingEvents = true;
//export on startup
Export();
Console.ReadLine();
}
private static bool GetIsExporting() {
lock (Locker) {
return isExporting;
}
}
private static void SetIsExporting(bool x) {
lock (Locker) {
isExporting = x;
}
}
private static async void OnChanged(object source, FileSystemEventArgs e) {
//Tableau version 2018.1.8 (20181.18.1213.2251)
//saves three times back-to-back when user clicks the save button
//this ensures that only one save is performed per half-second
if (GetIsExporting())
return;
SetIsExporting(true);
await Task.Delay(500);
Export();
SetIsExporting(false);
}
private static void Export() {
exportCount++;
Console.WriteLine($"Exporting #{exportCount} File: {tableauFile}");
var wr = new WorkbookReader(tableauFile);
wr.ExportToCsv(outputPath);
Console.WriteLine($"Complete.");
}
}
}
WorkbookReader
WorkbookReader类提取物和导出Tableau文件的内容。为简便起见,这里仅是其重要方法的描述。
方法:WorkbookReader(构造函数)
构造函数从Tableau文件读取元数据并将其提取到一系列Dictionary中。这是它的签名:
public WorkbookReader(string workbookFile)
方法:ExportToCsv
此方法在path参数指定的位置创建一组CSV文件。
public void ExportToCsv(string path)
未来的改进
源代码中有一些关于“小代码”改进的“TODO”注释。该项目可以轻松移植到.NET Core,以便Mac用户可以使用它。另外,Tableau报告中还可以报告其他一些方面,例如表计算,标记配置或过滤器使用情况。最后,可能有或可能没有一个好的参数来包括传递依赖性的完整列表,因为它的有用性可能不超过元浏览器WooKBook所需的复杂度。