1. Cesar Monroy
  2. PowerBuilder
  3. Thursday, 7 January 2021 21:29 PM UTC

I'm trying to generate an event calendar that starts on a given day of the week.

Thus I calculate the first day of the year, and the required offset to the selected day. Now I need to generate the dates for such offset starting weeks I know that starting date of the week has to be within the given year, even though it may extend to the next year. My sample code is the following:

integer li_index, li_year
date ld_currentdate

li_year = 2021
ld_currentdate = date(li_year, 1, 1)

// Solution: use the SetRedraw function with the listbox...
lb_weeks.SetRedraw(False)

do while ld_currentdate < date(li_year, 12, 31)
   yield()
   if daynumber(ld_currentdate) = 5 then
      messagebox("Current Date Processed", string(li_index) + ": " + 
      string(ld_currentdate))
      ls_currentdate = string(ld_currentdate)
      li_index = lb_weeks.additem(ls_currentdate)
      li_index++
   end if
   ld_currentdate = relativedate(ld_currentdate, 1)
loop

// Solution: and turn it on after the loop...
lb_weeks.SetRedraw(True)

It works as expected, but the thing is that without the messagebox, it goes to the land of the never ending loops. And it seem to recall that whenever I used loop, I confronted the same issue: the loop seems to loop too fast to perform anything else (reason why I inserted such a useless yield() at the beginning). In this case, if it weren't for the messagebox, the list box wouldn't be filled out (assuming, of course, that the loop allowed anything else to occur before crashing).

Any pointers (or solutions) to this looping issue will be greatly appreciated.

Accepted Answer
Arthur Hefti Accepted Answer Pending Moderation
  1. Friday, 8 January 2021 05:38 AM UTC
  2. PowerBuilder
  3. # Permalink

Hi

2 suggestions for your loop.

1. Determine the first Thursday in the year and add 7 days, so no need to check for daynumber in each loop and will reduce the number of loops rom about 360 to 52 or so.

2. Use lb_weeks.SetRedraw( FALSE ) bevor the loop and lb_weeks.SetRedraw( TRUE ) after the loop. This will prevent GUI updates and should make the loop finish very fast.

Regards
Arthur 

Comment
  1. Cesar Monroy
  2. Friday, 8 January 2021 14:28 PM UTC
Using the SetRedraw(FALSE) did the trick for me, Thank you Arthur.

About point 1: That was the code I was actually using before. I just need to determine which day is going to be considered the starting of the week, get there, and then just count 7 until the end of the year, right? But when examining the output data, I found that after February, the routine was selecting other day of the week. The code was the same, except for the RelativeDate(var, offset), where offset was 7, instead of 1. Nobody wants to get quircky results, so I went for the bigger hammer and actually made sure that I would inspect every single day of the year for being a Thursday
  1. Helpful
There are no comments made yet.
René Ullrich Accepted Answer Pending Moderation
  1. Friday, 8 January 2021 06:08 AM UTC
  2. PowerBuilder
  3. # 1

Hi Cesar,

I have no problems with your code (with and without messagebox).

If you have a long running loop (you excample is not long running) using the Yield function is a good way to do other things.

But it is dangerous! You have to write code to prevent user to do things that are not possible if the loop is running. Or you have to write code to stop loop if user have done some things.

Example: User may close the window or application -> this will produce an error in loop.

HTH,

René

Comment
  1. Cesar Monroy
  2. Friday, 8 January 2021 14:46 PM UTC
Thank you René. Neither did I, but if you remove the messagebox from the code, it will loop forever. Thanks to Arthur Hefti, who suggested setting the SetRedraw to false before doing the loop, the code now works as expected
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Friday, 8 January 2021 02:29 AM UTC
  2. PowerBuilder
  3. # 2

Greetings, Cesar -

Listbox controls are a type of visual control that is created and managed by Windows, not PowerBuilder. If you have the Listbox configured to sort the items it contains, each time you add an item the control has to examine the new item and ensure all of the items are properly sorted...even if you are inserting the items in sorted order (the Listbox control does not "know" you are inserting items in sorted order). A very inefficient and very CPU intensive loop results.

You should consider using a DataWindow instead of a Listbox control. Even if the event dates are not going to recorded in a database, it would be much more efficient to load the generated dates into a DataWindowChild and use it as the list displayed in a column's drop-down DataWindow. External-source DataWindows are well-suited to serve as data entry/selection mechanisms when no database integration is needed.

If this is a new concept to you, simply ask. The Appeon Community is always willing to help!

Regards, John

Comment
  1. Cesar Monroy
  2. Friday, 8 January 2021 14:41 PM UTC
The listbox was explicity configured as not sorted precisely for that reason.

I love datawindows, John, but when you are asked to keep the look-and-feel of a legacy application, there is not much leeway. But yes, you are right: I should use datawindows more often... Thank you
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.