この記事では、組み込みの NotesAdministrationProcess クラスと 2つのカスタム LotusScript クラスを使用して、LotusScript でグループを扱う方法について解説します。

Andre Guirard (Andre_Guirard@us.ibm.com)), EI Product Developer, IBM

Andre Guirard is a member of the Enterprise Integration team of IBM Lotus Software, the developers of Lotus Enterprise Integrator (LEI) and other products that let you connect disparate data sources with each other and with Lotus Notes. Andre has made occasional appearances as a speaker at IBM conferences, and his articles have previously appeared on LDD, as well as in The View magazine and elsewhere.



2005年 1月 04日

はじめに

グループは、Domino ディレクトリにある Notes 文書の 1 つのタイプです。NotesDocument クラスを使用してグループ文書を操作できます。このときに問題となるのは、どのフィールドのどの値が何を意味するのかを知ることと、他のグループを含むグループ (ネストされたグループ) やメンバーリストのサイズが制限を超えるグループを扱うことの複雑さです。

この記事では、グループを操作する 2つの方法について説明します。まず、Lotus Notes/Domino 6.0 以降で使用できる、組み込みの LotusScript クラス NotesAdministrationProcess を取り上げます。このクラスを使用すると、グループへのメンバーの追加、グループ名の変更、およびグループの削除ができます (これ以外にも、このクラスにはグループに関連しない多数の機能があります)。グループからユーザーを削除する機能はありませんが、システム管理プロセス (AdminP) を使用してユーザーを完全に削除すると、このユーザーはグループからも削除されます。NotesAdministrationProcess クラスの詳細については、記事『LotusScript: The NotesAdministrationProcess Class in Notes/Domino 6』を参照してください。

また、より広範囲のグループ操作をサポートする2つのカスタム LotusScript クラスも紹介します。このコードは Lotus Notes/Domino 6.0 以降用に書かれているため、リリース 5 で使用するには、若干の変更が必要です。記事にはいくつかのサンプル・エージェントが記載されていて、これらのクラスをさまざまな作業で使用する例が示されています。これらのクラスは内部で List データ型を使用しています。このデータ型は Visual Basic でサポートされていないため、これらのクラスは COM からは使用できません。

クラスの実際のコード、すべてのサンプル・エージェント、この記事で解説したすべてのプロパティとメソッドのリストは、Sandbox からダウンロードできるサンプル・データベースに含まれています (サンプル・データベースの任意のビューで、[GMan help] アクションを使用するか、[F1] キーを押すと、これらのカスタム・クラスに関する詳細なマニュアルが表示されます)。カスタム・クラスは NotesGroupManager と NotesGroup です。これらを使用するには、サンプル・データベースから自分のアプリケーションに [LotusScript GroupManager] スクリプトライブラリをコピーし、Use ステートメントを使用してスクリプトにインクルードします。これらのクラスは、次の機能を持ちます。

  • すべてのアドレス帳を検索する。
  • すべてのアドレス帳または指定されたサブセットでグループ文書を検索する。
  • グループの作成と削除。
  • メンバーの追加と削除。
  • メンバーリストをソートする。
  • 他のグループを含むグループを扱う。
  • ユーザーがグループのメンバーであるかどうかを判断する。ネストされたグループを含む、グループのすべてのメンバーのリストを取得する。
  • 1つのグループ文書に格納できる人数以上のメンバーを持つグループを、複数のグループ文書に分割して管理する。

サンプル・データベースには、Domino ディレクトリテンプレート (pubnames.ntf) からコピーした設計要素が含まれるので、サンプル・データベースに含まれるデータにツールを使用することができ、お使いの Domino ディレクトリ内のグループが変更されるのを避けられます。このコードは任意のアプリケーションで使用できます。

この記事は、LotusScript での開発経験のある方を対象として書かれています。


Notes Administration Process クラスのグループ・メソッド

最初の部分でも説明したように、NotesAdministrationProcess クラスを使用すると、グループに対していくつかのシンプルな操作をすることができます (グループに関連しない他の多くの操作も可能です)。関連するメソッドについては、次のセクションで説明します。

これらの各メソッドは、Notes システム管理要求データベース (admin4.nsf) 内で要求文書を作成することによって機能します。AdminP がサーバー上で実行されると、要求を認識し、要求されているすべての操作を実行します。他のユーザーの承認が必要な要求や、処理を行うために他の Notes ドメインへメール送信される要求もあります。

このクラスを使用する利点は、次のとおりです。

  • 操作を実行するサーバーに直接アクセスできない場合でも、要求を発行できます。
  • ユーザーがスクリプトの完了を待っている場合は、完了が早くなります。実際の処理は、サーバーによって行われるからです。
  • AdminP は、グループの削除と名前変更に関してより徹底した作業を実行します。AdminP は、グループ・レコードを削除または変更するだけでなく、古いグループ名の参照を追跡し、それらを新しいグループ名に更新します。

このクラスの短所は、次のとおりです。

  • この方法で実行できるのは一部の操作だけです。
  • 要求は、すぐに実行されないことがあります。
  • 1つのグループ文書に格納できないほど多数のメンバーがいるグループには、メンバーを追加できません。

このクラスのほとんどのメソッドは、システム管理要求データベース内の新規要求文書の note ID を返します。要求を作成できない場合は (たとえば、現在のユーザーが権限を持っていない場合など)、失敗の理由に応じて、空の文字列 ("") を返すか、エラー状態となります。

note ID が返されるので、必要であればこの文書をモニターして、いつ要求が完了されたのかを知ることができます。AdminP は、タスクがいつ完了したかを示す返答文書を作成します。サーバーの設定によっては、要求をポストしたサーバーとは別のサーバーで AdminP が実行されることがあるので、システム管理サーバーとの間で複製が行われるまでの間、遅延が生じることがあります。AdminP に対して手動で操作するための権限を持っていない場合は、AdminP を使用しても何もできません。処理は自動的に行われます。

この記事では、これらのメソッドの完全な構文は記述しません。詳細については、『Domino Designer ヘルプ』を参照してください。ここでは、まとめおよびマニュアルには記載されていない役に立つヒントを紹介します。

AddGroupMembers メソッド

グループ名 (文字列) とユーザー名の配列を指定すると、このメソッドは、指定されたユーザーをグループに追加します。グループを見つけるために、複数のディレクトリを検索することがあります。この名前のグループが存在しない場合は、多目的タイプのグループが作成されます。このタイプのグループは、電子メールやアクセス制御に使用されます。グループ内にすでに存在するユーザーは追加されません。

メモ:『Domino Designer ヘルプ』には、メンバーの引数は、一人のユーザー名を含む文字列でよいと書かれていますが、これは Lotus Notes/Domino 6.5.4 の時点では機能しないようです。一人のユーザー名を追加する場合は、1 要素の配列を使用してください。

例 1: メーリングリストへの自動的な追加

次のエージェント (AdminP\Process Subscription Requests) は、メール受信データベースで新規メモの作成時またはメモの変更時に実行されるよう設定されています。このエージェントは件名の行に「subscribe」という単語が含まれるかどうかをチェックし、含まれる場合はユーザーをグループに追加します。

Option PublicOption Declare ' always use Option Declare

Sub Initialize
        Dim session As New NotesSession
        Dim adminp As NotesAdministrationProcess
        Dim db As NotesDatabase
        Dim coll As NotesDocumentCollection
        Dim docRequest As NotesDocument
        Dim strID As String
        Dim strNewMembersArray( ) As String
        Dim intNewMemberCount As Integer
        
        Set db = session.CurrentDatabase
        Set coll = db.UnprocessedDocuments
        Set docRequest = coll.GetFirstDocument( )
        Do Until docRequest Is Nothing
                If docRequest.Subject(0) = "subscribe" Then
                        Redim Preserve strNewMembersArray(0 To intNewMemberCount) 
                          strNewMembersArray(intNewMemberCount) = 
                          docRequest.GetItemValue("From")(0)
                        intNewMemberCount = intNewMemberCount + 1
                End If
                session.UpdateProcessedDoc docRequest
                Set docRequest = coll.GetNextDocument(docRequest)
        Loop
        If intNewMemberCount  > 0 Then ' There are some members to add
                Set adminp = session.CreateAdministrationProcess("bobbity")
                strID = adminp.AddGroupMembers("Hazardous Joke 
                  Mailing List", strNewMembersArray)
                If strID = "" Then ' Probable insufficient access
                        Msgbox {Unable to create adminp request "Add or Modify 
                          Group"}, 0, {adminp failure}
                End If
        End If
End Sub

DeleteGroup

グループ名を指定すると、このメソッドは指定されたグループを Domino ディレクトリから削除します。また、他のすべてのグループのメンバーリスト、データベースのACL、およびすべてのデータベース内の文書の読者フィールドと作成者フィールドから、このグループ名が削除されます。サーバーで Windows オペレーティング・システムが使用されている場合は、オプションとして、このメソッドによって同じ名前のWindows グループを削除できます。

RenameGroup

RenameGroup メソッドは、グループの古い名前と新しい名前を示す 2つの文字列引数を受け取ります。このメソッドは、実際のグループ・レコードで名前を変更するだけでなく、データベースの ACL リスト、他のグループのメンバーリスト、読者フィールドと作成者フィールド、およびグループ名が使用されているそれ以外の部分を更新します。


GroupManager スクリプトライブラリ

GroupManager スクリプトライブラリには、2 つのクラスといくつかの定数が含まれています。これらの定数は、メソッドの引数やプロパティの値として使用したり、On Error ステートメントで使用することができます。次のクラスがあります。

  • NotesGroupManager は、Domino ディレクトリを監視し、グループ情報に関するメモリキャッシュを管理します。このクラスを使用すると、メモリ内に定期的にグループを再ロードすることなく、複数のグループに複数の操作を実行できます。変更の保存は、すべての処理が完了するまで遅らされることがあります。NotesGroupManager は、再帰モードまたは非再帰モードで使用できます。再帰モードでは、どのグループが別のグループを含んでいるかを識別し、現在のグループとすべてのサブグループからユーザーを削除するといった再帰的な操作を実行できるようにします。
  • NotesGroup は、1つのグループの情報を保持しています。

ほとんどのタスクは、グループ名を引数として渡すことにより、NotesGroupManager メソッドを介して直接実行できます。NotesGroup クラスを使用する必要があるときは、GetGroup メソッドまたは CreateGroup メソッドを使用して、NotesGroupManager から NotesGroup オブジェクトを要求してください。これは、いくつかの高度な操作 (グループの所有者の変更など) で有効です。また、同じグループに複数の操作を実行する際に、コードを簡素化し、効率を高めるためにも役立ちます。

サブグループ、ブレークアウト・サブグループ、および再帰モード

GroupManager スクリプトライブラリには、グループの階層 (他のグループをメンバーとして含むグループ) を 6段階のネストまで扱うことができる機能があります。この記事では、他のグループのメンバーになっているグループのこと「サブグループ」と呼びます。

NotesGroupManager オブジェクトを作成するときに、再帰機能を無効にするオプションを選択すると、グループを階層がないメンバーの集まりとして扱うことができ、パフォーマンスが向上します。これは、サブグループのメンバーが、メイングループのメンバーとして現れるわけではありません。メイングループのメンバーでない限り、メンバーとみなさないことを意味します。

ブレークアウト・サブグループ (breakout subgroup) と呼ばれる特殊なタイプのサブグループがあります。要約フィールドのサイズが 32 KB に制限されているとき、メンバーが多すぎてメイングループに収まらない場合にブレークアウト・サブグループが使用されます (このケースでは、要約フィールドにはメンバーのリストが含まれています)。グループ・マネージャは、メンバーリスト全体を十分に格納できる追加グループを自動的に作成し、これらのグループをメンバーとしてメイングループに追加します。

ブレークアウト・サブグループの名前は、メイングループの名前の後にスペースと番号を付加したものになります。これは、ここで説明するコードでの処理であり、Lotus Domino での処理ではありません。Lotus Domino はグループ名によって扱いを変えませんが、グループ・マネージャは扱いを変更します。

メモ:ブレークアウト・サブグループ機能は、再帰モードでのみ有効です。

通常のサブグループとブレークアウト・サブグループの違いを示す例として、図1 に 2つのグループ階層が表示されています。

図 1. 通常のサブグループとブレークアウト・サブグループ
通常のサブグループとブレークアウト・サブグループ

Sailors グループには、何人かの船員の名前と 2 つのグループ (Pirates と Naval Officers) が含まれています。Pirates の各メンバーは船員で、Naval Officers の各メンバーも船員です。2 つのグループに分けたのは、それが役に立つからです。たとえば、Naval Officers グループは、将校だけが使用できる乗務員勤務実績データベースへのアクセスを許可されています。また、Pirates グループは、一般の船員には意味のない Pillaging Newsletter (戦利品ニュースレター) 用のメーリング・リストに使用されます。

これに対し、Hispaniola Crew グループにはブレークアウト・サブグループが含まれています。Hispaniola Crew のサブグループは他の場所では使用されず、利便性や組織上の目的で存在するわけでもありません。Notes フィールドのサイズ制限をクリアするためだけに存在します。これらのグループの詳細については後述します。

図 2. メーリング・リストのメンテナンス

例 1 と同様に、[GMan Process Subscription Requests] エージェントは、ユーザーからのメール受信購読要求に基づいて、[メールのみ] グループのメンバーを制御します。エージェントが処理するデータを与えるために、サンプル・データベースには、いくつかのメール受信購読要求と購読停止要求が含まれる [Memos] ビューがあります。もちろん、通常は Domino ディレクトリがメール受信データベースになることは絶対にありませんが、ここでは説明の都合上、同じデータベースにグループ・レコードを置くことにします。

[GMan Process Subscription Requests] エージェントは、新規メールを受信すると実行されるよう設定されています。このエージェントは、UnprocessedDocuments コレクション内の各メモを処理します。エージェントのコードは、次のとおりです。メール受信データベースを作成せずにこれを試すために、同様のエージェント「GMan Samples\1. Process subscription requests」が用意されています。このエージェントは、[Memos] ビューで選択した文書に実行できます。

Option Public
Option Declare  ' Always use Option Declare
Use "GroupManager"
Sub Initialize
        Dim session As New NotesSession
        Dim db As NotesDatabase
        Dim coll As NotesDocumentCollection
        Dim doc As NotesDocument
        Dim strSubject As String, strVerb As String, strGroupName  
          As String, strFrom As String
        Dim result As Boolean
        Dim gman As New NotesGroupManager(True)
        Call gman.LoadPublicAddressBooks
        gman.DefaultType = GROUP_TYPE_MAIL ' If we create 
        ' a group, make it a mail-only group.
        
        Set db = session.CurrentDatabase
        Set coll = db.UnprocessedDocuments
        Set doc = coll.GetFirstDocument( )

        Do Until doc Is Nothing
                strSubject = Fulltrim(doc.GetItemValue("Subject")(0))
                ' We expect subject = "subscribe" or "unsubscribe"  
                ' followed by group name.
                strVerb = Lcase(Strleft(strSubject, " "))
                strGroupName = Strright(strSubject, " ")
                strFrom = doc.GetItemValue("From")(0)
                ' Make sure group name specified is one we let people
                'subscribe to, e.g., don't allow changes to LocalDomainAdmins 
                'membership.
                If ValidateGroup(strGroupName) Then
                        If strVerb = "unsubscribe" Then
                                ' Remove sender's email from group. Also from 
                                ' subgroups, in case list is so large that there are 
                                ' 'breakout' subgroups.
                                Call gman.RemoveFromGroup(strGroupName, 
                                  strFrom, GROUP_RECURSE)
                                SendMessage db, strFrom, "Your unsubscribe request  
                                  was processed", {You have been removed from group "} 
                                  & strGroupName & {". So long!}
                        Elseif strVerb = "subscribe" Then
                                ' Add member to the group with these options:
                                '  -- Create the group if it doesn't exist.
                                '  -- Don't add name if it's already in a subgroup.
                                '  -- If name is already there but not an exact match, 
                                ' update it.
                                result = gman.AddToGroup(strGroupName, strFrom, 0,  
                                  GROUP_CREATE + GROUP_RECURSE + GROUP_UPDATE)
                                If result Then
                                        ' Not already in the group (or name changed) -- 
                                        ' welcome them.
                                        SendMessage db, strFrom, "Your subscription to 
                                          "& strGroupName & " was processed.", 
                                          {Welcome to the "} & strGroupName & 
                                          {" mailing list! Please review our policy 
                                          at http://www.iupp.org before posting to 
                                          this list.}
                                End If
                        End If ' Subscribe
                End If ' Group name valid
                Call session.UpdateProcessedDoc(doc)
                Set doc = coll.GetNextDocument(doc)
        Loop
        gman.SaveAll ' Or none of your group changes will be saved
End Sub

サブルーチン ValidateGroup と SendMessage はここには表示されていませんが、サンプル・データベースには含まれています。ValidateGroup の実装は、このエージェントに管理させるグループによって異なります。また、SendMessage は、この記事で説明する範囲を超えています。例 1 と異なり、このエージェントは購読要求と購読停止要求の両方を扱います。ほとんどのコードは、何をするべきかを示す情報を取得します。次のコードで、それが実際に実行されます。

  • Use "GroupManager" は、GroupManager ライブラリをロードします。
  • Dim gman As New NotesGroupManager (True) は、NotesGroupManager オブジェクトを作成します。
  • Call gman.LoadPublicAddressBooks は、グループ・マネージャに、すべての Domino ディレクトリ (公開アドレス帳) を使用するよう指示します。
  • gman.DefaultType = GROUP_TYPE_MAIL は、グループを自動的に作成する場合は (ユーザーを追加するために)、それを「メーリング・リスト」グループにするよう指定します。
  • Call gman.RemoveFromGroup (strGroupName, strFrom, GROUP_RECURSE) は、1 つのグループとすべてのサブグループからユーザーを削除します。GROUP_RECURSE オプションも、このユーザーをすべてのサブグループから削除します。デフォルトでは、このユーザーは指定されたグループから削除されます。これは、ブレークアウト・サブグループが必要なほど大きなグループを扱うときに重要です。ユーザーをサブグループから削除しない限り、このユーザーはメイングループのメンバーとして残ります。
  • result = gman.AddToGroup(strGroupName, strFrom, 0, GROUP_CREATE + GROUP_RECURSE + GROUP_UPDATE) は、ユーザーをグループに追加します。この行について、いくつかの点を解説します。

    3 番目の引数 (0) は、グループが存在しないときに、グループを作成するディレクトリの 0 を基準としたインデックスです。このインデックスは、ロード済みの Domino ディレクトリのリストに基づきます。前に LoadPublicAddressBooks を呼び出したので、一次 Domino ディレクトリである names.nsf のインデックスは 0 になります。

    GROUP_RECURSE オプションは、ユーザーがすでにサブグループのメンバーである場合は、そのユーザーをメイングループに追加しないよう指定します。ブレークアウト・サブグループが必要なほど大きなグループを扱うときは、追加時の重複を防ぐために、このオプションを使用してください。

    GROUP_UPDATE は、追加したいユーザーと同じ電子メールアドレスを持つメンバー (しかし、まったく同じ名前ではない) がすでにグループにいる場合に、どのように処理するのかを制御します。たとえば、「Hester Prynne <hester@bigredletter.org>」というメンバーがいるときに「Hester A. Prynne <hester@bigredletter.org>」というユーザーを追加するような場合です。デフォルトでは、このような場合にグループは更新されませんが、GROUP_UPDATE を指定すると、新しい名前に正確に一致するよう、グループが更新されます。
  • gman.SaveAll は、グループ・マネージャを介して行われたすべてのグループ変更を保存します。

例 3: グループの削除と作成

[GMan Samples\2. Delete and Create Groups] エージェントは、グループの削除および作成の方法と、単純な階層のグループを扱う方法を示します。このエージェントは、図 1 に示されたすべてのグループを最初に削除します。Sailors、Naval Officers、および Pirates の各グループに対しては、これは簡単な作業です。グループの名前がわかっていて、gman.RemoveGroup を使用できるからです。しかし、Hispaniola Crew グループについては、含まれているブレークアウト・サブグループの数が不明なので、少し複雑な作業になります。メイングループを削除してもサブグループは自動的に削除されないので、手動で削除するコードが必要です。これらのグループをすべて削除するコードは、次のとおりです。

        Dim gman As New NotesGroupManager(True)
        Dim group As NotesGroup
. . .
        Call gman.RemoveGroup("Pirates")
        Call gman.RemoveGroup("Sailors")
        Call gman.RemoveGroup("Naval Officers")
        
        ' Because we'll be doing several operations on one group, 
        ' get a NotesGroup object to make things more efficient.
        Set group = gman.GetGroup("Hispaniola Crew")
        If Not (group Is Nothing) Then
                Dim subgroups
                ' Are there subgroups to hold overflow (e.g., "Hispaniola Crew 2")?
                subgroups = group.BreakoutSubgroups
                Forall subgroup In subgroups
                        Dim strTemp
                        strTemp = subgroup.Name
                        Call group.RemoveMembers(strTemp, 0) 'Remove subgroup from 
                          main group.
                        Call gman.RemoveGroup(strTemp) 'Delete the group altogether.
                End Forall
                gman.RemoveGroup("Hispaniola Crew")
        End If

BreakoutSubgroups プロパティは、名前を指定するためにコードで使用されているパターン (メイングループ名にスペースと番号を付加したもの) に一致するサブグループの名前を返します。この例では、NotesGroupManager クラスは、グループに関連するブレークアウト・サブグループのリストにアクセスするために必要なプロパティを持たないので、NotesGroup オブジェクトを使用して特定のグループの詳細を知る必要があります。

グループとそのすべてのブレークアウト・サブグループを削除するもう 1つの方法としては、それらの名前を知り、その名前のすべてのグループを削除します。次のようになります。

Sub DeleteBreakoutGroup(gman As NotesGroupManager, strName As String)
        Dim intInd As Integer
        If gman.RemoveGroup(strName) Then
                intInd = 2
                While gman.RemoveGroup(strName & " " & intInd)
                        intInd = intInd + 1
                Wend
        End If
End Sub

削除を要求したグループが実際に存在する場合は、RemoveGroup メソッドはブール値の True を返すので、戻り値を調べることによって、同様の名前を持つ他のグループを検索する必要があるかどうかを判断できます。このコーディングは簡単ですが、誰かがブレークアウト・サブグループの 1 つを手動で削除した可能性もあるので、この方法は絶対的な保証がなく、必ずしも安全ではありません。ブレークアウト・サブグループの 1 つが削除されていると、それよりも上位の番号のグループを削除できません。

次に、削除したばかりのグループを再び作成します。グループを作成するには 2 つの方法があります。例 2 で示したように GROUP_CREATE オプションを使用してメンバーを追加する方法と、次のように gman.CreateGroup を使用する方法です。

        Redim values(0 To 3) As String
        Set group = gman.CreateGroup("Naval Officers", GROUP_TYPE_MULTI, 0)
        group.Description = "Current serving officers only."
        values(0) = "Horatio Hornblower/Hotspur/HRMN"
        values(1) = "Jack Aubrey/Surprise/HRMN"
        values(2) = "Stephen Maturin/Surprise/HRMN"
        values(3) = "James Hook/BadGuys/Neverland"
        Call group.AddMembers(values, 0) ' 2nd argument is options

NotesGroup の Description プロパティを使用してリストの説明フィールドを割り当てたことに注目してください。これを実行できるのは NotesGroup オブジェクトを持っているときだけで、gman.AddToGroup でグループを作成した場合は、このオブジェクトを持っていません。もちろん、後から GetGroup を使用することで、いつでも NotesGroup オブジェクトを取得できます。たとえば、次のようになります。

gman.GetGroup("Pirates").Description = "Scourges of the Sea"

これまでに、メンバーをグループに追加する 2 つの方法である gman.AddToGroup と group.AddMembers について説明しました。メンバーを追加および削除するメソッドは、1 つの文字列または文字列の配列を受け取るので、一度に複数のメンバーを操作できます。この場合、配列の要素を割り当て、この配列を AddMembers に渡す方法ではなく、次のように記述することができます。

        Call group.AddMembers("Horatio Hornblower/Hotspur/HRMN", 0)
        Call group.AddMembers("Jack Aubrey/Surprise/HRMN", 0)
        Call group.AddMembers("Stephen Maturin/Surprise/HRMN", 0)
        Call group.AddMembers("James Hook/BadGuys/Neverland", 0)

Notes ID を短縮形式で使用しています。グループ文書内のユーザー名は正規形式 ("CN=...") でなければなりませんが、グループ・マネージャのコードはどちらの形式も受け入れ、変換を自動的に行います。

メンバーをグループに追加する 3番目の方法は、NotesGroup の Members プロパティを使用します。これは、読み取り/書き込みが可能なプロパティなので、配列の値を割り当てることによって、グループのメンバー全体を一度に変更できます。サンプル・エージェントの追加コードを以下に示します。

        Set group = gman.CreateGroup("Sailors", GROUP_TYPE_MULTI, 0)
        group.Description = "All navvies"
        values(0) = "Queequeg/Pequod/Whalers"
        values(1) = "Jack Dawson/Titanic/White Star"
        values(2) = "Pirates" ' the group
        values(3) = "Naval Officers" ' the group
        group.Members = values

この方法によるグループのメンバーの割り当ては、常に階層なしでの追加となります。サブグループに名前の重複がある場合でも、メンバーのリストは指定したとおりになります。

例 4: ブレークアウト・サブグループの作成

前の例では、ブレークアウト・サブグループの作成と通常のグループの作成に違いはありませんでした。必要なのは NotesGroupManager オブジェクトを必ず再帰モードで作成することだけであり (New メソッドへの引数を True に設定)、このようにすると、グループが大きすぎるときに、ブレークアウト・サブグループが自動的に生成されます。

[GMan Samples\3. Add many members] エージェントによって、これが示されています。ブレークアウト・サブグループが必要なほど大きなグループを作成するために、このエージェントには、形容詞、名、姓のリストからランダムに選択してメンバー (海賊) の名前 (例: Long John Silver や Whistling Ned Doggett など) を生成するコードが含まれています。ランダムな名前は、次のように Hispaniola Crew グループに追加されます。

        If group.AddMembers(strCrewName, GROUP_RECURSE) Then
                        intCount = intCount + 1
                End If

ブレークアウト・サブグループが必要なほど大きなグループを扱うときは、GROUP_RECURSE オプションを使用することが重要です。このようにしないと、すでにブレークアウト・サブグループに含まれるユーザーをメイングループに追加する可能性があります。同じことが、メンバーの削除にもあてはまります。

AddMembers の戻り値を使用すると、名前が実際に追加されたかどうかを判断できます。ユーザーがメンバーでなかった場合、このメソッドは True を返します。この場合は、重複のない名前がいくつ追加されたかを記録することで、停止するタイミングを知ることができます。

1つのグループに何人のメンバーを詰め込むことができるかを知るだけならば、このエージェントを複数回実行します。形容詞、名、姓の組み合わせは約 16,000 件あります。エージェントを編集し、リストに追加することにより、この組み合わせの数を増加させることができます。

例 5: グループの検索

NotesGroupManager は、キャッシュにロードしたすべてのグループのリストを示す CachedGroups プロパティを持っています。通常は、名前を指定して要求したグループがロードされます。再帰モードでは、要求したグループのすべてのサブグループもロードされます。

group.FTSearch を使用すると、全文検索のクエリーに一致するグループを検索できます。これは、クエリー文字列を引数として受け取ります。この文字列は、グループ・マネージャが認識する各 Domino ディレクトリにおける FTSearch メソッドへの引数として使用されます。検索に一致するグループ文書は、キャッシュ内に保持されます。

Domino ディレクトリに全文索引が作成されている場合は、Members フィールドで共通名またはメールアドレスを検索することにより、このメソッドを使用して特定のユーザーが含まれるすべてのグループを素早く検索できます。この後、group.IsMember プロパティを使用すると、誤った一致を取り除くことができます。次の例は、[GMan Samples\4. Full Text Search] エージェントに含まれているコードです。

        strSearch = Trim(Inputbox( "Search string:"))
. . .
        lngCount = gman.FTSearch(strSearch)
        Dim groupList As Variant
        Dim strGroupDesc As String
        
        If lngCount = 0 Then
                Msgbox "No groups matched your query."
        Else
                groupList = gman.CachedGroups
                Forall group In groupList
                        strGroupDesc =  strGroupDesc & ", " & group.Name
                End Forall
                Msgbox "The following " & lngCount & " groups matched 
                  your query: " & Mid$(strGroupDesc, 3)
        End If

検索結果に一致するグループだけを必要とし、そのサブグループは必要ない場合は、非再帰モードでグループ・マネージャを使用してください

キャッシュを操作するには、他にもいくつかの方法があります。LoadAllGroups、LoadGroup、Uncache および ClearCache です。LoadAllGroups は、すべてのディレクトリのすべてのグループの情報を取得するので、前述したようなループを使用して、各グループに繰り返しアクセスします。


まとめ

この記事では、グループを操作するカスタム・コードの使い方を解説するために、いくつかのサンプルを掲載しました。また、この記事では触れませんでしたが、他の操作を行なうためのメソッドやプロパティもあります。たとえば、グループの所有者を制御する、メンバーリストをソートする、対応するプロパティを持たないグループ文書のフィールドに直接アクセスして値を変更するなどの操作が可能です。これらのプロパティおよびメソッドの詳細は、すべてサンプル・データベースに掲載されています。

ソースコードを入手すると、用途に応じてクラスを改変したり拡張することができます。もし、リリース 5 または COM バージョンのコードを書かれた場合は、他のユーザーも利用できるように、ぜひ Sandbox までお送りください。サンプル・データベースのマニュアルまたはコードに不具合を見つけた場合は、メールにて作者までご連絡ください。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Lotus
ArticleID=340594
ArticleTitle=LotusScript でグループを操作する
publish-date=01042005