OUTLOOK VBA 選択した送信済みメールを(BCCで)再送信する

#コード
##前提
添付ファイルを送信したTo Cc Bccすべての宛先に、BCCでパスワードを送信する
##特徴
 - 送信済みになったメールをエクスプローラーで選択した状態で、マクロを起動すると送信メールが立ち上がる
 - メール本文(MailItem.Body)を作っておくと、再送信する内容を決められる。今回はパスワードを送信するが、添付ファイルの内容の訂正などいろいろな再送信に使える。
 - BCCの宛先をPropertyAccessorで拾うため、すべてBCCで送信する。Toに入れるとBCCが見えてしまう。そうした混乱を防ぐため、すべてBCCで送信を強制する。
 - 送信済みアイテムに入ったメールを開くことなく、選択したメールの宛先をすべてBCCにして送信する
 - Explorerが送信済みフォルダかそのサブフォルダの確認
 - 上記はSplitでフォルダ名を分割して確認します。
 - タイトルの省略：送信したメールのタイトルを漫然と繰り返すのではなく、不要な文字を削除し、全角を半角に変え、15文字程度にします。そして送信日時を加えています。

##イメージ
送信済みアイテム(メールが送信された後はいるフォルダ)英語ではSent
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/34eaa7c1-980e-0cc0-5d9a-4cc7e2389f09.png)

現在BCCで送信された２つのメールを選択している。しかしBCCでのみ送信されているため誰に送信したかはわからない。本当はこれに添付ファイルがつく。通常は再送信をするにはメールを開いてからしか指定できないが、ここで以下のマクロを起動するだけで送信メールが作成される。直接は送信されない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/4fcb319a-6251-eed6-e983-69a41cd56ba9.png)


##コード(Outlook VBA)

```vb
Sub SendPwMail()
'For Outlook
'Outlook 2007 Later
'送信済みフォルダで選択した添付ファイル付きメールの相手方に
'パスワードを送付する
'この場合,ToもCCもすべてBCCに変換する
'署名は無効化して独自に署名を添付する
'
Dim myItem As MailItem, objMail As MailItem
Dim snItem As Outlook.MailItem
Dim NS As Outlook.NameSpace
Dim olIns As Outlook.Inspector
Dim EX As Outlook.Explorer
Dim recips As Outlook.Recipients
Dim recip As Outlook.Recipient
Dim objFol As Outlook.Folder
Dim strFile As String, strSender As String, DT As Date
Dim adreadall As String
Dim objTempFile As Object, strBase
Dim StrSPFolder As String, Cnt As Integer
Dim RSChr As String, strSubject_Kenmei As String
Dim objOlFolder As Outlook.Folder
Dim ar As Variant, i1 As Long
Dim bl As Boolean
Dim sender As AddressEntry
Dim strBody_Honbun As String
Dim ArR() As Variant, iArR As Long, strRecip As String
Dim olDist As Outlook.DistListItem, olDfol As Outlook.Folder
Dim olR As Outlook.Recipient, olRs As Outlook.Recipients, strBCC As String
Dim pa As Outlook.PropertyAccessor, strB As String
Dim GetSmtpAddress､CNT As Long
'To CCにも送信する場合には、Microsoft VBScript Regular Expression 5.5 以降を参照設定して、Dimに以下の宣言をする。
Dim REG As New RegExp, MS, M As Match, sMS As SubMatches, iReg As Long, ccArray(), toArray()
Const PR_SMTP_ADDRESS As String = _
"http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
Const SendFolderName As String = "送信済みアイテム"
Const ReceiveFolderName As String = "受信トレイ"
Const strSendChr = "S"
Const strReceiveChr = "R"
'NameSpace
Set NS = Application.GetNamespace("MAPI")
Set EX = ActiveExplorer
'/// Exploreが送信フォルダを見ているか確認する ///
'Exploreのフォルダパスを分解する
ar = Split(EX.CurrentFolder.FolderPath, "\")
RSChr = "": bl = False
For Cnt = LBound(ar) To UBound(ar)
'送信済みフォルダを分けていない(それが普通?)場合にはこれで判定する
If EX.CurrentFolder.Name = SendFolderName Then
bl = True: RSChr = strSendChr: Exit For
ElseIf EX.CurrentFolder.Name = ReceiveFolderName Then
Exit Sub
End If
'送信済みフォルダにサブフォルダを作っていた場合にはarの一部が該当する
If ar(Cnt) = SendFolderName Then
bl = True: RSChr = strSendChr: Exit For
End If
Next Cnt
'受信や送信でもないなら終了
If bl = False Then Exit Sub
'送信済みフォルダが入らないなら終了
If RSChr = "" Then Exit Sub
'送信のsが入らないなら終了
If RSChr = "" Then Exit Sub
'/// 以上のテストをおこなって開始
For Each myItem In EX.Selection
'//// メールの作成 ///
'メールでも添付ファイルがなければ終了、BCCがなければ確認して終了
If myItem.Attachments.Count = 0 Then GoTo Continue '添付ファイルがなければPW送信もない
'BCCの宛先がないなら添付ファイルを送らない場合
'If myItem.BCC = "" Then
'If MsgBox("BCCで送信した宛先がありません。本当にパスワード送信が必要ですか?必要ならOKを、違うならキャンセルをクリックしてしてください。別のメールの処理に移るか、別のメールがなければ終了します。", vbOKCancel + vbInformation, "BCCがないので部外者には送信していないようです") = vbCancel Then GoTo Continue
'End If


'To CCの取得 ただしこの方法ではBCCは取得できない
''With REG
''    .Global = True
''    .IgnoreCase = True
''    .MultiLine = True
''    .Pattern = "[A-za-z0-9.\-_]*@*[A-Za-z0-9.\-_]+[a-z](?![a-z])" '雑なパターンで100%取得できるかは自信がありません...未検証です
''    If .test(myItem.To) = True Then
''        Set MS = .Execute(myItem.To)
''        For iArR = 0 To MS.Count - 1
''            ReDim Preserve toArray(0 To iArR)
''            toArray(iArR) = MS.Item(iArR)
''        Next
''    End If
''    If .test(myItem.CC) = True Then
''      Set MS = .Execute(myItem.CC)
''        For iArR = 0 To MS.Count - 1
''        ReDim Preserve ccArray(0 To iArR)
''        ccArray(iArR) = MS.Item(iArR)
''        Next
''    End If
''End With


'////件名(Subject)の作成
'受信するメールが多い場合はどのメールのパスワードかわからなくなるため、件名と送信時刻(MailItem.SentOn)をつけて相手方にわかるようにする
'さらに違うユーザーからでも送信できるようにする
DT = myItem.ReceivedTime
strSubject_Kenmei = "次の件名のパスワードを送付します:" & StrConv(replaceNGchar(Left(myItem.Subject, 30) & "…"), vbNarrow)  & ":送信時刻:" & Format(DT, "yyyy/mm/dd hh:MM:ss") & "分"
strFile = "": strBCC = ""
strBody_Honbun = _
Format(DT, "yyyy/mm/dd hh:mm:ss") & "に" & myItem.sender & "より送付させていただきました電子メール" & vbCrLf & _
"件名:" & myItem.Subject & vbCrLf & _
"の添付ファイルのパスワードはアルファベット小文字で" & vbCrLf & _
"password" & vbCrLf & _
"です。" & vbCrLf & vbCrLf
'署名は好みで削る(CreateItemの時点では署名は追加されていない)送信者は違っても署名はこれで統一できる。つまり代理の人間が送信することが可能。
strBody_Honbun = strBody_Honbun & _
"(Pw通知専用メール担当者 お問い合わせはこちらまで)Sent by:" & vbCrLf & _
"Corporation Name ああああああああああ" & vbCrLf & _
"Tel:0000-00-0000" & vbCrLf & _
"Fax: 0000-00-0000(Need Only in Japan?)" & vbCrLf & _
"A: 000-Code City vllage 00-00aaaaaa"
'////sstrSenderの定義
strSender = ""
'////送信先の設定
Set olRs = myItem.Recipients
strB = ""
iArR = 0
For i1 = 1 To olRs.Count
On Error Resume Next
Set olR = olRs.Item(i1)
Set pa = olR.PropertyAccessor
strB = pa.GetProperty(PR_SMTP_ADDRESS)
If Err.Number = 0 Then
ReDim Preserve ArR(0 To iArR)
ArR(iArR) = strB & ";"
iArR = iArR + 1
ElseIf strB <> "" Then
ReDim Preserve ArR(0 To iArR)
ArR(iArR) = strB & ";"
iArR = iArR + 1
End If
strB = ""
Next i1
'新規メールの作成
Set objMail = Outlook.Application.CreateItem(0): DoEvents
objMail.Body = "" '署名等の消去。追加されていないはずだがこれで署名は消える。
'配列からBCC送信先への文字列を作るメールアドレスごとにセミコロンで区切る
For iArR = LBound(ArR) To UBound(ArR)
strBCC = strBCC & ArR(iArR) & ";"
Next iArR
Erase ArR '次のメールに備えて配列をクリア
objMail.BCC = strBCC: DoEvents
objMail.Subject = strSubject_Kenmei '件名
objMail.Body = strBody_Honbun '本文の代入
objMail.Display
Continue:
Next
End Sub
Private Function replaceNGchar(ByVal sourceStr As String, _
Optional ByVal replaceChar As String = "") As String
’タイトルで必要性の低いと思われる文字を削除する
’たとえば/\円マーク、バックスラッシュはメールをダウンロードしてファイル名を件名にしたときにはカットされたり不具合を起こす。こうした危険をなくすためカットを行う
Dim tempStr As String

tempStr = sourceStr
tempStr = Replace(tempStr, "\", replaceChar)
tempStr = Replace(tempStr, "/", replaceChar)
tempStr = Replace(tempStr, ":", replaceChar)
tempStr = Replace(tempStr, "*", replaceChar)
tempStr = Replace(tempStr, "?", replaceChar)
tempStr = Replace(tempStr, """", replaceChar)
tempStr = Replace(tempStr, "<", replaceChar)
tempStr = Replace(tempStr, ">", replaceChar)
tempStr = Replace(tempStr, "|", replaceChar)
tempStr = Replace(tempStr, "[", replaceChar)
tempStr = Replace(tempStr, "]", replaceChar)

replaceNGchar = tempStr
End Function
```
#特徴


#PropertyAccessorおよびPrptagの解説は英語
[Obtain the E-mail Address of a Recipient](https://docs.microsoft.com/en-us/office/vba/outlook/Concepts/Address-Book/obtain-the-e-mail-address-of-a-recipient)
というか2018年8月20日から23日くらいなぜか英語にしかつながらなかったが、今は日本語もある。
[受信者の電子メール アドレスを取得する](https://msdn.microsoft.com/ja-jp/vba/outlook-vba/articles/obtain-the-e-mail-address-of-a-recipient?f=255&MSPPError=-2147217396)
このトピックは、メールを送信した宛先集合内のメールの各受信者のSMTPアドレスを取得する方法を示しています。(つまりTo CC BCCを問わずメールを送信したすべてのアドレスを含む)
　コードサンプルのメソッドGetSMTPAddressForRecipientsは、引数としてMailItemを受け取り、そのメールアイテムの各受信者のSMTPアドレスを表示します。 このメソッドは、まず、メールアイテムに指定された送信した宛先すべてを含んだ受信者集合を取得します。 その受信者集合内の各受信者に対して、メソッドはそのRecipientオブジェクトに対応するPropertyAccessorオブジェクトを取得し、PropertyAccessorを使用してMAPIプロパティhttps://schemas.microsoft.com/mapi/proptag/0x39FE001Eの値を取得し、 受信者のSMTPアドレスにマップされます。

```vb
Sub GetSMTPAddressForRecipients(mail As Outlook.MailItem) 
    Dim recips As Outlook.Recipients 
    Dim recip As Outlook.Recipient 
    Dim pa As Outlook.PropertyAccessor 
    Const PR_SMTP_ADDRESS As String = _ 
        "https://schemas.microsoft.com/mapi/proptag/0x39FE001E" 
    Set recips = mail.Recipients 
    For Each recip In recips 
        Set pa = recip.PropertyAccessor 
        Debug.Print recip.name &; " SMTP=" _ 
           &; pa.GetProperty(PR_SMTP_ADDRESS) 
    Next 
End Sub
```

#OUTLOOKのマクロの使用開始方法やオブジェクトの説明はこちら
[OUTLOOK VBA オブジェクトまとめ](https://qiita.com/Q11Q/items/ac14d96c00e707de5d13)
[MAPIについて - Outlook 研究所](https://outlooklab.wordpress.com/2007/02/24/mapi-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)
###PropaertyAccessorの例
Task 仕事 タスクのフォルダ（もしくはToDoのフォルダ）内の各アイテムのプロパティを取得する
[VBA Script that gets list of Outlook Tasks using PropertyAccessor](http://www.gregthatcher.com/Scripts/VBA/Outlook/GetListOfTasksUsingPropertyAccessor.aspx)

###Outlook 2007 の新機能PropertyAccessor
[<開発者向け> Microsoft Office Outlook 2007 の新機能 (2/2)](https://msdn.microsoft.com/ja-jp/library/bb226714(v=office.12).aspx)
PropertyAccessor オブジェクト

PropertyAccessor オブジェクトも、Table オブジェクトと同様に、Outlook オブジェクト モデルによって実現できる機能についての重要変更です。PropertyAccessor は、Outlook オブジェクト プロパティへのアクセスを可能にします。これは、Outlook オブジェクト モデルには存在しない機能です。Microsoft Collaboration Data Objects (CDO) 1.21 に詳しい方は、CDO の Fields および Field オブジェクトに置き換わるものと考えてください。CDO と違い、PropertyAccessor は、整数のタグ値の代わりに可読文字列の値を使用して、Outlook オブジェクトの組み込みプロパティとカスタム プロパティの両方にアクセスします。以下のオブジェクトは、PropertyAccessor をサポートしています。
    AddressEntry
    AddressList
    AppointmentItem
    Attachment
    ContactItem
    DistListItem
    DocumentItem
    ExchangeDistributionList
    ExchangeUser
    Folder
    JournalItem
    MailItem
    MeetingItem
    NoteItem
    PostItem
    Recipient
    RemoteItem
    ReportItem
    SharingItem
    Store
    TaskItem
    TaskRequestAcceptItem
    TaskRequestDeclineItem
    TaskRequestItem
    TaskRequestUpdateItem

注:   このコードの例で、PR_TRANSPORT_MESSAGE_HEADERS の値を Table から直接読み取っていないことに疑問を持たれるかもしれません。これは、Table から返される文字列の長さが、フォルダのストア プロバイダによって異なるためです。Exchange の場合、Table から返される文字列の長さが、255バイトに制限されます。この制限の実質的な影響について考えます。Exchange ストア内のフォルダで、255 バイトを超える文字列が必要になった場合、制限に Table を使用し (この場合は、トランスポート ヘッダー プロパティが Null または空ではないすべてのアイテムに行を指定します)、次に、Namespace.GetItemFromID を使用してアイテム全体を取得します。アイテム全体を取得しているときには、PropertyAccessor.GetProperty の呼び出しでは、Table から返される途中で切れた値ではなく、文字列全体が返されます。

名前空間によってプロパティを参照する形式

PropertyAccessor は、SetProperty または GetProperty 呼び出しの文字列引数にいくつかの形式をサポートしています。ただし、これらのすべての形式についてこの記事に記載することはできないため、以下の一覧に、PropertyAccessor に対して有効な、サポートされているいくつかの形式についての簡単な説明を示します。詳細については、『Outlook Developer Reference』の「Referencing Properties by Namespace」(英語) のトピックを参照してください。プロパティ タグの形式

この形式は、MAPI proptag 名前空間に基づいています。この構文は次のようになります。

```
http://schemas.microsoft.com/mapi/proptag/0xHHHHHHHH
```

HHHHHHHH は、MAPI プロパティ タグ値の 16 進数表現を表しています。プロパティ タグ形式では、0xHHHHHHHH の値が &H8000 を超える場合、エラーが発生します。16 進タグの値が &H8000 を超えるプロパティには、「id 名前空間の名前付きプロパティ形式」で示されている形式を使用します。

```
例 :
    http://schemas.microsoft.com/mapi/proptag/0x0037001E 
    は PR_SUBJECT を表します。
    http://schemas.microsoft.com/mapi/proptag/0x007D001E
    は PR_TRANSPORT_MESSAGE_HEADERS を表します。
```

####全く分からないのでまずPR_SUBJECT
0x0037001Eを
0x0037と
0x001Eに分けます
#####前半の0x0037
 - [PidTagSubject 標準プロパティ](https://docs.microsoft.com/ja-jp/office/client-developer/outlook/mapi/pidtagsubject-canonical-property)
   - メッセージの件名が字数制限なくすべて含まれる
 - 関連するプロパティ:PR_SUBJECT、PR_SUBJECT_A、PR_SUBJECT_W
 - 上記の関連するプロパティの対照表が[標準プロパティ名から MAPI 名へのマッピング](https://docs.microsoft.com/ja-jp/office/client-developer/outlook/mapi/mapping-canonical-property-names-to-mapi-names#tagged-properties)の[タグ付きのプロパティ](https://docs.microsoft.com/ja-jp/office/client-developer/outlook/mapi/mapping-canonical-property-names-to-mapi-names#tagged-properties)にある
 - 識別子:	0x0037 <<<<ここに注目0037
 - データの種類 :PT_STRING8、PT_UNICODE<<<<ここに注目PR_STRING8
 - 領域:	メッセージ全般
 - 注釈
   - これらのプロパティは、すべてのメッセージ オブジェクトに対して推奨されています。
   - これらのプロパティは、常にフルの件名のテキストをプレフィックスと正規化された件名を連結したものです。 
   - プレフィックスがない場合は、正規化された件名は、件名の場合と同じにします。 
   - メッセージを保存またはトランスポートのこれらのプロパティとルールを使用する正規化された件名を計算するためにされて(PidTagSubjectPrefix) のプロパティの両方は、PR_NORMALIZED_SUBJECT (で説明されているプロバイダーの使用PidTagNormalizedSubject)。
   -  256 文字は、通常は短い文字列は、件名のプロパティと、メッセージ ストア プロバイダーがそれらにIStreamインターフェイスをサポートする義務を負いません。 クライアントは、 IMAPIPropインターフェイスを介してアクセスを最初に試行し、 MAPI_E_NOT_ENOUGH_MEMORYが返された場合にのみ、 IStreamに頼る必要があります常に。
   -  レポートの場合は、このプロパティは、元のメッセージの件名の前に、メッセージに何が起こったかを示す文字列を含みます。
 - 関連リソース
   - プロトコルの仕様
     - [MS OXPROPS]関連する Exchange Server プロトコルの仕様への参照を提供します。
     - [MS OXCMSG]メッセージと添付ファイルのオブジェクトを処理します。
   - ヘッダー ファイル
     - Mapidefs.h データ型定義を提供します。
     - Mapitags.h 代替名として記載されているプロパティの定義が含まれています。

######後半の0x001E
2.9 Uncompressed OAB Version 4 Full Details File
2.9.6 Data Encoding
2.9.6.1 PtypInteger32 (0x0003) Value Encoding
2.9.6.2 PtypBoolean (0x000B) Value Encoding
[2.9.6.3 PtypString8 (0x001E) Value Encoding](https://msdn.microsoft.com/en-us/library/ee179601%28v=exchg.80%29.aspx?f=255&MSPPError=-2147217396)
All narrow character set or multi-byte character set strings are encoded as byte sequences and MUST be terminated by a single 0x00 byte. A string sequence MUST NOT contain a 0x00 byte as part of the string itself. A zero length or empty string MUST NOT be encoded, but MUST be marked as not present in the presenceBitArray.
Properties whose data type is PtypEmbeddedTable ([[MS-OXCDATA] section 2.11.1](https://msdn.microsoft.com/en-us/library/ee157583%28v=exchg.80%29.aspx?f=255&MSPPError=-2147217396)), and whose value represents a reference to at most one other Address Book object, are encoded using the PtypString8 value encoding. The string value MUST be a DN (3) for an Address Book object, which can be present in the OAB.
For more details about the PtypString8 data type, see [[MS-OXCDATA] section 2.11.1](https://msdn.microsoft.com/en-us/library/ee157583%28v=exchg.80%29.aspx?f=255&MSPPError=-2147217396).
All narrow character set or multi-byte character set strings are encoded as byte sequences and MUST be terminated by a single 0x00 byte. A string sequence MUST NOT contain a 0x00 byte as part of the string itself. A zero length or empty string MUST NOT be encoded, but MUST be marked as not present in the presenceBitArray.
Properties whose data type is PtypEmbeddedTable ([MS-OXCDATA] section 2.11.1), and whose value represents a reference to at most one other Address Book object, are encoded using the PtypString8 value encoding. The string value MUST be a DN (3) for an Address Book object, which can be present in the OAB.
すべての半角文字セットまたは全角(マルチバイト)文字セット文字列はバイトシーケンスとしてエンコードされ、単一の0x00バイトで終了しなければならない（MUST）。文字列シーケンスには、文字列自体の一部として0x00バイトを含めてはならない（MUST NOT）。長さゼロまたは空の文字列をエンコードしてはならない（MUST NOT）が、presenceBitArrayに存在しないとマークされなければならない（MUST）。
データ型がPtypEmbeddedTable（[[MS-OXCDATA]セクション2.11.1](https://msdn.microsoft.com/en-us/library/ee157583%28v=exchg.80%29.aspx?f=255&MSPPError=-2147217396)）で、その値が他の多くのアドレス帳オブジェクトへの参照を表すプロパティは、PtypString8値エンコーディングを使用してエンコードされます。文字列値は、アドレス帳オブジェクトのDN（3）でなければなりません（OAB内に存在する可能性があります）。
PtypString8データ型の詳細については、[[MS-OXCDATA]セクション2.11.1](https://msdn.microsoft.com/en-us/library/ee157583%28v=exchg.80%29.aspx?f=255&MSPPError=-2147217396)を参照してください。
#####以上を合成して0x0037001Eとなります
####実際のhttp:// schemas.microsoft.com/mapi/proptag/0x39FE001Eに当てはめる
#####まず0x39FEと0x001Eに分解します
そうすると0x001Eは先ほどと同じオブジェクトかエンコーディングをあらわす001Eであることがわかります。そうすると0x39FEがわかるとよいわけです。
[PidTagSmtpAddress 標準プロパティ](https://docs.microsoft.com/ja-jp/office/client-developer/outlook/mapi/pidtagsmtpaddress-canonical-property)
pitagsmtpaddress canonical property

 - 関連するプロパティ:PR_SMTP_ADDRESS、PR_SMTP_ADDRESS_A、PR_SMTP_ADDRESS_W
 - 識別子:0x39FE
 - データの種類 :PT_UNICODE(0x001F)、PT_STRING8(0x001E)
 - 領域:Address

これで
####id 名前空間の名前付きプロパティ形式
この名前付きプロパティの形式は、MAPI id 名前空間に基づいています。この構文は次のようになります。

```
http://schemas.microsoft.com/mapi/id/{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH}/HHHHHHHH
```

{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH} は、名前空間の GUID を表し、HHHHHHHH は、ID 値の 16 進表現を表します。PropertyAccessor メソッドは、内部で GetIDsFromNames を実行し、正しいプロパティ値が設定または返されていることを確認します。

```
例 :
http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/850E000B は、対応するアイテムの NoAging プロパティを表します。
```

####文字列名前空間の名前付きプロパティ形式

この名前付きプロパティの形式は、MAPI 文字列名前空間に基づいています。この構文は次のようになります。

```
http://schemas.microsoft.com/mapi/string/{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH}/name
```

{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH} は、名前空間の GUID を表し、name は、プロパティの文字列名を表します。PropertyAccessor メソッドは、内部で GetIDsFromNames を実行し、正しいプロパティ値が設定または返されていることを確認します。

```
例 :
http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/content-class
http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/x-mimeole
```

####Office 形式
***Microsoft Office 形式は、文字列名前空間の名前付き形式の変形***です。Office 形式は、組み込みの Outlook プロパティを参照するのにも使用できます。以下のスキーマ名は、両方がアイテムのカテゴリを返します。

```
http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/keywords
urn:schemas-microsoft-com:office:office#Keywords
```

###PropertyAccessor の使用方法のガイドライン

PropertyAccessor は、強力なオブジェクトですが、その使用方法には多少の説明が必要です。以下の一覧は、PropertyAccessor の用途に関する一般的なガイドラインを示しています。詳細については、『Outlook Developer Reference』の「Best Practices for Getting and Setting Properties」(英語) ([機械翻訳日本語プロパティの取得と設定に関するヒント集](https://msdn.microsoft.com/ja-jp/vba/outlook-vba/articles/best-practices-for-getting-and-setting-properties?f=255&MSPPError=-2147217396))のトピックを参照してください。
　PropertyAccessor は、MailItem.Subject や AppointmentItem.Start などのオブジェクト モデル プロパティに置き換わるものではありません。明示的な組み込みプロパティには、オブジェクト モデルの適切なメンバを引き続き使用する必要があります。UserProperties.Add で追加したカスタム プロパティや、カスタム フォームに定義したカスタム プロパティについては、引き続き UserProperties(CustomPropertyName) を使用してカスタム プロパティの設定または取得を行います。
    特定のプロパティが、オブジェクトで公開されていない場合は、PropertyAccessor を使用して、プロパティの読み取りや設定を行います。プロパティの設定が可能かどうかは、ストア プロバイダによって異なります。たとえば、一部のストア プロバイダでは、Folder オブジェクトにプロパティを設定できません。
    明示的に Save を呼び出す必要があるオブジェクトでは (MailItem、ContactItem など)、PropertyAccessor を使用して設定したプロパティを保存するために Save を呼び出す必要があります。
    複数のプロパティを設定または取得する必要がある場合は、ネットワーク トラフィックの削減と、パフォーマンスの向上のために、PropertyAccessor.GetProperties および PropertyAccessor.SetProperties を使用してください。
    PropertyAccessor は、Outlook アイテムにカスタム プロパティを作成するために使用できます。カスタム プロパティは、フィールドの選択でユーザーに表示されることはありません。また、カスタム フォームのコントロールに自動的にバインドされません。プロパティが存在しない場合には、SetProperty または SetProperties を呼び出すことで、特定の 1 つまたは複数のプロパティを作成できます。
    PropertyAccessor は、常に、日付/時刻値を UTC 時刻で返します。UTC の DateTime 値をローカル タイムに変換する必要がある場合は、PropertyAccessor.UTCToLocalTime ヘルパー メソッドを使用します。
    PropertyAccessor は、常に、(エントリ ID に使用されている) PT_BINARY 値をバイト配列で返します。バイト配列を文字列に変換する必要がある場合は、PropertyAccessor.BinaryToString ヘルパー メソッドを使用します。

AddressEntry の拡張

Outlook 2007 オブジェクト モデルでは、プログラムからのアドレス帳の表示や、AddressEntry オブジェクトの詳細情報の返送がサポートされるようになり、この趣旨で CDO と同レベルの機能が実現されています。SelectNamesDialog オブジェクトは、Outlook の [アドレス帳] ダイアログ ボックスの表示や、ボタンの数、ボタンのキャプション、初期アドレス一覧などのオプションの設定を可能にします。
SelectNamesDialog オブジェクト
例として、ユーザーが [連絡先] フォルダの受賞者を選択するように [アドレス帳] ダイアログ ボックスを表示する必要があると仮定します。Outlook の以前のバージョンでこの機能を実現するには、CDO またはサードパーティ ライブラリを使用する必要がありました。Outlook 2007 では、SelectNamesDialog オブジェクトのインスタンスを取得することで [アドレス帳] を表示できます。SelectNamesDialog でサポートされる機能の概要を以下に示します。

ダイアログ ボックス キャプションの設定
    受賞者の選考者数の指定と、所定の選択者に対するキャプションの変更
    ダイアログ ボックスでの初期アドレス一覧の設定と取得、およびダイアログ ボックス内で使用できるアドレス一覧を初期アドレス一覧だけにするかどうかの決定
    ユーザーが複数の受賞者を選択できるようにするかどうかの指定
    Outlook [アドレス帳] ダイアログ ボックスの表示
    ユーザーがダイアログ ボックスで選択したすべての受賞者を表す Recipients コレクション オブジェクトの取得

SelectNamesDialog のコード サンプルは、(図 6 の) アドレス帳のダイアログ ボックスを表示します。このダイアログ ボックスで、ユーザーは、[連絡先] フォルダから "受賞者" (複数可) を選択できます。ユーザーが複数の連絡先を選択する場合、SelectNamesDialog.Recipients によって、選択された受賞者を列挙できます。また、メッセージをプログラムによって送信するなどの追加機能でそれらの受賞者を使用できます。
[名前空間でプロパティを参照する](https://msdn.microsoft.com/ja-jp/vba/outlook-vba/articles/referencing-properties-by-namespace?f=255&MSPPError=-2147217396)
Outlook オブジェクトによって使用される名前空間
次の表に、名前空間と名前空間がサポートする Outlook オブジェクトの概要を示します。名前空間によるプロパティの参照は大文字と小文字が区別されます。

|名前空間 |サポートされている Outlook のオブジェクト|
|:------------------------------------:|:------------------------------------------------------------------------------------------------------------------|
| http://schemas.microsoft.com/mapi/proptag|Outlook アイテム オブジェクト、 AddressEntry、 AddressList、添付ファイル、ExchangeDistributionList、 ExchangeUser、フォルダー、受信者、およびストアのオブジェクトです。|
| http://schemas.microsoft.com/mapi/id|(上記と同様)|
| http://schemas.microsoft.com/mapi/string|(上記と同様)|
| http://schemas.microsoft.com/exchange|(上記と同様)|
| urn:schemas-microsoft-com:office|Outlook アイテム オブジェクト|
| urn:schemas-microsoft-com:outlook|Outlook アイテム オブジェクト|
| DAV:|Outlook アイテム オブジェクト|
| urn:schemas:calendar|Outlook アイテム オブジェクト|
| urn:schemas:contacts|Outlook アイテム オブジェクト|
| urn:schemas:httpmail|Outlook アイテム オブジェクト|
| urn:schemas:mailheader|Outlook アイテム オブジェクト|

MAPI (Messaging Application Programming Interface) の名前空間

Outlook をサポートする多くのプロパティは、MAPI プロパティです。PropertyAccessorオブジェクトは、MAPI 名前空間の 3 つの下位名前空間をサポートしています: proptag、id、および文字列。次のセクションに subnamespace、その subnamespace とで補強 Backus 法によるフォーム (ABNF)、で指定した [であるの表現の構文の定義にプロパティを参照する形式の説明の説明が含まれています。RFC4234]。

proptag名前空間

この名前空間は、プロパティのプロパティ タブを使用して MAPI 名前空間のプロパティにアクセスするときに使用されます。MAPI プロパティ範囲内のプロパティ (プロパティ ID が 0x8000 未満のプロパティ) のみをサポートしています。この名前空間のプロパティを参照するための形式は次のとおりです。

http://schemas.microsoft.com/mapi/proptag/0xHHHHHHHH

HHHHHHHHは、高階 16 ビットの一意のプロパティ識別子とプロパティの型が、下位の 16 ビットの 16 進数のプロパティ タグ値を表します。各 MAPI プロパティには、MAPI、Outlook、またはサービス プロバイダーによって、プロパティが定義されているかどうかに関係なく、プロパティタグが必要です。16 進数の値は、プレフィックス"0 x"に従う必要があります。正式には、この名前空間内のプロパティの参照は ABNF で次のようになります。
※４HEXDIGとは4桁の16進数の意味

```
 id-specifier = "http://schemas.microsoft.com/mapi/id/" property-set "/x" property-long-id 
property-set = "{" 8HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 12HEXDIG "}" 
property-long-id = 8HEXDIG
```

文字列の名前空間

この名前空間は、識別済みの名前空間の文字列名が付いたプロパティにアクセスするときに使用されます。この名前空間のプロパティを参照するための形式は次のとおりです。

```
http://schemas.microsoft.com/mapi/string/
{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH}/name

```

{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH}
8桁16進数-4桁16進数-4桁16進数-4桁16進数-12桁16進数
名前空間 GUID を表し、nameは、文字列として定義されているローカルプロパティ名。

正式には、この名前空間のプロパティの参照は ABNF で次のように定義できます。

```
  string-specifier = "http://schemas.microsoft.com/mapi/string/" property-set "/" property-name 
property-set = "{" 8*HEXDIG "-" 4*HEXDIG "-" 4*HEXDIG "-" 4*HEXDIG "-" 12*HEXDIG "}" 
property-name = 1*CHAR
```

```
The following is an example that uses this namespace:

 http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/content-class
```
| プロパティの参照内の文字| の文字列をエスケープします。

|Character|Escape String|
|:------|:-----------:|
|文字をスペース | %20 | 
|二重引用符 | %22 |
 |単一引用符 | %27 | 
|パーセント文字 | %25 |

Escaping rules apply to referencing named properties in the  **string** namespace. When referencing a named property that has a string identifier (for example, Author, Company, and Title), if the property name contains a space, single quote, double quote, or percent character, you must use Universal Resource Locator (URL) escaping and represent such characters with the corresponding escape string as shown in the following table.
エスケープルールは、文字列名前空間の名前付きプロパティの参照に適用されます。 文字列識別子（Author、Company、Titleなど）を持つ名前付きプロパティを参照する場合、プロパティ名にスペース、一重引用符、二重引用符、またはパーセント記号が含まれている場合は、ユニバーサルリソースロケータ（URL） 次の表に示すように、そのような文字を対応するエスケープ文字列で表しま

```
The following is an example of how you specify and 
get the value of a named property,  **Mom's "Gift"**,
defined in the MAPI string namespace, by using the  ** 
[PropertyAccessor.GetProperty](propertyaccessor-getproperty-method-outlook.md)** method:
次の例は、名前付きプロパティ「ママ’の　"贈り物" Mom's "Gift"」を次のタグでを使用すると、MAPI文字列名前空間で定義されます

PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/Mom%27s%20%22Gift%22")
```

###プロパティの取得と設定に関するヒント集
 - (前半を簡単に略すと)Mailitem.Subjectのように使わなくてもいいプロパティには使わない。
 - PropertyAccessorを使用して取得し、 DocumentItemオブジェクト、Outlook オブジェクト モデルで公開する組み込みのアイテム レベルのプロパティまたはプロパティに次のオブジェクトのカスタム プロパティを設定しますAddressEntry、 。Addresslist オブジェクトを見つける、添付ファイル、 ExchangeDistributionList、 ExchangeUser、フォルダー、受信者、およびストアです。
 - 複数のプロパティを取得または設定するには、パフォーマンスを向上させるために、PropertyAccessor.GetPropertyおよびPropertyAccessor.SetPropertyを繰り返し使用するのではなく、PropertyAccessor.GetPropertiesおよびPropertyAccessor.SetPropertiesを使用します。
 - 名前空間では大文字と小文字の区別があり、間違うとエラーになります。
 - アイテムオブジェクトの場合、アイテムの現在のフォルダにアイテムを保存するSaveメソッドを呼び出すと、アイテムのプロパティも保存されます。
 - Saveメソッドを持たない非アイテムレベルのオブジェクトは（AddressList、Folder、Recipient、およびStore）、PropertyAccessor.DeleteProperty、PropertyAccessor.DeleteProperties、SetProperty、またはSetPropertiesを呼び出すと、オブジェクトに暗黙的にプロパティが保存されます。
 - カスタム プロパティを作成するか、カスタム プロパティにアクセスするには、MAPI 文字列名前空間を使用すると便利です。アドインの GUID を名前空間 GUID として使用します。

- このセクションでは、 PropertyAccessorを使用して取得し、プロパティを設定するときに型の変換をシンプルに保つためのベスト プラクティスについて説明します。PT_SYSTIMEなどの MAPI プロパティの種類の定義、プロパティの型を参照してください。
 - ほとんどの Outlook の日付と時刻の値は世界協定時刻 (UTC) 形式で格納されますが、存在は保証されません、 PT_SYSTIMEの MAPI の種類のすべてのプロパティが常に UTC を返します。
 - PT_SYSTIMEのプロパティを取得すると、 VT_DATE値を返します。PT_SYSTIMEのプロパティを設定する場合は、ローカルの日付と時刻の値ではなく、UTC 値としてプロパティを設定することを確認します。GetProperty、 SetProperty、 GetProperties、およびSetPropertiesメソッドでは、タイム ゾーンの変換は実行されません。タイム ゾーンを明示的な変換を実行するのにには、ヘルパー メソッドPropertyAccessor.LocalTimeToUTCおよびPropertyAccessor.UTCToLocalTimeを使用します。
 - 複数値を持つプロパティ (Microsoft Visual Basic のVT_ARRAY型目) は、同じ数の要素は、プロパティに値があるとを含む 2 次元配列として格納されます。複数値を持つプロパティを取得すると、 VT_ARRAY値を返します。複数値を持つプロパティを設定する場合は、プロパティに設定する値ごとに 1 つの要素を持つ 2 次元配列 ( VT_ARRAY) を渡します。
 - バイナリ プロパティ (MAPI のPT_BINARY型目) は、文字列ではなく、バイトの配列として格納されます。バイナリ プロパティを取得すると、 VT_ARRAY型の値を返します。GetProperty、 SetProperty、 GetProperties、およびSetPropertiesメソッドでは、バイナリ配列と文字列間の変換は実行されません。明示的に変換を実行するのにヘルパー メソッドのPropertyAccessor.BinaryToStringおよびPropertyAccessor.StringToBinaryを使用します。
 - PT_OBJECTなど、特定の MAPI プロパティ種類は、 PropertyAccessorでサポートされていません。取得またはこのようなプロパティを設定しようとしています。「プロパティの操作がサポートされていません」エラーになります。
 - MAPI proptag 名前空間で参照を使用してプロパティの設定を取得またはとき、は、proptag で指定された型が、プロパティの基になる型と一致していることを確認してください。VT_BSTRとして取得またはプロパティのために proptag で一種 001E または 001F のいずれかを指定できるPT_STRING8プロパティの場合を除いてを取得または設定プロパティを伴わない任意の型の強制変換し、場合、エラーが返されますが 型の不一致です。
 - プロパティを設定する場合は、MAPI proptag 名前空間ではなく MAPI 文字列名前空間でプロパティ参照を使用するのには制限が少ない場合があります。MAPI 文字列名前空間でプロパティを指定しても、プロパティの基になる型と一致する値が厳密に必要はありません。たとえば、 PT_SYSTIMEなどの日付と時刻のプロパティを設定するのにはVT_BSTRのような文字列値を渡すことができますし、 VT_BSTRをされると、値の型がプロパティの型になります。


[[MS-OXCDATA]2.11.1 Property Data Types](https://msdn.microsoft.com/ja-jp/library/office/ee157583.aspx)
すべてのバリアントについて、プロパティ値の構造は同じであり、プロパティデータ型が実際にバッファにコード化されているかどうかにかかわらず、プロパティデータ型によって指定されます。次の表は、プロパティデータ型識別子とプロパティ値の形式の両方を示しています。 Web分散オーサリングおよびバージョン管理プロトコル（WebDAV）プロパティのデータ型識別子は、2.11.1.6項で規定されています。

カウントフィールドの幅には1つのバリエーションがあります。 RopGetPropertiesSpecific ROP（[MS-OXCROPS]セクション2.2.8.3）などのROPバッファのコンテキストでは、すべてのPtypMultipleプロパティ値のPtypBinaryプロパティ値と値カウントのバイト数は16ビットです。ただし、[MS-OXORULE]セクション2.2.4で指定された拡張ルールのコンテキストでは、PtypBinaryプロパティ値のバイト数とPtypMultipleプロパティ値の値カウントは32ビット幅であり、HTTPのMAPI拡張のコンテキストでは[MS-OXCMAPIHTTP]で指定されているように、PtypBinaryプロパティ値のバイト数は32ビットです。このようなカウントフィールドは、セクション2.11全体のように、明示的な幅ではなく、セクション2.11.1.1で指定されたCOUNTの幅指定を有する。

テーブル操作のコンテキストでは、プロパティは列と呼ばれます。 RopQueryRows ROP（[MS-OXCROPS]セクション2.2.5.4）などのテーブル操作でのプロパティ識別子、タイプ、および値の形式は、RopGetPropertiesSpecific ROPなどのプロパティ操作と同じです。プロパティのデータ型を次の表に示します。指定されたプロパティデータ型の値は16ビットの整数です。 [MS-NSPI]で指定されているネームサービスプロバイダインターフェイス（NSPI）プロトコルは、同じ数値を使用しますが、32ビット表現の上位16ビットは常に0x0000に設定され、32ビット整数として表現します。

|Property type name|Property type value|Property type specification|Alternative Names|
|:---------------------------:|:--------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------:|
| PtypInteger16 |0x0002,%x02.00|2 bytes; a 16-bit integer,[MS-DTYP]: INT16|PT_SHORT, PT_I2, i2, ui2|
| PtypInteger32 |0x0003,%x03.00|4 bytes; a 32-bit integer,[MS-DTYP]: INT32|PT_LONG, PT_I4, int, ui4|
| PtypFloating32 |0x0004,%x04.00|4 bytes; a 32-bit floating point number,[MS-DTYP]: FLOAT|PT_FLOAT, PT_R4, float, r4|
| PtypFloating64 |0x0005,%x05.00|8 bytes; a 64-bit floating point number,[MS-DTYP]: DOUBLE|PT_DOUBLE, PT_R8, r8|
| PtypCurrency |0x0006,%x06.00|8 bytes; a 64-bit signed, scaled integer representation of a decimal currency value, with four places to the right of the decimal point,[MS-DTYP]: LONGLONG,[MS-OAUT]: CURRENCY|PT_CURRENCY, fixed.14.4|
| PtypFloatingTime |0x0007,%x07.00|8 bytes; a 64-bit floating point number in which the whole number part represents the number of days since December 30, 1899, and the fractional part represents the fraction of a day since midnight,[MS-DTYP]: DOUBLE[MS-OAUT]: DATE|PT_APPTIME|
| PtypErrorCode |0x000A,%x0A.00|4 bytes; a 32-bit integer encoding error information as specified in section 2.4.1.,|PT_ERROR|
| PtypBoolean |0x000B,%x0B.00|1 byte; restricted to 1 or 0,[MS-DTYP]: BOOLEAN|PT_BOOLEAN. bool|
| PtypInteger64 |0x0014,%x14.00|8 bytes; a 64-bit integer,[MS-DTYP]: LONGLONG|PT_LONGLONG, PT_I8, i8, ui8|
| PtypString |0x001F,%x1F.00|Variable size; a string of Unicode characters in UTF-16LE format encoding with terminating null character (0x0000).,|PT_UNICODE, string|
| PtypString8 |0x001E,%z1E.00|Variable size; a string of multibyte characters in externally specified encoding with terminating null character (single 0 byte).|PT_STRING8|
| PtypTime |0x0040,%x40.00|8 bytes; a 64-bit integer representing the number of 100-nanosecond intervals since January 1, 1601[MS-DTYP]: FILETIME|PT_SYSTIME, time, datetime, datetime.tz, datetime.rfc1123, Date, time, time.tz|
| PtypGuid |0x0048,%x48.00|16 bytes; a GUID with Data1, Data2, and Data3 fields in little-endian format[MS-DTYP]: GUID|PT_CLSID, UUID|
| PtypServerId |0x00FB,%xFB.00|Variable size; a 16-bit COUNT field followed by a structure as specified in section 2.11.1.4.,|PT_SVREID|
| PtypRestriction |0x00FD,%xFD.00|Variable size; a byte array representing one or more Restriction structures as specified in section 2.12.,|PT_SRESTRICT|
| PtypRuleAction |0x00FE,%xFE.00|Variable size; a 16-bit COUNT field followed by that many rule action structures, as specified in [MS-OXORULE] section 2.2.5.|PT_ACTIONS|
| PtypBinary |0x0102,%x02.01|Variable size; a COUNT field followed by that many bytes.|PT_BINARY|
| PtypMultipleInteger16 |0x1002,%x02.10|Variable size; a COUNT field followed by that many PtypInteger16 values.,|PT_MV_SHORT, PT_MV_I2, mv.i2|
| PtypMultipleInteger32 |0x1003,%x03.10|Variable size; a COUNT field followed by that many PtypInteger32 values.,|PT_MV_LONG, PT_MV_I4, mv.i4|
| PtypMultipleFloating32 |0x1004,%x04.10|Variable size; a COUNT field followed by that many PtypFloating32 values.,|PT_MV_FLOAT, PT_MV_R4, mv.float|
| PtypMultipleFloating64 |0x1005,%x05.10|Variable size; a COUNT field followed by that many PtypFloating64 values.,|PT_MV_DOUBLE, PT_MV_R8|
| PtypMultipleCurrency |0x1006,%x06.10|Variable size; a COUNT field followed by that many PtypCurrency values.,|PT_MV_CURRENCY, mv.fixed.14.4|
| PtypMultipleFloatingTime |0x1007,%x07.10|Variable size; a COUNT field followed by that many PtypFloatingTime values.,|PT_MV_APPTIME|
| PtypMultipleInteger64 |0x1014,%x14.10|Variable size; a COUNT field followed by that many PtypInteger64 values.,|PT_MV_I8, PT_MV_LONGLONG|
| PtypMultipleString |0x101F,%x1F.10|Variable size; a COUNT field followed by that many PtypString values.,|PT_MV_UNICODE|
| PtypMultipleString8 |0x101E,%x1E.10|Variable size; a COUNT field followed by that many PtypString8 values.,|PT_MV_STRING8, mv.string|
| PtypMultipleTime |0x1040,%x40.10|Variable size; a COUNT field followed by that many PtypTime values.|PT_MV_SYSTIME|
| PtypMultipleGuid |0x1048,%x48.10|Variable size; a COUNT field followed by that many PtypGuid values.,|PT_MV_CLSID, mv.uuid|
| PtypMultipleBinary |0x1102,%x02.11|Variable size; a COUNT field followed by that many PtypBinary values.|PT_MV_BINARY, mv.bin.hex|
| PtypUnspecified |0x0000,%x00.00|Any: this property type value matches any type; a server MUST return the actual type in its response. Servers MUST NOT return this type in response to a client request other than NspiGetIDsFromNames or the RopGetPropertyIdsFromNames ROP request ([MS-OXCROPS] section 2.2.8.1).|PT_UNSPECIFIED|
| PtypNull |0x0001,%x01.00|None: This property is a placeholder.|PT_NULL|
| PtypObject or PtypEmbeddedTable |0x000D,%x0D.00|The property value is a Component Object Model (COM) object, as specified in section 2.11.1.5.|PT_OB|