[GastForen Programme Print/Bildbearbeitung Adobe InDesign Skriptwerkstatt in Tabelle Zeilen und Spalten vertauschen

  • Suche
  • Hilfe
  • Lesezeichen
  • Benutzerliste
Print/Bildbearbeitung - Photos, Layout, Design
Themen
Beiträge
Moderatoren
Letzter Beitrag

in Tabelle Zeilen und Spalten vertauschen

drerol74
Beiträge gesamt: 507

11. Dez 2011, 17:16
Beitrag # 1 von 10
Bewertung:
(9770 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Mitlesende,

das folgende Script soll Zeilen und Spalten einer ausgewählten Tabelle vertauschen, sprich die Tabelle invertieren. Es geht dabei wie folgt vor:

1. Zellen der Tabelle in ein Array einlesen
2. Tabellenzeilen und Tabellenspalten vertauschen
3. Zellen samt Inhalt wieder einfügen

Wenn man mit Text und „contents“ arbeitet, funktioniert das auch einwandfrei. Sobald aber „ganze“ Zellen (z. B. inklusive verankerte Objekte) in das Array eingelesen werden sollen, geht’s eben nicht mehr.

Vorher-/Nachher-Bild im Anhang ebenso wie ein Testdokument.

Offensichtlich verlieren die Zellen/Objekte durch die Umgestaltung der Tabelle den ursprünglichen Pfad. Weiß vielleicht jemand, ob sich dieses Problem irgendwie lösen lässt?

Schöne Grüße
Roland

Code
#target InDesign 

if (app.scriptPreferences.version >= 6) {
app.doScript(_upsideDown, ScriptLanguage.JAVASCRIPT , [], UndoModes.ENTIRE_SCRIPT, "Tabelle umkehren");
} else {
_upsideDown();
}



function _upsideDown () {

var _dok = app.activeDocument;

if ((app.selection.length > 0) && (_dok.selection[0].constructor.name == "Table")) {


// ausgewaehlte Tabelle bearbeiten
var _table = _dok.selection[0];

var _firstFooterRow = _table.rows.length -_table.footerRowCount;

// Kopfzeilen in Tabellenkoerperzellen umwandeln
for (var h = _table.headerRowCount-1; h >= 0 ; h--) {
if (String(_table.rows.item(h).rowType) == "HEADER_ROW") {
_table.rows.item(h).rowType = RowTypes.BODY_ROW;
}
}

// Fusszeilen in Tabellenkoerperzellen umwandeln
for (var f = _firstFooterRow; f < _table.rows.length; f++) {
if (String(_table.rows.item(f).rowType) == "FOOTER_ROW") {
_table.rows.item(f).rowType = RowTypes.BODY_ROW;
}
}

var _bodyColumnLength = _table.columns.length;
var _firstBodyColumn = 0;
var _lastBodyColumn = _bodyColumnLength -1;

var _bodyRowLength = _table.bodyRowCount;
var _firstBodyRow = _table.headerRowCount;
var _lastBodyRow = _bodyRowLength + _table.headerRowCount - 1;

var _bodyCells = [];
var _bodyCellStyles = [];


// Zellen einlesen
for (var c = _firstBodyColumn; c <= _lastBodyColumn; c++) {
for (var r =_firstBodyRow; r <= _lastBodyRow; r++) {

var _bodyCell = _table.cells.item(c + ":" + r);

_bodyCells.push(_bodyCell);

}
}

var _newBodyColumnLength = _bodyRowLength;
var _newBodyRowLength = _bodyColumnLength;


// Zeilen mit Spalten tauschen
if (_bodyRowLength != _bodyColumnLength) {

// weniger Zeilen als Spalten
if (_bodyRowLength < _bodyColumnLength) {

for (var i = 0; i < (_bodyColumnLength - _bodyRowLength); i++) {
_table.columns.lastItem().remove();
}
for (var i = 0; i < (_bodyColumnLength - _bodyRowLength) ; i++) {
_table.rows.add(LocationOptions.AFTER,_table.rows[_firstBodyRow]);
}

// mehr Zeilen als Spalten
} else {
_table.rows.itemByRange(_bodyColumnLength+_firstBodyRow,_bodyRowLength+_firstBodyRow-1).remove();
for (var i = 0; i < (_bodyRowLength - _bodyColumnLength) ; i++) {
_table.columns.add(LocationOptions.BEFORE,_table.columns[-1]);
}
}
}


// Zelleninhalt neu einsetzen
var _newTable = _dok.selection[0];
var _bci = 0;
var _newLastBodyColumn = _newBodyColumnLength -1;
var _newLastBodyRow = _newBodyRowLength + _table.headerRowCount - 1;

for (var r =_firstBodyRow; r <= _newLastBodyRow; r++) {
for (var c = _firstBodyColumn; c <= _newLastBodyColumn; c++) {

var _newBodyCell = _newTable.cells.item(c + ":" + r);
_newBodyCell = _bodyCells[_bci];

_bci = _bci + 1;

}
}

} else {

alert("Bitte eine Tabelle auswaehlen.");

}
}


Anhang:
vorher.png (24.1 KB)   nachher.png (14.6 KB)   flipTable_complete+anchoredObjects.jsx (3.41 KB)   tabelle_invertieren.idml (31.4 KB)
X

in Tabelle Zeilen und Spalten vertauschen

WernerPerplies
Beiträge gesamt: 2762

12. Dez 2011, 07:02
Beitrag # 2 von 10
Beitrag ID: #486104
Bewertung:
(9728 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Roland,

ich habe jetzt Dein Skript nicht vollständig analysiert, aber ich denke, Du hast schlechte Karten.

Wenn Du die Zellen in einem Array sammelst, sammelst Du eigentlich nicht die Zellen, sondern nur Referenzen auf die Zellen.

Damit wird der Inhalt der Zellen immer verändert, wenn Du die Ursprungszellen änderst.

Die Lösung besteht darin, dass Du echte Kopien der Zellen erzeugen musst, d. h., Du musst alle Referenzen auflösen und mit Werten füllen.

Das sollte eigentlich recht einfach mit einer rekursiven Routine, die eine for-in-Schleife enthält, realisierbar sein.

Ich habe so etwas vor kurzen versucht und eine ganze Reihe von Überraschungen erlebt und dann meine Arbeit an diesem Vorhaben zuerst einmal abgebrochen.

Falls Du keine bessere Lösung findest und weiter machen willst, stelle ich Dir meine bisherige Arbeit in meinem Forum zur Verfügung. Wir können dann da auch die einzelnen, bisher aufgetauchten Probleme diskutieren.

Sofern Du aber nicht die ultimative Zeilen-Spalten-Tauschroutine schreiben willst, solltest Du nur die wirklich benötigten Zelleigenschaften übertragen.

Manche Eigenschaften können/sollten ja auch keinesfalls übertragen werden wie z. B. readOnly-Objekte.

Einen besonderen Augenmerk musst Du auf verbundene Zellen richten, hier ändern sich rows.- , columns.- und cells.length und auch das Übertragen von cell.height und cell.width dürfte überraschend Momente beinhalten die natürlich auf jeden Fall zu vertauschen sind.


als Antwort auf: [#486087]

in Tabelle Zeilen und Spalten vertauschen

Uwe Laubender
Beiträge gesamt: 5316

12. Dez 2011, 09:28
Beitrag # 3 von 10
Beitrag ID: #486107
Bewertung:
(9700 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo, Roland!

Für den EINFACHSTEN Fall, dass Du KEINE VERBUNDENEN Zellen hast und auch sonst nur die GLEICHE Formatierung in allen Zellen UND zudem ohne verankerte Objekte arbeitest, brauchst Du nur den "Contents" von Zeilen und Spalten zu tauschen.

Hier ein Beispiel (Textrahmen mit EINER Tabelle ist angewählt):

Code
//Textrahmen mit NUR EINER Tabelle ist ausgewählt: 

var _tableSource = app.selection[0].tables[0];

var _tableTarget = app.selection[0].insertionPoints[-1].tables.add({
bodyRowCount:_tableSource.columns.length,
columnCount:_tableSource.rows.length
});

for(var n = 0;n<_tableTarget.columns.length ;n++){
_tableTarget.columns[n].contents = _tableSource.rows[n].contents;
};

_tableSource.remove();


Mit Formatierungen und verknüpften Objekten kommt meiner Ansicht nach nur ein Copy/Paste-Szenarium als Lösung in Frage.

Hier ein EINFACHES Beispiel, das voraussetzt, dass KEINE Zelle mit einer anderen verbunden ist:

Code
//Textrahmen mit NUR EINER Tabelle ist ausgewählt: 

var _tableSource = app.selection[0].tables[0];

var _tableTarget = app.selection[0].insertionPoints[-1].tables.add({
bodyRowCount:_tableSource.columns.length,
columnCount:_tableSource.rows.length
});

var _tableSourceRows = _tableSource.rows;
var _tableTargetColumns = _tableTarget.columns;

//Zeilen werden zu Spalten:
for(var r=0;r<_tableSourceRows.length;r++){

//Zelle der Quelle (zeilenweise):
var _cellsTS = _tableSourceRows[r].cells;

//Zelle des Ziels (spaltenweise):
var _cellsTT = _tableTargetColumns[r].cells;


//Die copy/paste-Orgie ;-) :
for(var c=0;c<_cellsTS.length;c++){
app.select(_cellsTS[c]);
app.copy();
app.select(_cellsTT[c]);
app.paste();
};
};

app.select(null);

_tableSource.remove();


Feste Zellenhöhen werden in diesen Beispielen NICHT beachtet.


als Antwort auf: [#486087]
(Dieser Beitrag wurde von Uwe Laubender am 12. Dez 2011, 09:34 geändert)

in Tabelle Zeilen und Spalten vertauschen

drerol74
Beiträge gesamt: 507

12. Dez 2011, 10:15
Beitrag # 4 von 10
Beitrag ID: #486110
Bewertung:
(9678 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Werner,

danke für deine Antwort.

Antwort auf: Die Lösung besteht darin, dass Du echte Kopien der Zellen erzeugen musst, d. h., Du musst alle Referenzen auflösen und mit Werten füllen.


Genau das wollte bei mir einfach nicht funktionieren. Wäre es möglich, hier ein kurzes Beispiel zu posten?


Antwort auf: Sofern Du aber nicht die ultimative Zeilen-Spalten-Tauschroutine schreiben willst, solltest Du nur die wirklich benötigten Zelleigenschaften übertragen.


Die ultimative Lösung soll nicht daraus entstehen ;) es sollte nur die Ursprungstabelle so weit wie möglich erhalten bleiben. Es sind keine verbundenen Zellen vorhanden, nur manchmal eben verankerte Objekte oder Zeichenformate in den Zellen.

Schöne Grüße
Roland


als Antwort auf: [#486104]

in Tabelle Zeilen und Spalten vertauschen

WernerPerplies
Beiträge gesamt: 2762

12. Dez 2011, 10:21
Beitrag # 5 von 10
Beitrag ID: #486113
Bewertung:
(9672 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Roland,

Zitat Genau das wollte bei mir einfach nicht funktionieren. Wäre es möglich, hier ein kurzes Beispiel zu posten?


Nein, leider nicht, wenn es ein kurzes Beispiel gäbe, hätte ich es schon gemacht und meine Arbeit zu Ende geführt.

Das Deep-Cloning ist bei InDesign leider keine einfache Sache.


als Antwort auf: [#486110]

in Tabelle Zeilen und Spalten vertauschen

drerol74
Beiträge gesamt: 507

12. Dez 2011, 10:29
Beitrag # 6 von 10
Beitrag ID: #486115
Bewertung:
(9666 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Uwe,

danke auch dir für die Antwort und die Beispiele.

Antwort auf: Für den EINFACHSTEN Fall, dass Du KEINE VERBUNDENEN Zellen hast und auch sonst nur die GLEICHE Formatierung in allen Zellen UND zudem ohne verankerte Objekte arbeitest, brauchst Du nur den "Contents" von Zeilen und Spalten zu tauschen.


Ja, mit "contents" funktioniert das auch bei mir, nur versuche ich auch die verankerten Objekte und die eventuell vorhandenen Zeichenformate mit zu übernehmen.

Antwort auf: Mit Formatierungen und verknüpften Objekten kommt meiner Ansicht nach nur ein Copy/Paste-Szenarium als Lösung in Frage.


Copy/Paste wollte ich - wenn möglich - vermeiden. Aber deine Vorschlag funktioniert ansonsten (und das noch mit wesentlich weniger Codezeile). Ich werde das dann nochmal genauer testen. Wenn der andere Weg nicht funktionieren sollte, werde ich wohl deinen Vorschlag aufgreifen.

Schöne Grüße
Roland


als Antwort auf: [#486107]

in Tabelle Zeilen und Spalten vertauschen

Uwe Laubender
Beiträge gesamt: 5316

12. Dez 2011, 10:40
Beitrag # 7 von 10
Beitrag ID: #486116
Bewertung:
(9660 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo, Roland!

Was auch Probleme machen kann, sind individuelle Umrandungsvorgaben der Zellen, die auch durch copy/paste nicht erhalten bleiben, da sie das optische Gesamtbild der Tabelle betreffen können.

Beispiel: alle am AUSSENRAND der Tabelle stehenden Zellenränder sollen eine andere Strichstärke oder Farbe haben.


als Antwort auf: [#486115]

in Tabelle Zeilen und Spalten vertauschen

Uwe Laubender
Beiträge gesamt: 5316

12. Dez 2011, 11:11
Beitrag # 8 von 10
Beitrag ID: #486118
Bewertung:
(9638 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo, Roland!
Noch ein Hinweis, der aber auf Deinen Fall wahrscheinlich nicht zutreffen wird, da Du ja auch die Zellenfüllung mit kopieren willst:

Möchtest Du nur den formatierten Textinhalt (inklusive der verankerten Objekte) vertauschen, dann kannst Du auch ohne Copy/Paste agieren, indem Du die Textobjekte (texts[0]) der einzelnen Zellen duplizierst:

Code
//Textrahmen mit NUR EINER Tabelle ist ausgewählt:  

var _tableSource = app.selection[0].tables[0];

var _tableTarget = app.selection[0].insertionPoints[-1].tables.add({
bodyRowCount:_tableSource.columns.length,
columnCount:_tableSource.rows.length
});

var _tableSourceRows = _tableSource.rows;
var _tableTargetColumns = _tableTarget.columns;

//Zeilen werden zu Spalten:
for(var r=0;r<_tableSourceRows.length;r++){

//Zelle der Quelle (zeilenweise):
var _cellsTS = _tableSourceRows[r].cells;

//Zelle des Ziels (spaltenweise):
var _cellsTT = _tableTargetColumns[r].cells;


//Nur die Textobjekte werden übertragen:
for(var c=0;c<_cellsTS.length;c++){
_cellsTS[c].texts[0].duplicate(LocationOptions.AFTER,_cellsTT[c].insertionPoints[0]);
};
};

_tableSource.remove();


Die Formatierung der Zellen mit Höhe, Füllung und Linien müßte dann anschließend erfolgen.


als Antwort auf: [#486116]

in Tabelle Zeilen und Spalten vertauschen

drerol74
Beiträge gesamt: 507

12. Dez 2011, 11:39
Beitrag # 9 von 10
Beitrag ID: #486122
Bewertung:
(9618 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Uwe,

doch doch, das könnte schon so funktionieren, danke für den Hinweis.

Die anderen Eigenschaften der Zelle übertrage ich dann mit Zellenformaten, soweit möglich. Kontur ist überall gleich.

Habe nur gerade keine Zeit, um das auszuprobieren, melde mich wieder.

Schöne Grüße
Roland


als Antwort auf: [#486118]

in Tabelle Zeilen und Spalten vertauschen

drerol74
Beiträge gesamt: 507

17. Dez 2011, 22:25
Beitrag # 10 von 10
Beitrag ID: #486545
Bewertung:
(9501 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Vielen Dank nochmals für eure Tipps.

Wenn jemand mal Zeilen und Spalten einer Tabelle vertauschen möchte, hier zwei Scripts zum Testen. (bisher getestet am Mac mit CS5.5)

Einzige Einschränkung an die Tabelle:
Die zu tauschenden Zellen dürfen nicht verbunden sein.

Script flipTable_Content+Format.jsx
Sämtliche Inhalte und die zugewiesenen Zellenformate werden mit den Zellen übertragen.

Script flipTable_allProps.jsx
tauscht zudem auch jene Eigenschaften, die nicht über ein Zellenformat zugewiesen sind, und Abweichungen vom Zellenformat. (Berücksichtigt werden dabei alle Eigenschaften, die mit einem Zellenformat übertragen werden können.) Das Script ist allerdings um einiges langsamer.

Da die Konturen nicht eindeutig einer Zelle zugeordnet werden können, müssen diese in den transformierten Zellen nachbearbeitet werden (z.B. wenn die Konturen von angrenzenden Zellen unterschiedliche Farbe und Stärke aufweisen) - ebenso wie Zellenhöhe und -breite (wenn unterschiedlich).

Schöne Grüße
Roland


als Antwort auf: [#486122]
(Dieser Beitrag wurde von drerol74 am 17. Dez 2011, 22:27 geändert)
X