26. 7. 2021, Vladimír Klaus, navštíveno 121x

Delphi
MS Excel
MS Office

A je tu další článek o tom, jak přistupovat k MS Excel souborům jako k databázi. Před časem jsem sice psal článek o přístupu k Excel souborům jako k databázi, ale nyní to z nějakého důvodu nefunguje - končí to chybou "Zkušební připojení se nezdařilo z důvodu chyby při inicializaci zprostředkovatele. Neznámý formát databáze / Unrecognized database format".

Databázové napojení na MS Excel přes ADO v Delphi a ASP.NET / C#, obr. 1

Delphi

Buď se jedná o chybu či specifikum novějšího driveru nebo nikoliv. To je ale jedno. Zkrátka se to musí nyní řešit jinak. Po nějakém tom pátrání jsem narazil na doporučení přidat:

Extended Properties="Excel 8.0"

Databázové napojení na MS Excel přes ADO v Delphi a ASP.NET / C#, obr. 2

A je pravdou, že toto zabere a jsem korektně připojen k MS Excel souboru. Lehce zmatečné je ovšem vygenerovaný ConnectionString. Vygenerují se tam všechny parametry, ale hlavně zmizí zadané Extended Properties

Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=d:\Pokusy\Delphi\ExcelNapojeni\Test.xlsx;Mode=Share Deny None;Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=37;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet OLEDB:Bypass UserInfo Validation=False;

Naštěsí se ukázalo, že vlastně vše řeší pouze Jet OLEDB:Engine Type=37 a vše ostatní můžete prozatím odstranit. Pokud tedy za běhu nastavíte ConnectionString na toto, bude to fungovat, i když vnitřně se tam opět vygenerují i ty další parametry. A tato informace o Engine Type je vhodná i pro další hledání na webu, protože to je nakonec opravdu ta klíčová informace. 😉

Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=d:\Pokusy\Delphi\ExcelNapojeni\Test.xlsx;Mode=Share Deny None;Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=37

Pokud máte ADOConnection.Active=true, tak při pokusu o otevření XLSX souboru v Excelu budete upozorněni, že to můžete jen v režimu "jen pro čtení". Stejně tak občas dochází k nějaké ztrátě připojení... A někdy zase naopak je Excel schopen automaticky aktualizovat data, která jsem upravili v mřížce aplikace Delphi. Asi by to chtělo další a mnohem hlubší průzkum.

Ale když vše funguje, a máte to dobře nastavené, uvidíte data z Excelu jako normální tabulku (TADOTable) ve vestavěném DBGridu.

Databázové napojení na MS Excel přes ADO v Delphi a ASP.NET / C#, obr. 3

Zcela stranou zatím nechávám poznatek, že mezi drivery je i Microsoft Office 16.0 Access Database Engine OLE DB Provider, nicméně pro potřeby tohoto použití tomu vůbec nepomáhá a nefunguje.

Databázové napojení na MS Excel přes ADO v Delphi a ASP.NET / C#, obr. 4

Jak toto funguje v ASP.NET / C#

Zde je příklad, který již pár let používám v jednom projektu a zatím vše funguje ke spokojenosti všech. Je vidět, že se opět jedná o jakési nastavení Extended Properites, byť v tomto případě na Excel 12.0. Ale je třeba poznamenat, že ASP.NET aplikace běží na Windows Serveru 2012, zřejmě i se staršími knihovnami a ovladači, takže asi není překvapení, že to funguje a není třeba (zatím) cokoliv dalšího měnit.

public static DataSet ExcelToDS(string Path, string sheetname) {
	//string xlsConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path + ";
	//	Extended Properties='Excel 8.0;HDR=NO;IMEX=1'";
	string xlsxConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path + ";
		Extended Properties='Excel 12.0;HDR=NO;IMEX=1'";
	using (OleDbConnection conn = new OleDbConnection(xlsxConn)) {
	    conn.Open();
	    string strExcel = "select * from [" + sheetname + "$]";
	    OleDbDataAdapter oledbda = new OleDbDataAdapter(strExcel, xlsxConn);
	    DataSet ds = new DataSet();
	    oledbda.Fill(ds, sheetname);
	    conn.Close();
	    return ds;
	}
}

Zdroj: