webForumDet fria alternativet

Rekursiv funktion?

ASP

30 svar · 1 278 visningar · startad av Jesper T

Medlem sedan nov. 20017 144 inlägg
Frågan#1

Försöker att skapa en "ul och li"-lista, men mina hjärnceller står still.
Skulle det inte gå att utgå ifråd detta må någe vis?

Sub LinkTree(intParent,intIndent) :	Dim X,Z
		For X = 0 To Ubound(arrLinks,2)		
			If arrLinks(1,X) = intParent then
			
					IF intIndent < 0 then 
				 		Response.Write "<li>"& arrLinks(2,X) &"</ul>"& VbCrlf
					ELSE	
					For Z = 1 To intIndent
					Response.Write Z &" * "& intIndent
					next						
						Response.Write("<li><a href=""javascript:void(0);"">"& arrLinks(2,X)& "</a></li></ul>"& VbCrlf)
					END IF
					
				Call LinkTree(arrLinks(0,X),intIndent + 1)
			End If
		Next 
		
End Sub
Medlem sedan apr. 20031 660 inlägg
#2

HEJ!

Menar du riktiga li/ul, dvs jag ser de ej i koden? Eller det är en liknelse för din meny?

I vilket fall, kolla vad som blir resultatet i koden, justera efter det/återkom till oss.

Medlem sedan nov. 20017 144 inlägg
#3

Har satt in några nu men det hjälper ju föga.

Jag satt med detta i fyra timmar i går och har pillat in ul och li-taggar men det funkar inte. Jag förstår att det är något som fattas funktionen. Har googlat: recursive ASP function li ul osv. utan något bra resultat.
För FSO så har jag en sådan funktion. Eventuellt så går den att överföra på ngt smidigt sätt till getrows?!

 function GetSubFolders(pfolder)
    Dim sFolders, fldr, fil
    sFolders = "<LI>" & pfolder.Name

    If pfolder.SubFolders.Count > 0 Or pfolder.Files.Count > 0 Then _
        sFolders = sFolders & "<UL>"

    For Each fldr In pfolder.SubFolders
        sFolders = sFolders & GetSubFolders(fldr)
    Next
    
    For Each fil In pfolder.Files
        sFolders = sFolders & "<LI>" & fil.Name & "</LI>"
    Next
    
    If pfolder.SubFolders.Count > 0 Or pfolder.Files.Count > 0 Then _
        sFolders = sFolders & "</UL>"
    
    sFolders = sFolders & "</LI>"

    Set fil = Nothing
    Set fldr = Nothing
    
    GetSubFolders = sFolders
End function
Medlem sedan dec. 20003 887 inlägg
#4

Hur är listan du vill skriva ut sparad? För att göra en rekursiv funktion som skriver ut en trädsstruktur bör man... hmmm... jag förklarar med ett exempel istället :)

tblTree
intNode
intParent
strNamn

Fylld med något i den här stilen

[u]intNode[/u] [u]intParent[/u] [u]strNamn[/u]
   1       0       '1'
   2       0       '2'
   3       0       '3'
   4       1       '1.1'
   5       1       '1.2'
   6       2       '2.1'
   7       6       '2.1.1'
   8       6       '2.1.2'
   9       2       '2.2'
   10      3       '3.1'

Nu ligger det en snygg liten trädstruktur där och för att skriva ut rasket rekursivt kan man antaglien göra så här

Sub PrintTree(intParent)
  Dim objNode, objChild

  strSQL = "SELECT intNode, strNamn FROM tblTree WHERE intParent = " & intParent

  Set objNode = Server.CreateObject("ADODB.Recordset")
  Set objChild = Server.CreateObject("ADODB.Recordset")

  objNode.Open strSQL, objConn

  While Not objNode.EOF
    strSQL = "SELECT 1 FROM tblTree WHERE intParent = " & objNode(0)

    objChild.Open strSQL, objConn

    If objChild.EOF Then
      Response.Write "<li>" & objNode(1) & "</li>"
    Else
      Response.Write "<ul>"

      PrintTree objNode(0)

      Response.Write "</ul>"
    End If

    objChild.Close

    objNode.MoveNext
  Wend

  Set objChild = Nothing
  
  objNode.Close : Set objNode = Nothing
  objConn.Close : Set objConn = Nothing
End Sub

Response.Write "<ul>" & PrintTree(0) & "</ul>"

Jag säger antagligen, eftersom jag inte har testat detta mer än i huvudet... ;) Och detta kanske inte passar ditt behov heller :)

Medlem sedan nov. 20017 144 inlägg
#5

Ja, det ser ju ut att likna det jag söker.
Dock får jag "Type Mismatch", här: -->Response.Write "<ul>" & PrintTree(0) & "</ul>"

Medlem sedan nov. 20017 144 inlägg
#6

Tabellen ser ut som i ditt exempel.

Medlem sedan dec. 20003 887 inlägg
#7

Öhh... jag som tänkte knasigt där...

Reponse.Write "<ul>"
PrintTree 0
Response.Write "</ul>"
Medlem sedan nov. 20017 144 inlägg
#8

Tack, nu rullar den. Men fel....

Medlem sedan nov. 20017 144 inlägg
#9

Det är denna form av struktur jag slulle vilja ha:
http://member.webforum.nu/Jesper T/liul.htm
...och det verkar vara svårt att åstakomma, eller?

Medlem sedan dec. 20003 887 inlägg
#10

Nädå... det är bara att lägga in en extra parameter för funktionen

Sub PrintTree(intParent[b], intDepth[/b])
  Dim objNode, objChild

  strSQL = "SELECT intNode, strNamn FROM tblTree WHERE intParent = " & intParent

  Set objNode = Server.CreateObject("ADODB.Recordset")
  Set objChild = Server.CreateObject("ADODB.Recordset")

  objNode.Open strSQL, objConn

  While Not objNode.EOF
    strSQL = "SELECT 1 FROM tblTree WHERE intParent = " & objNode(0)

    objChild.Open strSQL, objConn

    If objChild.EOF Then
      Response.Write [b]Space(intDepth * 4) & [/b]"<li>" & objNode(1) & "</li>"
    Else
      Response.Write "<ul>"

      PrintTree objNode(0, [b]intDepth + 1[/b])

      Response.Write "</ul>"
    End If

    objChild.Close

    objNode.MoveNext
  Wend

  Set objChild = Nothing
  
  objNode.Close : Set objNode = Nothing
  objConn.Close : Set objConn = Nothing
End Sub

Reponse.Write "<ul>"
PrintTree 0, 0
Response.Write "</ul>"

Inga större förändringar med andra ord :)

Medlem sedan nov. 20017 144 inlägg
#11

space() verkar bara trixa till tomrum i källkoden.

Medlem sedan dec. 20003 887 inlägg
#12

Ahh... det är ju förmodligen därför att <li>-elementen stör till det antar jag. Om du byter ut list-elementen mot ett tecken eller en liten bild så får du nog se vad jag hade tänkt att det skulle se ut som.

red.
Det Space(x) gör är returnerar en sträng med x mellanslag.

Medlem sedan nov. 20017 144 inlägg
#13

Åhhh, det var inte lätt detta. Jag är tebax på ruta ett. Om det inte blir li och ul taggar enligt strukturen på denna sida:
http://member.webforum.nu/Jesper T/liul.htm
så kommer inte javascriptet att funka.
"Jag" gjorde en variant med getrows, och den ritar ju ut strukturen rätt iaf. :)

Sub LinkTree(intParent,intIndent) :	Dim X,Z
		For X = 0 To Ubound(arrLinks,2)		
			
			If arrLinks(1,X) = intParent then
					
					For Z = 1 To intIndent
					Response.Write "-----"
					next
					
					IF len(arrLinks(3,X)) > 3 then
						Response.Write("<span><a href="""& arrLinks(3,X) &""">"& arrLinks(2,X)& "</a></span><br>"& VbCrlf) 
					ELSE	
						Response.Write "<span>"& arrLinks(2,X) &"</span><br>"& VbCrlf
					END IF
				Call LinkTree(arrLinks(0,X),intIndent + 1)
			End If
		
		Next 
End Sub
Medlem sedan jan. 20032 285 inlägg
#14

Det varkar ju som om Engine^s kod inte funkar riktigt, så jag kan väl bidra med den jag skrev nu i brist på annat?
Har bytt ut namnet på tabellen till tblNodes och kolumnerna till nodeId, nodeParent och nodeText, annars är det ingen skillnad i databasdesignen.

<%
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("db.mdb")

Sub PrintTree(intParent)
  strSQL = "SELECT nodeId, nodeParent, nodeText FROM tblNodes WHERE nodeParent = " & intParent
  Set objRubrik = objConn.Execute(strSQL)

  Response.Write("<ul>" & vbCrLf)

  Do Until objRubrik.EOF
    Response.Write("<li>" & objRubrik(2) & "</li>" & vbCrLf)
    strSQL = "SELECT nodeParent FROM tblNodes WHERE nodeParent = " & objRubrik(0)
    Set objNode = objConn.Execute(strSQL)

    If NOT objNode.EOF Then
      PrintTree objNode(0)
    End If

    objNode.Close : Set objNode = Nothing
    objRubrik.MoveNext
  Loop

  objRubrik.Close : Set objRubrik = Nothing
  Response.Write("</ul>")
End Sub

PrintTree 0

objConn.Close : Set objConn = Nothing
%>
Medlem sedan nov. 20017 144 inlägg
#15

Jag fick till Engine^s sub. Men ul och li-taggarna hamnar ändå på fel ställe.

Medlem sedan dec. 20003 887 inlägg
#16

Jesper T skrev:

Jag fick till Engine^s sub. Men ul och li-taggarna hamnar ändå på fel ställe.

Hur ser det ut då? Det kanske är enkelt att fixa till.

Medlem sedan nov. 20017 144 inlägg
#17

Ja det blir ju bara:

<ul>
<li></li>
<li></li>
</ul>

Och i det inflikade exemplet så är det lite mer komplext:

      <ul>
        <li class="toggle">Games
        <ul>
          <li class="toggle">Commodore 64
          <ul>
            <li class="toggle">Adventure
            <ul>
              <li>Curse of Sherwood, the</li>
              <li>Defender of the Crown</li>
              <li>Last Ninja, the</li>
            </ul>
            </li>
            <li class="toggle">Platform
            <ul>
...osv

:)

Medlem sedan jan. 20032 285 inlägg
#18

/red Missuppfattade allt. ;) Glöm bort!

Medlem sedan dec. 20003 887 inlägg
#19

Jag brukar aldrig använda mig av list-element, men skriver du ut rasket såhär kanske det blir bättre. Om inte så är det ju bara att testa flytta runt lite bland <li>- och <ul>-taggarna :)
Med min bristande kunskap om dessa listelement skulle jag kunna gissa på att det är helt onödigt att använda Space()-funktionen.

Sub PrintTree(intParent, intDepth)
  Dim objNode, objChild

  strSQL = "SELECT intNode, strNamn FROM tblTree WHERE intParent = " & intParent

  Set objNode = Server.CreateObject("ADODB.Recordset")
  Set objChild = Server.CreateObject("ADODB.Recordset")

  objNode.Open strSQL, objConn

  While Not objNode.EOF
    strSQL = "SELECT 1 FROM tblTree WHERE intParent = " & objNode(0)

    objChild.Open strSQL, objConn

    If objChild.EOF Then
      Response.Write Space(intDepth * 4) & "<li>" & objNode(1) & "</li>"
    Else
      Response.Write "<li>" & Space(intDepth * 4) & "<ul>" & objNode(1)

      PrintTree objNode(0), intDepth + 1

      Response.Write "</ul></li>"
    End If

    objChild.Close

    objNode.MoveNext
  Wend

  Set objChild = Nothing
  
  objNode.Close : Set objNode = Nothing
  objConn.Close : Set objConn = Nothing
End Sub

Reponse.Write "<ul>"
PrintTree 0, 0
Response.Write "</ul>"
Medlem sedan nov. 20017 144 inlägg
#20

Ehhh....

"<li>" & objRubrik(2) & "</li>"

Kan ju knappast bli :

<li>Games 
<ul>

;)

411 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
127 ms — deklarationer (db)
0 ms — hämta statistik (cache)
281 ms — hämta tråd, inlägg och bilagor (db)
123 ms — ändringar (db)