【问题标题】:Change Excel "External Data" Connection String更改 Excel“外部数据”连接字符串
【发布时间】:2011-09-01 09:06:57
【问题描述】:

我们目前在 Excel 2003 中使用数据透视表来进行报告。这些数据透视表使用内置的“导入外部数据”Excel 功能从 SQL(准确地说是 SQL server 2008)提供报告。

报告目前指向我们的英国数据库,但我们现在想要为指向我们新的美国数据库(与英国数据库具有相同架构)的每份报告制作副本。

与其费力地检查近 100 个电子表格,我希望有一点 COM 自动化,我可以使用它来更改每个电子表格中的连接字符串。

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

我正在使用 .Net(特别是 C#),但无论语言或方法如何,我都将不胜感激(它不必是 COM)。

【问题讨论】:

    标签: c# .net com excel-2003


    【解决方案1】:

    在查看了各种 VBA 示例和 MSDN COM 文档之后,我想出了如何去做。

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

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

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

    可能有更多的地方可以存储连接字符串,这是我目前所知道的仅有的两个。如果您知道更多,请在 cmets 中留下一些信息,我会添加到答案中。

    这是一个很好的注释完整的工作 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;
    }
    

    【讨论】:

    • 'pivotCache.Connection' 抛出了一个 'System.Runtime.InteropServices.COMException' 类型的异常......有什么想法吗?
    • 不幸的是,这是一个非常普遍的例外。您的工作表上是否有任何实际上不使用连接的数据透视表?我的代码假设它们都连接到外部数据源。您可以尝试在 foreach 内对 pivotCache.Connection 的调用周围放置一个 try catch,然后您可以记录哪个 pivotCache 导致了问题。它会以某种方式变得果味。
    • 感谢您的建议。我试试
    猜你喜欢
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    相关资源
    最近更新 更多