Avatar billede rille101 Nybegynder
23. april 2010 - 14:10 Der er 18 kommentarer

subscript fejl i løkke

Hej! Jeg prøver på at lsve en løkke, der opretter checkbokse ud fra en fastsat værdi (stations)
De checkbokse der bliver oprettet skal markeres, HVIS stationsnummeret figurerer i databasefeltet "slides.station"
"slides.station" indeholder værdier som f.eks. 1, 2, 5, 6 osv.

Den det jeg har lavet virker ikke!
Jeg får fejlen:
   

Microsoft VBScript runtime error '800a0009'
Subscript out of range: '1'
redigerslides.asp, line 491

491 indeholder: if counter = MyArray(arrayCounter) Then

Dette er mine koder, hvad gør jeg forkert?


Set myConn = Server.CreateObject("ADODB.Connection")
myConn.open(sConn)

set RSslides=Server.CreateObject("ADODB.recordset")
RSslides.Open "SELECT * FROM slides WHERE id = "& request.querystring("id") &" ORDER by prioritet", myConn


dim stations
stations = 3

dim ttlDefault
ttlDefault = 20


<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
                              <%
                             
              counter = 1
While counter =< stations
%>
<td width="20%" ><table width="100%" class="kontrol-indholdstekst" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td height="25">
      <%
    MyArray = split(RSslides.Fields.Item("station").Value,",")
arrayCounter = 1
While counter <= stations
  if counter = MyArray(arrayCounter) Then
    response.write "Skærm "& counter &"<input name=""station"" type=""checkbox"" value="" "& counter & """ checked=""checked"" />&nbsp;&nbsp;&nbsp;"
    arrayCounter = arrayCounter + 1
  else
    response.write "Skærm "& counter &"<input name=""station"" type=""checkbox"" value="" "& counter & """ />&nbsp;&nbsp;&nbsp;"
    arrayCounter = arrayCounter + 1
  end if
  counter = counter + 1
wend
%>
    </td>
  </tr>
</table>
Avatar billede softspot Forsker
23. april 2010 - 14:32 #1
Husk at arrays er nulbaseret i VBScript, så du skal starte med arrayCounter = 0 og så skal dine grænsecheck være < stations og <= stations.

Jeg er heller ikke helt med på at din indre løkke baserer sig på samme tæller og slutkriterium som den ydre. Skal den indre løkke ikke betinges af arrayCounter og ikke af counter?

Altså noget i stil med dette:

MyArray = split(RSslides.Fields.Item("station").Value,",")
arrayCounter = 0
While arrayCounter < stations
  if counter = MyArray(arrayCounter) Then
Avatar billede softspot Forsker
23. april 2010 - 14:34 #2
Ups! Der var lige en lille betydningsmæssig fejl i foregående indlæg. Følgende pasus

"og så skal dine grænsecheck være < stations og <= stations."

skal naturligvis være

"og så skal dine grænsecheck være < stations og ikke <= stations."

Beklager fejlen.
Avatar billede rille101 Nybegynder
26. april 2010 - 11:44 #3
Jeg har prøvet at ændre koderne som du har foreslået.
Men det giver desværre:

Microsoft VBScript runtime  error '800a0009'
Subscript out of range: 'arrayCounter'
redigerslides.asp, line 491
Avatar billede softspot Forsker
26. april 2010 - 12:21 #4
Hmmm... hvis jeg træder et skridt tilbage og kigge på den overordnede problemstilling, så ville jeg nok vælge at gøre det lidt anderledes (om ikke andet splitte koden lidt op, så der ikke bliver fedetet for mange ting sammen). Noget i stil med dette:

<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
<%
counter = 1
While counter <= stations
%>
    <td width="20%">
      <table width="100%" class="kontrol-indholdstekst" border="0"
              cellspacing="0" cellpadding="0">
        <tr>
          <td height="25">
<%
  response.write "Skærm "& counter
  response.write "<input name=""station"" type=""checkbox"" value=""" & counter & """
  if contains(RSslides("station"), counter) then
    response.write " checked"
  end if
  response.write "/>&nbsp;&nbsp;&nbsp;"
  counter = counter + 1
%>
          </td>
        </tr>
      </table>
    </td>
<%
wend
%>
  </tr>
</table>

Contains-funktionen har jeg så valgt at implementere således. Det kunne også have været gjort med et regulært udtryk, men jeg har valgt iterationsmetoden for at holde kompleksiteten på et lavt niveau.

<%
' undersøger om en kommasepareret streng med tal indeholder et givet tal
function contains(streng, indeholder)
  dim res, arr
  res = false
  arr = split(streng, ",")
  for each itm in arr
    if indeholder = clng(trim(itm)) then
      res = true
      exit for
    end if
  next
  contains = res
end function
%>

Jeg har tilladt mig at ændre lidt på placeringen af start- og sluttags i din tabeller, da det virkede lidt "ufærdigt". Det kan naturligvis også skyldes, at du kun har vist et udpluk af koden og at det hænger godt nok sammen i sin helhed... men du kan nok selv gennemskue hvordan det så skal se ud.
Avatar billede rille101 Nybegynder
26. april 2010 - 13:43 #5
Nu har jeg opsat følgende kode, men får fejlen:

Microsoft VBScript runtime  error '800a005e'
Invalid use of Null: 'split'
redigerslides.asp, line 484

Den kan fint skelne mellem, om der skal være et check i den første checkboks. den begynder også at indlæse checkboks 2 for den skriver rigtignok "skærm 2:" og viser en checkboks.

(Hvordan rammer du i øvrigt dine koder ind her på exp.dk?)

              <%
' undersøger om en kommasepareret streng med tal indeholder et givet tal
function contains(streng, indeholder)
  dim res, arr
  res = false
  arr = split(streng,", ")
  for each itm in arr
    if indeholder = clng(trim(itm)) then
      res = true
      exit for
    end if
  next
  contains = res
end function
%>
             
            <table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
<%
counter = 1
While counter <= stations
%>
    <td width="20%">
      <table width="100%" class="kontrol-indholdstekst" border="0"
              cellspacing="0" cellpadding="0">
        <tr>
          <td height="25">
<%
  response.write "Skærm "& counter
  response.write "<input name=""station"" type=""checkbox"" value=""" & counter & """"
  if contains(RSslides("station"), counter) then
    response.write " checked"
  end if
  response.write "/>&nbsp;&nbsp;&nbsp;"
  counter = counter + 1
%>
          </td>
        </tr>
      </table>
    </td>
<%
wend
%>
  </tr>
</table>
Avatar billede softspot Forsker
26. april 2010 - 13:57 #6
Jeg vil tro denne rettelse til contains-funktionen vil løse det Null-problem:

<%
' undersøger om en kommasepareret streng med tal indeholder et givet tal
function contains(streng, indeholder)
  dim res, arr, itm
  res = false
  arr = split(streng & "",", ")
  for each itm in arr
    if indeholder = clng(trim(itm)) then
      res = true
      exit for
    end if
  next
  contains = res
end function
%>

Indramningen gøres vha. såkaldte BB-codes der fungerer ved at sætte visse HTML-elementer i kantede paranteser i stedet for større end og mindre end. Til indramning af kode skal du benytte div og /div (start- og slut-tags). Se i øvrigt eksempler på BB-codes under tekstfeltet til "Skriv et indlæg" her på siden...
Avatar billede rille101 Nybegynder
26. april 2010 - 14:58 #7
Nu indlæser den siden uden fejl, men det er som om den kun tager højde for checkboks 1.

Uanset om db feltet indeholder 2, 3 eller ej, så bliver de ikke markeret.
Avatar billede softspot Forsker
26. april 2010 - 15:28 #8
Jeg er kommet lidt i tvivl om hvad der egentlig ligger i feltet station for én række i databasen... er det en enkelt værdi, eller er det, som jeg har antaget hidtil, en kommasepareret streng af tal? Hvis et er én enkelt værdi, så skal der nok skiftes til næste række i resultatet (RSslides) og så skal der slet ikke checkes med contains-funktionen.

Kan du prøve at vise nogle eksempler på hvad RSslides indeholder i hver række?

Hvilken datatype er feltet "station" i databasen?
Avatar billede rille101 Nybegynder
27. april 2010 - 15:44 #9
RSslides indeholder følgende felter:
id  (50)                    eks: 1
titel  varchar(50)      eks: fodboldstævne
beskrivelse  text      eks: I dag er der fodboldstævne
ttl  smallint(5)          eks: 20  (slided vises i 20 sek.)
img1  varchar(100)    eks: billedsti\billede.jpg
station  text              eks: 1, 2, 4, 5, 6, 7, 10
Avatar billede softspot Forsker
27. april 2010 - 22:51 #10
Med det afklaret, så er brugen af contains nok ok.

Jeg kan bare ikke rigtig se sammenhænget mellem stations (som du sættes til 3) og det at feltet kan være talrækker som indeholder værdier der er større end 3 - eksempelvis 1,2,4,5,6,7,10, som du viste i indlæg #9.

Desuden forstår jeg heller ikke at du udtrækker et resultat fra databasen, hvoraf du kun bruger første række (der er lagt op til at der skulle være flere, ellers giver en order by vel ikke så meget mening... ellers mangler der i det mindste en SELECT TOP 1 for at spare på datatransporten)...

Kan du ikke forklare lidt mere om hvorfor du mener stations skal være 3 og hvorfor du ikke brugere mere end første række i resultatet?

Desuden kunne jeg godt tænke mig at se nogle helt konkrete data fra din database, for at få vished om at den rent faktisk indeholder noget der falder indenfor de kriterier koden sætter op.
Avatar billede rille101 Nybegynder
28. april 2010 - 13:55 #11
OK.
Undskyld, jeg har glemt at nævne at de 3 stationer er variable. det kunne lige så godt være 20. Det er bare fordi jeg kludrer min konkrete situation sammen med de eksempler jeg har opstillet.

antallet af stationer defineres i en config.asp fil som er included i den side, hvorfra koderne kommer.

Mht. datatransport har du selvfølgelig ret. Den har jeg nu rettet til limit 0,1

Jeg forstår ikke helt med de konkrete data?
Jeg kan godt copy/paste indholdet fra tabellen her på siden, eller vil du have et screenshot?
Avatar billede softspot Forsker
28. april 2010 - 14:10 #12
Det jeg gerne vil sikre mig er at vi ikke jagter fejl i koden, hvis det rent faktisk er datagrundlaget der er årsagen til at koden agerer som den gør. Derfor vil jeg gerne helt konkret vide, hvilke data den situation, du siger "fejler", arbejder med.

Det mest sikre ville vel nok være at udskrive RSslides("station") inden du udskriver resten af siden og så fortælle mig hvad der skrives ud.
Avatar billede rille101 Nybegynder
28. april 2010 - 14:27 #13
OK.
Når jeg laver en response.write(RSslides("station") så får jeg udtrækket:

1, 2, 3 (inkl. mellemrum)
Avatar billede softspot Forsker
28. april 2010 - 15:09 #14
OK, jeg har lige lavet en test på contains og det er ikke umiddelbart der det går galt, så det må være i kaldet til funktionen der sker noget forkert. Jeg har dog en lille ændring til contains, som burde gør den lidt mere fleksibel ifht. håndterng af mellemrum omkring kommaseparatoren. Koden til contains skal se således ud:

<%
' undersøger om en kommasepareret streng med tal indeholder et givet tal
function contains(streng, indeholder)
  dim res, arr, itm
  res = false
  arr = split(streng & "",",")
  for each itm in arr
    if indeholder = clng(trim(itm)) then
      res = true
      exit for
    end if
  next
  contains = res
end function
%>

Mht. kaldet så vil jeg foreslå at du ændrer denne linie:

if contains(RSslides("station"), counter) then

til:

if contains(RSslides("station").Value, counter) then

Jeg ved ikke om det ændrer noget, men det gør i det mindste koden mere eksplicit mht. hvad det er der skal overføres til funktionen. Value er default-property på Field-objektet, men i visse situationer kan VBScript komme i tvivl om hvad det er der skal bruges - objektet eller default-egenskaben - og så vælges objektet efter min bedste overbevisning...
Avatar billede rille101 Nybegynder
28. april 2010 - 15:57 #15
Det gav desværre ingen effekt :-(
Den giver stadigvæk kun udsving ved skærm 1
Avatar billede softspot Forsker
28. april 2010 - 17:28 #16
Det er lidt sært for når jeg tager koden fra dit eget indlæg (#5) og udskifter rsslides("station") med en konstant streng, så ser det for mig ud til at fungere (de tre checkbokse er i det mindste afkrydset). Koden jeg bruger til at teste dette ser således ud (det er det eneste kode jeg har i min ASP-side):

<%
' undersøger om en kommasepareret streng med tal indeholder et givet tal
function contains(streng, indeholder)
  dim res, arr
  res = false
  arr = split(streng,",")
  for each itm in arr
    if indeholder = clng(trim(itm)) then
      res = true
      exit for
    end if
  next
  contains = res
end function
%>
             
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
<%
stationLst = "1, 2, 3"
stations = 3
counter = 1
While counter <= stations
%>
    <td width="20%">
      <table width="100%" class="kontrol-indholdstekst" border="0"
              cellspacing="0" cellpadding="0">
        <tr>
          <td height="25">
<%
  response.write "Skærm "& counter
  response.write "<input name=""station"" type=""checkbox"" value=""" & counter & """"
  if contains(stationLst, counter) then
    response.write " checked"
  end if
  response.write "/>&nbsp;&nbsp;&nbsp;"
  counter = counter + 1
%>
          </td>
        </tr>
      </table>
    </td>
<%
wend
%>
  </tr>
</table>

Så hvis du udskifter den konstante liste med RSslides("station").value, så burde det altså fungere. Hvis ikke så er der noget andet kode på siden som forstyrrer det kode du har vist. Ændringen jeg foreslår ovenfor ser således ud:

stationLst = RSslides("station").Value
Avatar billede rille101 Nybegynder
24. marts 2011 - 13:17 #17
Hej Softspot.
Jeg fik det til at virke.
vil du smide et svar?
Avatar billede softspot Forsker
24. marts 2011 - 14:49 #18
Super! Du får lige et svar :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester