Geschrieben von: Rene Drescher-Hackel
Kategorie: ASP Grundlagen
This printed page brought to you by AlphaSierraPapa
Im heutigen Artikel möchte ich Ihnen zeigen, daß es sinnvoll sein kann, seinen ASP-Dateien mehr "Struktur" zu verleihen. Der Artikel wird Ihnen zeigen, wie Sie selbst bei übermäßig vielen Programmzeilen immer noch den Überblick behalten.
In meiner täglichen Praxis erlebe ich immer wieder, wie wichtig es ist, sauber und übersichtlich zu programmieren. Fast jeder von Ihnen wird immer öfter mit Arbeiten konfrontiert, die vor Monaten - oder Jahren - einmal fertiggestellt wurden. Wer will da noch die genauen Überlegungen kennen, die einst bei der Scripterstellung leitend waren.
ASP-Einsteigern soll der Artikel dazu dienen, von Anfang an auf eine saubere und übersichtliche Programmierung zu achten und zeigen, wie man dies unter anderem erreichen kann.
Der erste Eintrag auf der ASP-Seite ist
<%@ Language=VBScript %>
wenn VBScript die von Ihnen bevorzugte Script-Sprache ist.
Sie sollten auf gar keinen Fall die erste Zeile umbrechen und innerhalb der ersten Begrenzungszeichen weiteren Code unterbringen. Dies führt regelmäßig zu folgender Fehlermeldung:
Active Server Pages- Fehler 'ASP 0221' Ungültige @ Kommandozuweisung
Als nächstes folgen daher wieder die typischen Script-Begrenzungszeichen:
<% ... %>
Innerhalb dieser Begrenzungszeichen steht dann der eigentliche Code.
Ihr nächster Eintrag sollte dann die Anweisung
Option Explicit
sein. Diese Anweisung "zwingt" Sie dazu, daß Sie Ihre im Script später benutzten Varaiablen vor ihrer ersten Verwendung deklarieren, also bekannt machen. Dies macht aus zweierlei Gründen Sinn: Zum einen wissen Sie beim ersten Lesen Ihres Scriptes später, welche Variablen Sie alle benutzen. Zum anderen ist der Zugriff auf deklarierte Variablen schneller, da hier über die Ordinalzahl (der Variable) auf sie zugegriffen wird, während im anderen Fall über den Varaiablennamen der Zugriff erfolgt.
Die Variablendeklarationen können dabei mit
Private | Public | Dim Variablenname
erfolgen. Es empfiehlt sich dabei, die einzelne Anweisung gleichzeitig zu kommentieren:
Dim strName ' Name des Benutzers
Ein weiterer Punkt ist die Namensgebung bei der Variablenbenennung. Ich empfand es bislang als äußerst hilfreich, den von mir in der Variable erwarteten Variablentyp im Namen mit anzugeben. Wenn also der Typ "String" erwartet wird, dann wurde dem Variablennamen das Kürzel "str" voran gestellt. Beim Typ "Integer" dann "int", bei "Boolean" dann "bln" und so weiter. Darüber hinaus sollten Sie sich angewöhnen, sinnvolle Namen als Bezeichnung zu wählen. So kann die Variable für eine Kundennummer z.B. "intKundenNr" heißen, statt nur "KNR".
Wie oben für die Variablendeklaration schon angesprochen, sollten Sie Ihre Scripte kommentieren - das erhöht die spätere Lesbarkeit. Kommentare können dabei u.a. den dann folgenden Scriptblock näher beschreiben oder gar nur eine einzelne Anweisung näher erläutern.
Stellen Sie sich vor, sie müssen aus diversen Datenbanktabellen verschiedene Informationen zusammentragen und in einer SELECT-BOX darstellen. Es wäre müßig, jedes Mal den selben Codeabschnitt neu zu verfassen.
Hier kann man sich die Arbeit dadurch erleichtern, in dem man immer wiederkehrende Programmteile in einzelne Prozeduren verpackt. Dabei können Sie zwischen
Private | Public Sub | Function ([parameter])
wählen.
Ob Sie nun "Sub" oder "Function" wählen hängt ganz davon ab, was Sie von Ihrer Prozedur erwarten. Soll ein bestimmter Codeblock nur abgearbeitet werden, so ist "Sub" die richtige Wahl. Möchten Sie aber durch den Aufruf der Prozedur einen Wert zurück erhalten, dann ist Function die richtige Entscheidung. Hier wird also deutlich: Sub kann keine Werte zurück geben (mit einer Ausnahme, wie Sie weiter unten noch sehen werden) - Function schon.
Die Prozedur bzw. Methode wird durch die Angabe des Gültigkeitsbereiches (Private oder Public) , der Methodenart (Sub oder Function) und der an die Prozedur zu übergebenden Parameter gekennzeichnet. Die Angabe von Parametern ist optional. Sind keine Parameter zu übergeben, entfällt also diese Angabe. Hier ist jedoch noch zu beachten: Übergeben Sie Parameter an die Prozedur immer " ByVal " (Wertübergabe). Dies hat den Vorteil, daß innerhalb der Prozdur der Wert der Variablen sich ändern kann, jedoch außerhalb der Prozedur der ursprüngliche Variablenwert erhalten bleibt. Wollen Sie jedoch gerade diesen Umstand bezwecken, daß sich aufgrund des Prozeduraufrufes die an die Prozedur übergebene Variable sich mit ändert, lassen Sie den Zusatz "ByVal" weg. Standardmäßig werden Variablen an Prozeduren "ByRef" übergeben.
Das Ende einer Prozedur wird mit der Anweisung
End Sub | Function
gekennzeichnet. Ist es erforderlich die Prozedur vorzeitig zu verlassen, so erfolgt dies mit
Exit Sub | Function
Schauen wir uns das ganze mal an einem Beispiel an - einer dynamisch erzeugten SELECT-BOX. Der Code hierfür könnte wie folgt aussehen:
Public Sub meineSelectBox(ByVal strTable, ByVal strColumn, ByVal strElement) ' Prozedur erzeugt anhand der übergebenen Werte für ' Tabelle, Spalte und Elementname eine Select-Box Dim strTemp ' Temporärvariable strTemp = "<select name=" & strElement & ">" strTemp = strTemp & "<Option value=0 >Bitte wählen Sie</Option>" ' Datenbankteil ' SQL-Abfrage Dim sql sql = " SELECT id, " & strColumn & " FROM " & strTable & " " call dbconnect() ' Datenbankverbindung herstellen set rs = conn.Execute(sql) if rs.eof then ' Prozedur vorzeitig verlassen ' und nur Textfeld ausgeben Response.Write "<input type=text name=" & strElement & ">" call dbclose() ' Datenbankverbindung vorher schließen Exit Sub ' Prozedurende else while not rs.eof strTemp = strTemp & "<Option value=" & rs(0) & ">" & rs(1) & "</Option>" rs.MoveNext wend end if call dbclose() ' Datenbankverbindung schließen strTemp = strTemp & "</select>" ' SelectBox ausgeben Response.Write strTemp End Sub
Nach der einleitenden Kommentierung erfolgt zunächst die Deklarierung einer lokalen Variable strTemp. Dies ist insoweit vorteilhaft, als daß der Zugriff auf lokale Variablen (also solchen, die innerhalb von Prozeduren deklariert werden), wieder schneller ist, als der Zugriff auf globale (außerhalb von Prozeduren deklarierte) Variablen. Für die Datenbankverbindung ist es jedoch ratsamer die Variable "conn" global zu deklarieren, damit andere Prozeduren das conn-Objekt nutzen können. Dabei sollten Sie beachten, daß im Fall der "conn"-Variable, diese PUBLIC deklariert werden sollte.
Dann folgt der erste Teil der Select-Box. Dadurch, daß der Elementname mitübergeben wurde, kann die Select-Box mit jedem Aufruf der Prozedur einen beliebigen Namen bekommen, sodaß am Ende dieselbe Prozedur auf ein und derselben Seite mehrfach aufgerufen werden kann und dennoch immer wieder (namentlich) verschiedene HTML-Elemente erzeugt werden.
Jetzt folgt die SQL-Anweisung. Auch hier ist die SQL-Anweisung so formuliert, daß sie am Ende variabel einsetzbar ist. Hierbei wurde jedoch davon ausgegangen, daß die abzufragende Tabelle über eine Primärschlüsselspalte mit der Bezeichnung "id" verfügt. Dies ist dann für die Wertzuweisung im Option-Value hilfreich. An das SQL-Statement wird die auszulesende Spalte und Tabelle übergeben. Dadurch ist es wieder möglich jede x-beliebige Tabelle/Spalte auszulesen und das Ergebnis in einer Select-Box darzustellen.
Sofern kein Datensatz gefunden wurde, wird - um das HTML-Design nicht zu zerstören - ein einfaches Textfeld ausgegeben und die Prozedur vorzeitig verlassen.
Ist ein Datensatz vorhanden, so werden die Option-Einträge der Select-Box erzeugt. An dieser Stelle kommt uns der Primärschlüssel des ausgelesenen Datensatzes zu gute. Um dem value nicht eine unnötig lange Zeichenkette zuzuweisen, wird hier einfach ein Integer-Wert - die Datensatz-ID - zugewiesen.
Abschließend wird die HTML-Anweisung komplettiert und ausgegeben.
Das ganze ließe sich mit einer Function genauso realisieren. Lediglich die erste und die letzten beiden Zeilen würden sich ändern:
Public Function meineSelectBox(ByVal strTable, ByVal strColumn, ByVal strElement) ... meineSelectBox = strTemp End Function
Damit die Function den Wert entsprechend zurückgibt, wird ihr der Wert von "strTemp" entsprechend zugewiesen. Die Ausgabe erfolgt dann mit dem Funktionsaufruf:
Response.Write meineSelectBox(...)
In den runden Klammern sind dann die Werte für die entsprechende Tabelle/Spalte und der Elementname an die Function mitzuübergeben.
Bei der Übergabe der Parameter an die Prozedur sollte folgendes beachtet werden:
Wie oben in unserem kleinen Beispiel schon zu sehen war, können die Parameter durch Voranstellen des Schlüsselwortes ByVal an die jeweilige Prozedur übergeben werden. ByVal bewirkt dabei, daß nur der Wert der Variablen übergeben wird. Arbeiten Sie innerhalb der Prozedur mit der gleichen Varaiablen weiter, so bleibt der Wert der Variablen außerhalb der Prozedur erhalten - gleich welchen Wert Sie der Variablen innerhalb der Prozedur zuweisen. Folgendes Codebeispiel soll Ihnen dies hier einmal verdeutlichen:
<% dim a ' Variable a a=5 ' Wertzuweisung Response.Write "Die Variable a= " & a & " vor Prozeduraufruf <hr>" 'vor Prozeduraufruf call meineProzedur(a) Response.Write "Die Variable a= " & a & " nach Prozeduraufruf <hr>" 'vor Prozeduraufruf Public Sub meineProzedurByVal(ByVal a) Response.Write "Die Variable a= " & a & " in der Prozedur vor Wertänderung <hr>" a=10 ' Wert ändern Response.Write "Die Variable a= " & a & " in der Prozedur nach Wertänderung <hr>" End Sub %>
In diesem Beispiel wird der Variablen a der Wert 5 zu gewiesen. Dann erfolgt der Aufruf einer Prozedur, wobei die Variable a ByVal an die Prozedur übergeben wird. Um deutlich zu machen, wie sich eine Wertänderung innerhalb der Prozedur außerhalb dieser wieder auf a wertmäßig auswirkt, habe ich hier in der Prozedur a den Wert 10 zugewiesen. Die nachfolgende Grafik zeigt recht deutlich, welchen Wert a jeweils angenommen hat und wie sich ByVal in der Parameterübergabe auf den Wert der Variablen ausgewirkt hat.
Das Gegenstück zu ByVal ist ByRef. Hier wird die Adresse der Variable übergeben, so daß - das obige Beispiel entsprechend abgeändert - a den Wert aus der Prozedur automatisch übernimmt.
dim a ' Variable a a=5 ' Wertzuweisung Response.Write "Die Variable a= " & a & " vor Prozeduraufruf <hr>" 'vor Prozeduraufruf call meineProzedur(a) Response.Write "Die Variable a= " & a & " nach Prozeduraufruf <hr>" 'vor Prozeduraufruf Public Sub meineProzedurByRef(ByRef b) Response.Write "Die Variable a= " & a & " in der Prozedur vor Wertänderung <hr>" b=10 ' Wert ändern Response.Write "Die Variable a= " & a & " in der Prozedur nach Wertänderung <hr>" End Sub
Um deutlich zu machen, wie ByRef sich verhält, habe ich jetzt die Prozedurvariable b eingeführt. Im Gegensatz zu dem vorangegangenen Beispiel habe ich hier b den Wert 10 zugewiesen. Dennoch hat sich der Wert von a geändert, wie die nachfolgende Grafik wieder zeigt:
Anders als bei PHP, erfolgt die Übergabe der Variablen standardmäßig - also ohne Angabe von ByVal oder ByRef - By Reference. Die Übergabe von Variablen ByRef an die Prozedur ist also dann sinnvoll, wenn der Variablenwert mit geändert werden soll. Daneben ist der Einsatz von ByRef wieder etwas schneller als ByVal.
Wenn man dabei ist, sich Gedanken zu machen wie und wann es am sinnvollsten erscheint ByVal oder ByRef einzusetzen, so möchte ich Ihnen noch folgenden Hinweis geben:
Gelegentlich kommt es vor, daß man mehr als einen Wert durch den Funktionsaufruf zurückgegeben haben möchte, eine Function aber andererseits nur einen Rückgabewert erlaubt. Wie kann man dem Abhelfen? Nun, Sie übergeben einfach eine zusätzliche Variable an die Funktion - allerdings diesmal bewußt ByRef. Da Sie nun wissen, wie sich der Wert der Variable ändern kann, die ByRef an die Funktion übergeben wurde, haben Sie auch zugleich den Weg, mehr als einen Wert aus einem Funktionsaufruf zurückzuerhalten. Und genau so könnten Sie mit einer Sub-Prozedur verfahren. Die Sub-Routinen geben nie einen Wert an die aufrufende Stelle zurück. Benötigen Sie aber gerade durch den Aufruf einer Sub einen bestimmten Rückgabewert, so übergeben Sie an die Sub einfach einen Wert ByRef. Das Ergebnis ist analog den obigen Ausführungen zur Function.
Lassen Sie mich an dieser Stelle ein paar Ausführungen zum Unterschied der Schlüsselwörter Private und Public machen.
Beide Schlüsselwörter beschreiben den Geltungsbereich - sowohl der Prozedur als auch der einzelnen Variable. Hinsichtlich der Variablendeklaration sollten Sie folgende Überlegungen beachten:
Wenn Sie denn so detailiert vorgehen und fast alles in Prozeduren verpacken, dann stellt sich die Frage, wie man am besten die ASP-Script-Logik zentral verfügbar (administrierbar) machen kann.
Dies erreichen Sie über ein entsprechendes INCLUDE der jeweiligen Logik-Seite.
<!--#include file="../meineLogik.asp"-->
Hierbei müssen Sie aber beachten, daß die Seite, in welcher der INCLUDE-Befehl steht, ebenfalls eine ASP-Seite sein muß. Dies ist dadurch begründet, da Sie ja hier die Prozedur aus der includierten Seite aufrufen wollen, was regelmäßig wie folgt geschieht:
<% call meinProzedurname(meineParameter,...) %>
Die call-Anweisung ist dabei nicht zwingend, bringt aber einen entscheidenen Syntax-Vorteil im Aufruf der Prozedur. Nehmen wir hier wieder das obige Beispiel der Select-Box. Hier haben wir uns für eine SUB-Prozedur entschieden. Der Aufruf dieser SUB-Prozedur ohne dem Schlüsselwort call müßte dann korrekter Weise folgendermaßen erfolgen:
MeineSelectBox strTable, strColumn, strElement
Wenn wir nun call verwenden sieht das Ganze so aus:
call meineSelectBox(strTable, strColumn, strElement)
Sie sehen also, beim Einsatz von call ist es erforderlich, die übergebenen Parameter in runden Klammern zu fassen. Wäre unsere Prozedur als FUNCTION definiert worden, so müßten wir in jedem Fall die Parameter in entsprechender Umklammerung mit angeben.
Die Benutzung von call beim Prozeduraufruf hat also den Vorteil der einheitlichen Syntax - ich muß also nicht mehr darauf achten, ob ich nun eine SUB oder eine FUNCTION aufrufe - in jedem Fall werden die Parameter in runder Umklammerung an die Prozedur übergeben.
Des weiteren wird durch call im Script deutlich, daß an dieser Stelle eine Prozedur aufgerufen wird.
Der Artikel soll insbesondere ASP-Einsteigern dazu dienen, von Anfang an darauf zu achten, sauber und übersichtlich - strukturiert - zu programmieren.
Durch den Einsatz von Prozeduren, lassen sich insbesondere mit Blick auf die Ressourcen, verschiedenste Programmteile gezielt ansteuern. So kann eine Datenbankverbindung z.B. erst dann angefordert werden, wenn diese auch explizit benötigt wird und sobald sie nicht mehr erforderlich ist, entsprechend wieder freigegeben werden.
Mit Prozeduren kann man seinen Code so gestalten, daß er weitgehend allgemeingültig bleibt, was die Wiederverwendbarkeit in anderen Projekten enorm erleichtert. Eine weitere Möglichkeit wäre auch Kapselung des Script-Codes in einzelne Klassen (Class ... End Class).
Durch die "Auslagerung" der einzelnen Prozeduren in eine eigenständige ASP-Datei kann man auch noch klarer Design und Programmierung voneinander trennen, was am Ende die Wartungsfreundlichkeit des ASP-Codes und die Zusammenarbeit der Abteilungen (Designer/Programmierer) enorm erleichtert.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20011112.zip
Überprüfen von HTML-Formularen mit ASP
http:/www.aspheute.com/artikel/20000522.htm
@-Direktiven auf ASP Seiten
http:/www.aspheute.com/artikel/20000405.htm
Auswertung von HTML Formularen mit ASP
http:/www.aspheute.com/artikel/20000406.htm
Dynamische Includes in ASP
http:/www.aspheute.com/artikel/20000706.htm
Einführung in Stringoperationen
http:/www.aspheute.com/artikel/20001003.htm
Einfache String Operationen
http:/www.aspheute.com/artikel/20000503.htm
Fehlerbehandlung richtig eingesetzt
http:/www.aspheute.com/artikel/20001011.htm
Global.asa: Verwendung, Events und Probleme
http:/www.aspheute.com/artikel/20001018.htm
Klassen in VBScript
http:/www.aspheute.com/artikel/20000526.htm
Session Variablen - Verwendung und Stolpersteine
http:/www.aspheute.com/artikel/20000505.htm
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.