Amazonで商品を見るセール会場へ

Photoshop JSXでグループ内も名前で選択する|再帰検索・同名・階層指定

Photoshopのグループ内・孫グループ内も含め、指定した名前を探して1つ選ぶJSXです。全階層で一致が1件の場合だけ選び、同名が複数ある場合は停止します。同名を親グループで区別する場合は、後半の名前配列で指定する例を使います。文書直下だけを探す場合は直下の名前選択へ進んでください。

今回確認したのは標準JavaScriptの構文と模擬条件です。Photoshopでの選択・表示・実画面の撮影は未検証です。コードはレイヤーの移動・名前変更・保存を呼びませんが、選択状態は変わります。非表示、ロック、複数選択、アートボードの実際の挙動は自作の文書で確認してください。

目次

名前検索・階層指定・複数選択の違い

目的使う方法
子・孫も含め同名が1件だけ全階層を走査して一致数を確認してから選択。
別グループに同名がある親から子への名前配列で、各段階の一致が1件か確認。
同名を全部選びたいこの例の対象外。複数選択の追加・解除とIDを使う方法を別に設計する。
非表示のまま選びたいDOM選択の実表示を確認する。旧MkVs=falseの設定とDOM代入の挙動を同じ保証にしない。

全階層を探し、一致が1件だけなら選択する

新しい全体コードをUTF-8の.jsxとして保存し、ファイル→スクリプト→参照から実行します。旧コードへ追記せず、別ファイルとして1回実行してください。メニューへの登録は動作を確認した後に行います。

LayerSetだけを再帰処理し、グループ自体の名前も候補に含めます。先に見つかった1件で打ち切らず、全体を調べることで別グループの同名も検出します。大規模・極端に深い階層の速度や再帰上限は未測定です。

#target photoshop
(function () {
    if (app.documents.length === 0) { alert("文書を開いてください。"); return; }
    try {
        var doc = app.activeDocument;
        var targetName = "CGM_target";
        var matches = [];
        function collect(container) {
            for (var i = 0; i < container.layers.length; i++) {
                var layer = container.layers[i];
                if (layer.name === targetName) { matches.push(layer); }
                if (layer.typename === "LayerSet") { collect(layer); }
            }
        }
        collect(doc);
        if (matches.length !== 1) {
            alert("全階層の一致: " + matches.length + "件。選択を変更しません。");
            return;
        }
        doc.activeLayer = matches[0];
    } catch (error) {
        alert("読取または選択で中断: " + error.message + "\n行: " + error.line);
    }
}());

同名を親グループからの名前配列で区別する

targetPathは親から子への名前の配列です。例ではCGM_GroupA→CGM_Subgroup→CGM_targetをたどります。別グループのCGM_targetと区別できますが、同じ親の下に同名が2つあれば停止します。名前に「/」がある場合も配列の1要素として扱い、区切り文字として分割しません。

#target photoshop
(function () {
    if (app.documents.length === 0) { alert("文書を開いてください。"); return; }
    try {
        var doc = app.activeDocument;
        var targetPath = ["CGM_GroupA", "CGM_Subgroup", "CGM_target"];
        if (targetPath.length === 0) { alert("名前の配列を指定してください。"); return; }
        var container = doc;
        var target = null;
        for (var step = 0; step < targetPath.length; step++) {
            var matches = [];
            for (var i = 0; i < container.layers.length; i++) {
                if (container.layers[i].name === targetPath[step]) { matches.push(container.layers[i]); }
            }
            if (matches.length !== 1) {
                alert("段階 " + (step + 1) + " の一致: " + matches.length + "件。選択を変更しません。");
                return;
            }
            target = matches[0];
            if (step < targetPath.length - 1) {
                if (target.typename !== "LayerSet") {
                    alert("途中の名前がグループではありません。選択を変更しません。");
                    return;
                }
                container = target;
            }
        }
        doc.activeLayer = target;
    } catch (error) {
        alert("読取または選択で中断: " + error.message + "\n行: " + error.line);
    }
}());

途中の名前はグループである必要があります。最後の名前はレイヤーでもグループでも構いません。グループ名を変更した後は配列も更新します。表示名をつないだ文字列だけを固有IDとみなさず、各段階の候補を検査してください。

階層と同名の確認例

自作文書の条件全階層の例名前配列の例
CGM_targetが孫に1つその孫を選択指定した経路なら選択
GroupA/targetとGroupB/target2件で停止親を指定して区別
同じ親の下に同名が2つ2件で停止その段階で停止
対象がグループ自体1件ならグループ選択最後の名前ならグループ選択
途中がArtLayer・名前なし・文書なし該当条件で停止選択代入前に停止

表は実機の成功結果ではなく、模擬条件で確認した処理の期待値です。Photoshopでは自作の入れ子と同名を使い、選択行・非表示・ロック・複数選択・アートボード、選択前後のレイヤー数と順序を確認します。選択後の保存や削除をつなぐ前に、対象を読み違えていないかを確認してください。

見つからない・選べないときの切り分け

症状確認すること
文書を開いてくださいPSDなどの文書を開く。文書取得より先にapp.documents.lengthを検査する。
一致0件検索範囲、名前の大文字小文字・全角半角・前後の空白を確認。背景の名前は言語や改名で変わる。
同名で停止名前だけでは対象を一意に決められない。親グループを指定するか、一意な名前へ整理してから実行する。
読取または選択で例外error.messageと行番号を記録。不在と断定しない。文書切替・閉じる操作・対象の状態を確認してから再実行する。

表示確認では、選択した行のハイライトとレイヤー名を記録します。レイヤーを選ぶ操作は不透明ピクセルの選択範囲を作る操作とは別です。選択後の処理を追加する前に、期待した対象だけを選んだことを確認してください。

旧コードと過去の画面(参照用)

旧ActionReference.putNameの例は保持しますが、同名を区別するコードではありません。MkVs=falseを明示していても、対象の一意性や全階層の検索結果を保証しません。ScriptingListenerの記録を基にしたことだけで「確実」とは判断しません。executeActionの失敗をすべて不在とする説明も除去しています。

// 選択するレイヤー名を指定
var targetLayer = "背景";

// アクションリファレンスを作成
var idSelect = charIDToTypeID("slct");
var desc = new ActionDescriptor();
var idNull = charIDToTypeID("null");
var ref = new ActionReference();
var idLayer = charIDToTypeID("Lyr ");

// レイヤー名を指定
ref.putName(idLayer, targetLayer);
desc.putReference(idNull, ref);

// レイヤーの可視状態を変更しない設定
var idMakeVisible = charIDToTypeID("MkVs");
desc.putBoolean(idMakeVisible, false);

// アクションを実行
try {
    executeAction(idSelect, desc, DialogModes.NO);
} catch (e) {
    alert("レイヤー '" + targetLayer + "' が見つかりません。");
}
旧記事のAction Managerコード編集画面。下部の結果はActionDescriptor表示で、Photoshopのレイヤーパネルや同名・階層の選択結果は写っていません。
旧記事のAction Managerコード編集画面。下部の結果はActionDescriptor表示で、Photoshopのレイヤーパネルや同名・階層の選択結果は写っていません。 過去の掲載画像で、撮影日・Photoshopの詳細版は未確認です。

参照資料と確認範囲

Adobe Photoshop Scripting Guide 2020の38〜39ページ(並び順・レイヤーセット)、JavaScript Scripting Reference 2020のDocument、ArtLayers、Layers、LayerSetを参照しています。2020年版のExtendScript資料で、現在のPhotoshopで実機確認した記録ではありません。

Adobeのレイヤー選択手順ではパネルでの選択と、サムネールからのピクセル選択を区別しています。UXPのLayers資料は別の実行環境です。このJSXを.psjsに改名するだけでは移行できません。UXPスクリプトの実行方法で分担を確認してください。

旧配布と関連する手順

旧配布はGitHubの元コードに残しています。公開フォルダーの01.jsは今回の新しい例へ更新していません。実行する場合は、このページの新しい全体コードを別の.jsxとして保存してください。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Photoshopのおすすめ書籍

動作要件とPCの確認項目

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次