メールを保存する - Outlookの続き


[メールを保存する - Outlook](http://qiita.com/int_main_void/items/7d944286dda2992cbde0)のの続き

# 実行時エラー
選択するメールが多すぎると、以下のエラーのダイアログが出る。

ダイアログのエラーメッセージを素直に読めば、サーバ側の設定によると思われる。出たのは、IMAPのとき。(ただ、自分のPCの[レジストリかも？](https://blogs.technet.microsoft.com/outlooksupportjp/2014/06/26/outlook-2/)という記事もあった。。。)

> ###実行時エラー
同時に開くことができるアイテムの数が、サーバ管理者によって制限されています。開いているメッセージを閉じるか、作成中のメッセージから添付ファイルや画像を削除してください。


ForEachでイテレートしているメールオブジェクトを参照(mail.xxxxx)したタイミングで発生するようだ。

```vbnet:ForEach箇所
For Each mail In ActiveExplorer.Selection
```

しかし、そもそも「**オブジェクトを参照したいからイテレートしている**」というジレンマ。

## 発生個所
```vbnet:発生箇所1
    ' ビュー一覧のうち選択したメールに対して保存処理をする
    Dim mail As Object
    For Each mail In ActiveExplorer.Selection

        ' 保存したいメールアドレスが含まれているかチェックする
        ' 送信者アドレス(SenderEmailAddress) → なかったら → 受信者アドレス(RecipientのAddress)
        ' mdirが空文字列("")だったら、TERGETではないのでスキップする
        Dim mdir As String
        Dim sndr_addr As String

        mdir = ""
        sndr_addr = mail.SenderEmailAddress
```

**<code>sndr_addr = mail.SenderEmailAddress</code>**の箇所で発生。
ここをどうにかしてパスすると・・・

```vbnet:発生箇所2
        ' 添付ファイル
        Dim f As Attachment
        Dim attach_fname As String
        For Each f In mail.Attachments
            ' 添付ファイル名
            attach_fname = fso.buildPath(folder_name, replaceNGchar(f.DisplayName, "_"))
```
**<code>For Each f In mail.Attachments</code>**の箇所で発生。

##暫定対策
今のところ、「Outlookで選択するメールの数を減らす」という使い方で逃げている。
(<code>For Each mail In ActiveExplorer.Selection</code>でイテレートするオブジェクトを減らす)

##もしかすると？
要はmailオブジェクトの参照がどこかで解放できていない(補足[1])。
<code>Set mail = Nothing</code>を入れて、**できるかぎり解放してたつもり**だった。。。が、「Continue的な箇所」(GoTo Continue)」の箇所が解放できてない<code>GoTo Continue</code>～<code>Continue: </code>ように思う。・・・ったが解放してもダメそうだった。

```vbnet:原因箇所？
    Dim mail As Object
    For Each mail In ActiveExplorer.Selection
' ・・・
        If mdir = "" Then
            GoTo Continue ' Continue文がないので、GoToで代用。
        End If
' ・・・
        Set mail = Nothing
Continue:
        ' Continue文がないので、GoToで代用
    Next
```

##ちなみに・・・

```vbnet:
    Dim mail As Object
    For Each mail In ActiveExplorer.Selection
```

<code>Dim mail As Object</code>の部分は、**たいていのメール**に対しては、

```vbnet:MailItem
    Dim mail As MailItem
    For Each mail In ActiveExplorer.Selection
```
<code>Dim mail As MailItem</code>で動く。ただ、**MailItemでない何か**(ちゃんと調べていないが、会議予定など？)が、「For Each mail In ActiveExplorer.Selectionで入れられてしまう」ので、エラーが発生する。


# 添付ファイルの拡張子がなくなる件

```vbnet
        ' 添付ファイル
        Dim f As Attachment
        Dim attach_fname As String
        For Each f In mail.Attachments
            ' 添付ファイル名
            attach_fname = fso.buildPath(folder_name, replaceNGchar(f.DisplayName, "_"))
```

メール(*.msg)が添付ファイルにされていると、拡張子がなくなってしまう。
たとえば、"abcの件.msg" が"abcの件"というファイルになる

## 暫定対策
拡張子を付けることで.msgとして開けるようになる。

##原因箇所？
f.DisplayNameの動きがそうなっているから・・・と思うが、.msgだけが拡張子がなくなるのかどうかがわからないし、手作業でなんとかなる程度の量だったのでまだよく調べていない。


#補足
##補足[1]
オブジェクト解放は、<code>Set objReference = Nothing</code>してしまえばよい。(オブジェクトの参照カウントかなんかで数えていて、いいように解放してくれる。たぶん。)

普段は、VBScriptの「ちょっとしたモノ」ばっかり書いてたので、↓の記事を

[なぜそれを実行したのか - Microsoft スクリプト センター _ TechNet](https://technet.microsoft.com/ja-jp/scriptcenter/ff729447.aspx)
> オブジェクト参照を Nothing に設定する方法もよく目にします。・・・
>**すべてのオブジェクト参照は、スクリプトが終了するときに自動的に解放されるので、強制的に解放する必要はありません。**

と見ていた。ここでは、その前提条件の

> オブジェクト参照を Nothing に設定する方法もよく目にします。・・・
ここでは、**新しいオブジェクトでオブジェクト参照を再利用しない場合や、スクリプトで大量のメモリを消費しない場合**には、次のコードを実行する必要はないと言えば十分でしょう。

>```
Set objReference = Nothing
```

に着目したほうがよさそうだ。



#参考
[なぜそれを実行したのか - Microsoft スクリプト センター _ TechNet](https://technet.microsoft.com/ja-jp/scriptcenter/ff729447.aspx)
[Outlook で予定表を表示する際の制限数について – Outlook Support Team Blog JAPAN](https://blogs.technet.microsoft.com/outlooksupportjp/2014/06/26/outlook-2/)