Navision Timer 1.0.Timer

Matt.HillMatt.Hill Member Posts: 32
I'm trying to write some some code that will run a batch of reports overnight, so far I've got NAS in place and running, but now I need to introduce an element of timing (the code needs to run during a specific time window to stop it affecting the TV channel that we run). So far I have some code (in a single instance codeunt):
IF ISCLEAR(Timer) THEN
CREATE(Timer); 
Interval := 60 * 15; //wake up every 15 minutes
Timer.Enabled := FALSE;
Timer.Interval := Interval * 1000;
Timer.Enabled := TRUE; 
UserStartTime := 222900T; 
LastRunDate := 0D; 
Timer::Timer(Milliseconds : Integer)
IF (TIME >= UserStartTime) AND (TODAY <> LastRunDate) THEN BEGIN
  MESSAGE('Start Time %1',TIME);
  REPORT.RUNMODAL(795,FALSE,FALSE);
  MESSAGE('End Time %1',TIME);
  LastRunDate := TODAY;
END;

However, it complains about the following line when trying to complile as being "not an allowed option":
Timer::Timer(Milliseconds : Integer)


Even to me that syntax seems a 'bit odd' but its replicated in all the examples I've found here. ](*,)

Timer is defined as being an Automation variable of 'Navision Timer 1.0.Timer'

What am I doing wrong???


Thanks in advance!

Comments

  • krikikriki Member, Moderator Posts: 9,112
    Matt.Hill wrote:
    Timer::Timer(Milliseconds : Integer)
    
    This code means it is a function in the program, not a functioncall.
    In the global variable of the Timer-automation, you have to put its property "WithEvents" to TRUE. This will create the function. Then you put the code in it.
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • Matt.HillMatt.Hill Member Posts: 32
    kriki wrote:
    In the global variable of the Timer-automation, you have to put its property "WithEvents" to TRUE. This will create the function. Then you put the code in it.

    Where is this property??? I select properties with the line selected in variables, all I get as properties are its object id and dimensions???
  • krikikriki Member, Moderator Posts: 9,112
    Matt.Hill wrote:
    kriki wrote:
    In the global variable of the Timer-automation, you have to put its property "WithEvents" to TRUE. This will create the function. Then you put the code in it.

    Where is this property??? I select properties with the line selected in variables, all I get as properties are its object id and dimensions???
    Open the global variables. Position the cursor on the Timer-automation. Hit Shift+F4. This opens the properties of the variable. And there it is.
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • Matt.HillMatt.Hill Member Posts: 32
    kriki wrote:
    Open the global variables. Position the cursor on the Timer-automation. Hit Shift+F4. This opens the properties of the variable. And there it is.

    Calm down...I know how to get to the properties of a variable....

    It wasn't in the list of options...seems that it needed to be a global (not local)...oh well!



    Anyhow...all fixed!
  • krikikriki Member, Moderator Posts: 9,112
    Matt.Hill wrote:
    kriki wrote:
    Open the global variables. Position the cursor on the Timer-automation. Hit Shift+F4. This opens the properties of the variable. And there it is.

    Calm down...
    Don't worry. I wasn't angry. I was just pointing you step-by-step to the correct place.
    When we see a post, it is often difficult to see if the person who posted it is a newby or a Navision-ace.
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • petevanspetevans Member Posts: 78
    I am new to Automations with WithEvents and am having problems when testing this timer.

    Normal CodeUnit (not single-instance):
    OnRun()
      IF ISCLEAR(Timer) THEN CREATE(Timer);
      Timer.Interval := 1000;
      Timer.Enabled := TRUE;
      SLEEP(5000);
    
    Timer::Timer(Milliseconds : Integer)
      MESSAGE('pling');
    

    I was hoping for 5 "pling"'s, but obviously I am doing something wrong. Any help appreciated!
    NAVN00b
  • lubostlubost Member Posts: 627
    Codeunit must be single instance, because it need to remain in memory. If you do not set this property, codeunit do the code in OnRun trigger and then clears all variables and is removed from memory.
  • kinekine Member Posts: 12,562
    During the sleep, the process is still running and it is why the event is not called. Sleep does not mean that the "thread" is sleeping or something, it is just frozen for the amount of time and other applications can do something. But not Nav client itself...
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • petevanspetevans Member Posts: 78
    Thanks for answering!

    I was indeed hoping that the event would trigger during the sleep in a multithreaded fashion, but in retrospect I see that I was hoping for too much! :)

    Changing the CodeUnit to SingleInstance makes the timer work, but it only triggers when the codeunit is not processing any other code.

    For example, writing:
    OnRun()
      IF ISCLEAR(Timer) THEN CREATE(Timer);
      Timer.Interval := 3000;
      Timer.Enabled := TRUE;
    
      REPEAT 
        i := i+1
      UNTIL i>10000000;
    

    ...causes the timer-event to trigger only after the loop has finished.

    So to me it seems like Automation-events in Navision need to be in a Single-Instance CodeUnit, and that they will only trigger when the codeunit is "idling" - that is, not currently performing any other code.

    Any comments welcome! 8-[
    NAVN00b
  • kinekine Member Posts: 12,562
    Yes, this is a way how NAV works. One thread, if running, other events are suspended. (But, if you do some tests, you can see that the timer event wait in some queue and is processed after the running thread ends. I wrote some example of this in one thread on this forum).
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • primeapprimeap Member Posts: 37
    Hi, I posted a solution here http://stackoverflow.com/questions/17827347/time-scheduling-in-navision-with-timer

    This example runs at 7:40, 12:40 and 16:40 each day.

    Using the Navision Timer 1.0 NAVTimer Automation 'Navision Timer 1.0'.Timer

    Set the Property 'WithEvents' of the NAVTimer to Yes

    Set the Property 'SingleInstance' of the Codeunit, if you using one, to Yes

    In the On Run Trigger write
    IF ISCLEAR(NAVTimer) THEN 
     CREATE(NAVTimer);
    
    NAVTimer.Interval := 1 * 60000;  // Important! set to 1 Minute
    
    NAVTimer.Enabled := TRUE;
    

    In the Timer Trigger (it appers after you change WithEvents Property to Yes) write
    sTime := COPYSTR(FORMAT(TIME), 1, 5); // Cut seconds
    sHour := COPYSTR(sTime, 1, 2);
    sMinute := COPYSTR(sTime, 4, 2);
    IF sHour IN ['07','12','16'] THEN
      IF sMinute = '40' THEN
        IF NOT CODEUNIT.RUN(CODEUNIT::xxx) THEN;
    
Sign In or Register to comment.