Excel vba outlookのExchangeのグローバルアドレス一覧から特定の肩書から名前を検索するマクロ

#設定と注意
##設定
Exchangeのグローバル アドレス一覧の中に存在する、会社の新宿支店の名簿から肩書(JobTitle)=総務課長の名前を抜き出します。(仮に複数ある場合には最初にヒットしたものが返ります)

課長の名前は 吉田 兼好(JPNTOKYO_0001新宿支店)のようになっています。
この氏名をSheet1のAI83に入力します。
##注意
個人ではExchangeは使っていないのが一般的です。これは法人用です。Exchangeのグローバルアドレス一覧から検索するものです。
グローバルアドレス一覧の名前を確認して、VBAを設定してください。そうしないと動きません。
わからないときはOUTLOOKのVBAのサンプルで確認してみてください。

##ExchangeUser Object
ExchangeUser オブジェクト (Outlook)](https://msdn.microsoft.com/ja-jp/vba/outlook-vba/articles/exchangeuser-object-outlook)
ExchangeUser オブジェクトは AddressEntry オブジェクトから派生し、呼び出し元が AddressEntry オブジェクトに対してクエリ インターフェイスを実行すると、 AddressEntry の代わりに返されます。

## Objectの並び順
OutlookApplication -- Namespace -- AddressLists -- AddressList -- AddressEntries --AddressEntry -- ExchageUser

##使用する定数 Enum

###[OlAddressListType 列挙 (Outlook)](https://msdn.microsoft.com/ja-jp/vba/outlook-vba/articles/oladdresslisttype-enumeration-outlook)

|名前 |値 |説明 |
|:---:|:---:|:----:|
|olCustomAddressList|4|カスタム アドレス帳プロバイダー。|
|olExchangeContainer|1|Exchange サーバー上のアドレス一覧を入れるコンテナー。|
|olExchangeGlobalAddressList|0|Exchange グローバル アドレス一覧。|
|olOutlookAddressList|2|Outlook 連絡先アドレス帳に対応するアドレス一覧。|
|olOutlookLdapAddressList|3|LDAP (Lightweight Directory Access Protocol) を使用するアドレス一覧。|

今回は0のグローバルアドレス一覧(GAL)を使用する
###参考としたコード
ExchangeUserの名前をぬきだす。全部やると止まらないので3名程度で止める。
元のコードは止まらないので危ない。

```visualbasic:DemoAE
Sub DemoAE()
'For Outlook And Exchage User
'Not For Personal
Dim colAL As Outlook.AddressLists
Dim oAL As Outlook.AddressList
Dim colAE As Outlook.AddressEntries
Dim oAE As Outlook.AddressEntry
Dim oExUser As Outlook.ExchangeUser
Dim Cnt as Long
Set colAL = Application.Session.AddressLists
Cnt =1
For Each oAL In colAL
'Address list is an Exchange Global Address List
If oAL.AddressListType = olExchangeGlobalAddressList Then
Set colAE = oAL.AddressEntries
For Each oAE In colAE
If oAE.AddressEntryUserType = _
olExchangeUserAddressEntry Then
Set oExUser = oAE.GetExchangeUser
Debug.Print(oExUser.JobTitle)
Debug.Print(oExUser.OfficeLocation)
Debug.Print(oExUser.BusinessTelephoneNumber)
If cnt >= 3 then exit for Else Cnt = Cnt + 1
End If
Next
End If
Next
End Sub
```
```visual basic
‘これは法人用でExchangeのグローバルアドレス一覧から検索するものです。
‘個人ではExchangeは使っていない
‘Outlook Object Libraryに参照設定することをお勧めします。(してなくても動くようにはしています)参照した場合は、置換で 'As を ASに変えてください。

‘Exchangeの会社の新宿支店の名簿から肩書(JobTitle)総務課長の名前を抜き出します。
‘課長の名前は 吉田 兼好(JPNTOKYO_0001新宿支店)のようになっています。
‘検索して肩書を見つけたら、Sheet1のAI83に入力します。

Sub GetNameFromOlGlobalAddress()
‘For Excel
‘With Outlook And Exchage
‘Not for Personal 個人用ではありません(個人では通常Exchangeを使用していないため)

' Create an Outlook application.
Dim oApp ‘As Outlook.Application:Set oApp = CreateObject("Outlook.Application")
Dim oNS ‘As Outlook.Namespace
Set oNS = GetNamespace("MAPI")
Dim colAL ‘As Outlook.AddressLists ' Outlook.AddressLists
Dim oAL ‘As Outlook.AddressList ' Outlook.AddressList
Dim colAE ‘As Outlook.AddressEntries
Dim oAE ‘As Outlook.addressEntry
Dim AddressLists ‘As Outlook.AddressLists
' Outlook.AddressEntries
Dim addressEntry As Object ' Outlook.AddressEntry
Dim oExuser ‘As Outlook.ExchangeUser
Dim JobtitleKey As String
Dim ExactName, ExactNameEx As String
Dim objWin As Excel.Window: Set objWin = ActiveWindow: objWin.Visible = True
Dim i, i2 As Integer
Dim ws, myWS As Worksheet
Set AddressLists = oNS.AddressLists
'確認して変更する
Set oAL = oNS.AddressLists.Item("グローバル アドレス一覧、組織名など確認して入れる") 'GALを絞り込む 'Set oAL = oNS.AddressLists.Item("JPNTOKYO_0001新宿支店") 
Set colAE = oAL.AddressEntries
JobtitleKey = "総務課長" '肩書きで検索
Set colAE = oAL.AddressEntries

For Each oAE In colAE
Set oExuser = oAE.GetExchangeUser
If oAE.AddressEntryUserType = olExchangeUserAddressEntry Then

Set oExuser = oAE.GetExchangeUser

If oExuser.JobTitle = JobtitleKey Then

ExactName = Replace(oExuser.Name, "( JPNTOKYO_0001新宿支店)", "") ‘吉田 兼好(JPNTOKYO_0001支店) のように余計な文字があれば抜く

Worksheets("Sheet1").Range("AI83").Value = ExactName

End If
End If
Next
End Sub
```

#参考リンク
[グローバル アドレス一覧の作成]( https://technet.microsoft.com/ja-jp/library/bb232063(v=exchg.150).aspx)

>グローバル アドレス一覧 (GAL) は、MicrosoftExchange が実装されている組織内のすべてのグループ、ユーザー、連絡先のエントリが含まれているディレクトリです。組織でアドレス帳ポリシーを使用する場合、追加の GAL を作成できます。詳しくは、「アドレス帳ポリシー」をご覧ください。

[アドレス帳を作成する]( https://support.office.com/ja-jp/article/アドレス帳を作成する-41d343c2-0508-45fe-b6f4-a0294bfe3da0)

こちらが個人用
[Exchange Online のアドレス一覧の手順]( https://technet.microsoft.com/ja-jp/library/jj983793(v=exchg.150).aspx)
[アドレス帳を追加、削除する]( https://support.office.com/ja-jp/article/アドレス帳を追加、削除する-fd067150-ba37-42a4-b88e-5b15f3dba4e6)
Exchange Server アカウントで Outlook を使用している場合は、アドレス帳の一覧にグローバル アドレス一覧 (GAL) が含まれます。GAL には、Exchange Server のアカウントを持つすべてのユーザーの名前とメール アドレスが含まれています。GAL は Exchange によって自動的に構成されます。
[GAL (グローバル アドレス一覧) をエクスポートする方法]( https://support.microsoft.com/ja-jp/help/555397)
Exchange Server 2003 Standard Editionというプロ向けなので、これは知らなくてよい。
全部バックアップしても意味がない。
[グローバル アドレス リストを識別するか、ストアのアドレスのセットを一覧表示]( https://msdn.microsoft.com/ja-jp/vba/outlook-vba/articles/identify-the-global-address-list-or-a-set-of-address-lists-with-a-store)

>セッションでは、Microsoft Outlook のプロファイルで複数の Microsoft Exchange アカウントが定義され、ストアに関連付けられている複数のアドレス一覧が存在すること場合があります。このトピックには、特定のストアのグローバル アドレス一覧を取得する方法およびすべての特定のストアに関連付けられているAddressListオブジェクトを取得する方法を示す 2 つのコード サンプルです。

これはメインで使っているアドレスの場合はまず関係がない。通常複数のアカウントがある場合両方とも同じGALにアクセスできるためである。さらにこのサンプルはC#でVBAマクロと関係ない。