hast Du Dir mal vor Augen geführt, was Dein Code macht?
Die Zuweisung der Auswahl an eine Variable sel zur einfacheren Adressierung ist soweit klar.
In der Schleife wird (ungeprüft, ob das ausgewählte Objekt überhaupt Zeichen/characters beinhaltet) der Reihe nach jeweils die Schriftgröße des ersten Zeichens der ausgewählten Objekte ermittelt und in die Variable char1size geschrieben.
Am Ende wird der Inhalt der Variable car1size ausgegeben.
Weil der aber in der Schleife jeweils überschrieben wurde, wird am Ende nur der Wert des letzten Objekts ausgegeben. Die anderen Werte sind bis dahin längst vergessen.
Du solltest während dem Schleifendurchgang die Werte z.B. in einem Array festhalten und am Ende zusammengefasst ausgeben.
Hier ein Beispiel mit Prüfung auf Zeichen in den ausgewählten Objekten:
Math.max(???) von was?
Wie würdest Du zu Fuß oder händisch zur Bestimmung des gewünschten Rahmens vorgehen? Was würdest Du tun, wenn der höchste Wert zwei oder mehrere Male vertreten wäre? Und was wäre die Konsequenz der Ermittlung des Maximums? Einfach darauf hinweisen?
Viele Grüße Martin
(Dieser Beitrag wurde von Martin Fischer am 12. Mai 2021, 19:25 geändert)
Aufgabestellung: Finde Textrahmen mit größter Schriftgröße
Mein Skript tut genau das.
Und es zeigt außerdem: 1. Wie man die Sichtbarkeit von Variablen einschränkt 2. Den Einsatz von Prototypen 3. Wie man Fehler behandelt 4. liefert eine Sortierroutine für Arrays und Collections.
Also kurz, wen nur die Aufgabenstellung interessiert, kann die Routine als Funktion benutzen, wer das Skript verstehen will, sollte die einzelnen Schritte am Besten im Einzelschrittverfahren durchgehen.
Ich bevorzuge halt wiederverwendbaren Codde, den man in vielen ähnlichen Aufgabenstellungen einsetzen kann.
@Werner: Das ist der totale Overkill :-) So viele Prüfungen benötige ich gar nicht. Aber trotzdem Danke, der Code zeigt auf wie viele Umstände man berücksichtigen kann.
@Martin: Hier geht es schon in die richtige Richtung. Vielen Dank. Die Prüfung ob die Auswahl characters enthält ist aber in meinem Fall auch nicht notwendig, da nur Textrahmen mit Inhalt ausgewählt werden. Ziel ist nach wie vor zu ermitteln, welcher Textrahmen als erstes Zeichen das mit der größten Schriftgröße enthält. Das wird dann wohl mit einer Math.max Abfrage im neu erstellten Array funktionieren oder? Mit diesem Textrhamen soll dann in weiterer Folge auch etwas passieren.
Persönlich würde ich in einem Array die ausgewerteten Textrahmen und ihre Schriftgrößen ermitteln und anschließend nach den Schriftgrößen sortieren und daraus den Textrahmen mit der maximalen Schriftgröße ermitteln:
Aber Du kannst auch beim Durchgang durch die Schleife den aktuellen Wert der Schriftgröße (sel[i].characters[0].pointSize) mit dem bislang ermittelten Maximum (max) vergleichen und ggf. den alten Maximumswert ersetzen durch den aktuellen und den neuen Favoriten (fav) festhalten.
Hallo Werner, ja dein Skript habe ich ausprobiert und es funktioniert auch wunderbar. Vielen Dank dafür! Aber leider ist dieses Skript für mich zu kompliziert um es nachvollziehen zu können. Und das ist es auch worum es mir geht.
Ich möchte auch verstehen was hier vor sich geht. :-) Und das geht nur bei einfach gestrickten Skripten, bei denen nicht alle möglichen Szenarien abgefragt werden.
Ich bin was Skripten anbelangt wirklich Anfänger und weit davon entfernt für andere zu programmieren. Das ist auch nicht mein Ziel :-) Für mich muss ein Skript nachvollziehbar und so einfach/kurz wie möglich sein. Mir ist die Gefahr durchaus bewußt, dass es zu Abstürzen kommen kann, falls gewisse Abfragen nicht durchgeführt werden, aber ich schreibe diese kleinen Helferlein nur für mich und ich weiß ja was z.B. ausgewählt ist. Würde ich für andere schreiben müsste ich an meine Skripte ganz anders herangehen.
Vielen Dank nochmal Werner. Alles Gute. LG faxinger
Wo ich mit meiner Denkweise scheitere ist: es wird zuerst ein Array mit den Werten der Schriftgrößen erzeugt.
Wieso kann ich nicht danach (sobald der Array fertig generiert wurde)den größten Wert aus diesem Array ermitteln? Hier habe ich den Knopf in meiner Denkweise. Für mich wäre das der logische Ablauf: Erstelle Array und dann liefere den größten Wert aus den einzelnen Werten des Arrays.
Bin auch kein Programmierer, sondern ein an Automatisierung interessierter Schriftsetzer.
Das geht schon.
Aber dann kennst Du zwar den maximalen Wert, weißt aber (noch) nicht, in welchem Textrahmen der nun steckt, weil er - skripttechnisch - noch keine Verbindung zum Textrahmen hat.
Nun könntest Du hingehen, und die Schleife nochmal durchgehen und prüfen, wo dieser Wert (zum ersten Mal) vorkommt. Das ist recht umständlich (und frißt ggf. Zeit). Oder Du kannst die Position des höchsten Wertes im Array ermitteln und von dort auf den entsprechenden Textrahmen in der Auswahl schließen.
In meinem einfachen Code oben habe ich versucht, beim ersten Durchgang quasi das Ergebnis schon mitzunehmen: Was bei der Prüfung gleich richtig einsortiert wird, braucht nicht nachher neu herausgefunden werden.
Aber wie oben angegeben: Es führen viele Wege nach Rom.
Viele Grüße Martin
(Dieser Beitrag wurde von Martin Fischer am 14. Mai 2021, 09:42 geändert)
Genau das hatte ich ja versucht mit 2 Durchgängen, was zwar umständlicher ist als dein elegantes Vorgehen aber eben für mich durchschaubarer :-)
Aber math max lieferte mir nicht die größte pointsize von allen ausgewählten Textrahmen erstes Zeichen, sondern die pointsize des ersten ausgewählten Textrahmens (also die Größe des ersten Zeichens dieses Textrahmens) Und da bin ich gescheitert.
Meine Vorgehensweise wäre so, dass ich nachdem der maxWert ermittelt wurde, den Textrahmen adressieren würde. Wie genau muss ich mir noch überlegen. Vielleicht mit parentTextframe?
Im ersten Entwurf des Skripts oben sollten die Schriftgrößen am Ende als String ausgegeben werden. Zwar hätte die Umwandlung in Kombination mit einem anderen hinzuzufügenden String-Element (in JavaScript) automatisch funktioniert. Aber wo möglich, versuche ich die Kontrolle über diese Umwandlung zu behalten.
Und genau diese ausdrückliche Stringumwandlung sorgt bei Dir bei der späteren Sortierung für unerwartete Ergebnisse: im Array wird nicht nach nu merischen Schriftgrößen sortiert, sondern nach Strings.
Deswegen solltest Du auf die String-Umwandlung der Werte bei der Aufnahme in’s Array verzichten:
Viele Grüße Martin
(Dieser Beitrag wurde von Martin Fischer am 14. Mai 2021, 10:20 geändert)
parentTextFrames[0] würde passen, wenn es denn eine Verbindung von der ermittelten Zahl zu dem Textrahmen, in dem sie enthalten ist, geben würde. Aber genau diese Verbindung fehlt Dir. Du hast die maximale Zahl und kannst sie benennen. Aber zu diesem Zeitpunkt wissen Du und das Skript nicht mehr, aus welchem Textrahmen die Zahl entnommen ist, da sie nur noch nackert als Zahl da steht, ohne den Container, aus dem sie ermittelt wurde.
Hallo zusammen, ein Array kann ja nicht nur Strings speichern, man könnte auch den zugehörigen character oder textStyleRange mit dazu speichern. In einem Aufwasch.
Oder man macht das in einem Objekt.
Eine Schleife durch alle textStyleRanges, die PointSize wird ermittelt, übersteigt sie die PointSize im gespeicherten Objekt oder Array, werden die Werte dort einfach neu zugewiesen.
Hier ein Beispiel mit einem Array als Resultat. Voraussetzung ist ein ausgewählter Textrahmen:
zum Einen hatten Herr Perplies und ich oben auf die Möglichkeit eines Arrays mit Objekten und anschließender Sortierung bereits hingewiesen. Auf eine Ausführung dieses Ansatzes hatte ich jedoch bewusst verzichtet, um es Faxinger nicht zu kompliziert zu machen.
Zum Anderen geht es Faxinger nicht um die Ermittlung der textStyleRanges eines ausgewählten Textrahmens, sondern um die Bestimmung desjenigen Textrahmens (aus einer Auswahl von mehreren - ausdrücklich mit Inhalt), dessen erstes Zeichen (oder erster TextStyleRange) den höchsten Schriftgrad hat.
Oder hast Du für Deine Idee mit dem zweidimensionalen Array bewusst eine geänderte Aufgabenstellung verwendet?
Ferner hätte ich noch eine Frage zu Deiner Feststellung oben:
Ist dem bei der gegebenen Aufgabenstellung tatsächlich so, dass die Auswertung des ersten textStyleRanges statt des ersten characters in mehreren ausgewählten Textrahmen einen zeitlichen Unterschied macht? Kann mir das eigentlich nicht vorstellen, habe das aber auch nicht nachgemessen, weil ich vermute, dass bei ein paar Textrahmen der zeitliche Unterschied nicht ins Gewicht fallen dürfte und auf einem Druckbogen erwarte ich eine überschaubare Zahl an zu prüfenden Textrahmen, und nicht hunderte oder gar tausende.
Aber ich weiß, Du bist ein Perfektionist. ;-)
Viele Grüße Martin
(Dieser Beitrag wurde von Martin Fischer am 14. Mai 2021, 16:05 geändert)
Hallo Martin, ich hoffe, ich habe ein für faxinger lesbares und verstehbares Skript geschrieben, das nach seiner sehr eng formulierten Aufgabenstellung etwas mehr Perspektive zeigt. ***** Mit herzlichem Gruß, Uwe Laubender
dem ist gewiss so. Mich verwundert lediglich etwas die Konzentration auf die textStyleRanges. Und da dachte ich, ich könnte ja mal nachfragen, weil ich es mir nicht so recht vorstellen kann, dass/wie die Auswertung der jeweils ersten textStyleRanges von vielen Textrahmen performanter sein soll als die Auswertung von den jeweils ersten characters.
Werde gelegentlich mal eine Versuchsanordnung anlegen und dem nachspüren ob und ab wann das messbar wird.
Viele Grüße Martin
(Dieser Beitrag wurde von Martin Fischer am 14. Mai 2021, 16:25 geändert)
nochmals herzlichen Dank für eure Anregungen. @Uwe: der Weg über die textstyleRanges wäre mir deshalb nicht in den Sinn gekommen, weil es ja nur um die Ermittlung des ersten Zeichens bzw. dessen Schriftgröße aus einer Auswahl an Textrahmen ging. Bei textstyleRanges denke ich eher an wechselnde Formatierungen innerhalb eines Textabschnittes und das wäre in diesem Fall für mich kein Unterscheidungsmerkmal mit dem ich arbeiten würde.
Die Laufdauer des Skripts ist in meinem Fall auch nebensächlich, da meistens eine überschaubere Anzahl an Textrahmen (meist unter 10) ausgewählt ist. Ob die Ermittlung des Textrahmens mit dem größten ersten Zeichens dabei 0,05 Sekunden oder 0,04 Sekunden dauert ist mir schlichtweg Banane :-)