Outlook 研究所

2016年2月6日

HTML メールでの OLE パッケージ オブジェクトを制限する方法

Filed under: Outlook Tips — outlooklab @ 12:00 PM

015 年の 12 月に Outlook でメッセージをプレビューしただけで悪意のあるコードを実行されてしまうという Word の脆弱性に対応するセキュリティ修正プログラムがリリースされましたが、それに関連して以下のブログの脆弱性が話題になっているようです。

OLEOutlook – bypass almost every Corporate security control with a point’n’click GUI

このブログで記載されている脆弱性というのは、以下のような手順でメールを送信することにより、exe ファイルを意図せず実行させられるというものです。

  1. HTML 形式のメールを作成し、[挿入]-[オブジェクト] でパッケージとして exe ファイルを埋め込みます。
      (このとき、アイコンや名前を変更し、通常のファイルのように偽装できます。)
  2. 作成したメールを送信前の状態で下書きや msg ファイルとして保存し、別のメールに添付して送信します。
  3. 受信側で添付された下書きメールに表示されているオブジェクトをダブルクリックすると、埋め込んだ exe ファイルが実行できてしまいます。

この問題に対する対処方法としては、mso を危険な添付ファイルの拡張子としてブロックする設定を行うというものがあります。
Outlook での拡張子による添付ファイルのブロック方法はいくつかありますが、ユーザー権限でできる方法は以下のレジストリ設定となります。

  キー: HKEY_CURRENT_USER\Software\Microsoft\Office\<Ver>\Outlook\Security
  名前: Level1Add
  種類: REG_SZ
  値: .mso

※  <ver> は Outlook のバージョン (2007 = 12.0、2010 = 14.0、2013 = 15.0、2016 = 16.0)

上記以外の設定方法については Outlook 2013 で添付ファイル設定を計画する をご覧ください。

HTML メールで OLE オブジェクトを埋め込んだ場合は拡張子が .mso となるので、上記の設定により OLE パッケージ オブジェクトが埋め込まれたとしても実行ができなくなります。
ただし、この設定を行うと、パッケージ オブジェクトだけでなく、Excel ワークシートや PowerPoint スライドなど他の OLE オブジェクトも実行できなくなります。
そのため、Excel ワークシートを埋め込んで返信時にフォームのように入力させたり、AllowInplaceOleActivation レジストリの設定により受信時の OLE オブジェクト実行を可能としているような場合には注意が必要です。

なお、上記のブログでは回避策として ShowOLEPackageObj というレジストリ設定を 0 にするというものが紹介されていますが、これは回避策とはなりません。
何故なら、ShowOLEPackageObj が有効なのはリッチテキスト形式で本文に OLE パッケージ オブジェクトが埋め込まれている場合であり、HTML 形式のメールには作用しないためです。

また、ShowOLEPackageObj は既定で 0 (= 表示しない) となっているため、通常はリッチテキスト形式で上記の手順を実行しても OLE パッケージ オブジェクトは表示すらされません。
意図的に ShowOLEPackageObj を 1 と設定している場合に限り、既定の 0 に戻すことで上記のような手順による攻撃を防ぐことができるようになります。

メッセージ形式により OLE オブジェクトの動作や設定が変わり、ちょっとわかりにくいかと思いましたので、整理してみました。

HTML 形式の場合

  • 既定の動作
    • 受信メール: OLE オブジェクトは画像として表示され、実行はできない
    • 送信前のメール: OLE オブジェクトの実行ができる
  • Level1Add などにより .mso を制限する拡張子として追加
    • 受信メール・送信前のメールとも、OLE オブジェクトは画像として表示され、実行できなくなる
  • ShowOLEPackageObj を設定
    • HTML 形式では無効

リッチテキスト形式の場合

  • 既定の動作
    • OLE パッケージ オブジェクトは表示されない
    • 受信メール: パッケージ以外のオブジェクトは画像として表示され、実行はできない
    • 送信前のメール: パッケージ以外のオブジェクトの実行ができる
  • ShowOLEPackageObj を 1 とした場合の動作
    • 受信メール: パッケージを含む OLE オブジェクトは画像として表示され、実行はできない
    • 送信前のメール: パッケージを含む OLE オブジェクトの実行ができる
  • Level1Add などにより .mso を制限する拡張子として追加
    • リッチテキスト形式では無効

2016年1月30日

予定表を定期的に ics ファイルに保存し、自動で特定のアドレスに送信するマクロ

コメントにて以下のご要望をいただきました。


ご質問】予定表を定期的にicsファイルに落とし、自動で特定のアドレスに送信する

いつも参考にさせていただいております。
当方、マクロは全くの素人のため、当サイトのマクロ
をそっくり使わせていただいており、非常に助かっております。

今回、どうしても欲しいマクロで、どこのサイトを探しても
それらしい物が無かったため、要望させていただきます。

outlook2007使用

・他の人と共有している予定表を、icsファイルに変換し、それを特定のアドレスに
送信する

・上記メールを決まった時間 or outlook起動時など定期的に自動で送信する

そんな都合の良いマクロは作成可能でしょうか?

素人の為どの位ムチャな要望なのかも分かっておりません。

大変申し訳ありません、何卒ご教示ねがいます。



Outlook のオブジェクト モデルには、予定アイテム単体を iCal ファイルに保存するメソッドは用意されていますが、予定表全体を保存するメソッドはありません。
そのため、一つ一つのアイテムを iCal で保存し、それをまとめた iCal ファイルを作成するというような処理が必要となります。
また、定期的にマクロを実行する方法としては、マクロ実行用の仕事アイテムを用意し、そのアイテムのアラームが表示されるタイミングで処理を実行する、というようなものがあります。

以下のマクロは、起動時に iCal ファイルを送信し、さらに仕事アイテムを使って 1 日おきに iCal ファイルを送信するマクロです。
件名や宛先などを適宜変更して使用してください。
なお、予定表に大量のアイテムがある場合にはマクロの実行に時間がかかったり、iCal ファイルのサイズが非常に大きくなったりする可能性があるのでご注意ください。

' ここをトリプルクリックでマクロ全体を選択できます。
' 定期実行のためのタスクの件名
Const CALSEND_ITEM = "予定表自動送信タスク"
' iCal を送信するメールの件名
Const MSG_SUBJECT = "予定表送信"
' iCal を送信するメールの本文
Const MSG_BODY = "予定表を送信します"
' iCal を送信するメールの宛先
Const MSG_TO = "user1@example.com"
' iCal のローカル保存用ファイル名
Const ATT_FILE = "c:\temp\予定表.ics"
' iCal 作成の作業ファイル名
Const TEMP_FILE = "c:\temp\~temp~.ics"
'
' 起動時に自動実行されるルーチン
Private Sub Application_Startup()
    Dim fldTask As Folder
    Dim objTask As TaskItem
    Set fldTask = Session.GetDefaultFolder(olFolderTasks)
    ' 自動送信タスクの検索
    Set objTask = fldTask.Items.Find("[件名]='" & CALSEND_ITEM & "'")
    If objTask Is Nothing Then
        ' 自動送信タスクが存在しなければ作成
        Set objTask = fldTask.Items.Add
        objTask.Subject = CALSEND_ITEM
    End If
    ' 自動送信タスクのアラームを 1 日後に設定
    objTask.ReminderTime = DateAdd("d", 1, Now)
    objTask.ReminderSet = True
    objTask.Save
    ' iCal 送信
    SendMyCalendar
End Sub
'
' アラーム表示で実行されるルーチン
Private Sub Application_Reminder(ByVal Item As Object)
    ' 自動送信タスクだったら
    If Item.Subject = CALSEND_ITEM Then
        ' 一時的にアラームをオフ
        Item.ReminderSet = False
        Item.Save
        ' 自動送信タスクのアラームを 1 日後に設定
        Item.ReminderTime = DateAdd("d", 1, Now)
        Item.ReminderSet = True
        Item.Save
        ' iCal 送信
        SendMyCalendar
    End If
End Sub
'
' 予定表を iCal で送信するルーチン
Public Sub SendMyCalendar()
    On Error Resume Next
    ' ADO の定数設定
    Const adTypeText = 2
    Const adTypeBinary = 1
    Const adSaveCreateOverWrite = 2
    '
    Dim fldCalendar As Folder
    Dim oneAppt As AppointmentItem
    Dim stmWrite 'As ADODB.Stream
    Dim stmRead 'As ADODB.Stream
    Dim strText As String
    Dim binIcs As Variant
    Dim msgSend As MailItem
    ' UTF-8 で iCal ファイルを作成するためのストリーム作成
    Set stmWrite = CreateObject("ADODB.Stream")
    With stmWrite
        .Type = adTypeText
        .Charset = "UTF-8"
        .Open
        ' iCal のヘッダーを書き込み
        .WriteText "BEGIN:VCALENDAR" & vbCrLf
        .WriteText "PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN" & vbCrLf
        .WriteText "VERSION:2.0" & vbCrLf
        .WriteText "METHOD:PUBLISH" & vbCrLf
        .WriteText "X-WR-CALNAME:" & Session.CurrentUser & vbCrLf
    End With
    ' 既定の予定表を取得
    Set fldCalendar = Session.GetDefaultFolder(olFolderCalendar)
    ' すべての予定アイテムを処理
    For Each oneAppt In fldCalendar.Items
        Err.Clear
        ' 単一のアイテムを iCal として保存
        oneAppt.SaveAs TEMP_FILE, olICal
        If Err.Number = 0 Then
            ' iCal ファイルを UTF-8 として読み込む
            Set stmRead = CreateObject("ADODB.Stream")
            With stmRead
                .Type = adTypeText
                .Charset = "UTF-8"
                .Open
                .LoadFromFile TEMP_FILE
                strText = .ReadText
                .Close
            End With
            ' iCal データのうち VEVENT の部分だけ抜きとり
            strText = Mid(strText, InStr(strText, "BEGIN:VEVENT"))
            strText = Left(strText, InStr(strText, "END:VCALENDAR") - 1)
            ' 送信用 iCal ファイルへ書き込み
            stmWrite.WriteText strText ' adWriteChar
        End If
        DoEvents
    Next
    '
    With stmWrite
        ' iCal ファイルの終わりを書き込み
        .WriteText "END:VCALENDAR" & vbCrLf
        ' iCal ファイルの保存
        .SaveToFile ATT_FILE, adSaveCreateOverWrite
        .Close
    End With
    ' iCal ファイルを添付してメールを送信
    Set msgSend = CreateItem(olMailItem)
    msgSend.Subject = MSG_SUBJECT
    msgSend.Body = MSG_BODY
    msgSend.To = MSG_TO
    msgSend.Attachments.Add ATT_FILE
    msgSend.Send
End Sub

マクロの登録方法やメニューへの追加について

2016年1月23日

宛先に応じて署名をクイックパーツから挿入するマクロ

コメントにて以下のご要望をいただきました。


お世話になっております。
業務上 outlookを多用しており 作業の効率化を図るため
活用させていただいております。

さて過去にも “署名” について、いくつかご投稿されておりますが
署名を何パターンか登録し 送信先によって、差し込む署名を変えたいと考えております。
過去のサンプルを基に 構文を探しましたがわかりませんでした。
お手数ですが ご教授の程 宜しくお願いいたします。
また クイックパーツで登録した文章も 差し込む構文も合わせてご教授いただければ幸いです。

‘ 署名の置き換え
Set objWord = ActiveInspector.WordEditor
Set objSignature = objWord.Bookmarks(“_MailAutoSig”)
objSignature.Range.Text = ANOTHER_SIGNATURE

バージョン:OutLook2010 SP2



宛先により差し込む署名を変えるとなると、宛先と署名を紐づけるものが必要となります。
今回のマクロでは、宛先のアドレスに該当する連絡先を検索し、見つかった連絡先の分類項目の文字列を名前とするクイックパーツで署名を置き換えるというものにしてみました。
マクロは以下の通りです。

' ここをトリプルクリックでマクロ全体を選択できます。
Public Sub ChangeSignatureByRecipients()
    Dim objRecip As Recipient
    Dim objContact As ContactItem
    '
    For Each objRecip In ActiveInspector.CurrentItem.Recipients
        ' 受信者のアドレスに該当する連絡先を検索
        Set objContact = FindContactByAddress(objRecip.Address)
        If Not objContact Is Nothing Then
            ' 連絡先の分類項目が設定されているか確認
            If objContact.Categories <> "" Then
                ' 分類項目の文字列を名前とするクイックパーツの埋め込み
                If ReplaceSignatureByQuickParts(objContact.Categories) Then
                    Exit For
                End If
            End If
        End If
    Next
End Sub
'   アドレスから連絡先を検索する関数
Private Function FindContactByAddress(strAddress As String)
     Dim objContacts 'As Folder
     Dim objContact As ContactItem
     '
     Set objContacts = Session.GetDefaultFolder(olFolderContacts)
     Set objContact = objContacts.Items.Find("[Email1Address] = '" & strAddress _
         & "' or [Email2Address] = '" & strAddress _
         & "' or [Email3Address] = '" & strAddress & "'")
     Set FindContactByAddress = objContact
End Function
'   指定した名前のクイックパーツで署名を置き換える関数
Private Function ReplaceSignatureByQuickParts(strName As String)
    On Error Resume Next
    Dim oDoc As Object
    Dim oWord As Object
    Dim strTemp As String
    Dim oParts As Object
    Dim oSignature As Object
    ReplaceSignatureByQuickParts = False
    ' 現在表示しているメールの Word コンポーネントを取得
    Set oDoc = ActiveInspector.WordEditor
    Set oWord = oDoc.Parent
    ' メールの標準テンプレートからクイックパーツを取得
    strTemp = oWord.Options.DefaultFilePath(2) & "\NormalEmail.dotm"
    Set oParts = oWord.templates(strTemp).BuildingBlockEntries(strName)
    ' クイックパーツが見つからなければ中断
    If oParts Is Nothing Then Exit Function
    ' メールの署名をクイックパーツで置き換え
    Set oSignature = oDoc.Bookmarks("_MailAutoSig")
    oParts.Insert Where:=oSignature.Range, RichText:=True
    ReplaceSignatureByQuickParts = True
End Function

マクロの登録方法やメニューへの追加について

2016年1月16日

Outlook 2016/2013/2010 の累積的な修正プログラム 2016 年 1 月分がリリース

Filed under: 修正プログラム — outlooklab @ 12:00 PM

1/12 に Office 2016、Office 2013 および Office 2010 の累積的な修正プログラム (以下、CU) がリリースされました。
以下は各製品のそれぞれの KB へのリンクです。

Office 2016

Outlook 2016 の修正

Outlook 2016 (KB3114532) は、2016 年 1 月 12 日更新
Outlook 2016 の不具合が 2 件修正されています。

Office 2016 共通コンポーネントの修正

Office 2016 (KB3114536) は、2016 年 1 月 12 日更新
Outlook 2016 関連の不具合が 1 件修正されています。

Office 2013

Outlook 2013 の修正

January 12, 2016, update for Outlook 2013 (KB3114500)
1 件の機能追加と 2 件の不具合修正が行われています。

Office 2013 共通コンポーネントのセキュリティ修正

MS16-004: Description of the security update for Office 2013: January 12, 2016
セキュリティに関するものではありませんが、Outlook 2013 がハングアップする不具合が修正されています。

Office 2010

Outlook 2010 の修正

2016 年 1 月 12 日は、Outlook 2010 (KB3114570) の更新します。
1 件の不具合修正が行われています。

その他の修正

他の Office 製品の修正へのリンクは、以下の KB にまとめて記載されています。

2016 年 1 月 12 日は、Office を更新します。

2016年1月9日

検索を連続して実行するマクロ

コメントにて以下のご要望をいただきました。


Outlook2010でメールを検索するときにいつも次のような使い方をしていますが、もう少し効率よくできないものかと思っています。
下記手順のうちc)~f)をマクロで簡単にできないでしょうか?
あるいは、最悪、c)とd)の所だけでもショートカットキーで一発で検索ダイアログボックスが出せるようになるとうれしいのですが。
ご教示いただきたく、よろしくお願いいたします。

a) クイック検索でメール本文に”xyz”という文字列を含むメールを検索
b) 検索で見つかった一番上のメールを選択
c) Ctrl+Gで「検索と置換」ダイアログボックスを表示
d) 「検索」タブに切り替えて”xyz”という文字列を検索
e) そのメールの最後まで検索したら、次のメールを選択
f) c)~e)を繰り返す



Outlook では Explorer で次のメールを選択するという方法が用意されていないため完全に自動化はできなかったのですが、マクロを使用して以下のような手順にはできます。

  1. SearchStart マクロを実行し、検索文字列を入力すると Outlook で検索が行われる
  2. 検索結果のメールのうち一つを選択すると、そのメールに含まれる文字列を自動的に検索する
  3. SearchNext マクロを実行すると、同じメール本文の中をさらに検索する
  4. メールの最後まで検索したら、手動で別のメールを選択すると 2. の状態になる
  5. 検索を終了するときには SearchStop マクロを実行する

上記を実現するマクロは以下のようになります。 SearchStart、SearchNext、SearchStop をクイック アクセス ツールバーに登録しておけばより便利になると思います。

' ここをトリプルクリックでマクロ全体を選択できます。
Dim WithEvents myExplorer As Explorer
Dim mySearchWord As String
Dim myFind As Object
'
' 検索を開始するマクロ
Public Sub StartSearch()
    mySearchWord = InputBox("検索文字列:")
    Set myExplorer = ActiveExplorer
    myExplorer.Search mySearchWord, olSearchScopeCurrentFolder
End Sub
'
' 次の文字列を検索するマクロ
Public Sub NextSearch()
    If Not myFind Is Nothing Then
        myFind.Execute
    End If
End Sub
'
' 検索を終了するマクロ
Public Sub StopSearch()
    myExplorer.ClearSearch
    Set myExplorer = Nothing
    Set myFind = Nothing
End Sub
'
' 検索結果のアイテムをクリックした際に発生するイベントで本文検索開始
Private Sub myExplorer_SelectionChange()
    On Error Resume Next
    Dim objWord As Object
    If myExplorer.Selection.Count = 0 Then
        Exit Sub
    End If
    Set objWord = myExplorer.Selection(1).GetInspector().WordEditor
    DoEvents
    Set myFind = objWord.Parent.Selection.Find
    With myFind
        .ClearFormatting
        .Text = mySearchWord
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchByte = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = False
        .MatchFuzzy = True
        .Execute
    End With
End Sub
'
' フォルダーが切り替わったら検索を終了させるための記述
Private Sub myExplorer_FolderSwitch()
    StopSearch
End Sub

マクロの登録方法やメニューへの追加について

2015年12月26日

Outlook の予定表に「山の日」を含む 2016 年以降の祝日を追加するスクリプト

Filed under: スクリプト — outlooklab @ 12:00 PM

Outlook の予定表に 2013 年以降の祝日を追加するスクリプトのコメントにて以下のご質問をいただきました。


山の日が追加されたのですが、どうしたらよいでしょうか。



山の日は 2014 年に制定された新しい祝日なので、それ以前にリリースされた Outlook 2013 などの祝日情報には含まれていません。
Outlook 2016 の祝日情報には山の日が含まれていますが、すでに以前のバージョンでインポート済みであると、既存の祝日が重複してインポートされる動作となってしまいますので、祝日を追加するスクリプトを作りました。

スクリプトは以下の通りです。このスクリプトを AddHoliday.vbs という名前で保存し、ダブルクリックして実行すると、2013 年以降の祝日が Outlook の既定の予定表に追加されます。

' - ここをトリプル クリックするとすべてのコードが選択できます。
'
Option Explicit
Const olFolderCalendars = 9
Const olAppointmentItem = 1
Const olFree = 0
Dim objOutlook
Dim objSession
Dim objCalendar
Dim colEvents
Dim objHoliday
Dim iYear
' Outlook アプリケーション オブジェクトの取得
Set objOutlook = CreateObject("Outlook.Application")
' Namespace オブジェクトの取得
Set objSession = objOutlook.GetNamespace("MAPI")
' 予定表フォルダの取得
Set objCalendar = objSession.GetDefaultFolder(olFolderCalendars)
Set colEvents = objCalendar.Items
' 予定表から 2016 年以降の祝日のみを取得
Set objHoliday = colEvents.Find("[分類項目] = '祝日' AND [開始日] >= '2015/12/31' AND [場所] = '日本'")
' 2016 年以降の祝日を削除
While Not objHoliday Is Nothing
    objHoliday.Delete
    Set objHoliday = colEvents.FindNext
Wend
'
' 2016 年から 2022 年までの祝日を追加
For iYear = 2016 to 2022
    AddNormalHoliday "天皇誕生日", iYear, 12, 23
    AddNormalHoliday "勤労感謝の日", iYear, 11, 23
    AddNormalHoliday "文化の日", iYear, 11, 3
    AddHappyMonday "体育の日", iYear, 10, 2
    AddHappyMonday "敬老の日", iYear, 9, 3
    AddNormalHoliday "山の日", iYear, 8, 11
    AddHappyMonday "海の日", iYear, 7, 3
    AddNormalHoliday "こどもの日", iYear, 5, 5
    AddNormalHoliday "みどりの日", iYear, 5, 4
    AddNormalHoliday "憲法記念日", iYear, 5, 3
    AddNormalHoliday "昭和の日", iYear, 4, 29
    AddNormalHoliday "建国記念の日", iYear, 2, 11
    AddHappyMonday "成人の日", iYear, 1, 2
    AddNormalHoliday "元日", iYear, 1, 1
Next
' 日付が一定でない祝日の追加
AddNormalHoliday "春分の日", 2016, 3, 20
AddNormalHoliday "春分の日", 2017, 3, 20
AddNormalHoliday "春分の日", 2018, 3, 21
AddNormalHoliday "春分の日", 2019, 3, 21
AddNormalHoliday "春分の日", 2020, 3, 20
AddNormalHoliday "春分の日", 2021, 3, 20
AddNormalHoliday "春分の日", 2022, 3, 21
AddNormalHoliday "秋分の日", 2016, 9, 22
AddNormalHoliday "秋分の日", 2017, 9, 23
AddNormalHoliday "秋分の日", 2018, 9, 23
AddNormalHoliday "秋分の日", 2019, 9, 23
AddNormalHoliday "秋分の日", 2020, 9, 22
AddNormalHoliday "秋分の日", 2021, 9, 23
AddNormalHoliday "秋分の日", 2022, 9, 23
'
' 振り替え休日を考慮しない祝日の追加
Sub AddHoliday( sName, dtDay )
    Set objHoliday = objOutlook.CreateItem(olAppointmentItem)
    objHoliday.Subject = sName
    objHoliday.Start = dtDay
    objHoliday.AllDayEvent = True
    objHoliday.Categories = "祝日"
    objHoliday.ReminderSet = False
    objHoliday.BusyStatus = olFree
    objHoliday.Location = "日本"
    objHoliday.Save
    Set objHoliday = Nothing
End Sub
'
' ハッピーマンデーの祝日の追加
Sub AddHappyMonday( sName, iYear, iMonth, iMonday )
    Dim iWk
    Dim iDay
    Dim dtDay
    iWk = Weekday(iYear & "/" & iMonth & "/1" )
    If iWk <= 2 Then
        iWk = iWk + 4
    Else
        iWk = iWk - 3
    End If
    iDay = 7 * iMonday - iWk
    AddHoliday sName, iYear & "/" & iMonth & "/" & iDay & " 00:00 AM"
End Sub
'
' 通常 (振り替え休日あり) の祝日の追加
Sub AddNormalHoliday( sName, iYear, iMonth, iDay )
    Dim iWk
    Dim dtSub
    Dim objHoliday
    AddHoliday sName, iYear & "/" & iMonth & "/" & iDay & " 00:00 AM"
    iWk = Weekday( iYear & "/" & iMonth & "/" & iDay )
    If iWk = 1 Then
        dtSub = CDate(iYear & "/" & iMonth & "/" & iDay)
        Do    ' 振替休日が国民の祝日だったら、翌日に繰り越し
            dtSub = DateAdd("d", 1, dtSub)
            Set objHoliday = colEvents.Find("[分類項目] = '祝日' AND [開始日] >= '" & _
                dtSub & " 00:00 AM' AND [終了日] <= '" & DateAdd("d", dtSub, 1) & _
                "' AND [場所] = '日本'")
        Loop While Not objHoliday Is Nothing
        AddHoliday "振替休日 (" & sName & ")", dtSub & " 00:00 AM"
    End If
End Sub

2015年12月19日

Outlook 2010 の定例外の修正プログラムがリリース

Filed under: 修正プログラム — outlooklab @ 12:00 PM

12/16 に以下の通り Outlook 2010 の修正プログラムがリリースされました。

Outlook 2010 (KB3114560) は 2015 年 12 月 16 日更新

12 月の更新プログラムで発生していた Outlook がセーフモードでしか起動しないという不具合を修正したものです。
こちらは Windows Update では提供されないようなので、12 月の更新プログラムによる修正が直ちに必要という場合は、この修正プログラムを手動で適用する必要があります。

2015年12月12日

Outlook 2016/2013/2010 の累積的な修正プログラム 2015 年 12 月分がリリース

Filed under: 修正プログラム — outlooklab @ 12:00 PM

12/9 に Office 2016、Office 2013 および Office 2010 の累積的な修正プログラム (以下、CU) がリリースされました。
以下は各製品のそれぞれの KB へのリンクです。

Office 2016

Outlook 2016 の修正

December 8, 2015, update for Outlook 2016 (KB3114387)
Outlook 2016 の不具合が 4 件修正されています。

December 8, 2015, update for Outlook 2016 (KB3101550)
Outlook 2016 のデータ損失防止ポリシー表示のコンポーネントの不具合が 2 件修正されています。

Office 2016 共通コンポーネントの修正

December 8, 2015, update for Office 2016 (KB3114391)
Outlook 2016 に関する不具合が 1 件修正されています。

December 8, 2015, update for Office 2016 (KB3114390)
Outlook 2016 に関する不具合が 1 件修正されています。

December 8, 2015, update for Office 2016 (KB3114381)
Outlook 2016 に関する不具合が 1 件修正されています。

 

Office 2013

Outlook 2013 の修正

December 8, 2015, update for Outlook 2013 (KB3114349)
1 件の機能追加と 12 件の不具合修正が行われています。

Office 2013 共通コンポーネントの修正

Office 2013 (KB3114333) は 2015 年 12 月 8 日更新
Outlook 2013 に関する不具合が 3 件修正されています。

Word 2013 のセキュリティ修正

MS15-131: Description of the security update for Word 2013: December 8, 2015
セキュリティに関連するものではありませんが、Outlook 2013 に関する機能追加が 1 件行われています。

Office 2010

Outlook 2010 の修正

Outlook 2010 (KB3114409) は 2015 年 12 月 8 日更新
1 件の機能追加と 4 件の不具合修正が行われていますが、セーフモードでしか起動できなくなるという不具合があるため、現在はダウンロードできなくなっています。

Exchange アドインの修正

Office 2010 (KB2760779) は 2015 年 12 月 8 日更新
1 件の不具合修正が行われています。

その他の修正

他の Office 製品の修正へのリンクは、以下の KB にまとめて記載されています。

December 8, 2015, update for Office

2015年12月5日

メールのスレッドを保持してExcelにエクスポートするマクロ

コメントにて以下のご要望をいただきました。


スレッドを保ったまま、Excelへ書き出すマクロは生成できますか?
例えば、
相手のメールを抜き出し、日付、宛名、件名、本文、を一行でExcelへ抽出する際に、
そのメールに対する自分の返信があった場合は同じ行の本文の横のセルに自分の返信、更に相手からまた返信があった場合は、その横のセルに追加のようにやりとりが同じ行に追加されていく
その他のメールは別の行にみたいな方法をおしえていただけなでしょうか?



Outlook のオブジェクト モデルには Conversation というオブジェクトがあり、スレッドに含まれるアイテムを取得することが可能です。
これを利用すると、特定のスレッドのメールだけ 1 行に出力できます。
なお、Conversation が使えない状況も考えられるため、その場合はメッセージ ヘッダーに含まれる Message-ID と In-Reply-To を使用してスレッドを認識するようにしてみました。
マクロは以下の通りです。

' ここをトリプルクリックでマクロ全体を選択できます。
Public Sub ExportToExcelWithThread()
    Dim appExcel 'As Excel.Application
    Dim objBook 'As Excel.Workbook
    Dim objSheet 'As Excel.Worksheet
    Dim bConvOK As Boolean
    Dim colItems As Items
    Dim objItem 'As MailItem
    Dim c As Integer
    '
    Set appExcel = CreateObject("Excel.Application")
    Set objBook = appExcel.Workbooks.Add()
    Set objSheet = objBook.Sheets(1)
    With objSheet
        .Cells(1, 1) = "スレッド情報"
        .Cells(1, 2) = "日付"
        .Cells(1, 3) = "宛先"
        .Cells(1, 4) = "Cc"
        .Cells(1, 5) = "差出人"
        .Cells(1, 6) = "件名"
        .Cells(1, 7) = "本文"
    '
        Set colItems = ActiveExplorer.CurrentFolder.Items
        colItems.Sort "送信日時"
        bConvOK = ActiveExplorer.CurrentFolder.Store.IsConversationEnabled
        For Each objItem In colItems
            If bConvOK Then
                ExportThreadByConversation objItem, objSheet
            Else
                ExportThreadByMessageId objItem, objSheet
            End If
        Next
        For c = 2 To .UsedRange.Columns.Count Step 6
            .Cells(1, c) = "日付"
            .Cells(1, c + 1) = "宛先"
            .Cells(1, c + 2) = "Cc"
            .Cells(1, c + 3) = "差出人"
            .Cells(1, c + 4) = "件名"
            .Cells(1, c + 5) = "本文"
        Next
    End With
    '
    appExcel.Visible = True
    objBook.Windows(1).Visible = True
End Sub
'
Private Sub ExportThreadByConversation(objItem, objSheet)
    Const PR_CONVERSATION_ID = "http://schemas.microsoft.com/mapi/proptag/0x30130102"
    Dim strConvID As String
    Dim r As Integer
    Dim c As Integer
    '
    With objItem.PropertyAccessor
        strConvID = .BinaryToString(.GetProperty(PR_CONVERSATION_ID))
    End With
    r = 2
    While objSheet.Cells(r, 1) <> ""
        If objSheet.Cells(r, 1) = strConvID Then
            Exit Sub
        End If
        r = r + 1
    Wend
    objSheet.Cells(r, 1) = strConvID
    c = 2
    EnumConversation objItem.GetConversation().GetRootItems, objSheet, r, c
End Sub
'
Private Sub EnumConversation(colItems As SimpleItems, objSheet, r As Integer, c As Integer)
    Dim objItem 'As MailItem
    Dim conv As Conversation
    Dim colSubItems As SimpleItems
    For Each objItem In colItems
        WriteCell objItem, objSheet, r, c
        c = c + 6
        Set conv = objItem.GetConversation()
        Set colSubItems = conv.GetChildren(objItem)
        If colSubItems.Count > 0 Then
            EnumConversation colSubItems, objSheet, r, c
        End If
    Next
End Sub
'
Private Sub ExportThreadByMessageId(objItem As MailItem, objSheet)
    Const PR_INTERNET_MESSAGE_ID = "http://schemas.microsoft.com/mapi/proptag/0x1035001e"
    Const PR_IN_REPLY_TO_ID = "http://schemas.microsoft.com/mapi/proptag/0x1042001e"
    Dim strMsgID As String
    Dim strRepID As String
    Dim r As Integer
    Dim c As Integer
    Dim bFound As Boolean
    '
    With objItem.PropertyAccessor
        strMsgID = .GetProperty(PR_INTERNET_MESSAGE_ID)
        strRepID = .GetProperty(PR_IN_REPLY_TO_ID)
    End With
    '
    With objSheet
        c = 2
        If strRepID = "" Then
            r = .UsedRange.Rows.Count + 1
        Else
            bFound = False
            r = 2
            While (Not bFound) And .Cells(r, 1) <> ""
                If InStr(.Cells(r, 1), strRepID) > 0 Then
                    While .Cells(r, c) <> ""
                        c = c + 6
                    Wend
                    bFound = True
                Else
                    r = r + 1
                End If
            Wend
        End If
        .Cells(r, 1) = .Cells(r, 1) & strMsgID
        WriteCell objItem, objSheet, r, c
    End With
End Sub
'
Private Sub WriteCell(objItem, objSheet, r As Integer, c As Integer)
    With objSheet
        .Cells(r, c) = objItem.SentOn
        .Cells(r, c + 1) = objItem.To
        .Cells(r, c + 2) = objItem.CC
        .Cells(r, c + 3) = objItem.Sender
        .Cells(r, c + 4) = objItem.Subject
        .Cells(r, c + 5) = objItem.Body
    End With
End Sub

マクロの登録方法やメニューへの追加について

2015年11月28日

特定のフォルダー以下のサブフォルダーの未読メールをまとめて管理する方法

Filed under: Outlook Tips — outlooklab @ 12:00 PM

コメントにて以下のご要望をいただきました。


Outlook2010で、部署名フォルダの下に各社員のフォルダをつくる等、階層構造を使って管理しております。
その際、下記の2つを実行できたらと考えているのですが、そのようなスクリプトは作成可能でしょうか。

1) サブフォルダ以下の未読数を表示する機能。
部署名フォルダにサブフォルダ(各社員)の未読数の合計を表示。

2) フォルダ及びサブフォルダの未読を一括して既読にする機能。
部署名フォルダを選択した際に、部署フォルダ及びサブフォルダ(各社員)の未読を一括して既読にできる機能。

もし方法がありましたら、教えていただければ大変助かります。



このようなご要望であれば、検索フォルダーでも実現可能でしょう。
既定の「未読メール」検索フォルダーはメールボックスのすべての未読メールが表示されますが、カスタマイズした検索フォルダーを作ることで特定のフォルダーの下のサブフォルダーすべての未読メールだけを検索することが可能です。
そのような検索フォルダーを作成する手順は以下の通りです。

  1. フォルダー ツリー上の [検索フォルダー] を右クリックし、[新しい検索フォルダー] をクリックします。
  2. [検索フォルダーを選択してください] の下のボックスをスクロールし、一番下の [カスタム検索フォルダーを作成する] を選択します。
  3. [選択] ボタンをクリックします。
  4. [名前] に適切な名前 (xx フォルダーの未読 など) を入力します。
  5. [条件] をクリックし、[詳細設定] タブで [開封状況] をオンにし、右のドロップダウンで [未読] を選択して [OK] をクリックします。
  6. [参照] をクリックします。
  7. 既定ではメールボックスのルート フォルダーのチェックボックスがオンになっているので、これをオフにします。
  8. 部署名のフォルダーのチェックボックスをオンにし、ダイアログ下部の [サブフォルダーも検索する] をオンにして [OK] をクリックします。
  9. [OK] をクリックします。

このようにして作成した検索フォルダーには指定されたフォルダー以下のすべてのサブフォルダーの未読メールがリストアップされ、検索フォルダーの右の数字はすべてのサブフォルダーの未読メールの合計数となります。
また、検索フォルダーを右クリックし、[すべて開封済みにする] をクリックすれば、サブフォルダーのすべての未読メールを既読にすることもできます。

次ページへ »

Rubric テーマ. WordPress.com で無料サイト・ブログを作成.

フォロー

新しい投稿をメールで受信しましょう。

現在98人フォロワーがいます。