You are not registered yet. Please click here to register!


 
 
plc storereviewsdownloads
This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc.
 
Try our online PLC Simulator- FREE.  Click here now to try it.

New Here? Please read this important info!!!


Go Back   PLCS.net - Interactive Q & A > PLCS.net - Interactive Q & A > LIVE PLC Questions And Answers

Reply
 
Thread Tools Display Modes
Old May 4th, 2021, 02:17 PM   #1
Revnus
Member
Brazil

Revnus is offline
 
Join Date: Aug 2019
Location: Brazil
Posts: 25
FTViewSE - Need help at VBA - Display command

I'm begginer at VBA. What should be the correct way to check if a display is currently showing and then show another display?

I tried to put this code on two main displays "display1" and "display2":

Private Sub Display_AnimationStart()
ShowDisplay ("bannerA")
End Sub

Private Sub Display_AfterAnimationStop()
ShowDisplay ("bannerB")
End Sub

This works when start, display1 or display2, or when I change from them to another display (to display99 for example).

But when I change from display 1 to display 2 , it shows "bannerB" replacing "bannerA", when it should keep "bannerA" in this case.

It seems that sub Display_AfterAnimationStop of the closing display executes after Display_AnimationStart of the opening display(which is strange).

I tried BeforeAnimationStop and same thing happens.

I don't want to use "pause", because banner B would show quickly before displaying banner A. What I want is:

- When I change between display1 and display2, it keeps banner A.
- When I change from display1 or display2 to any other main display, it changes from bannerA to bannerB.
- When I change from any other main display to display1 or display2, it changes from bannerB to bannerA.
- Use the working VBA command only on display1 and display2.

Thank you!
  Reply With Quote
Old May 4th, 2021, 05:40 PM   #2
drbitboy
Lifetime Supporting Member
United States

drbitboy is online now
 
drbitboy's Avatar
 
Join Date: Dec 2019
Location: Rochester, NY
Posts: 2,661
If the theory is correct that AfterAnimationStop on display 1 or 2 is called after AnimationStart on display 2 or 1, then I wonder if the following approach might work (new code in blue).

Code:
Boolean showB = True

Private Sub Display_AnimationStart()
  ShowDisplay ("bannerA")
  showB = False     ''' Display is 1 or 2
End Sub

Private Sub Display_AfterAnimationStop()
  if (showB) then   ''' Display is neither 1 nor 2
    ShowDisplay ("bannerB")
  else
    showB = True    ''' Assume next display will be neither 1 nor 2
  endif
End Sub

It depends on the variable [showB] being Global, or at least Static.
__________________
Take care of the bits, and the bytes will take care of themselves.
  Reply With Quote
Old May 5th, 2021, 11:56 AM   #3
Revnus
Member
Brazil

Revnus is offline
 
Join Date: Aug 2019
Location: Brazil
Posts: 25
Quote:
Originally Posted by drbitboy View Post
If the theory is correct that AfterAnimationStop on display 1 or 2 is called after AnimationStart on display 2 or 1, then I wonder if the following approach might work (new code in blue).

Code:
Boolean showB = True

Private Sub Display_AnimationStart()
  ShowDisplay ("bannerA")
  showB = False     ''' Display is 1 or 2
End Sub

Private Sub Display_AfterAnimationStop()
  if (showB) then   ''' Display is neither 1 nor 2
    ShowDisplay ("bannerB")
  else
    showB = True    ''' Assume next display will be neither 1 nor 2
  endif
End Sub

It depends on the variable [showB] being Global, or at least Static.
Thank you. I will try it in the next minutes and post if it worked or not.
Looking at your code I have a question tho:

Let's assume operator opens display 1 (showB =False), and then change from display1 to display 99. When Sub Display_AfternimationStop executes, wouldn't showB still be False? If this is the case, it would not show "bannerB" (keeping "bannerA") and only then, change showB to true.
  Reply With Quote
Old May 5th, 2021, 01:38 PM   #4
drbitboy
Lifetime Supporting Member
United States

drbitboy is online now
 
drbitboy's Avatar
 
Join Date: Dec 2019
Location: Rochester, NY
Posts: 2,661
Quote:
Originally Posted by Revnus View Post
Thank you. I will try it in the next minutes and post if it worked or not.
Looking at your code I have a question tho:

Let's assume operator opens display 1 (showB =False), and then change from display1 to display 99. When Sub Display_AfternimationStop executes, wouldn't showB still be False? If this is the case, it would not show "bannerB" (keeping "bannerA") and only then, change showB to true.



yeah, I might not have gotten that right yet. there are more than two cases, so it needs more than one bit to hold state ...


My other idea was similar but with a timestamp, instead of the Boolean, written by the ...Start, and if the ...Stop is called within a few ms of the ...Start, then don't display B.



How about this?


Code:
Dim count12 as Integer

Private Sub Display_AnimationStart()
   count12 = count12 + 1
   ShowDisplay("bannerA")
End Sub

Private Sub Display_AfterAnimationStop)
   count12 = count12 - 1
   if (count12 < 1) then
     ShowDisplay("bannerB")
   endif
 End Sub
Assume count12 starts as 0.


At the first selection of display1 or display2 from a display other than display1 or display2, AnimationStart will bump count12 to 1 and bannerA will be displayed; AfterAnimationStop will not be called so bannerA will remain displayed and count12 will still be 1.



After that, at any subsequent selections of display1 or display2, count12 will be bumped to 2 at the exit of AnimationStart, and then be dropped back to 1 after the first statement in AfterAnimationStop, so bannerB will not be displayed.


When a display other than display1 or display2 is selected, from display1 or display2, AnimationStart will not be called, so count12 will not change until AfterAnimationStop decrements it back to to 0, at which point bannerB will be displayed.
__________________
Take care of the bits, and the bytes will take care of themselves.

Last edited by drbitboy; May 5th, 2021 at 02:32 PM.
  Reply With Quote
Old May 5th, 2021, 04:33 PM   #5
Revnus
Member
Brazil

Revnus is offline
 
Join Date: Aug 2019
Location: Brazil
Posts: 25
Quote:
Originally Posted by drbitboy View Post
yeah, I might not have gotten that right yet. there are more than two cases, so it needs more than one bit to hold state ...


My other idea was similar but with a timestamp, instead of the Boolean, written by the ...Start, and if the ...Stop is called within a few ms of the ...Start, then don't display B.



How about this?


Code:
Dim count12 as Integer

Private Sub Display_AnimationStart()
   count12 = count12 + 1
   ShowDisplay("bannerA")
End Sub

Private Sub Display_AfterAnimationStop)
   count12 = count12 - 1
   if (count12 < 1) then
     ShowDisplay("bannerB")
   endif
 End Sub
Assume count12 starts as 0.


At the first selection of display1 or display2 from a display other than display1 or display2, AnimationStart will bump count12 to 1 and bannerA will be displayed; AfterAnimationStop will not be called so bannerA will remain displayed and count12 will still be 1.



After that, at any subsequent selections of display1 or display2, count12 will be bumped to 2 at the exit of AnimationStart, and then be dropped back to 1 after the first statement in AfterAnimationStop, so bannerB will not be displayed.


When a display other than display1 or display2 is selected, from display1 or display2, AnimationStart will not be called, so count12 will not change until AfterAnimationStop decrements it back to to 0, at which point bannerB will be displayed.
This one seems to be perfect!

I was able to accomplish it, but using other method which is not ideal since it has a delay to open banner. Here is the code:


Dim WithEvents Group As tagGroup
Dim WithEvents ChangeBannerAlarmVBA As Tag

Private Sub Display_AnimationStart()
On Error GoTo ErrHandler

Set Group = Application.CreateTagGroup(Me.AreaName) 'Group Creation
Group.Add ("ChangeBannerAlarmHMI")
Group.Active = True
Set ChangeBannerAlarmVBA = Group.Item("ChangeBannerAlarmHMI")

Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AnimationStart(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub
Private Sub ChangeBannerAlarmVBA_Change(ByVal Value, ByVal TimeStamp As Date, ByVal Quality As tagQualityConstants, ByVal SubStatus As tagSubStatusConstants, ByVal Limit As tagLimitConstants)
On Error GoTo ErrHandler


Dim PauseTime, Start, Finish, TotalTime
PauseTime = 1 ' Set duration.
Start = Timer ' Set start time.
Do While Timer < Start + PauseTime
DoEvents ' Yield to other processes.
Loop
Finish = Timer ' Set end time.
If ChangeBannerAlarmVBA.Value = "False" Then
Application.ShowDisplay ("bannerB")
Else
Application.ShowDisplay ("bannerA")
End If

Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" ChangeBannerAlarmVBA_Change(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub


To set ChangeBannerAlarmHMI, I used the following startup and shutdown commands at display1 and display2 properties:

Startup: Pause 1.2;&Set ChangeBannerAlarmHMI 1
Shutdown: &Set ChangeBannerAlarmHMI 0

This worked, but as I said, it has some delay (between 1 and 2 seconds)

I just tried your code: I hoped it would work.

When I change from display99 to display1 or display2 it shows bannerA, but when I change between display1 and display2, it tries to open bannerA again, and after, it opens banner B.

The complete code with your idea:

Dim count12 As Integer

Private Sub Display_AnimationStart()
On Error GoTo ErrHandler

count12 = count12 + 1
If (count12 >= 1) Then
ShowDisplay ("bannerA")
Else
End If

Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AnimationStart(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub

Private Sub Display_AfterAnimationStop()
On Error GoTo ErrHandler

count12 = count12 - 1
If (count12 < 1) Then
ShowDisplay ("bannerB")
Else
End If

Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AfterAnimationStop(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub


It seems count12 is loosing his value and going back to 0 at some point, I guess.

Last edited by Revnus; May 5th, 2021 at 04:37 PM. Reason: More information
  Reply With Quote
Old May 5th, 2021, 05:28 PM   #6
drbitboy
Lifetime Supporting Member
United States

drbitboy is online now
 
drbitboy's Avatar
 
Join Date: Dec 2019
Location: Rochester, NY
Posts: 2,661
Quote:
Originally Posted by Revnus View Post

Dim count12 As Integer

Private Sub Display_AnimationStart()
On Error GoTo ErrHandler

count12 = count12 + 1
If (count12 >= 1) Then
ShowDisplay ("bannerA")
Else
End If


Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AnimationStart(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub

Private Sub Display_AfterAnimationStop()
On Error GoTo ErrHandler

count12 = count12 - 1
If (count12 < 1) Then
ShowDisplay ("bannerB")
Else
End If

Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AfterAnimationStop(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub


It seems count12 is loosing his value and going back to 0 at some point, I guess.

Hmm, maybe just [Dim count12 as Integer] creates an automatic (temporary) variable that gets re-initialized when the code is called. Perhaps there is another keyword (Private? Global? Static?) that will make it permanent.


The app should not need the code in red above, but it should not cause a problem either (also, [count12 > 0] is cleaner than [count12 >= 1], don't you think?).


Is it possible for the VBA to write code to a console that you could watch? Or maybe write to a variable in the PLC? Perhaps we could store count12 on the PLC to make it more permanent.


Is it possible that AfterAnimationStop is not executing when switching away from display1 or from display2, but it is called as part of the actual switch TO display1 or display2?
__________________
Take care of the bits, and the bytes will take care of themselves.
  Reply With Quote
Old May 6th, 2021, 11:12 AM   #7
Revnus
Member
Brazil

Revnus is offline
 
Join Date: Aug 2019
Location: Brazil
Posts: 25
Quote:
Originally Posted by drbitboy View Post
Hmm, maybe just [Dim count12 as Integer] creates an automatic (temporary) variable that gets re-initialized when the code is called. Perhaps there is another keyword (Private? Global? Static?) that will make it permanent.


The app should not need the code in red above, but it should not cause a problem either (also, [count12 > 0] is cleaner than [count12 >= 1], don't you think?).


Is it possible for the VBA to write code to a console that you could watch? Or maybe write to a variable in the PLC? Perhaps we could store count12 on the PLC to make it more permanent.


Is it possible that AfterAnimationStop is not executing when switching away from display1 or from display2, but it is called as part of the actual switch TO display1 or display2?
I used count12 as a HMI tag and it worked perfectly!!!

Thank you very much. I've been strugling with this almost a week.

Also, I followed your recomendations to make the code cleaner.

Here is the complete code (count12 new name is ChangeBannerVBA_int as VBA Tag which points to ChangeBannerHMI_int integer HMI tag):


Dim ChangeBannerVBA_int As Tag
Dim MyGroup As TagGroup

Private Sub Display_AnimationStart()
On Error GoTo ErrHandler

Set MyGroup = Application.CreateTagGroup(Me.AreaName) 'Criação do Grupo
MyGroup.Add ("ChangeBannerHMI_int")
Set ChangeBannerVBA_int = MyGroup.Item("ChangeBannerHMI_int")

ChangeBannerVBA_int.Value = ChangeBannerVBA_int.Value + 1
ShowDisplay ("bannerA")

Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AnimationStart(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub

Private Sub Display_AfterAnimationStop()
On Error GoTo ErrHandler

ChangeBannerVBA_int.Value = ChangeBannerVBA_int.Value - 1
If (ChangeBannerVBA_int.Value < 1) Then
ShowDisplay ("bannerB")
Else
End If


Exit Sub

ErrHandler:
Application.LogDiagnosticsMessage "Error occurred in " & ThisDisplay.FullName & _
" Display_AfterAnimationStop(). Error # " & Err.Number & ": " & Err.Description, ftDiagSeverityError
End Sub


Last edited by Revnus; May 6th, 2021 at 11:15 AM. Reason: Correction
  Reply With Quote
Old May 6th, 2021, 10:14 PM   #8
drbitboy
Lifetime Supporting Member
United States

drbitboy is online now
 
drbitboy's Avatar
 
Join Date: Dec 2019
Location: Rochester, NY
Posts: 2,661
Quote:
Originally Posted by Revnus View Post
I used count12 as a HMI tag and it worked perfectly!!!


Brilliant on your part to use the HMI to make the value persistent!!!


So apparently the VBA script/code starts from scratch each time it is triggered. I wonder why you only need to do the Set MyGroup/MyGroup.Add/Set ChangeBannerVBA_int in the AnimationStart Sub but not again in the AfterAnimationStop Sub; I suppose the Stop Sub is called as part of the same event that triggers the Start Sub, so ChangeBannerVBA_int is still valid.
__________________
Take care of the bits, and the bytes will take care of themselves.
  Reply With Quote
Old Yesterday, 10:51 AM   #9
Revnus
Member
Brazil

Revnus is offline
 
Join Date: Aug 2019
Location: Brazil
Posts: 25
Quote:
Originally Posted by drbitboy View Post
Brilliant on your part to use the HMI to make the value persistent!!!


So apparently the VBA script/code starts from scratch each time it is triggered. I wonder why you only need to do the Set MyGroup/MyGroup.Add/Set ChangeBannerVBA_int in the AnimationStart Sub but not again in the AfterAnimationStop Sub; I suppose the Stop Sub is called as part of the same event that triggers the Start Sub, so ChangeBannerVBA_int is still valid.
It was your idea to create an external tag. I just found easier to create HMI instead of PLC tag. Thanks to you!

I think that what you supposed is true. I saw that there are subs, private subs and public subs. I don't know the difference yet, but I will study it later. Still, at first I thought that if we declared the "count12" before any sub, it would become a global variable and then it could be used by other scripts. That might not be true, but maybe there is way to do it..
  Reply With Quote
Reply
Jump to Live PLC Question and Answer Forum

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Topics
Thread Thread Starter Forum Replies Last Post
B&R 5C2000.02 No Display Output KeepItSimple LIVE PLC Questions And Answers 2 September 26th, 2019 05:44 AM
Control RSView32 Display From VBA rickj LIVE PLC Questions And Answers 7 June 27th, 2017 07:34 AM
Write VBA to read alarm tag and open associated display in Factory Talk View SE Programmersbug LIVE PLC Questions And Answers 2 April 13th, 2017 04:14 AM
Issue with Goto Display in MAIN - FTVS kandymann LIVE PLC Questions And Answers 21 February 11th, 2016 05:17 PM
Calling all Siemens S7-200 gurus mjamil LIVE PLC Questions And Answers 14 October 17th, 2004 07:22 PM


All times are GMT -4. The time now is 09:37 AM.


.