Programmieren in Visual Basic

Theoretische Grundlagen

Grundlegende Herangehensweise

Denk strukturiert

Bei der Software Entwicklung sollte man nie direkt loslegen zu programmieren!

Typischer Ablauf, auch wenn in einfachen Fällen stark verkürzt:

  1. Requirement Engineering
  2. Design
  3. Implementation
  4. Testing

Wichtige Prinzipien:

  • Eine Komponente hat genau eine Aufgabe
  • hierarchisches Denken, von Abstrakt zu Konkret
  • One Level of Abstraction

Sei penibel

Ein PC ist dumm. Er kann maximal so intelligent werden, wie sein Programmierer.

Ein PC kann nicht abschätzen, nicht annehmen, nicht vermuten. Entweder man sagt ihm genau was Sache ist oder er baut Scheiße

Wenn du in Gedanken etwas So ungefähr oder So in etwa hast, kann der PC damit noch nichts anfangen. Er braucht Genau so.

Alles was du nicht bedenkst wird später von deinem Code falsch gemacht

Drück dich klar aus

Das folgt eigentlich aus vorigem Punkt: Die Penibilität muss sich auch im geschriebenem Wort (egal ob Anforderung oder Code) wiederfinden. Die Suche nach geeigneten Namen ist manchmal nicht trivial, dabei sollte man aber dennoch nicht aus Frust das erst-beste nehmen.

Aber das geschriebene Wort muss auch für jeden zukünftigen Leser (inkl. dir selbst) in sich klar sein. Er muss es überschauen und vom Grund her schnell verstehen können.

Hilfreiche Handlungsempfehlungen:

  • Sprechende Namen von Variablen und Methoden
  • kaum Abkürzungen
  • kurze Methoden
  • kleine Klassen

Oder anders ausgedrückt:

Guter Code ist seine eigene Dokumentation

Guter Code liest sich wie Prosa

Prinzipientreue

Klingt vielleicht eher abschreckend und wird einem nicht unbedingt sofort klar, es hilft aber enorm:

Folge praktisch erprobten Prinzipien - du musst nicht jeden Fehler selber wiederholen

Prinzipien kamen bereits und werden immer wieder auftauchen. Sie helfen einem Fehler vorzubeugen und, wenn die Prinzipien wirklich eingeschliffen sind, schneller zu gutem Code zu kommen.

Je nach Bereich in dem man sich bewegt sind andere wichtig. Was eigentlich durchweg immer gilt:

  • Single Responsibility
  • KISS: Keep it simple, stupid
  • CSE30 (Bitte ANR: HALTET EUREN SCHEIß KONSISTENT)

Requirement Engineering: Ziel & Anforderungen

Beim Requirement Engineering geht es darum die Anforderungen des Systems sauber zu erarbeiten und zu dokumentieren um dann technische Lösungen dafür entwickeln zu können.

Anforderungsanalyse ist dabei bereits ein erster Schritt zur Lösungserzeugung, allerdings eher fachlich denn technisch.

Folgende Aspekte des Systems sollten betrachtet werden:

Ziel

Kurze, knappe Beschreibung wofür man das Ganze macht. Bei größeren Systemen ist esdurchaus möglich, dass es mehr als 1 gibt - bei kleinen Helferlein wie Makros am besten Unix-Regel befolgen:

one task one process

ein Tool pro Aufgabe

Rahmenbedingungen

Was muss bei der Umsetzung beachtet werden?

  • technisch:
    • Programmiersprache
    • Framework
    • Environment
  • organisatorisch:
    • wo liegen die Daten?
    • wohin mit Ergebnissen
  • fachlich:
    • math. Algorithmen?
    • fachliche Hintergründe und Regelwerke

In größeren Systemen müssen noch die beteiligten Akteure sowie die Stakeholder berücksichtigt werden.

Datenmodel

Eine Beschreibung bzw. Definition der Objekte und deren Attribute mit denen innerhalb des Systems gearbeitet wird. Primär sollte man sich auf die fachlichen Datenobjekte konzentrieren, sowie deren Beziehung untereinander. Aber auch die systembedingten (z.B. Konfiguration) sollten durchdacht sein.

Prozessablauf

Beschreibung dessen, was denn wirklich zu tun ist, um das Ziel zu erreichen.

Möglichst nicht in Prosa sondern kurz, klar, strukturiert. Möglichkeiten sind Diagramme (z.B. UML) oder Use Cases.

Prosa birgt durch Worte und Begriffe wie oder, wie, in etwa oder analog zu durchaus mehr Potential zu Zweideutigkeiten und Missverständnissen als man zuerst glauben mag.

Dabei sollte man nicht einen einzigen, vollständig ausdetailierten Prozess beschreiben, sondern hierarchisch vorgehen. Ein Prozess besteht aus um die 7 Schritte von denen jeder wieder als Unterprozess ausdetailiert werden kann.

Innerhalb eines Prozess sollte jeder Schritt auf dem gleichen Abstraktionslevel liegen.

Design: Dekomposition

Die Dekomposition ist der erste technische Schritt zur Lösungserzeugung.

Hierarchische Aufteilung

Man nimmt die erarbeiteten Anforderungen und guckt welche Teile man also im System brauchen wird um die gewünschte/beschriebene fachliche Lösung technisch wirklich umsetzen zu können.

Dabei sollte man so viel wiederverwerten, verallgemeinern und vereinheitlichen wie möglich - ohne natürlich die endgültige Lösung fachlich zu verändern.

Man geht hierarchisch dabei vor und baut erstmal größere Blöcke, die zu weiteren, kleineren, spezifischeren Blöcken dekomponiert werden.

Dabei sollte immer gelten:

  • Information Hiding
  • Single Responsibility & Separation of Concern
  • One Level of Abstraction

Design Pattern

Design Patterns sind Strukturen und Mechansismen, die sich bewährt haben um bestimmte, wiederkehrende Problemstellungen zu Lösen. Dabei sind Design Patterns mehr eine Lösungsschablone denn die fertig ausgearbeitete Musterlösung.

Zumindest einige, grundlegende sollte man im groben kennen - ähnlicher Hintergrund wir bei den Prinzipien:

Du musst dir nicht jede Lösung neu ausdenken

Eines der wohl bekanntesten Bücher dazu: Gang of Four, Design Patterns

Implementierung

Das ist, was die meisten als Programmierung verstehen. Es ist aber nicht der einzig wichtige Part.

Es geht hierbei darum die definierten Blöcke des Designs so zu erschaffen, dass die Prozesse des Requirement Engineering möglich sind.

Im Design wird üblicherweise nicht jedes Detail bis zum Ende durchdacht, vielfach werden letzte Stellschrauben im Verlauf der Implementierung verändert bzw. erst gesetzt. Während der Implementation lohnt es sich deshalb immer auch über das Mikro-Design des aktuellen Codes nachzudenken.

Egal was im Requirement Engineering und Design erdacht ist, es wird ausgeführt, was implementiert wurde. Aber ohne vorangehendes Requirement Engineering und Design ist die Wahscheinlichkeit von funktionellen Fehlern oder Miskonzeptionen höher.

Der Code ist am Ende die einzige Wahrheit

Code muss auch grade deshalb unbedingt gut strukturiert und lesbar sein - sonst ist die Suche nach Umsetzungsfehlern (Bugs) sehr aufwendig und nervig. Geschweige denn Weiterentwicklung.

Wichtige Prinzipien:

  • sprechende Namen von Klassen, Methoden und Variablen
  • kurze Methoden
  • kleine Klassen
  • One Level of Abstraction

Grundlegende Werkzeuge

Primitive Ausdrücke

Typen

In jeder Programmiersprache gibt es verschiedene Typen an Daten mit denen man arbeitet. Von den ganz konkreten Ja/Nein, Zahl und Text über abstrakteren wie Menge/Liste zu ganz abstrakten. Wie die Typen heißen und welche Untertypen (Ganze Zahlen, reelle Zahlen, ...) es gibt hängt von der jeweiligen Programmiersprache ab.

Je nach Typ kann man andere mathemathische, vergleichende oder logische Operationen durchführen. Eine Text kann man zum Beispiel nicht dividieren, bei einer Zahl nicht Buchstaben anfügen.

Native Typen in VBA:

  • Ja/Nein: Boolean
  • ganze Zahlen: Byte, Integer, Long
  • reelle Zahlen: Single, Double, Decimal
  • Text: String
  • Datum: Date
  • Währung: Currency

Variablen

Um mit einem Wert, der einen bestimmten Typ hat, besser im Programm arbeiten zu können weist man den üblicherweise einer Variable zu. Die Variable kann wie der Wert an sich verwendet werden, der Variable kann aber auch im weiteren Verlauf ein neuer Wert zugewiesen werden.

In vielen Programmiersprachen ist eine Variable einem Typ fest zugeordnet, sprich es können der Variable nur Werte dieses Typs zugewiesen werden (statische Typisierung). Anderen Sprachen können Werte beliebigen Typs der gleichen Variable zugewiesen werden (dynamische Typisierung). VB ist primär dynamisch Typisiert, man kann aber auch eine statische Festlegung einer Variable erzwingen.

Variablennamen sollten immer mit Kleinbuchstaben beginnen.

Variablennamen sollten klar darlegen welche Aufgabe die Variable hat.

In VB erfolgt die übliche, dynamische Deklaration wie folgt:


	Dim nameDerVariable
			

Eine statische Deklaration wäre:


	Dim nameDerVariable As TypDerVariable
			

Eine Deklaration einer Liste (Array) von Typen wäre:


	Dim nameDesArrays(anzahlDerElemente) As TypDerElemente
			

Üblicherweise unterscheidet man dabei zwischen dem Erzeugen einer Variable (Deklaration) und der Zuweisung eines Werts zur Variable (Definition). In einigen Programmiersprachen wird eine Variable implizit deklariert sobald sie das erste mal definiert wird. Häufig können (explizite) Deklaration und Definition in einem Schritt erfolgen.

Das implizite deklarieren hat Vorteile, da man währnd des Programmierens nicht erst drüber nachdenken muss, welche Variablen man denn nun alle braucht und sind die schon deklariert oder muss dies noch erfolgen. Dadurch kann man also schneller Code runterschreiben. Allerdings hat dieses Verhalten auch Nachteile - zum einen was die effizienz von Code angeht aber es kann auch die Fehlersuche schwerer machen. Wird nämlich aus Versehen eine Variable falsch geschrieben (Zeichendreher oder ähnliches), so muss man sehr genau hinschauen wo man die Variable wie geschrieben hat. Bei explizit notwendiger Deklaration weist einen der Compiler/Interpreter darauf hin, wenn eine Variable (die falsch geschriebene) das erste mal genutzt wird. Man wird also direkt darauf gestoßen, dass da etwas nicht stimmt.

Eine (einfache) Variable wird definiert via:


	nameDerVariable = wertDerVariable
			

In bestimmten Sonderfällen kommt folgende Variante zum Einsatz (später mehr):


	Set nameDerVariable = wertDerVariable
			

Um in VB zu erzwingen, dass alle Variablen explizit deklariert werden müssen kann folgende Befehl zu Beginn des Moduls verwendet werden:


	Option Explicit
			

Mathematische Operatoren

+, -, *, /, ^, mod

  • Die ersten 4 sind bekannt.
  • ^ bedeutet hoch-Rechnung (3^3 = 27)
  • mod bedeutet modulo, also Rest (12 mod 5 = 2)

Vergleichende Operatoren

=, <, >, <=, >=, <>, is, like

  • <, >, <=, >= sind für numerische Werte sowie Strings/Texte
  • like ist nur für Strings/Texte:
    • vergleich auf Ähnlichkeit anhand von Platzhaltern
    • ? => beliebiges Zeichen
    • * => beliebig viele (auch 0) beliebige Zeichen
    • # => beliebige Ziffer
  • is vergleicht Objekte auf Identität (dasselbe Objekt)

Logische Operatoren

and

  • True and True => True
  • True and False => False
  • False and True => False
  • False and False => False

or

  • True or True => True
  • True or False => True
  • False or True => True
  • False or False => False

not

  • not True => False
  • not False => True

xor

  • True xor True => False
  • True xor False => True
  • False xor True => True
  • False xor False => False

eqv

  • True eqv True => True
  • True eqv False => False
  • False eqv True => False
  • False eqv False => True

Weitergehende boolsche Algebra

Regeln zur Negation von Ausdrücken

  • not (A and B) = (not A) or (not A)
  • not (A or B) = (not A) and (not B)

Rein informativ, die Regeln zu Herleitungen/Umrechnungen

  • A and (not A) => False
  • A or (not A) => True
  • (A and B) or (not A and not B) => A eqv B
  • (A and (not B)) or ((not A) and B) => A xor B
  • not (not A and not B) => A or B
  • not (not A or not B) => A and B

Kommentare

Ein Kommentar ist ein beliebiger Text der vom Compiler/Interpreter vollkommen ignoriert wird und für den menschlichen Leser des Codes gedacht ist.

Kommentare sind ein gutes Hilfsmittel um deutlich zu machen was im Code vor sich geht, aber auch dieses Hilfsmittel hat auch negative Seiten:

  • Es verleitet dazu den Code nicht ganz so sauber zu programmieren, da man ja über einen Kommentar beschreiben kann, was er macht
  • Code und Kommentar können sich im Laufe der Zeit auseinanderleben, das heißt der Code wird angepasst an neue Bedingungen/Situationen aber der Kommentar vergessen. Und dadurch passt der Code nicht mehr zum Kommentar bzw. schlimmstenfalls verleitet der Kommentar den Programmierer den Code falsch zu verstehen.

Aus beiden Gründen ist meine persönliche Empfehlung:

Der Code sollte sich selbst erklären, durch geeignete Wahl der Namen und durch Kürze der Code-Blöcke

Kommentare sollten nur das Wieso nie das Was/Wie erklären

In VB werden Kommentare über das Apostroph eingeleitet und gehen bis zum Ende der Zeile.


	doSomething 'alles hier ist Kommentar
			

Flow control

In imperativen Programmiersprachen wird jeder Befehl von oben nach unten nacheinander ausgeführt. Das ist der Programmfluss. Diesen kann man aber auch steuern. Zum einen in dem man in bestimmten Situationen Teile des Codes überspringt, je nach Situation andere Teile des Codes benutzt oder in dem man Teile des Codes mehrfach ausführen lässt.

Alternative Abläufe

If

Das If ist wohl das einfachste aber auch häufigst genutzte Werkzeug zur Kontrolle des Programmflusses.

Es kann sowohl eingesetzt werden um nur in bestimmten Situation Code auszuführen, als auch um je nach dem entweder diesen oder jenen Code auszuführen. Und man kann sogar ganze Ketten an Code-Blöcken definieren die nur in den jeweiligen bestimmten Situation genutzt werden.


	If bedingung Then
		...
	End If

	If bedingung Then
		...
	Else
		...
	End If
	
	If bedingung1 Then
		...
	Elseif Bedingung2 Then
		...
	Elseif Bedingung3 Then
		...
	Else
		...
	End If
				

Select Case

Ein Select ist eine einfachere Möglichkeit Ketten an Codeblöcken zu definieren, die je nach Wert eines bestimmten Ausdrucks ausgeführt werden.


	Select Case ausdruck
		Case wert1
			...
		Case wert2
			...
		Case Else
			...
	End Select
	
	Select Case Ausdruck
		Case Is vergleichsausdruck1
			...
		Case Is vergleichsausdruck2
			...
		Case Else
			...
	End Select
				

iif

inline if


	ergebnis = iif(Bedingung, WertWennErfüllt, WertWennNichtErfüllt)
				

switch

inline case


	ergebnis = switch(Bedingung1, WertWennBedingung1, Bedingung2, WertWennBedingung2, ...)
				

choose

spezieller inline case


	ergebnis = choose(Auswahlwert, ErgebniswertWennAuswahl1, ErgebniswertWennAuswahl2, ...)
				

Schleifen

Schleifen bieten die Möglichkeit bestimmte Schritte mehrfach auszuführen. Zusammen mit if/select bieten sie die fundamentale Basis zum Steuern des Programmflusses.

Grundsätzlich besteht jede Schleife aus einer Bedingung und einem Schleifenkörper. Die Bedingung bestimmt, ob die Schleife durchgeführt wird und der Schleifenkörper ist, was bei erfüllter Bedingung durchgeführt wird.

Ein Schleifendurchgang wird oft auch als Iteration und das Durchlaufen einer Schleife als iterieren bezeichnet.

Es gibt verschiedene Arten von Schleifen die sich für bestimmte Szenarien besser oder schlechter eignen.

Do While|Until ... Loop

Über die Do While-Schleife kann man Code so lange wiederholen lassen, bis ein vordefinierter Ausdruck das erste mal False ergibt.


	Do While ausdruck
		...  
	Loop
				

Es gibt auch die Variante Do Until die den Code so lange wiederholt, bis der Ausdruck das erste mal True ergibt.


	Do Until ausdruck
		...
	Loop
				

Innerhalb der Schleife kann man den Ablauf auf zwei Arten zusätzlich manipulieren:

Über Exit Do kann man die Schleife beenden, also direkt mit dem nächsten Befehl nach der Schleife weiter machen.

Do ... Loop While|Until

Diese Schleife ist im Grunde nur eine weitere Variante der vorigen (genauer gesagt sind es zwei weitere), die sich darin unterscheidet, dass zuerst der Inhalt der Schleife durchgearbeitet wird und erst danach der Ausdruck geprüft wird. Der Schleifenkörper wird also immer mindestens einmal ausgeführt.


	Do 
		...  
	Loop While ausdruck
				

	Do
		...
	Loop Until ausdruck
				

In diesen Varianten ist Exit Do in gleicher Weise nutzbar.

For ... Next

Das numerische For ist geeignet, um die Schleife eine bestimmte Anzahl an malen zu durchlaufen, oder um durch eine bestimmte Zahlenreihe zu iterieren.

Will man eine Schleife genau X mal durchlaufen, so ist dies auf folgende Weise möglich:


	For zähler = 1 To X
		...
	Next
				

Die Variable die man im For deklariert wird Zählervariable oder auch Iterator genannt. Diese ist üblicherweise nur innerhalb des Schleifenkörpers gültig.

Die Schrittweite lässt sich auch vorgeben, will man alle grade Ziffern haben so wäre folgender Code zu nutzen:


	For ziffer = 2 To 8 Step 2
		...
	Next
				

Den Start- und Endwert kann man beliebig wählen, auch absteigend. Zum Beispiel für einen Countdown:


	For rest = 10 To 0 Step -1
		...
	Next
				

Analog zu den Do ... Loop-Schleifen kann man auch hier den Verlauf der Schleife manipulieren:

Über Continue For kann man direkt zur nächsten Iteration springen, den Rest des codes bis zum loop also überspringen.

For Each ... Next

Dieses For wird oft generisches genannt, da es nicht über einen Zahlenbereich iteriert sondern über beliebige Listen. Zum Beispiel Array oder List-Objekte.


	For Each zähler In aufzählung
		...
	Next
				

Auch hier gibt es den Befehl Exit For

Methoden

Methoden sind eine Gruppierung von zusammengehörenden Befehlen um diese mehrfach zu verwenden.

Diese Gruppierungen können parametrisiert werden, also in Abhängigkeit von externen Infos spezifisch reagieren. Diese externen Informationen werden der Methode beim Aufruf übergeben und üblicherweise Parameter genannnt.

Einige Methoden müssen auch Informationen zurück übermitteln, sei es das Ergebnis einer mathematischen Berechnung oder den aktuellen Status oder Information über den Ausgang einer (möglicherwiese komplexeren) Verarbeitung. Diese zurückgemeldeten Informationen heißen Rückgabewerte oder häufig auch auf englisch return value.

Eine Methode kann, in den allermeisten Programmiersprachen, nur einen Wert zurückgeben. Es gibt aber auch Sprachen die beliebig viele Werte zurückgeben können.

Deklaration und Definition

Eine Methode muss, wie Variablen auch, deklariert und definiert werden. Eine explizite Deklaration ohne direkte Definition passiert in nur noch wenig Programmiersprachen. Meist wird beides gemeinsam durchgeführt.

Bei der Deklaration wird der Name, die Parameter und (in statisch typisierten Programmiersprachen) der Typ des Rückgabewertes angegeben. In statisch typisierten Sprachen ist der Typ des Rückgabewertes von Methoden die nichts zurückgeben meist void oder nil, was beides im Grunde Das Nichts bedeutet.

In VB muss man unterscheiden, ob die Methode einen Rückgabewert hat oder nicht. Methoden ohne Rückgabewert werden als Sub-Routinen bezeichnet und wie folgt deklariert und definiert:


	Sub methodenName(Parameter1, Parameter2)
		...
	End Sub
			

Methoden, die einen Rückgabewert haben werden als Funktionen bezeichnet und wie folgt deklariert undd definiert:


	Function methodenName(Parameter1, Parameter2)
		...
		methodenName = wertOderVariable
	End Function
			

Der Rückgabewert wird festgelegt, in dem man einer (magischen) Variable mit dem gleichen Name wie der Methode einen Wert zuweist.

Optional kann man, wie bei der Variablendeklaration auch bei der Methodendeklaration einen Typ festlegen, den Typ des Rückgabewertes:


	Function methodenName(Parameter1 As TypDesParameter, Parameter2 As TypDesParameter) As TypDesRückgabeWertey
		...
		methodenName = wertOderVariable
	End Function
			

Methodennamen sollten immer klar darstellen, was das Ziel der Methode ist.

Methodennamen sollten immer ein Verb als zentrales Element beinhalten.

Methoden überladen (overloading)

(Auch wenn dies von VB nicht unterstützt wird der Vollständigkeit halber)

Eine Reihe von Programmiersprachen unterstützen das sogenannte überladen einer Methode. Das heißt es gibt die gleiche Methode (des Namens nach) in mehreren, spezialisierten Varianten, je nach dem welche und wieviele Parameter übergeben werden. Dabei kann sich auch der Rückgabetyp von einer Methodenvariante zur anderen unterscheiden.

Optionale Parameter

In immer mehr Programmiersprachen können Parameter als optional deklariert werden. Das heißt, wenn beim Aufruf der Methode kein Wert für diesen Parameter benannt wird, so wird ein, bei der Deklaration festgelegter, Standardwert genommen.

Üblicherweise müssen die optionalen Parameter hinten in der Parameterliste auftauchen, also es darf kein benötigter Parameter hinter einem optionalen Auftauchen.

In VB werden optionale Parameter wie folgt deklariert:


	Sub methodenName(Parameter1, Optional Parameter2 As TypDesParameter = StandardwertDesParameter)
		...
	End Sub
			

Benutzung

Eine Methode wird über ihren Namen aufgerufen, danach folgen die Parameter die man der Methode mitgeben will. Im Grunde alle weithin bekannten Programmiersprachen kapseln dabei die Parameter in Klammern ein, was die Übersicht erhöht sobald die Aufrufe ein wenig komplizierter werden. Eine Reihe Programmiersprachen bieten dabei an die Klammern wegzulassen, solange der Ausdruck dadurch eindeutig bleibt.

VB ist ein wenig anders. Um Methoden aufzurufen (ohne an deren Rückgabewert interessiert zu sein) darf man keine Klammern um die Parameter schreiben:


	methodenName
	methodenName parameter1, parameter2
			

Ist man aber an dessen Rückgabewert, in welchem Kontext auch immer, muss man die Parameter einklammern:


	variablenName = methodenName()
	if methodenName(parameter1, parameter2) then ...
			

Man kann VB dazu bringen auch bei einfachen Methodenaufrufen Klammern zu erwarten, in dem man dem Methodenaufruf call voranstellt:


	call methodenName()
			

Als Parameter einer Methode kann natürlich der Rückgabewert einer anderen genommen werden:


	methode1 parameter1VonMethode1, methode2(parameterVonMethode2)
			

Möchte man einen optionalen Parameter überspringen, den darauffolgenden optionalen Parameter aber setzen, so lässt man den Wert des zu überspringenden Parameters weg, schreibt aber das Komma um anzuzeigen, dass nun der nächste Parameter definiert wird:


	methodenName parameter1, , parameter3
			

Rekursion

Eine Rekursion ist, wenn eine Methode sich selber aufruft. Dies kann in manchen Fällen enorm praktisch sein, allerdings muss man genau aufpassen, dass sich dadurch keine Endlosschleife bildet. Man braucht also ein Abbruchkriterium welches innerhalb der Methode geprüft wird.

Ein bekanntes Beispiel ist die Berechnung von Fibunacci-Zahlen:


	Function fib(zahl As Integer) As Integer
		if zahl == 0 'Abbruchkriterium
			fib = 1
		elsif zahl == 1 'Abbruchkriterium
			fib = 1
		else
			fib = fib(zahl - 1) + fib(zahl - 2) 'Rekursion
		end
	End Function
			

ByVal und ByRef

Es gibt zwei Arten wie Parameter an eine Methode übergeben werden können:

  • ByVal: Es wird der Wert der Variable genommen, kopiert und der Methode als ein Parameter übergeben
  • ByRef: Es wird eine Referenz auf die Variable selber der Methode als Parameter übergeben

In VB macht es für die Benutzung keinen Unterschied, ob ein Parameter ByVal oder ByRef ist. Aber es ergeben sich dadurch unterschiedliche Möglichkeiten aber auch potentielle Schwierigkeiten.

ByVal-Variablen kann man nach belieben innerhalb der aufgerufenen Methode ändern und verarbeite. Keine dieser Änderungen ist außerhalb dieser Methode sichtbar, da die Methode eben eine Kopie des Wertes als Parameter erhalten hat.

Dahingegen ist jegliche Änderung an einer ByRef-Variable die in einer aufgerufenen Methode durchgeführt wird auch der aufrufenden Methode sichtbar, da die Variable selber an die Methode übergeben wird.


	Sub foo(ByRef fubar As Integer)
		fubar = fubar + 5
	End Sub
	
	Sub bar()
		Dim beliebigeVariable As Integer
		beliebigeVariable = 3

		foo beliebigeVariable
	
		MsgBox (beliebigeVariable) ' zeigt an: "8"
	End Sub
			

Module

Nicht alle Programmiersprachen haben Module in dem hier gemeinten Sinne. Manchmal ist der Begriff für anderes verwendet, zum Teil gibt es Module nicht explizit sondern implizit in anderen Konzepten wie Objekt-Orientierung.

Als Modul ist in Visual Basic eine Zusammenstellung von Methoden gemeint. In Excel ist jede Tabelle implizit auch ein Modul, aber man kann auch manuell weitere Module anlegen.

Module eignen sich um eine weitere Ebene der Strukturierung einzuführen. Methoden die inhaltlich zusammenhängen können als ein Modul modelliert werden. Das hat mehrere Vorteile:

  • Den Benutern des Codes zeigt man an, dass die Methoden ähnliche Thematik abdecken
  • Man selber muss sich durch weniger Code auf einmal durcharbeiten, wenn man nach Fehlern sucht oder die Umsetzung einzelner Methoden ändern will
  • Man kann gezielter Code wiederverwenden, da man Module ex- und importieren kann
  • Module bieten die Möglichkeit interne Helferlein zu benutzen, die dem Rest des Codes nicht verkomplizieren (Siehe folgenden beiden Kapitel).

Modul-interne Methoden

Man kann einer Methode eine sogenannte Sichtbarkeit mitgeben. Dies hat einen Einfluss darauf, von welchen anderen Methoden und Modulen diese Methode aufgerufen werden darf. Es gibt drei Werte:

  • Public: Diese Methode darf von überall aufgerufen werden
  • Friend: Diese Methode darf von jeglichem Code des gleichen Dokuments aufgerufen werden
  • Private: Diese Methode darf nur innerhalb des gleichen Moduls aufgerufen werden.

Durch die Möglichkeit private Methoden zu deklarieren kann man Helfermethoden innerhalb eines Moduls erschaffen, die häufig genutzte Arbeitsschritte einmalig bereitstellen, die dann von den anderen Methoden in diesem Modul verwendet werden können. Gleichzeitig stehen nach außen (also den anderen Modulen) nur die öffentlichen Methoden zur Benutzung, die die Hauptaufgaben ausführen.

Helfermethoden sollten immer privat deklariert werden.

Öffentliche Methoden sollten immer eine in sich abgeschlossene Funktionalität darstellen.

Modul-interne Variablen

Deklariert man innerhalb eines Moduls, aber außerhalb einer Methode, Variablen, so stehen diese allen Methoden des Moduls zur Verfügung. Damit kann man zum Beispiel zentrale Konfigurationen für dieses Modul ablegen, oder aber Werte uber eine Methode berechnen lassen und über eine andere Methode abfragen.

Analog zu den Methoden in einem Modul könne auch Modulvariablen als Public oder Private deklariert werden.

Modulvariablen sollten immer privat deklariert werden.

Nutzen von Modulen

Der wahre Nutzen von Modulen, und allen anderen Mitteln zur Strukturierung von Code, erschließt sich meist erst in der Praxis im Laufe der Zeit. Sobald der eigene Code so lang geworden ist, dass man sich nicht mehr zurecht findet oder man kaum was wiederverwenden kann, weil es so viele Querverbindungen von einer Methode zu den andern gibt spielen Module als Gegenentwurf ihre Stärke aus. Mein Rat ist deshalb einfach immer über Module nachzudenken - man lernt sie mit der Zeit schätzen.

Eine Methode für eine Aufgabe.

Ein Modul für eine Thematik.

Weitergehende Konzepte

Objektorientierung

Excel: Zellen & Ranges

String-Verarbeitung

Dateien

Excel: Tabellen & Workbooks

Dekomposition