ASP Classic

Mit multidimensionalen Arrays zählen

Anzahl von Teil-Strings in einer Tabelle ermitteln

Wer mit Datenbanken hantiert kommt das ein oder andere Mal in die Situation Datensätze zählen zu müssen. Mit SQL eigentlich kein Problem. Etwas kniffliger wird die Sache, wenn man ermitteln möchte wie oft ein Teil eines Feldinhaltes in einer Tabelle vorkommt.

Ein Beispiel: fast alle Webs bieten ein Log in dem festgehalten wird, welche Zugriffe stattgefunden haben. Dabei wird u.a. die IP-Adresse und der Host-Name des Besuchers festgehalten. Möchte man nun eine Auswertung über die Host-Namen erstellen, ist es sinnvoll nur den Domain-Namen und die Top-Level-Domain heranzuziehen, da die Sub-Domains aufgrund der Zuweisung von dynamischen IP-Adressen bei den meisten Providern immer anderes lauten. Beispielsweise lautet der Host-Name eines Telekom-Kunden p1451708C.dip.t-dialin.net. Um nun zu erfahren wieviele Besucher über die Telekom die Seite besuchen ist nur der Teil-String t-dialin.net relevant.

Da in der Tabelle aber nur der gesamte String steht, muss der String an den Punkten aufgeteilt werden, um anhand der letzten beiden Teile die gleichlautenden Einträge in der Tabelle zu zählen. Mit SQL ist das zwar möglich, aber etwas aufwendiger. Einfacher ist es über alle Datensätze der Tabelle zu gehen, den relevanten Teil des Host-Namens auszuschneiden und diesen zu zählen. Aber wo sollen die bereits aufgetretenen Einträge und der Zähler abgelegt werden? In einem zweidimensionalen Array mit dem Host-Namen als erste und dem Zähler als zweite Dimension.

Dimensionieren wir uns zunächst ein entsprechendes Sammel-Array und initialisieren es mit zwei Dimensionen (0 und 1)

Dim arrHosts()
ReDim arrHosts(0, 1)

Als nächstes brauchen wir den Zugriff auf die entsprechende Tabelle über ein ADO-Recordset, die wir anschließend mit einem Do...Loop vom ersten bis zum letzten Datensatz durchlaufen:

... Datenbankverbindung aufbauen und Recordset initialisieren
Do Until rs.EOF
   ...
Loop

In dieser Schleife überprüfen wir für jeden Datensatz als erstes, ob in dem zu verarbeitenden Host-Namen überhaupt ein Punkt vorkommt, nach dem wir den String trennen können. Wenn ja, wird er mit der Split-Funktion in ein Hilfs-Array zerlegt und die letzten beiden Teile in der Variable strHost gespeichert. Wenn nein, dann wird der gesamte Host-Name verwendet:

If Instr(1, rs.Fields("HostName"), ".") > 0 then
   arrTemp = Split(rs.Fields("HostName"), ".")
   strHost = arrTemp(UBound(arrTemp) - 1) & "." & arrTemp(UBound(arrTemp))
Else
   strHost = rs.Fields("HostName")
End if

Als nächstes müssen wir überprüfen, ob der Host-Name bereits in unserem Sammel-Array arrHosts enthalten ist. Dies geschieht, in dem in einer Schleife der Wert der ersten Dimension mit dem aktuellen Host-Namen verglichen wird. Wird er gefunden, so wird der Wert der korrespondierenden zweiten Dimension um eins erhöht und über die Variable bolFound gekennzeichnet, dass der Host-Name bereits verarbeitet wurde:

For j = 0 To UBound(arrHosts)
   If arrHosts(j, 0) = strHost Then
      arrHosts(j, 1) = arrHosts(j, 1) + 1
      bolFound = True
      Exit For
   Else
      bolFound = False
   End If
Next

Ist der Host-Name nicht bereits im Array enthalten, müssen wir nun zunächst das Array für den neuen Eintrag erweitern. Leider ist es jedoch so, dass die VBScript-eigene Funktion ReDim Preserve dies zwar erledigen kann, aber immer nur für die letzte Dimension. Wir müssen jedoch an die erste Dimension ein weiteres Feld anhängen! Da hilft nur eine Zusatzprozedur, in der das Array einfach in ein neues umkopiert wird. Das Original-Array wird hierbei ByRef übergeben.

Exkurs:

Public Sub ReDimEx(arrSource, intNewX, intNewY)

   Dim arrTemp
   Dim i, j

   arrTemp = arrSource
   ReDim arrSource(intNewX, intNewY)

   For i = LBound(arrTemp, 1) To UBound(arrTemp, 1)
      For j = LBound(arrTemp, 2) To UBound(arrTemp, 2)
         If i <= intNewX And j <= intNewY Then
            arrSource(i, j) = arrTemp(i, j)
         End If
      Next
   Next

End Sub

Mit dieser Prozedur können wir nun den neuen Host-Namen an das Sammel-Array anfügen:

If bolFound = False Then
   Call ReDimEx(arrHosts, UBound(arrHosts, 1) + 1, UBound(arrHosts, 2))
   arrHosts(UBound(arrHosts, 1) - 1, 0) = strHost
   arrHosts(UBound(arrHosts, 1) - 1, 1) = 1
End If

Wurden alle Datensätze verarbeitet und ist die Datenbankverbindung wieder geschlossen, können wir uns abschließend um die Darstellung der Array-Einträge kümmern:

For i = 0 to Ubound(arrHosts, 1)

   strHostName = arrHosts(i, 0)
   strHostCount = arrHosts(i, 1)

   ... Darstellung z.B. in einer Tabellenzelle

Next
kick it on dotnet-kicks.de AddThis Trackback-Url...

Keine Kommentare bislang...

Dein Kommentar hierzu...


Kommentar-Feed für diesen Beitrag
Gravatare werden unterstützt .:. eMail-Adressen werden nicht veröffentlicht
 

RSS-Feed

Die URL des Standard-Newsfeed von zerbit.de lautet:

http://www.zerbit.de/rssfeed.aspx

Login


 

 

Statistik



kürzlich kommentiert

Artikel 31

  • Datum: 09.05.2005
    Kategorie: ASP Classic
    Zugriffe: 1.292
    Kommentare: 0
    Trackbacks: 0

Letzte Beiträge

Kategorien

Buttons & More

Blog-Roll

Banner Piraten-Partei