Exclude Already-Selected Documents from Dropdown List

In our M-Files setup, we have a class called Invoices which includes a property named Supporting Info. This property points to another class of documents (also called "Supporting Info") and is set up as a dropdown list in the metadata card so users can select one or more supporting documents to link with the invoice.

The challenge we're facing is that even after a document is selected and attached as Supporting Info on an invoice, it still appears in the dropdown list for the same and other invoices. The list of the supporting info documents is populated with a lot of documents, making it difficult for users to find relevant, unused documents.

What we're trying to achieve:
We want to exclude documents that have already been selected as Supporting Info from showing up in the dropdown list. Ideally, once a supporting document is linked to an invoice, it should no longer appear as an option.

Any best practices or tips would be appreciated.

Thanks

  • You can add a new lookup property named something like "IsUsed". The lookup will have "YES" (ID 1) and "NO" (ID 2) and put it in supporting info class. Now, you can filter out "Supporting Info" multi lookup property with "IsUsed" != "YES".

    So, when some object from "Supporting Info" class is used in "Invoices" class, you can set "IsUsed" to "YES" and it will not appear in the lookup again.

    Const oSuppsID = xxxx 'mulitselect property we have in Invoices
    Const IsUsedID = xxxx 'Yes/No list that will be in supporting info class
    
    
    Dim PropertyValues : Set PropertyValues = Vault.ObjectPropertyOperations.GetProperties(ObjVer)
    Dim classOfObject : classOfObject = PropertyValues.SearchForProperty(100).TypedValue.GetValueAsLookup().Item
    
    IF classOfObject = xxx THEN 'your Invoices class ID goes here
      oSupps = Vault.ObjectPropertyOperations.SearchForProperty(oSuppsID).TypedValue.DisplayValue
      IF oSupps <> "" THEN 'we have something(s) selected in the property
        SET oSupps = Vault.ObjectPropertyOperations.SearchForProperty(oSuppsID).TypedValue.GetValueAsLookups
        For Each xitem in oSupps
          Set oObjId = CreateObject("MFilesAPI.ObjID")
    
          oObjId.Type = oSuppObj
          oObjId.ID = xitem.ObjVer.ID
    
          Set oSuppObject = Vault.ObjectOperations.GetLatestObjectVersionAndProperties(oObjId, true)
          Set oSuppProperties = oSuppObject.Properties
          IF oSuppProperties.IndexOf(IsUsedID) <> -1 THEN 'do we have this property in the class
            IF oSuppProperties.SearchForProperty(IsUsedID).TypedValue.DisplayValue <> "" THEN 'does it contain anything
              'it does
              Dim oValue : SET oValue = CreateObject("MFilesAPI.PropertyValue")
              Dim oValues : SET oValues = CreateObject("MFilesAPI.PropertyValues")  
    
              oValue.PropertyDef = IsUsedID
              oValue.TypedValue.SetValue MFDataTypeLookup, 1 'assuming YES has 1 as ID
              oValues.Add 0 , oValue
    
              Vault.ObjectPropertyOperations.SetProperties ObjVer, oValues
            END IF
          END IF
        Next
      END IF
    END IF

    you can automate setting "IsUsed" to "YES" with this VBScript. Know that, the script is;

    • rushed
    • untested
    • written in the morning pre-coffee Slight smile

    so, it should work but I suspect it might need a checkout on the objects we are trying to set IsUsed = YES

  • I would strongly advise against using VBScript if you can. VBScript will be removed by Microsoft at some point in the future, so creating new scripts seems like a bad idea. 

    If you can use either the VAF or property calculator instead. 

    During IMPACT we talked about the future options here, but I don't know what is public yet. 

  • I knew this would come from you and/or Joonas Smiley I couldn't find a way to do it with property calculator in my pre-tea/coffee state in the morning Slight smile

    I still can't see how it could be done with property calculator tho.. And having to restart whole vault for every VAF implementation is not possible every time.

    As I have never been lucky enough to join any kind of "IMPACT" so far (been 13 years...) I have no idea what kind of news you have for us Slight smile

  • I don't know whether it *can* be done with those tools, so this was more of a general statement!

    We have published IMPACT documents to the partner portal though so partners can see the preview content there (I think the session was called "the future of vault development" or similar).

    It's not my baby and I'm not aware specifically of what has been said outside of our partner network (who are obviously under NDA), hence why I won't go into more details here. 

    Edit:

    One other thing I would push back on is "having to restart whole vault for every VAF implementation is not possible every time".  I understand the point here but I would voice my own personal opinion that the vault restart should not be seen as something which is a significant issue in most real-world cases.  During development (i.e. when you are changing the application a lot) you should be using your own machine or a dev/test vault, so nobody will care how often it gets restarted.  When you get to the point of deployment there should be a change deployment process which can include agreement about when the change gets deployed to minimise downtime.  It's rare, outside of very large or geographically-distributed customers, where a time cannot be organised for something like this in a production environment.

    And those larger customers will certainly highly value a well-written, well-tested (manual and automated) vault application over a VBScript.  Certainly the risk to a production vault of deploying a well-written, well-tested (manual and unit testing) vault application should be far less than the risk of deploying VBScript, which (by its nature) is easier to accidentally break without significant manual testing.

    Additionally there is a lot of work ongoing within M-Files at the moment around "zero downtime" which is the concept of being able to restart a vault in the cloud without anyone even noticing.  Whilst the target here is certainly how our cloud can be awesome many of these optimisations will come to on-premises as well, meaning that vault restarts will end up being much faster in the future.  The result of this should be that even things like vault application deployments will be less of a concern.

    So, whilst I understand your point, I do question whether in the real-world it's something that will realistically be a significant concern in the medium-term.  Certainly building something in VBScript has real-world and significant known issues (right now in terms of testability, and in the future in terms of deprecation), so those outweigh any vault-restart concerns in my eyes.