Toon posts:

[ASP] Probleempje met coden van een treeview

Pagina: 1
Acties:
  • 129 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
In een ander topic had ik het al over hoe ik een treeview volledig "uitgevouwen" kon laten weergeven. Via een handig linkje van een vriendelijke got-er kwam ik terecht bij een stukje php-code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php 
// $parent is the parent of the children we want to see 
// $level is increased when we go deeper into the tree, 
//        used to display a nice indented tree 
function display_children($parent, $level) { 
   // retrieve all children of $parent 
   $result = mysql_query('SELECT title FROM tree '. 
                          'WHERE parent="'.$parent.'";'); 

   // display each child 
   while ($row = mysql_fetch_array($result)) { 
       // indent and display the title of this child 
       echo str_repeat('  ',$level).$row['title']."\n"; 

       // call this function again to display this 
       // child's children 
       display_children($row['title'], $level+1); 
   } 
} 
?>


Nu moest ik dit in asp krijgen en dat ging vrij goed tot ik op deze error stootte:
This array is fixed or temporarily locked: 'rij'
Dus omdat ik telkens opnieuw de array rij gebruik en dit niet kan (want reeds in gebruik) krijg ik een error.

Ik kan niet direct aan op een oplossing kome want mijn tree gaat een onbepaald aantal niveau's diep.
Dit is mijn code (eerste versie dus nog wat 'slordig')
ASP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Set cnDB = OpenDB()
Dim rsData         ' As ADODB.Recordset
Dim strSQL        ' As String
Dim strURL        ' As String
Dim rij
Set rsData = Server.CreateObject("ADODB.Recordset")
Response.write(geefchilds(0,0))
Function geefchilds(parent, level)
Response.write(Parent&level)
    rsData.open "SELECT * From Links Where Parent=" & parent, cnDB, adOpenStatic

    rij = rsData.GetRows()
    rsData.close
    iRecFirst   = LBound(rij, 2)
    iRecLast    = UBound(rij, 2)




    For I = iRecFirst To iRecLast
    Response.write(herhstring("&nbsp;&nbsp;&nbsp;", level) & rij(2,I))
    einde= einde & geefchilds(rij(6,I), level+1)
    



    Next ' I



geefchilds=einde
End Function
Set rsData= nothing

Ik weet dat de variabele einde eigenlijk niets voorstelt en geefchilds eigenlijk beter een functie zou zijn :)

EDIT: Voor de codezoekers: de oplossing staat onderaan :*)

[ Voor 8% gewijzigd door Verwijderd op 26-01-2004 17:51 ]


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 22:24

gorgi_19

Kruimeltjes zijn weer op :9

Het eerste wat ik kan bedenken is om rij in de functie te declareren.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Eeuh als ik dim rij vlak na het declareren van mijn functie plaats dan krijg ik een oneindige loop denk ik (en opnieuw dus een error :d)
Ik had er ook al eens aan gedacht, maar dat helpt dus blijkbaar niet :(

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 22:24

gorgi_19

Kruimeltjes zijn weer op :9

Dan is er wat anders fout, maar je moet iig rij in de functie declaren, anders wil je steeds de originele waarden overschrijven en krijg je dus fouten. Je bent immers nog in die array als je hem eigenlijk wil overschrijven met nieuwe data.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Nu heb ik dit:
ASP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!--#include file="incdbxml.ssi" -->
<%
' database laden etc.
Set cnDB = OpenDB()
Dim rsData         ' As ADODB.Recordset
Dim strSQL        ' As String
Dim strURL        ' As String

Set rsData = Server.CreateObject("ADODB.Recordset")
Response.write(geefchilds(0,0))
Function geefchilds(parent, level)
Dim rij
Response.write(Parent&level)
    rsData.open "SELECT Naam, Parent From Links Where Parent=" & parent, cnDB, adOpenStatic

    rij = rsData.GetRows()
    rsData.close
    iRecFirst   = LBound(rij, 2)
    iRecLast    = UBound(rij, 2)




    For I = iRecFirst To iRecLast
    Response.write(rij(1,I)&rij(2,I))
    Response.write(herhstring("<br>&nbsp;&nbsp;&nbsp;", level) & rij(1,I))
    einde= einde & geefchilds(rij(2,I), level+1)
    'Response.write("<br>"&rij(6,I)&"<br>"&rij(1,I)&"<br>"&level+1)



    Next ' I



geefchilds=einde
End Function


Set rsData= nothing
%>

En nu werkt het helemaal niet meer :(
Microsoft VBScript runtime error '800a01fb'

An exception occurred: 'Open'

/flabbergasted/links.asp, line 14
Dat is dus deze regel: rsData.open "SELECT Naam, Parent From Links Where Parent=" & parent, cnDB, adOpenStatic

Ik begrijp het niet echt meer :(

  • Gert
  • Registratie: Juni 1999
  • Laatst online: 05-12-2025
Als je Access als database gebruikt zou kolomnaam Naam wel eens niet kunnen werken. Je kan dat oplossen door of je kolomnamen te hernoemen of door er [] om heen te zetten.

  • faabman
  • Registratie: Januari 2001
  • Laatst online: 08-08-2024
je probeert een recordset te openen die al open staat...

wat je beter kan doen is de volledige tabel in een array gooien en met een recursieve functie je treeview opbouwen...

en om je ook meteen maar even te helpen
ASP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
objRS.Open sqlquery, Con, 3, 1
If Not objRS.Eof Then
  arr_menu = objRS.GetRows()
End If
objRS.Close

menu(0)

Function menu(parentID)
  dim I
  For I = 0 To Ubound(arr_menu,2)
    If arr_menu(kolom_parentID, I) = parentID Then
      Response.Write(arr_menu(kolom_menuID, I) & "verdere zooi die je weer wil geven")
      
      menu(arr_menu(kolom_menuID,I))
    End If
  Next
End Function


en bovenstaand voorbeeld zijn kolom_* contstanten die verwijzen naar het kolom-coordinaat in je array
ik ben er van uit gegaan dat je parentID 0 is wanneer een item op het hoogste niveau ligt...

disclaimer, heb het niet getest, als je een stack overflow of iets dergelijks krijgt moet je de functie ff in 2 functies verdelen waarbij de 2e recursief is


oww, en nog ff mbt naam, volgens mij is naam helemaal geen reserved value in access, lijkt me eerder dat dat name is, mocht naam wel reserved zijn dan moet je die even tussen blokhaken zetten (zoals al eerder gezegd is) naam wordt dan dus [naam] en niet naampje...

[ Voor 78% gewijzigd door faabman op 23-01-2004 20:21 ]

Op zoek naar een baan als Coldfusion webdeveloper? Mail me!


Verwijderd

Topicstarter
Bedankt heb even in Naampje veranderd ;) maar het werkt nog steeds niet
error is nu:
00Andere LinksFlabbergasted Links0
Flabbergasted Links01
Microsoft VBScript runtime error '800a01a8'

Object required

/links.asp, line 14

En de code is al geworden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Response.write(geefchilds(0,0))
Function geefchilds(parent, level)
Dim rij
Response.write(Parent&level)
    rsData.open "SELECT Naampje, Parent From Links Where Parent="&parent, cnDB, adOpenStatic

    rij = rsData.GetRows()
    Response.write(rij(0,1))
    rsData.close
    Set rsData= nothing
    iRecFirst   = LBound(rij, 2)
    iRecLast    = UBound(rij, 2)
    For I = iRecFirst To iRecLast

    Response.write(rij(0,I)&rij(1,I))
    Response.write(herhstring("<br>&nbsp;&nbsp;&nbsp;", level) & rij(0,I))
    einde= einde & geefchilds(rij(1,I), level+1)
    'Response.write("<br>"&rij(6,I)&"<br>"&rij(1,I)&"<br>"&level+1)



    Next

set rij = nothing

geefchilds=einde
End Function

en lijn 14 is rsData.open "SELECT Naampje, Parent From Links Where Parent="&parent, cnDB, adOpenStatic

Ik vind er echt niets meer in dat fout lijkt...
en mijn sql lijkt juist ...

P.S. De pagina staat hier http://forpex.no-ip.com/flabbergasted/links.asp
en dit zit er in de database (testgegevens)
Link_ID Naampje Beschrijving Poster Datum Tijd Parent Url
1 Flabbergasted Links iets 1 0
2 Andere Links iets anders 1 0
3 Flabbergasted op StuBru Site 1 4 http://www.stubru.be/stub...en/kalender_02/index.html
4 Stubru 1 1 http://www.stubru.be
5 Bockstael 1 2 http://www.bockstael.be
6 Radio donna 1 1
7 Kalender radio donna 1 6

[ Voor 24% gewijzigd door Verwijderd op 23-01-2004 20:16 ]


  • faabman
  • Registratie: Januari 2001
  • Laatst online: 08-08-2024
mag ik trouwens weten waarom je doet

set rij = nothing???

rij is toch helemaal geen object?? is volgens mij een array...

Op zoek naar een baan als Coldfusion webdeveloper? Mail me!


  • Gert
  • Registratie: Juni 1999
  • Laatst online: 05-12-2025
Je doet set rsData = Nothing na de eerste execute en daarna vertel je nooit meer dat rsData een RecordSet object moet zijn.

Verwijderd

Topicstarter
Bedankt :) het begint +- te werken, nog een paar foutjes eruit halen maar het begint erop te lijken.
Ik zal morgen de code posten (afgewerkte) zodat men ze via de search kan vinden...

Verwijderd

Topicstarter
Zoals beloofd, hier de code :)
Ik gebruik wel een error-afhandeling om de tree te bouwen, maar in ieder geval: hij werkt en ik heb er genoeg van mee zitten kl*ten...
ASP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Set cnDB = OpenDB()
Dim rsData         ' As ADODB.Recordset
Dim strSQL        ' As String
Dim strURL        ' As String

Set rsData = Server.CreateObject("ADODB.Recordset")
Response.write(geefchilds(0,0))
Function geefchilds(parent, level)
Dim arrDBData


    rsData.open "SELECT Naampje, Parent, Link_ID From Links Where Parent="&parent& " Order By Naampje", cnDB, adOpenStatic
On Error Resume Next
    arrDBdata = rsData.GetRows()
    iRecFirst   = LBound(arrDBData, 2)
    iRecLast    = UBound(arrDBData, 2)
rsData.close
    For I = iRecFirst To iRecLast
        Response.write("<br/>"& herhstring("&nbsp;&nbsp;&nbsp;", cint(level)) & arrDBData(0,I))
        Call geefchilds(arrDBData(2,I), level+1)
    Next
If Err.number <> 0 Then
End If
geefchilds=""
End Function
Set rsData = nothing

  • faabman
  • Registratie: Januari 2001
  • Laatst online: 08-08-2024
heel mooi dat je je code gepost hebt, maar mag ik opmerken dat de manier waarop je nu bezig bent totaal niet efficient is...

once more een paar puntjes:
- je opent je recordset heel vaak en sluit hem helemaal niet...
- je hebt een if staan waar je niets mee doet (if err.number <> 0)
- je declareert niet al je waarden (iRecFirst / iRecLast)
- iRecFirst en iRecLast zijn helemaal niet nodig als je neerzet For I = 0 To Ubound(arrDBData, 2)
- 'Call' zal wel uit vb afkomstig zijn... ik heb het in ieder geval nog nooit in ASP gezien
- geefchilds = "" is volgens mij helemaal niet nodig... je benoemt hem immer nergens...

oplossing, zie mijn eerder geposte verhaal

Op zoek naar een baan als Coldfusion webdeveloper? Mail me!


  • Gert
  • Registratie: Juni 1999
  • Laatst online: 05-12-2025
Je kan zeker niet zo goed lezen want er staat wel degelijk rsData.close :o

Bij een call naar een functie of sub die geen waarde returned is Call functie/sub wel degelijk nodig in vbscript.

Bij een for x to UBound(arrray) loop zal bij elke iteratie gekeken worden wat de maximum lengte is van de array. Gezien de array niet in grootte veranderd tijdens de iteratie is het nuttig een variabele te gebruiken waar je eenmalig de lengte van de array aan toe kent.

In regel 7 doet hij Response.Write(geefchilds(0,0))
De geefchilds functie zal dus een waarde moeten hebben aan het einde wat hij doet door er "" aan toe te kennen in regel 24.

Het is inderdaad wel nuttig om Option Explicit te gebruiken zodat elke variabele netjes gedeclareerd wordt.

  • faabman
  • Registratie: Januari 2001
  • Laatst online: 08-08-2024
Gert schreef op 25 januari 2004 @ 09:58:
Je kan zeker niet zo goed lezen want er staat wel degelijk rsData.close :o

Bij een call naar een functie of sub die geen waarde returned is Call functie/sub wel degelijk nodig in vbscript.
8)7 snelheid en lezen gaat meestal nie echt samen

maar, van call heb ik nog nooit gehoord / nooit gebruikt, OOK niet bij functies die geen waarde teruggeven (maar alleen wat uitvoeren)
knip

In regel 7 doet hij Response.Write(geefchilds(0,0))
De geefchilds functie zal dus een waarde moeten hebben aan het einde wat hij doet door er "" aan toe te kennen in regel 24.

knip
daar heb je gelijk in, maar, waarom een response.write geven wanneer een functie geen waarde terug geeft :? roep hem dan gewoon aan zonder de response.write

Op zoek naar een baan als Coldfusion webdeveloper? Mail me!


Verwijderd

Topicstarter
Ah ja nu je het zegt ;)
Ik had mijn uiteindelijke code een beetje teruggebracht tot iets algemeners en daardoor staat er response.write.
Op mijn pagina wordt door geefchilds telkens een variabele aangevuld in plaats van direct response.write te doen.
Zo krijgt geefchilds wel echt een waarde en is het dus een echte functie.
Bij het weergeven van mijn pagina hoef ik dan enkel even Response.write(geefchilds(0,0)) te doen en ik heb de hele tree.

Dat van die error is nodig voor als ik op het einde van een subtree kom.
irecfirst, ireclast... mierenneuker >:) gewoon vergeten

[ Voor 14% gewijzigd door Verwijderd op 25-01-2004 14:51 ]


  • Myrdhin
  • Registratie: April 2000
  • Laatst online: 27-05 14:56
Waarschijnlijk komt het stukje code uit dit artikel:
http://www.sitepoint.com/article/1105

Maar kijk eens verder. Er staat een andere oplossing in waarmee je met 1 query een complete tree kunt terughalen.

Verwijderd

Ik maak meestal gebruik van een recursieve sub.

Een verkorte versie die ik wel eens gebruik:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%
Sub display(bernr, level)
  if (level < 8) Then
    Response.Write "<UL>"
    Set RS = Server.CreateObject("ADODB.RecordSet")
    if bernr = 0 then Sorter = "DESC"
    if bernr <> 0 then Sorter = "ASC"
    SQL = "SELECT * FROM Message ORDER BY ID " & Sorter & ";"
    rs.Open SQL, Conn, 3, 3
    While Not rs.eof And level <>1
      Response.Write "<li><A HREf=""" & ScriptName &_
        "?ID=" & rs("ID") & """>" &_
        Left(rs("Subject"), 35) & "</a></li>" & VbCrLf
      Call Display(RS("ID") ,level + 1)         
      Rs.Movenext
      if Not RS.Eof And level = 1 Then Response.Write  VBCrLf
    Wend
    Rs.Close
    Set RS=Nothing
    Response.Write "</UL>"
  End if
End sub
%>


<% Call Display(0,1) %>
Pagina: 1