Avatar billede mortenbock Nybegynder
14. februar 2006 - 15:51 Der er 33 kommentarer og
1 løsning

SQL kald i en løkke

Hej Eksperter

Jeg er ved at implementere denne kalender i mit administrationssystem. http://activedeveloper.dk/artikler/default.asp?articleid=37

Nu vil jeg lige høre jeres mening om hvordan man bedst får implementeret en database til den.

I databasen er en række datoer. Disse datoer er "optaget".
Jeg vil have kalenderen til at skrive en dato med rød, hvis den er optaget.

Det jeg tænker på at gøre er (dummycode markeret med '--):

<%
For y = 1 to 6
  If blnLast <> True Then
    '-- hent poster fra database hvor dato = dtmCurDate
    '-- hvis recordset.EOF then
    Response.Write "<tr>"
    '-- ellers Response.Write "<tr style='color: red'>"
    For x = 1 to 7
      Response.Write "<td align=center><font face=verdana size=2>"
      intLoopDay = intLoopDay + 1
      If intLoopDay >= intFirstDay Then
        dtmCurDate = DateAdd("d", intLoopDay-intFirstDay, dtmFirstDate)
        If Month(dtmCurDate) = Month(dtmFirstDate) Then
          If dtmCurDate = dtmToday Then
            Response.Write "<strong><font color=#ff0000>"
          End If
          Response.Write Day(dtmCurDate)
          Response.Write "</strong></td>"
          blnLast = False
        Else
          Response.Write "-</td>"
          blnLast = True
        End If
      Else
        Response.Write "-</td>"
        blnLast = True
      End if
    Next
  End If
Next
Response.Write "</font></td></tr>"
%>


Dette vil jo så lave ca. 30 sql kald på meget kort tid. Er det noget der kan gøres mere effektivt?

Jeg benytter asp/access. Der er pt. ikke mange der skal benytte systemet samtidig, men der må gerne være plads til at vokse.

/Bock
Avatar billede mortenbock Nybegynder
14. februar 2006 - 15:52 #1
hov... det var noget ged... Har markeret hele rækken med rød...

Men håber I forstår det alligevel :)
Avatar billede mortenbock Nybegynder
14. februar 2006 - 15:55 #2
<%
For y = 1 to 6
  If blnLast <> True Then
    Response.Write "<tr>"
    For x = 1 to 7
    '-- hent poster fra database hvor dato = dtmCurDate
    '-- hvis recordset.EOF then
      Response.Write "<td>"
    '-- elelrs  Response.Write "<td style='color: red'>"
      intLoopDay = intLoopDay + 1
      If intLoopDay >= intFirstDay Then
        dtmCurDate = DateAdd("d", intLoopDay-intFirstDay, dtmFirstDate)
        If Month(dtmCurDate) = Month(dtmFirstDate) Then
          Response.Write Day(dtmCurDate)
          Response.Write "</td>"
          blnLast = False
        Else
          Response.Write "-</td>"
          blnLast = True
        End If
      Else
        Response.Write "-</td>"
        blnLast = True
      End if
    Next
  End If
Next
Response.Write "</td></tr>"
%>

Det var vidst bedre....
Avatar billede tofte Juniormester
14. februar 2006 - 16:05 #3
lav et sql kald til at starte med, hvor du finder alle de datoer som er optaget i den måned du kigger på. Du skal ordne opslaget efter dato. Når du så genererer kalenderen skal du hver gang du skriver en dato/dag bare undersøge om datoen findes i recordsettet, hvis ja, så skal den være rød. Håber du forstår hvad jeg mener.
Avatar billede mortenbock Nybegynder
14. februar 2006 - 16:11 #4
Hvordan tester jeg om datoen er i mit recordset?

Jeg har nu sporet det ned til dette:

        If Month(dtmCurDate) = Month(dtmFirstDate) Then
          if dtmCurDate <> CDATE("15-2-2006") then
            Response.Write("<span>")
          else
            Response.Write("<span style='color: red;'>")
          end if

Nu tester den om datoen er 15-2-2006. Mine datoer ligger i et recordset og kan hentes med rs("dato"). Men hvordan tester jeg om dtmCurDate er i det recordset?
Avatar billede mortenbock Nybegynder
14. februar 2006 - 16:29 #5
rs.BOF
do until rs.EOF or optaget = true
  if CDATE(rs("dato")) = dtmCurDate then
    Response.Write("<span style='color: red;'>")
    optaget = true
  else
    optaget = false
  end if
rs.MoveNext
loop
if optaget = false then
  Response.Write("<span>")
end if
Response.Write Day(dtmCurDate)
Response.Write "</span></td>"


Er det noget i den stil?
Avatar billede mortenbock Nybegynder
14. februar 2006 - 16:51 #6
Dette virker, men kan jeg ikke undgå at udføre "set rs = conn.Execute(sql)" hvor eneste gang den skriver en dato? Hvordan "spoler man tilbage" i sit recordset og starter forfra?


<%
set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("../../db/bwm.mdb")
   
sql = "SELECT dato FROM afbud"



For y = 1 to 6
  If blnLast <> True Then
    Response.Write "<tr>"
    For x = 1 to 7
      Response.Write "<td>"
      intLoopDay = intLoopDay + 1
      If intLoopDay >= intFirstDay Then
        dtmCurDate = DateAdd("d", intLoopDay-intFirstDay, dtmFirstDate)
        If Month(dtmCurDate) = Month(dtmFirstDate) Then
            set rs = conn.Execute(sql)
            do until rs.EOF or optaget = true
              if CDATE(rs("dato")) = dtmCurDate then
                Response.Write("<span style='color: red;'>")
                optaget = true
              else
                optaget = false
              end if
            rs.MoveNext
            loop
            if optaget = false then
              Response.Write("<span>")
            end if
            Response.Write Day(dtmCurDate)
            Response.Write "</span></td>"
              blnLast = False
        Else
          Response.Write "-</td>"
          blnLast = True
        End If
      Else
        Response.Write "-</td>"
        blnLast = True
      End if
    Next
  End If
Next
Response.Write "</td></tr>"

rs.close
set rs = Nothing
conn.close
set conn = Nothing

%>
Avatar billede tofte Juniormester
14. februar 2006 - 17:06 #7
du behøver ikke at spole tilbage, da dit recordset er sorteret er det nok kun at løbe det gennem en gang. Jeg fiker lige et eksempel
Avatar billede tofte Juniormester
14. februar 2006 - 17:21 #8
Håber du kan forstå idén
<%
'sætter datoer som er besatte, dette kunne være dit recordset.
myOcc=Array(1,2,6,9)
'myOccPos angiver hvilken værdi i arrayet vi kigger på. Vi starter med at sætte den til arrayets start.
myOccPos=LBound(myOcc)

for myDate = 1 to 31
    'Løkken kører hvis indholdet af vores recordset er mindre end den dato vi ser på, samt vi ikke har EOF(sidste led)
    while ((myOcc(myOccPos)<myDate) AND (myOccPos<UBound(myOcc)))
        'Her kører vi movenext på recordsettet
        myOccPos=myOccPos+1
    wend   
    'Hvis datoen af vores recordset er lig med den dato vi skriver gør vi den FED ellers ikke
    if myOcc(myOccPos)=myDate then
        response.Write " <B>"&myDate&"</B> "
    else
        response.Write " "& myDate & " "
    end if
next

%>
Avatar billede tofte Juniormester
14. februar 2006 - 17:22 #9
Jeg render lige på posthuset men er snart tilbage.
Avatar billede mortenbock Nybegynder
14. februar 2006 - 17:46 #10
så i mit tilfælde bliver det:

while (CDATE(rs("dato")) < dtmCurDate AND NOT rs.EOF)
  rs.MoveNext
wend
if (CDATE(rs("dato")) = dtmCurDate) then
  response.write ("<b>" & dtmCurDate & "</b>")
else
  response.write (dtmCurDate)
end if


jeg er dog ikke helt sikker på "AND NOT rs.EOF"... er det den rigtige måde at skrive det på?
Avatar billede tofte Juniormester
14. februar 2006 - 17:51 #11
jeg er heller ikke helt sikker. Men sæt nogle paranterser for en sikkerhedsskyld
while ((CDATE(rs("dato")) < dtmCurDate) AND (NOT rs.EOF))
hvis det ikke giver syntax fejl virker det.
Avatar billede mortenbock Nybegynder
14. februar 2006 - 18:19 #12
det gav syntaks fejl....
Avatar billede tofte Juniormester
14. februar 2006 - 18:20 #13
hvad skriver den?
Avatar billede tofte Juniormester
14. februar 2006 - 18:21 #14
prøv evt at flytte NOT uden for ( så der står AND NOT (
Avatar billede mortenbock Nybegynder
14. februar 2006 - 18:24 #15
Den skriver: error '80020009'

Den skriver fint nok den første dato der er "optaget", men datoen efter går det galt. altså der hvor den netop skal til at udføre while sætningen.
Avatar billede tofte Juniormester
14. februar 2006 - 18:27 #16
har du mulighed for at uploadet scriptet og databasen et eller andet sted. Jeg kan ikke helt gennemskue det?
Avatar billede mortenbock Nybegynder
14. februar 2006 - 18:38 #17
Det kan jeg desværre ikke. Men det er helt klart i while løkken at fejlen er.
Avatar billede tofte Juniormester
14. februar 2006 - 19:02 #18
men skriver den ikke hvad fejlen er?
Avatar billede mortenbock Nybegynder
14. februar 2006 - 19:09 #19
Den skriver kun error '80020009'
Avatar billede tofte Juniormester
14. februar 2006 - 19:13 #20
jeg kan desværre ikke sige hvor fejlen er, der er ikke så meget andet at gøre end at begynde at fejlsøge systematisk.
Start med at fjerne
if (CDATE(rs("dato")) = dtmCurDate) then
  response.write ("<b>" & dtmCurDate & "</b>")
else
  response.write (dtmCurDate)
end if
og skriv evt kun dtmCurDate osv......
Avatar billede mortenbock Nybegynder
14. februar 2006 - 19:20 #21
Først og fremmest. Det her virker: (bare så jeg selv kan huske det)

For y = 1 to 6
  If blnLast <> True Then
    Response.Write "<tr>"
    For x = 1 to 7
      Response.Write "<td style='text-align: center;'>"
      intLoopDay = intLoopDay + 1
      If intLoopDay >= intFirstDay Then
        dtmCurDate = DateAdd("d", intLoopDay-intFirstDay, dtmFirstDate)
        If Month(dtmCurDate) = Month(dtmFirstDate) Then
            rs.Requery
            do until rs.EOF or optaget = true
                if  (CDATE(rs("dato")) = dtmCurDate) then
                    farve = "style='color: red; font-weight: bold; text-decoration: none;'"
                    optaget = true
                  else
                    farve = "style='text-decoration: none;'"
                    optaget = false
                end if
            rs.MoveNext
            loop
            Response.Write ("<a href='?member=" & Request.QueryString("member") & "&date=" & dtmCurDate & "' " & farve & ">" & Day(dtmCurDate) & "</a>")
            Response.Write "</td>"
            farve = ""
            optaget = ""
              blnLast = False
        Else
          Response.Write "-</td>"
          blnLast = True
        End If
      Else
        Response.Write "-</td>"
        blnLast = True
      End if
    Next
  End If
Next
Avatar billede mortenbock Nybegynder
14. februar 2006 - 19:22 #22
men den spoler recordsettet tilbage ved hver dato, og det burde jo ikke være nødvendigt.
Avatar billede mortenbock Nybegynder
14. februar 2006 - 19:35 #23
Det ser ud til at det er et problem med rs.movenext, for fejlen kommer først frem efter den sidste dato i databasen er løbet igennem. Kan der være et eller andet der forsøger at hente data selvom rs er tom?
Avatar billede tofte Juniormester
14. februar 2006 - 19:40 #24
ja, det kan du have en pointe i

prøv med if not rs.eof omring dine ifsætninger. Noget ala
For y = 1 to 6
  If blnLast <> True Then
    Response.Write "<tr>"
    For x = 1 to 7
      Response.Write "<td style='text-align: center;'>"
      intLoopDay = intLoopDay + 1
      If intLoopDay >= intFirstDay Then
        dtmCurDate = DateAdd("d", intLoopDay-intFirstDay, dtmFirstDate)
        If Month(dtmCurDate) = Month(dtmFirstDate) Then
           
            do until ((CDATE(rs("dato")) >= dtmCurDate) OR (rs.EOF))
                rs.MoveNext
            loop
            if not rs.eof
                if  (CDATE(rs("dato")) = dtmCurDate) then
                    farve = "style='color: red; font-weight: bold; text-decoration: none;'"
                optaget = true
                else
                    farve = "style='text-decoration: none;'"
                    optaget = false
                end if
            end if
           
            Response.Write ("<a href='?member=" & Request.QueryString("member") & "&date=" & dtmCurDate & "' " & farve & ">" & Day(dtmCurDate) & "</a>")
            Response.Write "</td>"
            farve = ""
            optaget = ""
              blnLast = False
        Else
          Response.Write "-</td>"
          blnLast = True
        End If
      Else
        Response.Write "-</td>"
        blnLast = True
      End if
    Next
  End If
Next
Avatar billede mortenbock Nybegynder
14. februar 2006 - 19:49 #25
Problemet er, at når du har sagt "rs.MoveNext" på den sidste post, så er rs.EOF sandt. næste gang For løkken kører igennem, så tester du på rs("dato") igen, hvilket jo ikke eksisterer.

Dvs. der skal på en eller anden måde testes på om rs.EOF er sandt, før man tester på om datoen er >= dtmCurDate

Har jeg ret?
Avatar billede tofte Juniormester
14. februar 2006 - 19:57 #26
har du set mit svar af 14/02-2006 19:40:29
Avatar billede mortenbock Nybegynder
14. februar 2006 - 19:59 #27
jeps, har også afprøvet den, og det giver samme resultat.
Avatar billede tofte Juniormester
14. februar 2006 - 20:03 #28
hvad hvis du fjerner

if not rs.eof
                if  (CDATE(rs("dato")) = dtmCurDate) then
                    farve = "style='color: red; font-weight: bold; text-decoration: none;'"
                optaget = true
                else
                    farve = "style='text-decoration: none;'"
                    optaget = false
                end if
            end if

så får du selvf. ingen datoer, men fejler den så alligevel?
Avatar billede mortenbock Nybegynder
14. februar 2006 - 20:24 #29
Nu er den der:

For y = 1 to 6
  If blnLast <> True Then
    Response.Write "<tr>"
    For x = 1 to 7
      Response.Write "<td style='text-align: center;'>"
      intLoopDay = intLoopDay + 1
      If intLoopDay >= intFirstDay Then
        dtmCurDate = DateAdd("d", intLoopDay-intFirstDay, dtmFirstDate)
        If Month(dtmCurDate) = Month(dtmFirstDate) Then
            if rs.EOF then
                farve = "style='text-decoration: none;'"
                Response.Write ("<a href='?member=" & Request.QueryString("member") & "&date=" & dtmCurDate & "' " & farve & ">" & Day(dtmCurDate) & "</a>")
                Response.Write "</td>"
            else
                if  (CDATE(rs("dato")) = dtmCurDate) then
                    farve = "style='color: red; font-weight: bold; text-decoration: none;'"
                else
                    farve = "style='text-decoration: none;'"
                end if
               
                do until rs.EOF
                    if CDATE(rs("dato")) = dtmCurDate then
                        rs.MoveNext
                    else
                        exit do
                    end if
                loop

               
                Response.Write ("<a href='?member=" & Request.QueryString("member") & "&date=" & dtmCurDate & "' " & farve & ">" & Day(dtmCurDate) & "</a>")
                Response.Write "</td>"
                farve = ""
            end if   
            blnLast = False
        Else
          Response.Write "-</td>"
          blnLast = True
        End If
      Else
        Response.Write "-</td>"
        blnLast = True
      End if
    Next
  End If
Next
Avatar billede mortenbock Nybegynder
14. februar 2006 - 20:27 #30
Så lykkedes det mig at undgå at checke på rs("dato") mens rs.EOF er sandt.
Avatar billede tofte Juniormester
14. februar 2006 - 20:36 #31
det var heldigt
Avatar billede mortenbock Nybegynder
14. februar 2006 - 20:39 #32
Smid et svar. Du viste princippet i løsningen. Tak for hjælpen
Avatar billede tofte Juniormester
14. februar 2006 - 20:42 #33
Det var så lidt
Avatar billede mortenbock Nybegynder
15. februar 2006 - 00:01 #34
Efter en test har det vist sig at der går kuk i den når man går over til en ny måned.

Jeg er derfor gået tilbage til modellen beskrevet i indlægget af 14/02-2006 19:20:56
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