使用ADO和VB.net从excel中的特定行检索列标题

时间:2016-08-30 20:28:07

标签: vb.net excel-vba ado.net vba excel

我有一个应用程序,用户上传电子表格并指定标题行的工作表名称和行号。我需要该应用程序从该指定行中提取列名称。我能够让它返回顶行。我如何指出我想要的列名应该在行(x)

     Dim ExcelConn As System.Data.OleDb.OleDbConnection
        Dim ExcelTable As DataTable = Nothing
        Dim dr As DataRow
        Dim sheet_found As Boolean = False
        ExcelConn = New system.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & file & ";Extended Properties=Excel 12.0;")
        End If

        'open the file
        ExcelConn.Open()
        ExcelTable = ExcelConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "Table"})

        'make sure there is a matching sheet name
        For Each dr In ExcelTable.Rows
            If dr("TABLE_NAME").ToString() = sheet & "$" Then
                sheet_found = True
                Exit For
            End If
        Next
        If sheet_found = False Then
            MesgBox("the sheet name specified in the header (" + sheet + ") was not found")
            ExcelConn.Close()
            Exit Sub
        Else
            Dim sheet_name As String = Nothing
            sheet_name = "[" & sheet & "$]"
            Dim cmd1 As New System.Data.OleDb.OleDbCommand("Select * From " & sheet_name, ExcelConn)
            Dim da As New OleDbDataAdapter("Select * From " & sheet_name, ExcelConn)
            Dim ds As DataSet = New DataSet()
            Dim dc As DataColumn
            da.Fill(ds)
            For Each dc In ds.Tables(0).Columns 'this returns col names fine from first row. how would i tell it to get names from 2nd or 3rd row, etc. The integer var is passed in. i just need to know how to specify that it is row(x)
                header_row = LCase(RTrim(header_row + "|" + dc.ColumnName))
            Next
            MsgBox(header_row)
            ExcelConn.Close()
        End If

2 个答案:

答案 0 :(得分:0)

据我所知(过去检查过该问题),如果标题未放入第1行,则无法使用SQL查询从excel文件中选择System.Data.OleDb的表。我的解决方案是在查询工作表之前删除标题行上方的所有行 - 只需打开工作簿Microsoft.Office.Interop删除额外的行,关闭它而不是查询它。

Excel是一个非常强大的工具,但从来没有设计成像数据库(例如sql server或access file)。

答案 1 :(得分:0)

jonathana指出,使用JET / ACE驱动程序访问Excel工作表中的数据有一些已知的限制。

作为替代方案,我想提供我们的Excel ADO.NET Provider。有了它,您可以从JET / ACE驱动程序获得您习惯使用的Excel数据的所有SQL访问权限,但可以更灵活地在Excel中安排数据。

在您的示例中,您可以提交类似以下内容的查询,以表示标题位于第4行:

SELECT * FROM Sheet1#A4:**

使用我们的提供商,您的代码将类似于以下内容:

Dim ExcelConn As System.Data.CData.Excel.ExcelConnection
Dim ExcelTable As DataTable = Nothing
Dim dr As DataRow
Dim sheet_found As Boolean = False
ExcelConn = New System.Data.CData.Excel.ExcelConnection("Excel File=" & file & ";")

'open the file
ExcelConn.Open()
ExcelTable = ExcelConn.GetSchema("Tables")

'make sure there is a matching sheet name
For Each dr In ExcelTable.Rows
  If dr("Table_Name").ToString() = sheet Then
    sheet_found = True
    Exit For
  End If
Next
If sheet_found = False Then
  MesgBox("the sheet name specified in the header (" + sheet + ") was not found")
  ExcelConn.Close()
  Exit Sub
Else
  Dim sheet_name As String = Nothing
  'Here, I assume that header_row indicates the row that contains the headers
  sheet_name = "[" & sheet & "#A" & header_row & ":**]"
  Dim cmd1 As New System.Data.CData.Excel.ExcelCommand("Select * From " & sheet_name, ExcelConn)
  Dim da As New System.Data.CData.Excel.ExcelDataAdapter("Select * From " & sheet_name, ExcelConn)
  Dim ds As DataSet = New DataSet()
  Dim dc As DataColumn
  da.Fill(ds)
  For Each dc In ds.Tables(0).Columns
    'I wasn't sure what this code was meant to accomplish, but at this point, 
    'dc.ColumnName contains the column names from header_row
  Next
  ExcelConn.Close()
End If

我们的网站上有一个blog post,其中包含有关我们提供商的更多信息,您也可以从我们的网站download a free trial获取。