2011-09-01 15 views
5

現在、Excel 2003でピボットテーブルを使用してレポートを作成しています。これらのピボット・テーブルは、組み込みの「外部データのインポート」Excel機能を使用して、SQL(SQL Server 2008を正確に)からレポートを供給します。Excelを変更する "外部データ"接続文字列

現在のレポートは英国のデータベースを指していますが、新しい米国データベース(英国のデータベースと同じスキーマを持つ)を指している各レポートのコピーを作成したいと考えています。

苦労して100枚近くのスプレッドシートを調べるのではなく、各スプレッドシートの接続文字列を変更するのに便利なCOMオートメーションがあることを期待していました。

COMから外部データソース接続文字列を変更する方法を知っている人はいますか?

私は.NET(特にC#)を使用していますが、言語や方法に関係なく(COMである必要はありません)どんなヘルプにも感謝します。

答えて

12

さまざまなVBAの例とMSDN COMのドキュメントを見て、それを行う方法を理解しました。

重要な部分は、ワークシートの作成方法によって2つの場所のいずれかに接続文字列が保持されることです。あなたは、接続文字列 が Workbook.PivotCaches()関数によって返されたコレクションに格納され、ピボットテーブルウィザードを使用している場合

  1. (PivotCacheが返さ が接続 文字列が含まれているConnectionプロパティを持つオブジェクト) 。

  2. あなたは、「外部データの取り込み」を使用した場合は、接続文字列が (クエリテーブルが返さ が接続 文字列が含まれているConnectionプロパティを持つオブジェクト) Worksheet.QueryTablesプロパティによって返されるコレクションに格納されます。

接続文字列を格納できる場所がもっとあるかもしれませんが、これはこれまで私が知っている唯一の2つです。あなたがもう知っているなら、コメントの中にいくつかの情報を残してください。私は答えに追加します。

ここでは、この問題に出くわす誰を助けるためにうまくコメント完全に動作する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; 
} 
関連する問題