Outlook はVBScriptで操作できる 予定表編 山の日を登録する(OL2013/OL2010必須公式の方法追加)

OutlookのVBAって使ったことがありますか？
まともな本もないのでなかなか誰も思いつかないでしょう。
検索しても三流君、OUTLOOK研究所くらいだと思います。
[Outlookを操作してメールを送りたい -三流君](http://www.ken3.org/vba/backno/vba055.html)
[Outlook 研究所](https://outlooklab.wordpress.com/)
詳細は偉大な２つのサイトに譲るとして実はVBScriptで以下のようなことができます。
メールの作成（添付ファイルをつけて、送信済みフォルダに残さない）
予定表の作成（定期的な予定もカテゴリをつけて）
タスクの作成
メモの作成
連絡先の作成
え？大体全部できるじゃないかって？そうです。実は全部できます。
じゃあ何に使うのか。
例えばメールに添付ファイルをつけるのはいろいろな障害がある時代ですが、テキストなら大丈夫です。
　メール本文にスクリプトを貼って送信し、それをメモ帳でVBSにしてしまえばよいわけです。
　これが役立つのは予定表、連絡先です。
　予定表は特に項目だけの予定表（時間がゼロ）というのが作れます。
[予定表・アポの作成](http://www.ken3.org/cgi-bin/group/vba_outlook_Appointment.asp)
　を参考に時の記念日を設定してみましょう
  予定時間がゼロのパターン
  さらに予定なしにしているので、他の予定を入れても重複になりません。

```vb:VBSCript
'Make時の記念日onOL.VBS
Option Explicit
'OutlookのVBAでは不要
Const olFolderCalendar = 9
Const olNormalWindow=2
Const olAppointItem=1
Const olSave=0
Const olConfidential=3
Const olNormal =0 '標準
Const olPersonal = 1 '個人用
Const olPrivate= 2 '非公開
Const olImportanceLow=0 '重要度低い
Const olBusy = 2 '予定あり。
Const olFree = 0 '予定なし。
Const olOutOfOffice = 3 '外出中。
Const olTentative = 1 '仮の予定あり。 

'Sub Test() 'VBAに貼りつけたときはここをコメントアウト
Dim strAppointSubject 'As String  '予定の名前
strAppointSubject="時の記念日テスト設定"
Dim olApp :Set olApp = CreateObject("Outlook.Application")
Dim NS :Set NS = olApp.GetNamespace("MAPI")
Dim oFol  :set oFol=NS.GetDefaultFolder(olFolderCalender):oFol.Display
olApp.Activewindow.WindowState=olNormalWindow
Dim MyITEM   'As Outlook.AppointmentItem :Set MyItem = olApp.CreateItem(1)       
myITEM.Display
With MyITEM
.Body="時の記念日の試験設定です"
.Location="日本"
.Start=#6/10/2016 08:00:00AM# '日付リテラル 月日年 時分秒 AM/PMを##で囲む
.End=#6/11/2016 08:00:00AM#
'このあとはお好みでBLOCK Start
.AllDayEvent=False '終日か
.Sensitivity = olNormal
.IsRecurring＝False
.Importance=olImportanceNormal
.BusyStatus=olFree 
.ReminderMinutesBeforeStart =15 '分前にアラームを鳴らす
'ここまで--このあとはお好みで Block End
.Save
.Close
End With
```

```vb:VBSCript:Make時の記念日onOL.VBS
Option Explicit
'OutlookのVBAでは不要
Const olFolderCalendar = 9
Const olNormalWindow=2
Const olAppointItem=1
Const olSave=0
Const olConfidential=3
Const olNormal =0 '標準
Const olPersonal = 1 '個人用
Const olPrivate= 2 '非公開
Const olImportanceLow=0 '重要度低い
Const olBusy = 2 '予定あり。
Const olFree = 0 '予定なし。
Const olOutOfOffice = 3 '外出中。
Const olTentative = 1 '仮の予定あり。 

'Sub Test() 'VBAに貼りつけたときはここをコメントアウト
Dim strAppointSubject 'As String  '予定の名前
strAppointSubject = "時の記念日テスト設定"
Dim olApp: Set olApp = CreateObject("Outlook.Application")
Dim NS: Set NS = olApp.GetNamespace("MAPI")
Dim oFol: Set oFol = NS.GetDefaultFolder(olFolderCalendar): oFol.Display
olApp.ActiveWindow.WindowState = olNormalWindow
Dim MyITEM As 'Outlook.AppointmentItem
Set MyITEM = olApp.CreateItem(1)
MyITEM.Display
With MyITEM
.Subject = strAppointSubject
.Body = "時の記念日の試験設定です"
.Location = "日本"
.Start = #6/10/2016 8:00:00 AM# '日付リテラル 月日年 時分秒 AM/PMを##で囲む
.End = .Start
.BusyStatus = olFree
'このあとはお好みでBLOCK Start
.AllDayEvent = False '終日か
.Sensitivity = olNormal '内緒？
.Importance = olImportanceNormal '重要度
.ReminderMinutesBeforeStart = 15 '分前にアラームを鳴らす
'ここまで--このあとはお好みで Block End
.Save
.Close olSave
End With
End Sub
```


```vb:VBSCript
'Make時の記念日onOL.VBS
Option Explicit
'OutlookのVBAでは不要
Const olFolderCalendar = 9
Const olNormalWindow=2
Const olAppointItem=1
Const olSave=0
Const olConfidential=3
Const olNormal =0 '標準
Const olPersonal = 1 '個人用
Const olPrivate= 2 '非公開
Const olImportanceLow=0 '重要度低い
Const olBusy = 2 '予定あり。
Const olFree = 0 '予定なし。
Const olOutOfOffice = 3 '外出中。
Const olTentative = 1 '仮の予定あり。 

'Sub Test() 'VBAに貼りつけたときはここをコメントアウト
Dim strAppointSubject 'As String  '予定の名前
strAppointSubject="時の記念日テスト設定"
Dim olApp :Set olApp = CreateObject("Outlook.Application")
Dim NS :Set NS = olApp.GetNamespace("MAPI")
Dim oFol  :set oFol=NS.GetDefaultFolder(olFolderCalender):oFol.Display
olApp.Activewindow.WindowState=olNormalWindow
Dim MyITEM   'As Outlook.AppointmentItem :Set MyItem = olApp.CreateItem(1)       
myITEM.Display
With MyITEM
.Body="時の記念日の試験設定です"
.Location="日本"
.Start=#6/10/2016 08:00:00AM# '日付リテラル 月日年 時分秒 AM/PMを##で囲む
.End=#6/11/2016 08:00:00AM#
'このあとはお好みでBLOCK Start
.AllDayEvent=False '終日か
.Sensitivity = olNormal
.IsRecurring＝False
.Importance=olImportanceNormal
.BusyStatus=olFree 
.ReminderMinutesBeforeStart =15 '分前にアラームを鳴らす
'ここまで--このあとはお好みで Block End
.Save
.Close
End With
'End Sub 'VBAのとき必要
```
　テンプレートのコツですがConstがやたらにあるのが抵抗を感じるでしょう。
　これはConstをあらかじめ作っておくことで、Outlookの定数を参照することなく設定できるようにするためです。
　一見見づらいですがこのようにしておくと毎回ヘルプを引かなくてよいです。
　また重複が出ないように、予定なしで設定するとこうした記念日も入力することができるわけです。

##山の日の設定
それでは次に山の日を作ってみましょう。今年(2016年)から始まる定期的な予定です。
古いアウトルックだと山の日は入っていませんが、VBSCRIPTで設定できます。

```vb:VBSCript:
' Make山の日onOL.VBS
Option Explicit
'Sub Test() 'VBAに貼りつけたときはここをコメントアウト
Dim strAppointSubject 'As String  '予定の名前
strAppointSubject = "山の日"
Dim olApp: Set olApp = CreateObject("Outlook.Application")
Dim NS: Set NS = olApp.GetNamespace("MAPI")
Dim oFol: Set oFol = NS.GetDefaultFolder(9): oFol.Display
Dim MyITEM 'As Outlook.AppointmentItem
Dim oPattern 'As Outlook.RecurrencePattern
Set MyITEM = olApp.CreateItem(1)
MyITEM.Display
olApp.ActiveWindow.WindowState = 2
    MyITEM.Subject = "山の日"
    Set oPattern = MyITEM.GetRecurrencePattern
With oPattern
    .Interval = 1
    .Occurrences = 10
    .PatternStartDate = #8/11/2016#
    .StartTime = #12:00:00 AM#
    .Duration = 24 * 60
    .NoEndDate = True
    .RecurrenceType = 6
End With
With MyITEM
.Subject = strAppointSubject
.Body = "山の日は2016/8/11からです"
.Location = "日本"
.AllDayEvent = True
.BusyStatus = 0
.Save
.Close 0
End With
'End Sub
```

これはConstの定数、つまり列挙体(Enum)をすべて数字にしたものです。
これはあとで検証しにくいです。
ちなみに定数についてはolSaveがいくつであるかは、
Visual Basic Editorを起動しF2を開き、検索欄に定数をいれるとわかります。
だからConstの定数は、列挙体と同じ名前にしておく方がよいわけです。
参考：
[[方法] 終日イベントの予定を作成する](https://msdn.microsoft.com/ja-jp/library/office/ff184629.aspx?f=255&MSPPError=-2147217396)
>予定を終日イベントにするには、Startプロパティをイベントが開始する日の12:00 A.M. (午前 0 時) に設定し、End プロパティをイベントが終了する日の翌日の 12:00 A.M. に設定します。Start または End の時刻を 12:00 A.M. 以外の日時の値に設定すると、その予定は終日イベントではなく複数日の予定になります。

これにならって開始時は8/11　12：00：00AMにします

##メールの送信も
　次に何百ものアクセスやエクセルに張り付けた連絡先にメールを送りたい。あなたはまさか手作業でやってないですよね？
　これもVBScriptでできます。もちろんオフィスが入っているという前提ですが。
　まあ山の日で盛り上がったのでまたの機会に。
[Office Space: Microsoft Outlook から定期的な予定の一覧を取得する](https://technet.microsoft.com/ja-jp/library/ee692908.aspx)
Constの名前、数はこちらを参照してください
[列挙体 (Outlook)](https://msdn.microsoft.com/ja-jp/library/office/ff860961.aspx)
C#
[How to: Create an Annual Recurring Appointment That Uses a YearNth Pattern](https://msdn.microsoft.com/en-us/library/office/ff184611.aspx)

##補足
この記事は2016年06月10日に書いたものですが、公式は2016年07月14日に[Outlook 2016/2013 で祝日として山の日を追加する方法](https://blogs.technet.microsoft.com/outlooksupportjp/2016/07/14/yamanohi/) をブログで書いていたようです。Microsoftがこの記事を見てブログを出したのかな...
しかしWeb版のOutlookでは2017年は山の日が表示されないケースがあったようです。[Outlook カレンダーで「山の日」が表示されない-世の中は不思議なことだらけ 2017/06/30](http://snow-white.cocolog-nifty.com/first/2017/06/outlook-8584.html)

##[追記2020/09/10]Microsoft推奨のOUTLOOK.HOlを編集する方法 Outlook2010 Outlook2013は重要
[Outlook にて祝日をカスタマイズする方法 https://support.microsoft.com/ja-jp/help/4495698](https://support.microsoft.com/ja-jp/help/4495698)
これがMicrosoft公式の方法である。重要なのはOutlook2013の祝日データは2022年までしかはいっていないことである。最終的にもう少し伸びるかもしれないが、現在の最新版のOutlook2019でも2012年から2026年までで過去に遡ると祝日は正確に表示されない。
それにしても平文のテキストファイルなのには驚く。

>延長サポートとなっている Outlook 2010/Outlook 2013 では、OUTLOOK.HOL ファイルが更新されないため、この方法で新しい祝日をカスタマイズできます。

と言っているのは延長サポートを超えて使うユーザーを想定して延長サポートを超えて使う欠点の一つは祝日データが更新されないということなる。
###OUTLOOK.HOlの場所はバージョン、64/32bit C2R版で異なる
<UL>
<li>Outlook 2013 64bit日本語版1041 `%PROGRAMFILES%\Microsoft Office\Office15\1041\OUTLOOK.HOl`
<li>Outlook 2016 64bit日本語版1041 `%Programfiles%\Microsoft Office\Office16\1041\OUTLOOK.HOL`
<li>C2R 版Outlook 2016/2019だと 64bit日本語版1041　`%Programfiles%Microsoft Office\root\Office16\1041\OUTLOOK.HOL`
<Li>64bit OS で32bitだと%PROGRAMFILES(x86)%になる。
<Li>ファイルの場所はバージョン、64/32bit C2R版で異なる。
</UL>
###メモ帳で開いて編集
<OL>
<li>Notepad メモ帳で開きます。
<LI>CTRL+F "[日本]"
<LI>[日本] 194
<LI>日本の隣にある数字をいったんメモ（これが休日の総数）
<LI>削除したら減少させる
<LI>追加したら加算する
<LI>書式:祝日名半角コンマ2020/9/23 例:`架空の休日,2020/9/22`
</OL>

####OUTLOOK.HOlをカスタマイズする方法の短所
<UL>
<LI>1日単位でしか設定できない 2020/9/21-2020/9/22は不可
<LI>毎年だからといっても　元旦,1/1のように年を省略することができないため、1年1年設定する必要がある。
<LI>この方法だと日本カテゴリの祝日を追加、削除できるが、日本そのもののカテゴリを登録している必要がある。
<LI>過去にこの方法で追加していた場合は重複する恐れがある。削除の手順を踏む必要がある。
<LI>VBSはスクリプトさえ配布できれば設定できるが、OUTLOOK.HOL ファイルはシステム ファイルのため、ユーザーに管理者権限がないとファイルの変更または上書きができず設定がそもそもこのカスタマイズする方法は使えない。
</UL>
というわけで年単位で設定できるものは、VBSを使う方法が簡便であるうえに、さらに管理者権限のためにカスタマイズできない場合もある。
他方、VBSCriptは管理者権限に関係がなく設定できる（VBSそのものの動作を止めることもありうるが）。創立記念日のようなものはカテゴリを設定すると同じような動きになり、まとめて表示や削除も可能となる。比較するとVBSで設定する方法が大変有効だということになる。