我一直在努力寻找获取和更改Excel工作簿连接的方法(菜单数据 - >现有连接 - >此工作簿上的连接)。它是一个连接(实际上是几个)到SQL Server并使用在数据透视表中。
我尝试过使用 Application.ActiveWorkbook.Connections 或 Globals.ThisWorkbook.Connections ,但它们都返回Null ..我已经在工作表事件中尝试过以及自定义功能区的按钮事件。
我能想到的唯一方法就是用来编写一个VBA方法来完成工作,然后在我的VSTO代码中调用它,但它不是很优雅它是......
答案 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中使用查询表。