This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Copy item from single-select to multi-select.

Former Member
Former Member
Hello, this is my first post, so thanks up front for whatever help anyone can give, and sorry for my lack of knowledge.

I am trying to copy the selection in a single-select property (iRollNumberProperty) to the selection in a multi-select property (iLandIDProperty) on the same object. The properties pull from two different Object Types which use identical queries to pull from the same external source (so, the unique IDs are the same in both Object Types).

I borrowed the AddUpdateProperty function from another topic, and used it without modification. The code is in the automatic value of an unrelated field.

I have used one specific case (129203000) to troubleshoot. The idea is to add the objectID "129203000" to the Land ID property to the object I was using as a test. When I trigger it, I get the error message that is attached. 344 is the ID of the Land ID object type, which is where the property value should be pulled from.

Hopefully my code will fill in the gaps where my explanation may be lacking. This is M-Files 2015.3.

Thanks.



Option Explicit

Dim iRollNumberProperty : iRollNumberProperty = 1432 '1432 is the Roll Number Property Definition
Dim iLandIDProperty : iLandIDProperty = 1747 '1747 is the LandID Property Definition
Dim objClientLookup: Set objClientLookup= PropertyValues.SearchForProperty(iLandIDProperty).TypedValue.GetValueAsLookup()

if IsNull(PropertyValues.SearchForPropertyEx(iLandIDProperty, true))=False then

    dim iRolls: iRolls = 129203000
    AddUpdateProperty iRolls, iLandIDProperty

end if


Function AddUpdateProperty(sValue, PROP_ID)

Dim oProperty : Set oProperty = CreateObject("MFilesAPI.PropertyValue")
oProperty.PropertyDef = PROP_ID
Dim iDataType : iDataType = Vault.PropertyDefOperations.GetPropertyDef(oProperty.PropertyDef).DataType
Dim iValue : iValue = CLng(sValue)
Dim oLookups : Set oLookups = PropertyValues.SearchForProperty(PROP_ID).TypedValue.GetValueAsLookups()
Dim oLookup : Set oLookup = CreateObject("MFilesAPI.Lookup")
Dim oCount

oCount = oLookups.Count
If oCount <> 0 then oCount = oCount + 1
oLookup.Item = iValue
oLookups.Add oCount, oLookup
PropertyValues.SearchForProperty(PROP_ID).TypedValue.SetValueToMultiSelectLookup oLookups
oProperty.TypedValue.SetValueToMultiSelectLookup oLookups
Vault.ObjectPropertyOperations.SetProperty ObjVer, oProperty
End Function
Parents
  • Dear DonO,

    I couldn't find anything that definitively tells me when the auto-calculate properties on an object cause an associated script to run.

    you can see execution order of scripts here: https://www.m-files.com/user-guide/latest/eng/execution_order_of_scripts.html?hl=order%2Cscripts
    you can see available event handlers here: https://www.m-files.com/user-guide/latest/eng/Event_handlers_variables.html?hl=event%2Chandlers

    The code is in the automatic value of an unrelated field.

    Why don't you write copying script into property definition that you are automatically calculating (LandID Property)? then you would not need to use SetProperty VaultObjectPropertyOperation in your code and copying would become as simple as:


    CONST ROLL_NUMBER_PD = 1432 'Single select where to copy from
    CONST LAND_ID_OBJTYPE = 344 ' Object Type of Land ID

    dim RollNumberPV: set RollNumberPV = PropertyValues.SearchForPropertyEx(ROLL_NUMBER_PD, true)

    if not IsNull(RollNumberPV) then 'Roll Number Property Definition exists on metadata card

    'Get selected Rollnumber as Lookup
    dim RollNumberLookup: set RollNumberLookup = RollNumberPV.Value.GetValueAsLookup()

    'Find LandID list item by DisplayID of selected Rollnumber
    dim LandIDListItem
    set LandIDListItem = Vault.ValueListItemOperations.GetValueListItemByDisplayID(LAND_ID_OBJTYPE , RollNumberLookup.DisplayID)

    'Owerwrite all existing selections with found single select value
    Output.SetValue MFDatatypeMultiselectLookup, LandIDListItem.ID

    end if


    In order to prevent "maximum number of script executions exceeded" from happening, you could check if property was already selected, if it is don't update property.
    Example how I would check if item is selected by creating IsItemSeleted function

    Option Explicit

    CONST ROLL_NUMBER_PD = 1432 'Single select where to copy from
    CONST LAND_ID_OBJTYPE = 344 ' Object Type of Land ID

    CONST LAND_ID_PD = 1747 'Multi select where to copy to

    dim LandIDPV: set LandIDPV = PropertyValues.SearchForPropertyEx(LAND_ID_PD, true)
    dim RollNumberPV: set RollNumberPV = PropertyValues.SearchForPropertyEx(ROLL_NUMBER_PD, true)

    if not IsNull(LandIDPV) then 'LandID property definition exists on meta-data card
    if not IsNull(RollNumberPV) then 'Roll Number property definition exists on meta-data card

    if not RollNumberPV.Value.IsNull() then 'Something is selected on Roll Number property

    'Get selected Roll number as Lookup
    dim RollNumberLookup: set RollNumberLookup = RollNumberPV.Value.GetValueAsLookup()

    'Find LandID list item by DisplayID of selected Roll Number
    dim LandIDListItem
    set LandIDListItem = Vault.ValueListItemOperations.GetValueListItemByDisplayID( LAND_ID_OBJTYPE , RollNumberLookup.DisplayID )

    if not IsItemSeleted( LandIDPV.Value, LandIDListItem.ID ) then 'This LandID is not already selected


    LandIDPV.Value.SetValue MFDatatypeMultiSelectLookup, LandIDListItem.ID 'Select/overwrite current selection with LandIDListItem.ID

    'or alternatively append selection with AppendSelection procedure defined below
    'AppendSelection LandIDPV.Value, LandIDListItem.ID, LAND_ID_OBJTYPE

    Vault.ObjectPropertyOperations.SetProperty ObjVer, LandIDPV 'Commit this propertyValue to current ObjVer
    end if
    end if
    end if
    end if

    'Check if provided itemID is selected in MultiSelectTypedValue
    function IsItemSeleted(MultiSelectTypedValue, ItemID )
    dim Result: Result = false

    if not MultiSelectTypedValue.IsNull() then
    dim Lookups: set Lookups = MultiSelectTypedValue.GetValueAsLookups()
    dim Lookup
    for each Lookup in Lookups
    if Lookup.Item = ItemID then
    Result = true
    Exit For
    end if
    next
    end if
    IsItemSeleted = Result
    end function

    'Append given itemID as selection of provided MultiSelectTypedValue. TypeID Is objectType ID of lookup
    sub AppendSelection(MultiSelectTypedValue, ItemID, TypeID )

    dim NewLookup: Set NewLookup = CreateObject("MFilesAPI.Lookup")

    NewLookup.ObjectType = TypeID
    NewLookup.Item = ItemID
    NewLookup.SetLatestVersion

    dim Lookups
    if MultiSelectTypedValue.IsNull() then
    set Lookups = CreateObject("MFilesAPI.Lookups")
    else
    set Lookups = MultiSelectTypedValue.GetValueAsLookups()
    end if

    Lookups.Add -1, NewLookup
    MultiSelectTypedValue.SetValueToMultiSelectLookup Lookups
    end sub




Reply
  • Dear DonO,

    I couldn't find anything that definitively tells me when the auto-calculate properties on an object cause an associated script to run.

    you can see execution order of scripts here: https://www.m-files.com/user-guide/latest/eng/execution_order_of_scripts.html?hl=order%2Cscripts
    you can see available event handlers here: https://www.m-files.com/user-guide/latest/eng/Event_handlers_variables.html?hl=event%2Chandlers

    The code is in the automatic value of an unrelated field.

    Why don't you write copying script into property definition that you are automatically calculating (LandID Property)? then you would not need to use SetProperty VaultObjectPropertyOperation in your code and copying would become as simple as:


    CONST ROLL_NUMBER_PD = 1432 'Single select where to copy from
    CONST LAND_ID_OBJTYPE = 344 ' Object Type of Land ID

    dim RollNumberPV: set RollNumberPV = PropertyValues.SearchForPropertyEx(ROLL_NUMBER_PD, true)

    if not IsNull(RollNumberPV) then 'Roll Number Property Definition exists on metadata card

    'Get selected Rollnumber as Lookup
    dim RollNumberLookup: set RollNumberLookup = RollNumberPV.Value.GetValueAsLookup()

    'Find LandID list item by DisplayID of selected Rollnumber
    dim LandIDListItem
    set LandIDListItem = Vault.ValueListItemOperations.GetValueListItemByDisplayID(LAND_ID_OBJTYPE , RollNumberLookup.DisplayID)

    'Owerwrite all existing selections with found single select value
    Output.SetValue MFDatatypeMultiselectLookup, LandIDListItem.ID

    end if


    In order to prevent "maximum number of script executions exceeded" from happening, you could check if property was already selected, if it is don't update property.
    Example how I would check if item is selected by creating IsItemSeleted function

    Option Explicit

    CONST ROLL_NUMBER_PD = 1432 'Single select where to copy from
    CONST LAND_ID_OBJTYPE = 344 ' Object Type of Land ID

    CONST LAND_ID_PD = 1747 'Multi select where to copy to

    dim LandIDPV: set LandIDPV = PropertyValues.SearchForPropertyEx(LAND_ID_PD, true)
    dim RollNumberPV: set RollNumberPV = PropertyValues.SearchForPropertyEx(ROLL_NUMBER_PD, true)

    if not IsNull(LandIDPV) then 'LandID property definition exists on meta-data card
    if not IsNull(RollNumberPV) then 'Roll Number property definition exists on meta-data card

    if not RollNumberPV.Value.IsNull() then 'Something is selected on Roll Number property

    'Get selected Roll number as Lookup
    dim RollNumberLookup: set RollNumberLookup = RollNumberPV.Value.GetValueAsLookup()

    'Find LandID list item by DisplayID of selected Roll Number
    dim LandIDListItem
    set LandIDListItem = Vault.ValueListItemOperations.GetValueListItemByDisplayID( LAND_ID_OBJTYPE , RollNumberLookup.DisplayID )

    if not IsItemSeleted( LandIDPV.Value, LandIDListItem.ID ) then 'This LandID is not already selected


    LandIDPV.Value.SetValue MFDatatypeMultiSelectLookup, LandIDListItem.ID 'Select/overwrite current selection with LandIDListItem.ID

    'or alternatively append selection with AppendSelection procedure defined below
    'AppendSelection LandIDPV.Value, LandIDListItem.ID, LAND_ID_OBJTYPE

    Vault.ObjectPropertyOperations.SetProperty ObjVer, LandIDPV 'Commit this propertyValue to current ObjVer
    end if
    end if
    end if
    end if

    'Check if provided itemID is selected in MultiSelectTypedValue
    function IsItemSeleted(MultiSelectTypedValue, ItemID )
    dim Result: Result = false

    if not MultiSelectTypedValue.IsNull() then
    dim Lookups: set Lookups = MultiSelectTypedValue.GetValueAsLookups()
    dim Lookup
    for each Lookup in Lookups
    if Lookup.Item = ItemID then
    Result = true
    Exit For
    end if
    next
    end if
    IsItemSeleted = Result
    end function

    'Append given itemID as selection of provided MultiSelectTypedValue. TypeID Is objectType ID of lookup
    sub AppendSelection(MultiSelectTypedValue, ItemID, TypeID )

    dim NewLookup: Set NewLookup = CreateObject("MFilesAPI.Lookup")

    NewLookup.ObjectType = TypeID
    NewLookup.Item = ItemID
    NewLookup.SetLatestVersion

    dim Lookups
    if MultiSelectTypedValue.IsNull() then
    set Lookups = CreateObject("MFilesAPI.Lookups")
    else
    set Lookups = MultiSelectTypedValue.GetValueAsLookups()
    end if

    Lookups.Add -1, NewLookup
    MultiSelectTypedValue.SetValueToMultiSelectLookup Lookups
    end sub




Children
No Data