ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 18.10.2000

Diese Seite wurde zuletzt aktualisiert am 18.10.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Eindeutige Schlüssel

Zurück...


Anzeige

(-hg) mailto:hg_keyunique@aboutvb.de

Probieren Sie doch einmal folgendes aus:

Dim colTest As New Collection

colTest.Add "Item1", "daß"
colTest.Add "Item2", "dass"

An und für sich sieht das doch ganz gut aus - es werden zwei Elemente mit offensichtlich verschiedenen Schlüsseln hinzugefügt. Doch Sie erhalten den Laufzeitfehler 457 - "Dieser Schlüssel ist bereits einem Element dieser Auflistung zugeordnet".

Bei Schlüsseln aus Wörtern in verständlicher Sprache mögen Sie das Problem ja gegebenenfalls noch umgehen können, indem Sie auch für sich die beiden Schreibenweisen als identisch betrachten und sie eventuell vor der Schlüsselzuweisung entsprechend umwandeln. Doch wenn es sich um abstrakt (anhand welcher Kriterien und aus welchen Gründen auch immer) generierte Schlüssel handelt, etwa "a9xssv&t" und "a9xßv&t", dann sollten die beiden Schlüssel wohl doch als voneinander verschieden behandelt werden können.

Warum macht aber die Collection intern aus dem "ß" ein "ss"? Zwei Gedanken führen auf die Spur des Phänomens. Der erste: Die Collection ignoriert auch die Groß-/Kleinschreibung. Der zweite Gedanke: Sie behandelt auch noch andere Zeichen auf gleiche Weise, nämlich die Zeichen "Æ" (Ascii 198) und "æ" (Ascii 230). Letztere beiden werden wie "AE" und "ae" behandelt (wobei es auch nur um die Groß-/Kleinschreibungsvarianten handelt, die es beim "ß" ja nicht gibt). Bei keinem anderen Zeichen sonst tritt das Phänomen auf.

Alle drei Zeichen haben übrigens eines gemeinsam: Es handelt sich um so genannte "Ligaturen". Das sind zu einem Zeichen verschmolzene, ursprünglich einmal getrennt mit zwei Zeichen geschriebene Buchstaben bzw. Laute (Eigentlich müsste zwar das "ß" im Sinne der ursprünglichen Verschmelzung in "sz" aufgelöst werden, aber diese Auflösung ist etwas verstaubt und wird heute kaum noch verwendet, "auszer" von wohl einigen wenigen EMail-/NG-Anti-Umlaut-Fans...). Die Auflösung der Ligatur-Zeichen in Einzelzeichen tritt auch bei der Anwendung der Vergleichsmethode nach der Anweisung "Option Compare Text" auf, die global für ein Modul in dessen Deklarationsteils platziert werden kann (etwa beim Like-Operator), und bei Funktionen wie StrComp, InStr, InStrRev, Replace usw., bei denen die Vergleichsmethode "vbCompareText" per optionalem Parameter angegeben werden kann.

Daraus ergibt sich, dass die Collection offensichtlich intern und unabhängig von der Moduleinstellung (die ja in der Voreinstellung standardmäßig einem "Option Compare Binary" entspricht) die Textvergleichsmethode verwendet. Leider lässt sich diese interne Voreinstellung der Collection nicht ändern - sie bietet weder eine entsprechende Eigenschaft oder (optionale) Parameter dazu, und sie reagiert auch nicht auf eine Änderung der Voreinstellung eines Moduls.

Sie werden wohl oder übel die Schlüssel modifizieren müssen. Es würde allerdings wenig nützen, jeden Schlüssel vor Verwendung einzeln auf das Vorkommen einer Ligatur hin zu prüfen und irgendwie zu modifizieren. Denn jede willkürliche Modifikation könnte schließlich auch auf "natürliche" Weise vorkommen. So wäre eine wirkliche Eindeutigkeit nicht zu gewährleisten, wenn Sie nicht exakt vorherbestimmen können welche Schlüssel auftreten könnten. Nur eine systematische Modifikation aller Schlüssel hilft in diesem Fall.

Um lediglich das Ligaturen-Problem zu lösen, würde eine Unterscheidung der Länge genügen. Hängen Sie jeweils die Längenangabe an den Schlüssel an, unterscheiden sich ein Schlüssel der eine Ligatur enthält, und ein Schlüssel, der eine aufgelöste Ligatur enthält, eindeutig voneinander.

Wenn Sie jedoch noch den Schritt weiter gehen wollen und vollkommen eindeutige Schlüssel benötigen, die auch hinsichtlich der Groß-/Kleinschreibung eindeutig sind, wird es etwas aufwändiger. Der Aufwand wird sicher auch etwas Performance und Speicher kosten. Doch da Schlüssel meistens recht kurze Strings sind, mag das, falls es wirklich auf die Eindeutigkeit ankommt, nicht so sehr ins Gewicht fallen. Zu lösen wäre also folgende Aufgabe:

Dim colTest As New Collection

colTest.Add "Item1", "abc"
colTest.Add "Item2", "ABC"

Und wie erhalten Sie nun einen, für solche Zwecke "binären", eindeutigen Schlüssel? Nun, fügen Sie einfach hinter jeden Kleinbuchstaben ein Leerzeichen und hinter jeden Großbuchstaben ein beliebiges, einmal festgelegtes Zeichen (etwa Ascii 255) ein. Dadurch unterscheiden sich nun in der Folge Groß- und Kleinbuchstaben aufgrund des jeweils nachfolgenden Zeichens. Ebenso ist das Ligaturen-Problem gelöst, da in einem Schlüssel vorkommende aufgelöste Ligaturen ("ss", "AE", "ae") schon vor der Zuweisung als Schlüssel an die Collection durch das zusätzlich eingefügte Zeichen auseinandergerissen werden.

Die folgende Hilfsfunktion KeyUnique präpariert einen Schlüssel nach Wunsch. Sie können im optionalen Parameter CompareMethod den Grad der Eindeutigkeit angeben. Die Voreinstellung ist kuCompareText - der Schlüssel wird nicht präpariert und die Collection verhält sich wie gewohnt. Geben Sie kuCompareLigatures an, werden nur Ligaturen eindeutig umgesetzt, Groß- und Kleinschreibung sind, wie bei der Collection gewohnt, weiterhin nicht eindeutig. Die Angabe kuCompareBinary hingegen sorgt (wie beschrieben) dafür, dass ein Schlüssel in jedem Fall eindeutig ist. Diese Art der Schlüsselpräparierung verhilft Ihnen auch zu eindeutigen Schlüsseln bei anderen Collections (etwa der Nodes-Collection beim TreeView-Steuerelement), die ebenfalls nicht die Groß-/Kleinschreibung berücksichtigen, selbst wenn sie keine Probleme mit den Ligaturen haben sollten.

Public Enum CompareMethodConstants
  kuCompareBinary
  kuCompareLigatures
  kuCompareText
End Enum

Public Function KeyUnique(Key As String, _
 Optional ByVal CompareMethod As CompareMethodConstants = _
 kuCompareText) As String

  Dim nRetKey As String
  Dim l As Long
  Dim nChar As String
  
  Select Case CompareMethod
    Case kuCompareBinary
      nRetKey = Space$(Len(Key) * 2)
      For l = 1 To Len(Key)
        nChar = Mid$(Key, l, 1)
        If UCase(nChar) = nChar Then
          Mid$(nRetKey, l * 2 - 1, 2) = nChar & Chr$(255)
        Else
          Mid$(nRetKey, l * 2 - 1, 1) = nChar
        End If
      Next 'l
      KeyUnique = nRetKey
    Case kuCompareLigatures
      KeyUnique = Key & CStr(Len(Key))
    Case kuCompareText
      KeyUnique = Key
  End Select
End Function

Modul und Beispiel-Projekt KeyUnique (keyunique.zip - ca. 2,3 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer