Pokud provozujete nějaký internetový časopis, určitě uvítáte možnost, aby
čtenáři mohli vaše články ohodnotit. Ze získané průměrné známky pak můžete usoudit, jak se jim články líbí
(či nelíbí). A v případě, že bude hodnocení článků nelichotivé, víte na čem zapracovat...
Podle obrázku si
aplikaci nejprve navrhneme. Čtenář vašeho časopisu si přečte článek a ohodnotí jej (v rozsahu 5ti stupňů
- jako ve škole), dejme tomu, na dvojku. Známka se uloží do databáze
a návštěvník je přesměrován zpět. Pod stupnicí je také zobrazena průměrná známka a v závorkách počet
hlasujících. Aby výsledky nebyly zkreslené, povolíme čtenáři v rámci jednoho připojení hlasovat jen jednou.
Aplikace se skládá ze dvou stránek
ASP - jedna zobrazuje stupnici (hodnoceni.asp) a druhá zapisuje do
databáze (zapis.asp) - a databáze, pro kterou vytvoříme DSN se jménem "ankety". Tato
databáze bude obsahovat všechny tabulky, jež použijeme i v dalších dílech. V
tomto díle vytvoříme tabulku se jménem hodnoceni_clanku s touto strukturou:
| Název pole |
Datový typ |
| ID |
automatické číslo - primární klíč |
| znamka1 |
číslo |
| znamka2 |
číslo |
| znamka3 |
číslo |
| znamka4 |
číslo |
| znamka5 |
číslo |
V každé buňce tabulky bude uložena informace, kolikrát bylo pro určitou
známku hlasováno. Pokud tedy známkou "2" ohodnotilo článek 26 čtenářů, bude v buňce znamka2
uložena hodnota 26.
Základ aplikace máme hotový, proto teď začneme vytvářet
soubor hodnoceni.asp, jehož podobu jste již viděli. Nejdůležitější a nejtěžší částí bude určení průměrné známky. Tu určíme tak, když součet všech známek vydělíme počtem hlasujících.
Součet známek získáme vynásobením každé známky počtem lidí, kteří pro ni hlasovali:
(1 * pocet_lidi_znamka1) + (2 * pocet_lidi_znamka2) + (3 * pocet_lidi_znamka3) + (4 * pocet_lidi_znamka4) + (5 * pocet_lidi_znamka5)
Například 70 návštěvníků hodnotilo takto:
(1 * 18) + (2 * 12) + (3 * 15) + (4 * 22) + (5 * 3) = 190
Průměrná známka po zaokrouhlení na dvě desetinná místa tedy je:
190 / 70 = 2,71
Postup pro určení průměrné známky již známe,
proto jej teď převedeme do ASP kódu a vytvoříme stránku
hodnoceni.asp:
<%
Set conn =
Server.CreateObject("ADODB.Connection")
conn.Open "ankety"
rs = conn.execute("SELECT * FROM hodnoceni_clanku")
celkem = rs("znamka1") + rs("znamka2") + rs("znamka3") + rs("znamka4") + rs("znamka5")
soucet = rs("znamka1") + (rs("znamka2") * 2) + (rs("znamka3") * 3) + (rs("znamka4") * 4) + (rs("znamka5") * 5)
if celkem > 0 Then
prumer =
soucet / celkem
Else
prumer = 0
End If
%><br><a href="zapis.asp?znamka=
1">1</a>- <a href="zapis.asp?znamka=
2">2</a>- <a href="zapis.asp?znamka= 3">3</a>- <a href="zapis.asp?znamka=
4">4</a>- <a href="zapis.asp?znamka=5">5</a> <br>
Aktuální hodnocení: <% response.write Round(prumer,2) %> (<% response.write celkem %>)<br>
<% conn.close
Set conn =
Nothing
Set rs = Nothing
%>
|
V případě, že článek je nový a ještě nebyl nikým ohodnocen, je obsah proměnné celkem (zastupuje počet hlasujících)
nula. Ale protože získáváme průměrnou známku výrazem soucet / celkem, vyskočila by chyba - dělení nulou není možné. Proto tuto skutečnost ošetřujeme rozhodovací konstrukcí. Dělíme jen v případě, že hodnota proměnné celkem je větší než nula. V opačném případě se hodnota proměnné prumer (uchovává průměrnou známku) automaticky nastaví na nulu (nikdo nehlasoval, proto není jiná možnost).
Průměrnou hodnotu nakonec ještě před vypsáním zaokrouhlujeme na dvě desetinná místa pomocí funkce VBScriptu Round.
Všechny odkazy zastupující známky 1-5 vedou na soubor zapis.asp:
<%
Set conn =
Server.CreateObject("ADODB.Connection")
conn.Open "ankety"
If IsNumeric(Request.QueryString("znamka")) and Session("hlasoval")="" Then
znamka = Request.QueryString("znamka")
strSQL = "Select * From hodnoceni_clanku"
rs = conn.execute(strSQL)
Select Case znamka
Case 1
strSQL2 = "UPDATE hodnoceni_clanku SET znamka1 = znamka1 + 1"
Case 2
strSQL2 = "UPDATE hodnoceni_clanku SET znamka2 = znamka2 + 1"
Case 3
strSQL2 = "UPDATE hodnoceni_clanku SET znamka3 = znamka3 + 1"
Case 4
strSQL2 = "UPDATE hodnoceni_clanku SET znamka4 = znamka4 + 1"
Case 5
strSQL2 = "UPDATE hodnoceni_clanku SET znamka5 = znamka5 + 1"
End Select
If len(strSQL2)>0 Then
Session("hlasoval")=1
conn.execute (strSQL2)
End If
conn.close
Set conn = Nothing
Set rs =
Nothing
response.redirect "hodnoceni.asp"
Else
response.redirect "hodnoceni.asp"
End If
%>
|
Ještě dříve, než se vytváří instance objektu Connection a otevírá spojení s databází, se ověří, zda byl předán potřebný parametr. Tento soubor je totiž ze stránky hodnoceni.asp volán s parametrem znamka obsahující číslo 1-5. Další podmínkou je, že čtenář ještě nehlasoval. Pokud totiž hlasuje poprvé, uloží se mu do proměnné hlasoval číslo 1. A jestliže se pokouší hlasovat podruhé, má smůlu - tato podmínka jej nepustí dál.
Dále se pomocí rozhodovací konstrukce Select Case porovnává hodnota parametru znamka s jednotlivými čísly za klíčovými slovy Case. Pokud se někde shoduje, jsou vykonány příkazy za příslušným slovem Case (konče následujícím slovem Case), porovnávání se přerušuje a pokračuje se v kódu za slovy End Select.
Například, pokud je hodnota parametru znamka 2, vykonají se příkazy za Case 2. Nachází se tam jen jeden příkaz, kterým je přiřazení SQL kódu proměnné strSQL2. Tento kód přičte ke stávající hodnotě počtu hlasujících v buňce znamka2 jedničku. SQL příkaz je vykonán za klíčovými slovy End Select a společně s ním se do proměnné hlasoval uloží číslo 1.
Může však nastat situace, že jako parametr se předá něco jiného než číslo v rozmezí 1-5. V tomto případě pak není proměnné strSQL2 přiřazen žádný SQL příkaz, neboť parametr znamka se neshoduje s žádnou hodnotou u slov Case. Ale kdyby byla volána metoda Execute bez žádného SQL příkazu, vyvolala by chybu. Proto je také pomocí konstrukce If...Else ověřeno, že proměnná strSQL2 není prázdná. Jestliže je, metoda není volána a také není do proměnné hlasoval uložena jednička.
V tomto bodě již máme hotovu funkční aplikaci. My však chceme, aby tyto dva ASP soubory byly v souboru jednom. Není to nic těžkého, jen je jednoduše spojíme do souboru hodnoceni.asp:
<%
response.buffer = true
response.expires = -1000
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "ankety"
%>
<html>
<head>
<title>Hodnocení článku</title>
</head>
<body>
<%
If len(Request.QueryString("znamka"))>0 AND Session("hlasoval")="" Then
znamka = Request.QueryString("znamka")
strSQL = "Select * From hodnoceni_clanku"
rs = conn.execute(strSQL)
Select Case znamka
Case 1
strSQL2 = "UPDATE hodnoceni_clanku SET znamka1 = znamka1 + 1"
Case 2
strSQL2 = "UPDATE hodnoceni_clanku SET znamka2 = znamka2 + 1"
Case 3
strSQL2 = "UPDATE hodnoceni_clanku SET znamka3 = znamka3 + 1"
Case 4
strSQL2 = "UPDATE hodnoceni_clanku SET znamka4 = znamka4 + 1"
Case 5
strSQL2 = "UPDATE hodnoceni_clanku SET znamka5 = znamka5 + 1"
End Select
If len(strSQL2)>0 Then
Session("hlasoval")=1
conn.execute (strSQL2)
End If
conn.close
Set conn = Nothing
Set rs = Nothing
response.redirect "hodnoceni.asp"
%>
<% Else %>
<%
rs = conn.execute("SELECT * FROM hodnoceni_clanku")
celkem = rs("znamka1") + rs("znamka2") + rs("znamka3") + rs("znamka4") + rs("znamka5")
soucet = rs("znamka1") + (rs("znamka2") * 2) + (rs("znamka3") * 3) + (rs("znamka4") * 4) + (rs("znamka5") * 5)
if celkem > 0 Then
prumer = soucet / celkem
Else
prumer = 0
End If
%>
<a href="hodnoceni.asp?znamka=1">1</a> -
<a href="hodnoceni.asp?znamka=2">2</a> -
<a href="hodnoceni.asp?znamka=3">3</a> -
<a href="hodnoceni.asp?znamka=4">4</a> -
<a href="hodnoceni.asp?znamka=5">5</a><br><br>
Aktuální hodnocení: <% response.write Round(prumer,2) %> (<% response.write celkem %>)<br>
<%
conn.close
Set conn = Nothing
Set rs = Nothing
End If
%>
</body>
</html> |
První novinkou, se kterou jste se nemuseli setkat, může být příkaz response.buffer. Zkuste jej vynechat, otevřete si prohlížeč s naší aplikací a ohodnoťte článek. Měla by se vám vypsat chyba podobná této:
Objekt Response chyba ASP 0156 : 80004005'
Chyba záhlaví.
/1/hodnoceni.asp, řádek 38
Záhlaví HTTP jsou již do prohlížeče klienta
zapsána. Jakékoli úpravy záhlaví HTTP je nutné
provést před zápisem obsahu stránek.
Tento příkaz totiž určuje, zda se má stránka odesílat prohlížeči jako celek, anebo postupně, jak je zpracovávána. Může nabývat dvou hodnot - true nebo false. Pokud je nastavena na true, odesílá se jako celek, pokud na false, odesílá se postupně. (Standardní hodnotou je u ISS 4 a nižších false, u ISS 5 a vyšších true. Nebudeme však spoléhat na to, že skripty poběží na ISS 5, a proto pro jistotu nastavíme hodnotu na true.) V ASP stránkách, které kombinují HTML obsah a příkazy response.redirect, musí být hodnota nastavena true.
Pomocí dalšího příkazu, response.expires, nastavíme dobu platnosti stránky. Někdy je nežádoucí, aby se stránka ukládala do dočasných souborů prohlížeče, ale je třeba ji vždy nově generovat. Proto nastavíme hodnotu na "-1000", což nám zaručí, že data zobrazená čtenáři budou co nejaktuálnější.
Vaše třetí, a doufám, že i poslední otázka může znít nějak takto: jak má "překladač" kódu ASP zjistit, zda má vypsat 5 odkazů, anebo aktualizovat data v databázi? Jednoduše. Pokud totiž čtenář hlasuje, je předáván stránce hodnoceni.asp parametr znamka, a pokud jen otevírá článek, je stránka volána bez tohoto parametru. Proto se v kódu objevuje konstrukce If len(Request.QueryString("znamka"))>0 ...(aktualizace databáze) Else...(zobrazení ankety)
Dospěli jsme k úplnému závěru článku. Celou hotovou aplikaci (i s databází) si můžete stáhnout zde.
Zde pod článkem si hodnocení můžete vyzkoušet v praxi. Chci vás ale upozornit, že u tohoto článku funguje jenom jednička :-)
Liška Adam
|