Skip to main content
Newcomer
December 28, 2022
Solved

"Collection was modified; enumeration operation may not execute" error when executing a member list

  • December 28, 2022
  • 2 replies
  • 0 views

Hi all,

I'm receiving the error in the subject when executing a MemberList.

This is the ML code, it should retrieve base member of "TF" in the flows dimension with SwitchType attribute set to True.

Dim objMemberListHeader As New MemberListHeader(args.MemberListArgs.MemberListName)
Dim objFlowList As List(Of member) = api.Members.GetBaseMembers(api.Pov.FlowDim.DimPk,api.Members.GetMemberId(api.Pov.Flow.DimTypeID,"TF"))
Dim FlowMemberID As Integer
For Each FlowMember In objFlowList
   FlowMemberID = api.Members.GetMemberId(api.Pov.Flow.DimTypeId,flowmember.Name)
   If api.Flow.SwitchType(FlowMemberID) Then objFlowList.Add(flowmember)
 Next
Dim objMemberList As New MemberList(objMemberListHeader, objFlowList)
Return objMemberList

Any advice, really appreciated

Thanks and regards

Massimo

Best answer by ChrisLoran

There are three issues with this code example
a) You are performing an unnecessary GetMemberId inside the loop. Instead you can just refer to FlowMemberId = FlowMember.MemberID.  Try to limit the references to member names as much as possible, especially inside loops.

b) You are trying to append a member to the same list that you are iterating through. That is why the error message says the collection [that you are looping through] is being modified. You should instead add the FlowMember to a NEW (initially empty) list.
c) You are trying to append a member ID (which is a number) to a list of member objects (not list of MemberIDs). 

This modified snippet should work better (although I have not tested it for real):

Dim objMemberListHeader As New MemberListHeader(args.MemberListArgs.MemberListName)
Dim sourceFlowList As List(Of Member) = api.Members.GetBaseMembers(api.Pov.FlowDim.DimPk, api.Members.GetMemberId(api.Pov.Flow.DimTypeID,"TF"))
Dim resultFlowList As New List(Of Member)
For Each FlowMember In sourceFlowList
   If api.Flow.SwitchType(FlowMember.MemberId) Then resultFlowList.Add(FlowMember)
Next
Dim objMemberList As New MemberList(objMemberListHeader, resultFlowList)
Return objMemberList

a more compact version could be done by using Linq , like this. (for example purposes only, this is not tested for real):

Dim objMemberListHeader As New MemberListHeader(args.MemberListArgs.MemberListName)
Dim sourceFlowList As List(Of Member) = api.Members.GetBaseMembers(api.Pov.FlowDim.DimPk, api.Members.GetMemberId(api.Pov.Flow.DimTypeID,"TF"))
Dim resultFlowList As List(Of member) = sourceFlowList.Where( Function(thisFlow) (api.Flow.SwitchType(thisFlow.MemberId)) )

Dim objMemberList As New MemberList(objMemberListHeader, resultFlowList)
Return objMemberList

2 replies

OneStream Employee
December 28, 2022

There are three issues with this code example
a) You are performing an unnecessary GetMemberId inside the loop. Instead you can just refer to FlowMemberId = FlowMember.MemberID.  Try to limit the references to member names as much as possible, especially inside loops.

b) You are trying to append a member to the same list that you are iterating through. That is why the error message says the collection [that you are looping through] is being modified. You should instead add the FlowMember to a NEW (initially empty) list.
c) You are trying to append a member ID (which is a number) to a list of member objects (not list of MemberIDs). 

This modified snippet should work better (although I have not tested it for real):

Dim objMemberListHeader As New MemberListHeader(args.MemberListArgs.MemberListName)
Dim sourceFlowList As List(Of Member) = api.Members.GetBaseMembers(api.Pov.FlowDim.DimPk, api.Members.GetMemberId(api.Pov.Flow.DimTypeID,"TF"))
Dim resultFlowList As New List(Of Member)
For Each FlowMember In sourceFlowList
   If api.Flow.SwitchType(FlowMember.MemberId) Then resultFlowList.Add(FlowMember)
Next
Dim objMemberList As New MemberList(objMemberListHeader, resultFlowList)
Return objMemberList

a more compact version could be done by using Linq , like this. (for example purposes only, this is not tested for real):

Dim objMemberListHeader As New MemberListHeader(args.MemberListArgs.MemberListName)
Dim sourceFlowList As List(Of Member) = api.Members.GetBaseMembers(api.Pov.FlowDim.DimPk, api.Members.GetMemberId(api.Pov.Flow.DimTypeID,"TF"))
Dim resultFlowList As List(Of member) = sourceFlowList.Where( Function(thisFlow) (api.Flow.SwitchType(thisFlow.MemberId)) )

Dim objMemberList As New MemberList(objMemberListHeader, resultFlowList)
Return objMemberList
MStucchiAuthor
Newcomer
December 28, 2022

Thanks Chris.....I totally missed I was adding the item to the same list i am looping....

Regards

Massimo