Hallo zusammen, muss für mehrsprachige Preislisten versuchen, die Produktnummern zu ändern. Fall: QXP 6.5 Dokument (Doppelseite), wie in einem typischen Katalog oder einer bebilderten Preisliste. Es gibt einen verkettenen Haupttextrahmen. Darin stehen die Produktpositionen von A bis...z.B. H untereinander immer in der Art: Position, Produktname, Beschreibung, Produktnummer, Farbe, Preis usw. Alle Bestandteile haben auf allen Seiten jeweils die gleichen Stilvorlagen zugewiesen bekommen (Also auch die Produktnummer hat eine eindeutige, eigene Stilvorlage). Die Produktnummer sieht z.B. folgendermaßen (9-stellig) aus: 11 11 11 11 1 ich muss 2 Dinge hinbekommen: Im einen Fall daraus ein 11 11 11 machen, oder 11 11 11 22 Der vordere Bereich der Nummer bleibt also. Hinten (rechts) muss es in der einen Sprache um 3 Stellen gekürzt werden, in der anderen Sprache werden 3 gekürzt und "55" angesetzt (getrennt mit Leerzeichen). So kann man später im Webshop auswerten, aus welcher Preisliste und Sprache bestellt wurde. Und das ganze bei allen Nummern eines verketteten Rahmens. und nun die eigentliche Frage: Kann man per AS so eine Zeichenkette suchen und entspr. bearbeiten? Evtl. könnte auch die Stilvorlage helfen, denn die Produktnummer hat eine eigene, immer gleiche Stilvorlage zugewiesen. Vielleicht schaffe ich es, irgendwie herauszufinden, wie das mit dem ersetzen geht. Dazu steht woanders auch etwas ähnliches. Wie ich aber die Daten "analysieren" kann, weiß ich noch nicht.
Ich hab auch noch eine zweite Sache, die aber im anderen Posting steht. Viele Grüße Kultgerd
das direkte Suchen und Ersetzen nach Datenmuster per Script ist in einer XPress-Textbox nicht möglich.
Das "Analysieren" der Daten geht nur über einen Umweg: Einer Variablen die Story – als reinen Text umgewandelt – zuweisen. Und dann kann man mit einem RegEx-Werkzeug, z.B. Satimage.osax, nach Ziffern suchen und diese nach Wunsch ersetzen. Aber dann muss man das Resultat wieder in die Textbox bringen. Und je nachdem, wie der Text formatiert ist, kann es problematisch sein.
Also auch hier: Erst mit einem Real-Life-Projekt kann ich Dir den Weg zeigen.
Es handelt sich um eine Textzeile aus dem QuarkXpress, in Tags umgerechnet, damit die Stilvorlegen nicht verloren gehen: @1035_Bestell-Nr:<*p(0,0,0,8.2,0,0,g,"Deutsch")>89<\!s>16<\!s>17<\!s>58 25 <@Text/light_2000><>marine<\t><@Text/fett_2000>2 Garnituren<@$p>
Das rote ist die Stilvorlage. Das blaue die Produktnr. ich muss nun die letzten beiden Paare löschen oder das letzte Paar "25" durch die "55" ersetzen. Das letzte soll also dann egal bei welcher Nr. die "55" werden. Ich muss für zwei verschiedene Listen einmal die eine Lösung, für die andere, die andere Lösung machen. Bin am probieren mit FileMaker, komme aber nicht recht weiter.
ja, das hilft. Wenn Du den String so wie er ist, einer Variablen zuweist, dann kann wie schon erwähnt, mithilfe der Satimage.osax das Suchen und Ersetzen vorgenommen werden. Die Syntax ist: --- set aString to "Hello" set newString to change "e" into "a" in aString[color=pink] [/color][pink]-->"Hallo"[/pink] ---
Wenn gewisse Typen von Zeichen (wie z.B. Ziffern) gesucht werden sollen, dann helfen dabei die Wildcards der "Regular Expressions". Mit der Range [0-9] wird jede Zahl zwischen 0 und 9 gefunden. Um ein Ziffernpaar zu finden, kann man entweder [0-9][0-9] verwenden oder [0-9]+ wobei das Pluszeichen bedeutet, dass eine oder mehr Ziffern gesucht wird. Die geschützten Zwischenräume <\!s> enthalten einen Backslash. Weil dieser in der RegEx-Umgebung ein spezielles Zeichen ist, muss er im Suchstring vervierfacht werden, wenn man Versuche im Script-Editor-Fenster macht.
Die Zeichenfolgen fasst man mit Klammern zu Gruppen zusammen. Im vorliegenden Fall wird die erste Gruppe von den Paaren gebildet, welche erhalten bleiben. Die zweite Gruppe ist das Paar (inklusive Zwischenraum), welches geändert oder entfernt werden soll.
Im Ersetzenstring kann mit \\1 auf die erste Gruppe verwiesen werden, das heisst, sie wird an dieser Stelle eingesetzt. Statt für die zweite Gruppe \\2 zu verwenden, wird dort die literale Änderung eingefügt. Nicht vergessen: 'with regexp' anfügen, sonst wird nichts ersetzt. Das letzte Ziffernpaar durch '55' ersetzen: Die beiden letzten Ziffernpaare tilgen: Die Scripting Addition "Satimage.osax" findest Du hier http://www.satimage.fr/software/en/downloads_osaxen_pop.html oder hier http://www.fachhefte.ch / Link "AppleScripts", Ordner "z_additions_os_x".
Hallo Hans, vielen Dank erst Mal hierfür und auch bzgl. des anderen Postings!
Mein Problem ist noch, dass ich den ganzen Code aus der Haupttextbox vor mir habe, mit vielen Bestellnummern. Das war ein Beispiel, bei dem nur ein Teil eines Produktes betroffen ist.
Pro Doppelseite gibt es teilweise 15 - 20 Artikel und für jeden Artikel auch verschiedene Farben oder Größen. Nun muss das Script Bestellnummer für Bestellnummer finden und erkennen und anschließend die entsprechende Änderung durchführen. Jede Bestellnummer ist anders. Ich muss anhand der letzten Stellen von rechts nach links ändern (löschen bzw. ersetzen).
also ... wenn Du mir bitte mal ein Musterprojekt zustellen würdest, samt genauer Aufgabenstellung, dann könnte ich versuchen, eine Lösung zu finden, welche die Bestellnummern eine nach der andern behandelt.
Hallo zusammen (und ganz besonderer Gruss an Hans) :!: Ich hab den ersten Teil jetzt auf eine etwas andere Weise hin bekommen. Die Produktnummern bekomme ich über eine extra Tabelle. Die schmeiss ich ne FM DB und mach mir eine alt - neu Gegenüberstellung; in die gleiche Tabelle füg ich hintenan Datensätze die nur eine Preisgegenüberstellung haben. Mit AS hole ich mir den in Tags gewandelten Text in FM, lasse erst die Sperrungen </s> löschen, dann die Produktnrn. austauschen, (Wobei ich einmal die neue Produktnr MIT Sperrung (für den Austausch) und einmal OHNE Sperrung (für den Abgleich) habe) anschließend die Preise. Zu guter Letzt schneide ich das Ergebnis aus und ersetzte damit den ausgewählten Text in QXP. Am Ende wird dann zurück konvertiert in (ohne Tags) und fertig. Das dauert pro Doppelseite für den Haupttextrahmen ca. 5-10 Sekunden. Dadurch, dass ich zwar ohne gesperrte Leerzeichen abgleiche, aber dann die Variante mit den gesperrten Leerzeichen abgleiche, bleiben die Stände jeweils gleich.
Das einzige, das ich nicht hinbekommen habe, ist die erste Produktnummer. Die funzt noch nicht. Mal sehen, das krieg ich schon noch hin.
LETZTES PROBLEM BIS ZUM GLÜCK: Zu jedem Bild ist nochmal ein Textrahmen mit der Produktposition auf der Seite (A, B, C oder 1, 2, 3...) und der Preis. Ich muss nun irgendwie die Preistabelle nehmen und Rahmen für Rahmen (Außer dem höchsten, denn den hab ich dann ja schon) durchgehen und den Preis austauschen. Grundsätzlich ist es relativ gut machbar, da - egal um welches Produkt es sich handelt - je ein vorkommender Preis durch einen anderen, jeweils gleichen Preis, ausgetauscht wird (1:1) Bsp: alle Preise 4,99 in der Liste werden zu 8,95 alle Preise 9,99 in der Liste werden zu 14,95 alle Preis 11,48 in der Liste werden zu 15,45 usw.
Ich checke einfach nicht, wie man ne Liste Preisalt - Preisneu direkt mit einen Textrahmen nach dem anderen in QXP abgleicht. Kann man das überhaupt?? Das Script müsste dann einen Textrahmen nach dem anderen (aus besagtem größten) aufgrund des Preises prüfen und den neuen Preis einsetzen. Zur Not müsste ich das halt auch mit FM wie im Haupttextrahmen machen. Aber wie geht das, einen Rahmen nach dem anderen durchzugehen??
Zuerst die Hauptbox auswählen und die Textkette benennen. --- tell document 1 of application "QuarkXPress 6.5" tell current box tell story 1 set name to "main" end tell end tell end tell --- Damit kann diese Textkette bei der Wiederholungsschleife, welche durch alle Stories geht, ausgeschlossen werden.
Im zweiten Script werden zuerst die beiden Listen mit den alten und den neuen Preisen definiert. Dann geht das Script alle Textketten durch und ersetzt mit dem XPress-Befehl 'set every text' die alten durch die neuen Preise. --- set oldPriceList to {"4,99", "9,99", "11,48"} set newPriceList to {"8,95", "14,95", "15,45"}
tell document 1 of application "QuarkXPress 6.5" activate repeat with i from 1 to count of stories tell story i if name is not "main" then repeat with j from 1 to count of oldPriceList set oldPrice to item j of oldPriceList set newPrice to item j of newPriceList try set (every text where it is oldPrice) to newPrice end try end repeat end if end tell end repeat end tell ---
danke für das Musterprojekt. Ja, Du siehst es richtig: Weil die Cents anders als die ganzen Eurobeträge formatiert sind, kann man die Preise nicht direkt in den Textboxen suchen und ersetzen, sondern muss die Story im XPress-Tags-Format exportieren.
Ich habe leider feststellen müssen, dass den Preisen keine entsprechende Stilvorlage zugewiesen worden ist. Ein Beispiel: Der Preis 14,99 ist mit "Normal" formatiert. Das bedeutet, dass die Tags der lokalen Änderungen direkt vor die Ziffern zu stehen kommen. Statt der erwarteten Kette "<k$>14<->99" wird "<z56k-15f\"B Futura Bold\">1<k$>4<->99" exportiert.
Für interessierte Mitleser: Im XPress-Layout ist der Preis ohne Komma getippt und die 99 Cents sind "tiefgestellt", deshalb der Tag '<->'.
In der Liste 'oldPriceList' muss deshalb das führende '<k$>' (das Zurücksetzen auf den Unterschneidungswert der Stilvorlage) hinter die Ziffer "1" verschoben werden .
Damit nicht genug. Das Dollarzeichen ist ein Zeichen mit spezieller Bedeutung in den RegEx-Suchstrings (Ankerpunkt für ein Zeilenende). Okay, es kann deaktiviert werden, indem man zwei Backslashes davorsetzt. --- set aString to "<z56k-15f\"B Futura Bold\">1<k$>4<->99<$z60c$$>" try set oldPrice to matchResult of (find text "[0-9]?[0-9]?[0-9]?(<k\\$>)?[0-9]<->[0-9][0-9]" in aString with regexp) end try -->"1<k$>4<->99" --- Exkurs: Die Bedeutung von [0-9] ist schon weiter oben erklärt worden. Die Fragezeichen bedeuten, dass die davorstehende Ziffer nicht vorhanden sein muss. Mit diesem Suchstring werden also ein- bis vierstellige Preise gefunden. Normalweise könnte man die Kette kürzen zu "[0-9][1,4]<->[0-9][1,2]". Weil aber der "Störenfried" '<k\\$>' eingefügt werden muss, ist die Option '[1,4]' (= mindestens eine, maximal vier Stellen) nicht möglich. Dieses '<k\\$>' sollte eigentlich nach jeder Ziffer eingesetzt sein. Damit die Suchkette aber leserlich bleibt, habe ich es hier nur einmal vorgesehen, damit wenigstens das Beispiel abgedeckt ist. Wichtig ist, dass diese sechs Zeichen mit runden Klammern zu einer Gruppe zusammengefasst werden. Nicht die eckigen Klammern verwenden. --- set oldPriceList to {"1<k$>4<->99", "1<k$>9<->99", "24<->99", "39<->99"} set newPriceList to {"<k$>24<->99", "<k$>29<->99", "<k$>34<->99", "<k$>49<->99"} set aString to "<z56k-15f\"B Futura Bold\">1<k$>4<->99<$z60c$$>" try set oldPrice to matchResult of (find text "[0-9]?[0-9]?[0-9]?(<k\\$>)?[0-9]<->[0-9][0-9]" in aString with regexp) end try -->"1<k$>4<->99" repeat with i from 1 to count of oldPriceList if item i of my oldPriceList is oldPrice then set nItem to i exit repeat end if end repeat {oldPrice, nItem} -->{"1<k$>4<->99", 1} set newPrice to item nItem of my newPriceList -->"<k$>24<->99" set newString to change oldPrice into newPrice in aString -->"<z56k-15f\"B Futura Bold\"><k$>24<->99<$z60c$$>" --- Im anderen Thread erwähnst Du – zu Recht – das Problem, wie ein Preis, welcher nicht in der Liste vorgesehen ist, notiert werden kann. Dafür habe ich im Script eine Lösung eingebaut: Die betreffende Textbox wird mit "Magenta" eingefärbt. So kann man sie lokalisieren und den Preis manuell berichtigen.
Ich werde Dir das Script mal zustellen. Allerdings: In Anbetracht der 1601 (!) zu berücksichtigenden Preise, frage ich mich, ob nicht eine weniger komplizierte Methode vorzuziehen sei. Ich habe eine Idee, wie die Texte ohne Export ins XPress-Tags-Format behandelt werden können. Muss sie zuerst realisieren, befürchte aber, dass uns die Unterschneidungen einen Streich spielen werden ...
ja, es funktioniert! Die Idee war, die Preise als reinen Text zu behandeln, z.B. "1999", das Austauschen vorzunehmen und schliesslich den beiden letzten Stellen den Stil "Tiefgestellt" zuweisen. Damit entfällt das Exportieren im XPress-Tags-Format in eine Datei usw. Die Elemente der Preislisten können vereinfacht werden und man muss sich nicht darum kümmern, wie und wo das Unterschneiden aufgehoben worden ist.
Allerdings hat man das Problem, dass eventuelle Unterschneidungs-Kandidaten nicht wie bei der XPress-Tags-Variante im voraus leicht definiert werden können. Im folgenden Script wird versucht, wenigstens der Ziffer '1' die Werte zuzuweisen. Alle weiteren Kombinationen müssen manuell nachbearbeitet werden.
Zum Beschleunigen der Ausführung enthält das Script zwei Script-Objekte, welche mit 'do script' aufgerufen werden. Dadurch wird beim Testprojekt die Dauer von 7.3 auf 3.8 Sekunden verringert. --- -- einige Variablen als 'global' bezeichnen, damit sie in den Handlern bekannt sein werden global boxNum global newPrice global newPriceList global oldPriceList global priceCount global storyOne global x1 global x2
-- die Liste mit den "alten" Preisen set oldPriceList to {"1499", "1999", "2499", "3999"} -- die Liste mit den "neuen" Preisen set newPriceList to {"1599", "2999", "3499", "4999"} -- die Anzahl der Elemente der Liste wird gezählt set priceCount to count of oldPriceList
tell document 1 of application "QuarkXPress 6.5" activate set selection to null -- eine Wiederholungsschleife durch die Textketten repeat with i from 1 to count of text boxes tell text box i set boxNum to i -- der Variablen 'storyOne' die aktuelle Textkette zuweisen set storyOne to do script {getStory} if storyOne is not "" then -- den zu ändernden Preis, dessen Position und Länge feststellen set someDigits to (find text "[0-9]{1,6}" in storyOne with regexp) -- der Variablen 'oldPrice' den alten Preis zuweisen set oldPrice to matchResult of someDigits -- den Handler aufrufen, welcher den neuen Preis zurückgibt set newPrice to my getNewPrice(oldPrice) -- wenn es geklappt hat ... if newPrice is not "" then -- der Variablen 'x1' die Position ... set x1 to (matchPos of someDigits) -- ... und 'x2'die Länge zuweisen set x2 to (matchLen of someDigits) do script {changePrice} else set properties to {color:"Magenta", shade:50} end if end if end tell end repeat display dialog "Fertig." buttons "OK" default button 1 with icon 1 giving up after 2 end tell
script getStory set someDigits to "" tell document 1 of application "QuarkXPress 6.5" tell text box boxNum -- nur wenn die Anzahl Zeichen grösser als 2 und kleiner als 99 ist ... if (count of characters of story 1) is greater than 2 and (count of characters of story 1) is less than 99 then set storyOne to story 1 else set storyOne to "" end if end tell end tell if storyOne is not "" then try -- prüfen, ob die Story mindestens 3 aufeinanderfolgende Ziffern enthält set someDigits to matchResult of (find text "[0-9]{3,3}" in storyOne with regexp) end try end if if someDigits is "" then set storyOne to "" end if return storyOne end script
on getNewPrice(oldPrice) repeat with i from 1 to count of oldPriceList if item i of my oldPriceList is oldPrice then set nItem to i exit repeat end if end repeat try set newPrice to item nItem of my newPriceList return newPrice on error return "" end try end getNewPrice
script changePrice tell document 1 of application "QuarkXPress 6.5" tell text box boxNum try -- den neuen Preis einsetzen set characters (x1 + 1) thru (x1 + x2) of story 1 to newPrice set x3 to count of newPrice -- die Cents tiefstellen set style of characters ((x1 + x3) - 1) thru (x1 + x3) of story 1 to {subscript} -- das Unterschneiden bei der '1' vornehmen if newPrice contains "1" then repeat with i from 1 to (x3 - 1) set curChar to (x1 + i) tell story 1 if character curChar is "1" then if character (curChar + 1) is "1" then set kern of character curChar to -30 else set kern of character curChar to -15 end if end if end tell end repeat end if on error set properties to {color:"Magenta", shade:50} end try end tell end tell end script --- Auch dieses Script stelle ich Dir zu. Dann kannst Du entscheiden, welches geeigneter ist.
Hallo Hans, 1000 Dank für die Scripts. Ich hab schon einige Tests gemacht. Mit der Musterseite geht es problemlos. Habe noch ein bischen Probleme, bei anderen Seiten als der Musterseite. Während des Script-Durchlaufs beim ersten Script stürzt QuarkXpress ab. Schicke Dir ScreenShots diesbzgl. zu.
Beim 2. Script scheint nur der erste Preis geändert zu werden, sobald ich die Musterseite mit Bildmaterial und Fussleiste verwende. Wenn ich Dann verschiedene Kompnenten (z.B. Fussleiste) lösche, dann stürzt auch wieder QuarkXpress ab.
Ich probiere mal, vielleicht kann ich das Problem einschränken.
Abstürze sind ärgerlich. Hatte auch ein paar erlebt, während des Entwickelns des ersten Scripts. Die Ursache war aber immmer eine unzulässig abgeänderte Textkette (musste halt ein bisschen pröbeln) oder ein nichtkonformes Adressieren von XPress-Objekten.
Was ist, wenn Du die Fussleiste enfernst, bevor Du das Script startest?
Würdest Du mir bitte auch ein Projekt mit Fussleiste und Bildboxen (Bilder entfernen) senden? Bitte zippen, damit alles geschützt ist. Danke im voraus.
Hallo Hans, ich bau das mal um um schick Dir das noch. Ich fürchte, einen hab ich dann noch: Ich hab gerade die Info bekommen, dass wir "Ganze" Preis in der Form 14,- und nicht 1400 bekommen. Gibt es dafür auch eine Formaterkennung mit regexp?
was meinst Du mit "Ganze"? Sind das Preise, welche ganze Euros (ohne Cents) zeigen? Wird ein Halbgeviertstrich verwendet? Sicher gibt es dafür ein RegEx-Suchmuster. Ich müsste aber ein Musterprojekt bekommen (inkl. Beispiel des neuen Preises), damit ich das Script ergänzen kann.
Hallo Hans, es ist, wie du richtig vermutest. Die Euro-Cent entfallen (Also kein 1400) sondern ein 14,-. das Komma und der Bindestrich werden in der Schriftgröße der 14 erstellt. Es handelt sich also um einen ganz einfach Bindestrich. Ich werd Dir spätestens morgen die Datei mit den Rahmen zusenden.
hab mir da mal was mit meinen anfängerhaften Gehversuchen zusammenfantasiert, erhalte aber die Fehlermeldung:
NSCannotCreateScriptCommandError
So wie nachfolgend sieht dieser Teil des Scriptes aus. Ist aber nur ein Auszug! Bis dahin wird der Haupttextrahmen gefunden, der mit farbig markierter "Fantasie" bearbeitet werden sollte.:
tell document 1 of application "QuarkXPress Passport" activate menu item tell current spread repeat with i from 1 to count of text boxes tell text box i tell text 1 set numChars to count of characters if numChars is greater than 150 then my selectText(i)
exit repeat end if end tell end tell end repeat end tell end tell
[color=red] tell selection
set paragraphs to i repeat with i from 1 to count of paragraphs of selection -- Textkette in Form von xx xx xxx finden set someDigits to (find text "[0-9]{2,2}&space&[0-9]{2,2}&space&[0-9]{3,2}" in selection with regexp) change someDigits into (find text "[0-9]{2,2}&space&[0-9]{2,2}&space&[0-9]{2,2}" with regexp) end repeat end tell [/color]
on selectText(i) tell document 1 of application "QuarkXPress Passport" set selection to text 1 of text box i set aString to contents of selection set the clipboard to aString end tell end selectText
das kann nicht funktionieren, weil: 1. Das Suchen und Ersetzen mit der Satimage.osax nur im Speicher vorgenommen werden kann; 2. 'find text' und 'change' zwei verschiedene Befehle sind, welche nicht in der gleichen Zeile stehen dürfen; 3. Das Konstrukt '"[0-9]{2,2}&space&[0-9] usw.' String und Konstante mischt, aber ohne die An- und Abführungszeichen vor und nach den '&'-Zeichen zu wiederholen: 4. Das Resultat von 'find text' ein Record mit 3 Einträgen ist: matchPos, matchLen und matchResult
Zu 1.: Wenn der Text keine lokalen Formatierungsänderungen aufweist, dann kann man einer Variablen den Inhalt der Textbox zuweisen. Der Text muss nicht ausgewählt werden. Meistens werden aber im Text Auszeichnungen vorkommen. Damit diese nicht verloren gehen, gibt es zwei Möglichkeiten: a) die Story im XPress-Tags-Format auf die Harddisk speichern, dann in eine Variable einlesen, das Suchen und Ersetzen vornehmen, den neuen String wieder in eine Datei sichern und in die Textbox importieren. b) die Story direkt in eine Variable geben, mit 'find text' die Position und die Länge der gesuchten Textkette ermitteln und dann mit einem XPress-Befehl gezielt die neue Textstelle anstelle der alten einsetzen.
Zu 2.: Mit 'find text' wird einer Variablen eine bestimmte Reihe von Zeichen eines Strings zugewiesen. Dazu noch die Position und die Anzahl Zeichen. Mit 'change' wird in einem String ein (oder mehrere) Zeichen gegen ein anderes ausgewechselt (siehe das Beispiel in meiner Einführung, ganz am Anfang dieses Themas). Wenn das Suchmuster eines 'change'-Befehls in der Textkette nicht vorkommt, dann geschieht nichts, das heisst, das Ergebnis ist die unveränderte Textkette. Bei einem 'find text'-Befehl wird eine Fehlermeldung generiert, falls keine Übereinstimmung gefunden wird. Deshalb muss dieser Befehl immmer mit einem 'try'-Wickel umgeben sein.
Zu 3.: Richtig wäre: "[0-9]{2,2}" & space & "[0-9]{2,2}" & space & "[0-9]{2,2}" Aber es genügt, einen normalen Zwischenraum zu tippen: "[0-9]{2,2} [0-9]{2,2} [0-9]{2,2}"
Zu 4.: Das Ergebnis von ... --- set aString to "Hallo 12 34 56 Gerd" set someDigits to (find text "[0-9]{2,2}" & space & "[0-9]{2,2}" & space & "[0-9]{2,2}" in aString with regexp) --- ... ist: {matchPos:6, matchLen:8, matchResult:"12 34 56"} Davon interessiert uns eigentlich nur 'matchPos', weil die Länge des Strings bekannt ist und nicht dynamisch verwaltet werden muss. Der Wert von 'matchPos' ist ein sogenannter 'offset'. Das bedeutet, die Anzahl Zeichen, welche im Text vor dem ersten Zeichen des gefundenen Musters stehen.
Hallo Hans, wie Du siehst, da hat viel Fantasie darin gesteckt. Immerhin hat AS schon mal die Syntax nicht angemeckert. :oops:
Ich hab gestern erfahren, dass ich bei einem Kunden keine Referenz von Alter zu Neuer Nummer bekomme. Bei denen ändert sich nur die letzte Stelle der Nummer, die halt ganz einfach weg fällt.
Nachdem ich ja mit Deiner Hilfe die Preise in den einzelnen kleinen Preisrahmen getauscht bekomme, hab ich gehofft, dass vielleicht Zeilenweise im Haupttextrahmen das so nach dem ungefähren Muster funktioniert, wie ich das zu schreiben versucht hab.
Ich müsste demnach ja den Inhalt des Haupttextrahmens in eine Variable schreiben und dann Zeile für Zeile nach dem String suchen und diesen anschließend mit einer um sich selbst um die rechte Stelle gekürzten Wert ersetzen.
Ich probiers mal weiter. Vielleicht weiß auch noch jemand anderes Rat, so daß ich DIch nicht ständig damit belästige.
von Belästigen keine Spur. Aber ich nehme an, dass Dir bewusst geworden ist, dass eine recht komplexe Materie nicht in ein paar Tagen beherrscht werden kann.
Für den vorliegenden Fall (die letzte Ziffer aller Bestellnummern entfernen) werde ich heute Abend versuchen, eine Lösung zu finden.
Weil pro Zeile meistens zwei Bestellnummern vorkommen, finde ich, dass es einfacher sein wird, den anscheinend komplizierteren Weg über den XPress-Tags-Export zu gehen. Der Vorteil: Das Entfernen der Ziffern geschieht mit einem Befehl: --- set aString to "16 62 810 weiß 26 14 372 bleu" set newString to change "([0-9]{2,2} [0-9]{2,2} [0-9]{2,2} [0-9][0-9])([0-9])" into "\\1" in aString with regexp -->"16 62 810 weiß 26 14 372 bleu" --- Die XPress-Tags habe ich hier weggelassen, damit es leserlicher wird.
Hallo Hans, in dem Script hab ich ja an einer Stelle die Daten des Haupttextrahmens in Tags vorliegen. Ich schick Dir nochmal das ganze Script per Mail. Dann hast Du den aktuellen Stand im Kontext.
Ich bin grad am durcharbeiten den Buches "The TAO of AppeScript" (S. 64 :oops: ) Wenn ich das durch hab, wird mir sicher einiges klarer. Dann noch fleissig üben und es wird bestimmt bald besser mit mir!
Dein aktuelles Script habe ich nicht erhalten. Macht aber nichts, denn jetzt habe ich zu Beginn des Scripts, welches die Preise in den kleinen Textboxen austauscht, den Code eingefügt, welcher die Hauptbox behandelt. Damit können die Listen der Preise für beide Teile benutzt werden.
"Stop! Stop!!!" wirst Du rufen, "die Preise der Hauptbox sind alle in der gleichen Schriftgrösse, die Eurobeträge mit Komma von den Cents getrennt. Und in den kleinen Boxen fällt das Komma weg und die Cents sind tiefgestellt."
Kein Problem. Die Preise in den Listen können im Format "1999" oder "19,-" getippt sein. Für die Hauptbox fügt das Script – falls notwendig – ein Komma ein. Nachstehend ein Auszug des Scripts "NummernPreiseAendern_01d", der Handler, welcher die Hauptbox behandelt. Die Kommentare erklären, was gerade geschieht.
Wenn ein Preis in der Hauptbox nicht in der Liste 'oldPrice' vorkommt, wird er im String mit XPress-Tags versehen, damit der Preis beim Import mit Magenta eingefärbt wird, z.B. "<cM>23,99<c$>". --- -- dieser Handler nimmt das Kürzen der Bestellnummern und das Austauschen der Preise vor on modNumChangePrice(boxNum) global allPrices global defList -- der Text wird in XPress-Tags-Format in eine Datei exportiert tell document 1 of application "QuarkXPress 6.5" tell page curPage tell text box boxNum save every text of story 1 in tempFilePath as "TEXT" end tell end tell end tell -- der exportierte Text wird in die Variable 'aString' gelesen set aString to read file tempFilePath try -- ... die Kürzungen vornehmen ... set newString to change "([0-9]{2,2}<\\\\!s>[0-9]{2,2}<\\\\!s>[0-9][0-9])([0-9])" into "\\1" in aString with regexp end try -- die Liste der Preise aufstellen set allPrices to {} try -- der String 'Preis>' ist ein Teil des Zeichenstilvorlagen-Namens im XPress-Tags-Format und -- dient als "Anker" um die nachfolgende Ziffernfolge als Preis zu identifizieren -- die Fragezeichen im Suchmuster bedeuten, dass sowohl "19,99" als auch "19,-" gefunden wird -- 'using "\\2"' heisst, dass nur die zweite Gruppe des Suchmusters in die Liste aufgenommen wird -- mit 'all occurrences and string result' erhält man die Strings aller Vorkommen set allPrices to (find text "(Preis>)([0-9]+,[0-9]+?-?)" in aString using "\\2" with regexp, all occurrences and string result) end try -- wenn die Liste nicht leer ist ... if allPrices is not {} then set defList to {} -- allfällige Mehrfachvorkommen eliminieren repeat with i from 1 to count of allPrices set curPrice to item i of my allPrices if curPrice is not in defList then set end of defList to curPrice end if end repeat -- Wiederholungsschleife durch die Elemente der Liste repeat with i from 1 to count of defList set curPrice to item i of my defList -- das Komma entfernen, aber nur wenn der Preis Cents-Stellen enthält if curPrice contains ",-" then set oldPrice to curPrice else set oldPrice to change "," into "" in curPrice end if -- den Handler aufrufen, welcher den neuen Preis ermittelt set newPrice to my getNewPrice(oldPrice) -- wenn es geklappt hat ... if newPrice is not "" then -- im neuen Preis falls notwendig das Komma einfügen if newPrice contains "," then set defPrice to newPrice else set defPrice to change "([0-9]+)([0-9][0-9])" into "\\1,\\2" in newPrice with regexp end if -- in der gesamten Textkette den Wechsel vornehmen set newString to change curPrice into defPrice in newString else -- ... wenn nicht, den alten Preis mit Magenta-Tag versehen set notFoundPrice to "<cM>" & curPrice & "<c$>" set newString to change curPrice into notFoundPrice in newString end if end repeat end if -- ... und die neue Textkette zurückschicken return newString end modNumChangePrice --- Das komplette Script ist unterwegs zu Dir.
Erste Tests: Sensationell!!!! Ich bin tief beeindruckt. Es funktioniert problemlos. (Mal abgesehen davon, das QXP manchmal "CU" sagt :evil: Is halt nicht so wirklich stabil)
Die Abstürze von XPress sind ärgerlich. Aber das Script verlangt ja auch viel ...
Vielleicht bringt es etwas, wenn nicht der unsichtbare "Temporary Folder" als Zielordner für das Schreiben und Lesen der XPress-Tags-Dateien verwendet wird. Ersetze bitte mal oben im Script diese Zeilen ... --- -- der Pfad zum Temporär-Ordner wird gespeichert set tmpFolder to (path to temporary items) as string set tempFilePath to tmpFolder & "TempScratchFile.xtg" -- der Pfad zum Ordner des eingeloggten Users wird gespeichert set tmpFolder to (path to "cusr") as string set tempFilePath to tmpFolder & "TempScratchFile.xtg" ---
Wichtig: Nach jedem Crash zuerst (vor dem Neustart von XPress) den QuarkXPress-Programm- Ordner öffnen und eine eventuell vorhandene, temporäre XPress-Datei entfernen. Normalerweise hat XPress Zeit, aufzuräumen. Es kommt aber vor, dass eine Datei liegenbleibt. Und wenn diese beim Crash beschädigt worden ist, dann sind weitere Abstürze programmiert.
Es kann auch etwas bringen, nichtverwendete XTensions in den Ordner "XTension Disabled" zu verschieben (z.B. "Index.xnt", "Kern-Track Editor.xnt" usw.).
Und von Zeit zu Zeit sollte man den "Preferences"-Ordner durch eine frische Kopie aus dem Backup ersetzen.
Zwei andere Probleme haben sich noch ergeben: Die Stilvorlage für den Preis ist Blockweise mal anders. Ich brauch doch dann nur: try -- der String 'Preis>' ist ein Teil des Zeichenstilvorlagen-Namens im XPress-Tags-Format und -- dient als "Anker" um die nachfolgende Ziffernfolge als Preis zu identifizieren -- die Fragezeichen im Suchmuster bedeuten, dass sowohl "19,99" als auch "19,-" gefunden wird -- 'using "\\2"' heisst, dass nur die zweite Gruppe des Suchmusters in die Liste aufgenommen wird -- mit 'all occurrences and string result' erhält man die Strings aller Vorkommen set allPrices to (find text "(Preis>)([0-9]+,[0-9]+?-?)" in aString using "\\2" with regexp, all occurrences and string result) end try
Die Stilvorlage dort abzuändern, nicht wahr??
Ein zweites Problem ist, dass ich in einigen Fällen nicht den Hauptrahmen als als Auswahl erhalte, sondern irgendeinen Textrahmen. Diesbzgl. exprimentier ich mal mit der Anzahl der Zeichen, die als Indikator dient. Wenn es allerdings klappt, werden die Daten des Hauptrahmens nicht mehr in den ursprünglichen Rahmen zurückgeschrieben, sondern in irgendeinen anderen Rahmen und dieser Inhalt wird dann ersetzt. Diesbzgl. hab ich keine Idee, wo ich da ansetzen könnte.
ja, die Zeichenstilvorlage – welche hoffentlich jedem Preis der Haupttextbox zugewiesen wurde – erscheint ja in der XPress-Tags-Datei als, z.B. <@Preis>. Die beiden Zeichen "<@" habe ich absichtlich weggelassen, weil auch das "@" ein Metazeichen ist.
Dieses Stück Stilvorlagen-Name als Anker zu gebrauchen ist notwendig, weil sonst auch für die Grössen wie "Größe 34,36,38" ein Preis gesucht würde und – weil nicht vorhanden – würden zwei davon Magenta eingefärbt ...
Zum zweiten Problem: Verstehe ich es richtig, dass die Preise und die Bestellnummern der Haupt- textbox noch nie korrekt ausgetauscht und gekürzt worden sind? Und was geschieht, wenn Du das Projekt verwendest, welches Du mir zugestellt hast?
Würdest Du mir bitte ein Projekt zustellen, mit welchem das Resultat so ist, wie Du beschreibst?
Hallo Hans, Ich hab jetzt folgenden Stand: Im Prinzip funktionert das Austauschen. Der Haupttextrahmen wird auch erkannt, der Inhalt des Haupttextrahmens erscheint aber nach dem Ändern 2 mal. Einmal im Haupttextrahmen, aber unverändert und einmal in einem anderen Rahmen. (Zum Beispiel in einem kleinen Rahmen, in dem die Farbe nochmal am Bild steht. scheinbar willkürlich)
Ich schau mir das nochmal genauer an, wie das funktioniert nach dem Tauschen.
Das andere Problem liegt an Ausnahmen bzgl. der Textlänge nicht produkt relevanter Rahmen (Blabla-Text). Hab ich im Griff.
sende mir doch bitte solch ein Projekt, in welchem diese Verdoppelung geschieht. Mit etwas Glück kann ich es dann nachvollziehen. Und hoffentlich die Ursache herausfinden und Gegenmassnahmen treffen.
Morgen Samstag werde ich den ganzen Tag abwesend sein. Am Sonntag werde ich voraussichtlich erst gegen Abend wieder erreichbar sein.
Hallo Hans, In dem Musterdokument passiert inzwischen bei mir das gleiche. Bitte prüf mal, wo die Daten des Hauptrahmens hin geschrieben werden. Bei mir ist es der kleine Rahmen am unteren Ende der Spalte, in der auch der Hauptrahmen steht. Da werden dann die geänderten Hauptrahmendaten hineinkopiert.
danke für das Zusenden der Dateien. Wäre eigentlich nicht notwendig gewesen, denn der Fehler lag bei mir ... Genauer gesagt, im Handler, welcher den modifizierten Text wieder importiert, hatte ich in der Eile vergessen, den Bezug zur Seite einzubauen.
Bitte entschuldige meine Nachlässigkeit. Das korrigierte Script (NummernPreiseAendern_02d) ist unterwegs. Jetzt sollten in der Hauptbox die Bestellnummern gekürzt und die Preise ausgetauscht werden.
Wenn mir das nicht noch a bissl zu undurchsichtig wäre, hätte ich vielleicht selbst drauf kommen können. Bin heilfroh, dass DU da was machen konntest.
Hab übrigends bei dem Teil, der den Tausch der kleinen Textrahmen behandelt, noch geringfügig verändert, damit die Trefferquote höher liegt (Falls diese Boxen mit ner Zahl beginnen, von"1" auf "2" erhöht); Hab's rot markiert: -- eine Wiederholungsschleife durch die Textketten repeat with i from 1 to count of text boxes tell text box i set boxNum to i -- der Variablen 'storyOne' die aktuelle Textkette zuweisen set {storyOne, cents} to do script {getStory} if storyOne is not "" then -- den zu ändernden Preis, dessen Position und Länge feststellen if cents then set someDigits to (find text "[0-9]{2,6}" in storyOne with regexp) else set someDigits to (find text "[0-9]{2,4},-" in storyOne with regexp) end if -- der Variablen 'oldPrice' den alten Preis zuweisen set oldPrice to matchResult of someDigits -- den Handler aufrufen, welcher den neuen Preis zurückgibt set newPrice to my getNewPrice(oldPrice) -- wenn es geklappt hat ... if newPrice is not "" then -- der Variablen 'x1' die Position ... set x1 to (matchPos of someDigits) -- ... und 'x2' die Länge zuweisen set x2 to (matchLen of someDigits) do script {changePrice} else set properties to {color:"Magenta", shade:50} end if end if end tell end repeat
Merci für Deine Hilfe! Die Kommentare helfen mir auch sehr viel weiter, das ganze in für mich erkennbare Sinnblöcke zu bekommen und den Ablauf zu verstehen.
aufgepasst! Mit Deiner Massnahme wird die Trefferquote nicht erhöht. Im Gegenteil ...
Im Suchmuster "[0-9]{1,4},-" steht die Ziffer '1' nicht für die Position (= Offset) des Preises, sondern für die Mindestanzahl Stellen. Mit "{2,4},-" werden Preise von minimal 10,- und maximal 9999,- gefunden. Wenn einstellige Eurobeträge nie vorkommen: okay. Sonst schleunigst wieder den alten Zustand herstellen.
Wenn Du vermeiden möchtest, dass das Script gebremst wird, weil es sich auch um Zahlen zu Beginn der Story (= Position 0) kümmert, dann könnte man im Script-Objekt 'getStory' der Variablen 'storyOne' die Zeichen 2 bis zum letzten der 'story 1' zuweisen. Aber dann müsste man die Positionswerte um Zeichen verschieben, sonst würde die Ersetzung verschoben vorgenommen werden.
Bitte teile mir mit, ob es wünschenswert ist, dass das erste Zeichen in einer Box ausgeschlossen wird. Ich werde dann das Script entsprechend ändern.
Hingegen könnte man die Werte im Teil des Tests, welcher die Euro+Cents-Beträge auszieht, die Vorgabe auf {3,6} ändern. Dadurch würden immer noch Preise von minimal 111 (= Euro 1,11) und 999999 (= Euro 9999,99) berücksichtigt. Mit anderen Worten: Das Ergebnis wird dasselbe sein, weil nur Stories zurückgegeben werden, welche mindestens drei Ziffern in Folge enthalten. --- -- den zu ändernden Preis, dessen Position und Länge feststellen if cents then set someDigits to (find text "[0-9]{3,6}" in storyOne with regexp) else set someDigits to (find text "[0-9]{1,4},-" in storyOne with regexp) end if ---
Hallo Hans, sorry, dass ich mich jetzt erst melde.
Zum ersten: Mir ist aufgefallen, dass Preise nicht erkannt wurden, wenn eine Positionsnummer im kleinen Textrahmen steht. Mit "Positionsnummer" meine ich die Artikelposition auf der Seite. Nachdem ich das wie beschrieben geändert habe, hat es funktioniert.
Es kann natürlich schon vorkommen, dass einstellige Preise auftauchen. Das kann ich nicht ausschließen. Insofern wäre es natürlich sicherer, wenn das auch berücksichtig würde.
Die Änderung mache ich wieder rückgängig und ändere den ersten Wert in "3".
Zum zweiten Posting: Wäre Super, wenn das bis einschl. 4-Stellig funktionieren würde. Selbst bei nem Angelkatalog oder auch Werkzeugkatalog gibt es Zubehör, das bis zu 4-stellig sein kann. Wenn dann z.B. noch in eine andere nicht-Euro Währung geändert werden muss, kommen 1.000er Preis durchaus vor, mehr aber eigentlich nicht.
Es kommt sogar manchmal vor, dass in einem kleinen Textrahmen Preis und Produktnummer stehen (z.B. bei Accessoires, die nicht nochmal im Haupttextrahmen auftauchen.
Da das Script aber dann das Feld in Magenta hinterlegt, ist das kein Problem und wird einfach manuell geändert.
Ob mehrere Preise vorkommen können, kann ich gar nicht sagen, da wir teilweise nur Seiten zuliefern und die unterschiedlichsten Sachen für die diversen Kunden machen. Wir haben bei den aktuellen Produktionen noch nicht alle Seiten erhalten. Wenn ich mehr weiss, schrieb ich Dir.
das Problem wegen der Positionsnummer kann ich nicht nachvollziehen. Da wäre ich sehr dankbar für ein entsprechendes XPress-Projekt.
Die einstelligen Preise werden berücksichtigt wenn der Zusatz bei den Cents {3,6} lautet und bei den ganzen Beträgen {1,4}.
Damit letztere auch drei- und vierstellig erkannt werden, habe ich nun im Script-Objekt 'getStory' die Reihenfolge geändert. Jetzt wird zuerst geprüft, ob mindestens eine Zahl gefolgt von Komma und Bindestrich vorkommen.
Wenn die Produktenummer vor einem Preis mit Cents in einer kleinen Box steht, dann wird letzterer nicht geändert. Aber bei einem ganzzahligen Preis sollte dieser gefunden werden. Doch in allen Fällen wird die Produktenummer nicht gekürzt. Müsste ich noch einbauen, falls gewünscht.
Dasselbe gilt für die Möglichkeit, dass zwei Preise in einer kleinen Box vorkommen.
Ich werde Dir gleich die Version 03 des Scripts zustellen, in welcher schon mal das hier im dritten Absatz angekündigte Verhalten eingebaut ist.
Hallo Hans, mit der Änderung funktioniert es ja auch. Das war "bevor" das geändert war.
Es sind sicherlich immer wieder mal Sonderfälle, aber man kann schließlich nicht alles "automatisieren".
Wir versuchen jetzt mal weiter mit der Version. Ich persönlich finde das Teil "geil"!! Den Rest soll der Lektor machen. Das kann nicht mehr viel sein. Wir haben manchmal Bildtexte MIT KBNR + Kurztext + Preis und das wiederum in unterschiedlichen Reihenfolgen. Manchmal stimmen auch formatierungen nicht 100%. Darüber mach ich mir jetzt keine Sorgen mehr.
Vielen, vielen Dank, Hans! (Da schwingt gehöriger Respekt mit!)