Mein Ziel ist: Ich habe ein Dokument mit einer Doppelseite oder Einzelseite (das kann von Dokument zu Dokument variieren) und mehreren Ebenen. In diesem Dokument sollen alle Elemente (Polygone) die mit 100 % Yellow gefüllt sind gelöscht werden.
Nur ist mir nicht klar wie ich diese Elemente auswählen könnte. Das Gelb ist zwar in den Farbfeldern definiert, hat aber keinen "richtigen" Namen sondern nur die Farbwerte als Namen.
ich habe mich geirrt, ich muss nur alle Polygone auswählen und löschen unabhängig von der Farbe.
Was ich noch wissen müsste ist wie ich an alle Polygone rankomme. Also alle Polygone auf allen Seiten und allen Ebenen. Ich habe zwar schon etwas Code aber der funktioniert schon von der Auswahl her nicht:
Bitte um kurze Antwort.
Danke LG faxinger
(Dieser Beitrag wurde von faxinger am 31. Mai 2019, 13:40 geändert)
vielen Dank für eure Antworten. Ich muss gestehen dass mir der Einzeiler bzw. das Kurzscript von Hans besser gefällt, da ich dabei auch navollziehen kann was genau passiert, was ich bei Werners Script leider nicht kann. Das ist für mich zu hoch. ;-)
Es ist zwar schön etwas Einblick in die Hohe Kunst des JS zu bekommen, aber Verständnis geht für mich vor.
Danke für eure Bemühungen.
@Hans: Die Variable runterzuzählen in der for-Schleife hat wahrscheinlich den Grund das Objekte gelöscht werden und somit die Anzahl der zu löschenenden Objekte bei jedem Durchgang kleiner wird, oder?
Wenn die Schleife durch den Array vorwärts läuft ...
... kommt eine Fehlermeldung, wenn mehr als ein Polygon vorhanden ist.
Angenommen, im Dokument sind drei Polygons: – Beim ersten Durchgang wird ein Polygon entfernt. Es verbleiben zwei. – Beim zweiten Durchgang wird eines davon entfernt. Es verbleibt eines. – Beim dritten Durchgang versucht das Script das dritte Polygon (von dreien) zu löschen. Aber das gelingt nicht, weil nur noch eines vorhanden ist.
Bitte ausprobieren!
***** Wenn die Schleife rückwärts läuft, muss als Startwert die Anzahl Objekte minus eins verwendet werden, weil das letzte Objekt mit "0" adressiert wird: – Durchgang 1: lösche Objekt 2; – Durchgang 2: lösche Objekt 1; – Durchgang 3: lösche Objekt 0;
Hallo Faxinger, wenn Du nach pageItems fahndest, bekommst Du pageItems zurück. Die Oberklasse gewissermaßen von "Rectangles", "Ovals", "Polygons" etc.pp.
Willst Du nun wissen, was ein bestimmtes pageItems nun eigentlich ist, kannst Du das beispielsweise so machen:
InDesign ist dann gezwungen genau nachzusehen, um was es sich handelt. Also haben wir's mit einem Rechteck, Polygon etc.pp. zu tun.
und weil das nicht nur für PageItems gilt, sondern auch für eine Reihe von anderen Objekten (z. B. Colors), verwende ich meine Funktion InnerConstructorName, die, wenn immer möglich, einen ConstuctorName zurückgibt.
So, und jetzt machen wir mal 'was wirklich Lustiges:
Gell, da staunt ihr.
InDesign behauptet nach der Aktion mit convertShape() immer noch, es handelt sich um ein Rechteck. Optisch wird das allerdings keinesfalls unterstützt. Die Seite zeigt einen Kreis!
Werners Funktion hilft dagegen leider auch nicht. Die arbeitet ja auch mit getElements()[0]. Ist aber nicht Werners Schuld. Möglicherweise beruht das Problem auf einem Bug in der Scripting-Engine. ***** Mit herzlichem Gruß, Uwe Laubender
InDesign behauptet fälschicherweise selbst nach Speichern und Wiederöffnen der Datei, es läge ein Rechteck vor. Obwohl doch jeder sehen kann, dass es sich bei pageItems[0] um einen Kreis handelt.
Diese Faxen hören auch dann nicht auf, wenn wir die Datei nach IDML exportieren und mit der IDML-Datei weiterarbeiten. ***** Mit herzlichem Gruß, Uwe Laubender
Es werden tatsächlich nicht alle Polygone gelöscht.
Die Ursache ist, dass der Inhalt der Polygone ja auch ein Textframe oder ein Grafikrahmen sein kann in Polygonform.
Ich glaube es muss ein neuer Ansatz her: Anbei mal ein Beispiel als idml.
Die Ausgangssituation: Ich habe eine Doppelseite oder Einselseite (von Fall zu Fall unterschiedlich). Darauf befinden sich Polygone auf verschiedenen Ebenen.
(Im Original habe ich natürlich noch andere Elemente auf der Seite.)
Ziel: Die Polygone sollen gelöscht werden.
Das Problem dabei: meine "Polygone" könnten ja eigentlich Textrahmen oder Grafikrahmen oder Rahmen mit nicht zugewiesenem Inhalt mit vielen Pfadpunkten sein.
Ich ging davon aus dass man mit PageItems.polygons alle Rahmen mit vielen Pfadpunkten erwischt.
Aber da liegt der Fehler.
Ich glaube man muss die Auswahl über das Kriterium der Pfadpunkte (Anzahl größer als z.B 10 Punkte) treffen unabhängig vom jeweiligen Inhalt.
Vielleicht gibt es auch noch eine andere Möglichkeit.
Du musst einfach innerhalb der Schleife mit einer oder mehrer If-Bedingungen die gewünschten PageItems herausfiltern und dann löschen.
Bitte habe Verständnis dafür, dass ich Dir gerne bei exakt definierten Teilproblemen Lösungsvorschläge mache, aber Dir kostenlos keine Komplettlösungen liefere.
So, wie Du vermutlich von Deiner Arbeit lebst, lebe ich von der Programmierung von Skripten.
Ich denke, wir haben Dir hier reichlich Tipps für Deine Problemstellung gegeben.
Du hast richtig erkannt, dass nur durch die Prüfung der Pfadpunkte alle Polygons erwischt werden. Allerdings muss der Grenzwert tiefer als die genannten 10 angesetzt werden. Sonst wird ein normales Fünfeck nicht erfasst.
Wenn Gruppierungen vorkommen, müssen diese zuerst aufgehoben werden. Es sei denn man verwende allPageItems für den Array der Objekte, statt pageItems.
Weil mit 'allPageItems' nebst den Rahmen einer Gruppe auch eventuelle Bilder und die Gruppe selbst aufgelistet werden, muss die Pfadpunkte-Prüfung in einen try-Wickel gepackt werden. Sonst kommt eine Fehlermeldung, sobald die Gruppe an der Reihe ist.
Doch eine Pfadpunkte-Prüfung ist nicht so einfach zusammenzusetzen. Deshalb folgende kleine Hilfestellung:
Damit werden sowohl geschlossene als auch offene Pfade erfasst. Sollten letztere erhalten bleiben, müsste eine Prüfung eingefügt werden.
daran hatte ich (ganz kurz :-) gedacht. Aber auch, dass ... 1. Solche Objekte sehr selten sind; 2. der gute Faxinger ein entsprechendes Versagen schon melden wird.
Hallo zusammen, ich weiss ja nicht, ob ihr mal in die von faxinger angehängte IDML-Datei reingeschaut habt, aber dort sind vier Objekte vertreten. Mit jeweils 114 oder 77 Pfaden pro Objekt.
nun ist der Fall eingetreten, dass sich manche Polygone nicht per Skript löschen lassen.
Siehe anhängliche idml:
Alle roten Polygone werden nicht gelöscht nur das blaue Polygon wird gelöscht. Meine Fragen: wieso und warum? Hier nochmal das Skript das hier zur Anwendung kommt:
Wenn ich die pathPoints.length von 5 auf 2 vermindere werden alle Objekte gelöscht. Aber leider auch Objekte die nicht gelöscht werden sollen.
Es erschließt sich mir leider nicht wieso die Objekte die eigentlich wesentlich mehr als 5 Pfadpunkte haben erst bei einer Abfrage ob sie mehr als 2 Pfadpunkte haben gelöscht werden.
Der geniale if-Test von "path" vermeidet eine Fehlermeldung, wenn das aktuelle Objekt eine Gruppe oder ein Bild ist.
Die 'alert(e.message)' meldet eigentlich nur gesperrte Objekte, weil sich diese nicht entfernen lassen. Doch sie könnten vorher entsperrt werden. Mit oder ohne vorhergehende Gesperrt-Prüfung. Das wird funktionieren. Aber nur wenn sich solche Objekte nicht in einer Gruppe befinden.
***** Deshalb ein neuer Ansatz: Vorgängig die Ebenen entsperren und alle Gruppen auflösen. Somit wäre 'allPageItems' nicht mehr zwingend. Aber mit 'pageItems' erreicht man verankerte Rahmen nicht.
Den try-Wickel braucht es eigentlich nicht mehr. Aber vielleicht ist in den zu behandelnden Dokumenten nichts gesperrt und die vorsorglichen Zeilen zum Entsperren der Ebenen und Entgruppieren werden entfernt. Aber dann ist doch irgendwo etwas gesperrt.
Es kann auch sein, dass gewisse Objekte nicht entfernt werden dürfen. Dann kann man sie sperren und die Zeilen 36 bis 40 des Scripts entfernen. Oder den Test benutzen und nur löschen, wenn das Objekt nicht gesperrt ist.
Noch nicht gelöst ist das von Thomas Richard gemeldete Problem mit in Kurven gewandelten Schriften. Aber vielleicht kommen solche gar nicht vor. Zudem tritt es nur auf, wenn diese Objekte nicht in einem Textrahmen stecken.
Meiner Meinung nach sollte immer eine Fehlerbehandlung vorgenommen werden, damit man überhaupt merkt, dass ein unerwarteter Fehler aufgetreten ist.
Erwartete Fehlermöglickeiten sollten durch eine vorausschauende Prüfung, wie z. B. oben mit der "Path-Prüfung" ausgeschlossen werden, also die von Dir genannte Fehlermöglichkeit des gesperrten Seitenobjektes.
In seltenen Fällen lässt sich in InDesign keine vorausschauende Prüfung vornehmen, dann landet das Skript in der Fehlerbehandlungsroutine, und man kann mit Hilfe der Fehlermeldung/-nummer ermitteln, ob in diesen wenigen Ausnahmefällen der Fehler ignoriert werden darf.
Try-Catch kostet ohne Auftreten eines Fehles extrem wenig Zeit, bei Auftreten eines Fehlers steigt die Laufzeit eines Skriptes erheblich an.
Auch deswegen ist leere Fehlerbehandlungsroutine (Catchzweig) ein Unding!
alle Gruppen auflösen? Vorsicht, das kann unschöne Auswirkungen haben.
Welche Probleme hast Du genau mit gesperrten Objekten? Wann lassen sich gesperrte Objekte im Schleifendurchgang mit allPageItems nicht entsperren? ***** Mit herzlichem Gruß, Uwe Laubender
Gilt beispielsweise auch für Objekte, die in einen gesperrten Grafikrahmen eingefügt wurden.
Was hilft, ohne dass irgendwelche Gruppen auseinandergenommen werden müssen: Zunächst mal den allPageItems array durchgehen und alle pageItems.locked auf false setzen.
Und in diesem Fall sollte es kein Problem machen, wenn der catch leer bleibt. Ästhetisch unbefriedigend, meinetwegen… ***** Mit herzlichem Gruß, Uwe Laubender
Eine Fehlerbehandlung immer vornehmen? Nicht unbedingt. Das hängt von der Aufgabe ab.
Zunächst versuche ich, im voraus zu prüfen, ob die Voraussetzungen gegeben sind. Ist dabei etwas nicht wie es sollte, wird der Anwender informiert, bevor das Script die eigentliche Ausführung macht.
Wenn dann letztere läuft, ist es meistens störend, wenn der Anwender bei jedem Fehler informiert wird. Deshalb ziehe ich es vor, bei einem Fehler eine Zählervariable hochzuzählen. Und den Anwender am Schluss zu informieren, wieviele Probleme und welcher Art aufgetreten sind.
***** Übrigens: Bei der vorliegenden Aufgabe konnte die Fehlerbehandlung nicht auf das Versagen hinweisen, als die Pfade-Monster-Rahmen nicht entfernt wurden.
***** Es gibt aber auch Fälle, in welchen dem Anwender absichtlich nicht gesagt wird, dass etwa nicht klappte. Ich habe hier ein JavaScript, welches aktuell 26'486 Zeilen umfasst. Es wird vom Anwender gestartet, um die gelieferten Fernseh-Programm-Texte (welche beim Export aus einer Datenbank mit InDesign-Tags versehen werden) in die vorbereiteten Textrahmen zu importieren. Und gleich darauf werden sie editiert: Je nach Titel der Sendung wird die Beschreibung (oder die ganze Sendung) entfernt. Öfters muss die Numerierung von Serien hinter den Untertitel verschoben werden. Oder es ist eine Zusammenlegung von Sendungen mit dem gleichen Titel gewünscht, um Platz zu gewinnen usw. usf.
Es kommt ab und an vor, dass die Konstruktion eines Abschnitts nicht mehr der bisherigen entspricht. Im "schlimmsten" Fall ergibt das einen Fehler und die bisherige Korrektur wird nicht gemacht. Der Anwender bemerkt dies immer und korrigiert von Hand. Er ist das gewohnt, weil sowieso hier und dort eingegriffen werden muss.
Im Script, welches ich benutzte, um das Ergebnis zu prüfen, enthält jeder der 43 'catch'-Abschnitte zwei Alerts: der erste meldet den Fehler, der zweite zeigt den Inhalt des betroffenen Absatzes an. Das erleichtert die Anpassung des Scripts enorm.
In der Version. welche in der Produktion benutzt wird, sind die Alerts entfernt. Die Meldungen kämen zwar selten, wären aber störend. Vor allem im Batch-Betrieb, während welchem die Texte in die Dokumente einer ganzen Woche geladen werden.
ich habe das angefangen, und hoffe, dass wir das hier zu Ende bringen. Ist ja alles Off-Topic!
Aber ich bleibe dabei, eine leerer Catch-Zweig ist ein schwerer Programmierfehler.
Wo wir uns nicht ganz einig sind, ist offensichtlich, dass wir beide etwas unterschiedliches unter Fehlerbehandlung verstehen.
Was ist also eine Fehlerbehandlung?
Zuerst einmal, als Programmierer sollte man vermeiden, dass überhaupt Fehler auftreten:
Ja, das mache ich auch, s. o..
Na ja, jeder Anwender sollte das Ergebnis prüfen, aber sollte man ihm nicht die Arbeit erleichtern, in dem man auf erkannte Fehler hinweist?
Du meinst während der Entwicklungsphase?
Ich baue immer die komplette Fehlernehandlung ein, setzte aber während der Entwicklung Breakpoints -> $.bp(true) in den Catch-Zweig, dann hält das Skript an, ich kann in der Konsole die Situation untersuchen und testweise Korrekturen vornehmen.
Da stimme ich Dir zu, Alerts gibt es nur in absoluten Abbruch-Situationen.
Die neueste Version meines WpsCreateAnchoredFrames-Skriptes sammelt Fundstellen von bestimmten Fehlersituaionen in einer DropDown-Liste, aus der der Anwender direkt an die problematischen Stellen springen kann. Dies funktioniert natürlich auch über mehrere InDesign-Dateien.
Das wäre in unserem Fall zu umständlich. Ein nichtentfernter Absatz, z.B., ist offensichtlich. Und rasch ausgewählt und gelöscht.
Das erwähnte Script muss periodisch an neue Sendungen (vor allem Serien) angepasst werden. Dazu habe ich meine Testversion. Sobald die Anpassungen funktionieren, mache ich eine Kopie für die Produktion: Die Zeile aktivieren, welche den Pfad zu den Textdateien auf dem Server enthält. Und jene auskommentieren, welche zum meinem lokalen Verzeichnis führt. Und eben die Auswertungen eventueller Fehlermeldungen entfernen.
Ich habe auch ein kurzes Testscript, mit welchem eventuelle Varianten der Zusammensetzung getestet werden können. Je nach Länge des Titels und des Untertitels wird die Numerierung hinter den Untertitel verschoben oder auch nicht. Eventuell wird das Wort "Serie" entfernt, um eine Zeile zu sparen. Mit diesem Script können auch die Zusammenlegungen von aufeinanderfolgenden Serien getestet werden. Die Numerierung, z.B. (5/18/24), verschieben, ab der zweiten bis zur letzten der Titel entfernen, der Uhrzeit wird "9 pt" zuweisen und die Returns (ausser dem letzten) in Zeilenschaltungen verwandeln, damit der Einzug stimmt. Erschwert wird das Ganze durch ein Piktogramm, welches unveröffentlichte Sendungen kennzeichnet. Falls eingefügt, hat der Abschnitt einen Absatz mehr. Je nach Platz muss das Pikto hinter den Titel verschoben werden.
und hier eine neue Version. Die Gruppen werden nicht aufgelöst. Das von Uwe vorgeschlagene Entsperren wird nur bei Gruppen vorgenommen.
Die Sperrung nichtgruppierter Objekte wird vor dem Entfernen aufgehoben. Sollten weder Gruppen noch Sperrungen vorkommen, kannst Du das Script vereinfachen.
Guten Morgen Werner, nur auf die Schnelle, Dein Skript zur Wiederherstellung des Zustands wirft einen Fehler: "unclosed token". Habe noch nicht herausgefunden, weshalb.
Beispieldatei, bei der das passiert:
Dein Skript umgeschrieben und ergänzt. Für den Fall, dass mittlerweile Elemente gelöscht wurden:
vielen Dank für die zahlreichen Antworten. Ich kann nur staunen.
Das skript von Hans funktioniert wunderbar, vielen Dank dafür und auch nochmals danke an alle anderen die sich so intensiv mit der Problematik auseinandergesetzt haben. Dachte nicht dass das Thema so große Wellen schlägt.
mir ist etwas bei diesem Skript aufgefallen: Wie du auch schreibst werden die Gruppen nicht aufgelöst.
Das ist ja bei Gruppierungen von mehr als 2 Objekten wovon eines (nämlich das Objekt mit den vielen Pfadpunkten) gelöscht wird auch so gewollt.
Wenn ich aber z.B nur 2 Objekte in meiner Gruppe habe und eines davon gelöscht wird, habe ich eine Gruppe bestehend aus einem Objekt. Ich wusste gar nicht dass so etwas überhaupt möglich ist.
ja dem ist so. Wenn nach dem Entfernen eines Objekts (oder mehreren) einer Gruppe nur noch ein Objekt übrigbleibt, ist dieses immer noch als "Gruppe" definert.
Dieser Zustand kann entweder manuell aufgehoben werden oder durch das Ergänzen des Scripts durch folgende Zeilen: