Erster VB.net -Kurs
Dieses sind Notizen zu dem VB.net -Kurs vom 4. Juni 2012.
Einleitung
Überblick über den geplanten Kursinhalt, Änderungswünsche möglich
> Visual Basic
>> Vorbemerkungen
>> Erste Schritte
>> Einfache Ausdrücke
>> Einfache Anweisungen
>> Datentypen
>> Operatoren
>> Deklarationen
>>> Deklarationen von Aufrufbarem
>>> Deklarationen von Konstanten
>>> Deklarationen von Variablen
>>> Deklarationen von Klassen
Themenwünsche? Fragen?
Kurs könnte für Teilnehmer mit Vorkenntnissen langsam wirken, da er sich an Anfänger richtet
Fragen besser zu schon Behandeltem als vorausgreifen, Vorausgreifende in Fragestunde
Fragen nach Ende des Kurses schwierig, statt dessen beim nächsten Termin stellen
Am Anfang des Kurses gibt es zunächst noch wenig Übungen im Programmieren, da erst einmal einige Grundlagen vorgestellt werden müssen
Hinweise zu teilweiser Anwesenheit im Kurs oder an einem Termin
Erste Schritte
- >722196 Erste Grundbegriffe der Programmierung
- + Quelltextmodell und Laufzeitmodell, statisch und dynamisch
(statisch = wird durch den Quelltext des Programms festgelegt und kann während der Ausführung des Programms nicht verändert werden, dynamisch = kann während der Ausführung des Programms verändert werden.)
Erste Grundbegriffe der Visual Basic-Programmierung
„Visual Basic“ wird auch „VB“ genannt und wurde von Microsoft von 2002 bis 2008 auch „Visual Basic .Net“ oder „VB.Net“ genannt.
Dieser Kurs hier ist für Visual-Basic-Versionen ab 10.
Spezifikationsquelle der Sprache Visual Basic: Visual Basic Language Specification
info: http://msdn.microsoft.com/en-us/library/ms234437.aspx
download: http://www.microsoft.com/en-us/download/details.aspx?id=15039
Ein erstes Beispielprogramm in Visual Basic
Eingeben und Ausführen eines Beispielprogramms mit einer Visual-Basic-Entwicklungsumgebung und Umgang mit Fehlermeldungen
Arbeitsordner anlegen
Main.vbc
Module Module1
Sub Main()
Call [global].[System].[Console].[ReadLine]()
End Sub
End ModuleMain.cmd
vbc.exe Module1.vbc
IF NOT ERRORLEVEL 1 .\Module1.exe
PAUSE
C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe
Der Name der Datei (Main) und der Klasse (Main) muß nicht übereinzustimmen. Der Name der exe-Datei wird aus dem Dateinamen gebildet. Ausgeführt wird eine passende Main-Methode.
Übung In der Kommandodatei den Pfad von vbc.exe hinzufügen
Übung Dies zum Laufen bringen.
Übung Fehler einbauen und deren Meldung beobachten.
Fehler einbauen
Dieses Programm bis auf weiteres verwenden
Formatierung von Quelltext in Visual Basic
Wörter bestehen aus Buchstaben, Ziffern und Grundstrichen, dürfen aber nicht mit einer Ziffer beginnen. Keywords und Namen, lexikalische Einheiten aus Sonderzeichen.
Lexikalische Einheiten werden durch Leerraum getrennt, falls sonst Ziffern oder Buchstaben direkt aufeinanderfolgen würden
Zeilenenden haben eine Bedeutung zum Abschluß einer logischen Zeile und sind nicht einfach Leerraum
" _" (Leerzeichen und danach Grundstrich) zur Verlängerung
http://msdn.microsoft.com/en-us/library/865x40k4.aspx implicit line continuation:
Kommentare mit Apostroph (') oder REM
Installation der Entwicklungsumgebung von Visual Basic
[basic 2010 express]
http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-basic-express
http://www.microsoft.com/visualstudio/en-us/products/2010-editions/express-iso
[basic 2008 express iso] mit Upgrade-Converter für VB6
http://www.microsoft.com/en-us/download/details.aspx?id=20682
Programs > Microsoft Visual Studio 2010 Express > Microsoft Visual Basic 2010 Express
Start mit Strg-F5
? im Direktfenster
>cls im Direktfenster
Esc zum Schließen von Eingabehilfen
Einfache Ausdrücke
Ausdrücke
- Zwei Ausdrücke
- System.Console.ReadLine()
System.Console.ReadLine
http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.71).aspx
Public Function ReadLine()
- Syntax eines Aufrufausdrucks
- InvocationExpression ::= Expression [ OpenParenthesis [ ArgumentList ] CloseParenthesis ]
Auswertung, Auswirkung;
»System.Console.ReadLine()« ist Ausdruck, der hier ausgewertet wird, wodurch eine Operation aktiviert wird, die einen Prozeß bewirkt.
„auswerten“
Kontexte, Wörter und Phrasen
Im gegebenen Kontext (der Stelle im Quellcode) ist »Me« ein bekannter Bezeichner
Leerraum um die Punkte ist erlaubt
qualifizierte Namen
keyword Namespace Class Function
V V V V
Global . System . Console . ReadLine()Member of Assembly mscorlib
Member of .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5
Global = root = Default = unnamed outermost namespace
Begriff des Namensraums an einem Kontext (Stelle¹ des Quelltextes¹), Struktur des globalen Namensraums¹
<Default>- System- System.Console-
Kontext Kontext Kontext
V V V
System. Console. ReadLine()
Namensräume und Klassenangaben¹
Der Objekt-Browser ([F2])
Browsen, Suchen, zurückgehen
Kontext = Gueltigkeitsbereich = Namensraum c Semantik
Methode = Sub/Function
einfache und qualifizierte Namen
Methodennamen, Typnamen (Klassennamen), Namensraumnamen
Groß- und Kleinschreibung
Dokumentation
Dokumentation lesen und ihre Teile verstehen
Dokumentation lesen und einen passenden Aufruf schreiben
Dokumentation der Standardbezeichner
Übung Einfaches Aufrufbares aufrufen.
System.Console.WriteLine
http://msdn.microsoft.com/en-us/library/system.console.writeline(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/zdf6yhx5
System
Console Class
Overloads Public Shared Sub WriteLine()
Importdeklarationen
Abkürzen langer globaler Bezeichner (Namespace oder Type)
Namenraum importieren: Imports [ aliasname = ] namespace
Element eines Namensraums (z.B. Klasse) importieren: Imports [ aliasname = ] namespace.element
Imports Microsoft.VisualBasic.Strings
String.Left("Hello World", 5)
Imports Str = Microsoft.VisualBasic.Strings
Str.Left("Hello World", 5)
Vorgegebene Importe von Entwicklungsumgebungen
Einfache Anweisungen
Aufrufanweisung
Anweisung zur bloßen Auswertung ohne weitere Verwendung des Wertes
CALL Aufruf
Die CALL-Anweisung verlangt die Ausführung des folgenden Aufrufs.
Ausdruck auf einer Zeile für sich
Übung Erkennen, ob Anweisung oder Ausdruck
InvocationStatement ::= [ Call ] InvocationExpression StatementTerminator
Beim Weglassen von Call wird die Anweisung dadurch ausgedrückt, daß der Ausdruck auf einer Zeile für sich steht.
Ausdrücke werden „ausgewertet“, Anweisungen werden „ausgeführt“.
Die Aufrufanweisung verlangt die Auswertung ihres Aufrufausdrucks.
In einem Sub ist zunächst nur eine Anweisung erlaubt, kein Ausdruck, deswegen muß der Ausdruck durch CALL (oder die Zeilenformatierung) in eine Anweisung umgestellt werden.
---
System.Console.ReadLine
Call System.Console.ReadLine
Datentypen
Methoden mit und ohne Wirkung
- WriteLine (Dokumentation)
- Namespace System
Class Console
Public Shared Sub WriteLine()
Wirkung: Ausgabe einer Leerzeile.
Die Methode »WriteLine()« ist ein Sub. Die Auswertung Ihres Aufrufs hat eine Wirkung, die im Quelltext durch den Aufruf repräsentiert wird.
- Beispiel (Konsolenanwendung)
Module Module1
Sub Main()
Call Global.System.Console.WriteLine()
End Sub
End Module- Doppelklick auf Fehlersymbol um Class Main als Startklasse festzulgen.
- Start mit Strg-F5
- GetCurrentThreadId (Dokumentation)
- Namespace System
Class AppDomain
Public Shared Function GetCurrentThreadId()
Wert: Kennzahl des aktuellen Ablaufs.
Die Methode »GetCurrentThreadId()« ist eine Funktion. Die Auswertung ihres Aufrufs hat keine Wirkung.
Funktionen und Subs sind Methoden („Methode“ ist der speziellste Oberbegriff von „Funktion“ und „Sub“.)
- Beispiel (Konsolenanwendung)
Module Module1
Sub Main()
Call Global.System.AppDomain.GetCurrentThreadId()
End Sub
End Module
Beim Start des Programms sieht man also nur, daß das Programm nichts macht. Eventuelle Hinweise darauf, daß die Methode »GetCurrentThreadId« veraltet sei, können ignoriert werden. Es ist derzeit auch noch nicht nötig, den Sinn dieser Methode zu verstehen, denn sie soll hier nur als Beispiel dafür dienen, daß die Auswertung des Aufrufs mancher Methoden keine Wirkung hat.
Argumente
- Beispiel (Konsolenanwendung)
Module Module1
Sub Main()
Call Global.System.Console.WriteLine(
Global.System.AppDomain.GetCurrentThreadId() )
End Sub
End Module
Das obige Beispiel zeigt den Aufruf einer Methode in den runden Klammern einer anderen Methode. Solch ein Aufruf wird bei jeder Ausführung der Call-Anweisung folgendermaßen ausgewertet: Zuerst wird der innere Aufruf »Global.System.AppDomain.GetCurrentThreadId()« ausgewertet, dann der äußere Aufruf »Global.System.Console.WriteLine(…)«.
Zusätzlich kann die erste Auswertung hierbei die zweite Auswertung auch noch beeinflussen. Die äußere Methode ist eine Ausgabemethode, bei der aber noch nicht festgelegt wurde, was ausgegeben wird. Dieses Bestimmungsstück der Ausgabe wurde als ein sogenannter Parameter noch offengelassen. Die Auswertung des inneren Aufrufs liefert dann zur Laufzeit diese Information.
- Abfolge und Informationsfluß
GetCurrentThreadId --->> WriteLine
Es findet sich eine Dokumentation einer Methode namens »WriteLine«, die dieses zum Ausdruck bringt:
- Console.WriteLine Method (Int32)
Namespace System
Class Console
Public Shared Sub WriteLine (
value As Integer
)- Effect: Writes the text representation of the specified 32-bit signed integer value, followed by the current line terminator, to the standard output stream.
Die Angabe »value As Integer« ist die Beschreibung des Parameters der Methode in der Dokumentation.
Es gibt also zwei verschiedene WriteLine-Methoden: Eine mit leeren Klammern und eine mit einen Parameter! In dieser Lektion geht es nur um die mit dem Parameter.
Bei der Beschreibung der Wirkung wird ein Wert »value« noch offengelassen. Die Operation, welche durch diese Methode angegeben wird ist also insofern bis zur Auswertung des Ausdrucks noch unbestimmt. Daher kann man auch sagen, daß eine Methode mit einem Parameter, eine parametrisierte Operation angebe.
Die Auswertung des Aufrufs »GetCurrentThreadId()« ergibt zur Laufzeit gerade einen Wert, welcher dann also von »WriteLine(…)« ausgegeben wird.
Eine Methode wie »GetCurrentThreadId()« ist nicht als selbständige Methode gedacht, sondern nur, um parametrisierte Operationen zur Laufzeit näher zu bestimmen. Solch eine Methode hat gar keine Wirkung, aber sie liefert einen Wert. Wenn ihr Aufruf in die runden Klammern eines anderen Aufrufs geschrieben wird, so bedeutet dies, daß dieser Wert zur Laufzeit als Wert für den Parameter dieses anderen Aufrufs verwendet werden soll. Der Wert der Auswertung des Aufrufs von »GetCurrentThreadId()« wird also als Wert für den Parameter »value« von »WriteLine(…)« verwendet.
Einen Ausdruck, dessen Wert zur Festlegung des Wertes eines Parameters dient, nennt man auch einen Argumentausdruck. Bei jeder Auswertung des gesamten Ausdrucks »WriteLine( GetCurrentThreadId() )« wird der Argumentausdruck erneut ausgewertet. Der sich bei dieser Auswertung ergebende Wert wird auch kurz als „Wert des Argumentausdrucks“ bezeichnet (obwohl dies nicht ganz korrekt ist, da der Argumentausdruck gar keinen bestimmten Wert hat, weil dieser bei jeder Auswertung ein anderer sein kann).
Eine Methode, die einen Wert ergibt, wird als „Funktion“ bezeichnet. Solch eine Funktion kann oft nicht alleine hinter dem »CALL« aufgerufen werden, denn da sie ja keine Wirkung hat, hat ihre Auswertung durch »CALL« keine erkennbare Auswirkung.
Ein Funktionsaufruf sollte normalerweise in einem WriteLine-Aufruf stehe, damit man den Wert der Auswertung sehen kann.
Eine Methode, die keinen Wert ergibt, wird als „Sub“ bezeichnet.
Ein Sub-Aufruf sollte normalerweise hinter dem Schlüsselwort »CALL« stehen, damit die Wirkung der Auswertung eintritt.
Verhalten
Eine Handlung eines Systems wird hier allgemein als eine Aktivität bezeichnet.
Verhalten einer Aktivität = Wert und Wirkung
- Beispiel (Konsolenanwendung)
Module Module1
Sub Main()
Call Global.System.Console.WriteLine(
Global.System.Console.Read() )
End Sub
End Module
Das Verhalten von »Read()« besteht hier nur aus dem Wert. Es hängt hier von der Eingabe ab, gleiche Eingabe ergibt aber immer wieder gleiches Verhalten. Eine solche Aktivität, wird hier auch als eine Interaktion bezeichnet.
Signatur und Überladung
Der Aufruf »WriteLine()« paßt am besten zur Signatur »WriteLine()«.
Der Aufruf »WriteLine( Global.System.AppDomain.GetCurrentThreadId() )« paßt am besten zur Signatur »WriteLine(Integer)« (auch als »WriteLine(int32)« bezeichnet).
Die Signatur einer Methode besteht aus der Angabe ihres Namens und der Beschreibung ihrer Parameter.
Der Name WriteLine ist überladen (in der Klasse »Console«).
Während es ohne die Möglichkeit der Überladung ausreichen würde, den Namen zu verwenden, um eine Methode eindeutig zu bezeichnen, ist bei der Möglichkeit der Überladung die Angabe der vollständigen Signatur nötig, also beispielsweise „die Methode »WriteLine()«“, nicht nur „die Methode »WriteLine«“).
Ganze Zahlen
0 und 00 haben den gleichen Wert, also sind Literale nicht gleich Werte.
23
99999999999
Integer System.Int32 32 bits (4 bytes) -2,147,483,648 to 2,147,483,647
Integer
appended type character für Literale: I oder %
IntLiteral ::= Digit+
Vorzeichen gehört nicht zu Literal
Ausdrücke sind nun Aufrufe oder Literale
Sequenz
Folge von Anweisungen
(Es gibt keine Block-Anweisung zur bloßen Zusammenfassung einer Folge zu einer neuen Anweisung.)
Colon: Dim sampleString As String = "Hello World" : MsgBox(sampleString)
Debugger:
Object Browser Settings: +View Namespaces, -Show Inherited Members
F7 Quelltext-Fenster
Strg-R Projekt-Explorer
Strg-G Direktfenster
F4 Eigenschaften
- Beispiel (in Console-Anwendung)
Debug.WriteLine(5) ' Breakpoint
Debug.WriteLine(6)
Debug.WriteLine(7)
Debug.WriteLine(8)
Das Verhalten der Aktivität »Console.WriteLine(2)« oder »Debug.WriteLine(2)« ist immer gleich. Es handelt sich um eine Aktion. »Console.WriteLine(Integer)« oder »Debug.WriteLine(Integer)« bezeichnen eine parametrisierte Aktion.
Aktivität
- Aktion: Verhalten immer gleich
- Interaktion: Verhalten abhängig von Wechselwirkung mit der Umgebung während ihrer Ausführung
parametrisierte Aktivität
- parametrisierte Aktion: Aktion, die durch Argumente bestimmt wird (aber dann nicht mehr durch Wechselwirkung mit der Umgebung)
- parametrisierte Interaktion: Interaktion, die durch Argumente bestimmt wird (und dann außerdem noch durch Wechselwirkung mit der Umgebung während ihrer Ausführung)
Methoden sind parametrisierte Aktivitäten.
Bei einer Sub-Methode besteht das Verhalten nur aus einer Wirkung, aber es gibt keinen Wert.
? im Direktfenster
Gleitkommazahlen
appended type character: R oder #
23E2
2.3
Double
Double System.Double 64 bits (8 bytes) 15-16 digits 5.0 x 10-324 to 1.7 x 10308
Beispiel Ausgabe von 22e22 und 1234567890123456789012345678901234567890E0
Member of System.Math
Public Shared Function Round(ByVal value As Double, ByVal digits As Integer) As Double
Typbedingungen bei Verschachtelung von Aufrufen; Reihenfolge der Auswertung
CInt rundet, während Int abschneidet: Debug.WriteLine(CInt(3.8)), Debug.WriteLine(Int(3.8)), Debug.WriteLine(CInt(9e99)), Debug.WriteLine(Int(9e99))
Single-Gleitkommazahlen
Single: Type Character: F oder !
Single System.Single 32 bits (4 bytes) 7 digits 1.5 x 10^-45 to 3.4 x 10^38
Member of Microsoft.VisualBasic.VBMath
Public Shared Function Rnd() As Single
Zeichenliterale, Zeichentyp, Codepunkten
Zeichenliterale: "a"C, deren Datentyp ist Char, Microsoft.VisualBasic.AscW("a"C)
Char System.Char 16 bits (2 bytes) One unicode symbol in the range of 0 to 65,535.
Zeichenfolgen (Literale und Typ)
"ABC""DEF"
Übung Hallo sagt er ausgeben, Quelltext ausgeben als Zusatzaufgabe
vbCrLf
Typwandlung mit Str: Str(2) erzeugt Leerzeichen als Vorzeichen, Format(2) jedoch nicht,Format( 5459.4, "##,##0.00" )
Zeilenformatierung in der Ausgabe
Zeilenausgabeformatierung, Ausg v Leerzeilen, Umlaute: Debug.Write/Debug.WriteLine/vbCrLf
Debug:
public static void Print(string message);
public static void Print(string format, params object[] args);
public static void WriteLine(object value);
public static void WriteLine(string message);
Print can do formatted strings and WriteLine can dump objects.
vbCrLf
Überladene vordefiniterte Namen und deren Auflösung
System.Console:
Overloads Public Shared Sub Write(Integer)
Integer, Double, …
vordefinierte Konstanten
CONFIG
DEBUG
vbCrLf
Properties
TimeOfDay
Typwandlungen
CInt(2.3)
CDbl
Int
CStr(2.3)
AscW
ChrW
Option Strict
Operatoren
Grundrechenarten, Abweichungen von Alltags- und Schulmathematik, implizite Typanpassung
Klammern () Ausdrucktest
Mögliche Aufrufe
- Call (System.Console).ReadLine
- Call (Console).ReadLine
Eine Aufrufanweisung darf nicht mit einer Klammer beginnen
- (Console).ReadLine
Implizite Fortsetzung einer logischen Zeile nach öffnender oder vor schließender Klammer
Grundrechenarten
+ plus 2 + 3
- minus 2 − 3
* mal 2 × 3, 2 · 3, 2y
/ durch 2/3, 2 ÷ 3, — (Bruchstrich)
Punktrechnung (* /) geht vor Strichrechnung (+ -)
Vorzeichen:
+ plus +2
- minus −2
1.1 * 1.1 - 1.21
Assoziativität: 1/2/3 vs 1/(2/3)
Vorrang: 1+2*3 vs (1+2)*3
9999 * 9999 * 9999
\ ganzzahlige Division
Mod modulo
^ Potenzieren: -1^2 = −1²
Implizite Fortsetzung einer logischen Zeile nach binären Operatoren (+ - * / Mod ^, vermutlich auch \)
Beispiele 1e20 + 1 - 1e20, 1.1 * 1.1, 9999*9999*9999, 2000000000+2000000000, 3.+4, 1/0, 1\0
Schreiben Sie möglichst kurze Ausdrücke für die folgenden Terme, ohne vorher irgendwelche Teile der Terme im Kopf auszurechnen.
Terme
1 3 3 + 4
--- - ---, -------
2 4 5 - 6
- 7 × 3 ÷ 5 · 3
- 2 / 3 / 4
- 4³
- Das Doppelte von 18
- Sieben Prozent von 180
- Der Preis von 2 kg, wenn 3 kg 6,50 Euro kosten
- 140 Kelvin in Grad Celsius angegeben
Übung Bereich des Produkts oder der Summe mit einer Zufallszahlen, Würfel
Eigentliche Funktionen
System.Math:
Public Shared Function Abs ( _
value As Integer _
) As Integer
- Beispiel (Konsolenanwendung)
Module Module1
Sub Main()
Call Global.System.Console.WriteLine(
Global.System.Math.Abs( -2 ))
End Sub
End Module- Beispiel (Konsolenanwendung)
Module Module1
Sub Main()
Call Global.System.Console.WriteLine(
Global.System.Math.Abs(
Global.System.AppDomain.GetCurrentThreadId() ))
End Sub
End Module
Wahrheitswerte
BooleanLiteral ::= True | False
True
False
( 1.1 * 1.1 = 1.21 )
Boolean System.Boolean 32 bits (4 bytes) True or False
Typwandlung mit CInt, CBool
Vergleichsoperatoren
( 3 > 2 > 1 )
<> ungleich
= gleich
<= Kleiner-Gleich
>= Größer-Gleich
< Kleiner
> Größer
Beispiele 3.7F == 3.7#
Verneinung
Not True
Not False
Not(1.1 * 1.1 = 1.21)
Textverbindung mit »&«
? 0 & vbCr & 1
implicit line continuation: After the concatenation operator (&).
Prioritäten
^ Exponentialoperator
- negatives Vorzeichen
*, / Multiplikation, Division
\ ganzzahlige Division
Mod Modulo
+, - Addition, Subtraktion
& Textverbindung
=, <>, <, >, <=, >=
Not logisches Nicht
Teil 2 Anweisungen
Schwerpunkt: imperative Programmierung
- >722568 Wirkausdrücke in VB.net
Teil 3 Deklarationen
Schwerpunkt: prozedurale Programmierung
- >722580 Lokale Konstanten in VB.net
Definitionen
Subdefinitionen
Methoden ohne Parameter und ohne Ergebnis
Sub Name()
End Sub
Aufruf im Direktbereich mit/ohne CALL, mit/ohne Klasse/Modul
Beispiele Refrain
Debugger für Methodenaufrufe
- Sub-Beispiel
Sub Main()
Debug.Print "Auf einem Baum ein Kuckuck, -"
Debug.Print "Sim sa la dim, bam ba,"
Debug.Print "Sa la du, sa la dim -"
Debug.Print "Auf einem Baum ein Kuckuck sass."
'
Debug.Print "Da kam ein junger Jaeger, -"
Debug.Print "Sim sa la dim, bam ba,"
Debug.Print "Sa la du, sa la dim -"
Debug.Print "Da kam ein junger Jaegersmann."
'
Debug.Print "Der schoss den armen Kuckuck, -"
Debug.Print "Sim sa la dim, bam ba,"
Debug.Print "Sa la du, sa la dim -"
Debug.Print "Der schoss den armen Kuckuck tot."
End Sub- Sub-Beispiel
Sub Refrain()
Debug.Print "Sim sa la dim, bam ba,"
Debug.Print "Sa la du, sa la dim -"
End SubSub Main()
Debug.Print "Auf einem Baum ein Kuckuck, -" : Call Refrain()
Debug.Print "Auf einem Baum ein Kuckuck sass."
Debug.Print "Da kam ein junger Jaeger, -" : Call Refrain()
Debug.Print "Da kam ein junger Jaegersmann."
Debug.Print "Der schoss den armen Kuckuck, -" : Call Refrain()
Debug.Print "Der schoss den armen Kuckuck tot."
End Sub
Debugger: Unterschied zwischen F8 und Umschalt-F8
In »Hallo:Hallo« wird das erste »Hallo« falsch verstanden, in »Hallo():Hallo()« stellen die Klammern klar, daß ein Methodenaufruf gemeint ist.
Abstraktion: Schnittstelle und Implementation
- Übungsfrage
- Module1
Module Module1
Sub Alpha()
Debug.WriteLine("A")
End SubSub Main()
Debug.WriteLine("B")
End SubEnd Module
- Übungsfrage Was gibt das Programm "Main" aus?
- Übungsfrage
- Modul1
Module Modul1
Sub Hallo()
Debug.WriteLine("Hallo")
End SubSub Hallo2()
Hallo() : Hallo()
End SubSub Main()
Hallo() : Hallo2()
End SubEnd Module
- Hinweis Ohne die Klammern würde das erste Sub als Marke interpretiert werden.
- Übungsfrage Was gibt das Sub "Main" aus?
- Übungsfrage
- Modul1
Module Module1
Sub Alpha()
Debug.Write("[")
Debug.Write("]")
End SubSub Main()
Debug.Write("(")
Alpha()
Debug.Write(")")
Debug.WriteLine("")
End SubEnd Module
- Übungsfrage Was gibt das Sub "Main" aus?
- Übungsaufgabe
- Modul1
Module Modul1
Sub Alpha()
Debug.WriteLine("Hallo")
End SubSub Beta()
Alpha() : Alpha()
End SubSub Main()
Alpha() : Beta()
End SubEnd Module
- Übungsaufgabe Ändern Sie den Name »Beta« in »Gamma«, ohne daß sich dadurch eine Änderung des Verhaltens des Programms ergibt (Refaktor).
- Übungsaufgabe
- Modul1
Module Modul1
Sub Alpha()
Debug.WriteLine("Hallo")
End SubSub Main()
Alpha()
End SubEnd Module
- Übungsaufgabe Ändern Sie die Reihenfolge der Definition der beiden Subs, ohne daß sich dadurch eine Änderung des Verhaltens des Programms ergibt (Refaktor).
- / Leerzeile ausgeben
- Schreiben Sie mit Hilfe eines Aufrufs von »WriteLine« eine Definition eines Subs namens »Leerzeile«, das eine Leerzeile ausgibt.
- Unterprogramme definieren
- Schreiben Sie das folgende Programm um, so daß sich wiederholende Anweisungen von einem Unterprogramm (oder von mehreren Unterprogrammen) ausgeführt werden, das dann wiederholt aufgerufen wird (bzw. aufgerufen werden). Das Umschreiben soll die Ausgabe des Programmes nicht verändern.
Sub Main
Debug.Print "Tomaten"
Debug.Print "Rotkohl Gruenkohl"
Debug.Print "Gurken"
Debug.Print "Tomaten"
Debug.Print "Rotkohl Gruenkohl"
Debug.Print "Spinat"
Debug.Print "Tomaten"
Debug.Print "Rotkohl Gruenkohl"
Debug.Print "Kohlrabi"
End Sub- Direktbereich
Tomaten
Rotkohl Gruenkohl
Gurken
Tomaten
Rotkohl Gruenkohl
Spinat
Tomaten
Rotkohl Gruenkohl
Kohlrabi
Übungsaufgabe Schreiben Sie eine Funktionsdefinition für eine Funktion, deren Aufruf eine Zufallszahl zwischen 1 und 6 ausgibt! Rufen Sie diese Funktion dann drei Mal im Sub »Main« auf, so daß die drei Zufallszahlen ausgegeben werden (z.B. »5«, »2« und »2«)!
Funktionsdefinitionen
Eine Funktion erlaubt es zusätzlich zu den Möglichkeiten eines Subs noch, einen Typ und einen Wert für den Aufruf festzulegen.
Die Kennzeichnung mit »Public« ist nicht nötig, da sie im allgemeinen stillschweigend angenommen wird.
Das folgende Beispiel zeigt die einfachste Funktionsdefinition.
- Beispiel (Modul)
Module Module1
Function F()
End FunctionSub Main()
Call Global.System.Diagnostics.Debug.Print(
Global.ConsoleApplication1.Module1.F() )
End SubEnd Module
Der Vollständigkeit halber wird oben ein ganzes Modul gezeigt, das auch ein Sub namens Main enthalten muß, damit es kompiliert werden kann. Die Funktionsdefinition besteht aber nur aus den beiden Zeilen »Function F()« und »End Function«.
Es wird eine Funktion mit dem Namen »F« definiert, die keine Parameter hat.
Der Typ eines Aufrufs »F()« der definierten Funktion ist »Object«, der dieses Aufrufs ist »Nothing«, da diese beiden Angaben verwendet werden, wenn ausdrückliche Festlegungen des Typs oder Werts im Quelltext fehlen. Zunächst wird als Typ »Object« angenommen, und bei diesem Typ werden fehlende Angaben als »Nothing« interpretiert. Der Typ »Object« drückt einen fast beliebigen „Gegenstand“ aus, der fast alles sein kann, der Wert »Nothing« das Fehlen einer genaueren Spezifikation. (Der Leser braucht zunächst nicht mehr über »Object« und »Nothing« zu wissen. Später sollen diese Themen vertieft werden.)
Damit die Namenspfade genau nachvollzogen werden können, werden sie ab »Global« angegeben. Tatsächlich würde aber meist schon »Debug.Print( F() )« reichen.
Beispiel (Funktionsaufruf)
? F()
Nothing
Ein Wert der beim Fehlen einer Wertangabe verwendet wird, wird Fehlwert genannt.
Der Fehlwert von Object oder String ist Nothing.
Der Fehlwert von Integer ist 0.
Der Fehlwert von Double ist 0.0.
Der Fehlwert von Single ist 0.0F.
Der Fehlwert von Double ist ChrW( 0 ).
Der Fehlwert von Boolean ist False.
Es ist empfehlenswert, den Typ und Wert einer Funktion bei der Funktionsdefinition ausdrücklich festzulegen. Das vorherige Beispiel, bei dem dies nicht geschah wurde zum besseren Verständnis beim Lesen von Quelltext ohne solche Angaben gegeben, beim Schreiben einer Funktion sollten diese Angaben aber stets erfolgen.
- Beispiel (Modul)
Module Module1
Function F() As Double
Return 1.2
End FunctionSub Main()
Call Global.System.Diagnostics.Debug.Print(
Global.ConsoleApplication1.Module1.F() )
End SubEnd Module
Man sagt auch, der Wert (hier: 1.2) werde von der Funktion „zurückgegeben“ und nennt ihn auch das „Ergebnis“ oder den „Rückgabewert“ der Funktion.
Abgrenzung zur Ausgabe
Wenn der Typ des Ausdrucks hinter dem Schlüsselwort »Return« nicht mit dem Typ des Funktionsergebnisses übereinstimmt, so wird dies oft toleriert, und der Wert wird in den Typ des Funktionsergebnisses gewandelt (wie die »300« vom Typ »Integer« [= »Global.System.Int32«] in dem folgenden Beispiel).
An Stelle einer Return-Anweisung kann auch eine Pseudo-Zuweisung an den Namen der Funktion mit einer folgenden Exit-Anweisung erfolgen.
- Beispiel (Modul)
Module Module1
Function F() As Double
F = 1.2
Exit Function
End FunctionSub Main()
Call Global.System.Diagnostics.Debug.Print(
Global.ConsoleApplication1.Module1.F() )
End SubEnd Module
Auf die Return-oder Exit-Anweisung folgende Anweisungen werden nicht mehr ausgeführt, da die Return-Anweisung die Kontrolle an den Aufrufer zurückgibt.
Die Namen sollten die Bedeutung des Wertes widerspiegeln.
- Beispiel (Modul)
Module Module1
Function TemperatureInKelvin() As Double
Return 300
End FunctionFunction Offset() As Double
Return 273.15
End FunctionFunction TemperatureInDegreesCelsius() As Double
Return TemperaturInKelvin() - Offset()
End FunctionSub Main()
Call Global.System.Diagnostics.Debug.Print(
Global.ConsoleApplication1.Module1.
TemperatureInDegreesCelsius() )
End SubEnd Module
- Beispiel (Ausgabe)
26.85
Nachdem Funktionsdefinitionen bekannt sind, kann auch schon früher Behandeltes aus einem anderen Blickwinkel verdeutlicht werden:
Der Aufruf mit CALL verwirft (ignoriert) den Rückgabewert einer Funktion:
- Beispiel (Modul)
Module Module1
Function ValueAndEffect() As Integer
Debug.Print(2)
Return 3
End FunctionSub Main()
Call ValueAndEffect()
End SubEnd Module
- Beispiel (Ausgabe)
2
Übungsaufgabe Schreiben Sie eine Funktionsdefinition für eine Funktion, deren Aufruf den Typ »Integer« hat, und deren Wert eine Zufallszahl zwischen 1 und 6 (einschließlich) ist! Rufen Sie diese Funktion dann drei Mal im Sub »Main« auf, so daß die Ergebnisse dreier Aufrufe ausgegeben werden (z.B. »4«, »4« und »2«)!
Deklarationen von Variablen
Eine Variable ist ein Speicher mit einem statischen Typ und einem – im Gegensatz zu einer Konstanten – dynamischen Wert.
Die Festlegung des Anfangswertes einer Variablen nennt man Initialisierung.
Const k As Integer = 0
Dim v As Integer = 1
Variablen werden immer mit dem Fehlwert ihres Typs initialisiert, wenn kein anderer Wert angegeben wurde.
Dim j As Integer
»Option Infer On« aktiviert die Ableitung des Typs aus dem Typ des Initialisierungsausdrucks. Dies ist aber umstritten und nicht unbedingt empfohlen.
Dim k = 0
Vieles zuvor über Konstanten Gesagte kann auf Variablen übertragen werden.
- Beispiel (Modul)
Module Module1
Sub Main()
Dim l = 9999
Debug.Print( l * l * l )
End SubEnd Module
- Beispiel (Fehlerausgabe)
A first chance exception of type 'System.OverflowException' occurred ...
- Beispiel (Modul)
Module Module1
Sub Main()
Dim n = 0
Debug.Print( 1 \ n )
End SubEnd Module
- Beispiel (Fehlerausgabe)
A first chance exception of type 'System.DivideByZeroException' occurred ...
Als Wert einer Variablen ist jeder Wert ihres Typs zulässig. Der Typ einer Variablen kann nicht verändert werden.
Die Entwicklungsumgebung kann die Werte der Variablen nicht sehen, da diese dynamisch sind. Daher können die Fehler nun erst zur Laufzeit erkannt werden. Dies läßt sich durch Verwendung von Konstanten vermeiden. Konstanten sind auch in vielerlei Hinsicht einfacher zu handhaben als Variablen, daher:
Wann immer möglich, sollten Konstanten statt Variablen verwendet werden.
(first chance exception = the debugger gets the first chance to see the exception. If the debugger allows the program execution to continue and does not handle the exception, the program will see the exception as usual. If the program does not handle the exception, the debugger gets a second chance to see the exception. In this latter case, the program normally would crash if the debugger were not present. If you do not want to see the first chance exception in the debugger, you should disable first chance exception handling for the specific exception code. Otherwise, when the first chance exception occurs, you may need to instruct the debugger to pass on the exception to the program to be handled as usual. )
Zuweisungen
Module Module1
Sub Main()
Dim n = 0
n = 7
Debug.Print( n = 8 )
Debug.Print( n )
End SubEnd Module
Aufgabe Schreiben Sie Anweisungen, die den Wert einer Integer-Variablen »a« um 1 erhöhen.
Aufgabe Schreiben Sie Anweisungen, die den Wert einer Double-Variablen »x« mit dem Wert einer Double-Variablen »y« vertauschen.
Parameter von Subs
- Beispiel (Modul)
Module Module1
Sub Emit5()
Debug.Print( 5 )
End SubSub Emit6()
Debug.Print( 6 )
End SubSub Emit9()
Debug.Print( 9 )
End SubSub Main()
Emit5()
Emit6()
Emit9()
End SubEnd Module
- Beispiel (Ausgabe)
5
6
9- Beispiel (Modul)
Module Module1
Sub Emit( ByVal v As Integer )
Debug.Print( v )
End SubSub Main()
Emit( 5 )
Emit( 6 )
Emit( 9 )
End SubEnd Module
- Beispiel (Ausgabe)
5
6
9- Beispiel (Modul)
Module Module1
Sub Print( ByVal v As Integer )
System.Console.WriteLine( v )
End SubSub Main()
Print( 5 )
Print( 7 )
End SubEnd Module
- Beispiel (Ausgabe auf Konsole)
5
7
Umleitungsprinzip
Typbedingungen
Parametrisierung von Aktionen: »Print« ist eine parametrisierte (also teilweise unbestimmte) Aktion, »Print( 5 )« ist eine (bestimmte) Aktion.
- Beispiel (Modul)
Module Module1
Dim v As Integer
Sub Print()
Debug.Print(v)
End SubSub Main()
v = 9 : Print()
v = 2 : Print()
End SubEnd Module
- Beispiel (Ausgabe im Direktfenster)
9
2
Die Übergabe über eine geteilte Variable ist im allgemeinen zu vermeiden, da fehlerträchtiger und unübersichtlicher (etwa bei vielen Funktionen). Geteilte Variablen sind aber nicht vollständig abzulehnen, da sie in anderem Zusammenhang hilfreich sind. Zu bloßen Übergabe einer Information an eine Methode sollten aber stets Paramter bevorzugt werden.
- Beispiel (Modul)
Module Module1
Sub Change( ByVal v As Integer )
v = 3
End SubSub Main()
Dim v = 9 : Change( v ): Debug.Print( v )
End SubEnd Module
- Beispiel (Ausgabe im Direktfenster)
9
Übungsaufgaben
- / Übungsfrage
- Welche Ausgabe wird erzeugt?
Module Module1
Dim v As Integer = 22
Sub Print( ByVal v As Integer )
Debug.Print( v )
End SubSub Main()
Dim v As Integer
v = 6 : Print( 17 )
End SubEnd Module
- / Übungsaufgabe Sub zur Ausgabe einer Zufallszahl im Bereich von 1 bis n.
Mehrere Parameter
- Beispiel (Modul)
Module Module1
Sub Print2( ByVal i As Integer, ByVal j As Integer )
Debug.Print( i )
Debug.Print( j )
End SubSub Print2a( ByVal i As Integer, ' implicit line continuation
ByVal j As Integer )
Debug.Print( i )
Debug.Print( j )
End SubSub Main()
Debug.Print( "-- " & TimeOfDay )
Print2( 15, 16 )
Print2a( 17, 18 )
End SubEnd Module
- Beispiel (Ausgabe im Direktfenster)
-- 18:06:01
15
16
17
18- / Übungsaufgabe Sub zur Ausgabe einer Zufallszahl im Bereich von n bis m.
Parameter von Funktionen
- Beispiel (Modul)
Module Module1
Function TemperatureInDegreesCelsius(
ByVal temperatureInKelvin As Double ) As Double
Const offset As Double = 273.15Return temperatureInKelvin - offset
End Function
Sub Main()
Debug.Print( TemperatureInDegreesCelsius( 300 ))
End SubEnd Module
- Beispiel (Ausgabe)
26.85
- Beispiel (Modul)
Module Module1
Function g()
Debug.Print( "g" )
End FunctionFunction f( ByVal x )
Debug.Print( "f" )
End FunctionSub Main()
Call f( g() )
End SubEnd Module
- Beispiel (Ausgabe)
g
f- / Übungsaufgabe Sub zur Rueckgabe einer Zufallszahl im Bereich v n bis m.
Überladungen von Methoden
- Beispiel (Ausgabe)
Module Module1
Sub S( ByVal p As Integer )
Debug.Print("Integer")
End SubSub S( ByVal p As Double )
Debug.Print("Double")
End SubSub Main()
S( 1 )
S( 1.0 )
End SubEnd Module
- Beispiel (Ausgabe)
Integer
Double
statische Objekte
Module Counter
Dim field As Integer = 0
Sub Reset()
Counter.field = 0
End SubSub Print()
Deb`ug.Print(Counter.field)
End SubSub Increment()
Counter.field = Counter.field + 1
End SubEnd Module
Module Module1
Sub Main()
Counter.Reset()
Counter.Print()
Counter.Increment()
Counter.Print()
End SubEnd Module
Teil 4 Weitere Sprachelemente von VB
Schwerpunkt: strukturierte Programmierung
{$ulxxo~>722551 jf — Module in VB.net}If- und IIf-Funktion
The new If function does the same thing as IIf except it performs short-circuit evaluation. Dim value = If(False, FunctionA(), FunctionB())
Weitere Möglichkeiten der IDE
Sprungmarken und GoTo
Steuerstrukturen
{$ulxxo~>722550 jf — Die if-Anweisung in VB.net}Teil 5 Objekte
objekt-orientierte Programmierung
{$ulxxo~>722570 Statische Aufrufe in VB.net }Referenztypen
Aufrufe mit Kontext
Beispiele nichtstatischer Methoden aus der Standardbibliothek
Beziehungen zwischen Referenztypen
Objekte
MsgBox("Run-time type of constant naturalLogBase is " & _ naturalLogBase.GetType.ToString())
Referenznamen
nullable, meaning it can take the value Nothing:
Dim a As Integer?
Dim b? As Integer
Dim c As Nullable(Of Integer)
Der Fehlwert von String und anderen Referenztypen ist Nothing.
Exemplarerzeugung
Erste Schritte mit WinForms
Die objektorientierte Programmierung ist zunächst ein allgemeines Konzept, das sowohl zusammen mit einer Konsolenoberfläche als auch mit graphischen Benutzeroberflächen eingesetzt werden kann. Genauso können Programme mit graphischer Benutzeroberfläche auch ohne objektorientierte Programmierung erstellt werden. Heute findet man zwar oft beides kombiniert, man darf aber deswegen nicht denken, daß die objektorientierte Programmierung speziell für graphische Benutzeroberflächen gedacht ist oder umgekehrt graphische Benutzeroberflächen unbedingt objektorientierte Programmierung verlangen würden.
Operationen auf Oberklassen
Referenzdeklarationen
Referenzvariablen
Referenzen und Referenzeffekte
Referenzparameter
Referenzergebnisse
Nicht-Shared Deklarationen
Exemplare zu einer Klassendeklaration
Deklaration von Methoden
Deklaration von Feldern
Konstruktoren
Anwendungen
Die Implementation von Schnittstellen
Textfelder in WinForms
Optionale Ergänzungen des bisherigen Aufbaukurses
Behandlung von Ausnahmen (Laufzeitfehlern)
Datenbankzugriffe
Zugriffe auf das Netz (Internet)
Erstellen von Webseiten
Dateizugriffe
Anhang
Aufruf von VB-Funktionen aus Excel
VB-Funktionen können grundsätzlich von Excel aus aufgerufen werden, wenn eine COM-DLL mit TLB-Datei mit VB erzeugt wird, die dann von VBA aus aufgerufen werden kann. Dafür wird ein class library project erstellt und ein COM Class item eingefügt. Dieses COM Class item konnte aber in der aktuellen Express-Version nicht gefunden werden. Da bei dieser Vorgehensweise
VB10 hat kein Com Class Item Typ mehr, statt dessen wird die folgenden Auszeichnung verwendet
<ComClass(Class1.ClassId, Class1.InterfaceId, Class1.EventsId)>
Public Class Class1
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "93534c94-9fc1-4a54-b022-338fa7d454c1"
Public Const InterfaceId As String = "03787ed3-bc65-41a1-9053-d37f390ff94b"
Public Const EventsId As String = "34d12c14-8afd-44b7-a987-fc2f909724b6"
#End Region
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
Public Sub SortArray(ByRef arTemp() As String)
Array.Sort(arTemp)
End Sub
Public Function Test() As String
Test = "Abc"
End Function
End Class
Als Admin:
C:
cd \Users\s\AppData\Local\Temporary Projects\ClassLibrary1\bin\Release
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe ClassLibrary1.dll /tlb /codebase
(Runtime error 80070002 erscheint später in VBA, falls "/codebase" vergessen wird)
In VBA Verweis hinzufügen.
Sub a()
Dim C As New Class1
Debug.Print C.Test
End Sub
Sub Example()
Dim Cls1 As New ClassLibrary1.Class1
Dim arTemp(0 To 2) As String
arTemp(0) = "Bottle"
arTemp(1) = "Apple"
arTemp(2) = "Aaron"
Call Cls1.SortArray(arTemp)
Set Cls1 = Nothing
Debug.Print arTemp(0)
Debug.Print arTemp(1)
Debug.Print arTemp(2)
End Sub
Function alpha() As String
Dim C As New Class1
alpha = C.Test
End Function