wurde die Frage aufgeworfen, wie man möglichst schnell feststellen kann, ob ein Asset mit einem bestimmten Namen in einer Library bereits existiert, und wenn ja, soll ein neuer, eindeutiger Name mit angehängter Nummer erzeugt werden.
Die bisher benutzte Lösung sah so aus:
Code: Alles auswählen
counter=0;
var Templatename_full = Templatename;
do
{
counter+=1
Templatename_full = Templatename+" "+counter
var Templatename_vorhanden = lib_prod.assets.itemByName(Templatename_full).isValid
}
while (Templatename_vorhanden == true);
Code: Alles auswählen
lib_prod.assets.itemByName(Templatename_full).isValid
Um die Problematik des Fragestellers nachstellen zu können erstelle ich mir im ersten Schritt eine Library mit 260 Einträgen, deren Namen sich aus einem Buchstaben und einer vierstelligen laufenden Nummer ergibt, z. B:
a0000,a0001... z0009
Der zugehörige Programmcode sieht so aus:
Code: Alles auswählen
String.prototype.fill = function(number){var filled ="";for (var i=0;i<number;++i){filled += this;}return filled;}
String.prototype.padLeft = function(fillc, length)
{if (this.length<length){return (fillc.fill(length-this.length)+this).substr(-length);}return this;}
main();
function main()
{
app.doScript(createLib,ScriptLanguage.JAVASCRIPT,undefined, UndoModes.AUTO_UNDO);
}
function createLib()
{
var lib = app.libraries.add("C:/Dokumente und Einstellungen/Administrator/Eigene Dateien/Indesign SkriptTests/library/test.indl");
var chars = "abcdefghijklmnopqrstuvwxyz";
var startTime = new Date().getTime();
for (i=0;i<chars.length;i++)
{
for (j=0;j<10;j++)
{
var asset = lib.store(app.activeDocument.pageItems[0]);
asset.name = chars[i]+(j.toString()).padLeft("0",4);
}
}
lib.close();
var neededTime = getUsedTime(startTime);
alert(neededTime);
}
function getUsedTime(startTime)
{
var neededTime = new Date().getTime()-startTime;
neededTime = new Date().setTime(neededTime);
var seconds = neededTime/1000;
var minutes = 0;
var hours = 0;
if (seconds>60)
{
minutes = Math.floor(seconds/60);
seconds = seconds-minutes*60;
if (minutes>60)
{
hours = Math.floor(minutes/24);
minutes = minutes-hours*60
}
}
return [hours, minutes, seconds];
}
Code: Alles auswählen
String.prototype.fill = function(number){var filled ="";for (var i=0;i<number;++i){filled += this;}return filled;}
String.prototype.padLeft = function(fillc, length)
{if (this.length<length){return (fillc.fill(length-this.length)+this).substr(-length);}return this;}
main();
function main()
{
// app.doScript(createLib,ScriptLanguage.JAVASCRIPT,undefined, UndoModes.AUTO_UNDO);
app.doScript(store2Array,ScriptLanguage.JAVASCRIPT,undefined, UndoModes.AUTO_UNDO);
}
function store2Array()
{
var lib = app.open("C:/Dokumente und Einstellungen/Administrator/Eigene Dateien/Indesign SkriptTests/library/test.indl");
var startTime = new Date().getTime();
var allAssets = new Array();
for (i=0;i<lib.assets.length;i++)
{
allAssets.push({commonName: lib.assets[i].name.substr(0,1), fullName: lib.assets[i].name});
}
allAssets = allAssets.sort(sortElements);
Code: Alles auswählen
if (allAssets.length>1)
{
var assetNames = new Array();
var assetOneName = {commonName: allAssets[0].commonName, subAssets: [{name: allAssets[0].fullName}]};
for (i=1;i<allAssets.length;i++)
{
var subAsset = {name: allAssets[i].fullName};
if (allAssets[i].commonName == allAssets[i-1].commonName)
assetOneName.subAssets.push(subAsset);
else
{
assetNames.push(assetOneName);
assetOneName = {commonName: allAssets[i].commonName, subAssets: [subAsset]};
}
}
if (assetNames.length > 0)
{
if (assetNames[assetNames.length-1].commonName != assetOneName.commonName)
{
assetNames.push(assetOneName);
}
}
}
var neededTime = getUsedTime(startTime);
alert(neededTime);
Das Erstellen der Arrays ist bei größeren Libraries ein einmaliger Zeitaufwand, der bei einer weiteren Optimierungsstufe komplett in eine eigene Datei ausgelagert werden könnte, um nicht bei jeden Skriptstart erneut ausgeführt werden zu müssen.
Die Routine getNewNameFromArray(assetNames, "z") führt jetzt die Suche nach einem Eintrag für den Buchstaben "z" aus, ermittelt die Anzahl der "z"-Einträge und erzeugt einen neuen Dateinamen:
Code: Alles auswählen
var startTime = new Date().getTime();
var newName = getNewNameFromArray(assetNames, "z");
var neededTime = getUsedTime(startTime);
alert(neededTime);
Die zugehörige Funktion:
Code: Alles auswählen
function getNewNameFromArray(groupedAssets, name)
{
for (var i=0; i<groupedAssets.length;i++)
{
if (groupedAssets[i].commonName==name)
{
// found!
// construct new name
var newName = name+(groupedAssets[i].subAssets.length+1).toString().padLeft("0",4);
groupedAssets.push({name: newName});
return newName;
}
}
var newName = name+("1").padLeft("0",4);
groupedAssets.push({commonName: name, subAssets: [{name: newName}]});
return newName;
}
var startTime = new Date().getTime();
var newName = getNewNameFromLib(lib, "z");
var neededTime = getUsedTime(startTime);
alert(neededTime);
Die zugehörige Funktion:
Code: Alles auswählen
function getNewNameFromLib(lib, name)
{
var counter=0; var newName = "";
do
{
++counter;
newName = name+((++counter).toString()).padLeft("0",4);
}
while (lib.assets.itemByName(newName).isValid);
return newName;
}
Das vollständige Skript gibt's hier:
libTest.zip
Zum Schluss eine Gegenüberstellung der Zeiten,
260 Einträge:
2600 Einträge: