Potresti fare una cosa del genere adattandola al formato del tuo excel.

codice:
 Private rowCount As Integer = 0
    Private IsExcelReaded As Boolean = False
    Private columnCountToRead As Integer = 0

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Try
            Dim MyConnection As System.Data.OleDb.OleDbConnection
            Dim DtSet As System.Data.DataSet
            Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
            MyConnection = New System.Data.OleDb.OleDbConnection _
            ("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\temp\testfile.xls';Extended Properties='Excel 8.0;IMEX=1;ImportMixedTypes=Text'")
            MyCommand = New System.Data.OleDb.OleDbDataAdapter _
                ("select * from [Test$]", MyConnection)
            MyCommand.TableMappings.Add("Table", "TestTable")

            DtSet = New System.Data.DataSet
            MyCommand.Fill(DtSet)
            IsExcelReaded = False
            While IsExcelReaded = False
                columnCountToRead = 0
                'Controllo il numero di colonne valide da leggere ipotizzando che sia specificato il nome colonna della tabella
                For columnHeaderIndex As Integer = 0 To DtSet.Tables(0).Columns.Count - 1

                    If (IsReadeableColumn(DtSet.Tables(0).Rows(rowCount)(columnHeaderIndex).ToString()) = True) Then
                        columnCountToRead = columnCountToRead + 1
                    End If
                Next
                'Alla prima lettura l'indice parte da 0
                If (rowCount <> 0) Then
                    rowCount = rowCount + 1
                End If
                'Leggo Righe
                ReadRows(DtSet)
                If (rowCount = DtSet.Tables(0).Rows.Count) Then
                    IsExcelReaded = True
                End If
            End While
            MyConnection.Close()
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub ReadRows(ByVal DtSet As DataSet)
        For rowIndex As Integer = rowCount To DtSet.Tables(0).Rows.Count - 1
            If (DtSet.Tables(0).Rows(rowIndex)(0).ToString().Contains("///") = False) Then
                Dim columnsValues As String = String.Empty
                For columnHeaderIndex As Integer = 0 To columnCountToRead - 1
                    columnsValues = columnsValues & DtSet.Tables(0).Rows(rowIndex)(columnHeaderIndex).ToString() & ";"
                Next
                MessageBox.Show(columnsValues)
            Else
                rowCount = rowCount + 1
                Exit For
            End If
            rowCount = rowCount + 1
        Next
    End Sub


    Private Function IsReadeableColumn(ByVal columnValue As String) As Boolean
        If (String.IsNullOrEmpty(columnValue)) Then
            Return False
        End If
        Return True
    End Function
Il codice sopra legge i valori di un excel formattato con le tabelle una sotto l'altra dando per scontato che ci sia il nome del campo per ogni tabella e non ci siano righe vuote tra una "tabella" e l'altra ma solo i ///// come seperatore di tabella.

Id | Valore
1 | a
2 | b
3| c
////////// ////////
Tab2Id | Tab2Valore | Tab3Valore
10 | h | bbb
11 | j |
12 | k |
13 | l |
//////// //////// ///////////