最上位の親レイヤーを1つだけ対象にし、直下の子レイヤーを同じ位置の最上位へ移してから、空になった親を削除するJSXです。孫以下の階層は子と一緒に残します。
2026年10月3日にコードと説明を改修しました。掲載例はコピーしたデータで試し、レイヤー構造、重なり順、外観、書き出し結果を確認してから使ってください。現在の改修版について、Illustratorでの動作確認はまだ完了していません。
この処理が対象にする構造
| 実行前 | 実行後 |
|---|---|
| 親 → 子A → 孫A、親 → 子B | 子A → 孫A、子B。親だけ削除。 |
| 親の直下に図形・文字などがある | 削除せず、移動前に停止。 |
| 他の親レイヤー | 処理対象外。 |
| ロック・非表示の親または子孫 | 状態を変更せず停止。 |
親レイヤーに設定した透明度、描画モード、マスク、効果は、子を外すと見た目が変わる可能性があります。このコードは、それらを子に複製したり完全に検出したりする処理を持ちません。親の外観が必要なデータでは使わず、手動で構造を整理します。
旧コードで削除され得た内容
以前のコードは全レイヤーを巡回してロックと表示状態を変更し、最初のレイヤーを削除していました。子を移しても親の直下の図形・文字は残るため、親と一緒に削除される可能性がありました。2026年10月3日の改修では、アクティブな最上位1件だけを対象にし、直下のオブジェクトがあれば操作前に停止します。
実行手順
- AIを別名のコピーとして保存する。
- レイヤーパネルで対象の最上位親をアクティブにし、新しいオブジェクトの配置先がその親であることを確認する。子孫や複数レイヤーの選択とは区別します。
- 親の直下に図形や文字がないこと、親の外観に依存していないことを確認する。
- 下のJSXを実行し、確認画面の親名と子の件数を照合する。
- 子・孫の階層、レイヤーの前後、オブジェクトの件数・外観を比較してから保存する。
(function () {
try {
if (app.documents.length === 0) throw new Error("ドキュメントを開いてください。");
var doc = app.activeDocument;
var parent = doc.activeLayer;
if (parent.parent !== doc) throw new Error("最上位の親レイヤーをアクティブにしてください。");
checkTree(parent);
if (parent.layers.length === 0) throw new Error("子レイヤーがありません。");
for (var i = 0; i < parent.pageItems.length; i++) {
if (parent.pageItems[i].parent === parent)
throw new Error("親の直下にオブジェクトがあります。削除せず終了します。");
}
var children = [];
for (var j = 0; j < parent.layers.length; j++) children.push(parent.layers[j]);
if (!confirm("コピーしたデータですか?\n親「" + parent.name + "」の子 " + children.length +
" 件を最上位へ移し、親だけを削除します。\n親の外観・透明度が不要なことも確認してください。")) return;
for (var k = 0; k < children.length; k++)
children[k].move(parent, ElementPlacement.PLACEBEFORE);
if (parent.layers.length !== 0 || parent.pageItems.length !== 0)
throw new Error("親の中に項目が残っています。親は削除しません。");
parent.remove();
alert("親を削除しました。子の階層・重なり・外観を確認してから保存してください。");
} catch (e) {
alert(String(e) + "\n途中で失敗した場合、一部の移動が残る可能性があります。保存せず状態を確認してください。");
}
function checkTree(layer) {
if (layer.locked || !layer.visible || !layer.editable)
throw new Error("ロック・非表示・編集不可のレイヤーがあります。");
for (var i = 0; i < layer.layers.length; i++) checkTree(layer.layers[i]);
}
}());JSXの保存と実行
コードをUTF-8のテキストで保存し、拡張子を.jsxにします。「ファイル」→「スクリプト」→「その他のスクリプト」から選びます。保存・実行の詳しい手順はJSX入門を参照してください。各コードは別々のファイルとして実行します。
途中で失敗した場合
moveが途中で失敗すると、すでに移動した子だけが最上位に出た状態が残ります。自動ロールバックや自動保存はしません。親の削除には最後まで進まず、残った親と移動済みの子を確認します。確実に元の構造へ戻すには、試験用コピーを保存せず閉じて開き直します。
移動前の子を配列へ控え、前から順に親の直前へ入れます。子の相対順序と孫の階層を保つことを意図した処理です。実機での順序・外観の比較は必要です。レイヤー取得・移動の基礎はレイヤー操作のJSXを参照してください。
参照資料
Adobeのレイヤー削除、Adobe資料をもとに維持されているLayerのAPI参照を参照しました。旧GitHub版は今回のコードと一致するとは限りません。

コメント
コメント一覧 (1件)
I like the efforts you have put in this, regards for all the great articles.