My first thought is if you used the member filter in the formula you could call all base accounts under IncomeStatement. As an example -
api.Data.Calculate(formula, accountFilter, flowFilter, originFilter, icFilter, ud1Filter, ud2Filter, ud3Filter, ud4Filter, ud5Filter, ud6Filter, ud7Filter, ud8Filter, onEvalDataBuffer, userState, isDurableCalculatedData)
My second thought is using a data buffer, you would only have base accounts to loop through. Another benefit of a data buffer is that it will only run on members that have values - this will limit how often it runs and will yield better performance.
Dim myDataBuffer As DataBuffer = api.Data.GetDataBufferUsingFormula("A#60000 - A#41000") '<-- Update with your data buffer information
api.Data.FormulaVariables.SetDataBufferVariable("myDataBuffer", myDataBuffer, False)
'Loop over data buffer and get member names
For Each sourceCell As DataBufferCell In myDataBuffer.DataBufferCells.Values
'Can now access member information for the current cell in the data buffer
Dim accountName As String = sourceCell.DataBufferCellPk.GetAccountName(api)
Dim ud1Name As String = sourceCell.DataBufferCellPk.GetUD1Name(api)
Dim ud2Name As String = sourceCell.DataBufferCellPk.GetUD2Name(api)
Next
Typically if you have to loop its over POV members like Entity - And here is an example of that.
'Loop through Base members and do something
Dim baseMembers As List(Of Member) = api.Members.GetBaseMembers(entityDimPk, entityId, Nothing)
If Not baseMembers Is Nothing Then
For Each objMember As Member In baseMembers
'Do something
Next
End If
Also you can simply look at the POV and see if an entity is a base entity by using - Not api.Entity.HasChildren()
As you can see there are lots of options, but what is best might be determined by the calc you need.