loops

i am a fair way through a conversion of a filemaker solution to servoy and so far am finding this reasonably straightforward (event programming is amazing!) and am now starting on converting some of the looping scripts. Javascript loop i am using is:

var new_date = purchase_date
var foundset_size = purchases_to_lineitems.getSize()

for ( var i = 0 ; i < foundset_size ; i++ )
{
forms.lines_in.controller.setSelectedIndex = i
purchases_to_lineitems.line_date = new_date
}

i am missing something obvious as the dates are not being set at all. All variables are correct. i am calling this method from a purchase table form through a portal to change the line date of the child records.

Would really appreciate some help.

Your problem is that getSize() will deliver the fetch size of the relaion, which is 40. Servoy fetches only the fetch size of foundsets, which is 40 for relations and 200 for table foundsets. The rest is loaded “on demand”, usually when you scroll to the end.

In your case it goes wrong, because you ask the foundst for its size before you enter the loop once. In the case of 55 records, this will return 40 and that’s it. To overcome this, change your code to

var new_date = purchase_date

for ( var i = 0 ; i < purchases_to_lineitems.getSize() ; i++ )
{
var vLineItem = purchases_to_lineitems.getRecord(i);
vLineItem.line_date = new_date;
}

In this case, getSize will be updated if 40 is reached. I have also changed the index selection to a more abstract notation (getRecord), which does not update th UI and is faster.

Hope this helps
Patrick

P.S.: Welcom to Servoy! Event programming will not be the only thing you will find amazing!

Many thanks for your quick reply.

when i run this method now i get the following error

“cannot convert null to an object”

when i watch the variables your vLineItem = null

I have 6 records in the portal and all refences to the relationship seem right.

regards
Rodney

Oops. That was my fault. Usually things in the Java area are zero based, but not foundsets. So change this to:

var new_date = purchase_date

for ( var i = 1 ; i <= purchases_to_lineitems.getSize() ; i++ )
{
var vLineItem = purchases_to_lineitems.getRecord(i);
vLineItem.line_date = new_date;
}

Again thanks for your quick response.

My method now runs but again only changes the first record and doesn’t loop through all related records. I decided to pare it all back to just see any basic loop work!

Created a table with one text field (new_text), 7 records, one looping method:

for ( var i = 1 ; i <= 7 ; i++ )
{
new_text = “anything!!!”;
}

when i run this script, again only the current selected changes no other record values are set. Starting to get worried! i’m missing something obvious.

regards,
Rodney

Yes, you are. Look closely at my code:

var vLineItem = purchases_to_lineitems.getRecord(i); 

This will load the i-th record into the variable vLineItem. Now with

vLineItem.line_date = new_date;

the property “line_date” of the variable vLineItem (that contains the i-th record) is set to the contents of your “new_date” variable.

Your code loops perfectly, but you always set the value to the record the cursor sits on (typically the first record). So seven times you set “new_text” of the first record to “anything!!!”. Change your code to

for ( var i = 1 ; i <= 7 ; i++ )
{
var iRecord = foundset.getRecord(i); // loads record i into the variable iRecord
iRecord.new_text = "anything!!!"; // sets "anything!!!" into the field "new_text"
}

and it works.

I recommend using the debugger to really see what is going on. Open the method editor, click “enable debugger”, choose “enable entry break” from the little triangle next to “enable debugger” and have a look at the variables tab of the debugger window. You should then see the “iRecord” variable getting filled every time with the i-th record while you step through the loop.

Hope this helps,
Patrick

THIS IS THE BEST TECHNICAL SUPPORT I’VE EVER HAD!

Thanks mate

Everything is working fine now, your explanation really helps. Loops in servoy are very different to filemaker and are the first thing thats taken awhile to get my head around. Now that i’ve got my first loop working should be ok from now on.

one last question: can you confirm that the “.getSize ()” fx will work with foundsets greater than the 200 limit i keep reading about.

Again thanks so much

Yes, getSize() on a foundset directly (not related) will work the same. But do not put getSize() into a variable and loop using that variable. Then you “freeze” at 200. Instead use

for ( var i = 1 ; i <= foundset.getSize() ; i++ )
{
var record = foundset.getRecord(i);
}

If you reach 200, getSize will automatically increase to 400, 600, 800 etc. depending on the actual size of the foundset. What you can also do is

var foundsetSize = databaseManager.getFoundSetCount(foundset); // returns the actual size of the foundset, can be timeconsuming if you have a large foundset
for ( var i = 1 ; i <= foundsetSize  ; i++ )
{
var record = foundset.getRecord(i);
}

this way you “freeze” the real size, not the fetch size.