Using pstimer to run an event - progress-4gl

I want to execute a function or a procedure or a block in regular intervals of 60seconds.
Do i have to use PS timer for that?
let this be my block
MyString = myEditor.Screen-Value.
Message MyString.
//myEditor is my Editor widget in the frame.
//My String is a string which i will use to display
I want to repeat this in each 60 seconds.. So that everytime it should display whatever I typed
inside the editor.? How can I do this with using PSTimer or without using it?

You must generate a Tick trigger block.
In this block can you write your code.
PSTimer has a property "Interval", which means interval for Tick event in miliseconds.
It has also other property "Enabled", witch starts and stopts timer.
When you run some longer code from your Tick event, schould be better switch that property "Enabled" on FALSE and on end of the trigger over on TRUE. Otherwise you can become a conflict with your code and new Tick event resp. your program will making never other, only showing runing your trigger script.

Related

How to display delay time of current agent in a delay block?

I would like to display in a text object the current delay time of a delay block. In the value editor of the text object I have sta1Delay.getDelayTime(agent) which throws an error "agent cannot be resolved to a variable".
You can do this:
In the "on enter" code box of your delay block, write myText.setText("Delay time: "+delayTime);
The keyword delayTime provides the duration for every new agent arriving.
Worth learning about those keywords, see https://www.benjamin-schumann.com/blog/2016/2/4/the-magic-lightbulb-and-how-it-can-help-your-anylogic-modelling

Is it possible to dynamically update if functions in anylogic?

I'm using a state chart in combination with a schedule in Anylogic (see picture). The output of the schedule is equal to 1 during working hours and 0 otherwise. Now I want the transition from state1 to state2 to happen when the schedule is turning to 1 or is equal to 1(so otherwise wait until the working hours).
I have tried using an if statement
if( main.plannerSchedule()==1 )(<perform action>)
However, by this method, the state transition only happens if the statement is true but doesn't wait for it to become true. Is there a way to constantly update the state transition or is there a "wait until" function that can solve this problem?
Best let the schedule send a message to your statechart when it switches. This assumes that the statechart lives on the same agent type as the schedule. Write this code in the action code box of the schedule:
if (value==1) {
statechart.fireEvent("go to state 2");
}
Obviously, your message transition needs to await the "go to state 2" message.
Note the value keyword. See https://www.benjamin-schumann.com/blog/2016/2/4/the-magic-lightbulb-and-how-it-can-help-your-anylogic-modelling for more info on that

How I can evaluate a condition on next time-step in anylogic?

I am trying to write a code for one state to another state transition where the system will first store the initial model time and then will check a condition (used while loop). It will continue to run the loop until the condition is false and when the condition is false it will record the final model time. So, my main objective is to get the total time that while loop condition is true. The problem is, I don't know how to check the while loop every 1 time step, For example, I tried "wait (1);" in place of "???" section of the below code which is not correct. Can anyone please suggest how I can do this?
My transition code as below:
...
...
initialTime=time();
while ((thisPed.inState(walking) && thisPed.fieldOfVision.contains(pedX, pedY));
{
???
}
finalTime= time();
exposureTime = finalTime - initialTime;
...
...
you can't put while statements in a model that at the same time run with time steps... to do that you have many other ways..
For instance you can generate a transition that goes from that state to the same state (internally) and generate your code there every time step.
Another option is to use a conditional transition in the same way
BUt NOT a while loop

Override 'Cancel' in event procedures

There is data validation in my MS Word user form which returns the focus to the textbox where the user entered something incorrect. Now I am trying to accommodate the user's change of mind: instead of correcting the entry, I want him to be able to exit the form (click the Exit command button), in which case the entry would be discarded. I suppose that a solution would start with not using the text box's exit event. I little help from someone who knows the answer would save me a lot of testing time, perhaps to find out that I can't do it.
Does anyone know?
I understand that you are handling the Exit event of the Textbox, setting the Cancel output parameter if the data is not valid.
There's a tricky but simple solution that permits to keep that working and still have an Exit button. It permits to activate the handler of the Exit button without requiring the focus to leave the Textbox. This way you can unload the Form safely in this handler.
Try this it works pretty smoothly:
1- Set the property TakeFocusOnClick of the Exit command button to False. You can do that at design time in the property-sheet, or at run-time i.e. at UserForm_Activate
2- just unload the form when the Exit button is clicked:
Private Sub ExitButton_Click()
Unload Me
End Sub
#A.S.H provided the key to the solution below. His point is that it is possible to call another event procedure while Cancel is active in the Exit procedure of a control. That other procedure can be used to rectify the condition in the first control which is triggering the Cancel, thereby enabling an orderly exit. The all-enabling condition is that the control on whose click event the rectifying procedure is to run must not take the focus when clicked (meaning it can run without triggering an exit from the control stuck on Cancel). I have added code to the exit procedure to set CmdExit.TakeFocusOnClick = False when a Cancel condition arises there. Now, ...
Private Sub CmdExit_Click()
' 12 May 2017
' if CmdExit can't take the focus it can't be the ActiveControl
If Not ActiveControl Is CmdExit Then
Select Case ActiveControl.Name
Case "Cbx107"
Cbx107.Value = ""
Case "Tbx53"
Tbx53.Value = "0"
End Select
With CmdExit
If Not .TakeFocusOnClick Then
.TakeFocusOnClick = True
.SetFocus
End If
End With
End If
' now CmdExit is the ActiveControl
MsgMe "Cmd Exit: ActiveControl = " & ActiveControl.Name
Me.Hide
End Sub

Using REPEAT a block till an event occurs?

This is my issue:
On triger of a START button i wan to execute one block. And it should stop executing when I
press STOP button.
Eg
on triger of start button:
REPEAT:
message "hai".
END.
and when I press STOP button It should stop. What additional condition should I give to REPEAT block?Preferably I dont want to write the condition in STOP button Triger..Please give suggestion .
Progress is not multi-threaded.
So you have to carefully think through which bits of code need to execute in what context in order to fake it. (More carefully than my initial "it cannot be done" response.)
As "firhang" points out "PROCESS EVENTS" can be used to check for events queued and ready to be acted on.
So you could run your loop inside an event handler and have that event handler listen for additional events.
I believe that the following satisfies the original question and works in both GUI and Character clients:
define variable i as integer no-undo.
define variable bStop as logical no-undo.
define button butStart label "Start".
define button butStop label "Stop".
form butStart butStop with frame but-frame row 1.
on choose of butStop bStop = true.
on choose of butStart do:
bStop = false.
do while bStop = false:
i = i + 1.
process events.
message i.
end.
message "Paused".
end.
enable butStart butStop with frame but-frame.
pause 0 before-hide.
wait-for window-close of current-window.
PROCESS EVENTS statement
Processes all outstanding events without blocking for user input.
Syntax
PROCESS EVENTS
Example
This procedure counts to 1,000 until you choose STOP:
r-proevs.p
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
DEFINE VARIABLE stop-sel AS LOGICAL NO-UNDO.
DEFINE BUTTON stop-it LABEL "STOP".
DISPLAY stop-it.
ON CHOOSE OF stop-it
stop-sel = TRUE.
ENABLE stop-it.
DO ix = 1 TO 1000:
DISPLAY ix VIEW-AS TEXT.
PROCESS EVENTS.
IF stop-sel THEN LEAVE.
END.
On each pass through the loop, the procedure displays the new value of ix and then checks whether any events are waiting to be processed. If no events have occurred, execution continues and the loop iterates. If the STOP button has been chosen, that event is processed changing the value of stop-sel. When execution continues, the program exits the loop.
If the loop does not contain the PROCESS EVENTS statement, the choose event never processes and the loop iterates until ix equals 1,000.
Notes
The WAIT-FOR statement processes all pending events and blocks all other execution until a specified event occurs. The PROCESS EVENTS statement processes all pending events and immediately continues execution with the next statement.
If there are any asynchronous requests for which PROCEDURE-COMPLETE events have been received but not yet processed, this statement processes these events as described for the WAIT-FOR statement.
You cannot call the .NET method system.Windows.Forms.Application:DoEvent( ) in ABL. The PROCESS EVENTS statement performs the function of this method.
.NET can raise exceptions in the context of an ABL session when this statement executes.
DEFINE VARIABLE bStop AS LOGICAL NO-UNDO.
DEFINE BUTTON butStop LABEL "Stop".
FORM butStop WITH FRAME but-frame ROW 1.
ON CHOOSE OF butStop bStop = TRUE.
ENABLE butStop WITH FRAME but-frame.
REPEAT:
PROCESS EVENTS.
MESSAGE "hai".
IF bStop THEN LEAVE.
END.
MESSAGE "stoped".
WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW.