Častým požadavkem na programátory ve VFP je komunikace s Excelem. Uživatelé Excel znají a umí v něm data dále zpracovat, takže je mnohdy výhodné přenést data z VFP do Excelu, předzpracovat je a pak už nechat vše na uživateli. Pojďme si tedy ukázat jednoduchý příklad komunikace s Excelem.
Co chceme dosáhnout
Naším cílem bude přenést data z VFP do Excelu a zobrazit uživateli souhrn dat – pro lepší vysvětlení si ukážeme screenshot (z Office 2007, ale funguje to samozřejmě i ve starších verzích):
Spustíme Excel
Nejdříve musíme samozřejmě nastartovat Excel. Dovolím si jen poznamenat, že co verze Excelu, to jiné chování, pokud jde o využití již běžících instancí Excelu, takže my zde použijeme pouze ten nejjednodušší způsob (a navíc v celém programu neprovádím žádné kontroly na chyby apod. – to už si budete muset doplnit).
LOCAL oExcel AS Excel.Application
oExcel = CREATEOBJECT("Excel.Application")
* chceme pouze 1 sheet v novém worksheetu
oExcel.SheetsInNewWorkbook = 1
oExcel.Workbooks.Add() && vytváříme nový sheet
Zde stojí za zmínku pouze příkaz LOCAL, který nám zajistí fungování Intellisense v programu.
Nastavíme vlastnosti Excelu
Určitě budeme chtít, aby byl Excel maximalizovaný přes celou obrazovku. My ale dosáhneme ještě navíc toho, že uživatel Excel uvidí (.Visible = .T.), ale nebude moci nic měnit (.Interactive = .F.)! To je důležité proto, že by jinak mohl v průběhu výpočtu mazat data atd. Navíc ještě zakážeme zobrazení všech dialogů (.DisplayAlerts = .F.), takže by se Excel ani neptal, jestli skutečně chceme skončit bez uložení souboru,… Tohle jsou skutečně důležitá a užitečná nastavení.
oExcel.WindowState = -4137 && xlMaximized
oExcel.Interactive = .F.
oExcel.DisplayAlerts = .F.
oExcel.Visible = .T.
Vytvoříme testovací data
Vzhledem k tomu, že potřebuji trochu složitější data, použiji SELECT na data z Tastrade:
OPEN DATABASE _samples+"tastrade\data\tastrade"
SELECT ;
Customer.company_name AS Firma, ;
Orders.order_id AS Objednávka, ;
SUM(oli.unit_price*oli.quantity) AS Částka,;
AVG(oli.unit_price) AS PrůměrnáCena ;
FROM Customer ;
INNER JOIN Orders ON Customer.customer_id = Orders.customer_id ;
INNER JOIN Order_line_items AS oli ON Orders.order_id = oli.order_id;
GROUP BY Customer.company_name, Orders.order_id ;
ORDER BY Customer.company_name, Orders.order_id ;
INTO CURSOR q
Přeneseme data do clipboardu
V mnoha případech nejrychlejší a nejúčinnější způsob přenosu dat je pomocí clipboardu. Uložíme proto data z cursoru do clipboardu pomocí _VFP.DataToClip – to je skutečně rychlé a jednoduché:
_VFP.DATATOCLIP(,,3)
Teď zavřeme databázi. Navíc ještě potřebujeme odstranit mezery, abychom zbytečně do Excelu nepřenášeli 50 znaků, kde bude 40 mezer.
CLOSE DATABASES
DO WHILE SPACE(5)$_CLIPTEXT
_CLIPTEXT = STRTRAN(_CLIPTEXT, SPACE(5), "")
ENDDO
DO WHILE " "+CHR(9)$_CLIPTEXT
_CLIPTEXT = STRTRAN(_CLIPTEXT, " "+CHR(9), CHR(9))
ENDDO
Data z clipboardu do Excelu
Jelikož máme data v clipboardu, přeneseme je do Excelu velmi jednoduše:
oExcel.ActiveSheet.Range("A1").Select()
oExcel.Selection.PasteSpecial
Rychlé zformátování
Na vzhledu záleží :-), takže provedeme rychlé zformátování:
oExcel.Selection.AutoFormat(17, .t.,.t.,.t.,.t.,.t.,.f.)
oExcel.Cells.EntireColumn.AutoFit
Vytvoření souhrnů dat
Nyní to bude trochu složitější, ale to je vlastně to, co Vám chci hlavně ukázat :-). Jde o použití funkce COMARRAY, pomocí které specifikujeme, jak budeme nějakou referenci (v našem případě referenci na oblast zkopírovaných dat) předávat COM serveru. Bez tohoto nastavení se Vám nepodaří něco takového vůbec dosáhnout!
* vybereme, co budeme sčítat
oSelected = oExcel.Selection
* Ujistíme se, že pole (array) se předává referencí a s indexováním od 1
COMARRAY(oSelected, 11)
* Chceme sčítat sloupce 3 a 4
LOCAL ARRAY laArray(2)
laArray(1) = 3
laArray(2) = 4
#DEFINE xlSum -4157
#DEFINE xlSummaryBelow 1
oSelected.Subtotal(1, xlSum, @laArray, .T., .F., xlSummaryBelow)
oSelected = NULL
Hotovo
Data jsou pro uživatele připravena a uživatel může začít pracovat. Je mnoho způsobů, jak ukončit práci, my zvolíme ne úplně ideální :-) – ukončíme Excel a ten se tedy automaticky uživatele zeptá, kam chce tento worksheet uložit. Samozřejmě musíme nejprve povolit komunikaci s uživatelem:
oExcel.Interactive = .T.
oExcel.DisplayAlerts = .T.
oExcel.Quit()
oExcel = NULL
Zde si můžete stáhnout kód k tomuto článku.
A to je vše. Mějte se krásně.
Milan Kosina