• マクロでOutlookの予定表を iCalendar形式 (ics)で出力する

    予定表アイテムを別のカレンダーアプリケーションへインポートするために、Outlookの予定表をiCal形式で出力したい。

    ■前提
    • 既定以外の予定表フォルダも指定したい
    • 出力処理を自動化したい(警告ダイアログは困る)
    • セキュリティ警告周辺の設定をいじらないで済ませたい
    • Outlook 2003でも使いたい
    てな条件でjscriptで書いてみた。

    ol2ics.txt
    (コンテキストメニューから保存。拡張子を.jsに)

    cscript.exe ol2ics.js [/folder:folder_path] 出力ファイル.ics

    /folder:予定表フォルダのpath。

    • エクスポート時点で、終了時刻が過ぎていない予定が出力される
    • 定期的な予定は未対応
      インポート先アプリケーションが繰り返し予定のインポートに対応していない(手入力はできるのに・・)ので、まぁいい。
    • SaveAsしないのは、
      →OL2003で↓警告が出たから。次項のAppointmentItem.Bodyと関係ある?
      ol_caution.png

      →OL2007だとデフォルトでは、以下のような設定になっていて、アンチウイルスが有効なら警告されないみたい。試しにアンチウイルスをoffにしてから試行したら警告が出た。
      ol_sc.png
    • DESCRIPTIONを出力していないのは、
      →AppointmentItem.Bodyを参照すると上記の警告ダイアログが出たから。(OL2003)
      →インポート先アプリケーションのUIを勘案して、SUMMARYだけ反映できれば十分と割り切ることに。。
    • OL2007だと、Folderに対してSaveAs出来るようだけど、OL2003でも使うので見送りに。

    OutlookからUIを用いてics形式で保存すると、UIDの桁数がかなり多く、AppointmentItem.EntryIDの値とは異なる。
    AppointmentItem.EntryIDのリファレンスには"The EntryID property returns a MAPI long-term Entry ID. "とあるけど。



  • VBAで Outlookの予定表フォルダを取得する

    folders.png
    ※VBAで、といいつつJScript。

    既定の予定表は、こんな感じでFolderオブジェクトを得られる(JScript)

    var app = new ActiveXObject("Outlook.Application");
    var ns = app.GetNamespace("MAPI");
    var folder = ns.GetDefaultFolder(olFolderCalendar);

    ※olFolderCalendarは9

    ここの環境は、以前、別のOffice環境から移行してきたデータファイルがあるため、左のように複数の予定表フォルダがある。これに対応するFolderオブジェクトを取得したい。(で、配下の予定表アイテムを列挙、といきたい)

    FolderのEntryIDが事前に分かっていれば、NameSpaceから取得できるようなんだけど・・・。

    「おれおれフォルダ→予定表」にあたるFolderオブジェクトのFolderPathは
     "\\おれおれフォルダ\予定表"
    になることがわかったので、ルートから順番に辿ってパスで判断することに。



    ■folders.js

    /**
     * Enum folders(and its itemtype) of Outlook(!=express).
     *
     * usage:
     *   cscript.exe folders.js
     *
     * Tried env.
     *   Outlook 2003 SP3 + XP Prof SP2(ja)
     *   Outlook 2007 SP1 + Vista Ultimate SP1 x64(ja)
     */

    if( !WScript.FullName.match( /cscript\.exe$/i ) )
    {
        WScript.echo( "run me under cscript.exe");
        WScript.Quit();
    }

    var app = new ActiveXObject("Outlook.Application");
    var ns = app.GetNamespace("MAPI");

    traverse( ns );

    function    traverse( folder )
    {
        if( folder.FolderPath )
        {
            WScript.echo( folder.FolderPath + ": " + folder.DefaultItemType );
        }
        else
        {
            WScript.echo( folder );
        }

        var folders = folder.Folders;
        for( var i = 1 ; i <= folders.Count ; i++ )
        {
            traverse( folders(i) );
        }
    }