AfterEffectsスクリプトの使用状況をExcelに出力してみよう ~JavascriptとPythonの連携~
2013/8/26
Tag: AfterEffects,javascript,python,script,TD,tool
お久しぶりです、半年ぶりの投稿になりますDFの篠崎愛こと@takowasabiです。
・・・・あっ、殴らないで下さい!(;´∀`)
今回はAEScript(javascript)とpythonの連携と銘打ってみました。
AEScriptでは出来ないアレコレをpythonを通してアレコレやってみようという内容です。
「AEscriptでは出来ない事が出来るようになるの?」とか
「pythonってよく聞くけど何ができるの?」とか
なんというかまぁそういう方々に読んでもらえればなーと。
とりあえず今回はAE上でスクリプトを実行した際、誰が・いつ・なんていうスクリプトを実行したのかpythonを介してエクセルに記述する。
というTDの承認欲求と自己顕示欲むき出しのツールを作成してみたいと思います。
主なスクリプトのフロー
AEscript→pythonの流れは大まかに絵で書きますとこんな感じです。
AEscriptからbatファイルを作成して引数を渡し、batファイル内でpython.exeとpythonスクリプトを起動し
AEscriptから渡された引数を受け取り、エクセルに渡しーの、煮るなり焼くなり調理する。という流れです。
あんま難しいことはしてないです。
macだとbatファイルではなくてシェルを作成・・・って流れになるんでしょうかね。
今回はwindowsに絞ってその作成の流れを紹介したいと思います。
なお、今回は全てCドラ直下にエクセルのシートとpythonスクリプトを配置しています。
AEスクリプトの作成。
それでは早速スクリプトをガリガリ書きます。
var dlg = new Window("dialog","C:。ミ",[100,100,300,150]); dlg.Btn=dlg.add('button',[10,10,190,40], 'pushpush!'); dlg.Btn.onClick = function (){ alert("なにかしらの処理~C:。ミ"); CreateBatAndExecute(); dlg.close(); } function CreateBatAndExecute(){ var BatFile = new File("C:/"+ScriptName()+"_"+system.userName+".bat") if (BatFile){ BatFile.open("w"); BatFile.writeln(BatCmd(BatFile)); BatFile.close(); BatFile.execute() } else{ alert("batch file create failed") } } function GetDate(){ var dObj = new Date(); var y = dObj.getFullYear(); var m = dObj.getMonth() + 1; var d = dObj.getDate(); return (y+"/"+m+"/"+d) } function GetTime(){ var dObj = new Date(); var h = dObj.getHours(); var m = dObj.getMinutes(); var s = dObj.getSeconds(); return (h+":"+m+"\'"+s) } function ScriptName (){ ScriptName =new File( $. fileName).name.replace(/.jsx$/,"") return ScriptName } function BatCmd(BatFile){ var Args = ScriptName()+"_"+GetDate()+"_"+GetTime()+"_"+system.userName //今回はデバック用にあえてbatファイルを残す方向ですが、実行後batファイルを削除したい時はこう書くと良い。 //var CMD="chcp 932\nC:\\python\\python26x64\\python.exe C:\\PyToXls.py "+Args+"\ndel " + BatFile.fsName var CMD="chcp 932\nC:\\python\\python26x64\\python.exe C:\\PyToXls.py "+Args return CMD } dlg.show();
まぁこんな感じでガリガリと。
AEを立ち上げてスクリプトを実行するとこんな画面が立ち上がります。
pushって言うから押してあげるとこんなアラートが出てきます。
自分で作っておいてこんなこと言うのもアレですが微妙にイラッとしますねこのアラート。
スクリプト内のこのイラッとするアラート行の真下に書かれてるCreateBatAndExecute();
これが今回のキモです。
早速中身をみてみると・・・
11行目でbatファイルの場所のパスを指定し(batファイルの名前はスクリプトの名前+”_”+ユーザー名.bat)
batファイルが作成できるようなら、
13行目でbatファイルの中を記述モードでopen、
14行目でbatファイルの中身をガリガリ記述
15行目でcloseして
16行目でbatファイルを叩く(実行!)
そいでもってbatファイルの中に記述する文章は43行目のfunction BatCmd()の戻り値ですね。
14行目で記述内容をfunction BatCmd()の戻り値としていますし。
43行目の関数に書かれてる内容を見てみましょう。
44行目の内容は実行された日付とかユーザー名とか時間とかそういうpythonに引数として渡したい文字列をアンダーバーでくっつけて
1つの変数にぶち込んでるだけですね。
それよりも45行目にchcp932と書かれてる箇所があります。
コレを忘れずに書いておいて下さい。
AEスクリプトの文字コードはutf-8ですが、batファイルの文字コードはshift-jisです。
shift-jisで書かないとバッチが動いてくれないのでchcp932と記述し文字コードはshift-jisですよーって指定してあげます。
あとはpython.exeのパスと、実行したいpythonスクリプトのパスを指定、半角のスペースを開けて引数として渡したい文字列を記述します。
python内での処理
ここからは以前たつみさんが書かれた内容と被る箇所がありますが大目に見てくれると嬉しいですヽ(°▽、°)ノエヘヘヘヘ
pythonスクリプトの処理の内容としては
エクセル起動し、指定されたワークブックを開く。
ワークブックを開いた後、スクリプト名と同じシートを検索。
スクリプト名と同じシートが無いようだったらシートを新規で追加作成。
該当するシート内のデータが入っているセルの最終行に、AEスクリプトからの引数である
ユーザー名・日付・時刻を記述し、保存して閉じる。
という流れです。
事前にCドラ直下にScriptUserCheck.xlsという名前のワークブックを作成しておいてください。
コードに関しては以下のようになります。
PyToXls.pyという名前で保存して置いてください。
import sys ExcelWrite = sys.argv[1].split("_") ScriptName= ExcelWrite[0] Date = ExcelWrite[1] Time= ExcelWrite[2] UserName =ExcelWrite[3] import win32api import win32com.client xapp = win32com.client.Dispatch("Excel.Application") xapp.Visible = True book = xapp.Workbooks.Open(r"C:\ScriptUserCheck.xls") #新規でシートを作成した際に一番上の罫線とか文字とか太さとか設定する。 def SettingNewSheet(): StrList =["Date", "Time", "UserName"] for i in range(3,6): Cell=TargetSheet.Cells(3, i) Cell.Value =StrList [i-3] Cell.Font.Bold = 1 # 文字を太くしたい時は1、したくない時は0。true=1 false=0 Cell.HorizontalAlignment = -4108 #文字列を中央揃えにする。左揃えにしたい時は-4131、右揃えにしたい時は-4152 #罫線の設定、これでぐるっとセルを罫線で囲む設定。 Cell.Borders(7).LineStyle = 1 Cell.Borders(7).Weight = 4 Cell.Borders(8).LineStyle = 1 Cell.Borders(8).Weight = 4 Cell.Borders(9).LineStyle = 1 Cell.Borders(9).Weight = 4 Cell.Borders(10).LineStyle = 1 Cell.Borders(10).Weight = 4 #セルの塗りつぶし色設定。 Cell.Interior.ColorIndex = 20 #セルの幅設定。 Cell.ColumnWidth = 15 #該当するシートに日時とユーザー名を記述します def WriteSheet(): TargetSheet.Cells(WriteRow,3).value = Date TargetSheet.Cells(WriteRow,4).value = Time TargetSheet.Cells(WriteRow,5).value = UserName #日時とかユーザー名とか記述したセルの罫線の設定と文字列を中央寄せにする def WriteSheetBorderAndCentering(): #セル囲みの罫線の設定 for j in range(3,6): WriteCell=TargetSheet.Cells(WriteRow,j) WriteCell.Borders(7).LineStyle = 1 WriteCell.Borders(7).Weight = 2 WriteCell.Borders(8).LineStyle = 1 WriteCell.Borders(8).Weight = 2 WriteCell.Borders(9).LineStyle = 1 WriteCell.Borders(9).Weight = 2 WriteCell.Borders(10).LineStyle = 1 WriteCell.Borders(10).Weight = 2 #文字列を中央揃えにする WriteCell.HorizontalAlignment = -4108 try: TargetSheet = book.Worksheets(ScriptName) TargetSheet.Activate() except: TargetSheet = book.Worksheets.Add() TargetSheet.Name =ScriptName SettingNewSheet() TargetSheet.Activate() #LastRow=データが入っている最終行 LastRow = TargetSheet.Range("C65536").End(-4162).Row #WriteRow=新たに値を追記する場所の行 WriteRow=LastRow+1 WriteSheet() WriteSheetBorderAndCentering() book.Save() book.Close() xapp.Quit()
コマンドラインから渡された引数の取得。
pythonでコマンドラインからの引数を取得するにはsysモジュールのargvを使用します。
引数は配列として取得されてるのでargv[1]を使用します。
ちなみにargv[0]は実行したいpythonスクリプトのフルパスが帰ってきます。
argv[1]で取得できる引数はアンダーバーでくっつけてる文字列なのでsplit()し、
どれがユーザー名なのかスクリプト名なのか順番ごとに取得していきます。
win32comモジュールの使用
今回はpythonからエクセルをいじくりまわすのにwin32comを使用しました。
win32comってなんぞやと言われたら
windowsの中に入ってるエクセルとかメモ帳とかを起動させたり処理をさせたりできるような
関数とか命令とかのセットって感じでしょうか。
今回はこのwin32comを使用し、エクセルのマクロを組む際などに使用されるVBをpythonライクに記述することで
動作させてみました。
エクセルが嫌ならGoogleDocsでもいいのよ。
「えー、これならpython使用するメリットがあまり感じられない。VB(VBS)でいいじゃん」
という方もいらっしゃるかもしれません。
GoogleDocsを使用したい場合はgoogleさんから提供されてるgdata-python-clientを使用すればgoogleDocsへのread/writeが可能になります。
また、libreofficeはどうなんじゃろとふと思って検索してみたらマクロ側でpythonがちゃんとサポートされてるようですしイケそうな気がしますね・・・。
検証せずにこんなこと書いてしまうのもアレなんですが!
今回作成したスクリプトはいちいち黒い画面が前面にフワッと出てきてみたりエクセルがフワッと立ち上がってみたり
残りカスみたいなbatファイルは削除されずにそのままだったりと
(今回は)
ユーザー目線で言ったらかなり使用感のキモいツールになりましたが、そこらへん気持ちよく使用できるように整形してもらえれば
今までできなかったことが可能になる&ナカナカの使用感でかなりいい感じのツールが作成できるのではないかなーと思います。
ではではまた今度 C:。ミ
コメント
コメントフォーム