协助打开从C#VSTO Excel项目到关闭的.xlsx文件的连接(不打开.xlsx文件)

时间:2019-04-03 10:32:48

标签: c# excel vba vsto

我正在尝试将在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设置中。如果需要更多信息,请告诉我。预先感谢您为帮助我解决此问题提供的任何帮助。

1 个答案:

答案 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