optionale Argumente in einer Function

Bild

Betrifft: optionale Argumente in einer Function
von: Frank
Geschrieben am: 29.10.2015 10:01:20

Hallo Zusammen,
ich habe mir eine Funktion geschrieben mit der ich den Flächeninhalt eines Polygonzuges berechnen kann. Das funktioniert soweit ganz gut. Nun kann es u.U. sein, dass die Fläche Aussparungen enthält. Dafür habe ich optionale Argumente definiert. Da ich damit das erste Mal zu tun habe weiß ich nicht ob ich das richtig gemacht habe. Jedenfalls ist es so, wenn ich diese optionalen Argumente frei lasse, dann ergibt die Funktion #Wert. Kann mir jemand sagen wie ich das umgehe bzw. was in meinem Quellcode falsch ist? Das würde mir weiter helfen.
Leider kann ich die Datei nicht anfügen obwohl sich diese auf C:\ befindet und lediglich 19kB groß ist. Von daher der Quellcode:

Function A_Gauß(yc, zc, Optional ya As Variant = 0, Optional za As Variant = 0) As Double
'Function berechnet den Flächeninhalt eines nicht überschlagenen, geschlossenen, auch unregelmäß _
igen Polygons mit N Polygonpunkten
Dim Anzyc, Anzzc    'Anzahl der y- und z-Werte der Polygonpunkte
Dim Anzya, Anzza    'Anzahl der y- und z-Werte der Aussparungspolygonpunkte
Dim ycVek, zcVek    'ycVek = y-Flächenvektor, zcVek = z-Flächenvektor
Dim yaVek, zaVek    'yaVek = y-Aussparungsvektor, zyVek = z-Aussparungsvektor
Dim i As Integer, nc As Integer, na As Integer
Dim Aa As Double    'Fläche Aussparung
Dim Ac As Double    'Fläche
Anzyc = yc.Count    'Anzahl y-Polygonpunkte aus Array bestimmen
Anzzc = zc.Count    'Anzahl z-Polygonpunkte aus Array bestimmen
ycVek = yc          'übergib die Polygonpunkte zum Vektor ycVek
zcVek = zc          'übergib die Polygonpunkte zum Vektor zcVek
Anzya = ya.Count    'Anzahl y-Aussparungspolygonpunkte aus Array bestimmen
Anzza = za.Count    'Anzahl z-Aussparungspolygonpunkte aus Array bestimmen
yaVek = ya          'übergib die Aussparungspolygonpunkte zum Vektor yaVek
zaVek = za          'übergib die Aussparungspolygonpunkte zum Vektor zaVek
If Anzyc <> Anzzc Or Anzya <> Anzza Then  'Prüfe, ob die Anzahl der y-Polygonpunkte = der  _
Anzahl der z-Polygonpunkte ist
    Exit Function   'ansonsten beende die Function
End If
nc = 1
na = 1
'variable Länge der Polygonpunkte, die letzten Zellen können leer sein
'durch die Loop Anweisung wird die letzte nicht leere Zelle gesucht und nc zugewiesen
Do Until IsEmpty(ycVek(nc, 1)) = True
    If nc = Anzyc Then    'wenn der nc-Zähler die maximale Anzahl der y-Daten erreicht hat,  _
dann verlasse die Do Until-Anweisung
        Exit Do
    Else
        nc = nc + 1
    End If
Loop
i = 1       'beginne die Gaußsche-Flächenformel auszuwerten ab dem i-ten Polygonpunkt
nc = nc - 1   'lass die Gaußsche Flächenformel auswerten bis zum n-ten Polygonpunkt
For i = i To nc
    Ac = ycVek(i, 1) * zcVek(i + 1, 1) - ycVek(i + 1, 1) * zcVek(i, 1)  'Berechnung der  _
Betonteilflächen
    Aa = -1 * (yaVek(i, 1) * zaVek(i + 1, 1) - yaVek(i + 1, 1) * zaVek(i, 1)) 'Berechnung der  _
Aussparungsteilflächen
    A_Gauß = A_Gauß + Ac + Aa   'Summation der Teilflächen
Next
A_Gauß = A_Gauß / 2     'nach der Gaußschen-Flächenformel wird der A(i)-ten Flächeninhalt durch  _
2 geteilt oder eben die Summe aller A(i)'s anschließend durch 2 geteilt
End Function

Vielen Dank und viele Grüße
Frank

Bild

Betrifft: AW: optionale Argumente in einer Function
von: Daniel
Geschrieben am: 29.10.2015 10:50:28
Hi
wenn du die Parameter ya und za weglässt, bekommen diese den Wert 0 und damit einen Einzelwert.
diesen übergibst du dann an yaVek und zaVek.
diese Verwendest du im Code aber als zweidimensionale Arrays, was zu einem Fehler führt, wenn sie eigentlich Einzelwerte sind.
dh du müsstest erstmal abfragen, ob Werte für ya und za eingegeben wurden.
da du ein Variant-Array hast, welches verschiedene Datentypen (Einzelwert Text, Einzelwert Zahl, Range-Objekt, Array) annehmen kann, müsstst du mit VARTYPE(za) erstmal ermitteln, was du überhaupt bekommen hast.
also im Prinzip etwa so:

if VarType(za) >=8192 and Vartype(ya) >= 8192 Then
    For i = i To nc
        Ac = ycVek(i, 1) * zcVek(i + 1, 1) - ycVek(i + 1, 1) * zcVek(i, 1)  
        Aa = -1 * (yaVek(i, 1) * zaVek(i + 1, 1) - yaVek(i + 1, 1) * zaVek(i, 1))
        A_Gauß = A_Gauß + Ac + Aa   'Summation der Teilflächen
    Next
else
    For i = i To nc
        Ac = ycVek(i, 1) * zcVek(i + 1, 1) - ycVek(i + 1, 1) * zcVek(i, 1)  
        A_Gauß = A_Gauß + Ac + Aa   'Summation der Teilflächen
    Next
end if

oder du lässt bei den Optionalen Parametern die Alternativwertzuweisung weg (das =0)
dann kannst du mit der Funktion IsMissing(za) überprüfen, ob der Optionale Wert übergeben wurde oder nicht und im Code entsprechend reagieren.
Gruß Daniel

Bild

Betrifft: AW: optionale Argumente in einer Function
von: Daniel
Geschrieben am: 29.10.2015 10:51:01
Hi
wenn du die Parameter ya und za weglässt, bekommen diese den Wert 0 und damit einen Einzelwert.
diesen übergibst du dann an yaVek und zaVek.
diese Verwendest du im Code aber als zweidimensionale Arrays, was zu einem Fehler führt, wenn sie eigentlich Einzelwerte sind.
dh du müsstest erstmal abfragen, ob Werte für ya und za eingegeben wurden.
da du ein Variant-Array hast, welches verschiedene Datentypen (Einzelwert Text, Einzelwert Zahl, Range-Objekt, Array) annehmen kann, müsstst du mit VARTYPE(za) erstmal ermitteln, was du überhaupt bekommen hast.
also im Prinzip etwa so:

if VarType(za) >=8192 and Vartype(ya) >= 8192 Then
    For i = i To nc
        Ac = ycVek(i, 1) * zcVek(i + 1, 1) - ycVek(i + 1, 1) * zcVek(i, 1)  
        Aa = -1 * (yaVek(i, 1) * zaVek(i + 1, 1) - yaVek(i + 1, 1) * zaVek(i, 1))
        A_Gauß = A_Gauß + Ac + Aa   
    Next
else
    For i = i To nc
        Ac = ycVek(i, 1) * zcVek(i + 1, 1) - ycVek(i + 1, 1) * zcVek(i, 1)  
        A_Gauß = A_Gauß + Ac    
    Next
end if

oder du lässt bei den Optionalen Parametern die Alternativwertzuweisung weg (das =0)
dann kannst du mit der Funktion IsMissing(za) überprüfen, ob der Optionale Wert übergeben wurde oder nicht und im Code entsprechend reagieren.
Gruß Daniel

Bild

Betrifft: AW: optionale Argumente in einer Function
von: Frank
Geschrieben am: 29.10.2015 11:40:33
Hallo Daniel,
vielen Dank für deine ausführliche Antwort, welche sehr hilfreich für mich war.
Danke ich werde meinen Code entsprechend verändern.
Vielen Dank und viele Grüße
Frank

Bild

Betrifft: AW: optionale Argumente in einer Function
von: Rudi Maintaire
Geschrieben am: 29.10.2015 11:13:05
Hallo,
du brauchst keine optionalen Argumente. Du musst die Punkte der Aussparungen nur in der umgekehrten Richtung angeben. Ganze Fläche links herum, Aussparungen rechts herum. Dabei immer letzter Punkt = erster Punkt (ein Rechteck hat 5 Punkte).
Für eine Fläche 5x5 mit einer Aussparung 2x2 in der Mitte sieht das so aus:

ABCDE
1xy  Fläche
200anfang Fläche 21
350   
455   
505   
600ende Fläche  
71,51,5anfang Aussparung  
81,53,5   
93,53,5   
103,51,5   
111,51,5ende Aussparung  

ZelleFormel
E2=flaeche(A2:B11)

Code:
Function flaeche(r As Range)
  Dim a, i
  a = r.Value
  For i = 1 To UBound(a) - 1
    flaeche = flaeche + (a(i, 1) * a(i + 1, 2) - a(i + 1, 1) * a(i, 2))
  Next
  flaeche = flaeche / 2
End Function
Gruß
Rudi

Bild

Betrifft: AW: optionale Argumente in einer Function
von: Frank
Geschrieben am: 29.10.2015 11:42:44
Hallo Rudi,
vielen Dank auch an dich, auch deine Antwort hat mir sehr geholfen und eine andere Herangehensweise gezeigt. Das man den Drehsinn beachten muss war mir bekannt. Ich wollte die Wertepaare in meiner Funktion aber unbedingt einzeln haben. Dennoch ist deine Lösung wie immer sehr elegant. Vielen Dank an dieser Stelle.
Vielen Dank und viele Grüße
Frank

Bild

Betrifft: AW: optionale Argumente in einer Function
von: Rudi Maintaire
Geschrieben am: 29.10.2015 12:10:49
Hallo,
Ich wollte die Wertepaare in meiner Funktion aber unbedingt einzeln haben.
kein Problem.

Function flaeche(y, z)
  Dim i As Long
  If y.Count = z.Count Then
    For i = 1 To UBound(y.Value) - 1
      flaeche = flaeche + (y(i, 1) * z(i + 1, 1) - y(i + 1, 1) * z(i, 1))
    Next
    flaeche = flaeche / 2
  Else
    flaeche = "#FEHLER!!!#"
  End If
End Function
Gruß
Rudi

Bild

Betrifft: Nachtrag...
von: Frank
Geschrieben am: 29.10.2015 11:44:56
Was mal ein schönes Feature in einer zukünftigen Excel Version wäre, ist das man genau wie bspw. einer WENN Funktion einen entsprechenden Hilfetext bei einer UDF angezeigt bekäme... Ich habe UDF wo ich zum Teil 10 Paramter übergebe und ich dann immer erstmal im Quellcode nachsehe in welcher Reihenfolge...

Bild

Betrifft: AW: Nachtrag...
von: Daniel
Geschrieben am: 29.10.2015 12:03:59
Hi
du kannst für deine UDFs über den Befehl Application.MacroOptions einen Hilfetext erstellen und du kannst für die Funktionsparameter möglichst sprechende Variablennamen verwenden.
beides wird aber nur sichtbar, wenn du die Funktion über den Funktionsassistenten eingibst (Formel - Funktion einfügen)
Gruß Daniel

Bild

Betrifft: In deiner XlVersion sollten auch die Argumente ...
von: Luc:-?
Geschrieben am: 29.10.2015 14:48:34
…mit VBA direkt beschreibbar sein, Frank;
in früheren war das nur per Umweg machbar.
Gruß, Luc :-?

Besser informiert mit …

Bild

Betrifft: wozu eigentlich UDF?
von: Rudi Maintaire
Geschrieben am: 29.10.2015 12:52:50
Hallo,
Punkte in A2:B11:
=(SUMMENPRODUKT(A2:A10;B3:B11)-SUMMENPRODUKT(A3:A11;B2:B10))/2
Gruß
Rudi

 Bild

Beiträge aus den Excel-Beispielen zum Thema "Bedingung einfügen"