Reg Exp
Web Design
Notes Client
Get a list of image resources
In the same web project where I talked about uploading an attachment and converting it to an image resource (Converting Web Attachment to Image Resource), I also wanted to make sure that the user didn't create multiple image resources with the same name. In the original tip, I pointed out that there was no checking for duplicate images. To prevent duplicate images, I ran an agent on web query open that populated a field with the names of the current images. Then I could use JavaScript on the client to check for a duplicate image, and also code in the web query save agent that checks for duplicates by looking for the image name inside the field set in query open.

The agent, as I always do, starts out defining the variables that will be needed:

Sub Initialize
   Dim ws As New NotesUIWorkspace
   Dim session As New NotesSession
   Dim dbPath As Variant
   Dim db As NotesDatabase
   Dim images() As String
   Dim i As Integer
   Dim coll As NotesNoteCollection
   Dim id As String
   Dim note As NotesDocument
   Dim temp As Variant
   Dim title As String

This example agent then prompts the user for the database to scan. Obviously, in my implementation as a web query open agent, I just use the current database and eliminate the ws variable entirely. But this example agent lets you explore other databases beyond the current one.

   dbPath = ws.Prompt(13, "Choose Database", "")
   If Not Isarray(dbPath) Then Exit Sub

The 13 constant is the same as PROMPT_CHOOSEDATABASE if you use the named constants instead of the numbers. If the user chooses a database, the method will return an array of 3 values. The first value is the server (an empty string for a local database). The second value is the file path. The third value is the database title. If the user clicked cancel, then an array is not returned. So, the second line in the code (checking for the array) checks for the user clicking cancel in the "Open Database" dialog box.

Once the code knows that the user didn't click cancel, the next thing to do is get a handle to the database. It might be that the user doesn't have access to the database. So the code needs to make sure the database can be opened:

   On Error Resume Next
   Set db = session.GetDatabase(dbPath(0), dbPath(1), False)
   If Not db.IsOpen Then Call db.Open("", "")
   If Not db.IsOpen Then
      Msgbox "Error. Could not open database.", 16, "Error"
      Err = 0
      Exit Sub
   End If
   On Error Goto 0
   If Err <> 0 Then
      Msgbox "Error " & Cstr(Err) & " (" & Error$ & ") attempting to open database.", 16, "Error"
      Err = 0
      Exit Sub
   End If

The next thing to do is get a collection of the Note ID's of the Image Resource design elements. That is done through the NotesNoteCollection class. That class is similar to a NotesDocumentCollection, except it can contain design elements in addition to documents.

   Set coll = db.CreateNoteCollection(False)
   Redim images(0)
   i = Lbound(images)
   coll.SelectImageResources = True
   Call coll.BuildCollection

The first line creates an object and doesn't put anything into the object by default (that's what the False parameter does). The next line initializes the array that will hold the names of the images. The next line sets the variable i to the lower bound of the array. I know that the lower bound is 0 and I could have just set the variable to zero. But setting it this way gives someone looking at the code later on down the road an indication that the variable i is going to have something to do with the array. In fact, it's going to be a pointer into the array. So that little bit of extra work on my part makes the code easier to support later on.

The next line tells the NotesNoteCollection object to put image resources into the collection when built. There are many properties that can be used to get different types of design elements, and all the properties are documented in the Domino Designer Help. The last line actually builds the collection.

Now that the code has a collection of image resources (technically, it only has a collection of Note ID's), those can be processed to find out the names of the images.

   If Not coll Is Nothing Then
      id = coll.GetFirstNoteId
      While id <> ""
         Set note = db.GetDocumentByID(id)
         temp = note.GetItemValue("$Title")
         If Isarray(temp) Then title = Cstr(temp(0)) Else title = Cstr(temp)
         Redim Preserve images(i)
         images(i) = title
         i = i+1
         id = coll.GetNextNoteId(id)
   End If

The NotesNoteCollection has an "array" of Note IDs. So, the code gets the first Note ID, then repeatedly gets the next Note ID until Domino returns an empty string indicating that all the Note IDs have been processed.

For each Note ID, get a handle to that design element as a document. The variable note is defined as a NotesDocument object. The document has fields that can be processed, including one called $Title which is the name (and possibly the alias) of the design element.

The code makes sure that it gets the first value if there is are more than one and puts it into the array of image names. The array is resized each time, which isn't the best for performance. But most databases are going to have relatively few (10 or less) image resources, so implementing a more efficient resizing algorithm probably isn't worth the effort.

After this loop is over, the variable images is an array of all the current image resources. In my web query open event, I just set a field value to this array and then I can use that field value to build a JavaScript array, and the field value will be there when the form is submitted. But for this example agent, the best thing to do is give the user a message box with the names of the images:

   title = "Here is a list of images from the database " & db.Title & ":"
   Msgbox title & Chr$(10) & Chr$(10) & Join(images, Chr$(10)), 64, "Images"
End Sub

You should now be able to use this agent to give yourself a list of all the image resources in any database you can access.