Gleichung in VBA (Excel) nach einer vorher definierten Variablen automatisch umstellen

Hallo,

für mein Studium muss ich ein Projekt machen und habe diesbezüglich ein Problem und hoffe daher um Ihre Mithife.

Das Problem ist folgendes: Ich muss verschiedene Formeln in Excel programmieren, die automatisch nach einer Variablen umgestellt werden. Also, ich habe bspw. die Formel: x=y+z. In die Zelle „A1“ kann der Wert für „x“ eingegeben werden, in die Zelle „A2“ den für „y“ und in „A3“ den für „z“. Wenn man jetzt bspw. ein „?“ in „A2“ eingibt, so soll die Formel automatisch nach „y“ umgestellt und berechnet werden. Ich könnte zwar die Formeln per Hand umstellen, aber da es eine Unmenge von Formeln sind, ist dies nicht möglich.

Ich hofe ich habe es verständlich erklärt. Ist die Problemlösung mit VBA möglich?

Vielen Dank

Viele Grüße
Marcel

Hallo Marcel,

ich kann leider nicht helfen , sorry. Ich stehe glaube ich in der falschen Kategorie - Visual Basic heißt nicht automatisch VBA, sondern in erster Linie „Visual Basic.NET“. Das müsste ich noch einmal ändern.

Allzu schwierig kann es nicht sein, da ja man von VBA den Zellinhalt über die Cells-Property ansprechen kann und die Formel z.B. über FormulaLocale usw.

Kennst Du das Wikibook zu VBA?

http://de.wikibooks.org/wiki/VBA_in_Excel_-_Grundlagen

Probier es doch einmal selber - ich denke, es ist nicht so kompliziert. Ein anderer Experte müsste Dir fast das fertige VBA-Programm schicken, da es glaube ich nicht so viel ist.

Viel Erfolg und viele Grüße,
Peter

In VBA kann natürlich abgefragt werden, was in die Zellen eingegeben wurde und dann entsprechend verzweigt werden.

Die Problematik dürfte aber eher einen Mathematiker interessieren, der einen Algorithmus finden muss, der Formeln entsprechend der belegten Variablen in die fehlende Variable umstellt. Bei der Komplexität der mathematisch möglichen Formeln dürfte ein einziger Algorithmus nach meinem mathematischen Verständnis ohnehin nicht allgemeingültig sein. Wenn ja, winkt der Nobelpreis.

Hallo Peter,

Danke für die Hilfe. Mit so einer schnellen Antwort habe ich nicht gerechnet :smile:

Wikibook werde ich mir mal anschauen, schein eine hilfreiche Seite zu sein.

Mal schauen was sich so ergibt.

Viele Grüße
Marcel

Hey,

danke für die Info. Da werde ich wohl irgendeinen anderen Weg finden müssen.

Viele Grüße
Marcel

Hallo Marcel,

Also, ich habe bspw. die Formel: x=y+z.

Ich hofe ich habe es verständlich erklärt. Ist die
Problemlösung mit VBA möglich?

Ja, das ist verständlich.
Zunächst muß ich Dir mitteilen, daß ich von VBA keine Ahnung habe. Wieviel VBA kannst Du?

VBA ist ja wie VB6 prozedural aufgebaut.
Was Du brauchst, ist eine Funktion, die die Formel umstellt.

Der Aufruf der Funktion würde dann so aussehen:

Ergebnis = Umstellen(Formel, Zielvariable)

Helfen könnte ich nur bei der Funktion. Der rest bezieht sich auf Excel, darüber weiß ich nichts.

Nun habe ich auch noch Fregen zu Funktion, b.z.w. zu den Formeln, die umgestellt werden sollen.

Wech Rechenoperationen können denn da vorkommen? Fertig gibt es dafür nämlich nichts, das muss alles Schritt für Schritt selbst programmiert werden. Die Funktion muss nach den Rechenzeichen suchen und wissen, wie man damit umgeht. Was da nicht programmiert wird, versteht die Funktion nicht. Findet sie ein ihr unbekanntes Zeichen, wird das als Veriable interpretiert.

Je universeller die Funktion arbeiten soll, um so umfangreicher und komplizierter wird die Funktion.

Gruß Rainer

Hallo Rainer,

also ist es prinzipiell möglich? Wenn das klappen würde, das wäre echt Spitze und würde sich voll gut für mein Projekt machen. Viel VBA kann ich nicht, aber ich müsste es hinkriegen, dass das ganze mit Excel verknüpft werden soll.

Es kommen auf jedefall die vier Standardrechenoperationen vor (plus, minus, mal , durch). Es werden keine Wurzeln und Winkelfunktionen vorkommen. Das schlimmste was es noch gibt ist, Exponent mit Bruch und Summe und noch Logarithmus, aber auf das kann ich notfalls verzichten. Am wichtigsten ist, wenn das mit den vier Operationen funktionieren würde.

Wäre echt nett, wenn du mir dabei helfen könntest.

Viele Grüße
Marcel

Hallo Marcel,

also ist es prinzipiell möglich?

grundsätzlich: Ja. Das ist möglich. Es ist nur nicht ganz einfach. Weil alle mathematischen Regeln beachtet werden müssen.

Wenn das klappen würde, das
wäre echt Spitze und würde sich voll gut für mein Projekt
machen. Viel VBA kann ich nicht, aber ich müsste es
hinkriegen, dass das ganze mit Excel verknüpft werden soll.

Es kommen auf jedefall die vier Standardrechenoperationen vor
(plus, minus, mal , durch). Es werden keine Wurzeln und
Winkelfunktionen vorkommen. Das schlimmste was es noch gibt
ist, Exponent mit Bruch und Summe und noch Logarithmus, aber
auf das kann ich notfalls verzichten. Am wichtigsten ist, wenn
das mit den vier Operationen funktionieren würde.

Wäre echt nett, wenn du mir dabei helfen könntest.

Ich habe schon mal mit Plus und Minus angefangen, das ist am leichtesten, weil in dem Fall der Rest der Formel nicht analysiert werden muss. Aber fertig habe ich selbst das noch nicht. :smile:

Du kannst aber schon anfangen zu versuchen, die Funktion einzubauen, auch wenn noch nichts umgestellt wird.

Im Ersten Schritt werden erst mal nur vorhandenen Leerzeichen entfernt, damit die beim Umstellen der Formel nicht stören können. Wenn Du das einbaust, sollten Deine Formeln zunächst Leerzeichen enthalten, die von der Funktion entfernt werden.

Wenn das Funktioniert ist Dein Teil der Arbeit erledigt dann mausst Du später die Funktion nur durch eine neue Version ersetzen und die Umstellung wird funktionieren.

Die Funktion, die Du schon mal einbauen kannst:

Private Function Umstellen(ByVal Formel As String, ByVal Ziel As String) As String
Umstellen = Spacekill(Formel)
End Function

Private Function Spacekill(ByVal Formel As String) As String
Dim i As Integer
For i = 1 To Len(Formel)
If Mid(Formel, i, 1) " " Then
Spacekill = Spacekill + Mid(Formel, i, 1)
End If
Next
End Function

Aufgerufen wird die Funktion mit:

Ergebnis = Umstellen(Formel, Zielvariable)

wobei Du die Veraiblen Ergebnis, Formel und Zielvariable als String deklarieren musst. In der Variablen Formel muss Deine Formel stehen, in der Variablen Zielvariable muss Deine Zielvariable stehen, nach der umgestellt werden soll und vor der Zielvariablen in der Formel muß im ersten Schritt noch entweder ein Plus oder ein Minus stehen.

Diesen Teil bauen wir erst einmal, dann siehst Du die Funktion, wie das aufgabaut ist, wie man so etwas macht. Wenn das fertig ist, kannst Du mir sagen, ob Du Dir den Rest selbst zutraust, oder ob ich daran weiter arbeite.

OK?

Bau den rudimentären Anfang erst mal ein und erzähle, ob das geklappt hat. Ich schreibe die Funktion für Plus und Minus so lang fertig.

Wenn Du die Funktion nicht selbst einbinden kannst, dann frag bitte im VB-Brett bei wer-weiss-was. Reinhard wird Dir da ganz sicher helfen, der kann das in zwei Minuten. :smile:

Gruß Rainer

Hallo Marcel,

für Plus und Minus funktioniert es jetzt.
Das ist relativ einfach, weil man den Ausdruck vor und nach der gesuchten Variable einfach in Klammern einschließen kann und mit negativem Vorzeichen auf die andere Seite der Gleichung schreiben.

Für Multiplikation und Division muss die Formel noch weiter zerlegt und richtig verarbeitet werden.

Das Problem ist also grundsätzlich ein mathematisches, beim Programmieren nur mehr Denk- und Tipparbeit. Das Prinzip ist identisch.

Getestet habe ich mit der Formel:

Y = - 2 + 7*v + (x^2) + b * n + f

und lasse nach (x^2) umstellen.

Entscheidend ist, daß vor und nach dem Ausdruck, nach dem umgestellt werden soll, ein Plus oder Minus steht.
Der Ausdruck, nach dem Umgestellt werden soll, kann natürlich auch ein einzelnes Zeichen sein.

Der Code dazu:

Private Function Umstellen(ByVal Formel As String, ByVal Ziel As String) As String
Dim i As Integer, po As Integer, po2 As Integer, TR As String, TL As String
Dim RZ As String, TM As String, t1 As String, t2 As String
If InStr(Formel, Ziel) = 0 Then
Umstellen = „Zielvariable in Formel nicht enthalten“
Exit Function
End If
Formel = Spacekill(Formel)
Text1.Text = Formel
po = InStr(Formel, Ziel)
po2 = InStr(Formel, „=“)
t1 = Mid(Formel, po - 1, 1)
t2 = Mid(Formel, po + Len(Ziel), 1)
If t1 „+“ And t1 „-“ Or t2 „+“ And t2 „-“ Then
Umstellen = „Im Moment sind nur Plus und Minus direkt vor und nach der Veriablen, nach der ungestellt werden soll, erlaubt“
Exit Function
End If
If po + Len(Ziel) - 1 " " Then
Spacekill = Spacekill + Mid(Formel, i, 1)
End If
Next
End Function

Gruß Rainer

Guten Morgen Rainer,

wow, ich bin begeistert. Besten Dank für deine Mühe. Ich schaffe es irgendwie nicht in Excel einzubinden.

Kannst du mir bitte sagen, wie ich den Reinhard finden kann. Ich kann ihn irgendwie nicht ausfindig machen.

Nochmal besten Dank.

Gruß Marcel

Hallo Rainer,

ich habe es hinbekommen, dass die erste Funktion in Excel einbinden kann. Es hat super funktioniert und alle Leerzeichen wurden aus der Formel entfernt. Also machte ich es auf die gleiche Weise für die zweite Funktion, aber da geht es komischerweise nicht. Muss ich irgendetwas bestimmtes beachten?

Danke

Viele Grüße
Marcel

Hallo,

ich habe es hinbekommen, dass die erste Funktion in Excel
einbinden kann. Es hat super funktioniert und alle Leerzeichen
wurden aus der Formel entfernt.

OK.

Also machte ich es auf die
gleiche Weise für die zweite Funktion, aber da geht es
komischerweise nicht. Muss ich irgendetwas bestimmtes
beachten?

Die Funktion, die die Formel umstellt hat den selben Namen. Du musst die erste Version der funktion durch die zweite erstzen. Du darfst nicht zwei Funktionen mit dem selben namen im Projekt haben.

In deinem Projekt müssen also zwei Funktionen stehen:

1.) Umstellen

2.) Spacekill

Das ist in VB getestet, das muss funktionieren.

Wenn es wider erwarten Probleme gibt, dann schreibe mir bitte die Fehlermeldung. Ich habe keine Befehle verwendet, die Excel-VBA nicht kennt.

Gruß Rainer

Hallo Marcel,

ich habe noch etwas entdeckt, eine Zeile ist zuviel, die versucht in ein Steuerelement 'Text1.Text" die bereinigte Formel zu schreiben. Das Steuerelement gibt es bei dir nicht, deshalb läuft der Code nicht. Das ist aber auch überflüssig, war nur für mich, um zu sehen, was passiert. Deshalb noch einmal die Funktion ohne diese Zeile:

Private Function Umstellen(ByVal Formel As String, ByVal Ziel As String) As String
Dim i As Integer, po As Integer, po2 As Integer, TR As String, TL As String
Dim RZ As String, TM As String, t1 As String, t2 As String
If InStr(Formel, Ziel) = 0 Then
Umstellen = „Zielvariable in Formel nicht enthalten“
Exit Function
End If
Formel = Spacekill(Formel)
po = InStr(Formel, Ziel)
po2 = InStr(Formel, „=“)
t1 = Mid(Formel, po - 1, 1)
t2 = Mid(Formel, po + Len(Ziel), 1)
If t1 „+“ And t1 „-“ Or t2 „+“ And t2 „-“ Then
Umstellen = „Im Moment sind nur Plus und Minus direkt vor und nach der Veriablen, nach der ungestellt werden soll, erlaubt“
Exit Function
End If
If po + Len(Ziel) - 1

Hallo Rainer,

ich habe jetzt nur noch den letzten von dir geschickten Code in Excel eingebaut. Eine Fehlermeldung wird irgendwie nicht ausgespuckt, in der Zelle von Excel erscheint nur „#WERT!“.

Ich kann dir ja mal den genauen Hergang beschreiben, vielleicht hilft es dir ja.

Den Code habe ich in ein Modul von VBA Abgespeichert. In Excel habe ich dann in Zelle A1 die Formel geschrieben (y = x + z - a), in Zelle A2 die Variable, nach der umgestellt werden soll (z). In Zelle A3 habe ich den Funktionsaufruf, mit „=Umstellen(A1;A2)“ gestartet. Wenn ich jetzt in Zelle A2 irgendetwas hineinschreibe, was nicht in der Formel vorkommt (f), dann erscheint „Zielvariable in Formel nicht enthalten“. Das funktioniert. Wenn ich jetzt aber eine Variable hineinschreiben, die in der Formel auftaucht (a), dann erscheint „#WERT!“. Mit „Spacekill“ habe ich es auch versucht, da werden die Lücken der Formel richtig entfernt.

Hast du vielleicht eine Idee, an was das liegen kann?

Viele Grüße
Marcel

Hey Rainer,

dass ist absolut super, jetzt funktioniert es. Besten Dank dafür.

Kann man die Funktion noch irgendwie so erweitern, dass das Ganze noch mit Multiplikation und Division möglich wird? Das wäre die absolute Krönung.

Danke nochmal für den Code

Viele Grüße
Marcel

Hallo Marcel,

nach der jetzigen Beschreibung tauchen zu viele Fragen auf. Mir ist nicht klar, was warum nicht klappt.

Bau noch mal die erste Version, die nur die Leerzeichen entfernt hat, die hat ja funktioniert.

In dieser version gibt es die Funktion ‚Umstellen‘ ja schon und sie wird ausgeführt.

Dann Musst Du da die Funktion ‚Umstellen‘ durch die Version der Funktion ‚Umstellen‘ durch die letzte erstetzen, die ich geschickt habe. Sonst nichts ändern, alles ander bleibt, wie es ist.

Wenn es dann nicht geht, schick mir die beiden vollständigen Codes. Den, der funktioniert und den, der nicht funktioniert.

Jeweils komplett alles, was Du getippt hast.
Ich kann den teil, der sich auf Excel bezieht zwar nicht aus dem Kopf schreiben, aber lesen kann ich’s und sehe vermutlich, wo das Problem liegt.

Gruß Rainer

Ach ja, damit die Formatierung erhalten bleibt, schick mir den Code per Mail, nicht daß wir hier ein Problem durch diesen Editor bekommen, der die Formatierung zerlegt. Eventuell hat uns der Editor hier aus einer Zeile zwei gemacht und das Problem verursacht.

Meine Mailadresse:

[email protected]

Hallo Marcel,

Kann man die Funktion noch irgendwie so erweitern, dass das
Ganze noch mit Multiplikation und Division möglich wird? Das
wäre die absolute Krönung.

das geht, klar. :smile:

Das ist nur eine Unmenge arbeit! :smile:

dazu muss der Teil der Formel, in der die Zielvariable steht zunächst untersucht werden, ob Teile mit Plus oder Minus verknüpft sind und diese zunächst auf die andere Seite gebracht werden.
Steht die Variable in einer Klammer, muss zunächst die Klammer aufgelöst werden.

Wenn das erledigt ist stehen auf der Seite nur noch Multiplikatoren oder Divisor oder Dividenden. Dann muss dei linke Seite der Formel geklammert werden und wird entweder Multiplikator oder Divisor oder Dividend, ja nach gefundenem Rechenzeichen.

Die frage ist jetzt, ob Du den bisherigen Code lesen kannst und Dir das selbst zutraust, oder ob ich das in einer Nachtschicht schreibe. :smile: Das geht nicht mehr so schnell.

Es kommen keine neuen Befehle dazu, man muss nur recht viel Code schreiben und genau aufpassen, daß alles in der richtigen Reihenfolge pasiert. Genau, wie man das auf dem Papier auch macht. Immer mit der niederen Rechenart anfangen und zur nächst höheren vorarbeiten. Aupassen, daß man nicht aus Summen kürzt, Klammern auflösen, notfalls ausklammern oder ausmultiplizieren … Das ist schon einiges an Schreib- und Denkarbeit. Prinzipiell sieht der Code aber aus wie der Anfang.

Gruß Rainer

Hallo Rainer,

sorry, ich glaube das ist ein kleines Missverständnis. Ich hatte dir 2 Antworten auf einemal geschrieben :smile: Deine Antwort hat sich wahrscheinlich mit meiner zeitlich überkreuzt.

Der letzte Code von dir funktioniert jedenfalls super. Nochmal besten Dank dafür.

Ich habe mich mal an den Code versucht, leider bekomme ich den Rest mit der Multiplikation und Division nicht hin. Hättest du vielleicht noch ein Tipp für mich?

Viele Grüße
Marcel

Hallo Marcel,

sorry, ich glaube das ist ein kleines Missverständnis. Ich
hatte dir 2 Antworten auf einemal geschrieben :smile: Deine Antwort
hat sich wahrscheinlich mit meiner zeitlich überkreuzt.

Der letzte Code von dir funktioniert jedenfalls super.

schon klar, ich habe die Korrektur bemerkt und gesehen, daß der Code jetzt läuft.

Ich habe mich mal an den Code versucht, leider bekomme ich den
Rest mit der Multiplikation und Division nicht hin. Hättest du
vielleicht noch ein Tipp für mich?

Hmmm. Tipp ist schwer. :smile:

Hast Du Dir mal mit dem Debugger angesehen, was der Code macht? Kennst Du den Debugger und kannst ihn verwenden? Wenn nicht, hast Du keine Chance, das wäre dann vorrangig.

Ich beschreibe erst mal kurz den Debugger. Wenn Du den kennst und verwendest, überspring den nächsten Abschnitt einfach.

In dem Editorfenster, in dem Du den Code bearbeiten kannst ist der linke, graue Rand breiter als sonst in Fenstern üblich. Klick dort in der ersten Zeile in der Befehle stehen, also nicht bei der Deklaration, auf diesen grauen Rand. Erwischst Du eine Zeile mit einem Befehl, wird auf dem Rand ein großer Punkt erscheinen. Das ist ein Stopp-Punkt. Startest Du nun Dein Programm wird es an dieser Stelle angehalten und Dir wird dieses Fenster gezeigt. Auf dem grauen Rand erscheint ein gelber Zeiger, der Programmzeiger. Er zeigt immer auf die Zeile, die als nächstes abgearbeitet werden soll. In der Zeile ist der Befehl, der als nächstes ausgeführt werden soll markiert. Zeigst Du in dieser Situation mit dem Mauszeiger auf eine Variable, wird die in einem ToolTipText deren Inhalt angezeigt. Mit der Taste F8 kannst Du den markierten Befehl ausführen, der Debugger springt zum nächsten Befehl, der ausgeführt werden soll. So kannst Du den Inhalt der Variablen während der Bearbeitung beobachten und genau verfolgen, was das Programm tut. Du kannst den gelben Zeiger auch mit der Maus verschieben und so bestimmte Programmteile ändern und neu ausführen lassen, ohne das Programm anzuhalten und neu zu starten.

Das Programm sucht zunächst die Zielvariable und merkt sich, wo die steht. Es sucht das Gleichheitszeichen und merkt sich dessen Position.

Es wird geprüft, ob die Zielvariable am Ende der Formel steht.

Falls die Variable nicht am Ende der Formel steht, wird der Teil links vom Gleichheitszeichen in die Variable ‚TL‘ (Teil Links) geschrieben. Der Teil nach dem Gleichheitszeichen einschließlich der Variablen wird in die Variable ‚TM‘ (Teil Mitte) übernommen. Der Teil nach der Zielvariablen kommt in die Variable ‚TR‘ (Teil Rechts). Im Moment wird dieser rechte Teil nur eingeklammert und vorzeichentichtig zwischen TR und das Gleichheitszeichen geschoben. Wenn hinter der Zielvariablen auch eine Multiplikation oder Division stehen darf, geht das nicht, das könnte falsch sein. Beispiel:

Y = 3*x*n + 4 … Daaus würde:
Y/(n+4)= 3*x

Das wäre falsch, denn richtig wäre:

Y-(4)/(n)=3*x

Die Klammern sind zwar in diesem Fall überflüssig, stören aber auch nicht. :smile:

Wenn die Multiplikation erlaubt ist muss also zunächst geprüft werden, ob zunächst Plus und Minus zu verarbeiten sind, bevor Multiplikation und Division verarbeitet werden dürfen.

Weiter im aktuellen Programm, die Zielvariable steht nun am Ende der Gleichung.
Die Positionen werden neu bestimmt, die Gleichung wieder zerlegt. In den Teil links von Gleichheitszeichen, den Teil rechts vom Gleichheitszeichen und Die Zielvariable. Dann wird wieder der Teil rechts vom Gleichheitszeichen eingeklanmmert und vorzeichenrichtig zwischen den Anfang der Gleichung und das Gleichheitszeichen geschoben. Die Zielvariable belibt allein rechts vom Gleichheitszeichen. Wenn da auch ein ‚*‘ oder ‚/‘ oder ‚‘ stehen darf, ist auch das falsch. Es wüdre z.B. aus:

Y = 3*n + 4*v + 3*x … ->
Y/(3*n + 4*v +3) = x

Richtig wäre:
(Y - (3*n + 4*v))/3 = x

Es muss wieder der Teil vor dem Multiplikatoer rest verarbeitet werden, bevor der Multiplikator verarbeitet werden darf.

Je mehr Rechenoperationen erlaubt werden, um so weiter muss das Programm entscheiden, was zuerst verarbeitet werden muss. muss diese Rechenzeichen erst finden, identifizieren, Klammern berücksichtigen, wenn welche vorkommen …

Das wird ein Tage langes versuchen und testen, im debugger verfolgen, was tatsächlich passiert. Die Ausgangsformel muss immer wieder verändert werden, damit das Programm nicht nur in einem Fall richtig arbeitet.

Zum Testen empfiehlt sich, für die variablen leicht nachrechenbare Werte zu übergeben und Excel den Wert der Formel berechnen zu lassen. In VBA heißt die Funktion, mit der man Formeln berechmem lassen kann ‚Eval‘ und ist Bestandteil von Access und VBScript. Wenn man Verweise auf eins von Beiden setzt, kann man Eval in VBA verwenden.

Gruß Rainer

Hallo,
weder Compiler noch Reflection aus .Net noch andere mir bekannte Systeme können Formeln automatisch umstellen.
Am einfachsten wird es wohl sein man schreibt sich selber einen Codegenerator, der alle Formeln in allen Varianten erzeugt.
Wenn man nicht so viel programmiererfahrung hat würde ich davon jedoch abraten, weil das nicht gerade einfach ist. Es bleibt dann also nur der Weg alle Formeln in allen Varianten gleich im Code zu hinterlegen.

Gruß
Alexander