My customer wanted to have the ability to show the last update time of the data in the Panorama's views' titles. He knows that I know to deliver

so in a couple of hours he had it. Using AMO and the view's xml manipulation it's very simple. Just note that changing views without NovaView Desktop is not supported by Panorama so watch out before you execute this program. In your first trials, always save the books dir (by default in c:\program files\panorama\e-bi\books) before you start. Also, be aware that this won't work for automatic views. The user must enter the view's title himself and write the string "Correct For" and the program will know to write the last update time after it. This is the program's code:
1 using System;
2 using System.Collection.Generic;
3 using System.Text;
4 using AMO = Microsoft.AnalysisServices;
5 using System.Xml;
6 using System.IO;
7
8 namespace CubeUpdateDate
9 {
10 class Program
11 {
12 static void Main (string[] args)
13 {
14 CubeUpdateDate cud = new CubeUpdateDate();
15 cud.Go();
16 }
17 }
18
19 class CubeUpdateDate
20 {
21 public void Go ()
22 {
23 DateTime cubeUpdateDate = GetCubeUpdateDate(GetConfigData("ServerName"),GetConfigData("DataBaseName"));
24 UpdateViews(GetConfigData("BookDir"),cubeUpdateDate);
25 }
26
27 private void UpdateViews (string dirName, DateTime cubeUpdateDate)
28 {
29 foreach (string subDirName in Directory.GetDirectories(dirName))
30 {
31 UpdateViews(subDirName, cubeUpdateDate);
32 }
33
34 foreach (string fileName in Directory.GetFiles(dirName))
35 {
36 UpdateFile(fileName, cubeUpdateDate);
37 }
38 }
39
40 private void UpdateFile (string fileName, DateTime cubeUpdateDate)
41 {
42 try {
43 XmlDocument xmlDoc = new XmlDocument();
44 xmlDoc.Load(fileName);
45 XmlNodeList titleTags = xmlDoc.GetElementsByTagName("Title");
46 if (titleTags.Count > 0)
47 {
48 string viewTitle = titleTags[0].ChildNodes[0].Attributes[0].Value;
49 if (viewTitle.Contains(@"Correct For"))
50 {
51 viewTitle = viewTitle.Substring(0, viewTitle.IndexOf("Correct For") + 11);
52 viewTitle += " " + cubeUpdateDate.ToShortTimeString() + " " + cubeUpdateDate.ToShortDateString();
53 titleTags[0].ChildNodes[0].Attributes[0].Value = viewTitle;
54 titleTags[0].ChildNodes[0].Attributes[1].Value = viewTitle;
55 xmlDoc.Save(fileName);
56 }
57 }
58 }
59 catch (Exception e)
60 {
61 Console.WriteLine("Error reading/writing file: " + fileName);
62 }
63 }
64
65 private string GetConfigData (string whichData)
66 {
67 XmlDocument xmlDoc = GetConfigXml();
68 return xmlDoc.GetElementsByTagName(whichData)[0].InnerText;
69 }
70
71 private XmlDocument GetConfigXml()
72 {
73 XmlDocument xmlDoc = new XmlDocument();
74 xmlDoc.Load("config.xml");
75 return xmlDoc;
76 }
77
78 private DateTime GetCubeUpdateDate (string serverName, string dbName)
79 {
80 using (AMO.Server server = new AMO.Server())
81 {
82 server.Connect("Data Source=" + serverName);
83 AMO.Database db = server.Databases[dbName];
84 return db.Cubes[0].LastProcessed;
85 }
86 }
87 }
88 }
The program uses xml config file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<ServerName>MyOlapServer</ServerName>
<DataBaseName>MyDBName</DataBaseName>
<BookDir>MyBookDirPath</BookDir>
</Config>
The program assumes that all the database has the same update time so it takes the last process time of the first cube in the database. If it's not true in your case you can change it in the method GetCubeUpdateDate.
Enjoy.
update: If you're getting trouble with XmlDocument.Load method because of hexadecimal characters in the view's xml file, look
here.