我正在将全新服务器上的 BizTalk 2016 更新到 BizTalk 2020,并安装了 Access OleDB 提供程序。它似乎适用于 .xlsx 文件,但对于 .xls 文件,它无法动态查找工作表名称。实际例程位于从 BizTalk 调用的 C# 类库中,但为了帮助调试,我创建了以下测试方法,以便我可以在 BizTalk 之外的简单控制台应用程序中对其进行测试。我通过了 conn.open() 和库未注册的问题。
我认为 .xls 根本没有加载。如果我使用硬编码的工作表名称,它会给出此错误:“Microsoft Access 数据库引擎找不到对象‘Sheet1$’”,即使在 Excel 中,这就是工作表名称(添加了 $ 符号)。
现有代码适用于我们现有的系统,并使用我在下面显示的 connectionStringOld。如果我在 .xls 文件上尝试该版本,它会出现“未注册”错误。
我是否必须为 .xls 文件使用旧版本的提供程序?
static void testAccessOleDBAdapterForExcel()
{
string methodPrefix = "method: testAccessOleDBAdapterForExcel - ";
string excelFilename = null;
string worksheetName = null;
int fileNumber = 1; //switch between two files and corresponding sheet name
if (fileNumber == 1)
{
excelFilename = @"\\Share1\SampleExcelFiles\PublishPowerMeterData_-15_05012023060600_2023-05-01T06-04-02.xls";
worksheetName = "Sheet1";
}
else
{
excelFilename = @"\\Share1\SampleExcelFiles\PublishForwardPrice_powerfolio_extract_05_01_2023_08_00_2023-05-01T14-56-04.xlsx";
worksheetName = "South";
}
// We have to add on the end of the actual Worksheet
worksheetName = worksheetName + "$";
// original code on BT20106 used ACE.OLEDB.10.0
//var connectionStringOld = @"Provider=Microsoft.ACE.OLEDB.10.0;Data Source=" + excelFilename + ";Extended Properties=\"Excel 10.0;HDR=YES\"";
var connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFilename + ";Extended Properties=\"Excel 12.0;HDR=YES\"";
Console.WriteLine(methodPrefix + "FileName=" + excelFilename);
Console.WriteLine(methodPrefix + "attempt spreadsheet read with Access OleDB Adapter");
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
Console.WriteLine(methodPrefix + "Conn.Open() succeeded");
var schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
// The following if statement throws the ArgumentException with the .xls
if (schemaTable.Rows.Count < 1) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet");
string dynWorksheet = schemaTable.Rows[0]["table_name"].ToString().Replace("'", "");
Console.WriteLine(methodPrefix + "dynWorksheet = " + dynWorksheet);
OleDbDataAdapter objDA = new System.Data.OleDb.OleDbDataAdapter
("select * from [" + dynWorksheet + "]", conn);
DataSet excelDataSet = new DataSet();
objDA.Fill(excelDataSet);
Console.WriteLine("method: testAccessOleDBAdapterForExcel - was able to fill dataset object");
}
}
调试中:
使用Visual Studio 2019(兼容BizTalk 2020), .NET Framework 4.7.2,以及这些构建选项:
尝试“Excel 8.0;HDR=Yes”时遇到同样的问题:https://www.connectionstrings.com/ace-oledb-12-0/excel-97-2003-xls-files-with-ace- oledb-120/
事实证明,以.xls 结尾的文件不是正确的文件。它没有标题,也没有数据,还有一个奇怪的工作表名称。当我使用正确的 .xls 文件进行测试时,它运行良好。
我把error改的更有意义,出自:
if (schemaTable.Rows.Count < 1) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet");
对此:
if (schemaTable.Rows.Count < 1) throw new ArgumentException(
"GetOleDbSchemaTable returned schemaTable.Rows.Count<0, so could not dynamically find the excel sheetname. " +
"Potentially invalid Excel worksheet, or missing data and/or headers.");
此外,由于在 BizTalk 下运行,它可能会出现奇怪的错误并且无法捕获 SEHException(在托管代码中),因此我也加强了异常消息:
catch (Exception ex)
{
// We had this issue when running in 32-bit instead of 64-bit on BizTalk 2020 install/testing
string messageIdentifier = "SystemException in MapExcel_To_Xml_v0100: ";
string errorMessage = messageIdentifier + " ex.Message=" + ex.Message;
string specialError = "External component has thrown an exception.";
if (ex.Message.Contains(specialError))
{
errorMessage = messageIdentifier + "This error might be an OLDEDB Conn.Open SEHException which .NET cannot catch correctly, " +
" and might be related to running in the 64-bit vs 32-bit mode. " +
" ConnectionString=" + connectionString +
" ex.errorMessage=" + ex.Message;
}
System.Diagnostics.EventLog.WriteEntry(strClassName + "." + strMethodName, errorMessage, System.Diagnostics.EventLogEntryType.Error);
throw ex;
}