Basic-Funktionen

Eigene Funktionen für Office-Programme

Mit Hilfe von Basic können sie eigene Funktionen erstellen, die sie zusätzlich mit den Standard-Funktionen in allen Kalkulationsblättern anwenden können. Besonders geeignet sind komplizierte Funktionen, die oft benötigt werden, sowie Algorithmen, die eine Programmiersprache erfordern, wie z.B. Iterationen.
VBA Basic LibreOffice-Basic, Visual Basic for Applications (VBA)
Start Eine eigene Funktion erstellen und anwenden
Funktion Übersicht: Namen, Argumente, Rückgabe, Grenzen
Trigger Wann und wie oft wird eine Function neu berechnet ?
Funktionstyp Jede Funktion liefert genau einen Wert (eines Typs) zurück
Argument-Typ Jede Funktion kann Argumente (Parameter) aller Typen annehmen
Optional Argumente wahlweise angeben oder weglassen
Wirkungsbereich Öffentlich oder Privat ?
ByRef & ByVal Übergabe von Argumenten als Verweis oder Wert
Bereich Bereich als Funktions-Argument
Rückgabe-Trick Rückgabe mehrerer Werte durch Funktionen
Hilfe Integrierte Hilfe, Internet, ...

Start:   Basic Funktion erstellen und anwenden

Erste Schritte zu einer "Benutzerdefinierten" Funktion.
Installation einer Basic-Function mit LibreOffice
Starten sie das Programm LibreOffice und darin ein (neues) Tabellen-Kalkulations-Dokument
Mit den Tasten Alt-F11 wird das Fenster des Makro-Managers geöffnet.
Alternative: Menü Extras | Makros | Makros verwalten | LibreOffice-Basic
Markieren sie links ('Makro aus...') ihr Dokument - meist das letzte der Liste (z.B. 'Unbenannt1').
Klicken sie den Button Neu und geben sie einen beliebigen Namen für das Basic-Modul ein (z.B. 'Modul1').
Das QuellText-Fenster des Moduls wird geöffnet. Darin ist meist ein Text enthalten, z.B. REM ***** BASIC *****
Fügen sie den QuellText der Basic-Funktion incr() (nächster Absatz) am Ende an.
Schließen sie das Basic-Fenster.
Installation einer Basic-Function mit MS-Excel
Starten sie das Programm MS-Excel
Mit den Tasten Alt-F11 gelangen sie in das → Basic-Fenster.
Alternative (je nach Excel-Version) Menü Extra | Makro | Visual Basic Editor oder Klick auf das VBA-Icon (rechts)
Markieren sie im Projekt-Manager (links) ihr Dokument - meist das letzte der Liste (z.B. 'Mappe1').
Fügen sie mit Menü Einfügen | Modul ein Basic-Modul ein.
Das leere QuellText-Fenster des Moduls wird geöffnet.
Fügen sie den QuellText der Basic-Funktion incr() (nächster Absatz) ein.
Kehren sie mit Alt-F11 oder mit Klick auf das Excel-Icon (ganz links oben) zur Kalkulation zurück.
Beispiel einer einfachen Basic-Funktion:
Die Function incr() erhält als Argument x eine Zahl, addiert +1 und gibt das Ergebnis zurück.
Function incr(x)
incr = x + 1
End Function

Anwendung:

Die Funktion wird in allen Kalkulations-Programme gleich verwendet:

Markieren sie eine beliebige Zelle des Kalkulations-Blatts und tragen sie ein:
=incr(123)
Bestätigen sie mit Taste Return oder mit Klick auf das grüne Häkchen

In der Zelle wird der von der Funktion zurückgegebene Wert 124 angezeigt.

Tragen sie in die Zelle A1 ein:
=GANZZAHL(ZUFALLSZAHL()*10)
Tragen sie in die Zelle A2 ein:
=incr(A1)

In Zelle A1 wird eine Zufallszahl erzeugt, in Zelle A2 die um +1 größere Zahl. Mit Taste F9 wird eine neue Zufallszahl erzeugt.
Sie haben damit:
eine eigene Basic-Funktion installiert
ihre benutzer-definierte Basic-Funktion in der Kalkulation angewendet.
Test:
Erzeugen sie selbst eine weitere Funktion decr(), welche den Eingabewert um -1 vermindert.

Basic-Funktionen

Function-Namen

Für die Namen gelten die gleichen Regeln wie für andere Basic-Variable.

Verwenden sie sprechende Namen, ohne Leerzeichen oder Sonderzeichen - Keine Umlaute !

Basic ignoriert Groß- und Kleinschreibung, daher kann Basic nicht zwischen den Functions test(), TEST(), Test(), ... unterscheiden.

Namen dürfen nicht identisch mit geschützten Worten sein, wie function, else, while, ...

Namen darf man nicht mit Zellen-Adressen verwechseln, daher sind A1, Z5, AB27, ... ausgeschlossen.

Rückgabe

Die Rückgabe des von einer Funktion berechneten Werts erfolgt durch Zuweisung an den Namen der Funktion (rechts).
In allen modernen Programmiersprachen wird dazu - anders als in Basic - die Anweisung return verwendet.

Eine Function kann nur genau einen Wert zurückgeben. Es ist erlaubt, jedoch nicht empfehlenswert, keinen Wert zurückzugeben. ↓ Tricks zur Rückgabe mehrerer Werte.

Der Typ der zurückgegebenen Daten wird mit dem Typ der Funktion angegeben - in diesem Beispiel Double (d.h. Gleitkomma-Zahl).
Wenn man z.B. den Typ auf Integer (Ganze Zahl) ändert, dann gibt die gleiche (!) Funktion eine ganze Zahl zurück !
Es ist nicht empfehlenswert, den Funktions-Typ wegzulassen: In diesem Fall versucht Basic den Typ zu erraten - das ist langsamer und weniger sicher.

Typ und Rückgabe des berechneten Werts:
Function incr(x) As Double
incr = x + 1
End Function

Funktions-Typ Double bedeutet: Diese Funktion gibt eine Gleitkomma-Zahl zurück. Falls das von der Funktion berechnete Ergebnis einen anderen Typ haben sollte, wird es vor der Rückgabe in den gewünschten Typ (hier: Double) umgewandelt.

Argumente

Die Arbeit einer Function wird normalerweise durch Daten (Argumente, Parameter) gesteuert, die man an sie übergibt. Wenn man z.B. in einer Kalkulation diese Function verwendet:
=add(A1;A2)
dann werden die aktuellen (Zahlen)-Werte der Zellen A1 und A2 als 'Argument'-Daten an die Function übergeben.

Die Basic-Function kann in diesem Fall so aussehen:
Function add(x, y)
add = x + y
End Function
Die Daten der beiden Argumente werden bei der Ausführung an die Variablen x und y der Function übergeben.
Vorteil: Die Function kann allgemeinrechnen, d.h. mit beliebigen Zahlenwerten von x und y

Argument-Typ
Es ist empfehlenswert, den Typ der Argument-Variablen ebenso wie jenen der Function (=ihres Rückgabe-Werts) festzulegen, z.B.
Function add(x As Double, y As Double) As Double
add = x + y
End Function
Wenn man die Typen der Argumente nicht angibt, dann versucht Basic, sie zu erraten. Das ist langsamer und weniger sicher.

Trigger
Das ist ein Argument, das man nicht zur Rechnung, sondern nur zur Neu-Berechnung der Funktion braucht. Details im Kapitel Trigger.

Optionale Argumente
Es ist möglich, Argumente optional anzugeben. Man kann sie bei der Anwendung wahlweise angeben oder weglassen. Details im Kapitel Optionale Argumente

Grenzen

Einer Basic-Function sind einige Grenzen gesetzt, die für allgemeine Basic-Programme (Subs) nicht gelten. Das Verhalten ist je nach Programm und Version unterschiedlich. Verwenden sie besser keine der unsicheren Methoden, damit ihre Functions unter allen bedingungen sicher funktionieren

ReadOnly
Eine Function darf die Werte anderer Zellen (oder die Eigenschaften von Objekten) lesen, jedoch normalerweise nicht ändern.
 

Trigger (Auslöser)

Als Beispiel werden Basic-Functions verwendet, die eine → Zufallszahl 'berechnen'.
Geben sie Formeln in Kalkulations-Zellen ein, welche diese Basic-Functions aufrufen.
Am Ergebnis sehen sie sofort, ob und wann die Function neu berechnet wurden.

Sonderfall Basic-Änderung

Basic-Functions werden unmittelbar nach jeder Änderung im Basic-Quelltext neu berechnet.
Das kann zu einer Fehl-Einschätzung führen, denn danach gelten andere Regeln für die erneute Berechnung !
Basic-Functions werden nur dann erneut berechnet, wenn sich mindestens eines der Argumente geändert hat.
Wenn das Beispiel mit einer beliebigen konstanten Zahl verwendet wird =rnd1(123) dann wird diese Zelle nie wieder neu berechnet, weil sich das Argument (Zahl 123) nicht ändert.
Wenn das Beispiel mit einer Adresse verwendet wird =rnd1(A1) dann wird die Function bei jeder Änderung des Wertes von Zelle A1 neu berechnet.
Wennn das Beispiel mit einer Zufallszahl verwendet wird =rnd1(Zufallszahl()) dann erfolgt eine erneute Berechnung der Function bei jeder beliebigen Änderung im Arbeitsblatt, sowie mit Taste F9 und mit MenüBefehl Extras | Optionen | Berechnung | Neu berechnen.

In manchen MS-VBA-Versionen ist es erforderlich, die Trigger-Variable auch zu verwenden. Entfernen sie in diesem Fall das ' Kommentar-Zeichen und aktivieren sie die betreffende Programmzeile, die im Programm nicht gebraucht wird.
Basic-Beispiel: Rückgabe einer Zufallszahl:

Function rnd1(trigger)
Dim x
' x = trigger
rnd1 = Rnd
End Function

Gefährliche Fehler

Die beiden rechts gezeigten Functions werden niemals neu berechnet:
Function xrnd2() erhält kein Argument und kann daher auf keine Änderung reagieren.
Function xrnd3() erhält ein Argument. Die Variable trigger wird jedoch nicht verwendet. Diese Function wird zwar in LibreOffice, nicht jedoch in MS-VBA-Versionen neu berechnet.
Zukünftige Basic-Versionen können sich evtl. anders verhalten - Programmieren sie trotzdem immer Functions, die sicher neu berechnet werden, wenn sie das erwarten.
Function xrnd2()
xrnd1 = Rnd
End Function

Function xrnd3(trigger)
xrnd2 = Rnd
End Function

Funktionstyp und Rückgabe

Jede Basic-Funktion liefert genau einen Wert an das aufrufende Programm (LibreOffice, Excel, Basic ..) zurück.
Der Rückgabewert ist ein bestimmter Daten-Typ, den sie selbst festlegen sollten.
Rückgabe (Return)
Nach Basic-Syntax erfolgt die Rückgabe eines Funktionswertes durch Zuweisung an den Namen der Funktion (hier myfunc ).
Die Zuweisung eines Rückgabe-Wertes kann beliebig oft innerhalb einer Function erfolgen. Tatsächlich zurückgegeben wird nur der zuletzt zugewiesene Wert (hier 987).

Function myfunc()
myfunc = 123
myfunc = 987
End Function
Basic zeigt keinen Fehler an, wenn sie auf die Rückgabe des Funktionswertes vergessen. Das Ergebnis ist in diesem Fall allerdings nicht sicher vorhersagbar. In diesem Fall wird meist der Funktionswert 0 (Zahl Null) zurückgegeben. Text-Funktionen liefern ohne Rückgabe einen leeren Text, usw.

Typ:

Wie jede Programmiersprache kennt auch Basic verschiedene Daten-Typen. Geben sie den Typ des Rückgabe-Werts (den FunktionsTyp) unbedingt an, um Fehlern vorzubeugen, und um die Function schneller auszuführen.
Beispiel: Function wurzel2() liefert eine Gleitkommazahl (Double) zurück, Function maier() liefert einen Text (String).
Function wurzel2() As Double
wurzel2 = Sqr(2)
End Function

Function maier() As String
maier = "Maier"
End Function
Basic zeigt keinen Fehler an, wenn sie auf die Festlegung des Funktionstyps vergessen oder verzichten. (Nur) VBA zeigt eine Auswahl-Liste möglicher Werte an, wenn sie die Type mit As eingeben.

Aufruf aus Basic:

Im Beispiel ↓ Öffentlich oder Privat wird gezeigt, dass Function's sowohl aus der Kalkulation als auch aus anderen Basic-Programmen aufgerufen werden können.
In MS-Excel erscheinen alle Function's in der Liste der BenutzerInnen-definierten Funktionen. Wenn sie eine Function nur in VBA verwenden wollen, dann deklarieren sie diese als Private
LibreOffice zeigt in der Liste der Funktionen leider überhaupt keine Basic-Funktionen an.
Private Function inc_priv(x)
' Kann nur in Basic verwendet werden
inc_priv = x + 1
End Function
...
y = inc_priv(987)
. . .
Wenn ihre Function mehrere Werte berechnet, dann gibt es einige ↓ Tricks, um sie an das aufrufende Programm zurückzugeben. Verwenden sie solche Tricks nur dann, wen sie den Umgang mit einfachen Functions sicher beherrschen.

Anzahl und Typen der Argumente (Parameter)

Funktionen ohne Argumente

sind selten. Sie liefern immer das gleiche Ergebnis (wie basic_pi() ). Außerdem werden solche Functions nur einmal berechnet (siehe ↑ Trigger / Auslöser).
Function basic_pi()
basic_pi = 4 * Atn(1)
End Function

Ein 1 Argument

Die Funktion erhält Daten in einer Variablen (hier a), verarbeitet sie nach jeder Änderung von a und gibt ein Ergebnis zurück.
Anwendung: In die Zelle eines Kalkulations-Blatts wird die Formel mit einer Adresse oder mit einer Zahl eingegeben:
=cub(A1)
=cub(12)
Die Funktion kann man - genauso wie jede Standardfunktion - in allen Blättern einer Kalkulation und in beliebig vielen (auch tausenden) Zellen verwenden. Die Ausführung ist jedoch meist etwas langsamer als die vergleichbarer Standardfunktionen.
Function cub(a As Double)
cub = a * a * a
End Function

Mit Anweisung As kann man optional den Variablen-Typ zu jedem Argument angeben. Das ist sehr empfehlenswert, da es mehr Klarheit in der Programmierung bringt, und schneller ausgeführt wird.

Mehrere Argumente

Jede Basic-Function kann beliebig viele Argumente (Parameter) aller Daten-Typen annehmen. Die Variablen der Argumente-Liste in () werden durch , Beistrich getrennt (Achtung: Basic verwendet für Gleitkomma-Zahlen wie alle anderen ProgrammierSprachen den Dezimal-Punkt !)
Function diff(x As Double, y As Double)
diff = y - x
End Function
Sie müssen beim Aufruf einer Function die Anzahl ihrer Argumente genau einhalten. Wenn sie eine Function mit mit weniger oder mehr Argumenten aufrufen als festgelegt, zeigt die Kalkulation den Fehler #WERT! an.
Ausnahme: ↓ Optionale Argumente .

Optionale Argumente (Parameter)

Man kann eine Function variabel gestalten, indem man die Eingabe mancher Argumente freistellt.
Mit Optional bezeichnete Argumente kann man wahlweise angeben oder weglassen.

Mit der Funktion IsMissing() stellt man fest, ob das betreffende Argument mitgegeben wurde. Wenn es fehlt, dann setzt man dafür einen Standard-Wert ein.
Die Funktion IsMissing() funktioniert in MS-VBA leider nur mit dem Typ Variant.

Optionale Argumente dürfen nur am Ende der Argumente-Liste stehen, d.h. nach den unbedingt erforderlichen Argumenten !

Beispiel: Argument x muss man (obligatorisch) angeben, alle anderen Argumente sind optional: Sie werden entweder angegeben oder mit Standard-Werten (hier alle =0) angenommen. Selbstverständlich könnten sie auch x als Optional definieren.
Basic-Funktion mit optionalen Argumenten:
Function parabel(x, _
Optional a As Variant, _
Optional b As Variant, _
Optional c As Variant) As Double
If IsMissing (a) Then a=0
If IsMissing (b) Then b=0
If IsMissing (c) Then c=0
parabel = a + b*x + c*x*x
End Function
Test in einer Tabellen-Kalkulation:
Tragen sie die Formel =parabel() ohne Argumente in eine Zelle ein: Das ergibt einen Fehler-Wert, da Argument x angegeben werden muss.
Tragen sie die Formel =parabel(A1) oder =parabel(3,456) in eine Zelle ein: Das ergibt auf Grund der verwendeten Formel immer den Wert 0, unabhängig von x

Tragen sie die Funktion =parabel(A1;A2) mit 2 Argumenten, =parabel(A1;A2;A3) mit 3 Argumenten oder =parabel(A1;A2;A3;A4) mit 4 Argumenten in eine oder mehrere Zellen ein. Sie können verfolgen, wie jedes Argument entweder angegeben und zur Berechnung verwendet, oder durch seinen Standardwert ersetzt wird.

Gültigkeits-Bereich: Öffentlich oder Privat ?

Wenn sie Basic-Functions nur aus der Kalkulation aufrufen, dann sind nur öffentliche Function's ( Public ) sinnvoll.

Wenn sie Functions nur aus VBA aufrufen, dann ist eine "Privatisierung" möglich. Das betrifft alle intern verwendeten Hilfs-Funktionen.
LibreOffice-Basic scheint den Unterschied derzeit zu ignorieren:
Man kann in der Tabellen-Kalkulation auch als Private deklarierte Funktionen verwenden (nicht empfehlenswert !)
Dieses Beispiel zeigt die benutzerdefinierte Funktion abstand()
Sie verwendet für die Berechnung die "Private" VBA-Funktion difq()
Private Functions sollten für das Kalkulations-Programm oder für andere Basic-Module nicht zugänglich sein.

Mit den Schlüsselworten Private oder Public (Standardwert) legen sie den Gültigkeits-Bereich von Basic-Functions fest.
Ohne spezielle Angabe ist jede Funktion Public
Function abstand(x1, y1, x2, y2)
abstand = Sqr(difq(x1, x2) + difq(y1, y2))
End Function

Private Function difq(a, b)
difq = (a - b) * (a - b)
End Function

Argumente ByRef oder ByVal

Wenn sie Basic-Funktionen nur aus der Kalkulation aufrufen, dann brauchen sie keine Information über die Art der Parameter-Übergabe an Basic-Functions. Dieses Kapitel betrifft nur den Aufruf von Basic-Functions aus Basic, d.h. aus anderen Basic-Functions oder Subs.

ByRef 6nbsp; (Standard)

Wenn nicht anders festgelegt, erfolgt die Übergabe von Argumenten immer so:
Die Funktion erhält die Adresse einer Kopie des Arguments.
Die Function kann daher die Werte der Argumente lesen und schreiben, eine Änderung wirkt sich jedoch nur auf die private Kopie aus, nicht auf das Original in der aufrufenden Function.

→ Arrays sind eine Ausnahme: Sie werden nicht kopiert, sondern es wird immer die Adresse des Original-Array's übergeben.
Details im Kapitel VBA-Arrays.
ByValue bedeutet Argument-Übergabe "als Wert":
Nur auf ausdrückliche Anweisung wird ein Argument als Wert übergeben. In diesem Falle ist ein "rückwirkender" Zugriff der aufgerufenen Function auf das Original des Arguments unmöglich.
Diese Variante müssen sie verwenden, wenn sowohl das Kalkulations-Programm als auch (andere) Basic-Functions auf eine Function zugreifen: Da beide Functions öffentlich (Public) sind, kann man beide in der Kalkulation verwenden, Function difq() darüber hinaus auch von Basic.
Offenbar können aus dem Kalkulations-Programm erhaltene Variable (x1,y1,x2,y2) nicht als Argumente bei einem Aufruf weiterer Basic-Functions eingesetzt werden. Das gilt 'meistens' - es ist leider unklar, warum manchmal Ausnahmen möglich sind.
Function abstand(x1, y1, x2, y2)
abstand = Sqr(difq(x1, x2) + difq(y1, y2))
End Function

Function difq(ByVal a, ByVal b)
difq = (a - b) * (a - b)
End Function

Bereich als Funktions-Argument

Die Standard Kalkulations-Funktionen =ANZAHL() und =SUMME() sind so bekannt, dass sie hier als Beispiel dienen. Man verwendet sie typisch mit einem Bereich als Argument, z.B. =SUMME(B1:C10)
Bereiche sind Objekte, die in LibreOffice-Basic und Visual Basic (VBA) unterschiedlich verwendet werden. Die beiden Versionen unterscheiden sich leider und werden deshalb getrennt vorgestellt.

Anzahl der Zellen

Die Funktion des Beispiels myCount() zählt die Anzahl der Zellen eines als Bereich erhaltenen Arguments, z.B.
=myCount(B1:C5)

LibreOffice-Basic erwartet den Bereich r als 2dimensionales → Array vom Typ Variant und verwendet die Basic-Funktion UBound(), um die Anzahl der Zeilen i und der Spalten j zu berechnen. Der Index der 1.Zelle LBound() ist immer =1

VBA erwartet den Bereich r als Objekt vom Typ Range und verwendet die Eigenschaft Count, um die Anzahl der Zellen zu lesen.
Anzahl der Zellen: LibreOffice-Variante
Function myCount(r As Variant) As Integer
Dim i,j As Integer
i = UBound(r,1)
j = UBound(r,2)
myCount = i * j
End Function

Anzahl der Zellen: VBA-Variante
Function myCount(r As Range) As Integer
Dim i As Integer
i = r.Count
myCount = i
End Function

Summe der Zellen

Die Funktion des Beispiels mySum() berechnet die Summe der Zellen eines als Bereich erhaltenen Arguments, z.B.
=mySum(B1:C5)
Damit wird der Lese-Zugriff auf die Zellen des Bereichs demonstriert. Der Schreib-Zugriff ist ist einer Function verboten und nur einem Sub erlaubt.

LibreOffice-Basic erwartet den Bereich r als 2dimensionales → Array vom Typ Variant
Die Anzahl der Zeilen und Spalten wird ebenso berechnet wie oben mit myCount() angegeben. Die Werte der Array-Elemente r(i,j) werden einfach an die Variable v zugewiesen und in s summiert.

VBA erwartet den Bereich r als Objekt vom Typ Range
Hier genügt eine einfache Schleife, um alle Zellen des Bereichs zu durchlaufen. Die Werte der Bereichs-Zellen werden mit Eigenschaft Value gelesen, an die Variable v zugewiesen und in s summiert.

In beiden Basic-Varianten werden die Zellen eines Bereichs zeilenweise verarbeitet, d.h. die 1.Zeile von links nach rechts, danach die 2. Zeile usw.

In beiden Basic-Varianten wird die 1. Zelle eines Bereichs mit dem Index 1 bezeichnet, nicht wie in allen anderen Programmiersprachen mit 0
Summe der Werte: LibreOffice-Variante
Function mySum(r As Variant) As Double
Dim i,j as Integer
Dim s,v As Double
s=0
For i = 1 To UBound(r,1)
For j = 1 To UBound(r,2)
v = r(i,j)
s = s + v
Next j
Next i
MySum = s
End Function

Summe der Werte: VBA-Variante
Function mySum(r As Range) As Double
Dim i As Integer
Dim v, s As Double
s = 0
For i = 1 To r.Count
v = r(i).Value
s = s + v
Next
mySum = s
End Function

Rückgabe mehrerer Werte durch Funktionen

In manchen Fällen ist es notwendig, mehrere Werte an das aufrufende Programm zurückzugeben. Das ist in Basic nicht vorgesehen.

Ein Beispiel dafür ist die Berechnung der 2dimensionalen Koordinaten eines Punktes mit einem Algorithmus, der beide Koordinaten X und Y liefert.

In den Beispielen wird das Ergebnis zur Vereinfachung nicht wirklich berechnet, sondern nur der Punkt (123,234) simuliert.
Dazu gibt es mehrere Möglichkeiten:
Variante 1: Sie erstellen getrennte Funktionen. Jede davon berechnet die komplette Lösung, gibt aber nur eines der Ergebnisse zurück. Langsam, aber sicher.

Variante 2: Sie rechnen nur einmal und speichern die Ergebnisse in globalen Variablen. Mehrere Rückgabe-Functions geben je eines der Ergebnisse zurück. Schnell, aber riskant.

Variante 3: Sie geben mehrere Ergebnisse als String zurück und zerlegen diesen anschließend in seine Bestandteile. Ziemlich schnell, sehr sicher.
Lösungs-Variante 1:
Sie erstellen eigene Funktionen für jedes Rückgabe-Datum. Jede davon berechnet die komplette Lösung, gibt aber nur eines der beiden Ergebnisse zurück.

Anwendung: In je eine Zelle werden die Formeln =calc_x() bzw. =calc_y() eingetragen.

Vorteil: einfache und saubere Lösung.

Nachteil: Der gesamte Algorithmus wird mehrfach berechnet, je einmal für jedes einzelne Ergebnis.

Verwenden sie diese Variante bei kurzen und schnellen Algorithmen, und wenn nur wenige Daten zurückzugeben sind. Hier macht es wenig aus, mehrfach zu rechnen.
Dim x, y As Double ' Global !
Function calc_x()
calc_xy()
calc_x = x
End Function

Function calc_y()
calc_xy(bereich)
calc_y = y
End Function

Private Function calc_xy()
' Modell-Algorithmus
x = 123
y = 234
End Function
Lösungs-Variante 2:
Der Algorithmus wird nur einmal ausgeführt und speichert seine Ergebnisse in globalen Variablen. Anschließend (!) werden die einzelnen Ergebnis-Daten durch eigene Rückgabe-Functions zurückgegeben.

Die Function calc_xy() wird (wie jede andere) neu berechnet,wenn sich ihre Argumente geändert haben. Das wird hier mit dem Argument t (Trigger) simuliert. Je nach Basic-Version genügt es nicht, dass ein Trigger-Argument angegeben wird, man muss es manchmal auch verwenden - hier mit der ansonsten wirkungslosen Anweisung t=t+1

Function calc_xy() gibt einen Zufalls-Wert zurück, der als Trigger (Auslöser) für die Berechnung der beiden anderen Functions verwendet wird. Damit wird sichergestellt, dass die Rückgabe-Funktionen erst nach der fertigen 'Berechnung' aufgerufen werden.

Die beiden Rückgabe-Functions übertragen lediglich je ein Ergebnis der Berechnung von den globalen Daten an die Kalkulation. Sie werden daher sehr schnell ausgeführt.

Anwendung
Formel in Zelle E1: =calc_xy(987)
(Ignorieren sie den in E1 berechneten Wert)
Formel in Zelle E2: =return_x(E1)
Formel in Zelle E2: =return_x(E1)
Die Berechnung wird nach jeder Änderung der Argumente von calx_xy() neu durchgeführt.

Vorteil: Schnellstes Verfahren.
Nachteil: Die Reihenfolge der Berechnung muss unbedingt sichergestellt werden.

Verwenden sie diese Variante bei längeren Berechnungen - Diese werden dann nur einmal ausgeführt. Die richtige Anwendung (Ergebnis von calc_xy() als Trigger für die Rückgabe) muss unbedingt befolgt werden, ansonsten liefert die Methode evtl. falsche Werte !
Dim x, y As Double

Function calc_xy(t)
' Modell-Algorithmus
t = t + 1
x = 123
y = 234
calc_xy = Rnd
End Function

Function return_x(t)
t = t + 1 ' Trigger
return_x = x
End Function

Function return_y(t)
t = t + 1 ' Trigger
return_y = y
End Function

Schnell aber riskant !
Wenn sie einen Trigger (t) nicht innerhalb der Function (beliebig) verwenden, dann wird diese Function auch bei Änderung des Triggers nicht neu berechnet !

Die Methode funktioniert nur dann, wenn man die Bedingungen der Anwendung einhält. Sie ist daher nur für eigene Kalkulationen geeignet, nicht zur Weitergabe.
Lösungs-Variante 3:
Der Algorithmus wird nur einmal ausgeführt, gibt jedoch mehrere Daten als String zurück, getrennt durch ein vereinbartes Trennzeichen (hier ; Strichpunkt).

Vorteil: Ziemlich schnell, sehr sicher.
Nachteil: Sie benötigen eine zusätzliche Funktion zur Aufspaltung des Rückgabe-Strings.

Verwenden sie diese Variante, wenn der Algorithmus lang und zeitraubend ist, oder wenn er mehr als 2 Daten zurückgeben soll.

Rechts ein Beispiel der Decodier-Function extract()
Verwenden sie eine Kalkulations-Zelle für das String-Ergebnis von calc_xy(), je eine weitere für jede im String enthaltene Variable, z.B.
A1 =calc_xy()
A2 =extract(A1;0)
A3 =extract(A1;1)
Option Base 0

Function calc_xy() As String
' Modell-Algorithmus
x = 123
y = 234
calc_peak = x & ";" & y
End Function

Function extract(strg, n) As Double
Dim sa() As String
sa = Split(text, ";")
Select Case index
Case Is < 0
Err.Raise 13
Case Is <= UBound(sa)
extract = sa(index - 1)
Case Else
Err.Raise 13
End Select
End Function
Wenn die Extraktion einer Variablen aus dem String scheitert, dann gibt die Funktion den Fehler #WERT zurück.

Wenn sie mehrere Variable ausschließlich innerhalb Basic übergeben wollen, dann eigen sich dazu am besten Arrays.
Details im Kapitel Basic-Arrays.
Kalkulations-Programme kennen keine Arrays, dafür jedoch Bereiche (Range). Aus unbekannten Gründen dürfen Basic-Functions keine Daten in Bereiche eintragen. Dafür kann man Basic- → Subs ('Unterprogramme') verwenden, denen dieses Recht erlaubt ist.

Hilfe

Informationen, genaue Definitionen und Beispiele finden sie u.a in der integrierten Hilfe: Klicken sie in VBA das -Symbol.
Hilfe finden sie u.a. zu folgenden Stichworten:
function, optional, byval, byref, ...
Online-Hilfe finden sie u.a. bei Microsoft