VSTO 3.0获取/更改excel 2007工作簿连接

时间:2009-09-24 16:15:45

标签: connection vsto excel-2007

我一直在努力寻找获取和更改Excel工作簿连接的方法(菜单数据 - >现有连接 - >此工作簿上的连接)。它是一个连接(实际上是几个)到SQL Server并使用在数据透视表中。

我尝试过使用 Application.ActiveWorkbook.Connections Globals.ThisWorkbook.Connections ,但它们都返回Null ..我已经在工作表事件中尝试过以及自定义功能区的按钮事件。

我能想到的唯一方法就是用来编写一个VBA方法来完成工作,然后在我的VSTO代码中调用它,但它不是很优雅它是......

3 个答案:

答案 0 :(得分:2)

Excel中的现有连接(这在2007中有效)不是活动连接。您必须先使用现有连接进行连接才能获取该连接(我在单击执行此代码的按钮之前手动完成此操作)。

var application = Globals.ThisAddIn.Application;
//This must be an active connection otherwise handle exceptions
// such as 'Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))'
var connection = application.ActiveWorkbook.Connections["EXISTING_CONNECTION_NAME"];
var oledb = connection.OLEDBConnection;
var settings = oledb.Connection;

答案 1 :(得分:1)

这里我调整了Excel Connections的连接字符串。请注意我在工作簿中只有一个连接。

public class WorkbookConnectionsManager
{
  public static void AdjustConnectionToSqlConnectionString(Excel.WorkbookConnection connection, String connectionString)
  {
    char[] propertiesSeparator = new char[] { ';' };
    char[] propertyValueSeparator = new char[] { '=' };

    Excel.OLEDBConnection oleDbConn = connection.OLEDBConnection;

    Dictionary<string, string> dictExcelConnStrProperties = GetConnStrDictionary(oleDbConn.Connection, propertiesSeparator, propertyValueSeparator);
    Dictionary<string, string> dictActualConnStrProperties = GetConnStrDictionary(connectionString, propertiesSeparator, propertyValueSeparator);

    string[] reggedPropertyies = new string[] { "Integrated Security", "Persist Security Info", "User ID", "Password", "Initial Catalog", "Data Source", "Workstation ID" };

    foreach (string property in reggedPropertyies)
      if (dictExcelConnStrProperties.ContainsKey(property) && dictActualConnStrProperties.ContainsKey(property)
        && null != dictActualConnStrProperties[property] && !String.IsNullOrEmpty(dictActualConnStrProperties[property].ToString()))
          dictExcelConnStrProperties[property] = dictActualConnStrProperties[property];

    string connStr = GetConnStrFromDict(dictExcelConnStrProperties, propertiesSeparator[0], propertyValueSeparator[0]);

    oleDbConn.Connection = connStr;
  }

  private static string GetConnStrFromDict(Dictionary<string, string> dictConnStrProperties, char propertiesSeparator, char propertyValueSeparator)
  {
    StringBuilder connStrBuilder = new StringBuilder();
    foreach (KeyValuePair<string, string> keyValuePair in dictConnStrProperties)
    {
      connStrBuilder.Append(keyValuePair.Key);
      if (!String.IsNullOrEmpty(keyValuePair.Value))
      {
        connStrBuilder.Append(propertyValueSeparator);
        connStrBuilder.Append(keyValuePair.Value);
      }
      connStrBuilder.Append(propertiesSeparator);
    }

    string connStr = String.Empty;
    if (connStrBuilder.Length > 1)
    {
      connStr = connStrBuilder.ToString(0, connStrBuilder.Length - 1);
    }

    return connStr;
  }

  private static Dictionary<string, string> GetConnStrDictionary(string connString, char[] propertiesSeparator, char[] propertyValueSeparator)
  {
    string[] keyAndValue;

    string[] arrayConnStrProperties = connString.Split(propertiesSeparator);
    Dictionary<string, string> dictConnStrProperties = new Dictionary<string, string>();
    foreach (string excelConnStrProperty in arrayConnStrProperties)
    {
      keyAndValue = excelConnStrProperty.Split(propertyValueSeparator);
      if (keyAndValue.Length > 1)
      {
        dictConnStrProperties.Add(keyAndValue[0], keyAndValue[1]);
      }
      else if (keyAndValue.Length > 0)
      {
        //standalone attribute
        dictConnStrProperties.Add(keyAndValue[0], String.Empty);
      }
    }

    return dictConnStrProperties;
  }



}

答案 2 :(得分:0)

我不记得在哪里,但我记得在某处读过Connections集合用于编写ODBC类型连接的用途有限。它有几个用于“连接”的枚举值,但我不确定其中一些是否只是来自该接口。

无论从VSTO实现新连接和编辑现有连接都应该很容易。最好的选择是use COM interop to call来自ODBCCP32.DLL win32库的SQLConfigDataSource() function。 另请查看the following addin,这样可以更轻松地在Excel中使用查询表。