问题
I am working with Excel Interop namespace to modify connection string in the Excel Workbook connections.
Why when I am trying to set the connection property (MSDN OLEDBConnection.Connection) throws an error on the line of the assignment?
Exception from HRESULT: 0x800A03EC
application = new Application();
Workbook wb = application.Workbooks.Open(file.FullName);
Sheets wbs = wb.Worksheets;
IEnumerable<Workbook> workbooks = application.Workbooks.Cast<Workbook>();
foreach (var connection in wb.Connections.Cast<WorkbookConnection>()
.Where(c => c.Type == XlConnectionType.xlConnectionTypeOLEDB))
{
connection.OLEDBConnection.Connection = "Test Connection String";
}
application.Quit();
However, calling Replace method as shown below is working. I have found this as workaround, not being sure why Replace works in this case.
application = new Application();
Workbook wb = application.Workbooks.Open(file.FullName);
Sheets wbs = wb.Worksheets;
IEnumerable<Workbook> workbooks = application.Workbooks.Cast<Workbook>();
foreach (var connection in wb.Connections.Cast<WorkbookConnection>()
.Where(c => c.Type == XlConnectionType.xlConnectionTypeOLEDB))
{
var conString = connection.OLEDBConnection.Connection.ToString();
connection.OLEDBConnection.Connection =
conString.Replace("Test Connection String", "New Test Connection String");
}
application.Quit();
This in fact is the only way I could get the connection string changed, therefore asking what is the reason behind why set could be throwing the error.
回答1:
There could be many reasons. The common of all being backwards compatibility. Such as XLS file being opened.
Also normalize the full file path - use backslashes. Set DefaultSaveFormat to xlOpenXML or something similar on 'application' if you are sure that you are not operating on a file created with older version of Excel.
The COM error with the code you specified, is generally thrown when it cannot resolve the object name - within the Workbook - or it has any other problem in resolution of such names.
If these fail, check this link:
http://www.hagrin.com/319/exception-hresult-0x800a03ec-excel-net-sql-and-windows-server-2008
回答2:
I found a way to use the OpenXML instead, seems that changing connection string via interop was not the only way.
using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(file.FullName, true))
{
WorkbookPart workbookpart = excelDoc.WorkbookPart;
ConnectionsPart connPart = workbookpart.ConnectionsPart;
string spreadsheetmlNamespace = @"http://schemas.openxmlformats.org/spreadsheetml/2006/main";
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("sh", spreadsheetmlNamespace);
XmlDocument xdoc = new XmlDocument(nt);
xdoc.Load(connPart.GetStream());
XmlNode oxmlNode = xdoc.SelectSingleNode("/sh:connections/sh:connection/sh:dbPr/@connection", nsManager);
string newConnection = ReplaceInitialCatalog(oxmlNode.Value, repConfig.DbName);
oxmlNode.Value = oxmlNode.Value.Replace(oxmlNode.Value, newConnection);
//Truncates part with FeedData
connPart.FeedData(connPart.GetStream());
xdoc.Save(connPart.GetStream());
}
回答3:
Issue was that connection string seem to have special prefix (OLEDB;
) which is checked upon the assignment so it can be solved by this:
...
connection.OLEDBConnection.Connection = "OLEDB;Test Connection String";
...
Prefix showed its face upon connection string retrieval, thus the clue.
Though recommend OpenXML due to ease of testability.
来源:https://stackoverflow.com/questions/38302778/why-setting-oledbconnection-connection-throws-exception-hresult-0x800a03ec