Excel „Tabela zewnętrzna nie ma oczekiwanego formatu”.

162

Próbuję odczytać plik Excel (xlsx) przy użyciu kodu pokazanego poniżej. Otrzymuję komunikat „Tabela zewnętrzna nie jest w oczekiwanym formacie”. błąd, chyba że mam już otwarty plik w programie Excel. Innymi słowy, muszę najpierw otworzyć plik w programie Excel, zanim będę mógł czytać z mojego programu C #. Plik xlsx znajduje się w udziale w naszej sieci. Jak mogę odczytać plik bez konieczności jego wcześniejszego otwierania? Dzięki

string sql = "SELECT * FROM [Sheet1$]";
string excelConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathname + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\"";

using (OleDbDataAdapter adaptor = new OleDbDataAdapter(sql, excelConnection)) {
    DataSet ds = new DataSet();
    adaptor.Fill(ds);
}
Sisiutl
źródło
FWIW Otrzymałem to na arkuszu Excela, próbując go otworzyć, korzystałem z aktualnego ACE i sugerowanych rozszerzonych właściwości. Kiedy ręcznie otworzyłem plik, na górze pojawił się monit, aby włączyć edycję, muszę uporządkować sposób automagicznego odwrócenia tego bitu, ale jeśli to otrzymujesz, być może wystarczy otworzyć plik, a następnie włączyć edycję . Mogę spojrzeć, czy mogę otworzyć plik tylko do odczytu, widziałem coś na ten temat bardzo daleko w tym wątku.
Jeff Patton

Odpowiedzi:

246

„Tabela zewnętrzna nie ma oczekiwanego formatu”. zwykle występuje podczas próby użycia pliku Excel 2007 z parametrami połączenia, które używają: Microsoft.Jet.OLEDB.4.0 i Extended Properties = Excel 8.0

Wydaje się, że użycie następujących parametrów połączenia rozwiązuje większość problemów.

public static string path = @"C:\src\RedirectApplication\RedirectApplication\301s.xlsx";
public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
FAtBalloon
źródło
10
Jak na ironię, otrzymałem ten błąd z cudzej aplikacji (Scribe), ale wyjaśnienie nadal rozwiązało problem: „Zapisz jako” Excel 97-2003 i błąd naprawiony.
Jeff Davis
4
Rozszerzenie .xlsx czy .xls?
FAtBalloon
3
być może będziesz musiał najpierw zainstalować to: microsoft.com/en-us/download/confirmation.aspx?id=23734
rovsen,
11
to może być niewiarygodne, ale po prostu zmieniam nazwę arkusza na małe litery i używam arkusza1 $
Smith
3
Używam LinqToExcel i aby LinqToExcel używał tego ciągu zapytania, muszę zmienić nazwę pliku na xlsx. Arkusz kalkulacyjny, o którym mowa, tak naprawdę jest arkuszem kalkulacyjnym programu Excel 97, ale dostawca ODBC nie wydaje się tym przejmować. Po nakłonieniu LinqToExcel do użycia prawidłowego ciągu zapytania, dostawca najwyraźniej określa sposób odczytu pliku niezależnie od rozszerzenia pliku. Wygodna luka w moim przypadku.
Tim Coker
26

Dzięki za ten kod :) Naprawdę to doceniam. Pracuje dla mnie.

public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

Więc jeśli masz wersję diff pliku Excel, pobierz nazwę pliku, jeśli jego rozszerzenie to .xlsx , użyj tego:

Private Const connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

a jeśli to .xls , użyj:

Private Const connstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" + path + ";Extended Properties=""Excel 8.0;HDR=YES;"""
Trex
źródło
5
FYI: Spowoduje to zgłoszenie OleDbException, jeśli spróbujesz otworzyć .xlsplik na komputerze, na którym nie jest zainstalowany Jet OleDb.
jp2code
@Trex Czy na pewno ostatnia linia kodu jest poprawna? Czy możesz ponownie sprawdzić to w jakimś edytorze?
Jogi
15

(Mam zbyt niską reputację, aby komentować, ale to jest komentarz do wpisu JoshCaby, używającego silnika Ace zamiast Jet for Excel 2007)

Jeśli nie masz zainstalowanego / zarejestrowanego Ace na swoim komputerze, możesz go pobrać pod adresem : https://www.microsoft.com/en-US/download/details.aspx?id=13255

Dotyczy to również programu Excel 2010.

cederlof
źródło
Mam zainstalowany silnik ACE, ale muszę wiedzieć, jakie odniesienie powinienem uwzględnić w moim projekcie, aby mój instalator uwzględnił go. Nie na wszystkich komputerach, na których jest zainstalowana moja aplikacja, musi być zainstalowany pakiet MS Office.
jp2code
1
Łącze wyświetla teraz komunikat o błędzie - We're sorry, this download is no longer available.
RBT
9

Po prostu dodaj moją walizkę. Mój plik xls został utworzony przez funkcję eksportu danych ze strony internetowej, rozszerzenie pliku to xls, można go normalnie otworzyć w programie MS Excel 2003. Ale zarówno Microsoft.Jet.OLEDB.4.0, jak i Microsoft.ACE.OLEDB.12.0 otrzymały „ Wyjątek: tabela zewnętrzna nie ma oczekiwanego formatu.

Wreszcie problem polega na tym, jak powiedział wyjątek, „nie jest w oczekiwanym formacie”. Chociaż jego nazwa rozszerzenia to xls, ale kiedy otwieram go w edytorze tekstu, jest to właściwie dobrze sformatowany plik HTML, wszystkie dane znajdują się w <table>, każdy <tr> jest wierszem, a każdy <td> jest komórka. Wtedy myślę, że mogę to przeanalizować w sposób html.

Joseph Ding
źródło
Tak też było w moim przypadku, jednak mój plik był w rzeczywistości XML. Mimo wszystko byłoby miło wiedzieć, jak zaimportować go za pomocą OBDC, ale nie sądzę, aby był obsługiwany.
David Rogers
@DavidRogers, kiedykolwiek widziałem coś takiego jak sterownik XML ODBC, ale nigdy nie był używany, zajrzyj na cdata.com/drivers/xml/odbc .
Joseph Ding
Ten sam przypadek, wydaje mi się, że magia zaczęła się od otwierania pliku za pomocą notatnika, w rzeczywistości głosuję w górę na twoją odpowiedź, ponieważ do tej pory nie przewinąłem w dół, aby zobaczyć twój post (a teraz już otworzyłem plik / przeanalizowałem go z pakietem Html Agility ...), ale Twoja odpowiedź zasługuje na to, by znaleźć się na szczycie, z czystej logiki: OTWÓRZ PLIK NAJPIERW! i zobacz, czy ma w sobie jakiś plik w stylu Excela!
Gabriel G
Jeśli jest to plik html, po prostu zastosuj rozszerzone właściwości w następujący sposób:Extended Properties=""HTML Import;HDR=No;IMEX=1
Nepaluz
4

Miałem ten sam problem. które rozwiązano, wykonując następujące czynności:

1.) Kliknij Plik

2.) Wybierz „zapisz jako”

3.) Kliknij listę rozwijaną (Zapisz jako typ)

wprowadź opis obrazu tutaj

4.) Wybierz skoroszyt programu Excel 97-2003

wprowadź opis obrazu tutaj

5.) Kliknij przycisk Zapisz

wprowadź opis obrazu tutaj

Kamran
źródło
1
Gwizd! Przywracanie przestarzałego formatu pliku nie powinno być nawet brane pod uwagę. W chwili udzielenia tej odpowiedzi format 97-2003 miał 16 lat i 12 lat. Rozumiem kilka lat, ale ponad dekada przestarzały nie powinien sugerować profesjonalnemu programistowi, że format pliku musi być starszy.
Lemiarty
3

Miałem ten sam problem (używając ACE.OLEDB) i tym, co go dla mnie rozwiązało, był ten link:

http://support.microsoft.com/kb/2459087

Istotą tego jest to, że zainstalowanie wielu wersji pakietu Office i różnych pakietów SDK, zestawów itp. Doprowadziło do odwołania ACEOleDB.dll w rejestrze wskazującego na folder OFFICE12 zamiast OFFICE14 w

C: \ Program Files \ Common Files \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

Z linku:

Alternatywnie możesz zmodyfikować klucz rejestru, zmieniając ścieżkę dll, aby była zgodna z wersją programu Access.

Access 2007 powinien używać OFFICE12, Access 2010 - OFFICE14 i Access 2013 - OFFICE15

(OS: 64-bitowy Office: 64-bitowy) lub (OS: 32-bitowy Office: 32-bitowy)

Klucz: HKCR \ CLSID {3BE786A0-0366-4F5C-9434-25CF162E475E} \ InprocServer32 \

Nazwa wartości: (domyślna)

Dane wartości: C: \ Program Files \ Common Files \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

(System operacyjny: 64-bitowy Office: 32-bitowy)

Klucz: HKCR \ Wow6432Node \ CLSID {3BE786A0-0366-4F5C-9434-25CF162E475E} \ InprocServer32 \

Nazwa wartości: (domyślna)

Dane wartości: C: \ Program Files (x86) \ Common Files \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

jordanhill123
źródło
Okazało się, że łatwiej jest po prostu przejść do Programy i funkcje oraz Napraw ACE. (Dla mnie ACE nazywa się Microsoft Access Runtime 2016). Zakładam, że miałem ten wariant problemu i że Naprawa po prostu zresetowała wszystkie klucze rejestru bez konieczności zawracania sobie głowy regedit ;-).
binki
2

Widziałem również ten błąd podczas próby użycia złożonych formuł INDIRECT () na importowanym arkuszu. Zauważyłem to, ponieważ była to jedyna różnica między dwoma skoroszytami, w których jeden importował, a drugi nie. Oba były plikami .XLSX 2007+ i zainstalowano silnik 12.0.

Potwierdziłem, że to problem przez:

  • Wykonywanie kopii pliku (nadal występował problem, więc nie była to różnica w zapisie)
  • Zaznaczanie wszystkich komórek w arkuszu za pomocą formuł pośrednich
  • Wklejanie tylko jako wartości

i błąd zniknął.

John M. Black
źródło
2

Otrzymywałem błędy podczas czytania skoroszytu XLSX przez strony trzecie i Oledb. Wygląda na to, że problem dotyczy ukrytego arkusza roboczego, który powoduje błąd. Odkrywanie arkusza umożliwiło zaimportowanie skoroszytu.

John M.
źródło
2

Jeśli plik jest tylko do odczytu, po prostu go usuń i powinien znów działać.

Tehscript
źródło
1

Wpadłem na ten sam problem i znalazłem ten wątek. Żadna z powyższych sugestii nie pomogła, z wyjątkiem komentarza @ Smitha do zaakceptowanej odpowiedzi 17 kwietnia 2013 roku.

Tło mojego problemu jest wystarczająco zbliżone do @ zhiyazw - w zasadzie próba ustawienia wyeksportowanego pliku Excela (w moim przypadku SSRS) jako źródła danych w pakiecie dtsx. Wszystko, co zrobiłem, po kilku majstrach, to zmiana nazwy arkusza. Nie musi to być małe, jak zasugerował @Smith.

Przypuszczam, że ACE OLEDB oczekuje, że plik Excela będzie miał określoną strukturę XML, ale usługi Reporting Services w jakiś sposób nie są tego świadome.

kerwei
źródło
Natknąłem się na to samo wydanie tabeli nie w oczekiwanym formacie. Sprawdziłem, że mój skoroszyt nie zawiera ukrytych arkuszy. Rzeczywista nazwa arkusza roboczego w skoroszycie jest pisana wielkimi literami, ale w kodzie C # do analizowania pliku dodałem .ToLower () dla nazwy karty, a teraz mogę ponownie przeanalizować plik Excela. DZIĘKUJĘ CI!
vvvv4d
1

Ten adres pliku programu Excel może mieć nieprawidłowe rozszerzenie. Możesz zmienić rozszerzenie z xls na xlsx lub odwrotnie i spróbować ponownie.

Mohammad Fathi MiMFa
źródło
0

plik może być zablokowany przez inny proces, musisz go skopiować, a następnie załadować zgodnie z tym poście

user3140982
źródło
0

Dodam tylko moje rozwiązanie tego problemu. Przesyłałem plik .xlsx na serwer sieciowy, a następnie czytałem z niego i masowo wstawiałem do SQL Server. Otrzymuję ten sam komunikat o błędzie, wypróbowano wszystkie sugerowane odpowiedzi, ale żadna nie działała. Ostatecznie zapisałem plik jako excel 97-2003 (.xls), który działał ... jedyny problem, jaki mam teraz, to fakt, że oryginalny plik miał ponad 110 000 wierszy.

Kieran Quinn
źródło
0

Jeśli nadal masz ten problem, sprawdź swoje uprawnienia, wypróbowałem wiele z tych sugestii, a moim konkretnym problemem było to, że plik, który chciałem przetworzyć, znajdował się pod kontrolą źródła, a wątek nie miał uprawnień, musiałem zmienić uprawnienia całego folderu i zaczęło działać (przetwarzałem tam wiele plików) ... Pasuje również do wielu sugestii, takich jak zmiana nazwy pliku lub sprawdzenie, czy plik nie jest loickowany przez inny proces.

Mam nadzieję, że Ci to pomoże.

Juan
źródło
0

Miałem ten problem i zmiana Extended Properties na HTML Import naprawił go zgodnie z tym postem Marcusa Mirisa:

strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & importedFilePathAndName _
         & ";Extended Properties=""HTML Import;HDR=No;IMEX=1"";"
majjam
źródło
0

Zamiast OleDb można użyć programu Excel Interop i otworzyć arkusz jako tylko do odczytu.

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbooks.open(v=office.15).aspx

Nelson
źródło
5
Współpraca między programem Excel nie jest zalecaną metodą pracy z programem Excel. Może powodować wiele problemów i dlatego nie powinien być zalecany.
MaxOvrdrv
Chociaż jest to stary post, zgadzam się z MaxOvrdrv, używanie interopu nie jest dobrym pomysłem i należy go unikać, jeśli nie ma innego powodu niż wymaga pełnej instalacji programu Excel na serwerze.
Lemiarty
Absolutnie nie powinieneś tego robić.
sovemp
0

ACE zastąpiło JET

Ace Obsługuje wszystkie poprzednie wersje pakietu Office

Ten kod działa dobrze!

        OleDbConnection MyConnection;
        DataSet DtSet;
        OleDbDataAdapter MyCommand;
        
        MyConnection = new System.Data.OleDb.OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\\Book.xlsx;Extended Properties=Excel 12.0;");
        MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
        DtSet = new System.Data.DataSet();
        
        MyCommand.Fill(DtSet);
        dataGridView1.DataSource = DtSet.Tables[0];
        MyConnection.Close();
Akshay Upadhyay
źródło
1
To nie. Problem może nadal występować, nie dowiedziałem się jeszcze dlaczego, skoro wszystkie moje pliki pochodzą z programu excel 2007, a część z nich działa, część nie.
Henrik
Czy masz źródło tego twierdzenia? Sam nie wiem, po prostu się zastanawiam. :-)
midoriha_senpai
0

Taka sytuacja może wystąpić, gdy skoroszyt jest chroniony hasłem. Istnieje kilka obejść, aby usunąć tę ochronę, ale większość przykładów, które znajdziesz w Internecie, jest nieaktualna. Tak czy inaczej, prostym rozwiązaniem jest ręczne wyłączenie ochrony skoroszytu, w przeciwnym razie użycie czegoś takiego jak OpenXML, aby programowo usunąć ochronę.

KthProg
źródło
0

Niedawno widziałem ten błąd w kontekście, który nie pasuje do żadnej z wcześniej wymienionych odpowiedzi. Okazało się, że był to konflikt z AutoVerem . Obejście: tymczasowo wyłącz AutoVer.

unbob
źródło
0

Niedawno miałem ten „System.Data.OleDb.OleDbException (0x80004005): zewnętrzna tabela nie jest w oczekiwanym formacie”. wystąpił błąd. Polegałem na programie Microsoft Access 2010 Runtime. Przed aktualizacją, która została automatycznie zainstalowana na moim serwerze 12 grudnia 2018 r., Mój kod C # działał poprawnie przy użyciu dostawcy Microsoft.ACE.OLEDB.12.0. Po zainstalowaniu aktualizacji z 12 grudnia 2018 r. Zacząłem otrzymywać komunikat „Zewnętrzna tabela nie jest w oczekiwanym formacie” w moim pliku dziennika.

Porzuciłem środowisko wykonawcze programu Microsoft Access 2010 i zainstalowałem środowisko wykonawcze programu Microsoft Access 2013, a mój kod C # zaczął ponownie działać bez wyjątku „System.Data.OleDb.OleDbException (0x80004005): tabela zewnętrzna nie jest w oczekiwanym formacie”. błędy.

Wersja 2013, która naprawiła ten błąd https://www.microsoft.com/en-us/download/confirmation.aspx?id=39358

Wersja 2010, która działała dla mnie przed aktualizacją, która została automatycznie zainstalowana na moim serwerze 12 grudnia. https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910

Również ten błąd wystąpił w zeszłym miesiącu w zautomatyzowanym procesie. Kod C # działał poprawnie, gdy uruchomiłem debugowanie. Okazało się, że konto usługi, na którym działa kod, również wymaga uprawnień do folderu C: \ Windows \ Temp.

vvvv4d
źródło
0

Mój zakres obejmuje pobranie szablonu i weryfikację szablonu, gdy jest wypełniony danymi.

1) Pobierz plik szablonu (.xlsx) z wierszem nagłówka. plik jest generowany przy użyciu openxml i działa doskonale.

2) Prześlij ten sam plik bez żadnych zmian w stosunku do stanu pobrania. Spowoduje to błąd połączenia i niepowodzenie (połączenie OLEDB jest używane do odczytu arkusza Excela).

Tutaj, jeśli dane są wypełnione, program działa zgodnie z oczekiwaniami.

Każdy, kto ma pomysł, że problem jest związany z plikiem, który tworzymy, jest w formacie xml formacie , jeśli go otworzymy i po prostu zapiszemy, przekonwertuj go do formatu Excel i działa dobrze.

Masz pomysł na pobranie programu Excel z preferowanym typem pliku?

Thomson Kattingal
źródło
nie powinieneś zadawać pytań w swoich odpowiedziach, jeśli potrzebujesz odpowiedzi na swoje pytanie, w razie potrzeby zadawaj je osobno.
Abhishek Garg
0

Pracując ze starszym kodem, natrafiłem na ten sam ogólny wyjątek. Bardzo trudno jest wyśledzić problem, więc pomyślałem, że dodam tutaj na wypadek, gdyby ktoś inny pomógł.

W moim przypadku nie było kod gdzie indziej w projekcie, który został otwarcie StreamReader plik Excel przed OleDbConnection spróbowało otworzyć plik (zostało to zrobione w klasie bazowej).

Zasadniczo musiałem Close()najpierw wywołać obiekt StreamReader, a następnie pomyślnie otworzyć połączenie OleDb. Nie miało to nic wspólnego z samym plikiem Excela ani z ciągiem znaków OleDbConnection (który jest oczywiście tym, na co patrzyłem jako pierwszy).

tbone
źródło