outlook-vba
はじめに第3部:店舗とそのすべてのフォルダ
サーチ…
前書き
このチュートリアルのパート2で開始したストアとフォルダの紹介を完了する
予期される事前知識 :このチュートリアルのパート2を読んだり、すでにその内容に精通しています。
3. 0内容
- アクセス可能なフォルダを参照する方法。
- 参照先フォルダのフルネームを取得する方法。
- アクセス可能なすべてのストア内のすべてのフォルダをまとめてリストするルーチンのペア。
- 親フォルダから別のフォルダにフォルダを移動するルーチン。
3.1関数GetFldrNames()はいくつかのデモンストレーションマクロに必要です
この部分のデモンストレーションマクロには、後で説明する機能が必要です。今のところGetFldrNames()
を適切なモジュールにコピーしてください。私はこの機能を頻繁に使用し、それを維持します。他の多くのマクロでは、「ModGlobalOutlook」という名前のモジュールで使用します。あなたは同じことをしたいかもしれません。あるいは、このチュートリアルのシリーズ内の他のすべてのマクロでマクロを保つこともできます。心が変わると後で移動することができます。
Public Function GetFldrNames(ByRef Fldr As Folder) As String()
' * Fldr is a folder. It could be a store, the child of a store,
' the grandchild of a store or more deeply nested.
' * Return the name of that folder as a string array in the sequence:
' (0)=StoreName (1)=Level1FolderName (2)=Level2FolderName ...
' 12Oct16 Coded
' 20Oct16 Renamed from GetFldrNameStr and amended to return a string array
' rather than a string
Dim FldrCrnt As Folder
Dim FldrNameCrnt As String
Dim FldrNames() As String
Dim FldrNamesRev() As String
Dim FldrPrnt As Folder
Dim InxFN As Long
Dim InxFnR As Long
Set FldrCrnt = Fldr
FldrNameCrnt = FldrCrnt.Name
ReDim FldrNamesRev(0 To 0)
FldrNamesRev(0) = Fldr.Name
' Loop getting parents until FldrCrnt has no parent.
' Add names of Fldr and all its parents to FldrName as they are found
Do While True
Set FldrPrnt = Nothing
On Error Resume Next
Set FldrPrnt = Nothing ' Ensure value is Nothing if following statement fails
Set FldrPrnt = FldrCrnt.Parent
On Error GoTo 0
If FldrPrnt Is Nothing Then
' FldrCrnt has no parent
Exit Do
End If
ReDim Preserve FldrNamesRev(0 To UBound(FldrNamesRev) + 1)
FldrNamesRev(UBound(FldrNamesRev)) = FldrPrnt.Name
Set FldrCrnt = FldrPrnt
Loop
' Copy names to FldrNames in reverse sequence so they end up in the correct sequence
ReDim FldrNames(0 To UBound(FldrNamesRev))
InxFN = 0
For InxFnR = UBound(FldrNamesRev) To 0 Step -1
FldrNames(InxFN) = FldrNamesRev(InxFnR)
InxFN = InxFN + 1
Next
GetFldrNames = FldrNames
End Function
3.2デフォルトフォルダの参照
TestDefaultFldr()
では、 Fldr
をデフォルトの受信トレイに設定しFldr
た。定数olFolderInbox
は、デフォルトのフォルダにアクセスできる他の値に置き換えることができます。 Set Fldr = Session.GetDefaultFolder(
VBエディタには、可能なすべての値のドロップダウンリストが表示されます。
Sub TestDefaultFldr()
Dim Fldr As Folder
Set Fldr = Session.GetDefaultFolder(olFolderInbox)
Debug.Print Join(GetFldrNames(Fldr), "|")
End Sub
私のラップトップでは、 TestDefaultFldr()
はOutlook data file|Inbox
を驚きとして表示しOutlook data file|Inbox
。私はGetFldrNames(Fldr)
を書いて、私が参照したフォルダが私が望むものであることを確認しました。私はデフォルトの受信トレイにアクセスし、それが空であることを発見しました!ストア "出力データファイル"はデフォルトインストールが付属していました。Outlookは自分のメールアカウントごとにストアを作成していたので、無視してしまいました。私の空の既定の受信トレイが見つかった後で、Outlookが自分の電子メールアカウントのどれが既定のアカウントになっているかを知る方法について考えました。標準のOutlookフォルダのうち、デフォルトがないか、またはデフォルトが「出力データファイル」内にあります。どのInboxがデフォルトの受信トレイであるかを変更することは可能かもしれませんが、私が変更した場合、どの電子メールアカウントをデフォルトにするかわからないため、調査していません。カレンダーアイテム、タスクなどはすべて「Outlookデータファイル」内にあり、アーカイブリストに「Outlook.pst」が含まれていることを確認してください。
ほとんどのOutlookオブジェクトにはParent
プロパティがあります。 GetFldrNames(Fldr)
は、親にアクセスしようとする前に、配列のフォルダの名前を記録します。配列の終わりに名前が追加されると、ストアに到達します。ストアには親がないため、アクセスしようとすると失敗します。配列内の名前の並びが逆にされ、呼び出し側に返されます。私はJoin
を使用して配列の名前を表示可能な文字列に変換しています。
3.3アクセス可能なストア内の任意のフォルダの参照
TestFldrChain()
は、アクセス可能なストア内の任意のフォルダを参照する方法を示します。
Sub TestFldrChain()
Dim Fldr As Folder
Set Fldr = Session.Folders("A").Folders("A2"). _
Folders("A21").Folders("A213")
Debug.Print Join(GetFldrNames(Fldr), "|")
End Sub
TestFldrChain()
:Aはストアの名前です。 A2はA内のフォルダの名前です。 A21はA2内のフォルダ名、A213はA21内のフォルダ名です。
ここで何が起きてるの?
Session
はアクセス可能なすべてのストアのリストであるプロパティFolders
あります。
このチュートリアルの第2回で使用したSession.Folders(integer)
、名前がわからないときにストアを順番に調べることができます。 Session.Folders("A")
使用すると、名前を知ったフォルダにアクセスできます。
Session.Folders("A")
フォルダであり、それはあまりにもプロパティがあるFolders
。
Session.Folders("A").Folders("A2")
を使用すると、ストア "A"内のフォルダ "A2"にアクセスできます。
私は任意のフォルダに到達するために必要な数のFolders("x")
をチェーンすることができます。チェーンが1行で長すぎる場合は、私が持っているようにいくつかの行にステートメントを分割することができます。
インストール中に最も深くネストされたフォルダを探し、A、A2、A21、A213をストアとフォルダの名前で置き換えます。必要に応じてチェーン内のフォルダの数を増減してください。
TestFldrChain()
を更新して実行すると、A、A2などがフォルダ名に置き換えられる以外は、次のように出力されます。
A|A2|A21|A213
3.4アクセス可能なすべてのストア内のすべてのフォルダの名前を一覧表示する
第2回では、アクセス可能なすべてのストアと、各ストア内のトップレベルのフォルダをリストする方法を示しました。これは、店舗を通るループと、その店舗の各店舗のループを含んでいます。あなたは、フォルダの階層内の任意の深さにある既知のフォルダを参照する方法を見てきました。これは、フォルダに達するのに必要な数のFolders("x")
連鎖させることを含んでいました。
私は今、すべての店舗内のすべての深さで、すべてのフォルダをリストしたいと思います。さまざまな長さのチェーンを下ろさなければならないこのタイプの問題を解決する最も簡単なコーディング手法は再帰です。あなたが別の言語やツールで深刻なプログラマーであれば、すでに再帰について知っているかもしれません。あなたが深刻なプログラマになることを希望しているなら、最終的には必ずしも必要ではないが、再帰を理解する必要があります。 「再帰」は、多くの人が最初に理解するのが困難な概念の1つです。好きな検索エンジンに「再帰」と入力して、この概念を説明するさまざまな試みを読むことができます。あるいは、これらのマクロ作業を受け入れることはできますが、動作の仕方は心配しないでください。
ListStoresAndAllFolders()
コメントに注意してください。これらのマクロには、 "Microsoft Scripting Runtime"への参照が必要です。 VB Editorウィンドウの上部にあるタブバーの[ ツール ]をクリックし、[ 参照設定 ]をクリックします。利用可能なすべての参照(ライブラリ)のリストが表示されます。一番上の方にはすでに刻まれています。残りはアルファベット順です。リストを下にスクロールし、 "Microsoft Scripting Runtime"の左側にあるチェックボックスをオンにします。 OKをクリックします。
Sub ListStoresAndAllFolders()
' Displays the name of every accessible store
' Under each store, displays an indented list of all its folders
' Technique for locating desktop from answer by Kyle:
' http://stackoverflow.com/a/17551579/973283
' Needs reference to “Microsoft Scripting Runtime” if "TextStream"
' and "FileSystemObject" are to be recognised
Dim FileOut As TextStream
Dim FldrCrnt As Folder
Dim Fso As FileSystemObject
Dim InxFldrCrnt As Long
Dim InxStoreCrnt As Long
Dim Path As String
Dim StoreCrnt As Folder
Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
Set Fso = CreateObject("Scripting.FileSystemObject")
Set FileOut = Fso.CreateTextFile(Path & "\ListStoresAndAllFolders.txt", True)
With Application.Session
For InxStoreCrnt = 1 To .Folders.Count
Set StoreCrnt = .Folders(InxStoreCrnt)
With StoreCrnt
FileOut.WriteLine .Name
For InxFldrCrnt = .Folders.Count To 1 Step -1
Set FldrCrnt = .Folders(InxFldrCrnt)
Call ListAllFolders(FldrCrnt, 1, FileOut)
Next
End With
Next
End With
FileOut.Close
End Sub
Sub ListAllFolders(ByRef Fldr As Folder, ByVal Level As Long, ByRef FileOut As TextStream)
' This routine:
' 1. Output name of Fldr
' 2. Calls itself for each child of Fldr
' It is designed to be called by ListStoresAndAllFolders()
Dim InxFldrCrnt As Long
With Fldr
FileOut.WriteLine Space(Level * 2) & .Name
For InxFldrCrnt = .Folders.Count To 1 Step -1
Call ListAllFolders(.Folders(InxFldrCrnt), Level + 1, FileOut)
Next
End With
End Sub
ListStoresAndAllFolders
を実行すると、DeskTopに "ListStoresAndAllFolders.txt"という名前の新しいファイルが作成され、ストアとフォルダの約束されたリストが格納されます。
3.5ある親フォルダから別の親フォルダへのフォルダの移動
なぜフォルダを参照したいのですか?次のセクションでは、参照先のフォルダ内の電子メールにアクセスする方法を示します。ここでは、フォルダの移動方法を説明します。私は自分の受信トレイ内に "Test"という名前のフォルダを作成しました。 TestMoveFolder()
では、 "A"を私の受信トレイを含むストアの名前に置き換えました。 TestMoveFolder()
実行すると、 "Test"が "Deleted Items"に移動しました。
Sub TestMoveFolder()
Dim FldrDest As Folder
Dim FldrToMove As Folder
Set FldrToMove = Session.Folders("A").Folders("Inbox").Folders("Test")
Set FldrDest = Session.Folders("A").Folders("Deleted Items")
FldrToMove.MoveTo FldrDest
End Sub
3.6チュートリアルのこの部分から覚えておくべきこと
- デフォルトのフォルダを参照する方法と、この手法の制限事項。
- アクセス可能なストア内の任意の深さに任意の単一のフォルダを参照する方法。
- 参照先フォルダのフルネームを表示する方法。
- サブルーチンと関数のデフォルトセットを超えた機能を提供する多くの利用可能なライブラリの1つを参照する方法。
- アクセス可能なすべてのストア内のすべてのフォルダの名前を表示する方法。
- 親フォルダから別のフォルダにフォルダを移動する方法。