YetAnotherForum
Welcome Guest Search | Active Topics | Log In | Register

Autorange trend using VBA Options · View
dehn0045
#1 Posted : Friday, April 08, 2011 5:33:52 PM
Rank: Newbie
Groups: Member

Joined: 4/8/2011
Posts: 2
Location: Houston, TX
I am trying to set up a basic control loop trend format that will be both easy for myself (the engineer) and the plant operators to use. I have the processbook display looking how I want, but now I am trying to set up a system that pops up a trend when you click on a valve. The trend will show the PV, SP, OP and MODE for a given control loop (most of our loops use control valves for the final control element). I have the button and trend working like I want, my programming may be a little sloppy, but it works. However, there is something that I don't like about the scaling of the y-axis. I need to use multiple scales as the mode is 0 to 5 while some flows are 7000, but I want the PV and SP to have the same scale. This will allow the operator to determine how well the loop is performing with respect to the SP. The problem is that when I autorange both PV and SP traces they end up with different scales. Also, I don't want to put in hard values for the scales as some of the flows and temperatures change significantly over a period of weeks or months, but are relatively stable for 24 hour periods. I don't want to have to go in and change the hard-coded scale every time a cloud goes over the plant.

So, here is what I tried:

Public Sub TIC7365()

If TIC7365_Trend.Visible = True Then

With TIC7365_Trend

.Visible = False
.Height = TIC7365_Button.Height
.Width = TIC7365_Button.Width
.Top = TIC7365_Button.Top
.Left = TIC7365_Button.Left

End With

Else:

TIC7365_Trend.CurrentTrace = 1
high = TIC7365_Trend.ScaleMax
low = TIC7365_Trend.ScaleMin
TIC7365_Trend.CurrentTrace = 2
TIC7365_Trend.SetTraceScale low, high


With TIC7365_Trend

.Visible = True
.Height = 1200
.Width = 2000
.Top = 14922
.Left = -13530

End With

End If

End Sub[/b][/b]


The problem is that "high" and "low" are the string "autorange", so I just end up with both traces being autoranged -- just what I don't want. I am thinking that I need to perform the "autorange" activity using VBA rather than using the "autorange" property of the trend. Any ideas?

Thanks!
Sponsor  
 

OSIsoft vCampus is a subscription-based, online offering that consists of providing everything people need to develop applications on the PI System.
We invite you to take a "tour" of the OSIsoft Virtual Campus - also feel free to consult the FAQ  or contact OSIsoft vCampus for more details.
jhcoxx
#2 Posted : Saturday, April 09, 2011 4:54:13 PM
Rank: Member
Groups: Member

Joined: 7/5/2010
Posts: 27
Location: Texas
Sounds like what you will need to do is to:

1. In VBA get the start and end time of the trend

2. In VBA, identify which tag (or tags) you want to use to set the scale for the PV and SP traces (you might be able to do this by loopin through the trend's tags, looking at the tag name extension if your plant/site/company has standard suffixes for these - such as .PV or .SP)

3. Use ejyoungone's PISDK snippet from the Max Value Per Hour thread below to get the max and min during the time span of the trend (might need some tweaking - I've not checked it out). If you can't make some standard assumption such as "the .PV and .SP will never be more than 100 apart" then you will have to get the max and min for both the SP and PV, then take the larger of the maxes and the smaller of the mins.

4. Set the appropriate trace scales with the high and low values

If you do all this a bit abstractly - putting all this code in a subroutine in a code module, and passing the either the trend as an object or its name - then you could come up with a single sub that would only need to be called from your existing button code. That would also be useful if you wanted to have more than one trend visible at a time (perhaps useful if you have cascade controllers...)

Hope this helps - let us know what you eventually decide to do!

jhcoxx
dehn0045
#3 Posted : Wednesday, April 13, 2011 5:40:18 PM
Rank: Newbie
Groups: Member

Joined: 4/8/2011
Posts: 2
Location: Houston, TX
With the help of this forum and other examples from OSI I was able to get the autorange to work just how I wanted. My programming is a probably messy, but it seems to work. Here goes:

The first section of code is used to maximize the application window and display window. Also, the setviewport method sets the viewport based on the width. If the specified height does not match the necessary height based on the screen resolution, the height is adjusted so the symbols are not skewed. I wanted to set the height of the viewport as I built my display from left-to-right and I wanted to maximize the size of the symbols. All of this wouldn't be necessary if the display was only used on monitors with the same resolution setting, but I do not have that luxury. (one other comment, I noticed that when you try to execute the Application.Maximize and ThisDisplay.Maximize from the Display_Open sub it glitches up and the application window shows to be maximized, but isn't maximized. BUT, if you do this action in a different sub and Call it using Display_Open it works great... I'm not really sure, maybe one of the programming guru's could shed some light...)

Private Sub Display_Open()

Call MaximizeDisplay


End Sub
Sub MaximizeDisplay()
Application.Maximize
ThisDisplay.Maximize

ThisDisplay.SetViewPort 14999, -15000, 1940, 4144

h1 = 1940
h2 = ThisDisplay.ViewHeight
If h2 = 1940 Then
Exit Sub
Else
For i = 1 To 1000
'h1 = ThisDisplay.ViewHeight
ThisDisplay.SetViewPort 14999, -15000, 1940, 4144 - Change
h2 = ThisDisplay.ViewHeight
Change = h2 - 1940 / 2
Next i
End If

End Sub


All of our controllers are set up with a similar naming system. TAGNAME.PV, TAGNAME.SP, etc. So I built buttons that matched the tagname for the controller that I wanted to trend. This gave me the ability to build a single trend and then just insert the traces for the controller. I made use of Rhys' GetSummary function that I found in the forum (couldn't have done it without this - THANKS!). Using the function, I get the min and max scale for the PV and SP and I set up the trend named "Controller_Trend" with trace 3 and 4 (.OP and .MODE) as autorange on both min and max. I also did a simple automation of the location of the trend in the viewport, this way when the trend is opened it is visible in the active viewport. Like I said, messy, but functional. Thanks to all who have posted thier ideas and solutions on this board, it was critical to this success (at least I call it a success..).

Public Sub AutoTrend()

Dim Trend As Object
Dim Button As Object
Dim PVtagname As String
Dim SPtagname As String
Dim OPtagname As String
Dim MODEtagname As String
Dim Max As Variant
Dim Min As Variant
Dim SearchChar As String
Dim MyPos As Integer
Dim Name As String

Set TheButton = SelectedSymbols.Item(ThisDisplay.SelectedSymbols.Count)
ButtonName = TheButton.Name

SearchChar = "_"

MyPos = InStr(1, ButtonName, SearchChar, vbTextCompare)
ParseName = Left$(ButtonName, MyPos - 1)
PVtagname = ParseName & ".PV"
SPtagname = ParseName & ".SP"
OPtagname = ParseName & ".OP"
MODEtagname = ParseName & ".MODE"
TrendName = "Controller_Trend"

Set Trend = Symbols.Item(TrendName)
Set Button = Symbols.Item(ButtonName)

If Trend.Visible = True Then

With Trend

.Visible = False
.Height = Button.Height
.Width = Button.Width
.Top = 13135
.Left = -14966

End With

Else:

Call MaxMinCalc(Min, Max, PVtagname, SPtagname)

Trend.SetTagName 1, PVtagname
Trend.SetTagName 2, SPtagname
Trend.SetTagName 3, OPtagname
Trend.SetTagName 4, MODEtagname
Trend.CurrentTrace = 1
Trend.SetTraceScale Min, Max
Trend.CurrentTrace = 2
Trend.SetTraceScale Min, Max

Call PositionTrend(Trend, Button)

Trend.SetTimeRange "*-1day", "*"

End If
End Sub


Sub MaxMinCalc(Min As Variant, Max As Variant, PVtagname As String, SPtagname As String)

Max1 = GetSummary(PISDK.Servers("appg-PIHOUT").PIPoints(PVtagname), "*-24h", "*", astMaximum)
Max2 = GetSummary(PISDK.Servers("appg-PIHOUT").PIPoints(SPtagname), "*-24h", "*", astMaximum)
If Max1 > Max2 Then
Max = Max1
Else: Max = Max2
End If

Min1 = GetSummary(PISDK.Servers("appg-PIHOUT").PIPoints(PVtagname), "*-24h", "*", astMinimum)
Min2 = GetSummary(PISDK.Servers("appg-PIHOUT").PIPoints(SPtagname), "*-24h", "*", astMinimum)
If Min1 < Min2 Then
Min = Min1
Else: Min = Min2
End If
End Sub
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.