DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

ChnFlagSet() command not working

Solved!
Go to solution

I was looking into answering the forum question 'How to work with flags in scripts' and discovered that the ChnFlagSet() command does not work properly (or I'm not using it correctly).  Please run the script below to see a demonstration of the problem.  

 

'-------------------------------------------------------------------------------
'-- VBS script file View_set_flags.VBS
'-- Author: Mechatronic Solutions LLC
' Mark W Kiehl
' www.SavvyDiademSolutions.com
'
' Programmatically setting flags in the View panel
'
'-------------------------------------------------------------------------------
Option Explicit
Call LogFileDel()

'Create data in the Data Portal..
Dim oChnTime, oChn, iRow, sGrp, oElementList, oGrp, iRows
sGrp ="SIN1"
Call Data.Root.Clear()
Call bCreateSineWave("SIN1")
Call Portal.Refresh()
'Plot the data in the View panel..
Set oGrp = Data.Root.ChannelGroups(sGrp)
Set oElementList = Data.CreateElementList()
Call oElementList.Add(oGrp.Channels("Time"))
Call oElementList.Add(oGrp.Channels("CycSin"))
Const sYScaling = "n systems [phys.]" 'independent plots; sYScaling = "1 system [phys.]" 'overlap plots
Call b2dPlotToViewByElementList(oElementList, sYScaling)
'Clear any flags, set the Band Cursor, and show the View panel
Call ChnFlagDelAll()
Set oChnTime = oGrp.Channels("Time")
Set oChn = oGrp.Channels("CycSin")
View.ActiveSheet.Cursor.X1 = 4.76
View.ActiveSheet.Cursor.X2 = 11.07
View.ActiveSheet.Cursor.P1 = iRowForChnTimeVal(oChnTime,View.ActiveSheet.Cursor.X1)
View.ActiveSheet.Cursor.P2 = iRowForChnTimeVal(oChnTime,View.ActiveSheet.Cursor.X2)
Call LogFileWrite("X1 to X2 = " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol)
Call LogFileWrite("P1 to P2 = " & View.ActiveSheet.Cursor.P1 & " to " & View.ActiveSheet.Cursor.P2)
View.ActiveSheet.Cursor.Type = "Band"
Call View.Refresh()
Call WndShow("VIEW")
Call MsgBox("Channel data created and Band Cursor set." & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

'Set flags using ChnFlagSet()
iRow = View.ActiveSheet.Cursor.P1
iRows = View.ActiveSheet.Cursor.P2 - View.ActiveSheet.Cursor.P1 + 1
Call LogFileWrite("Setting flags from " & iRow & " for " & Str(iRows) & " rows (.Size = " & oChnTime.Size & ")")
Call ChnFlagSet(oChnTime, iRow, iRows, True)
Call ChnFlagSet(oChnTime.GetReference(eRefTypeNameName), iRow, iRows, True)
Call WndShow("VIEW")
Call View.Refresh()
Call MsgBox("ChnFlagSet() called, but no flags set." & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

'Set flags using propety oChn.OperationalFlags(iRow) = True
For iRow = View.ActiveSheet.Cursor.P1 To View.ActiveSheet.Cursor.P2
oChn.OperationalFlags(iRow) = True
Next
Call WndShow("VIEW")
Call View.Refresh()
Call MsgBox("Property .OperationalFlags() = True used to successfully set flags." & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

'-------------------------------------------------------------------------------
' Helper functions

Function iRowForChnTimeVal(ByVal oChnTime, ByVal dChnVal)
'Returns the row for the closest value in oChnTime.
'Returns <= 0 if the row was not found.
'Expects oChnTime to be a numeric channel
iRowForChnTimeVal = 0
If oChnTime.DataType <> DataTypeChnFloat64 Then Exit Function
Dim sFormula
sFormula = "Ch(""" & oChnTime.GetReference(eRefTypeIndexIndex) & """)>=" & Str(dChnVal)
iRowForChnTimeVal = ChnFind(sFormula,1)
End Function 'iRowForChnTimeVal()

Function bCreateSineWave(ByVal sGrp)
Dim oChn, oGrp
Dim sFormula, arrSymbols, arrValues, dValStart, dValEnd
If Data.Root.ChannelGroups.Exists(sGrp) Then Call Data.Root.ChannelGroups.Remove(sGrp)
Set oGrp = Data.Root.ChannelGroups.Add(sGrp)
'Create the time channel
Set oChn = oGrp.Channels.Add("Time",DataTypeChnFloat64)
dValStart = 0.0
dValEnd = 50
Call ChnLinGen(oChn,dValStart,dValEnd,1000,"s")
Set oChn = oGrp.Channels.Add("CycSin",DataTypeChnFloat64)
ReDim arrSymbols(1): ReDim arrValues(1)
sFormula = "CycSin = Sin(Time)"
arrSymbols(0) = "Time"
arrSymbols(1) = "CycSin"
Set arrValues(0) = oGrp.Channels("Time")
Set arrValues(1) = oGrp.Channels("CycSin")
Call Calculate(sFormula, arrSymbols, arrValues)
Set oGrp = Nothing: Set oChn = Nothing
End Function 'bCreateSineWave()

'-------------------------------------------------------------------------------
' Plot two channels in View panel

Function b2dPlotToViewByElementList(ByVal oElementList, ByVal sYScaling)
'Creates a 2D plot in View of the data channels in oElementList.
'oElementList must contain at least 2 channels, and one of them
'must be a Time, DateTime, or DataType = DataTypeChnDate.
'Returns TRUE if successful.
b2dPlotToViewByElementList = False
If Not IsObject(oElementList) Then Exit Function
If oElementList.Count = 0 Then Exit Function
Dim oElement, oChnX, iChns
'Find the x-axis channel within oElementList
For Each oElement in oElementList
If oElement.IsKindOf(eDataChannel) Then
iChns = iChns + 1
If (Not IsObject(oChnX)) AND (oElement.Name = "Time" or oElement.Name = "DateTime" or oElement.DataType = DataTypeChnDate ) Then
Set oChnX = oElement
End If 'oElement.Name
End If 'oElement.IsKindOf()
Next 'oElement
If Not IsObject(oChnX) Then
Call LogFileWrite("ERROR - time / datetime channel not found in oElementList. Fn b2dPlotToViewByElementList()")
Exit Function
End If
If iChns < 2 Then
Call LogFileWrite("ERROR - insufficient channels passed in oElementList to Fn b2dPlotToViewByElementList()")
Exit Function
End If
'Delete any sheets that exist
Call View.Sheets.RemoveAll()
Call View.NewLayout()
'Add a single area with a 2D curve
Dim oArea, oChnDateTime, oChn
Set oArea = View.ActiveSheet.ActiveArea
oArea.DisplayObjType = "CurveChart2D"
'Add channels to the curve
For Each oElement in oElementList
If oElement.IsKindOf(eDataChannel) Then
If Not oElement.Name = oChnX.Name Then
Call oArea.DisplayObj.Curves.Add(oChnX.GetReference(eRefTypeIndexIndex),oElement.GetReference(eRefTypeIndexIndex))
End If
End If 'oElement.IsKindOf()
Next 'oElement
'"n systems [phys.]"
oArea.DisplayObj.YScaling = sYScaling
View.ActiveSheet.ActiveArea.DisplayObj.XScalingMode = "RangeFull"
View.Refresh()
Set oChnX = Nothing: Set oChn = Nothing: Set oArea = Nothing
b2dPlotToViewByElementList = True
End Function 'b2dPlotToViewByElementList()

 

0 Kudos
Message 1 of 3
(2,275 Views)

Hi markwkiehl,

 

Thanks for providing the useful replication code. I pulled it up on my end and noticed we need to reference the Y Axis values rather than the X Axis. In this example, this means changing the following code section:

 

'Set flags using ChnFlagSet()
iRow = View.ActiveSheet.Cursor.P1
iRows = View.ActiveSheet.Cursor.P2 - View.ActiveSheet.Cursor.P1 + 1
Call LogFileWrite("Setting flags from " & iRow & " for " & Str(iRows) & " rows (.Size = " & oChnTime.Size & ")")
Call ChnFlagSet(oChn, iRow, iRows, True)
Call ChnFlagSet(oChn.GetReference(eRefTypeNameName), iRow, iRows, True)
Call WndShow("VIEW")
Call View.Refresh()
Call MsgBox("ChnFlagSet() called, but no flags set." & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

 

Give this a go, it should work for you 🙂

0 Kudos
Message 2 of 3
(2,233 Views)
Solution
Accepted by topic author markwkiehl

The suggested changes work perfectly.  ChnFlagSet() works properly when the correct parameters are passed to it.  A full demo is shown below.

 

'-------------------------------------------------------------------------------
'-- VBS script file View_set_flags.VBS
'-- Author: Mechatronic Solutions LLC
' Mark W Kiehl
' www.SavvyDiademSolutions.com
'
' Programmatically setting flags in the View panel
'
' Related links:
' http://zone.ni.com/reference/en-XX/help/370858P-01/comoff/chnflagset/
' http://zone.ni.com/reference/en-XX/help/370858P-01/genview/genview/view_flags/
'-------------------------------------------------------------------------------
Option Explicit
Call LogFileDel()

'Enable/disable display of MsgBox()
Const bShowMsgBox = False

'Create data in the Data Portal..
Dim oChnTime, oChn, iRow, sGrp, oElementList, oGrp, iRows, bFlagFound
sGrp ="SIN1"
Call Data.Root.Clear()
Call bCreateSineWave("SIN1")
Call Portal.Refresh()
'Plot the data in the View panel..
Set oGrp = Data.Root.ChannelGroups(sGrp)
Set oElementList = Data.CreateElementList()
Call oElementList.Add(oGrp.Channels("Time"))
Call oElementList.Add(oGrp.Channels("CycSin"))
Const sYScaling = "n systems [phys.]" 'overlap plots; independent plots; sYScaling = "1 system [phys.]"
Call b2dPlotToViewByElementList(oElementList, sYScaling)
'Clear any flags, set the Band Cursor, and show the View panel
Call ChnFlagDelAll()
Set oChnTime = oGrp.Channels("Time")
Set oChn = oGrp.Channels("CycSin")
View.ActiveSheet.Cursor.X1 = 4.76
View.ActiveSheet.Cursor.X2 = 11.07
View.ActiveSheet.Cursor.P1 = iRowForChnTimeVal(oChnTime,View.ActiveSheet.Cursor.X1)
View.ActiveSheet.Cursor.P2 = iRowForChnTimeVal(oChnTime,View.ActiveSheet.Cursor.X2)
Call LogFileWrite("X1 to X2 = " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol)
Call LogFileWrite("P1 to P2 = " & View.ActiveSheet.Cursor.P1 & " to " & View.ActiveSheet.Cursor.P2)
Call LogFileWrite(vbTab)
View.ActiveSheet.Cursor.Type = "Band"
Call View.Refresh()
Call WndShow("VIEW")
If bShowMsgBox Then Call MsgBox("Channel data created and Band Cursor set to " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

'Set flags using ChnFlagSet()
'WARNING: Make sure to pass oChn (Y), not oChnTime (X).
iRow = View.ActiveSheet.Cursor.P1
iRows = View.ActiveSheet.Cursor.P2 - View.ActiveSheet.Cursor.P1 + 1
Call LogFileWrite("Setting flags from " & iRow & " for " & Str(iRows) & " rows (.Size = " & oChnTime.Size & ")")
Call ChnFlagSet(oChn, iRow, iRows, True)
Call ChnFlagSet(oChn.GetReference(eRefTypeNameName), iRow, iRows, True)
Call WndShow("VIEW")
Call View.Refresh()
If bShowMsgBox Then Call MsgBox("Flags set from " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

''Set flags using property OperationalFlags()
''Set flags from t=4.76 to 11.07 sec using propety oChn.OperationalFlags(iRow) = True
'For iRow = View.ActiveSheet.Cursor.P1 To View.ActiveSheet.Cursor.P2
' oChn.OperationalFlags(iRow) = True
'Next
'Call View.Refresh()
'If bShowMsgBox Then Call MsgBox("Flags set from " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

'Set flags from t=15.8 to 22.1 sec using propety oChn.OperationalFlags(iRow) = True
View.ActiveSheet.Cursor.X1 = 15.8
View.ActiveSheet.Cursor.X2 = 22.1
View.ActiveSheet.Cursor.P1 = iRowForChnTimeVal(oChnTime,View.ActiveSheet.Cursor.X1)
View.ActiveSheet.Cursor.P2 = iRowForChnTimeVal(oChnTime,View.ActiveSheet.Cursor.X2)
Call LogFileWrite("X1 to X2 = " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol)
Call LogFileWrite("P1 to P2 = " & View.ActiveSheet.Cursor.P1 & " to " & View.ActiveSheet.Cursor.P2)
Call LogFileWrite(vbTab)
Call View.Refresh()
'Call MsgBox("Band Cursor set to " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)
For iRow = View.ActiveSheet.Cursor.P1 To View.ActiveSheet.Cursor.P2
oChn.OperationalFlags(iRow) = True
Next
Call View.Refresh()
If bShowMsgBox Then Call MsgBox("Flags set from " & Str(View.ActiveSheet.Cursor.X1,"d.d") & " to " & Str(View.ActiveSheet.Cursor.X2,"d.d") & " " & oChnTime.UnitSymbol & vbCrLf & "Click 'OK to continue",vbOkOnly,CurrentScriptName)

'You can now programmatically access the flags and determine the rows where they start/end..
Call WndShow("SCRIPT")
bFlagFound = False
For iRow = 1 To oChnTime.Size
If oChn.OperationalFlags(iRow) = True AND bFlagFound = False Then
Call LogFileWrite("Flag start found at row " & iRow & " time = " & Str(oChnTime.Values(iRow),"d.d") & " " & oChnTime.UnitSymbol)
bFlagFound = True
ElseIf oChn.OperationalFlags(iRow) = False AND bFlagFound = True Then
Call LogFileWrite("Flag end found at row " & iRow & " time = " & Str(oChnTime.Values(iRow),"d.d") & " " & oChnTime.UnitSymbol)
bFlagFound = False
End If
Next

'-------------------------------------------------------------------------------
' Helper functions

Function iRowForChnTimeVal(ByVal oChnTime, ByVal dChnVal)
'Returns the row for the closest value in oChnTime.
'Returns <= 0 if the row was not found.
'Expects oChnTime to be a numeric channel
iRowForChnTimeVal = 0
If oChnTime.DataType <> DataTypeChnFloat64 Then Exit Function
Dim sFormula
sFormula = "Ch(""" & oChnTime.GetReference(eRefTypeIndexIndex) & """)>=" & Str(dChnVal)
iRowForChnTimeVal = ChnFind(sFormula,1)
End Function 'iRowForChnTimeVal()

Function bCreateSineWave(ByVal sGrp)
Dim oChn, oGrp
Dim sFormula, arrSymbols, arrValues, dValStart, dValEnd
If Data.Root.ChannelGroups.Exists(sGrp) Then Call Data.Root.ChannelGroups.Remove(sGrp)
Set oGrp = Data.Root.ChannelGroups.Add(sGrp)
'Create the time channel
Set oChn = oGrp.Channels.Add("Time",DataTypeChnFloat64)
dValStart = 0.0
dValEnd = 50
Call ChnLinGen(oChn,dValStart,dValEnd,1000,"s")
Set oChn = oGrp.Channels.Add("CycSin",DataTypeChnFloat64)
ReDim arrSymbols(1): ReDim arrValues(1)
sFormula = "CycSin = Sin(Time)"
arrSymbols(0) = "Time"
arrSymbols(1) = "CycSin"
Set arrValues(0) = oGrp.Channels("Time")
Set arrValues(1) = oGrp.Channels("CycSin")
Call Calculate(sFormula, arrSymbols, arrValues)
Set oGrp = Nothing: Set oChn = Nothing
End Function 'bCreateSineWave()

'-------------------------------------------------------------------------------
' Plot two channels in View panel

Function b2dPlotToViewByElementList(ByVal oElementList, ByVal sYScaling)
'Creates a 2D plot in View of the data channels in oElementList.
'oElementList must contain at least 2 channels, and one of them
'must be a Time, DateTime, or DataType = DataTypeChnDate.
'Returns TRUE if successful.
b2dPlotToViewByElementList = False
If Not IsObject(oElementList) Then Exit Function
If oElementList.Count = 0 Then Exit Function
Dim oElement, oChnX, iChns
'Find the x-axis channel within oElementList
For Each oElement in oElementList
If oElement.IsKindOf(eDataChannel) Then
iChns = iChns + 1
If (Not IsObject(oChnX)) AND (oElement.Name = "Time" or oElement.Name = "DateTime" or oElement.DataType = DataTypeChnDate ) Then
Set oChnX = oElement
End If 'oElement.Name
End If 'oElement.IsKindOf()
Next 'oElement
If Not IsObject(oChnX) Then
Call LogFileWrite("ERROR - time / datetime channel not found in oElementList. Fn b2dPlotToViewByElementList()")
Exit Function
End If
If iChns < 2 Then
Call LogFileWrite("ERROR - insufficient channels passed in oElementList to Fn b2dPlotToViewByElementList()")
Exit Function
End If
'Delete any sheets that exist
Call View.Sheets.RemoveAll()
Call View.NewLayout()
'Add a single area with a 2D curve
Dim oArea, oChnDateTime, oChn
Set oArea = View.ActiveSheet.ActiveArea
oArea.DisplayObjType = "CurveChart2D"
'Add channels to the curve
For Each oElement in oElementList
If oElement.IsKindOf(eDataChannel) Then
If Not oElement.Name = oChnX.Name Then
Call oArea.DisplayObj.Curves.Add(oChnX.GetReference(eRefTypeIndexIndex),oElement.GetReference(eRefTypeIndexIndex))
End If
End If 'oElement.IsKindOf()
Next 'oElement
'"n systems [phys.]"
oArea.DisplayObj.YScaling = sYScaling
View.ActiveSheet.ActiveArea.DisplayObj.XScalingMode = "RangeFull"
View.Refresh()
Set oChnX = Nothing: Set oChn = Nothing: Set oArea = Nothing
b2dPlotToViewByElementList = True
End Function 'b2dPlotToViewByElementList()

0 Kudos
Message 3 of 3
(2,228 Views)