3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AppleScript & Adobe アプリケーションで高速リスト処理

Last updated at Posted at 2020-11-01

#script object を使用したリスト処理

AppleScript は、リスト処理がとにかく遅いので有名です。
たとえば、以下のスクリプトは
1〜10,000をループさせて、一つずつ文字列に変換しつつリストに代入してゆくのですが、
とにかく実行してみてください。


**サンプルコード1**
sample1
use scripting additions
use framework "Foundation"

set eDate to current application's NSDate's timeIntervalSinceReferenceDate()

set a to {}
repeat with i from 1 to 10000
	set end of a to i as string
end repeat

display alert ((((current application's NSDate's timeIntervalSinceReferenceDate()) - eDate) & "秒かかりました") as string)

私のMacBook Pro(os10.14.6/2.2GHz Intel Core i7)では
こうなりました。
スクリーンショット0.png
いやいや…
こんなのに約1.4秒は遅いでしょ。

ということで、
リストを script object にしてみます。


**サンプルコード2**
sample2
use scripting additions
use framework "Foundation"

set eDate to current application's NSDate's timeIntervalSinceReferenceDate()

script a
	property contents : {}
end script

set contents of a to {}

repeat with i from 1 to 10000
	set end of contents of a to i as string
end repeat

display alert ((((current application's NSDate's timeIntervalSinceReferenceDate()) - eDate) & "秒かかりました") as string)

結果は、
スクリーンショット1.png
1/10以下のスピードで処理できます。

単にリストを定義するのではなく、
script objectproperty を使用してリスト定義をすると、
なぜか高速化するのです。

これについては以下のサイトを参考にさせて頂きました。

#では早速 Adobe アプリケーションに使ってみよう
こんなに速くなるのなら、と
Illustrator やら、 InDesign やら
大量にリストを使用する script に使ってみます。

以下は、Illustrator ドキュメント上の
全ての text frame をリストに代入しようとしています。


**サンプルコード3**
sample3
script allText
	property contents : {}
end script

tell application "Adobe Illustrator"
	tell document 1
		set contents of allText to text frames
	end tell
end tell

これを実行すると、
スクリーンショット2.png
エラーになってしまいます。

というのは、
Adobe Illustrator は、
contents」という property を内部で使っているからです。
スクリーンショット3.png
なんという意地悪!
#じゃ、結局使えないの?
そんなことはないです。


**サンプルコード4**
sample4
script allText
	property record : {}
end script

tell application "Adobe Illustrator"
	tell document 1
		set record of allText to text frames
	end tell
end tell

contents」を「record」に変えるだけで、
使用できるようになります。
スクリーンショット3.png
Adobe Indesign も同様に、


**サンプルコード5**
sample5
script allPageItems
	property record : {}
end script

tell application "Adobe InDesign CC 2019"
	tell document 1
		set record of allPageItems to all page items
	end tell
end tell
![スクリーンショット4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500852/55fc0029-a7ad-d53e-15eb-dec4283b60b0.png)

なぜ「record」が使えるのか、
私にはよくわかりません。

わかりませんが、
これであなたの作った script も確実に高速化します。
#最後に注意点
リストの高速化で、
一点だけ注意して欲しいこと。

それは、script obejct に対して
count」が使えなくなることです。


**サンプルコード6**
sample6
script allPageItems
	property record : {}
end script

tell application "Adobe InDesign CC 2019"
	tell document 1
		set record of allPageItems to all page items
	end tell
end tell

repeat with i from 1 to count of record of allPageItems
	get item i of record of allPageItems
end repeat
これを実行するとエラーになります。 ![スクリーンショット5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500852/e81020e6-e75c-ed19-d0ad-7d945796927f.png) これの解決策は、 「**count**」を「**length**」に変えること。 ***
**サンプルコード7**
sample7
script allPageItems
	property record : {}
end script

tell application "Adobe InDesign CC 2019"
	tell document 1
		set record of allPageItems to all page items
	end tell
end tell

repeat with i from 1 to length of record of allPageItems
	get item i of record of allPageItems
end repeat
![スクリーンショット6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500852/e223f7af-08dd-b173-df66-b539db0399f1.png)

よしよし。

では皆様、今後ともよろしくお願いいたします。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?