Невозможно получить имена листов с помощью GetOleSchemaTable () - PullRequest
0 голосов
/ 14 июня 2011

Я работаю с некоторым кодом, который использует OleDbConnection для загрузки данных из файла Excel в DataTable. В настоящее время по умолчанию используется первый лист, но его имя получают с использованием следующего кода:

string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=myFilename.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"""

DataTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schemaTable.Rows.Count > 0)
    return schemaTable.Rows[0]["TABLE_NAME"].ToString();
else
    return "Sheet1$"

Это работало нормально до недавнего времени, когда документ Excel (который мы получаем от третьей стороны) начал содержать именованные диапазоны. У меня нет скрытых листов, которые я могу найти.

Теперь

schemaTable.Rows[0]["TABLE_NAME"].ToString()

возвращает имя первого диапазона.

Могу ли я сделать что-то другое с моим объектом schemaTable для идентификации только листов, а не именованных диапазонов в листе?

Ответы [ 2 ]

0 голосов
/ 14 июня 2011

Обязательно ли использование OleDbConnection или вы можете переключиться на другие опции (например, DAO)?

альтернативное решение 1: с помощью взаимодействия:

    Private Function GetSheetNames(ByVal path As String)
    Dim lst As New List(Of String)
    'Note: this will not work for Excel 2007 (.xlsx) workbooks.
    If IO.File.Exists(path) AndAlso IO.Path.GetExtension(path) = ".xls" Then
    Dim app As New Excel.Application
    Dim WB As Excel.Workbook
    Try
       WB = app.Workbooks.Open(Filename:=path)
       If WB IsNot Nothing Then
         For Each ws As Excel.Worksheet In WB.Sheets
           lst.Add(ws.Name)
         Next
         WB.Close()
         System.Runtime.InteropServices.Marshal.ReleaseComObject(WB)
         WB = Nothing
       End If
    Catch ex As Exception
       MessageBox.Show(ex.Message)
    Finally
       System.Runtime.InteropServices.Marshal.ReleaseComObject(app)
       app = Nothing
    End Try
     End If
     Return lst
End Function

Источник: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/21d3f77c-1d3d-44e0-9bd5-eca45a0affa6

Альтернативное решение 2: с использованием DAO:

Dim dao_dbE As dao.DBEngine
Dim dao_DB As dao.Database
dao_dbE = New dao.DBEngine
Dim sheetsNames As List(Of String) = New List(Of String)()
dao_DB = dao_dbE.OpenDatabase(completeFileName, False, True, "Excel 8.0;")
For i As Integer = 0 To dao_DB.TableDefs.Count - 1
    sheetsNames.Add(dao_DB.TableDefs(i).Name)
Next
0 голосов
/ 14 июня 2011

Как правильно @Heinzi, вам следует изучить другие свойства возвращаемых метаданных, это единственный способ. Скорее всего, диапазоны будут отличаться от листов некоторым значением свойства.

Обновление: Поскольку это решение не работает, и если файл в формате XSLX, я думаю, что самым быстрым и простым решением будет просто перейти к необработанному xml (помните, что XLSX - это просто ZIP) myFilename.xlsx/xl/workbook.xml, скажем, # ZipLib и получить все имена листов из узла <sheets>.

...