我正在尝试将在VBA中编写的Excel加载项转换为C#VSTO。对C#和VS相当陌生,这似乎是一种扩展我的技能的好方法,而无需提出新的项目构想。
原始AddIn的功能之一是它可以将多个封闭的.xlsx工作簿读入内存,执行一些基本数学运算并将新数据输出到新工作簿中。最初,这是通过Adodb.Connection实现的。当前,我无法将连接复制到VSTO加载项中的工作簿。
正在读取的工作簿需要保持关闭状态。每个工作簿都有三到五个工作表,但是我只需要其中一个具有静态名称的数据。这些列具有标题,但是它们不是很友好的标题,例如“ Exclusive?(1 =是,0 =否)”或“卸货日期|时间显示”。列名是静态的,但列号不是。另外,我在每个工作簿中只处理少量数据。
到目前为止,我已经研究了几种不同的选择。 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设置中。如果需要更多信息,请告诉我。预先感谢您为帮助我解决此问题提供的任何帮助。
答案 0 :(得分:3)
正在读取的工作簿需要保持关闭状态。
尝试一下我快速编写的基本功能。在VB.Net中。
xlsFile
是带有路径的已关闭excel文件名,而ShName
是工作表名称。
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数据库引擎找不到对象“ Newborns_3 $”。这是我要查找的工作表的正确名称。 – 48分钟前,Courtland9777
经过反复测试
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