交通費精算自動化スクリプト(outlookから予定抽出)

<h2>環境</h2>
Windows10

<h2>概要/背景</h2>
会社の交通費精算をするとき、毎月1回スケジュールを見直してEXCELにして処理担当の人に送っていました。抽出がめんどくさくなったので、抽出を自動化しました。

<h2>機能</h2>
サラリーマンやってる人がよく使ってる会社の支給PCでも制限なく使えるようにWindows標準のWindows Script Host(WSH)を使ってます。outlookから過去の予定を抽出して、csvに保存、処理担当の人に送るメールを作るまで自動化してます。

```javascript
var FORREADING = 1;
var FORWRITING = 2;
var FORAPPENDING = 8;
var TRISTATE_TRUE = -1;   // Unicode
var TRISTATE_FALSE = 0;   // ASCII
var TRISTATE_USEDEFAULT = -2;
var WS_NOTVISIVLE = 0;
var WS_ACT_NORMAL = 1;
var WS_ACT_MIN = 2;
var WS_ACT_MAX = 3;
var WS_NOTACT_NORMAL = 4;
var WS_ACT_DEF = 5;
var WS_NOTACT_MIN = 7;

var outlook = WScript.CreateObject("Outlook.Application");
var olFolderCalendar = 9;
var name_space = outlook.GetNamespace("MAPI");
var folder = name_space.GetDefaultFolder(olFolderCalendar);
var objNetWork = new ActiveXObject("WScript.Network");

var fs = new ActiveXObject("Scripting.FileSystemObject");
var sh = new ActiveXObject("WScript.Shell");
var homeDir = sh.SpecialFolders("Desktop") + "\\";
var schduleContents = homeDir + "ExtractedSchedule_" + objNetWork.UserName +".csv";
var previousChecktimeFile = homeDir + "LastSearchedIndex_" + objNetWork.UserName +".txt";//デフォルト値0 => folder.items.countを格納する
var dd = new Date();

var shortCutName = "交通費精算_" + objNetWork.UserName;
var previousCheckMonth = homeDir + "lastCheckedMonth_" + objNetWork.UserName +".txt";

var file_prev;
var lastChecked;

if(fs.FileExists(previousCheckMonth)){
    file_prev = fs.OpenTextFile(previousCheckMonth, FORREADING, true, TRISTATE_FALSE);
    lastChecked = file_prev.ReadAll();
//  file_prev = fs.OpenTextFile(previousCheckMonth, FORWRITING, true, TRISTATE_FALSE);
//  file_prev.Write(dd.getYear() + "/" + (dd.getMonth()+1) + "/" + dd.getDate() );
    file_prev.Close(); 
}else{
    //ファイルを作成
    file_prev = fs.OpenTextFile(previousCheckMonth, FORWRITING, true, TRISTATE_FALSE);
//  file_prev.Write(dd.getYear() + "/" + (dd.getMonth()+1) + "/" + dd.getDate());
    lastChecked = "Null(いつまで清算済みかは個別確認してください!)";
    file_prev.Close();
}

var mail = outlook.CreateItem(0);
var mail_to = "担当者@メールアドレス ";
var subject = "交通費精算依頼";
var body    = "Auto-generated mail: "+ objNetWork.UserName + "です。\n"+lastChecked +"まで清算完了済みです。\n" + dd.getYear() + "/" + (dd.getMonth()+1) + "/" + dd.getDate() + "分までの交通費精算をお願いします。\n開始時間でソートしてください。\n 凡例(外出)・・・外出があった日\n(直行)・・・家から直行\n(直帰)・・・家に直帰\n外出が記載されず、直行/直帰のみ記載されている場合清算不要";

if (fs.FileExists(previousChecktimeFile)) {
    //存在した場合
    var file = fs.OpenTextFile(previousChecktimeFile, FORREADING, true, TRISTATE_FALSE);
    var file2 = fs.OpenTextFile(schduleContents, FORAPPENDING, true, TRISTATE_TRUE);
    var str = file.ReadAll();
    fileWrite(folder,file2,str);
    file = fs.OpenTextFile(previousChecktimeFile, FORWRITING, true, TRISTATE_FALSE);
    file.Write(folder.Items.Count);//調べたところまでを記録
    //  ファイルを閉じる
    file.Close();
    file2.Close();
} else {
    //存在しない場合
    //上書き新規保存
    var file2 = fs.OpenTextFile(schduleContents, FORWRITING, true, TRISTATE_FALSE);
    fileWrite(folder, file2, 0);
    file2.Close();
}

//ショートカットを同ディレクトリに作成
//var shortCut = sh.CreateShortcut(homeDir + shortCutName +  ".lnk");
//shortCut.TargetPath = schduleContents;
//shortCut.WindowStyle = WS_ACT_NORMAL;
//shortCut.Save();

mail.To = mail_to;
mail.Subject = subject;
mail.Attachments.Add(schduleContents);
mail.Body = body;
//mail.Send();
mail.Display();

file_prev = fs.OpenTextFile(previousCheckMonth, FORWRITING, true, TRISTATE_FALSE);
file_prev.Write(dd.getYear() + "/" + (dd.getMonth()+1) + "/" + dd.getDate() );
file_prev.Close();

//  オブジェクトを解放
fs = null;
sh = null;

function fileWrite(folder, writingFile,startNum) {
    writingFile.WriteLine("要件,時間(分),場所,開始時間,終了時間");//要件,時間(分),場所,開始時間,終了時間
    for (var i = folder.Items.Count; i > startNum; i--) {
        writingFile.Write(folder.Items(i).Subject.replace(/,/g, " "));
        writingFile.Write(",");
        writingFile.Write(folder.Items(i).Duration);
        writingFile.Write(",");
        writingFile.Write(folder.Items(i).Location.replace(/,/g, " "));
        writingFile.Write(",");
        writingFile.Write(folder.Items(i).Start);
        writingFile.Write(",");
        writingFile.Write(folder.Items(i).End);
        writingFile.Write(",");
        //writingFile.Write(folder.Items(i).Body.replace(/,/g, " "));
        writingFile.Write(",");
        writingFile.WriteLine();
    }
    //writingFile.Cose();
}
```

<h2>参考</h2>
WSH JScriptを使いこなそう
https://jscript.zouri.jp/