Skip to main content
Member
Oct 15, 2026 12:33 PM UTC
Solved

Display V#VarianceExplanation in a grid report or visualization

Hello, 

we have a few U8 members - vs Budget, vs PY etc. and are paired with V#VarianceExplanation member in our cube views for the users to enter commentary. We now have a requirement to present all that commentary in a grid view or some sort of report output rather than just the cube view. 

Is it even possible to bring in members like VarianceExplanation, Annotation etc. into OneStream’s reporting? I tried building a simple BIViewer grid with no luck, so any inputs are highly appreciated. 

Thanks!

SBeaverAnswer
Member
Oct 15, 2026 2:18 PM UTC

Hi ​@NagavalliV, 

If you are looking to target a specific POV in your grid view, I would try building a cube view that exposes these annotations and hook it to a data adapter.  The command type “Cube View” has options to expose any of the annotations associated with values you expose within the cube view. 

 

I find the table schema that the “Cube View” method command returns quite hard to tidy up into something presentable however. 

 

If you are comfortable with dashboard data set business rules you could directly retrieve all commentary entered in bulk using the method “BRApi.Finance.Data.GetDataAttachments”.  

I wrote the script below to hopefully get you started. It pulls all commentary entered for a specific scenario, time and annotation view.  

Note that the retrieval of the data cell amount per item is not going to be very efficient for large data sets.  

Dim amountViewName As String = 
args.NameValuePairs.XFGetValue("View", "YTD") ' Used to retrieve the data cell amount
Dim commentaryViewName As String =
args.NameValuePairs.XFGetValue("CommentaryView", "VarianceExplanation") ' Used to retreive the commentary
Dim scenarioName As String =
args.NameValuePairs.XFGetValue("Scenario", "Actual")
Dim timeName As String =
args.NameValuePairs.XFGetValue("Time", "2027M1")

Dim commentaryViewId As Integer = BRApi.Finance.Members.GetMemberId(si, DimTypeId.View, commentaryViewName)
Dim attachmentType As DataAttachmentType =
DataAttachmentTypeHelper.GetDataAttachmentTypeForViewMember(commentaryViewId)

' Build this member filter from member names passed as arguments
' for a more dynamic retrieval.
Dim memberFilter As String = $"S#[{scenarioName}]:V#[{commentaryViewName}]:T#[{timeName}]"

Dim dataAttachments As DataAttachmentList =
BRApi.Finance.Data.GetDataAttachments(
si,
memberFilter,
False
)

Dim resultDt As New DataTable()

With resultDt.Columns
.Add("Cube", GetType(String))
.Add("Scenario", GetType(String))
.Add("Entity", GetType(String))
.Add("Parent", GetType(String))
.Add("Time", GetType(String))
.Add("Cons", GetType(String))
.Add("Account", GetType(String))
.Add("Origin", GetType(String))
.Add("View", GetType(String))
.Add("Flow", GetType(String))
.Add("IC", GetType(String))
.Add("UD1", GetType(String))
.Add("UD2", GetType(String))
.Add("UD3", GetType(String))
.Add("UD4", GetType(String))
.Add("UD5", GetType(String))
.Add("UD6", GetType(String))
.Add("UD7", GetType(String))
.Add("UD8", GetType(String))
.Add("CommentaryView", GetType(String))
.Add("CreatedTimestamp", GetType(Date))
.Add("LastEditedTimestamp", GetType(String))
.Add("LastEditedUserName", GetType(String))
.Add("Title", GetType(String))
.Add("Text", GetType(String))
.Add("Amount", GetType(Decimal))
End With

For Each attachment As DataAttachment In dataAttachments.Items
' This attachment type filter may not be required due to the flow in the member script, but added it just in case.
If attachment.AttachmentType <> attachmentType Then Continue For

Dim amountMemberScriptBuilder As New MemberScriptBuilder(
attachment.Cube,
attachment.Entity,
attachment.Parent,
attachment.Cons,
attachment.Scenario,
attachment.Time,
amountViewName,
attachment.Account,
attachment.Flow,
attachment.Origin,
attachment.IC,
attachment.UD1,
attachment.UD2,
attachment.UD3,
attachment.UD4,
attachment.UD5,
attachment.UD6,
attachment.UD7,
attachment.UD8
)
Dim amount As Decimal =
BRApi.Finance.Data.GetDataCellUsingMemberScript(
si,
attachment.Cube,
amountMemberScriptBuilder.GetMemberScript()
).DataCellEx.DataCell.CellAmount

Dim dr As DataRow = resultDt.NewRow()

dr("Cube") = attachment.Cube
dr("Scenario") = attachment.Scenario
dr("Entity") = attachment.Entity
dr("Parent") = attachment.Parent
dr("Time") = attachment.Time
dr("Cons") = attachment.Cons
dr("Account") = attachment.Account
dr("Origin") = attachment.Origin
dr("View") = amountViewName
dr("Flow") = attachment.Flow
dr("IC") = attachment.IC
dr("UD1") = attachment.UD1
dr("UD2") = attachment.UD2
dr("UD3") = attachment.UD3
dr("UD4") = attachment.UD4
dr("UD5") = attachment.UD5
dr("UD6") = attachment.UD6
dr("UD7") = attachment.UD7
dr("UD8") = attachment.UD8
dr("CommentaryView") = commentaryViewName
dr("CreatedTimestamp") = attachment.CreatedTimestamp
dr("LastEditedTimestamp") = attachment.LastEditedTimestamp
dr("LastEditedUserName") = attachment.LastEditedUserName
dr("Title") = attachment.Title
dr("Text") = attachment.Text
dr("Amount") = amount

resultDt.Rows.Add(dr)

Thanks,

Stuart

 

4 replies

SBeaverAnswer
Member
Oct 15, 2026 2:18 PM UTC

Hi ​@NagavalliV, 

If you are looking to target a specific POV in your grid view, I would try building a cube view that exposes these annotations and hook it to a data adapter.  The command type “Cube View” has options to expose any of the annotations associated with values you expose within the cube view. 

 

I find the table schema that the “Cube View” method command returns quite hard to tidy up into something presentable however. 

 

If you are comfortable with dashboard data set business rules you could directly retrieve all commentary entered in bulk using the method “BRApi.Finance.Data.GetDataAttachments”.  

I wrote the script below to hopefully get you started. It pulls all commentary entered for a specific scenario, time and annotation view.  

Note that the retrieval of the data cell amount per item is not going to be very efficient for large data sets.  

Dim amountViewName As String = 
args.NameValuePairs.XFGetValue("View", "YTD") ' Used to retrieve the data cell amount
Dim commentaryViewName As String =
args.NameValuePairs.XFGetValue("CommentaryView", "VarianceExplanation") ' Used to retreive the commentary
Dim scenarioName As String =
args.NameValuePairs.XFGetValue("Scenario", "Actual")
Dim timeName As String =
args.NameValuePairs.XFGetValue("Time", "2027M1")

Dim commentaryViewId As Integer = BRApi.Finance.Members.GetMemberId(si, DimTypeId.View, commentaryViewName)
Dim attachmentType As DataAttachmentType =
DataAttachmentTypeHelper.GetDataAttachmentTypeForViewMember(commentaryViewId)

' Build this member filter from member names passed as arguments
' for a more dynamic retrieval.
Dim memberFilter As String = $"S#[{scenarioName}]:V#[{commentaryViewName}]:T#[{timeName}]"

Dim dataAttachments As DataAttachmentList =
BRApi.Finance.Data.GetDataAttachments(
si,
memberFilter,
False
)

Dim resultDt As New DataTable()

With resultDt.Columns
.Add("Cube", GetType(String))
.Add("Scenario", GetType(String))
.Add("Entity", GetType(String))
.Add("Parent", GetType(String))
.Add("Time", GetType(String))
.Add("Cons", GetType(String))
.Add("Account", GetType(String))
.Add("Origin", GetType(String))
.Add("View", GetType(String))
.Add("Flow", GetType(String))
.Add("IC", GetType(String))
.Add("UD1", GetType(String))
.Add("UD2", GetType(String))
.Add("UD3", GetType(String))
.Add("UD4", GetType(String))
.Add("UD5", GetType(String))
.Add("UD6", GetType(String))
.Add("UD7", GetType(String))
.Add("UD8", GetType(String))
.Add("CommentaryView", GetType(String))
.Add("CreatedTimestamp", GetType(Date))
.Add("LastEditedTimestamp", GetType(String))
.Add("LastEditedUserName", GetType(String))
.Add("Title", GetType(String))
.Add("Text", GetType(String))
.Add("Amount", GetType(Decimal))
End With

For Each attachment As DataAttachment In dataAttachments.Items
' This attachment type filter may not be required due to the flow in the member script, but added it just in case.
If attachment.AttachmentType <> attachmentType Then Continue For

Dim amountMemberScriptBuilder As New MemberScriptBuilder(
attachment.Cube,
attachment.Entity,
attachment.Parent,
attachment.Cons,
attachment.Scenario,
attachment.Time,
amountViewName,
attachment.Account,
attachment.Flow,
attachment.Origin,
attachment.IC,
attachment.UD1,
attachment.UD2,
attachment.UD3,
attachment.UD4,
attachment.UD5,
attachment.UD6,
attachment.UD7,
attachment.UD8
)
Dim amount As Decimal =
BRApi.Finance.Data.GetDataCellUsingMemberScript(
si,
attachment.Cube,
amountMemberScriptBuilder.GetMemberScript()
).DataCellEx.DataCell.CellAmount

Dim dr As DataRow = resultDt.NewRow()

dr("Cube") = attachment.Cube
dr("Scenario") = attachment.Scenario
dr("Entity") = attachment.Entity
dr("Parent") = attachment.Parent
dr("Time") = attachment.Time
dr("Cons") = attachment.Cons
dr("Account") = attachment.Account
dr("Origin") = attachment.Origin
dr("View") = amountViewName
dr("Flow") = attachment.Flow
dr("IC") = attachment.IC
dr("UD1") = attachment.UD1
dr("UD2") = attachment.UD2
dr("UD3") = attachment.UD3
dr("UD4") = attachment.UD4
dr("UD5") = attachment.UD5
dr("UD6") = attachment.UD6
dr("UD7") = attachment.UD7
dr("UD8") = attachment.UD8
dr("CommentaryView") = commentaryViewName
dr("CreatedTimestamp") = attachment.CreatedTimestamp
dr("LastEditedTimestamp") = attachment.LastEditedTimestamp
dr("LastEditedUserName") = attachment.LastEditedUserName
dr("Title") = attachment.Title
dr("Text") = attachment.Text
dr("Amount") = amount

resultDt.Rows.Add(dr)

Thanks,

Stuart

 

Member
Oct 15, 2026 2:29 PM UTC

this is very helpful, thank you Stuart! Let me start with building a data adapter and see how that goes. I will update you shortly.

Member
Oct 20, 2026 1:39 PM UTC

Stuart - Creating a simple data adapter with Cube View command type worked like a charm for what we are looking. I’ll still hold on to the Business rule recommendation for potential future use cases. Thank you again!

Member
Oct 20, 2026 1:46 PM UTC

That is great news, glad you got to a solution!