© Martin Korneffel, Stuttgart 2005 +++ email: trac@n.zgs.de +++ web: www.s-line.de/homepages/trac

VB.NET

Inhalt

  1. Einführung

    1. Historische Entwicklung

    2. Ziel der Programmierung

    3. Grundprinzipien der Programmierung

  2. VB.NET Compiler

    1. Option Explicit und Option Strict

    2. Übersetzen auf der Kommandozeile

    3. Präprozessordirektiven

      1. # const

      2. #if ... then #else

      3. # region

    4. Aufbau eines VB.NET Programmes

      1. Module und Klassen

      2. Namespaces

        1. Imports- Direktive

      3. Literale

      4. Operatoren

      5. Variablen

        1. Deklaration in VB.NET

        2. VB.NET Datentypen

        3. Zugriffsmodifikatoren

        4. Initialisierung

        5. Blockstruktur, Sichtbarkeit und Lebensdauer von Variablen

        6. Statische Variablen

      6. .NET Datentypen

      7. Referenztypen vs Wertetypen

      8. Boxing und Unboxing- Konvertierung

      9. Typ bestimmen

        1. is Operator

        2. Typvergleich mittels TypeOf ... is

        3. GetType() Methode

        4. GetType(x as Object) - Operator

      10. Implizite Typkonvertierung

      11. Explizite Typkonvertierung

      12. Reflektion

      13. Spezialwert Nothing

      14. Elementare Ein/Ausgabe

        1. Formatzeichenfolgen

        2. Formatzeichenfolgen für nummerische Typen

        3. Formatzeichenfolgen für Datumstypen

        4. Formatzeichenfolgen für Aufzählungstypen

        5. ToString und Formatierung

        6. Ausgabe mit IFormatProvidern

        7. Composit- Formating

      15. Enumerations

      16. Datenstrukturen

      17. Steuerung der Programmausführung

        1. Bedingt ausführbarer Programmabschnitt

        2. Bedingt wiederholbarer Programmabschnitt

      18. Arrays

        1. Initialisierung von Arrays

        2. Anzahl der Einträge bestimmen

        3. Zuweisen und Kopieren

        4. Redimensionierung

        5. Besuchen aller Einträge eines Arrays mittels foreach - Schleife

        6. Arrays sortieren

        7. Array mit selbstdefinierten Typen Sortieren

      19. Datum und Uhrzeit

      20. Chars

        1. Objektmodell von char

        2. Chars und Unicode

      21. Strings

        1. Teilstrings ausschneiden

        2. Umwandeln in Groß- oder Kleinschreibung

        3. Startposition von Teilstrings bestimmen

        4. Einfügen in Strings

        5. Auftrennen von Zeichenfolgen

        6. Splitten mittels Reguläre Ausdrücke

        7. Ersetzen mittels Regulärer Ausdrücke

      22. Funktionen und Prozeduren

        1. Mathematische Funktionen

        2. Optionale Parameter

        3. Parameterarrays

        4. Delegate (Funktionszeiger)

        5. Deklaration eines Delegate

Einführung

BASIC ist ein Akronym (Beginner’s All-purpose Symbolic Instruction Code = Allzweck-Symbolbefehlssprache für Anfänger) und bezeichnet eine Programmiersprache, die Mitte der 60-er von den US- Amerikanern John Kemeny und Thomas Kurtz entwickelt wurde. Sie diente ursprünglich für Schulungszwecke.

Ursprünglich war BASIC als Interpretersprache konzipiert. Ein geringer Umfang an Befehlen, die Insensitivität gegenüber der Groß/Kleinschreibung und die Interaktivität durch den Interpreter führten dazu, daß BASIC inbesondere unter Anfängern beliebt wurde.

Historische Entwicklung


Ziel der Programmierung

Standardsoftware anpassen

Beispiel: EXCEL wird als Kalkulationssoftware eingesetzt. Bestimmte Kalkulationen sollen online auf einem Webserver veröffentlicht werden, indem Inhalte aus Tabellenzellen in Datenbanktabellen auf dem Webserver übertragen werden. Für den Anwender soll die Übertragung genauso einfach wie ein Speichern des Arbeitsblattes sein. Als Werkzeug bietet sich hier VB und VBA an.

Automatisierung

Sich wiederholende, komplexe Arbeitsabläufe können in einem Script erfasst, und auf Knopfdruck gestartet werden. Beispiele: Backup von Datenbanken/Festplatten, Wiederherstellen von Arbeitsoberflächen (Anmeldescripte). Als Werkzeuge bieten sich hier Scriptsprachen wie PERL ound VBScript an.

Individualsoftware erstellen

Auf einer Plattform (PC oder Microcontroller) wird eine völlig neue Anwendung erstellt. Als Werkzeuge bieten sich hier Entwicklungsumgen wie Visual C++ oder Visual.NET an. Dies ist der kompliziteste Fall. Die Entwicklung von Individualsoftware kann sogar zur entwicklung völlig neuer Programmierwerkzeuge führen (UNIX-> C, DHTML-> JavaScript)

Grundprinzipien der Programmierung

EVA- Prinzip




Kommunizierende Objekte - das Paradigma der objektorientierten Programmierung

Die Welt besteht aus Objekten, die miteinander kommunizieren. Die Kommunikation erfolgt über Botschaften, die in den meisten objektoriantierten Sprachen als Methoden realisiert sind. Botschaften können Produkte von Ereignissen im System sein wie z.B. das Anklicken einer Schalftfläche durch einen Benutzer. Anderseits können Botschaften programmgesteuert an Objekte gesendet werden. Damit lassen sich Verarbeitungsformen wie Stapelverarbeitung (übergabe der Kontrolle an ein weiteres Objekt) und Client/Server (Ausfrufen eines Dienstes im Objekt) realisieren.



VB.NET Compiler

Im folgenden werden die Stufen der Übersetzung eines VB.NET- Programmsdargestellt:


Option Explicit und Option Strict

Die Strenge der Typisierung von VB kann über zwei Schalter gesteuert werden.

Option Explicit erzwingt bei On, daß alle Variablen vor ihrer Verwendung deklariert werden müssen.

Option Strict erzwingt zusätzlich eine strenge Typisierung: Deklarationen müssen Typen definieren, die Zuläsigkeit von Konvertierungen werden während der Kompilation und auch während der Laufzeit überwacht.

In Visual Studio 2005 können diese Optionen für alle VB- Projekte eingestellt werden unter

Extras/Optionen/Projekte und Projektmappen/VB Standard

Für jedes einzelne VB- Projekt kann davon in den Projekteinstellungen abweichend konfoguriert werden.

Übersetzen auf der Kommandozeile

Im Folgenden wird ein einfaches Programm erstellt, welches auf der Kommandozeile den String "Hallo Welt" ausgibt. Anhand des Programmes wird die Kompilation in MSIL sowie das Kompilat selbst untersucht.

Beispiel Hallo Welt

Legen sie eine Datei namens Hallo.vb an.

=> Quelltexte werden in Unicode- Dateien mit der Endung vb gespeichert.

' VB.NET Kennenlernen
' Kommentare sind einzeilig und werden mit einem Hochkomma (') eingeleitet
' Alle Prozeduren und Funktionen müssen in einem Modul-
' oder Klassenblock eingeschlossen werden
Module m1

    ' Die Prozedur Main hat eine besondere Bedeutung: Beim Programmstart 
    ' wird vom Lader des Betriebssystems an diese die Kontrolle übergeben
    Sub Main() 

        ' Hier wird ein Unterprogramm aus der Bibliothek System.dll aufgerufen
        ' Mittels des Unterprogramms Console.WriteLine erfolgt die Ausgabe
        ' der Zeichenkette "Hallo Maja" auf der Kommandozeile
        System.Console.WriteLine("Hallo Maja")

    End Sub

End Module

Übersetzen

Das Beispielprogramm kann auf der Kommandozeile (Visual- Studio- Tools/Command Prompt) durch folgenden Befehl kompiliert werden:

c:\vb-kurs\vbc hallo.vb /r: System.dll

Die Option /r weist den Compiler an, Einsprungpunkte für Unterprogramme aus der Bibliothek System.dll anzulegen.

Präprozessordirektiven

Mittels Präprozessordirektiven können Abschnitte von der Kompilation ausgeschlossen werden.

# const

Mit #const kann eine Konstante definiert werden, die in Präprozessorblöcken für die bedingte Kompilation ausgewertet wird. Die Konstanten müssen als erste Anweisungen in einer Quelltextdatei definiert werden.

#const XX_GRUSS_MAJA = True
Module m1

    Sub Main() 
       :
   End Sub
End Module

Hier wird eine Konstante namens XX_GRUSS_MAJA deklariert.

Nicht deklarierte Konstanten in Präprozessorblöcken werden durch Nothing ersetzt und stellen damit den boolschen Wert false dar.

#if ... then #else

In Abhängigkeit von bedingten Konstanten können Abschnitte im Quelltext von der Kompilation ausgeschlossen werden oder nicht:

#const XX_GRUSS_MAJA = True
Module m1

    Sub Main() 

#if XX_GRUSS_MAJA then
        System.Console.WriteLine("Hallo Maja")
#else
        System.Console.WriteLine("Hallo Marina")
#endif

   End Sub
End Module

In diesem Beispiel wird die Zeile zwischen #else ... #endif nicht kompiliert. Wenn die erste Zeile (#const ...) auskommentiert wird, dann erfolgt keine Kompilation für die Zeile zwischen #if ... #else.

# region

Dient zur logischen Gliederung des Quelltextes. Die IDE kann Regionen wahlweise auf- und zuklappen. Bsp.:

#region "mm"
  sub p1
   ...
  end sub
  sub p2
   ...
  end sub
#end region

Aufbau eines VB.NET Programmes

VB.NET ist eine vollständig objektorientierte Programmiersprache. Im Mittelpunkt der Progammierung mit VB.NET steht

  1. die Beschreibung des Aufbaus von Objekten durch Klassendeklarationen

  2. das Senden von Nachrichten an Objekte durch Methodenaufrufe

  3. die Reaktion auf asynchrone Nachrichten/Ereignisse durch Ereignisse

Module und Klassen

Die gesamte Logik muß in Klassendeklarationen verpackt werden. Es gibt 2 Arten von Klassendeklarationen:

Module

Class

Alle Elemente sind implizit shared

Zugriff auf die Elemente muss individuell festgelegt werden

Folgendes Beispiel zeigt ein einfaches Befehlszeilenprogramm. Es wird durch eine Modul- Klassendeklaration realisiert.

Module Module1

    Class class1

        Public x As Short

        Sub New() ' Konstruktor
            x = 99
        End Sub

        Function add_to_x(ByVal s As Short)
            Return x + s
        End Function
    End Class

    Sub Main()

        ' Hier steht ein Kommentar

        Dim x, y As Short
        Dim c As New class1

        x = 1

        ' Werte von x aus Main und x aus c ausgeben

        Console.WriteLine("Wert von x= {0:D}", x)
        Console.WriteLine("Wert von c.x= {0:d}", c.x)

        ' Eine Memberfunktion von class1 aufrufen
        y = c.add_to_x(5)

        ' Das Ergebnis in y ausgeben
        Console.WriteLine("Wert von c.x= {0:d}", y)

        ' Warten auf eine Eingabe des Benutzers
        Console.ReadLine()

    End Sub

End Module

Namespaces

Namespaces dienen zur Abgrenzung der Namensmengen zwischen verschiedenen Teilen von Bibliotheken und Programmen.

Namespace outer 

  Namespace inner 

     ' Deklaration des Namens x im Namespace outer.inner
     public x as Integer

  End Namespace

End Namespace

// Zugriff auf x 
outer.inner.x = 99;

Imports- Direktive

Imports Namespace
Imports Alias = Namespace

Literale

Menge

Beispiel

ganze Zahlen, dezimal

123

ganze Zahlen, Hexadezimal

&HAF

ganze Zahlen, Oktal

&O73

negative Zahlen

-123

rationale Zahlen

123.4

rationale Zahlen in Exponentialschreibweise

1.23e4

Zeichen

"A"C

Zeichenketten

"ABC"

Wahrheitswerte

true oder false

Datumsangaben (ami- Format MM/DD/YYYY)

#02/13/2004#

Operatoren

Operator

Beschreibung

( )

Klammern

^

Potenzieren

-

negatives Vorzeichen

* /

Multiplikation und Division

\

Integer Division

Mod

Modulo bzw. Rest aus Division, z.B. 7 Mod 3 = 1 denn 2*3 + Rest 1 = 7

+ -

Addition und Subtraktion

< > =

kleiner als, größer als, gleich

<> <= >= Like Is TypeOf

ungleich, kleiner gleich, größer gleich wie ist Typ-von

Not

logisches NICHT (Negation)

And Or

logisches UND, logisches ODER

Xor Equ

logisches Exlisiv ODER, Äquivalenz

Variablen

Unsere Programme realisieren Algorithmen, mit denen wir Daten verarbeiten. Um Zugriffe auf die Daten im Computerspeicher zu formulieren, muß uns die Programmiersprache entsprechende Ausdrucksmittel zur Verfügung stellen.

Ein elementares Ausdrucksmittel für Speicherzugriffe sind Variabeln.

Unter Variabeln können wir uns benannte Speicherplätze vorstellen. Variabeln sind immer vor ihrer Verwendung im Programmtext mittels einer Deklaration zu vereinbaren. In der Deklaration wird der zu verwendende Name für den Speicherplatz und der Datentyp festgelegt.

Deklaration in VB.NET

Zugriffsmodifikatoren Variabelname As Datentyp [= Startwert]

Der Datentyp steht für eine Klasse von Daten. Beispielsweise verbirgt sich hinter dem Datentyp Integer die Menge aller ganzen Zahlen im Intervall [-32768, 32767]. Der Datentyp bestimmt, wie die Informationen als Dualzahlen im Speicher zu verschlüsseln sind, und wieviel Speicherplatz für die Variabel benötigt wird. So werden Variabeln vom Typ Integer vom Dezimal- ins Dualsystem konvertiert, und für sie ein Speicherplatz von 16bit = 2Byte reserviert.

VB.NET Datentypen

Die primitiven Typen sind im Namespace System definiert:

VB.NET

CTS

Wertebereich

Literale

Boolean

System.Boolean

{true, false}

true


System.SByte

[-128, 127]

99

Byte

System.Byte

[0, 255]

255

Char

System.Char

[0, 65535]

"A"C

Short

System.Int16

[-32768, 32767]

199S


System.UInt16

[0, 65535]

199

Integer

System.Int32

[-2147483648, 2147483647]

199


System.UInt32

[0, 4294967295]

199 oder 199U

Long

System.Int64

[-9223372036854775808, 9223372036854775807]

199 oder 199L


System.UInt32

[0, 18446744073709551615]

199 oder 199UL

Single

System.Single

[-3.402823E+38, 3.402823E+38]

3.14 oder 3.14F

Double

System.Double

[-1.79769313486232E+308, 1.79769313486232E+308]

9.0 oder 9D

Decimal

System.Decimal

[0, 79.228.162.514.264.337.593.543.950.335]

125.99M

String

System.String

0- 2 Mrd. Unicodezeichen

"Hallo Welt"

Date

System.DateTime

00001-1-1 0:0:0 bis 9999-12-31 23:59:59

#5/31/1993#

Object

System.Object

 

 

Zugriffsmodifikatoren

Durch Zugriffsmodifikatoren wird das Prinzip der Kapselung in VB realisiert. Über Zugriffsmodifikatoren wird zur Entwurfszeit gesteuert, von welchen Programmteilen aus auf eine Variable zugegriffen werden kann. Dadurch können Implementierungsdetails von Bibliotheken verborgen werden. Sinn macht die Diskussion der Zugriffsmodifikatoren erst im Zusammenhang mit Klassen. An dieser Stelle wird nur der Zugriffsnodifikator Dim und Static eingeführt:

Zugriffsmodifikator

Beschreibung

Nicht deklarierebar in

Dim

nur im Block sichtbar, in dem deklariert wurde


Static

Definiert eine lokale Variable innerhalb einer Prozedur oder Funktion, die für den gesamten Zeitraum des Programmablaufes gültig, aber nur innerhalb der Methode sichtbar ist.

für Member einer Klasse oder Modul

Shared

Definiert einen Klassenmember. Der Member ist unabhängig von Instanzen der Klasse. Entspricht den Modulvariablen oder Prozeduren von VB6


Initialisierung

Für Variablen in statischen Methoden erfolgt eine automatische Initialisierung. Variablen in nichtstatischen Methoden müssen manuell initialsiert werden:

Dim i as int = 0

Blockstruktur, Sichtbarkeit und Lebensdauer von Variablen


Statische Variablen

In Sonderfällen kann es sinvoll sein, die Lebensdauer von Variablen in Funktionen und Prozeduren über die Blockgrenzen hinaus zu verlängern. Soll z.B. Protokolliert werden, wie oft eine Methode in einem Programm schon aufgerufen wurde, dann muß eine Zählervariable bereitgestellt werden, die wie eine Globale Variable zu Programmstart initialisiert und erst bei Programmende vernichtet wird.

Module Utils

   Function MakeID() as Long

     static id as Long = 0
     id += 1
     return id

   End Function

End Module

.NET Datentypen

Alle Typen sind auf den Basistyp System.Object rückführbar. D.h. alle Typen verfügen über die Eigenschaften und Methoden von System.Object.


Referenztypen vs Wertetypen

Die Menge aller Typen, die sich von System.Object ableiten, kann in zwei Teilmengen aufgeteilt werden: den Referenztypen und den Wertetypen. Die Wertetypen werden grundsätzlich auf dem Programmstack angelegt und entsprechen den eigebauten Typen in älteren Programmiersprachen.


Referenztypen erfordern eine Instanzieirung in 2 Schritten:




Boxing und Unboxing- Konvertierung

Zwecks erhöhung der Ausführungsgeschwindigkeit werden Wertetypen auf dem Stack wie in allen anderen nicht .NET- Sprachen als reine Werte abgelegt. Da aber alle Typen konmplexe Objekte darstellen, erfogt eine Konvertierung, wenn ein Wertetyp in einem Objektkontext aufgerufen wird. Dabei wird temporär auf dem Heap ein Objekt angelegt, und der Wert des Wertetypen hinenkopiert. Dies wird als boxing  bezeichnet.

char zeichen = 'A';     // vf ist ein Wertetyp und 
// Im folgenden wird der Wertetyp in einem Objektkontext eingesetzt (zeichen.isDigit())
// Hier wird auf dem Heap ein Objekt erzeugt, dessen Kopie zeichen aufnimmt.
string aussage = zeichen.isDigit() ? "Ziffer" : "keine Ziffer";  

Typ bestimmen

is Operator

Der Is- Operator ergibt True, wenn zwei Referenzen auf dasselbe Objekt verweisen:

If ref_a is ref_b
   return True
End IF

Typvergleich mittels TypeOf ... is

Mittels des typeof- Operators kann zu einer Klasse ein Typ- Objekt erzeugt werden. Er entspricht der statischen Methode System.Type.GetType(..).

if TypeOf a Is Integer Then 
   ....
end if

GetType() Methode

Jedes Objekt erbt von der .net Wuzel System.Object die Methode GetType. Diese liefert ein Type- Objekt, welches alle Metainformationen zu einem Typ enthält.

GetType(x as Object) - Operator

Der GetType(x as Object)- Operator ermöglicht es, zu einem beliebigen Typ (Klassenname) das Type- Objekt zu bestimmen, ohne das ein Instanz notwendig ist.

Implizite Typkonvertierung

Implizite Typkonvertierungen sind zwischen verwandten Datentypen möglich, wenn der Zieltyp mehr Informationen aufnehmen kann als der Quelltyp:




Explizite Typkonvertierung

Explizite Typkonvertierungen erzwingen die Umwandlung von einem Typ in einen anderen. Dabei gibt es jedoch verschieden starke Konvertierungsoperatoren. Auf der einen Steite gibt es die VB- Konvertierungsoperatoren, auf der anderen Seite die Operatoren der Klasse Convert.

VB

VB.NET

Convert-Klasse

x = Cbool(<expr>)

x = Ctype(<expr>, Boolean)

toBoolean(<expr>)

x = Cbyte(<expr>)

x = Ctype(<expr>, Byte)

toByte(<expr>)

x = Cchar(<expr>)

x = Ctype(<expr>, Char)

toChar(<expr>)

x = Cdec(<expr>)

x = Ctype(<expr>, Decimal)

toDecimal(<expr>)

Die Convert Funktionen sind am stärksten Konvertierungsfunktionen. Sie ermöglichen eine konvertierung zwischen an sich inkompatibelen Typen wie Zahlenwerte in Strings in nummerische Werte von Int32 etc.

Reflektion

Die in den Type- Objekten gespeicherten Metainformationen beschreiben die Struktur einer Klasse vollständig. Beispielsweise können alle Member einer Klasse wie folgt aufgelistet werden:

Imports System
Imports System.Reflection


class CTest 
  Dim ganzZahl as Integer
  enum EPartei
       gut
       boese
       gerecht
  End Enum
  Function TueWas() as Integer
     ganzZahl += 1
     Return ganzZahl
  End Function
End Class

:
    Sub Main()

        Dim t As Type

        t = GetType(CTest)

        ' Alle Felder, Eigenschaften und Methoden werden aufgelistet                 

        Dim minfos() As MemberInfo = t.GetMembers()

        For Each minfo As MemberInfo In minfos
            Console.WriteLine("{0}", minfo.ToString())
        Next

    End Sub

Aufgaben

  1. Entwickeln Sie eine Klasse CTypeBrowser, welche die Methode info(object) implementiert, die zu einem gegebenen Objekt alle Felder und Methoden auflistet.

Spezialwert Nothing

Nothing ist ein spezieller Wert, der jeder Variablen zugewiesen werden kann.

Zuweisung an Variable vom

bewirkt

Wertetyp

Die Variable wird auf ihren Standardwert zurückgesetzt (Strings z.B. auf leere Zeichenkette)

Referenztyp

Bei Objektvariablen verweisen diese nicht mehr auf das Objekt. Das Objekt wird jedeoch erst gelöscht, wenn die Garbage Collection keine Verweise auf das Objekt vorfindet.



Elementare Ein/Ausgabe

Beispiel:

Dim preis As Dezimal = 99.45
Console.WriteLine("Preis: {0,10:########.##}€", preis)

Formatzeichenfolgen

Über Formatzeichenfolgen wird abhängig vom Datentyp die Darstellung eines Wertes als String gesteuert. Es gibt Formatzeichenfolgen für:

Formatzeichenfolgen für nummerische Typen

Formatzeichenfolgen bestehen aus einem Formatbezeichner und optional aus der Angabe einer Genauigkeit XX. Um eine Zahl mit max. 3 Nachkommastellen auszugeben, kann folgende Formatzeichenfolge verwendet werden:

N3

Folgende Formatbezeichner sind vordefiniert:

Formatbezeichner

Bedeutung

Beispiel

Resultat

C

Währungsbetrag

(99.490).ToString("C")

99,49 €

D

Ganzzahliger Wert. Die Genauigkeit definiert die minimale Ausgabebreite. Sollte die darzustellende Zahl die minimale Ausgabebreite nicht erreichen, dann wird mit führenden 0-en aufgefüllt

(123).ToString("D5")

00123


E

Zahl in Exponentialschreibweise

(99.49).ToString("E")

9,95E+005

F

Festkomma. Die Genauigkeit gibt eine feste Anzahl von Nachkommastellen an

(99.49).ToString("F1")

99,5

G

Allgemein- Formatierung erfolgt abhängig vom Typ der Zahl

(99.49).ToString("G")

99,5

N

Zahl (allgemein). Die Genauigkeit beschreibt die Anzahl der Nachkommastellen

(99.49).ToString("N")

99,49

P

Prozentzahl. Der Wert wird mit 100 multiplizieret und mit einem Prozentzeichen versehen

(0.15).ToString("P")

15,00%

H

Hexadezimal

(0xA1).ToString("H")

A1

R

Stellt Zahlen so als Zeichenkette dar, daß sie aus diesen ohne Genauigkeitsverlust wieder zurückkonvertiert werden können.

(99.49).ToString("R")

99,49

Neben vordefinierten Formatzeichenfolgen können Formate wie im obigen Beispiel auch selbst definiert werden. Siehe dazu: Benutzerdefinierte Formatzeichenfolgen

Formatzeichenfolgen für Datumstypen

Formatbezeichner

Bedeutung

Beispiel

Resultat

d

Kurzes Datumsformat

DateTime.Now.ToString("d")

27.04.06

D

Langes Datumsformat

DateTime.Now.ToString("D")

27. April 2006

T

Zeitformat

DateTime.Now.ToString("T")

12:17:59

s

ISO 8601 konformes Datumsformat. Werte sind sortierbar. Dieser Typ wird z.B. in XML- Schema angewendet

DateTime.Now.ToString("s")

2006-04-27T12:17:47

Formatzeichenfolgen für Aufzählungstypen

Formatbezeichner

Bedeutung

Beispiel

Resultat

G

Stellt Wert eines Aufzählungstyps als String dar, falls möglich. Andernfalls wird der Wert als Integer- Zahlenwert dargestellt

(SUnits.cm).ToString()

"SUnits.cm"

F

Stellt Wert eines Aufzählungstyps als String dar, falls möglich. Andernfalls wird der Wert als Integer- Zahlenwert dargestellt

(SUnits.cm).ToString()


D

Stellt Wert eines Aufzälungstyps als dezimalen Integer dar

(SUnits.cm).ToString()

2

X

Stellt Wert eines Aufzälungstyps als hexadezimalen Integer dar

(SUnits.cm).ToString()

0x2

ToString und Formatierung


Ausgabe mit IFormatProvidern

Imports System.Globalization;

' Kopie des aktuell wirksamen Formatproviders erzeugen
Dim nif as NumberFormatInfo 
nif = CType(System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.Clone(),  NumberFormatInfo)

' Währungssysmbol auf Dollar umstellen
nif.CurrencySymbol = "$"

' Ausgabe eines Währungswertes
Dim preis as Double
preis = 99.99
Console.WriteLine(preis.ToString("C", nif))

Composit- Formating

In Methoden wie Console.WriteLine("Formatstring", object, ...) können Textkonstanten und Formatblöcke, die Formatzeichenfolgen für auszugebende Parameter enthalten, kombiniert werden. Dies wird als Composit- Formating bezeichnet. Soll z.B. ein Längenmaß ausgegeben werden, welches aus dem Wert und der Längeneinheit besteht, dann könnte dies durch folgende Anweisung erfolgen:

Console.WriteLine("Längenmaß: {0,5:N} {1,2}", LMasz.value, LMasz.unitToString());

Ein Formatblock hat folgende Syntax:

{ParamListenIndex[,alignment][:Formatzeichenfolge]}

Der ParamListenIndex bezeichnet den Parameter aus der Parameterliste, dessen Wert durch den Parameterblock formatiert werden soll. Das Alignment definiert die Ausrichtung und mindestbreite. Positive Werte stehen für eine Rechtsausrichtung, negative für eine Linksausrichtung.

Enumerations

Endliche Mengen lassen sich durch Aufzählungen modellieren (Enumarations). Beipiel:

Enum enumLaengenEinheiten
  mm
  cm
  dm
  m
  km
  AE
  LichtJahr
End Enum

Datenstrukturen

Datenstrukturen werden deklariert durch Blöcke mit dem Schlüsselwort Structure (bei VB 6.0 Type). Jedes Element einer Strukture muß mit einem Zugriffsmodifikator versehen werden (Public, friend, Protected, Private). Dim entspricht dem Zugriffsmodifikator Public.

Structure Point 
  
  Dim x as Double
  Dim y as Double

End Structure

Merkmale von Strukturen

Steuerung der Programmausführung

In seiner Grundbetriebsart lädt der Computer eine Anweisung nach der anderen aus dem Arbeitsspeicher und führt sie aus. Viele Algorithmen erfordern jedoch, daß einige Abschitte aus den Anweisungslisten nur unter bestimmten Bedingungen auszuführen sind (z.B. „Wenn bis zum Tag X kein Zahlungseingang erfolgte, dann Mahnung abschicken“) oder wiederholt werden müssen. Um dies zu ermöglichen, verfügt der Computer über spezielle Anweisungen, die den Befehlszählerstand manipulieren. Sie bewirken, daß nach ihrer Ausführung das Programm an einer beliebigen neuen Adresse fortgesetzt wird. Aufgrund dieser Wirkung werden sie Sprunganweisungen genannt.

In VBA sind die Sprunganweisungen in Form von bedingt ausführbaren, oder bedingt wiederholbaren Programmabschnitten implementiert.

Bedingt ausführbarer Programmabschnitt

Der bedingt ausführbare Programmabschnitt entspricht einer Wenn ... dann Regel.

IF Bedingung Then
   Anweisung 1
   Anweisung 2
       :
   Anweisung n
End IF

Trifft die Bedingung nicht zu, dann kann anschließend mit dem Schlüsselwort Else ein Programmabschnitt als Alternative formuliert werden:

IF Bedingung Then
   Anweisung 1
       :
   Anweisung n
Else
   Anweisung n+1
       :
   Anweisung n+m
End IF

Gibt es mehrere Alternativen, die von Zusatzbedingungen abhängig sind, dann können diese in ElseIf- Blöcken formuliert werden:

IF Bedingung Then
   Anweisung 1
       :
   Anweisung n
ElseIF Bedingung2
   Anweisung n+1
       :
   Anweisung n+m
End IF

Ist die Ausführung mehrerer Programmabschnitte vom Wert eines einzigen Ausdrucks abhängig, dann kann alternativ zu ElseIf eine vereinfachte Schreibweise mittels Select Case Block gewählt werden:

Select Case Ausdruck
Case Wert1
     Anweisung 1
         :
     Anweisung n
Case Wert2
     Anweisung n+1
         :
     Anweisung n+m
Case Wert3
  :
Case Else
     Anweisung 
End Select 

Bedingt wiederholbarer Programmabschnitt

Es handelt sich hierbei um Programmabschnitte, die sooft wiederholt werden, solange eine Bedingung zutrifft (wahr ist). Sie werden gewöhnlich als Schleifen bezeichnet. Zwei elementare Formen der Schleifen werden unterschieden: die abweisende, und die nichtabweisende Schleife.

Bei der abweisenden Schleife wird stets am Anfang des Programmabschnittes geprüft, ob die Bedingung für eine Ausführung des Abschnittes erfüllt ist. Wenn ja, dann wird der Programmabschnitt ausgeführt, und am Ende der Befehlszähler wieder auf die Startadresse des Programmabschnittes gesetzt. Gilt die Bedingung weiterhin, dann erfolgt eine wiederholte Ausführung des Programmabschnittes. Trifft die Bedingung nicht zu, dann wird der Programmabschnitt übersprungen.

DO Bedingung
   Anweisung 1
   Anweisung 2
       :
   Anweisung n
Loop

Bei der nichtabweisenden Schleife wird die Bedingung erst am Ende des Programmabschnittes überprüft. Trifft sie zu, dann wird der Befehlszähler auf den Abschnittanfang gesetzt, und dieser wiederholt. Sonst wird mit der nachfolgenden Anweisung fortgesetzt.

Da die Bedingung erst am Ende des Abschnittes überprüft wird, wird der Abschnitt immer mindestens einmal ausgeführt.

DO
   Anweisung 1
   Anweisung 2
       :
   Anweisung n
Loop Bedingung

Sind Datenfelder fester Länge zu durchlaufen, oder Berechnung mit einer vorgegebenen Zahl wiederholt auszuführen, dann bietet sich die For...to ... next Schleife an:

FOR i = <Startwert> TO <Endwert> [STEP <Schrittweite>]
   Anweisung 1
   Anweisung 2
       :
   Anweisung n
Next

foreach

For Each el [as Type] in Collection 
   ...
Next

Arrays

Zur Verarbeitung tabelarischer Daten dienen in VB Arrays. Durch die Deklaration eines Arrays werden im RAM n Speicherplätze zur Aufnahme von Werten des Typs x reserviert.

Arrays sind Referenztypen

Deklaration eines Arrays hat folgenden Aufbau:

Dim a(3) as Integer
    | |       +----- Typ der Einträge
    | +------------- größter Index eines Eintrages
    +--------------- Name des Arrays

Nach einer Arraydeklaration ergibt sich folgendes Format im Arbeitspeicher:


Der Zugriff auf die Elemente eines Arrays erfolgt über den Namen und den Indize:

Dim x as Integer

' x hat nach Ausführung dieser Anweisung den Wert 2
x = a(2)
    | +--- Indize (Platznummer)
    +----- Arrayname

Die Indizes können dynamisch zur Laufzeit festgelegt werden. Damit ist eine komfortable Verarbeitung der Arraydaten in Schleifen möglich:

Dim i as Integer, s as Long

' s enthält nach der Schleife die Summe aller Einträge
for i = 0 to 3
   s = s + a(i)
next

Initialisierung von Arrays

Dim primz() as Integer = {2, 3, 5, 7, 11}

Anzahl der Einträge bestimmen

Dim anz_elems as Int32 = primz.length  'Anzahl der Elemente in über alle Dimensionen
Dim anz_dims  as Int32 = primz.rank    'Anzahl der Dimensionen eines Arrays

Zuweisen und Kopieren

Durch Zuweisung wird nur eine Referenz erzeugt, jedoch keine Kopie.

Dim prim2() As Int32 = prim

Die Methode Clone() eines Arrays erzeugt eine 1:1 Kopie

Dim prim3() As Int32 = prim.Clone()

Redimensionierung

Zur Laufzeit können die Dimensionen eines dynamischen Arrays mit der Prozedur ReDim <arrayName>( <neuerMaxIndex>) vergrößert und verkleinert werden wie folgt:

:
ReDim Preserve a(6) 
' Das Array wird um 3 Elemente vergrößert, wobei der alte Inhalt erhalten bleibt
:
ReDim a(9) 
' Das Array wird wiederum um 3 Elemente vergrößert. Diesmal wird der alte Inhalt jedoch nicht
' erhalten (Preserve fehlt)

Besuchen aller Einträge eines Arrays mittels foreach - Schleife

For Each quadrat as Integer in quadrate) 
   Console.WriteLine(quadrat);
Next

Arrays sortieren

Dim planeten() as String = {"Merkur", "Venus", "Erde", "Mars", "Jupiter", "Saturn"}
Array.Sort(planeten);

Array mit selbstdefinierten Typen Sortieren

enum ELaenge {mm, cm, dm, m, km};

struct Laenge : IComparer
{
  public float  wert;
  public enumLaengenEinheiten einheit;

  public int Compare(object obj1, object obj2) 
  {
    Laenge l1 = (Laenge)obj1;
    Laenge l2 = (Laenge)obj2;

    // alles in mm umrechnen
    float il1 = tomm(l1), il2 = tomm(l2);
    if (il1 == il2)
      return 0;
    else if (il1 < il2)
      return -1;
    else 
      return 1;         
  }

  float tomm(Laenge l) 
  {
     switch (l.einheit) {
         case ELaenge.mm:
            return l.wert;
         case ELaenge.cm:
            return l.wert * 10;
         case ELaenge.dm:
            return l.wert * 100;
         case ELaenge.m:
            return l.wert * 1000;
         case ELaenge.km:
            return l.wert * 1000000;
     }
     return -1;
  }
}
// In Main
Laenge[] fahrten = new Laenge[3];
fahrten[0].einheit = ELaenge.mm;
fahrten[0].wert = 100000;
fahrten[1].einheit = ELaenge.cm;
fahrten[1].wert = 3000;
fahrten[2].einheit = ELaenge.km;
fahrten[2].wert = 0.99F;

Array.Sort(fahrten, fahrten[0]);

foreach (Laenge fahrt in fahrten) 
{
   Console.WriteLine("{0} {1}", fahrt.wert, fahrt.einheit.ToString());
}

Aufg.:

  1. Min/Max- Suche,

  2. Sortieren

  3. Messwerterfassung (akt. Wert, dyn. Mittelwert)

Datum und Uhrzeit

Grundlage für die Datumsberechnung ist ein linearer Zeitstrahl, der in Ticks unterteilt ist. Ein Tick hat die Dauer von 10-7s (zehnmillionstel Sekunde). Zeitpunkte auf dem Zeitstrahl werden durch Werte vom Typ Date angegeben. Ein Datumswert wird hat das Format #M/D/YYYY# (amerikanisches Datumsformat).


Date basiert auf System.DateTime. Die Konstruktoren von System.DateTime sind mehrfach überladen:

dim dat1 as New System.DateTime(Ticks)
dim dat2 as New System.DateTime(YYYY, MM, DD)
dim dat2 as New System.DateTime(YYYY, MM, DD, hh, min, sec, millisec)

Zur Darstellung von Zeiträumen dient die Klasse TimeSpan.

Chars

Objektmodell von char


Chars und Unicode

.NET unterstützt Unicode. Quelltexte können als Unicode- Dateien verpackt werden, und Zeichentypen wie char und string basieren auf 16bit Unicode. Folgendes Windows- Programm liefert einen Dialog mit einem kyrillischen Text:

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Vom Windows Form Designer generierter Code "
  :
#End Region

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' char verarbeiten Unicode- Zeichen
        Dim c1, c2, c3, c4, c5, c6, c7 As Char

        c1 = ChrW(1051)
        c2 = ChrW(1070)
        c3 = ChrW(1041)
        c4 = ChrW(1054)
        c5 = ChrW(1042)
        c6 = ChrW(1068)

        Dim str As String

        str += c1.ToString + c2.ToString + c3.ToString + c4.ToString + c5.ToString + c6.ToString

        lblDasWichtigste.Text = str


    End Sub
End Class

Mittels der Funktion ChrW(Zahl) wird eine nummerischer Unicode in ein Unicodezeichen umgewandelt. Der String aus den Unicodezeichen wird schließlich über ein Label (lblDasWichtigste) im Formular angezeigt.

Aufg.:
  1. Programm, welches in einer Textbox eine Teilmenge des Unicodes als Zeichencodetabelle ausgibt. Bsp: Währungssymbole von 20A1 bis 20AF

  2. Programm, welches alle Satzzeichen im Unicode ausfiltert und anzeigt

Strings

Siehe .NET Doku

Teilstrings ausschneiden

Dim txt as String = "Anton,Berta,Cäsar"
Console.WriteLine(txt.Substring(6, 5))

Umwandeln in Groß- oder Kleinschreibung

Dim txt as String = "Hallo Welt"

Console.WriteLine("Alles groß: {0}", txt.ToUpper())
Console.WriteLine("Alles klein: {0}", txt.ToLower())

Startposition von Teilstrings bestimmen

Dim txt as String = "Anton,Berta,Cäsar"
Dim pos as Int32  = txt.IndexOf("Berta")

Einfügen in Strings

Dim txt as String = "Anton,Berta,Cäsar"
txt = txt.Insert(txt.IndexOf("Berta"), "Aladin,")

Auftrennen von Zeichenfolgen

Dim txt as String = "Anton,Berta,Cäsar";
Dim namen() as String = txt.Split(","c);

Splitten mittels Reguläre Ausdrücke

Dim r As Regex = New Regex("\s*=\s*")
Dim aw() As String = r.Split("Durchmesser = 199")
Console.WriteLine("Attribut {0} hat Wert {1}", aw(0), aw(1))

Ersetzen mittels Regulärer Ausdrücke

' In folgendem String sollen alle Vorkommen von keinen durch [] markiert werden
txt = "Das Pferd frisst keinen Gurkensalat. Ich habe keine Ahnung warum"
Dim txt_neu As String = Regex.Replace(txt, "keinen", "[keinen]")
Console.WriteLine(txt_neu)

Aufgaben

  1. Romzahlkonverter

  2. Zählen der Buchstabenhäufigkeit in gegebenen Texten

Funktionen und Prozeduren

Mathematische Funktionen

Die wichtigsten mathematischen Funktionen sind im Math- Objekt des Namespace System enthalten.

Optionale Parameter

Beispiel: Eine Funktion soll implementiert werden, welche den Zeitraum zwischen zwei gegebenen Daten bestimmt. Als Standard wird der Zeitraum in Sekunden ausgegeben. Optional kann die verstrichene Zeit aber auch in Minuten, und Stunden ausgegeben werden:

Function Zeitraum_zwischen(ByVal start As Date, ByVal ende As Date, Optional ByVal einheit As String = "sec")
        Dim ticks As Long = Math.Abs(start.Ticks - ende.Ticks)
        Dim zr As New TimeSpan(ticks)
        Select Case (einheit)
            Case "sec"
                Return zr.TotalSeconds
            Case "min"
                Return zr.TotalMinutes
            Case "hh"
                Return zr.TotalHours
            Case Else
                Throw New Exception("Unbekannte Zeiteinheit")
        End Select

    End Function

Aufgabe:

Die Funktion Zeitraum_zwischen(...) zur Berechnung von Zeiträumen in Minuten und Stunden anwenden.

Parameterarrays

Beispiel:

Function summe_aus(ByVal ParamArray summanden( ) As Double)

        Dim i As Integer, sum As Double
        For i = 0 To summanden.GetUpperBound(0)
            sum += summanden(i)
        Next

        Return sum

 End Function

Aufgabe:

Die Funktion summe_aus (...) zur Berechnung der Summe verschiedener Listen einsetzen.

Delegate (Funktionszeiger)

Komponeten wie z.B. Formulare und strombasierte XML- Parser können über Ereignisroutinen (Eventhandler) an die Wünsche des Anwenders angepasst werden. Ereignisroutinen werden individuell vom Anwender erstellt und ähneln gewöhnlichen Prozeduren. Anschießend muß der Komponete die Ereignisroutinen bekannt gemacht werden. In C++ benutzt man dazu z.B. Funktionszeiger. Da VB.NET keine Zeiger bereitstellt, gibt es ein Sprachkonstrukt, die sog. Delegats (Delegierungen). Es handelt sich hierbei letzendlich um typisierte Funktionszeiger, deren Wert jedoch nicht geändert werden darf.

Deklaration eines Delegate

Jeder Delegate muß vor seiner Verwendung deklariert werden:

[Zugriffsmodifikator] Delegate Methodendeklaration
z.B.:
Public Delegate OnDirOpen(name as String)