hilfdirselbst.ch
Facebook Twitter gamper-media
« « 1 2 » »  
MatzeHH
Beiträge: 3
31. Mai 2012, 09:28
Beitrag #1 von 16
Bewertung:
(9037 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo,

ich habe ein Script geschrieben, das auf allen Seiten im aktuellen Dokument bei allen Objekten mit dem Scriptetikett "Hintergrund" den Inhalt an Rahmen anpasst.

Code
main(); 
function main(){
for(var myCountern = 0; myCountern < app.activeDocument.pages.length; myCountern++)
{
myPage = app.activeDocument.pages.item(myCountern);

meinObjekt = myPage.pageItems.item('Hintergrund');
if (meinObjekt != null)
{
meinObjekt.fit(FitOptions.contentToFrame); // Inhalt an Rahmen anpassen
}
}
}


Unter InDesign CS4 hat es problemlos funktioniert.

Mit CS5.5 geht es nicht mehr.
Im ExtendedScript Toolkit wird diese Zeile rot markiert:
Code
for(var myCountern = 0; myCountern < app.activeDocument.pages.length; myCountern++) 

In der Statuszeile unten steht nur "undefined ist kein Objekt".

Wo liegt der Fehler? Ich vermute, dass es am Auslesen der Seitenanzahl liegt. Aber wie kann ich das beheben?

MfG, Matthias Top
 
X
-hans-
Beiträge: 737
31. Mai 2012, 10:06
Beitrag #2 von 16
Beitrag ID: #495817
Bewertung:
(9016 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hi,

liest sich als hättest Du das Script im ESTK ausgeführt und target war nicht InDesign. Wenn #target InDesign am Scriptanfang steht wird der Target automatisch gesetzt.
Zitat Hallo,

ich habe ein Script geschrieben, das auf allen Seiten im aktuellen Dokument bei allen Objekten mit dem Scriptetikett "Hintergrund" den Inhalt an Rahmen anpasst.


Ein Scriptetikett == label kannst Du nicht direkt ansprechen.
Sicherlich ist 'name' (Name des Objektes in der Ebenenpalette) gemeint.
Lieben Gruß

Hans-Gerd Claßen
als Antwort auf: [#495815] Top
 
Martin Fischer  M  p
Beiträge: 11867
31. Mai 2012, 10:12
Beitrag #3 von 16
Beitrag ID: #495818
Bewertung:
(9010 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Matthias,

das Problem liegt vermutlich nicht an der Schleife.
Diesbezüglich hat sich in CS5.5 gegenüber CS4 nichts geändert.

Geändert hat sich aber etwas in der Adressierung von pageItems.

Bis CS4 war der Name eines pageItems quasi synonym mit dem label (Skriptetikett).

Ab CS5 gibt es eine neue pageItem-Eigenschaft 'name' (sichtbar in der Ebenen-Palette), die sich vom 'label' unterscheidet.

Lösung
Siehe den Beitrag von Hans mit den dort empfohlenen Lösungen: CS4-Script funktioniert nicht in CS5. Hilfe.

Weitere Hinweise: Textrahmen mit Skriptetiketten in InDesign CS5 verschieben.

Viele Grüße
Martin
als Antwort auf: [#495815]
(Dieser Beitrag wurde von Martin Fischer am 31. Mai 2012, 10:15 geändert)
Top
 
MatzeHH
Beiträge: 3
31. Mai 2012, 11:36
Beitrag #4 von 16
Beitrag ID: #495828
Bewertung:
(8968 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo,

danke für eure Antworten.
#target InDesign am Anfang hilft schonmal etwas, jetzt werden richtige Fehlermeldungen ausgegeben.

Das umschreiben der Bezeichnungen von Label zu Name funktioniert auch.

Mein Script zum Anpassen des Hintergrundes sieht jetzt so aus:
Code
var curDoc = app.activeDocument; 

var allItems = curDoc.pageItems;
var nItems = allItems.length;

for (var i=0; i<nItems; i++) {

myPage = app.activeDocument.pages.item(i);

meinObjekt = myPage.pageItems.ItemByName("Hintergrund");
if (meinObjekt != null)
{
meinObjekt.fit(FitOptions.contentToFrame); // Inhalt an Rahmen anpassen
}
}


Dabei wird die Zeile
Code
        meinObjekt = myPage.pageItems.ItemByName("Hintergrund"); 

angemeckert, mit der Begründung: "Fehlerzeichenfolge: myPage.pageItems.ItemByName ist keine Funktion"
Nur "name" statt "ItemByName" funktioniert auch nicht. Wie kann ich die Objekte mit dem Namen "Hintergrund" ansprechen?

MfG, Matthias
als Antwort auf: [#495818] Top
 
WernerPerplies
Beiträge: 2211
31. Mai 2012, 11:52
Beitrag #5 von 16
Beitrag ID: #495830
Bewertung:
(8957 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hi,

Zitat meinObjekt = myPage.pageItems.ItemByName("Hintergrund");


müsste es nicht
Code
meinObjekt = myPage.pageItems.itemByName("Hintergrund"); 

heißen?

Also statt ItemByName -> itemByName.

Einen schönen Tag wünscht

Werner Perplies
Auftragsprogrammierung und Skripte für Adobe InDesign
neu: WpsProjectHandler 15.06.2018, Version 1.75, neue Funktionen
Aktuelles
XING
als Antwort auf: [#495828] Top
 
MatzeHH
Beiträge: 3
31. Mai 2012, 13:36
Beitrag #6 von 16
Beitrag ID: #495834
Bewertung:
(8913 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Werner,

klar, das i muss klein geschrieben werden...
Allerdings wird es dann nur für ein Objekt auf einer Seite (merkwürdigerweise Seite 5 von 7) angewendet. (Vermutlich, weil das das erste Objekt in der Ebenenansicht ist.)

Ich habe es jetzt ganz anders gelöst, ohne alle Seiten manuell durchzulaufen:
Code
var allItems = app.activeDocument.allPageItems; 

for (var i=0; i<allItems.length; i++) {
if (allItems[i].label == "Hintergrund") {
allItems[i].fit(FitOptions.contentToFrame);
}
}


Vielen Dank für eure schnelle Hilfe!

MfG, Matthias
als Antwort auf: [#495830] Top
 
WernerPerplies
Beiträge: 2211
31. Mai 2012, 13:43
Beitrag #7 von 16
Beitrag ID: #495836
Bewertung:
(8907 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Matthias,

auch für eine Seite gibt es die Eigenschaft AllPageItems

Einen schönen Tag wünscht

Werner Perplies
Auftragsprogrammierung und Skripte für Adobe InDesign
neu: WpsProjectHandler 15.06.2018, Version 1.75, neue Funktionen
Aktuelles
XING
als Antwort auf: [#495834] Top
 
Martin Fischer  M  p
Beiträge: 11867
31. Mai 2012, 14:07
Beitrag #8 von 16
Beitrag ID: #495837
Bewertung:
(8883 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Matthias,

wenn es auf einer Seite mehrere Objekte mit dem Namen 'Hintergrund' gibt, dann liefert Deine Code-Zeile meinObjekt = myPage.pageItems.itemByName("Hintergrund"); ein Array mit allen Objekten, die 'Hintergrund' heißen.

Statt eine Fehlermeldung auszugeben, pickt sich InDesign bei der Weiterverarbeitung vermutlich jeweils nur das erste Element heraus und lässt die anderen außen vor.
Du solltest also beim Zugriff auf meinObjekt eine Schleife durch die Elemente des Arrays einrichten.
Dann sollte es so gehen.

Die einfachere Lösung hast Du bereits selbst gefunden: sprich die Objekte nicht bei ihren Namen an, sondern frage jeweils den Inhalt des Skriptetiketts ab.

Viele Grüße
Martin
als Antwort auf: [#495834]
(Dieser Beitrag wurde von Martin Fischer am 31. Mai 2012, 14:08 geändert)
Top
 
Hans Haesler  M  p
Beiträge: 5590
31. Mai 2012, 14:49
Beitrag #9 von 16
Beitrag ID: #495845
Bewertung:
(8853 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Martin,

das mit dem Array war einmal ... Mit den Etiketten bis und mit CS4. Ab CS5 wird von mehreren gleichnamigen nur noch ein Objekt gefunden.

Ausprobieren: Ein neues CS5.5-Dokument, eine Seite, einen Bildrahmen aufziehen, im Ebenenbedienfeld mit "Hintergrund" benennen. Zwei Mal duplizieren.

Jetzt enthält die Seite 1 drei Bildrahmen namens "Hintergrund". Nun dieses Snippet ausführen:

Code
var myPage = app.documents[0].pages[0]; 
var meinObjekt = myPage.pageItems.itemByName("Hintergrund");
alert (meinObjekt);
app.select(meinObjekt);

Der alert sagt: "[object PageItem]" und nach Klick auf "OK" wird nur ein Objekt ausgewählt.

Gruss, Hans
als Antwort auf: [#495837] Top
 
Martin Fischer  M  p
Beiträge: 11867
31. Mai 2012, 15:22
Beitrag #10 von 16
Beitrag ID: #495848
Bewertung:
(8831 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Hans,

das kommt davon, dass man blind was behauptet und dieser Behauptung ungeprüft Glauben schenkt, weil sie eine so einfache Erklärung böte ...


Antwort auf: das mit dem Array war einmal ... Mit den Etiketten bis und mit CS4. Ab CS5 wird von mehreren gleichnamigen nur noch ein Objekt gefunden.

Du hast leider recht.
Das bestätigt auch ein Blick auf die Belegung der Variable meinObjekt im Objektbrowser des ESTK.
Und darüber bin ich leicht entsetzt.

Denn dann eignet sich die 'schnelle' itemByName-Methode zur Ermittlung von mehreren Seitenobjekten auf einer Seite wohl nicht mehr. Dann ist es besser, man prüft alle Seitenobjekte in einer Schleife auf ein bestimmtes Kriterium (name oder label) und filtert so die gesuchten Seitenobjekte für sich heraus.

Offen gesagt enttäuscht mich die in CS5 eingeführte name-property damit noch mehr als sie es getan hat, nachdem ich seinerzeit feststellen musste, dass mir damit eine ebenso einfache wie schnelle, zur Gewohnheit gewordene Methode zur Adressierung bestimmter – per Skriptetikett mit Namen versehener – Seitenobjekte genommen wurde.

Vielleicht finden sich gelegentlich aber auch noch Vorteile dieser name-Property. Unimpressed

Viele Grüße
Martin
als Antwort auf: [#495845]
(Dieser Beitrag wurde von Martin Fischer am 31. Mai 2012, 15:24 geändert)
Top
 
Hans Haesler  M  p
Beiträge: 5590
31. Mai 2012, 22:28
Beitrag #11 von 16
Beitrag ID: #495864
Bewertung:
(8776 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Martin,

Zitat Und darüber bin ich leicht entsetzt.

Also ... darüber war ich schwer entsetzt gewesen, als ich dieses Elend entdeckt hatte.

Mit CS2 konnte man mit ...

Code
var rubFrameList = app.activeDocument.textFrames.item("rubrique").getElements(); 

... einen Array der Textrahmen bekommen, welche mit "rubrique" gelabelt waren. Dann eine Schleife durch diese Liste, um jedem Element den entsprechenden deutschen Inhalt zuzuweisen.

Ein anderes Beispiel. Ein Script erzeugt die schwarzen Quadrate eines Kreuzworträtsels überall dort wo ein Dollar-Zeichen (statt eines Buchstabens) steht. Damit diese Rahmen bei einem erneuten Start des Scripts abgeräumt werden, sind sie mit "black_frame" benannt. Zum Entfernen aller Rahmen genügte der Befehl:

Code
app.activeWindow.activeSpread.pageItems.item("black_frame").remove(); 

Ab CS5 müssen die schwarzen Quadrate einzeln begrüsst und entfernt werden.

Gruss, Hans
als Antwort auf: [#495848] Top
 
Gerald Singelmann  M  p
Beiträge: 6178
1. Jun 2012, 00:15
Beitrag #12 von 16
Beitrag ID: #495867
Bewertung: |
(8751 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Na, wenn zwei ausgesprochen kompetente Scripter extrem entsetzt sind, werde ich ja schon neugierig.

Erster Versuch: könnte man nicht stattdessen itemByRange nehmen?
Antwort: Im Prinzip ja, aber da dürfen auch keine gleichnamigen Objekte vorkommen. Genauer: von den gleichnamigen wird nur das erste gefunden.
Was ginge, wenn die entsprechenden Objekte Script-erzeugt sind: einen Namen mit Timestamp erzeugen. Man hat dann also nicht Objekte "rubrique" sondern "rubrique123456789".
Aber das ist nicht ansatzweise hübsch genug, um den Ansatz hier weiter zu verfolgen.
Trotzdem sinnvoll zu wissen, dass xxx.itemByRange("frame1", "frame999") wie gehabt tausend Objekte greift, unter der Voraussetzung, dass "frame1" und "frame999" tatsächlich vorhanden sind.

Zweite Frage: Ist es wirklich so punishing (Gibt es da ein vernünftiges deutsches Wort für?), wenn man seine eigene itemsByLabel Funktion schreibt?

Skizze zum selber weiterschreiben:
Code
#target indesign 

Document.prototype.pageItemsByLabel = function(label) { // Liefert ein Array zurück
var pi = this.pageItems.firstItem();
var wanted = new Array();
do {
if (pi.label == label) wanted.push( pi );
pi = this.pageItems.nextItem( pi );
} while (pi.isValid)
return wanted
}

Document.prototype.manyPageItemsByLabel = function(label) { // Liefert ein Array zurück
var pis = this.pageItems.everyItem().getElements();
var wanted = new Array();
for (var n = 0; n < pis.length; n++) {
if (pis[n].label == label) wanted.push( pis[n] );
}
return wanted
}

main();

function main() {
var doc = app.activeDocument;
var first = new Date().getTime();
var them = doc.manyPageItemsByLabel("kreis");
var later = new Date().getTime();
// app.select( them );
alert( (Math.round((later-first) / 100) / 10) + " Sekunden");
}


Die Funktion "pageItemsByLabel" ist eine Studie in "Wie man es nicht machen sollte".

Die Funktion "manyPageItemsByLabel" hingegen liefert mir bei einem Dokument mit rund 2000 pageItems, von denen jedes zweite das gewünschte Label hat, ein Array in weniger als zwei Zehntel Sekunden zurück.

Ich persönlich kann mit der Performance leben...
--------------------------

InDesign-Wissen und Automatisierung nicht nur rund um die Suite.

http://www.cuppascript.com
als Antwort auf: [#495864] Top
 
Martin Fischer  M  p
Beiträge: 11867
1. Jun 2012, 07:41
Beitrag #13 von 16
Beitrag ID: #495868
Bewertung:
(8711 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Ja, so kann man das mit Einführung der name-Property entstandene Defizit umschiffen.

Eine elegante Lösung und ein schönes Beispiel eines Prototypen.

Viele Grüße
Martin
als Antwort auf: [#495867] Top
 
Hans Haesler  M  p
Beiträge: 5590
1. Jun 2012, 08:00
Beitrag #14 von 16
Beitrag ID: #495869
Bewertung:
(8703 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Gerald,

ich bedanke mich für die Skizze.

Der Unterschied der Performance ist in der Tat gewaltig.
Schon nur mit 28 Kreisen: 2.2 Sekunden vs. 0 Sekunden.

Ein deutsches Wort für "punishing"? Eine Auswahl gibt es hier:
http://www.dict.cc/...utsch/punishing.html

Gruss, Hans
als Antwort auf: [#495867] Top
 
WernerPerplies
Beiträge: 2211
1. Jun 2012, 15:31
Beitrag #15 von 16
Beitrag ID: #495896
Bewertung:
(8609 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

CS5.5: Seitenanzahl herausfinden


Hallo Herr Singelmann,

nachdem ich bei meinen Hyperlink-Lösungen gerne den Durchsatz etwas steigern würde, war ich über Ihren Lösungsansatz ganz begeistert und habe Ihr Beispiel auf
hyperlinkPageItemSources
übertragen.

Meine beiden Routinen sehen so aus:

Die ursprüngliche Lösung:

Code
        /*pageItemSource*/function existThisPageitemSourceAlready(id) 
{
try
{
var l = document.hyperlinkPageItemSources.length;
var piss = document.hyperlinkPageItemSources;
for (var i = 0; i<l; i++)
{
if (piss[i].sourcePageItem.id == pi.id) return piss[i];
}
}
catch (error)
{

gO.myError.doError(error, arguments, $.stack, -1, false, true);
}
return null;
}


Die von nach Ihrem Vorschlag modifizierte Lösung:
Code
        /*pageItemSource*/function existThisPageitemSourceAlready(id) 
{
try
{
var pis = document.hyperlinkPageItemSources.firstItem();
if (pis.isValid)
{
do
{
if (pis.sourcePageItem.id == id) return pis;
pis = document.hyperlinkPageItemSources.nextItem( pis );
} while (pis.isValid)
}
}
catch (error)
{
gO.myError.doError(error, arguments, $.stack, -1, false, true);
}
return null;
}


Der Geschwindigkeitsunterschied ist gewaltig, nur leider ganz anders als von mir erwartet:

Bei 232 Aufrufen benötigt die zweite Lösung die sechzigfache Zeit!

Dabei fällt mir auf, dass der Vorgang vermutlich, warum auch immer, sehr speicherintensiv zu sein scheint, weil einige Durchgänge recht schnell ablaufen, dann eine längere Pause eintritt (garbage collector?) und danach geht es wieder für einige Durchläufe recht schnell ....

Bei der ersten Routine laufen die Aufrufe ganz gleichmäßig ab.

Einen schönen Tag wünscht

Werner Perplies
Auftragsprogrammierung und Skripte für Adobe InDesign
neu: WpsProjectHandler 15.06.2018, Version 1.75, neue Funktionen
Aktuelles
XING
als Antwort auf: [#495867] Top
 
« « 1 2 » »  
X