Skip to main content
Inspiring
April 21, 2022
Answered

スクリプトで、最後から二つ目の文字列が置き換えされない

  • April 21, 2022
  • 2 replies
  • 729 views

お世話になります。

 

Aiの開いているファイル全てで一気に特定の文字を置き換えしたいと思い、

ネット上にあるスクリプトを切り貼りして作成しているのですが、うまく行きません。

 

ぱっと見、上手くいっているようなのですが、最後から2つ目の文字列に当たるものだけが置き換えされません。

どうすれば、すべて置き換わるのでしょうか?

 

1つめ あああああ

2つめ ああああ ←この文字列すべてが置き換わらない

3つめ あああああ

 

 

if (app.documents.length > 0) { //開いているファイルすべてを選択
while (app.documents.length > 0){
var mydocument = app.activeDocument; //現在の一番前にあるファイル

// 置き換えの文字
var data = {src:"あかさたな", dst:"あいうえお"};

//テキスト一時保管
var targetObj = []; //文字を格納しておくところ

// ドキュメント内からテキストのみを取り出す
var docObj = activeDocument; //エディタで現在表示されているドキュメントを参照するときに使います
for(var i=0; i<docObj.pageItems.length; i++){
typ = docObj.pageItems[i].typename;
if (typ != "TextFrame") continue; // テキスト以外は無視
targetObj.push(docObj.pageItems[i]); // 対象を格納

// テキストの該当文字を置換
for(var i=0; i<targetObj.length; i++){
var regsrc=new RegExp(data.src, "gm");
targetObj[i].contents = targetObj[i].contents.replace(regSrc, data.dst);
}
}
app.activeDocument.save()//ファイルを保存
app.activeDocument.close()//ファイルを閉じる

}}

// 処理終了を告げる
alert(" 終わったよー!");

This topic has been closed for replies.
Correct answer Ten A

まず、オブジェクトの振り分け方法ですが、こちらを試してください。

 

alert(app.selection[0] instanceof TextFrame)

 

これで調査対象(この場合はselection[0])のプロトタイプチェーンを調べオブジェクトインスタンスのコンストラクターがTextFrameかどうかがわかります。もっとも、Illustratorの場合はDocumentクラスの子クラスとしてtextFramesコレクションがダイレクトに得られますからこのプロセス自体は省略しtextFramesクラスを対象としたループを実行すれば問題ありません。

で、一番の問題がajabonさんのご指摘の通りforの二重ループのインデックスが両方とも同じiだと言う点です。
ということで、できるだけシンプルに書きます。同様の文字列を一気に置換する場合は正規表現をグローバルで機能するようにします。

 

var mydocument = app.activeDocument;
var data = {src:"あかさたな", re:/あかさたな/g, dst:"あいうえお"};
var txf = mydocument.textFrames;
for(var i=0; i<txf.length; i++)
{
if (txf[i].contents.indexOf(data.src)<0) continue;
txf[i].contents = txf[i].contents.replace(data.re, data.dst);
}

 

初心者の場合、処理に関してはできるだけシンプルに書くように心がけてください。冗長になるとデバッグ自体の難易度が上がってしまいます。最初から一気に開いてるドキュメントを処理しようとせず部分的に煮詰めていくのが得策です。 

2 replies

Ten A
Community Expert
Ten ACommunity ExpertCorrect answer
Community Expert
April 21, 2022

まず、オブジェクトの振り分け方法ですが、こちらを試してください。

 

alert(app.selection[0] instanceof TextFrame)

 

これで調査対象(この場合はselection[0])のプロトタイプチェーンを調べオブジェクトインスタンスのコンストラクターがTextFrameかどうかがわかります。もっとも、Illustratorの場合はDocumentクラスの子クラスとしてtextFramesコレクションがダイレクトに得られますからこのプロセス自体は省略しtextFramesクラスを対象としたループを実行すれば問題ありません。

で、一番の問題がajabonさんのご指摘の通りforの二重ループのインデックスが両方とも同じiだと言う点です。
ということで、できるだけシンプルに書きます。同様の文字列を一気に置換する場合は正規表現をグローバルで機能するようにします。

 

var mydocument = app.activeDocument;
var data = {src:"あかさたな", re:/あかさたな/g, dst:"あいうえお"};
var txf = mydocument.textFrames;
for(var i=0; i<txf.length; i++)
{
if (txf[i].contents.indexOf(data.src)<0) continue;
txf[i].contents = txf[i].contents.replace(data.re, data.dst);
}

 

初心者の場合、処理に関してはできるだけシンプルに書くように心がけてください。冗長になるとデバッグ自体の難易度が上がってしまいます。最初から一気に開いてるドキュメントを処理しようとせず部分的に煮詰めていくのが得策です。 

Inspiring
April 22, 2022

ご回答いただき、ありがとうございました。

 

動きました!

また、とても丁寧に解説してくださって、ありがとうございます。

 

これからも、頑張って行きます。

ajabon grinsmith
Community Expert
Community Expert
April 21, 2022

あー、pageItemsのループ内でtargetObjのループをしています。

そこで変数 i の役割がかぶっちゃってるせいかと思います(試してないのですが)。

スクリプト末尾の閉じブラケット 「}」を1こ、//テキストの該当文字を置換 の前に移動してみてください。

Inspiring
April 22, 2022

ご回答いただき、ありがとうございます。

 

スクリプト末尾の閉じブラケット 「}」を1こ、//テキストの該当文字を置換

の前に移動移動させたところ、フリーズしました…。

ajabon grinsmith
Community Expert
Community Expert
April 22, 2022

あ、ごめんなさい

ファイルを保存 の前にあるブラケット の誤りでした。。

 

デバッグは変数の挙動を注意して見守ってみてください。

寄せ集め・つぎはぎのコードなら紙にフローチャートを書き起こしてみるのもひとつの手です。