コモノExtendScript100本ノック

超初心者のDTPオペレーターが週にひとつスクリプトを書くブログ

069.【Id】作業時間を記録する

InDesignドキュメントがアクティブ状態にある時間を計測し、作業時間を算出する。

挙動

  1. ドキュメントを開かない状態で実行する(あるいはInDesign起動前にStartup Scriptsフォルダに入れておく)。
  2. ドキュメントが開かれるとデスクトップに「log.txt」が作成され、ファイル名と時刻が記録される。
  3. 同時に、ドキュメントに対して以下のイベントリスナーが設定される。
    ①アクティブになったときに時間を記録する
    ②非アクティブになったときに時間を記録する
    ③①と②の差分=作業時間を記録する

コード

//@targetengine getActiveTimes

if (app.eventListeners.itemByName("getActiveTimes").isValid) {
    app.eventListeners.itemByName("getActiveTimes").remove();
}
var myListener = app.addEventListener("afterOpen", addEvToDocs);
myListener.name = "getActiveTimes";

function addEvToDocs(ev) {
    if (ev.target.constructor.name === "Document") {
        return;
    }
    var doc = app.activeDocument;
    var session = {};
    var start = new Date();
    session.start = start;
    writeTxt("~/Desktop/log.txt", doc.name + "\t" + parseDate(start));
    if (!doc.eventListeners.itemByName("beforeListener").isValid) {
        var bListener = doc.addEventListener("beforeDeactivate", writeCSV2);
        bListener.name = "beforeListener"

        function writeCSV2(ev) {
            if (ev.target.constructor.name === "Document") {
                return;
            }
            var fin = new Date();
            session.fin = fin;
            var myTime = Math.round((session.fin - session.start) / 60000) + "分";
            writeTxt("~/Desktop/log.txt", "\t" + parseDate(fin) + "\t" + myTime + "\n")
        }
    }

    if (!doc.eventListeners.itemByName("afterListener").isValid) {
        var aListener = doc.addEventListener("afterActivate", writeCSV1);
        aListener.name = "afterListener";

        function writeCSV1(ev) {
            if (ev.target.constructor.name === "Document") {
                return;
            }
            start = new Date();
            session.start = start;
            writeTxt("~/Desktop/log.txt", doc.name + "\t" + parseDate(start));
        }
    }
}

//テキスト追記
function writeTxt(path, txt) {
    var fObj = new File(path);
    fObj.encoding = (/csv$/.test(path)) ? "Shift-JIS" : "UTF-8"; //CSVで書き出す場合はShift-JIS
    if (fObj.open("e")) {
        fObj.read();
        fObj.write(txt);
        fObj.close();
    } else {
        alert("ファイルが開けません\n" + path);
    }
}

//日付表記変換
function parseDate(date) {
    var y = date.getFullYear().toString();
    var mo = date.getMonth() + 1;
    var d = date.getDate();
    var h = date.getHours();
    var min = date.getMinutes();
    var s = date.getSeconds();
    var result = y + "/" + mo + "/" + d + " " + h + ":" + min + ":" + s;
    return (result)
}

メモ

分かったこと

afterOpenやafterActivateに紐づけたEventは、
①ドキュメントが開かれた後
②ウィンドウがロードされた後
の2回実行される。
それぞれtargetが違う(①はDocument、②はLayoutWindow)。

積み残し

  • テキストデータへの追記の仕方
    途中で強制終了したときのことを考えて、ログを変数に貯めたりせず都度書き込むかたちにしている。
    read()することでeofに飛ぶようにしている(?)が、もう少しスマートなやり方がありそう。
  • 日付表記変換ももう少しスマートにしたい
  • InDesign自体が非アクティブのときは計測から除外したい

参考