Avatar billede zeusdk Nybegynder
18. marts 2003 - 14:52 Der er 48 kommentarer og
2 løsninger

Fjern forekomster i streng

Hej

Jeg har følgende side: http://www.selvet.dk/exp.asp

På den side skal et script undersøge en streng af datoer. Den skal fjerne datoen "03-05-2003", fordi det er den dato, som forekommer to gange (eller derover).

Men det gør den ikke, se resultatet ved at klikke på linket.

_______________KODEN FRA SIDEN____________________


<%

Set myConn=Server.CreateObject("ADODB.Connection")
myConn.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="+server.Mappath("/db/selvet.mdb"))
   
strSQL = "SELECT datopublish FROM search WHERE datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# order by datopublish"

set rs = myConn.execute(strSQL)
   
do while not rs.EOF
    if isDate(rs("datopublish")) then
        myDates = myDates & rs("datopublish") & ", "
    End If
rs.MoveNext
Loop
       
if right(myDates, 2) = ", " then
    myDates = left(myDates,len(myDates)-2)
end if

response.write "<br>Skal undersøge: <br>" & myDates & "<br><br><br>"
response.write "<br>Finder (fejlagtigt): <br>"
   
myDateArr = Split(myDates,",")

dato = date ()
datoSlut = DateAdd("yyyy",1,date)
i = 0
do while dato <= datoSlut
    if countDates(myDateArr(i), myDates) < 2 and CDate(myDateArr(i)) <> CDate(dato) then
        response.write myDateArr(i) & ", "
    else
        i = i + 1
        if i > ubound(myDateArr) then i = ubound(myDateArr)
    end if
    dato = dateAdd("d",1,dato)
loop

response.write "<br><br>Hvis det var rigtigt, havde den fundet:<br> 18-03-2003, 19-03-2003, 20-03-2003, 21-03-2003, 22-03-2003, 23-03-2003, 24-03-2003, 25-03-2003, 26-03-2003, 27-03-2003, 28-03-2003, 29-03-2003, 30-03-2003, 31-03-2003, 01-04-2003, 02-04-2003, 03-04-2003, 04-04-2003, 05-04-2003, 06-04-2003, 07-04-2003, 08-04-2003, 09-04-2003, 10-04-2003, 11-04-2003, 12-04-2003, 13-04-2003, 14-04-2003, 15-04-2003, 16-04-2003, 17-04-2003, 18-04-2003, 19-04-2003, 20-04-2003, 21-04-2003, 22-04-2003, 23-04-2003, 24-04-2003, 25-04-2003, 26-04-2003, 27-04-2003, 28-04-2003, 29-04-2003, 30-04-2003, 02-05-2003, 04-05-2003, 05-05-2003, 06-05-2003, 08-05-2003, 09-05-2003, 15-05-2003, 19-05-2003, 26-05-2003, 27-05-2003, 01-06-2003, 06-06-2003, 07-06-2003, 26-06-2003, 18-08-2003, 31-08-2003, 05-09-2003"

response.write "<br><br>Det skulle bare være de værdier, som forekom to gange eller derover... i dette tilfælde: 03-05-2003, 03-05-2003 der var blevet fjernet fra ovenstående liste af datoer."

Function countDates(patrn, strng)

    Dim regEx, Match, Matches  ' Create variable.
      Set regEx = New RegExp  ' Create regular expression.
      regEx.Pattern = patrn  ' Set pattern.
      regEx.IgnoreCase = True  ' Set case insensitivity.
      regEx.Global = True  ' Set global applicability.
      Set Matches = regEx.Execute(strng)  ' Execute search.
      For Each Match in Matches  ' Iterate Matches collection.
        intMatchCount = intMatchCount + 1
      Next
      countDates = intMatchCount
     
End Function

%>
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 14:55 #1
strSQL = "SELECT DISTINCT datopublish FROM search  ..."

...måske
Avatar billede zeusdk Nybegynder
18. marts 2003 - 14:57 #2
...men så ved scriptet jo ikke, hvornår en værdi forekommer 2 gange... right?
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 14:59 #3
Korrekt, det så jeg ikke. Men så

strSQL = "SELECT datopublish,count(*) AS antal FROM search  ... GROUP BY datopublish"

Lad blot SQL-maskinen knokle - den elsker det
Avatar billede dk_akj Nybegynder
18. marts 2003 - 15:00 #4
Hvad med at overføre datoer til et sorteret array ??

' hent alle datoer sorteret stigende
Set rs_id = conn.execute ("select datopublish FROM search ......" order by datopublish asc)

' overfør til array
myarray = rs_id.getrows()

' hvor mange er der ??
myMax = ubound(myarray,2)


' loop gennem arrayet
for i = 1 to mymax

    ' pos x i array ?
    newdate = myarray(0,i)

    check om den er det samme som sidste loop
    if newdate = lastdate then
        ' det er den samme som sidst
        ' slet eller hvad der nu skal ske
    else
        ' datoen er forskellig fra den sidste
    end if

    ' husk dato til næste loop
    lastdate = myarray(0,i)

next
//akj
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 15:01 #5
Øh ... du skal vide hvilke værdier der forekommer 2 gange? Eller du skal
bare fjerne dem? Du kan udvide mit forslag med "...WHERE antal>2..."
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:02 #6
>Øh ... du skal vide hvilke værdier der forekommer 2 gange? Eller du skal
bare fjerne dem?
De skal bare fjernes hårdt og brutalt. Jeg prøver lige.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:04 #7
Er det sådan du mener... jeg har kun indsat et "and":

strSQL = "SELECT datopublish,count(*) AS antal FROM search WHERE antal>2 and datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# GROUP BY datopublish"
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 15:05 #8
Øh .. mit spørgsmål formuleret korrekt. Skal begge fjernes hvis
en dato forekommer 2 gange - eller kun den ene?
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 15:05 #9
Ja, men antal>2 er nok forkert .... :)
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:06 #10
>Skal begge fjernes hvis en dato forekommer 2 gange
Begge skal fjernes
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 15:09 #11
antal=1  lyder så rigigst
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:09 #12
Men der kan også være datoer, som forekommer mere end 2 gange, og de skal også fjernes på samme måde.... slutresultatet skal bare en liste bestående af datoer, som enten ikke er blevet reserveret endnu eller datoer, som kun er blevet reserveret en gang.
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 15:11 #13
ikke reserveret? HVordan ser man det?
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:18 #14
Hvis du går ind på linket og ser under "Skal undersøge:", så finder du alle de datoer, som brugeren ikke må vælge, fordi de er blevet reserevet 0 gange eller 1 gang ;) ....

>>Skal begge fjernes hvis en dato forekommer 2 gange
>Begge skal fjernes
Undskyld... min fejl... det er kun den ene forekomst, der skal fjernes, men havde datoen f.eks. forekommet 3 gange, så skulle de 2 gentagelser af den fjernes.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:19 #15
reserevet = reserveret
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:22 #16
>fordi de er blevet reserevet 0 gange eller 1 gang ;) ....
Nu vrøvler jeg igen. Jeg prøver lige igen:

Hvis du går ind på linket og ser under "Skal undersøge:", så finder du alle de datoer, som brugeren ikke må vælge, fordi de er blevet reserveret.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:24 #17
Hvis sql-scriptet bare lige pillede gentagelserne ud myDates, så var alt, som det skulle være.
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 15:29 #18
Man kan få gentagelserne direkte fra ét SQL-kald som er:

SELECT datopublish,count(*) AS antal FROM search  ... GROUP BY datopublish AS antal HAVING antal > 1

Herefter er det bare at slette alle records hvor datoerne i resultatet fra ovenstående er registreret.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:56 #19
Nu har jeg den... men jeg ved ikke helt, hvordan jeg kan realisere den. Hvordan definerer jeg "antal" i følgende sætning?

strSQL = "SELECT DISTINCT datopublish,count(*) AS antal FROM search WHERE antal<1 and datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# GROUP BY datopublish"

Hvis sql-sætningens output kun bliver: "02-05-2003" Så ved jeg, hvordan jeg skal løse resten.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 15:57 #20
Antal kendes ikke i forvejen og er ikke skrevet ned i databasen, så hvordan finder jeg det?
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 16:00 #21
"SELECT DISTINCT datopublish,count(*) AS antal FROM search WHERE antal<1 and datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# GROUP BY datopublish HAVING antal > 1"
Avatar billede zeusdk Nybegynder
18. marts 2003 - 16:16 #22
Jamen den kender jo ikke "antal":
No value given for one or more required parameters.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 16:18 #23
Er det ikke også lidt modstridende?
"...WHERE antal<1 and....datopublish HAVING antal > 1"
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 16:22 #24
Jo. Den overså jeg. Her er den rigtige:

"SELECT DISTINCT datopublish,count(*) AS antal FROM search WHERE datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# GROUP BY datopublish HAVING antal > 1"
Avatar billede zeusdk Nybegynder
18. marts 2003 - 16:45 #25
"No value given for one or more required parameters."
Det er sikkert antal, som den ikke kan klare. Men hvor bliver antal defineret hende?
Avatar billede zeusdk Nybegynder
18. marts 2003 - 16:46 #26
hende = henne
Avatar billede erikjacobsen Ekspert
18. marts 2003 - 18:25 #27
Jeg tror ikke du skal have DISTINCT med her
Avatar billede zeusdk Nybegynder
18. marts 2003 - 18:29 #28
Men erikjacobsen - lige meget om jeg tager DISTINCT med eller ej, siger den "No "value given for one or more required parameters." fordi "antal" ikke er defineret. Kan du hjælpe?
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 18:41 #29
Sæt dit script til at skrive SQL'en ud før at den bliver udført.

Tag det udskrevne SQL og post det her, så vi kan se hvad der sker.

Iøvrigt undrer det mig at du har en masse havelåger med. Hvad gør de egentlig?
Avatar billede zeusdk Nybegynder
18. marts 2003 - 18:47 #30
>Tag det udskrevne...
Det gør jeg lige om lidt.

>masse havelåger med
Det er fordi jeg bruger Access, hvis jeg tager dem væk, så virker det ikke. Tro mig :-)
Avatar billede zeusdk Nybegynder
18. marts 2003 - 18:53 #31
Du kan se fejl her: http://www.selvet.dk/exp.asp

<%

Set myConn=Server.CreateObject("ADODB.Connection")
myConn.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="+server.Mappath("/db/selvet.mdb"))
   
strSQL = "SELECT DISTINCT datopublish,count(*) AS antal FROM search WHERE datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# GROUP BY datopublish HAVING antal > 1"
set rs = myConn.execute(strSQL)
response.write "<br>strSQL: " & strSQL & "<br><br>"
   
do while not rs.EOF
    if isDate(rs("datopublish")) then
        myDates = myDates & rs("datopublish") & ", "
    End If
rs.MoveNext
Loop

response.write "<br>myDates: " & myDates & "<br><br>"
       
if right(myDates, 2) = ", " then
    myDates = left(myDates,len(myDates)-2)
end if

response.write "<br>Skal undersøge: <br>" & myDates & "<br><br><br>"
response.write "<br>Finder (fejlagtigt): <br>"
   
myDateArr = Split(myDates,",")

dato = date ()
datoSlut = DateAdd("yyyy",1,date)
i = 0
do while dato <= datoSlut
    if CDate(myDateArr(i)) <> CDate(dato) then
        response.write myDateArr(i) & ", "
    else
        i = i + 1
        if i > ubound(myDateArr) then i = ubound(myDateArr)
    end if
    dato = dateAdd("d",1,dato)
loop

response.write "<br><br>Hvis det var rigtigt havde den kun skrevet 03-04-2003<br>"

%>
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 19:22 #32
Please - gør som jeg beder om:

1) Sæt dit script til at skrive SQL'en ud før at den bliver udført.
2) Tag det udskrevne SQL og post det her, så vi kan se hvad der sker.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 19:29 #33
Sådan:
SELECT DISTINCT datopublish,count(*) AS antal FROM search WHERE datopublish >= #2003-3-18# AND datopublish < #2004-3-18# GROUP BY datopublish HAVING antal > 1
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 19:36 #34
Det ser helt rigtigt ud. Det kan altså godt være at Access ikke understøtter HAVING-udtrykket. Prøv at fjerne DISTINCT (som Erik også foreslår).
Avatar billede zeusdk Nybegynder
18. marts 2003 - 19:42 #35
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 19:46 #36
Vil det sige at SQL-forespørgslen nu bliver kørt uden at den brokker sig over syntaksfejl?
Avatar billede zeusdk Nybegynder
18. marts 2003 - 19:47 #37
ja, men den kommer ikke med det rigtige resultat.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 19:52 #38
Sql-sætningen skulle kun finde de værdier, som forekommer mere end 1 gang. Men sætningen finder fejlagtigt alle forekomsterne.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 19:58 #39
Og man må desværre ikke skrive:
strSQL = "SELECT DISTINCT datopublish,count(*) AS antal FROM search WHERE antal > 1 and datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# GROUP BY datopublish"

For så siger den:
"No value given for one or more required parameters."
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 20:20 #40
Hvad angår "WHERE antal > 1": det er ikke så underligt at du ikke må det, for det er ikke gyldig SQL-syntaks.

Hvad angår det som dit script skriver ud: Så vidt jeg kan se finder den slet ikke noget. Skal datoerne ikke skrives ud før teksten "Skal undersøge"?
Avatar billede zeusdk Nybegynder
18. marts 2003 - 20:39 #41
Jeg ved ikke lige, hvad jeg skal svare på dit spørgsmål... men anyway... having-udtrykket virker åbenbart ikke med Access...pis. Men så må vi da vi dele den op i to sorteringer, nemlig en grov-sortering ved hjælp af sql og en fin-sortering ved hjælp af et script.

Derfor følgende kode:

<%

Set myConn=Server.CreateObject("ADODB.Connection")
myConn.Open ("PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="+server.Mappath("/db/selvet.mdb"))

strSQL = "SELECT datopublish FROM search WHERE datopublish >= #"  & Year(date) & "-" & month(date) & "-" & Day(date) &  "# AND datopublish < #" & Year(dateadd("yyyy",1,date)) & "-" & month(dateadd("yyyy",1,date)) &  "-" & Day(dateadd("yyyy",1,date)) & "# order by datopublish"
set rs = myConn.execute(strSQL)
response.write "<br>strSQL: " & strSQL & "<br><br>"
   
do while not rs.EOF
    if isDate(rs("datopublish")) then
        myDates = myDates & rs("datopublish") & ", "
    End If
    rs.MoveNext
Loop
   
if right(myDates, 2) = ", " then
    myDates = left(myDates,len(myDates)-2)
end if

response.write "<br>Skal undersøge: <br>" & myDates & "<br><br><br>"
response.write "<br>Finder: <br>"
   
myDateArr = Split(myDates,",")

dato = date ()
datoSlut = DateAdd("yyyy",1,date)
i = 0
do while dato <= datoSlut
    if countDates(myDateArr(i), myDates) < 2 AND CDate(myDateArr(i)) <> CDate(dato) then
        response.write myDateArr(i) & ", "
    else
        i = i + 1
        if i > ubound(myDateArr) then i = ubound(myDateArr)
    end if
    dato = dateAdd("d",1,dato)
loop

response.write "<br><br>Hvis det var rigtigt havde den kun skrevet 03-05-2003<br>"

Function countDates(patrn, strng)

    Dim regEx, Match, Matches  ' Create variable.
      Set regEx = New RegExp  ' Create regular expression.
      regEx.Pattern = patrn  ' Set pattern.
      regEx.IgnoreCase = True  ' Set case insensitivity.
      regEx.Global = True  ' Set global applicability.
      Set Matches = regEx.Execute(strng)  ' Execute search.
      For Each Match in Matches  ' Iterate Matches collection.
        intMatchCount = intMatchCount + 1
      Next
      countDates = intMatchCount
     
End Function

%>

Som giver følgende resultat:
http://www.selvet.dk/exp.asp
Avatar billede zeusdk Nybegynder
18. marts 2003 - 20:44 #42
Rettelse fra:
Hvis det var rigtigt havde den kun skrevet 03-05-2003

Til:
Det havde været rigtigt, hvis den havde skrevet alle datoerne, undtagen 03-05-2003
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 20:51 #43
Du *SKAL* have "HAVING antal > 1" med før at min taktik virker. Hvis databasen ikke acceptere det, er du nødt til at sortere efter antallet og kværne igennem resultatet selv.
Avatar billede zeusdk Nybegynder
18. marts 2003 - 20:53 #44
Det lyder fornuftigt, men kan du så ikke lige skrive det på en måde så min sql-maskine gider at æde det ;)
Avatar billede zeusdk Nybegynder
18. marts 2003 - 22:38 #45
Jeg har brug for et hurtigt svar, så jeg bliver desværre nødt til at lukke spørgsmålet nu. Gider du at trykke svar så du kan få nogle points :-)
Avatar billede _darkstar_ Nybegynder
18. marts 2003 - 23:01 #46
Hvis det ikke virker er du strengt taget ikke nødt til at give nogen points. Hvad for databaseserver kører du?
Avatar billede zeusdk Nybegynder
18. marts 2003 - 23:05 #47
Jeg bruger access... mere ved jeg ikke om den.

I skal alle være velkommen på http://exp.dk/spm/330512 :-)
Avatar billede erikjacobsen Ekspert
19. marts 2003 - 05:08 #48
Har du oprettet spørgsmålet mere end én gang? Det må du ikke.
Avatar billede zeusdk Nybegynder
19. marts 2003 - 10:06 #49
Jeg oprettede et spørgmål, som tager udgangspunkt i en grov/fin-sortering, som du ikke kunne hjælpe mig med. Desværre strandede vores sql-tilgang... pga. min sql-maskine.... havde sql'en bare virket, så var jeg i gang med noget helt andet nu. Jeg lukkede ikke dette spørgsmål, fordi du, erikjacobsen, ikke havde trykket svar, men nu lukker jeg det altså, så der ikke opstår problemer. Hvis du vil have nogle points, så trykker du blot svar i det andet spg. Mange tak for hjælpen :-)
Avatar billede erikjacobsen Ekspert
19. marts 2003 - 12:25 #50
Nej, herregud, jeg skal ikke have point - dem samler jeg nu ikke på.
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