2011-09-01 43 views
5

我們目前在Excel 2003中使用數據透視表來執行我們的報告。這些數據透視表使用內置的「導入外部數據」Excel功能從SQL(SQL Server 2008準確地)提供報告。更改Excel「外部數據」連接字符串

這些報告目前指向我們的英國數據庫,但我們現在想要製作一份指向我們新美國數據庫(與英國數據庫具有相同架構)的每份報告的副本。

與其苦心經過近100個電子表格,我希望能夠有一點COM自動化,我可以用它來更改每個電子表格中的連接字符串。

有誰知道從COM更改外部數據源連接字符串的方法嗎?我使用.Net(特別是C#),但我會很感激任何幫助,無論語言或方法(它不一定是COM)。

回答

12

看過各種VBA示例和MSDN COM文檔後,我已經知道如何去做。

重要的部分是連接字符串保存在兩個地方之一取決於您如何創建工作表。

  1. 如果你使用數據透視表嚮導,然後在連接字符串 將被存儲在 Workbook.PivotCaches()函數返回集合中(該PivotCache對象返回 有Connection屬性,它包含了連接字符串 ) 。

  2. 如果您使用「導入外部數據」連接字符串將存儲在 Worksheet.QueryTables屬性返回集合中 (該對象的QueryTable返回 有Connection屬性,它包含了連接 字符串)。

可能有更多的地方可以存儲連接字符串,這些是我目前知道的唯一兩個地方。如果您知道更多信息,請在評論中留下一些信息,我會添加到答案中。

這裏有一個很好的註釋完整的工作C#示例,以幫助其他任何人遇到這樣的問題:

static void ChangeConnectionStrings(string directoryName, string oldServerName, string newServerName) 
{    
    var directory = new DirectoryInfo(directoryName); 
    //get all the excel files from the directory 
    var files = directory.GetFiles("*.xls", SearchOption.AllDirectories); 

    Microsoft.Office.Interop.Excel.Application application = null; 

    try 
    { 
     //create a new application 
     application = new Microsoft.Office.Interop.Excel.Application(); 

     //go through each excel file 
     foreach (var file in files) 
     { 
      //open the file 
      application.Workbooks.Open(file.FullName); 

      //get the query tables from the worksheets 
      var sheets = application.Sheets.OfType<Worksheet>(); 
      var queryTables = sheets.SelectMany(s => GetQueryTables(s)); 

      //change the connection string for any query tables 
      foreach (var queryTable in queryTables) 
      { 
       queryTable.Connection = queryTable.Connection.Replace(oldServerName, newServerName); 
      } 

      //get the pivot table data from the workbooks 
      var workbooks = application.Workbooks.Cast<Workbook>(); 
      var pivotCaches = workbooks.SelectMany(w => GetPivotCaches(w)); 

      //change the connection string for any pivot tables 
      foreach (var pivotCache in pivotCaches) 
      { 
       pivotCache.Connection = pivotCache.Connection.Replace(oldServerName, newServerName); 
      } 

      Console.WriteLine("Saving " + file.Name); 

      //save the changes 
      foreach (var workbook in workbooks) 
      { 
       workbook.Save(); 
       workbook.Close(); 
      } 
     } 
    } 
    finally 
    { 
     //make sure we quit the application 
     if (application != null) 
      application.Quit(); 
    } 
} 

//PivotCaches isn't Enumerable so we can't just use Cast<PivotCache>, therefore we need a helper function 
static IEnumerable<PivotCache> GetPivotCaches(Workbook workbook) 
{ 
    foreach (PivotCache pivotCache in workbook.PivotCaches()) 
     yield return pivotCache; 
} 

//QueryTables isn't Enumerable so we can't just use Cast<QueryTable>, therefore we need a helper function 
static IEnumerable<QueryTable> GetQueryTables(Worksheet worksheet) 
{ 
    foreach (QueryTable queryTable in worksheet.QueryTables) 
     yield return queryTable; 
}