【Outlook VBA】ユーザ定義フィールドの最大値(最小値)を見つける

【Outlook VBA】ユーザ定義フィールドの最大値(最小値)を見つける

Outlookのユーザ定義フィールドから最大値を取得したかったのですが、標準関数がありませんでした。降順に並び替え、先頭の情報を取ろうとしても、データが並び変わらない様子です。さいわいフィルタは働くので、複数回フィルタを掛けることで最大値(最小値)を取得する方法を共有します。

数値で宣言したユーザ定義フィールドの最大値を取得したかったのですが、標準関数は準備されていない様です。

フィルタを複数回かけることで比較回数を抑えた処理ができそうなので、情報を共有したいと思います。

ユーザ定義フィールドとは?

メールの件名や予定のタイトルなどはフィールドと呼ばれます。

Outlookでは既存のフィールドに加え、ユーザが独自にフィールドを追加することができます。

独自のフィールドのことをユーザ定義フィールド(あるいは、カスタムフィールド)と呼びます。

ユーザ定義フィールド「管理番号」の最大値を探すコード

' --------------------------------------------------------------------------------
' 次の管理番号を取得します。
' --------------------------------------------------------------------------------
Private Function getSerialNumber(ByVal categoriesKey As String)

    Dim oFolder As Outlook.Folder
    Dim oItems As Outlook.Items
    Dim oItemsInCategories As Outlook.Items
    Dim oItemsInSerialNumber As Outlook.Items
    Dim oAppt As Outlook.TaskItem
    Dim strRestriction As String
    
    Dim maxNumber As Integer
    
    getSerialNumber = 0

    ' タスクのフォルダオブジェクトを取得
    Set oFolder = Application.Session.GetDefaultFolder(olFolderTasks)
    Set oItems = oFolder.Items
    ' 繰り返しのタスクも対象にする
    oItems.IncludeRecurrences = True
    
    ' 指定のカテゴリでフィルタ
    Const PropTag  As String = "https://schemas.microsoft.com/mapi/proptag/"
    strRestriction = "@SQL=""urn:schemas-microsoft-com:office:office#Keywords"" like '%" & categoriesKey & "%'"
    
    Set oItemsInCategories = oItems.Restrict(strRestriction)
    
    ' カスタムフィールドでソートが効かないため、フィルタ使って最大を探します
    ' 基本的に作成時間の若い順になるはず。タスクの作り直しに対応するために一応確認する。
    maxNumber = 0

    Dim userProperties_SerialNumber as string
    userProperties_SerialNumber = "管理番号"

    Do
    
        ' 管理番号が存在するタスクのみを取得
        strRestriction = "[" & userProperties_SerialNumber & "] > " & maxNumber
        Set oItemsInSerialNumber = oItemsInCategories.Restrict(strRestriction)
        
        ' 一旦作成時間でソート
        Call oItemsInSerialNumber.Sort("[creationTime]")
        
        If oItemsInSerialNumber.Count > 1 Then
        
            Set oAppt = oItemsInSerialNumber.GetFirst
        
            ' 管理番号候補が複数存在する場合、とりあえず先頭の番号を候補にして処理
            maxNumber = oAppt.UserProperties(userProperties_SerialNumber)
        
        Else
        
            Set oAppt = oItemsInSerialNumber.GetFirst
            
            ' 現在の管理番号をインクリメントして返します。
            getSerialNumber = oAppt.UserProperties(userProperties_SerialNumber) + 1
            
            Exit Do
            
        End If
    
    Loop

End Function

コード補足

最小値を取得する場合は、フィルタ条件の比較演算子を変更してください。

実際の処理コードを切り出しているため、カテゴリでフィルタを掛けた後に最大値を探しています。カテゴリのフィルタ部分はあいまい検索に対応していますので、カテゴリでフィルタを掛けたい場合の参考になると思います。

経緯

進行中のプロジェクトをOutlookで管理しています。
※進捗状況ではなく、タスクの管理です。

プロジェクトを立ち上げる際に管理番号を発行したいと考えていました。最大値を取得する関数がなけえれば、データを降順にソートし、先頭の値を取れば良いと考えたのですが、ユーザ定義フィールドではソートが効かないようです。(エラーは発生しませんが、データはソートされない状態)

全てのデータを愚直に比較するよりは、フィルタを使って絞り込みをしていく方が処理回数を抑えることができると思います。


この断片があなたの星へ続く道を、少しでも照らすことを願って

投稿者: 0.1

厚塗りで「存在感や重さ、質感による説得力」のあるイラストを目指しています。 日本では線画をベースとしたイラストが主流ですが、そこから外れたモノもイラストの世界を広げる為に必要だと考えています。「世界観にもう一味試したい」そんなときには、ぜひお声がけください。

COMMENT