Diese Seite mit anderen teilen ...

Informationen zum Thema:
Forum:
WinDev Forum
Beiträge im Thema:
10
Erster Beitrag:
vor 4 Jahren, 2 Monaten
Letzter Beitrag:
vor 4 Jahren, 2 Monaten
Beteiligte Autoren:
Mauricio, Bart VDE, Allard, David van Pelt, Fabrice Harari, Alexandre Leclerc

[WD 18] Children and recursive calls

Startbeitrag von Mauricio am 04.03.2014 08:25

Hi all,
I have a self related HyperFile table with a structure like this:
Id numeric
Description string
IdParent numeric
Usable boolean
It can have any number of levels and if a record is "level 0", the field IdParent is, of course, empty.
For example:
Id Description IdParent Usable
1 Music Null False
2 Guitars 1 False
3 Classic 2 True
4 Blues 2 True
In other words, a classic tree structure.
I want a function that returns all the ids of the children of a given records only for those where Usable = True. I know how to do it with MS SQL (CTEs are great for things like this) and I wrote a recursive function in WD but it's very slow in my opinion.
Perhaps someone has a better way to do this, I guess it's something very common.
Thanks for your help.

Mauricio

Antworten:

Hi

You can do this several ways. I am not an expert on this and I donnot know if the way I did it is the best way. I took a look at the crm example and it gave me insight in how to do this

So best lookat the crm example



regards

Allard

von Allard - am 04.03.2014 09:59
Hi Mauricio

just a "little" thing... Recursivity is officially NOT supported in wlanguage, which means that any cal "deep" enough will crash your program...

Last time I checked (can't remember if it was in 17 or 18) there were about 130 levels possible (a previous version had 600, so do not expect anything special in next version)

Best regards

von Fabrice Harari - am 04.03.2014 12:28
Maybe you could put once your HF table in a (invisible) treeview control and than use TreeListItem to get what you want

Regards,
Bart

von Bart VDE - am 04.03.2014 13:41
Hi Mauricio,

You should not use recursive calls for this. You should use an optimised SQL query that you will call for every required level in a loop. (And when it works, and if you can use stored proc on the server, put the proc on the server.)

Example (you can do that using the Query Editor - I did not check the following syntax, I write all this from memory):

SELECT Id FROM TheTable WHERE Usable = True AND IdParent IN {sListID}


Then, simply call your query (something like this):

let sID = ""
let s = "2" // init to the starting point you want to check
WHILE HExecuteQuery(MyQuery,hQueryDefault,s)
// Build the list of matching IDs
s = ""
FOR EACH MyQuery
IF s"" THEN s+=","
s += MyQuery.Id
END
// Keep all IDs in memory
IF sID"" THEN sID+=","
sID += s
END

RETURN sID


This way, most of the work will be done on the SQL server and you will have faster results. The loop works by "levels" instead of single elements. So if you have most of the data in 2-3 levels, you can have 25 results in only 2-3 queries.

Ok, depending of you data size it might not be a workable solution and there are some issues with that when scaling, but it might do the job correctly for you, I just don't know. But this is to say that there is often a way to optimize a slow process.

Hoping this can help you in finding a good solution.

Best regards,
Alexandre Leclerc

von Alexandre Leclerc - am 04.03.2014 14:28
Thanks for the answers, guys. I'm not sure how many calls I'm executing, I will test later but I'm sure there are many. I will try Alexander suggestion, I'm sure there is a better way to do it and if I find it I will let you know.
Thanks again.

von Mauricio - am 04.03.2014 15:06

how to use print screen


PROCEDURE GetChilds(id)
path is string

HReadSeekFirst(Music,id,id)
path = Music.description
WHILE Music.idparent > 0
HReadSeekFirst(Music,id,Music.idparent)
path = Music.description + TAB + path
END

TreeListItem(Tv1,path,"ListTree")



PROCEDURE ListTree(RecipeTV, ChildPath, ChildFound, Level, Pointer)
IF TreeTypeItem(RecipeTV, ChildPath + ChildFound) = tvLeaf THEN
Trace(ChildFound)
END

von Bart VDE - am 04.03.2014 15:56
Just for clarify, I'm not interesting in making a treeview, just getting all the children where Usable = TRUE of a given record.

von Mauricio - am 04.03.2014 17:30
The treeview is just a way of storing that, or loading them on-demand, etc.
Invisible controls can be very usable for these kind of things.
I would go for the query way as this is the thing that was / is made for this.

What also works (would never recommend it as we have databases) is array of structures,
and let the structure have it self.
I only use this method when I have a huge server and manipulate the data a lot.

But I think you should go for the way Alexandre described, using a query.

Best regards,
David

von David van Pelt - am 05.03.2014 09:00
If you take a look at the crm exaple it is slf explaining

Add stuff to the tree vieuw indeed the true or fase as well, in the last note

Then
treeselect(path)

variabele = extractstring(path, Level,tab)
variabele2 = extractstring(path,level,tab)
etc

The variabele gives you where you are and if it is true or false

reagrds

von Allard - am 05.03.2014 10:21
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.