更改Excel"外部数据"连接字符串

Rei*_*ica 8 .net c# com excel-2003

我们目前在Excel 2003中使用数据透视表来执行报告.这些数据透视表使用内置的"导入外部数据"Excel功能从SQL(精确的SQL Server 2008)提供报表.

这些报告目前指向我们的英国数据库,但我们现在想要制作一份指向我们新的美国数据库(与英国数据库具有相同模式)的每份报告的副本.

我不是苦心经历近100个电子表格,而是希望有一些COM自动化可用于更改每个电子表格中的连接字符串.

有没有人知道从COM更改外部数据源连接字符串的方法?

我正在使用.Net(特别是C#),但无论语言或方法如何,我都会感激任何帮助(它不一定是COM).

Rei*_*ica 13

在查看各种VBA示例和MSDN COM文档之后,我已经找到了如何做到这一点.

重要的是,连接字符串保存在两个位置之一,具体取决于您创建工作表的方式.

  1. 如果您已使用数据透视表向导,则连接字符串将存储在Workbook.PivotCaches()函数返回的集合中(返回 的PivotCache对象具有Connection包含连接字符串的属性).

  2. 如果使用"导入外部数据",则连接字符串将存储在Worksheet.QueryTables属性返回的集合中(返回 的QueryTable对象具有Connection包含连接字符串的属性).

可能存在更多可以存储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;
}
Run Code Online (Sandbox Code Playgroud)