Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
972to976
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
972to976
972to976
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Formel in Funktion umwandeln

Formel in Funktion umwandeln
01.05.2008 18:51:24
Peter
Guten Abend
Ich versuche eine etwas komplizierte Formel in eine Funktion umzuwandeln.
Formel in Zelle F2 =(SUMMENPRODUKT((Ref=G2)*((LINKS(_C)="C")*(_A0))*_A)+SUMMENPRODUKT((RefW=G2)*((LINKS(_C)="D")*(_A0))*_A))
Formel in Zelle F3 =pspos(G3;_A) 'selbstgebastelte Funktion
Option Explicit

Public Function psPos(Zelle As Range, Periode As String) As Double
psPos = Evaluate("=(SUMPRODUCT((Ref=" & Zelle & _
")*((LEFT(_C)=""C"")*(Periode0))*Periode)+SUMPRODUCT((RefW=" & Zelle & _
")*((LEFT(_C)=""D"")*(Periode0))*Periode) _
_
)")
End Function


Da in G2 und in G3 der gleiche String steht, sollte das Ergebnis in F2 und F3 gleichviel geben. F3 ergibt jedoch #WERT. Wahrscheinlich liegt es (auch) am ersten Argument, denn gefragt ist ja der Inhalt der Zelle und ich weiss nicht, wie ich den übergeben muss. Wer kann mir helfen? Ich habe die Beispielmappe hochgeladen.
Danke und Gruss, Peter
https://www.herber.de/bbs/user/52014.xls

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Formel in Funktion umwandeln
01.05.2008 19:13:00
Beate
Hallo Peter,
du könntest die Formel auch als Namen definieren:
 FG
244444C.1
344444C.1

Formeln der Tabelle
ZelleFormel
F2=Test
F3=Test
Namen in Formeln
ZelleNameBezieht sich auf
F2_A=QA!$K$2:$K$7
F2_C=QA!$F$2:$F$7
F2Ref=QA!$C$2:$C$7
F2RefW=QA!$D$2:$D$7
F2Test=SUMMENPRODUKT((Ref=Jahresrechnung!G2)*((LINKS(_C)="C")*(_A<0)+(LINKS(_C)="D")*(_A>0))*_A)+SUMMENPRODUKT((RefW=Jahresrechnung!G2)*((LINKS(_C)="D")*(_A<0)+(LINKS(_C)="C")*(_A>0))*_A)
F3_A=QA!$K$2:$K$7
F3_C=QA!$F$2:$F$7
F3Ref=QA!$C$2:$C$7
F3RefW=QA!$D$2:$D$7
F3Test=SUMMENPRODUKT((Ref=Jahresrechnung!G3)*((LINKS(_C)="C")*(_A<0)+(LINKS(_C)="D")*(_A>0))*_A)+SUMMENPRODUKT((RefW=Jahresrechnung!G3)*((LINKS(_C)="D")*(_A<0)+(LINKS(_C)="C")*(_A>0))*_A)
Namen verstehen

Also den definierten Namen Test nur einmal erfassen. Da die Formel relativ ist, passt sie die Bereiche dann an.
Gruß,
Beate

Anzeige
AW: Formel in Funktion umwandeln
01.05.2008 19:40:00
Peter
Hallo Beate
Danke, das ist ein interessanter Aspekt. Im konkreten Fall habe ich 50 - 100 Formeln, die ich gerne etwas einfacher haben möchte. Deshalb wäre ich sehr interessiert, dass ich diese Funktion bauen kann. Wer kann mir helfen?
Danke, Peter

Ich würde Beate's Vorschlag aufgreifen,...
02.05.2008 01:31:32
Luc:-?
...Peter!
Es ist nämlich fraglich, ob du das mit Evaluate hinbekommst. Allerdings könnte es dabei ein Problem geben, falls die Formel, der hier auch immer sämtliche Blattbezüge hinzugefügt wdn (bei Fernbezügen mit vollem Pfad!), länger als 256 Zeichen wird (dann, wenn möglich, in Teilformeln aufteilen!). Andererseits könnte es sein, dass das mit WorksheetFunction erst recht nicht fkt.
Vorausgesetzt, Evaluate geht mit den Bereichsnamen richtig um, könntest du es aber auch mal mit Zelle.Address statt nur Zelle versuchen oder du übergibst Arg1 deiner udF gleich als Text (Adresse)... ;-)
Außerdem handelt es sich ja bei Periode auch um ein FktArg. Also musst du das auch so behandeln wie bei dir Zelle; d.h., der FmlText endet vor Arg2 mit " &  und beginnt danach wieder mit  & ".
Ansonsten sollte auch kein Zeilentrennzeichen innerhalb von Text auftreten, aber das war viell die Forumssoftware!
Gruß Luc :-?

Anzeige
AW: Ich würde Beate's Vorschlag aufgreifen,...
02.05.2008 09:37:00
Peter
Hallo Luc
Vielen Dank für die Rückmeldung. Das wegen der 256 Zeichen ist ein wichtiger Hinweis. Habe vor einiger Zeit schon einmal eine Formel, die ich mit Evaluate berechnet habe, aufteilen.
Ohne Evaluate läuft ja im VBA nichts, den WorksheetFunction.Sumproduct kann nur sehr einfach gestrickte Argumente verarbeiten.
Vorerst noch ein technisches Problem: Wie kann ich beim Entwickeln einer solchen Funktion überprüfen, was im VBA effektiv landet - manchmal kann man ja mit der Maus auf eine Bezeichnung fahren und dann wird der Wert angezeigt, klappt aber hier nicht.
Gruss, Peter

Anzeige
Function aus Sub basteln....
02.05.2008 10:46:28
Renee
Hallo Peter,
.... und warum nimmst du nicht den Ansatz der Subroutine (siehe: https://www.herber.de/forum/archiv/972to976/t973014.htm ) und baust sie zu einer Funktion um?
z.B. so:

Public Function psPos(RefZelle As Range, _
Optional Periode As String = "_A", _
Optional Positiv As Boolean = True) As Variant
Application.Volatile
Dim sFormula As String
sFormula = "=" & IIf(Positiv, "", "-") & _
"(SUMPRODUCT((Ref=""" & RefZelle & _
""")*((LEFT(_C)=""C"")*(" & Periode & "0))*" & Periode & ")+SUMPRODUCT((RefW=""" & RefZelle & _
""")*((LEFT(_C)=""D"")*(" & Periode & "0))*" & Periode & "))"
If Len(sFormula) > 256 Then
psPos = "Error:Formel zu lang"
Else
psPos = Evaluate(sFormula)
End If
End Function


GreetZ Renée

Anzeige
AW: Function aus Sub, verbessert
02.05.2008 11:21:00
Renee
Hi nochmals,
Irgendwie hat es mich gestört, dass beim ersten Parameter nur ein Zellbezug funktioniert.
So läufts mit einem Zellbezug oder mit einem direkten Stringwert wie "C.1":

Public Function psPos(RefZelle As Variant, _
Optional Periode As String = "_A", _
Optional Positiv As Boolean = True) As Variant
Application.Volatile
Dim sFormula As String, sReference As String
If TypeName(RefZelle) = "String" Then
sReference = """" & RefZelle & """"
Else
sReference = RefZelle.Address(0, 0)
End If
sFormula = "=" & IIf(Positiv, "", "-") & _
"(SUMPRODUCT((Ref=" & sReference & _
")*((LEFT(_C)=""C"")*(" & Periode & "0))*" & Periode & ")+SUMPRODUCT((RefW=" & sReference & _
")*((LEFT(_C)=""D"")*(" & Periode & "0))*" & Periode & "))"
If Len(sFormula) > 256 Then
psPos = "Error:Formel zu lang"
Else
psPos = Evaluate(sFormula)
End If
End Function


GreetZ Renée

Anzeige
AW: Function aus Sub, verbessert
02.05.2008 14:56:19
Peter
Hallo Renée
Vielen, vielen Dank. Ich habe das ausgetestet und das funktioniert prima. Ich habe zwar eine Menge Zellen, wo nun diese UDF drin steht, doch die Berechnung ist extrem schnell.
Ein Vorkommnis gibt mir noch gewisse Rätsel auf:
Wenn ich die Tabelle, wo diese UDFs nun drin stehen, verlasse und irgend einen Eintrag in eine andere Tabelle der gleichen Arbeitsmappe mache, steht bei der Rückkehr in die Tabelle mit den UDFs in allen entsprechenden Zellen eine NULL. Nach Drücken von F9 ist alles wieder i.O.
Habe mir überlegt, wie ich dieses Problem lösen könnte, beispielsweise:
wenn ich die Tabelle verlasse die Calculation nur dieser Tabelle auf manuell (geht das?)
wenn ich sie wieder einschalte wieder auf automatische Berechnung stellen.
Danke für eine Rückmeldung.
Peter

Anzeige
AW: Calculate bei UDF
02.05.2008 15:36:00
Renee
Hi Peter,
Das kann ich leider nicht verhindern.
Da sich deine (benannten)-Referenzen auf ein anderes Blatt beziehen, passiert dies.
Ich habe zwar die UDF als flüchtig deklariert ( Application.Volatile ), d.h. sie wird immer neu gerechnet, wenn auf demselben Blatt (in dem sie steht) eine Änderung stattfindet. Das ist also technisch bedingt. Was helfen würde wäre im Blatt in der die Funktion gebraucht wird ein:

Private Sub Worksheet_Activate()
Application.Calculate
End Sub


GreetZ Renée

AW: Calculate bei UDF
02.05.2008 16:53:00
Peter
Hallo Renée
Das mit Application.Calculate habe ich ausprobiert und es hat auch funktioniert. Wenn ich dann allerdings die ganze Arbeitsmappe drucken wollte, waren die Zahlen nicht drin. Deshalb habe ich nun untenstehenden Code in das Worksheet mit den UDFs reingeschrieben und nun sind die Zellen immer aktuell.
Nochmals vielen Dank für die Unterstützung.
Gruss, Peter

Private Sub Worksheet_Activate()
Dim oWB As Workbook
Dim oWS As Worksheet
Set oWB = ThisWorkbook
Set oWS = oWB.Worksheets(Me.Name)
'Berechnung einschalten
oWS.EnableCalculation = True
End Sub



Private Sub worksheet_Deactivate()
Dim oWB As Workbook
Dim oWS As Worksheet
Set oWB = ThisWorkbook
Set oWS = oWB.Worksheets(Me.Name)
' Berechnung ausschalten
oWS.EnableCalculation = False
End Sub


Anzeige
AW: Ich würde Beate's Vorschlag aufgreifen,...
02.05.2008 11:27:00
fcs
Guten Morgen Peter,
ich würde Berechnungen in einem Tabellenblatt, die man mit den Standardfunktionen von Excel durchführen kann, niemals als benutzerdefinierte Funktion ins VBA auslagern. Es leidet immer die Rechengeschwindigkeit. Berechnungen in den Tabellenblättern werden evtl. schwieriger nachvollziehbar.
Das kommt bei mir erst zum Tragen, wenn zu viele Hilfs- und Nebenberechnungen erforderlich werden, die dann in einer benutzerdefinierten Funktion ggf. übersichtlicher dargestellt und gepflegt werden können.
Bei benutzerdefinierten Funktionen, die in Tabellenblättern verwendet werden, übergebe ich praktisch immer alle Parameter (Zellen, Zelbereiche, Werte) an die Funktion. Sonst muss für eine korrekte Akualisierung der Berechnungen mit "Application.Volatile" gearbeitet werden, was bei komplexen Berechnungen extrem auf die "Performance" durchschlägt.
Anzeige von Werten im VBA-Schrittmodus
Falls während der schrittweisen Abarbeitung von Prozeduren die Werte einzelner Funktionen oder Parameter nicht bei "Mauskontakt" angezeigt werden, dann solltest du zum Testen die Überwachung von Ausdrücken entsprechend einrichten.
Wenn du deine Berechnung in eine VBA-Function umsrtzen willst, dann koplett, wobei dann die SUMMENPRODUKT-Funktion ggf. durch entsprechende For-Next-Schleifen ersetzt werden muss.
Gruß
Franz

Formel in Tabellel:
=fncPsPos(Ref;G2;_C;"C";"D";_A;RefW)
'Userdefined Function:
Public Function fncPsPos(Ref As Range, Ref_Wert As String, _
C_Bereich As Range, C_Wert1 As String, C_Wert2 As String, _
A_Bereich As Range, RefW As Range) As Double
Dim lngZ As Long
'=SUMMENPRODUKT((Ref=G2)*((LINKS(_C)="C")*(_A0))*_A) _
+SUMMENPRODUKT((RefW=G2)*((LINKS(_C)="D")*(_A0))*_A)
'Ref auswerten
For lngZ = 1 To Ref.Rows.Count
If Ref(lngZ, 1) = Ref_Wert _
And _
((Left(C_Bereich(lngZ, 1), Len(C_Wert1)) = C_Wert1 And A_Bereich(lngZ, 1)  0)) Then
fncBerechnung = fncBerechnung + A_Bereich(lngZ, 1)
End If
Next
'RefW auswerten
For lngZ = 1 To RefW.Rows.Count
If RefW(lngZ, 1) = Ref_Wert _
And _
((Left(C_Bereich(lngZ, 1), Len(C_Wert2)) = C_Wert2 And A_Bereich(lngZ, 1)  0)) Then
fncBerechnung = fncBerechnung + A_Bereich(lngZ, 1)
End If
Next
End Function


Anzeige
Die 256 Zeichen (inkl =) beziehen sich hier...
02.05.2008 19:14:00
Luc:-?
...aber nur auf benannte Formeln, Peter!
In VBA gibt's allerdings die gleiche Grenze, wenn du einer udF einen Ausdruck als Argument übergibst...
Bsp: =myUDF(Bezug;...) für Arg1 als Variant
Beziehst du dich in Arg1 auf eine Zelle, die bspw einen Text enthält, kann der ruhig die xlblatt-übliche Länge haben. Schreibst du da eine Formel rein, die erst einen Text erzeugt, ist der auf 255|6 Zeichen beschränkt. Das erlebe ich stets, wenn ich meine udF TinLines (teilt einen Text in Zeilen auf) in Kombination mit meiner udF CForm benutze und CForm (liefert die Formel einer Zelle) einen FmlText zurückgibt, der mehr als 255 Zeichen hat. Schreibe ich CForm in eine eigene Zelle und beziehe mich mit TinLines auf diese, kann der FmlText die xlübliche Maximallänge haben.
Das kann man m.E. nicht ändern, weil es wohl zu den xlBasics gehört, aber mit List und Tücke umgehen (was ich bei diesem Bsp noch nicht, aber an anderer Stelle durchaus gemacht habe).
Vielleicht liegt's aber auch am Typ Variant und mit String würde es gehen? Habe ich jetzt nicht ggwärtig...
Gruß Luc :-?
Anzeige

300 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige