协助打开从 C# VSTO Excel 项目到关闭的 .xlsx 文件的连接(w/o 打开 .xlsx 文件)
Assistance opening a connection from C# VSTO Excel project to a closed .xlsx file (w/o opening the .xlsx file)
我正在尝试将我在 VBA 中编写的 Excel 加载项转换为 C# VSTO。作为 C# 和 VS 的新手,这似乎是扩展我技能的好方法,而无需提出新的项目想法。
原来的 AddIn 的一个特点是它可以将多个关闭的 .xlsx 工作簿读入内存,做一些基本的数学运算并将新数据输出到一个新的工作簿中。最初,这是使用 Adodb.Connection 实现的。目前,我无法将连接复制到 VSTO 插件中的工作簿。
正在读取的工作簿需要保持关闭状态。每个工作簿都有三到五个工作表,但我只需要其中一个具有静态名称的数据。这些列有 headers,但它们不是很友好 headers,例如 "Exclusive? (1=Yes, 0=No)" 或 "Discharge Date|Time Display"。列名是静态的,但列号不是。另外,我只处理每个工作簿中的少量数据。
到目前为止,我已经研究了几个不同的选项。 LinqToExcel 看起来很有希望,但由于我正在使用的列名太糟糕而未能实现。我还尝试使用 OleDbConnection 和 Adodb.connection 但收效甚微。
这是VBA成功的代码。
'Connection
Dim Cnx As ADODB.Connection: Set Cnx = New ADODB.Connection
With Cnx
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & fileToCopy & _
";Extended Properties='Excel 12.0 xml;HDR=Yes;IMEX=1;Readonly=False'"
.Open
End With
'Command String
Dim headerString As String, request_SQL As String
headerString = "[" & FullName & "]," & "[" & MRN & "]," & "[" & OHFColumnName & "]," & "[" & STSColumnName & "]," & "[" & IRColumnName & "]," & "[" & ERColumnName & "]"
request_SQL = "SELECT " & headerString & " FROM [" & NewbornsWS & "$] WHERE [" & FullName & "] IS NOT NULL OR [" & OHFColumnName & "] IS NOT NULL;"
'Create RecordSet
Dim Rst As ADODB.Recordset: Set Rst = New ADODB.Recordset
If OpenRecordset(Rst, request_SQL, Cnx) Then
Err.Raise vbObjectError + 518, Description:=Error518
End If
和
Private Function OpenRecordset(ByRef Rst As ADODB.Recordset, ByVal request_SQL As String, ByRef Cnx As ADODB.Connection) As Boolean
'Error Trapping for the RecordSet
myCallStack.Push "MonthStats.OpenRecordset"
Dim backupRequestString As String
On Error Resume Next
Rst.Open request_SQL, Cnx, adOpenStatic, adLockReadOnly, adCmdText
If Err.Number = 0 Then
OpenRecordset = False
myCallStack.Pop
Exit Function
Else
Rst.Close
OpenRecordset = True
myCallStack.Pop
Exit Function
End If
myCallStack.Pop
End Function
失败尝试:
我尝试在 C# 中使用 Adodb。这失败@ cnx.Open(connectionString);。
using ADODB;
internal static BreastFeedingData GetXlFileData(string fileName)
{
try
{
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + fileName +
";Extended Properties='Excel 12.0 xml;HDR=Yes;IMEX=1;Readonly=False'";
Connection cnx = new Connection();
cnx.Open(connectionString);
Recordset rst = new Recordset();
string headerString = $"[{MFullName}], [{MMRN}], [{MDDColumName}], [{MOHFColumnName}], [{MSTSColumnNameV}], [{MSTSColumnNameC}], [{MIRColumnName}], [{MERColumnName}]";
string request_SQL = $"SELECT {headerString} FROM [{MNewbornsWS}$] WHERE [{MFullName}] IS NOT NULL OR [{MOHFColumnName}] IS NOT NULL;";
rst.Open(request_SQL, cnx, CursorTypeEnum.adOpenStatic, LockTypeEnum.adLockReadOnly, 1);
BreastFeedingData breastFeedingData = ReadFromData(rst);
rst.Close();
return breastFeedingData;
}
catch (System.Runtime.InteropServices.COMException)
{
throw;
}
}
我也尝试过这个,运行 问题 @ cmd.Fill(excelDataSet);
private static TStats GetOpenXlFileData(DateTime dateTime, string fileName)
{
string connectionString = string.
Format("Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; " +
"Extended Properties='Excel 12.0; HDR = Yes; IMEX = 1; Readonly = False'", fileName);
OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);
string headerString = $"[{MFullName}], [{MMRN}], [{MOHFColumnName}], [{MSTSColumnNameV}], [{MSTSColumnNameC}], [{MIRColumnName}], [{MERColumnName}]";
string request_SQL = string.Format("SELECT {0} FROM [{1}$] WHERE [{2}] IS NOT NULL OR [{3}] IS NOT NULL;",
headerString, MNewbornsWS, MFullName, MOHFColumnName);
OleDbDataAdapter cmd = new System.Data.OleDb.OleDbDataAdapter(request_SQL, con);
con.Open();
System.Data.DataSet excelDataSet = new DataSet();
cmd.Fill(excelDataSet);
DataTable data = excelDataSet.Tables[0];
TStats stats = ReadFromData(data, dateTime);
con.Close();
return stats;
}
我不确定我的问题是在我的代码本身还是在我的 VS 设置中。如果需要更多信息,请告诉我。预先感谢您在帮助我解决此问题时可能提供的任何帮助。
The workbooks that are being read from need to remain closed.
试试我快速编写的这个基本函数。这是在 VB.Net.
xlsFile
是带路径的封闭 excel 文件名,ShName
是 sheet 名称。
Private Function LoadFromFile(xlsFile As String, ShName As String) As DataTable
Dim dt As DataTable = Nothing
'~~> Get the file data in the datatable
Try
'~~> Get data from file
Using MyConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" &
xlsFile &
";Extended Properties=""Excel 12.0;HDR=No;IMEX=1""")
MyConnection.Open()
Dim SheetName As String = ShName & "$"
Using MyCommand As New OleDb.OleDbDataAdapter("select * from [" & SheetName & "]", MyConnection)
dt = New DataTable
MyCommand.Fill(dt)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, "System Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return dt
End Function
Access database engine could not find the object 'Newborns_3$'. this is the correct name of the worksheet I am looking for. – Courtland9777 48 mins ago
久经考验
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim tmpdt As DataTable
tmpdt = LoadFromFile("C:\Users\routs\Desktop\book1.xlsx", "Newborns_3")
MessageBox.Show (tmpdt.Rows.Count)
End Sub
Private Function LoadFromFile(xlsFile As String, ShName As String) As DataTable
Dim dt As DataTable = Nothing
'~~> Get the file data in the datatable
Try
'~~> Get data from file
Using MyConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" &
xlsFile &
";Extended Properties=""Excel 12.0;HDR=No;IMEX=1""")
MyConnection.Open()
Dim SheetName As String = ShName & "$"
Using MyCommand As New OleDb.OleDbDataAdapter("select * from [" & SheetName & "]", MyConnection)
dt = New DataTable
MyCommand.Fill (dt)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, "System Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return dt
End Function
End Class
我正在尝试将我在 VBA 中编写的 Excel 加载项转换为 C# VSTO。作为 C# 和 VS 的新手,这似乎是扩展我技能的好方法,而无需提出新的项目想法。
原来的 AddIn 的一个特点是它可以将多个关闭的 .xlsx 工作簿读入内存,做一些基本的数学运算并将新数据输出到一个新的工作簿中。最初,这是使用 Adodb.Connection 实现的。目前,我无法将连接复制到 VSTO 插件中的工作簿。
正在读取的工作簿需要保持关闭状态。每个工作簿都有三到五个工作表,但我只需要其中一个具有静态名称的数据。这些列有 headers,但它们不是很友好 headers,例如 "Exclusive? (1=Yes, 0=No)" 或 "Discharge Date|Time Display"。列名是静态的,但列号不是。另外,我只处理每个工作簿中的少量数据。
到目前为止,我已经研究了几个不同的选项。 LinqToExcel 看起来很有希望,但由于我正在使用的列名太糟糕而未能实现。我还尝试使用 OleDbConnection 和 Adodb.connection 但收效甚微。
这是VBA成功的代码。
'Connection
Dim Cnx As ADODB.Connection: Set Cnx = New ADODB.Connection
With Cnx
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & fileToCopy & _
";Extended Properties='Excel 12.0 xml;HDR=Yes;IMEX=1;Readonly=False'"
.Open
End With
'Command String
Dim headerString As String, request_SQL As String
headerString = "[" & FullName & "]," & "[" & MRN & "]," & "[" & OHFColumnName & "]," & "[" & STSColumnName & "]," & "[" & IRColumnName & "]," & "[" & ERColumnName & "]"
request_SQL = "SELECT " & headerString & " FROM [" & NewbornsWS & "$] WHERE [" & FullName & "] IS NOT NULL OR [" & OHFColumnName & "] IS NOT NULL;"
'Create RecordSet
Dim Rst As ADODB.Recordset: Set Rst = New ADODB.Recordset
If OpenRecordset(Rst, request_SQL, Cnx) Then
Err.Raise vbObjectError + 518, Description:=Error518
End If
和
Private Function OpenRecordset(ByRef Rst As ADODB.Recordset, ByVal request_SQL As String, ByRef Cnx As ADODB.Connection) As Boolean
'Error Trapping for the RecordSet
myCallStack.Push "MonthStats.OpenRecordset"
Dim backupRequestString As String
On Error Resume Next
Rst.Open request_SQL, Cnx, adOpenStatic, adLockReadOnly, adCmdText
If Err.Number = 0 Then
OpenRecordset = False
myCallStack.Pop
Exit Function
Else
Rst.Close
OpenRecordset = True
myCallStack.Pop
Exit Function
End If
myCallStack.Pop
End Function
失败尝试:
我尝试在 C# 中使用 Adodb。这失败@ cnx.Open(connectionString);。
using ADODB;
internal static BreastFeedingData GetXlFileData(string fileName)
{
try
{
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + fileName +
";Extended Properties='Excel 12.0 xml;HDR=Yes;IMEX=1;Readonly=False'";
Connection cnx = new Connection();
cnx.Open(connectionString);
Recordset rst = new Recordset();
string headerString = $"[{MFullName}], [{MMRN}], [{MDDColumName}], [{MOHFColumnName}], [{MSTSColumnNameV}], [{MSTSColumnNameC}], [{MIRColumnName}], [{MERColumnName}]";
string request_SQL = $"SELECT {headerString} FROM [{MNewbornsWS}$] WHERE [{MFullName}] IS NOT NULL OR [{MOHFColumnName}] IS NOT NULL;";
rst.Open(request_SQL, cnx, CursorTypeEnum.adOpenStatic, LockTypeEnum.adLockReadOnly, 1);
BreastFeedingData breastFeedingData = ReadFromData(rst);
rst.Close();
return breastFeedingData;
}
catch (System.Runtime.InteropServices.COMException)
{
throw;
}
}
我也尝试过这个,运行 问题 @ cmd.Fill(excelDataSet);
private static TStats GetOpenXlFileData(DateTime dateTime, string fileName)
{
string connectionString = string.
Format("Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; " +
"Extended Properties='Excel 12.0; HDR = Yes; IMEX = 1; Readonly = False'", fileName);
OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);
string headerString = $"[{MFullName}], [{MMRN}], [{MOHFColumnName}], [{MSTSColumnNameV}], [{MSTSColumnNameC}], [{MIRColumnName}], [{MERColumnName}]";
string request_SQL = string.Format("SELECT {0} FROM [{1}$] WHERE [{2}] IS NOT NULL OR [{3}] IS NOT NULL;",
headerString, MNewbornsWS, MFullName, MOHFColumnName);
OleDbDataAdapter cmd = new System.Data.OleDb.OleDbDataAdapter(request_SQL, con);
con.Open();
System.Data.DataSet excelDataSet = new DataSet();
cmd.Fill(excelDataSet);
DataTable data = excelDataSet.Tables[0];
TStats stats = ReadFromData(data, dateTime);
con.Close();
return stats;
}
我不确定我的问题是在我的代码本身还是在我的 VS 设置中。如果需要更多信息,请告诉我。预先感谢您在帮助我解决此问题时可能提供的任何帮助。
The workbooks that are being read from need to remain closed.
试试我快速编写的这个基本函数。这是在 VB.Net.
xlsFile
是带路径的封闭 excel 文件名,ShName
是 sheet 名称。
Private Function LoadFromFile(xlsFile As String, ShName As String) As DataTable
Dim dt As DataTable = Nothing
'~~> Get the file data in the datatable
Try
'~~> Get data from file
Using MyConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" &
xlsFile &
";Extended Properties=""Excel 12.0;HDR=No;IMEX=1""")
MyConnection.Open()
Dim SheetName As String = ShName & "$"
Using MyCommand As New OleDb.OleDbDataAdapter("select * from [" & SheetName & "]", MyConnection)
dt = New DataTable
MyCommand.Fill(dt)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, "System Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return dt
End Function
Access database engine could not find the object 'Newborns_3$'. this is the correct name of the worksheet I am looking for. – Courtland9777 48 mins ago
久经考验
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim tmpdt As DataTable
tmpdt = LoadFromFile("C:\Users\routs\Desktop\book1.xlsx", "Newborns_3")
MessageBox.Show (tmpdt.Rows.Count)
End Sub
Private Function LoadFromFile(xlsFile As String, ShName As String) As DataTable
Dim dt As DataTable = Nothing
'~~> Get the file data in the datatable
Try
'~~> Get data from file
Using MyConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" &
xlsFile &
";Extended Properties=""Excel 12.0;HDR=No;IMEX=1""")
MyConnection.Open()
Dim SheetName As String = ShName & "$"
Using MyCommand As New OleDb.OleDbDataAdapter("select * from [" & SheetName & "]", MyConnection)
dt = New DataTable
MyCommand.Fill (dt)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, "System Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return dt
End Function
End Class