Redazione
a- a+

Sistema di statistiche per siti e blog

Vediamo come fare a creare in modo facile e veloce un sistema di statistiche per monitorare gli accessi di un sito web. Codice ed esempio.

Introduzione
Realizzeremo un sistema di statistiche per monitore gli accessi in un sito web. Un sistema di statistiche dettagliato non permette solo il conteggio degli accessi ad un sito, ma permette la creazione di un completo report che una volta analizzato potrà fornirci utili informazioni sulle abitudine degli utenti. Studieremo quindi WMPStat, il sistema di statistiche OpenSource (codice libero) realizzato dalla community di WebMasterPoint.org, non è ancora una versione perfetta al 100%, ma ottima per lo studio.

Il progetto
Un sistema di statistiche può essere realizzato in vari modi ma le caratteristiche principali che deve avere è ottenere molti dati importanti e realistici nel minor tempo possibile per non rallentare il caricamento della pagina da monitorare. Il software è basato su due pagine principali e un database nel nostro caso Access che permetterà di memorizzare le informazioni raccolte.

Raccolta dei dati
La pagina che raccoglie i dati (lez11_entry.asp) è il cuore dello script e deve essere realizzata nel modo piu' performante possibile, in quanto, una sua lenta esecuzione comporterebbe ad un caricamento della pagina web richiesta piu' lento.

La raccolta dei dati è molto complessa, quindi il codice sarà analizzato a blocchi, in ogni caso è tutto spiegato anche nei commenti.

<%'On Error Resume Next'*****************************************************************' apro la connessione%><!-- #include file="connessione.asp" --><%'*****************************************************************' dichiaro tutte le variabilidim ip, ipOnline, giorno_settimana, data, ora, browser, browserUtilizzato, numeroBrowserdim giorno, mese, anno, ore, minuti, secondidim dataGiorni, dataGiorniOggi, impressionGiorni, visitatoriGiornidim ingresso, provenienzaIngresso, urlIngresso, numeroIngresso, provenienza, url, arrUrlIngressodim oraMedia, accessiMedia, impressionMediadim nomeMediaSett, accessiMediaSett, impressionMediaSettdim pagineViste, arrPagineViste, urlPagineViste, numeroPagineVistedim urlProvenienza, numeroProvenienza, dataProvenienza, data_ultimoProvenienzadim settimana_anno, settimanaAnno, settimanaSettimana, settimanaAccessi, settimanaImpressiondim so, numeroSo, soSodim linkMotore, key, keyMotore, keyStr'*****************************************************************data = Date()ora = Time()settimana_anno = DatePart("ww", data)

Il comando che disabilita l'interruzione dell'esecuzione della pagina al verificarsi di un errore (On Errore Resume Next) è commentato, ma per esser sicuri che lo script non causi il blocco della pagina per un eventuale errore (per esempio l'impossibilità di connettersi al database) è consigliato eliminare il commento. Viene poi inclusa la pagina connessione.asp che ha il compito di aprire la connessione al database, dichiarate tutte le variabili utilizzate e infine memorizzati la data, l'anno e il numero della settimana nell'anno importanti per raccogliere i dati

' ricavo il giorno della settimana di oggigiorno_settimana = Weekday(data)Select Case giorno_settimanaCase "1"giorno_settimana = "Domenica"Case "2"giorno_settimana = "Lunedì"Case "3"giorno_settimana = "Martedì"Case "4"giorno_settimana = "Mercoledi"Case "5"giorno_settimana = "Giovedì"Case "6"giorno_settimana = "Venerdì"Case "7"giorno_settimana = "Sabato"End Select

Viene ricavato con la funzione Weekday() quale giorno della settimana è al momento della richiesta di questa pagina e con un Select Case (costrutto simile a If... Then... Else, ma molto piu' comodo per la verifica di molte condizioni) viene memorizzata nella variabile giorno_settimana il nome del giorno.

' separo la data di oggigiorno = Day(data)mese = Month(data)anno = Year(data)if mese < 10 thenmese = "0" & meseend ifif giorno < 10 thengiorno = "0" & giornoend if'*****************************************************************' separo l'ora odiernaore = Hour(ora)minuti = Minute(ora)secondi = Second(ora)ora = ore & ":" & minuti & ":" & secondi'*****************************************************************' mi ricavo l'ip del visitatoreip = Request.ServerVariables("REMOTE_ADDR")

E' inoltre necessario ai fini della statistica memorizzare i valori del giorno, mese, anno, ora, minuti e secondi... nonchè dell' indirizzo IP dell'utente per poter conteggiare anche gli accessi unici. Qui si conclude la fase di "preparazione".

' controllo che non sia già esistente entro un oraSQL = "SELECT * FROM ip WHERE ip='" & ip & "' AND ora=" & oreSet rs = Server.CreateObject("ADODB.Recordset")rs.Open SQL, objConn, 3, 3'*****************************************************************' se l'IP non esiste nell'ultima ora entro nel ifif rs.EOF then' lo inserisco nella tabella ipSQL = "INSERT INTO ip(ip, ora) VALUES ('" & ip & "', " & ore & ")"Set rs1 = Server.CreateObject("ADODB.Recordset")rs1.Open SQL, objConn, 3, 3elseipOnline = rs.Fields("ip")end if

Per prima cosa viene controllato se l' IP dell'utente è già presente nel database (il sistema memorizza gli IP dell'ultima ora), se non è esistente lo inserisce.

' controllo che nella tabella giorni ci siano già recordSQL = "SELECT * FROM giorni WHERE data=" & anno & "" & mese & "" & giornoSet rs4 = Server.CreateObject("ADODB.Recordset")rs4.Open SQL, objConn, 3, 3if not rs4.EOF thendataGiorni = rs4.Fields("data")impressionGiorni = rs4.Fields("impression")visitatoriGiorni = rs4.Fields("visitatori")end if

Ora è necessario controllare che nella tabella giorni del database sia già stato inserito il giorno attuale, in tal caso vengono prelevate le informazioni sulle impression e i visitatori del giorno che poi dovranno essere aggiornate.

dataGiorniOggi = anno & "" & mese & "" & giorno' se ci sono record modifico il campo impression giornaliere altrimenti inserisco un recordif (int(dataGiorni) = int(dataGiorniOggi)) thenSQL = "UPDATE giorni SET impression=" & int(impressionGiorni)+1 & " WHERE data=" & datagiorniOggiif ipOnline = "" then'*****************************************************************' nella tabella giorni modifico il campo come modifica univocaSQL = "UPDATE giorni SET visitatori=" & int(visitatoriGiorni)+1 & " WHERE data=" & int(dataGiorniOggi)Set rs6 = Server.CreateObject("ADODB.Recordset")rs6.Open SQL, objConn, 3, 3end ifelseSQL = "INSERT INTO giorni(data, impression, visitatori)" _& " VALUES(" & dataGiorniOggi & ", 1, 1)"end ifSet rs5 = Server.CreateObject("ADODB.Recordset")rs5.Open SQL, objConn, 3, 3

Vengono modificati i dati ricavati dalla tabella giorni, le impressions vengono aumentate di + 1, i visitatori, se poi è il primo accesso dell'utente che viene monitorato anche il campo visitatori viene aggiornato di + 1

provenienza = Request.ServerVariables("HTTP_REFERER")    if provenienza <> "" then    '*****************************************************************    ' controllo la provenienza dell'utente e i tempi    SQL = "SELECT * FROM provenienza WHERE url='" & provenienza & "'"    Set rs17 = Server.CreateObject("ADODB.Recordset")    rs17.Open SQL, objConn, 3, 3    if not rs17.EOF then    urlProvenienza = rs17.fields("url")    numeroProvenienza = rs17.fields("numero")    dataProvenienza = rs17.fields("data")    data_ultimoProvenienza = rs17.fields("data_ultimo")    end if    if (ipOnline = ip) then    'non si fa niente    else    if(Trim(LCase(urlProvenienza)) = Trim(LCase(provenienza))) then    if ipOnline = "" then    SQL = "UPDATE provenienza SET numero=" & int(numeroProvenienza)+1 & ", data_ultimo=#" & mese &"/"& giorno &"/"& anno & "# WHERE url='" & urlProvenienza & "'"    end if    elseif (ipOnline <> ip) then    SQL = "INSERT INTO provenienza(url, numero, data, data_ultimo)" _    & " VALUES('" & provenienza & "', 1, #" & mese &"/"& giorno &"/"& anno & "#, #" & mese &"/"& giorno &"/"& anno & "#)"    end if    Set rs18 = Server.CreateObject("ADODB.Recordset")    rs18.Open SQL, objConn, 3, 3    end if    end if    ' controllo da dove proviene l'utente    ingresso = Request.Servervariables("PATH_INFO")    SQL = "SELECT * FROM ingresso WHERE url='" & Trim(ingresso) & "'"    Set rs7 = Server.CreateObject("ADODB.Recordset")    rs7.Open SQL, objConn, 3, 3    if not rs7.EOF then    urlIngresso = rs7.fields("url")    numeroIngresso = rs7.fields("numero")    provenienzaIngresso = rs7.fields("provenienza")    end if    if (ipOnline = ip) then    'non si fa niente    else    if Trim(LCase(ingresso)) = Trim(LCase(urlIngresso)) then    SQL = "UPDATE ingresso SET numero=" & int(numeroIngresso)+1 & " WHERE url='" & urlIngresso & "'"    elseif (ipOnline <> ip) then    arrUrlIngresso = Split(ingresso, "/", -1, 1)    url = arrUrlIngresso(1)    SQL = "INSERT INTO ingresso(url, numero, provenienza)" _    & " VALUES('" & Trim(LCase(ingresso)) & "', 1, '" & url & "')"    end if    Set rs8 = Server.CreateObject("ADODB.Recordset")    rs8.Open SQL, objConn, 3, 3    end if

Viene ora controllata la provenienza con l'utilizzo di Request.ServerVariables("HTTP_REFERER") se non contiene niente le operazioni successive non saranno effettuate (a volte può capitare che non si riesca a prelevare l'url della pagina da cui l'utente proviene, i motivi posso essere svariati: può provenire da un link presente in una email per esempio). Se è possibile intercettare il Referer (provenienza) allora viene controllato se la pagina da cui proviene è già inserita nel database, se lo è allora aggiorna il campo numero di + 1 per indicare che un ulteriore utente proviene da quella pagina, se non è presente l'url, viene inserita con il campo numero impostato a 1, in quanto è il primo accesso proveniente da quella pagina.

' controllo le pagine visitatepagineViste = Request.Servervariables("PATH_INFO")arrPagineViste = Split(pagineViste, "/", -1, 1)pagineViste = arrPagineViste(UBound(arrPagineViste)-1) & "/" & arrPagineViste(UBound(arrPagineViste))SQL = "SELECT * FROM pagineviste WHERE url='" & pagineViste & "'"Set rs15 = Server.CreateObject("ADODB.Recordset")rs15.Open SQL, objConn, 3, 3if not rs15.EOF thenurlPagineViste = rs15.fields("url")numeroPagineViste = rs15.fields("numero")end ifif (Trim(Lcase(urlPagineViste)) = Trim(Lcase(pagineViste))) thenSQL = "UPDATE pagineviste SET numero=" & int(numeroPagineViste)+1 & " WHERE url='" & urlPagineViste & "'"elseSQL = "INSERT INTO pagineviste(url, numero)" _& " VALUES('" & pagineViste & "', 1)"end ifSet rs16 = Server.CreateObject("ADODB.Recordset")rs16.Open SQL, objConn, 3, 3

Viene prelevata la pagina che sta visitando l'utente e viene effettuato lo stesso ragionamento per i Referer. Se la pagina è già presente nel database il campo numero viene aggiornato di + 1, altrimenti l'url della pagina visualizzata viene inserito e il campo numero impostato a 1.

' controllo per settimana dell'annoSQL = "SELECT * FROM settimane WHERE anno=" & anno & " AND settimana=" & settimana_annoSet rs19 = Server.CreateObject("ADODB.Recordset")rs19.Open SQL, objConn, 3, 3if not rs19.EOF thensettimanaAnno = rs19.Fields("anno")settimanaSettimana = rs19.Fields("settimana")settimanaAccessi = rs19.Fields("accessi")settimanaImpression = rs19.Fields("impression")end ifif (int(settimanaSettimana) = int(settimana_anno)) thenSQL = "UPDATE settimane SET impression=" & int(settimanaImpression)+1 & " WHERE anno=" & anno & " AND settimana=" & settimanaSettimanaif ipOnline = "" thenSQL = "UPDATE settimane SET accessi=" & int(settimanaAccessi)+1 & " WHERE anno=" & anno & " AND settimana=" & settimana_annoend ifelseSQL = "INSERT INTO settimane(anno, settimana, accessi, impression)" _& " VALUES(" & anno & ", " & settimana_anno & ", 1, 1)"end ifSet rs20 = Server.CreateObject("ADODB.Recordset")rs20.Open SQL, objConn, 3, 3'*****************************************************************' inserisco la media oreSQL = "SELECT * FROM media_ore WHERE ora=" & oreSet rs9 = Server.CreateObject("ADODB.Recordset")rs9.Open SQL, objConn, 3, 3if not rs9.EOF thenoraMedia = rs9.Fields("ora")accessiMedia = rs9.Fields("accessi")impressionMedia = rs9.Fields("impression")end ifif (int(oraMedia) = int(ore)) thenSQL = "UPDATE media_ore SET impression=" & int(impressionMedia)+1 & " WHERE ora=" & oreif ipOnline = "" thenSQL = "UPDATE media_ore SET accessi=" & int(accessiMedia)+1 & " WHERE ora=" & oreend ifelseSQL = "INSERT INTO media_ore(ora, accessi, impression)" _& " VALUES(" & ore & ", 1, 1)"end ifSet rs10 = Server.CreateObject("ADODB.Recordset")rs10.Open SQL, objConn, 3, 3'*****************************************************************' inserisco la media settimanaleSQL = "SELECT * FROM media_settimana WHERE nome='" & giorno_settimana & "'"Set rs12 = Server.CreateObject("ADODB.Recordset")rs12.Open SQL, objConn, 3, 3if not rs12.EOF thennomeMediaSett = rs12.Fields("nome")accessiMediaSett = rs12.Fields("accessi")impressionMediaSett = rs12.Fields("impression")end ifif (Trim(LCase(nomeMediaSett)) = Trim(LCase(giorno_settimana))) thenSQL = "UPDATE media_settimana SET impression=" & int(impressionMediaSett)+1 & " WHERE nome='" & nomeMediaSett & "'"if ipOnline = "" thenSQL = "UPDATE media_settimana SET accessi=" & int(accessiMediaSett)+1 & " WHERE nome='" & giorno_settimana & "'"end ifelseSQL = "INSERT INTO media_settimana(nome, accessi, impression)" _& " VALUES('" & giorno_settimana & "', 1, 1)"end ifSet rs13 = Server.CreateObject("ADODB.Recordset")rs13.Open SQL, objConn, 3, 3

Con tutto questo codice vengono effettuate 3 operazioni differenti, ma volte tutte a raccogliere dati sugli accessi in base a determinati periodi di tempo:

  • settimana dell'anno (accessi nella 1°, 2°, 3°... 50° settimana dell'anno)
  • media ore (media accessi alle 01, 02, 03... 19... 22, 23)
  • media settimanale (media accessi il lunedì, martedì, mercoledì... )

Viene prima controllato se il record è presente, vengono recuperate le informazioni sugli accessi (accessi e impression) e poi aggiornati o inseriti nel caso non ci sia il record.

' mi ricavo il browser dell'utente e poi lo inserisco nel databasebrowser = UCase(Request.ServerVariables("HTTP_USER_AGENT"))if InStr(browser, "MSIE") thenbrowser = "Internet Explorer"elseif InStr(browser, "OPERA") thenbrowser = "Opera"elsebrowser = "Netscape"end ifSQL = "SELECT * FROM browser WHERE browser='" & browser & "'"Set rs2 = Server.CreateObject("ADODB.Recordset")rs2.Open SQL, objConn, 3, 3if rs2.EOF thenSQL = "INSERT INTO browser(browser, numero) VALUES('" & browser & "', 1)"elsebrowserUtilizzato = rs2.fields("browser")numeroBrowser = rs2.fields("numero")if ((ipOnline = ip) AND (browserUtilizzato = browser)) then'non si fa nienteelseSQL = "UPDATE browser SET numero=" & int(numeroBrowser)+1 & " WHERE browser='" & browser & "'"end ifend ifSet rs3 = Server.CreateObject("ADODB.Recordset")rs3.Open SQL, objConn, 3, 3'*****************************************************************' mi ricavo il sistema operativo dell'utente e poi lo inserisco nel databaseso = UCase(Request.ServerVariables("HTTP_USER_AGENT"))if instr(so, "98") thenso = "Windows 98"elseif instr(so, "95") thenso = "Windows 95"elseif instr(so, "NT 5.0") thenso = "Windows2K"elseif instr(so, "NT 5.1") thenso = "Windows Xp"elseif instr(so, "NT") thenso = "Windows NT"elseif instr(so, "LINUX") thenso = "Linux"elseif instr(so, "MAC") thenso = "Machintos"end ifSQL = "SELECT * FROM sistema WHERE os='" & so & "'"Set rs22 = Server.CreateObject("ADODB.Recordset")rs22.Open SQL, objConn, 3, 3if rs22.EOF thenSQL = "INSERT INTO sistema(os, numero) VALUES('" & so & "', 1)"elsesoSo = rs22.Fields("os")numeroSo = rs22.Fields("numero")if ((ipOnline = ip) AND (soSo = so)) then'non si fa nienteelseSQL = "UPDATE sistema SET numero=" & int(numeroSo)+1 & " WHERE os='" & soSo & "'"end ifend ifSet rs23 = Server.CreateObject("ADODB.Recordset")rs23.Open SQL, objConn, 3, 3

Il codice ricava le informazioni sul browser e il sistema operativo dell'utente per poi memorizzarli e capire i nostri utenti che software utilizzano. Questi dati sono normalmente simili in molti siti web, ma in siti di grafica professionale o orientati ad un particolare sistema operativo noteremo differenze... in quelli di grafica ci sarà una maggiore percentuale rispetto agli altri di Mac per esempio. Queste informazioni possono apparire inutile, ma al contrario (come abbiamo già analizzato su WebMasterPoint.org in un articolo di webmarketing) sono utili per comprendere che tipo di utenti accedono al nostro sito. Il ragionamento per l'inserimento delle informazioni è identico a quello visto in precedenza.

' mi ricavo il motore di ricerca e la keywords    'Controllo Google    If Instr(provenienza,"google.it") then    arrKey = Split(provenienza, "q=")    key = Replace(provenienza,"http://www.google.it/search?q="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.google.it"    'Controllo Virgilio.it    elseIf Instr(provenienza,"virgilio.it") then    arrKey = Split(provenienza, "qs=")    key = Replace(provenienza,"http://search.virgilio.it/search/cgi/search.cgi?db=v&op=and&qs=","")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.virgilio.it"    'Controllo Google.com    elseIf Instr(provenienza,"google.com") then    arrKey = Split(provenienza, "q=")    key = Replace(provenienza,"http://www.google.com/search?hl=en&q="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.google.com"    'Controllo Altavista.com    elseIf Instr(provenienza,"www.altavista.com") then    arrKey = Split(provenienza, "qs")    key = Replace(provenienza,"http://www.altavista.com/sites/search/web?q="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.altavista.com"    'Controllo Altavista.it    elseIf Instr(provenienza,"it.altavista.com") then    arrKey = Split(provenienza, "q=")    key = Replace(provenienza,"http://it.altavista.com/q?pg=q&q="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.altavista.it"    'Controllo Lycos.it    elseIf Instr(provenienza,"cerca.lycos.it") then    arrKey = Split(provenienza, "query=")    key = Replace(provenienza,"http://cerca.lycos.it/cgi-bin/pursuit?matchmode=and&mtemp=main&etemp=error&query="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.lycos.it"    'Controllo Yahoo.it    elseIf Instr(provenienza,"it.search.yahoo.com") then    arrKey = Split(provenienza, "p=")    key = Replace(provenienza,"http://it.search.yahoo.com/search/it?p="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.yahoo.it"    'Controllo Yahoo.com    elseIf Instr(provenienza,"search.yahoo.com") then    arrKey = Split(provenienza, "p=")    key = Replace(provenienza,"http://search.yahoo.com/bin/search?p="," ")    key = key & "" & arrKey(1)    keyMotore = key    linkMotore = "http://www.yahoo.com"    End If    ' inserisce nel database il motore    If linkMotore <> "" then    SQL = "SELECT * FROM motore WHERE motore='" & linkMotore & "'"    Set rs24 = Server.CreateObject("ADODB.Recordset")    rs24.Open SQL, objConn, 3, 3    if rs24.EOF then    SQL = "INSERT INTO motore(motore, accessi) VALUES('" & linkMotore & "', 1)"    else    SQL = "UPDATE motore SET accessi=" & int(accessi)+1 & " WHERE motore='" & linkMotore & "'"    end if    Set rs25 = Server.CreateObject("ADODB.Recordset")    rs25.Open SQL, objConn, 3, 3    '*****************************************************************    ' inserisce nel database la keyword    SQL = "SELECT * FROM keyword WHERE keyword='" & keyMotore & "'"    Set rs26 = Server.CreateObject("ADODB.Recordset")    rs26.Open SQL, objConn, 3, 3    if rs26.EOF then    SQL = "INSERT INTO keyword(keyword, numero) VALUES('" & keyMotore & "', 1)"    else    SQL = "UPDATE keyword SET numero=" & int(numero)+1 & " WHERE keyword='" & keyMotore & "'"    end if    Set rs27 = Server.CreateObject("ADODB.Recordset")    rs27.Open SQL, objConn, 3, 3    End If

Questo codice permette di ricavare gli accessi provenienti da eventuali motori di ricerca e le parole chiave utilizzate. Questo codice contiene ancora un bug da correggere ma è utile analizzare le funzioni utilizzate:

'Controllo GoogleIf Instr(provenienza,"google.it") thenarrKey = Split(provenienza, "q=")key = Replace(provenienza,"http://www.google.it/search?q="," ")key = key & "" & arrKey(1)keyMotore = keylinkMotore = "http://www.google.it"'Controllo Virgilio.itelseIf Instr(provenienza,"virgilio.it") then....

La funzione Instr(var,testo) permette di verificare se all'interno di var ci sia testo, la funzione restituisce True o False.
Se l'url è: http://www.google.it/search?sourceid=navclient&hl=it&ie=UTF-8&oe=UTF-8&q=cerca del motore google (a volte i parametri sono messi in ordine differente), l'istruzione:

Instr(provenienza,"google.it")

restituire True come valore.

La funzione Split(var,testo) permette di dividere una stringa var in un array dividendola prendendo come separatore testo.
Con la stessa url di prima l'istruzione:

arrKey = Split(provenienza, "q=")

crea un array con 2 record che contengono:

  • http://www.google.it/search?sourceid=navclient&hl=it&ie=UTF-8&oe=UTF-8&
  • q=cerca

In questo caso dovremmo prendere il secondo record che contiene "q=cerca" e fare un Replace(arrKey(1),"p=","") per eliminare q= e ottenere la parola chiave. Questa parola viene quindi memorizzata nella variabile key, viene impostato di quale motore si tratta in linkmotore. Infine key e linkmotore saranno inseriti nel database.

Visualizzazione delle statistiche
La pagina che si occupa della visualizzazione delle statistiche (statistiche.asp) pur essendo lunga centinaia di righe di codice (oltre 700) è molto semplice, perchè in base alla scelta effettuata da un menu che si trova in un file esterno (menu.asp) visualizza i dati richiesti formattandoli in una tabella con una semplice SELECT (Linguaggio SQL).

L'unica query interessante da analizzare è:

SQL = "SELECT TOP 20 * FROM ip ORDER BY ordine DESC"

Con l'utilizzo della clausola TOP 20 riusciamo a ricavare solo i primi 20 record, che saranno ordina in modo Decrescente (dall'ultimo) grazie all'utilizzo di DESC nella clausola ORDER BY (ordina per un determinato o piu' campi).

Connessione al database
La connessione al database è la classica connessione ADO

dim objConn, DSNtempset objConn= server.CreateObject("ADODB.Connection")DSNtemp="DRIVER={Microsoft Access Driver (*.mdb)}; "DSNtemp=DSNtemp & "DBQ=" & server.mappath("db/wmpstat.mdb")objConn.Open DSNtemp

in cui l'indirizzo del database viene indicato con un percorso relativo, che verrà trasformato in assoluto grazie all'utilizzo della funzione Server.MapPath.