The document is still under construction!
Das Dokument beschreibt an Hand eines Beispiels, wie Produktrecherche und Platzhalter vollständig aus Excel-Dateien geladen werden können.
Zur Installation muß lediglich ein (kleiner) Datenordner geladen werden und die eine Verbindung von InDesign® zu diesem Ordner hergestellt werden:
Nachdem die Verbindung zum Datenordner hergestellt wurde, kann das Beispiel vollständig genutzt werden. Zum Laden der Produkte öffnen Sie die Palette Produktrecherche und wählen links oben die Methode Fianzdaten laden. Die Liste wird automatisch geladen.
Bitte beachten Sie:
Die Einträge der Liste können jetzt einfach per DragAndDrop oder mit Hilfe des Produktaufbaus in ein Dokument eingefügt werden.
Die Implementierung des Beispiels basiert auf 'gewöhnlichen' Platzhaltern. Das bedeutet, dass Sie das Änderungsmanagement praktischerweise dazu geschenkt bekommen:
Das Beispiel verwendet die Exceldatei Financial Sample.xlsx des Beispielordners. Wir definieren dafür den Alias-Namen EXCELFILE, der in allen Skripten und Aufrufen verwendet werden kann. Dazu kann die die Palette Einstellungen verwendet werden. Alternativ können Sie die Einstellung auch in der Datei datafiles.xml des Datenordnes machen. Da die Datei im aktuellen Datenordner liegt, können wir als Pfad den global definierten Alias $COMETDATA verwenden. Hier die Defintion:
<datafile> <id>8</id> <path>$COMETDATA/Financial Sample.xlsx</path> <alias>EXCELFILE</alias> <description></description> <enabled>1</enabled> </datafile>
Mit excelquery verfügen die priint:comet Plugins zwar über eine einfache und hinreichend mächtige Sprache zur Ermittlung des Inhaltes von Zellen von Excel-Tabellen. Zur Abfrage von Zellbereichen ist die Sprache aber nicht geeignet. Die Produktliste muß also über ein Skript geladen werden.
Wir definieren als erstes ein Findstatement mit der Skriptdefintion zum Laden der Produktliste. Die Anweisung wird das Skript (die Aktion) 1000 ausführen, und den Namen kLoadProducts bekommen. (Für kLoadProducts wurde mit Hilfe der Palette Übersetzungen für Deutsch der Name Fianzdaten laden definiert.) Hier die Definition der Anweisung in der Datei findstatements.xml:
<findstatement> <id>22</id> <description>Laden von Produkten über ein cScript</description> <classid>3</classid> <userid>0</userid> <statement>" " #1000</statement> <label>kLoadProducts</label> <sequencenr>60</sequencenr> <hasstringids>1</hasstringids> <candelete>0</candelete> <label1>-</label1> <label2>-</label2> <label3>-</label3> <label4>-</label4> <value1></value1> <value2></value2> <value3></value3> <value4></value4> <sourcefiles> <sourcefile> <alias></alias> <path></path> </sourcefile> </sourcefiles> </findstatement>
Die Aktion 1000 zum Laden der Produktliste sieht auf den ersten Blick etwas kompliziert aus. Lassen Sie sich davon nicht abschrecken! Die Funktion läuft durch die erste Spalte der Excel-Tabelle (Index 0) und sammelt alle unterschiedlichen Einträge. Für jede dieser Zellen wird ein Eintrag in dier Ergebnisliste gProducts eingefügt. Als IDs der Ergebnisse werden die 1-basierte Zeile und Spalte (hier 1) der jeweils ersten gefundenen Einträge verwendet.
Jeder der gefundenen Einträge soll ausserdem selbst wieder Untereinträge laden können - die Ergebnisse bekommen dafür die kSubstatement-ID 10002, die im Absatz Panelstatement erklärt wird.
#pragma plain #include "internal/types.h" #include "internal/text.h" #include "internal/products.h" int pp (int id1, int id2, int id3, String sid, String r1, String r2, int pid, int subid) { Product p = product::alloc (kGlobalStack); product::set (p, kID, id1); product::set (p, kID2, id2); product::set (p, kID3, id3); product::set (p, kStringID, sid); product::set (p, kLevel, 23210); // icon id product::set (p, kRow1, r1); product::set (p, kRow2, r2); product::set (p, kPageitemid, pid); product::set (p, kSubstatement, subid); productlist::append (gProducts, p, 1); return 0; } int main () { ExcelBook ebook; String sv = string::alloc (); String empty = string::alloc (); StringList sl = stringlist::alloc (); // Need this for uniqueness int i; ebook = excel::open ("$EXCELFILE"); if (!ebook) { showmessage ("Cannot open Excel file"); return 0; } for (i = 1; i< excel::last_row (ebook, ""); i++) { excel::read (ebook, "", i, 0, kString, sv, 0, kExportPlain); if (stringlist::get_pos (sl, sv) < 0) { stringlist::append (sl, sv); pp (i+1, 1, 0, empty, sv, empty, 313, 10002); } } excel::close (ebook); return 0; }
Anweisungen zum Laden von Untereinträgen der Produktrecherche werden als Panelstatements definiert. In Aktion 1000 haben wir die ID 10002 festgelegt. Das Skript sucht alle Zeilen der Excel-Tabelle, deren Spalten bi szur aktuellen Schachtlungstiefe gleich sind. Bei der vierten Ebene werden keine weiteren Unterelemente mehr geladen. Als IDs der Ergebnisse werden wie in Aktion 1000 die 1-basierte Zeile und Spalte (die sich pro Ebene um 1 erhöht) der jeweils ersten gefundenen Einträge verwendet.
Das Skript ist im Wesentlichen identisch mit Aktion 1000 zum Laden der obersten Produktebene mit dem Unterschied, dass auch weiter links liegende Spalten gleich sein müssen. Hier die Defintion des Elementes statement des Panelstatements 10002 aus panelstatements.xml :
#pragma plain #include "internal/types.h" #include "internal/text.h" #include "internal/products.h" int pp (int id1, int id2, int id3, String sid, String r1, String r2, int pid, int subid, int iconid) { Product p = product::alloc (kGlobalStack); product::set (p, kID, id1); product::set (p, kID2, id2); product::set (p, kID3, id3); product::set (p, kStringID, sid); product::set (p, kLevel, iconid); // icon id product::set (p, kRow1, r1); product::set (p, kRow2, r2); product::set (p, kPageitemid, pid); product::set (p, kSubstatement, subid); productlist::append (gProducts, p, 1); return 0; } int main () { ExcelBook ebook; String pre[100]; String sv = string::alloc (); String empty = string::alloc (); StringList sl = stringlist::alloc (); // Need this for uniquness int i, j, okay; ebook = excel::open ("$EXCELFILE"); if (!ebook) { showmessage ("Cannot open Excel file"); return 0; } // Load values of previous cells in same row (gRecordID - 1) // for (i = 0; i < gRecordID2; i++) { pre[i] = string::alloc (); excel::read (ebook, "", gRecordID - 1, i, kString, pre[i], 0, kExportPlain); } for (i = 1; i < excel::last_row (ebook, ""); i++) { // Check if we are in a correct row. All previous columns // must match the pre-values // okay = true; for (j = 0; j < gRecordID2; j++) { excel::read (ebook, "", i, j, kString, sv, 0, kExportPlain); if (string::compare (sv, pre[j]) != 0) { okay = false; break; } } if (okay) { excel::read (ebook, "", i, gRecordID2, kString, sv, 0, kExportPlain); // gRecordID2 is the row we are looking for now if (stringlist::get_pos (sl, sv) < 0) { stringlist::append (sl, sv); if (gLevel == 0) pp (i+1, gRecordID2+1, 0, empty, sv, empty, 0, 10002, 2010); else if (gLevel == 1) pp (i+1, gRecordID2+1, 0, empty, sv, empty, 0, 10002, 2043); else if (gLevel == 2) pp (i+1, gRecordID2+1, 0, empty, sv, empty, 0, 0, 2059); } } } // Clean up // for (i = 0; i < gLevel + 1; i++) { string::release (pre[i]); } excel::close (ebook); return 0; }
Damit ist die Produktrecherche fertig konfiguriert. Zur Vervollständigung können Sie jetzt gerne noch eine Suche implementieren. Beachten Sie dabei, dass die Suche nur auf Objekte der obersten Ebene angewendet wird. Sie müssen also lediglich die Aktion 1000 anpassen und die im Findstatement 8 die Suchfelder konfigurieren.
Textinhalte von Excel-Zellen können sehr einfach mit excelquery geladen werden. Im wesentlichen werden die Excel-Datei und die Zell-Indexe benötigt. Als Datei verwenden wir wieder den in Excel-Datei definierten Datei-Alias. Die Zelle selbst wird von den IDs der Produkte festgelegt: In <ID> steht die 1-basierte Zeile, in <ID2> die 1-basierte Spalte. Daraus ergibt sich die folgende Anweisung, die wir in der Aktion 2520 abgelegt haben.
"$EXCELFILE" select "%s" with plain <ID>, <ID2> onebased
Passend zur ID der Aktion 2520 haben wir dazu einen Text-Platzhalter mit der gleichen ID definiert, der die Aktion 2520 als Laden-Skript verwendet. Da Aktion 2520 einen einfachen (oder auch formatierten) String als Ergebnis liefert, kann als Sync-Skript der Standard -1 verwendet werden (und alle Sync-Vergleiche werden automatisch von den Plugins erledigt). Hier die Definition des Platzhalters aus placeholder.xml :
Es ist nicht zwingend, dass ID und Laden-ID eines Platzhalters gleich sind (sorgt aber für eine bessere Übersicht).
<placeholder> <id>2520</id> <name>Excel-Content</name> <description></description> <type>text</type> <domain></domain> <domainid></domainid> <class>3</class> <load>2520</load> <sync>-1</sync> <store>0</store> <lov>0</lov> <color name=""> <id>9</id> </color> <style></style> <styleid>0</styleid> <syncstateinvisible>0</syncstateinvisible> <loadconstraint>0</loadconstraint> <active>1</active> </placeholder>
Wenn Sie die Platzhalter-Palette öffnen und laden sollten Sie folgende Einträge sehen:
damit können wir jetzt schon Folgendes tun: