Komplexere Berechnung: Lineares Gleichungssystem beliebigen Grades

Gleichungen eingeben | Programmierung mit vba | Etwas Design
Button für den Makroaufruf | Makro zum Löschen der Lösung | Sicherung der Tabelle

Excel ist ein wahrer Rechenmeister, man besehe sich nur die Funktionsübersicht an, die man erhält, wenn man den mit " fx" beschrifteten Button drückt. Die Lösung eines linearen Gleichungssystems gehört allerdings nicht dazu. Für Berechnungen, die viele Eingabewerte benötigen, ist Excel deshalb sehr geeignet, weil man die Eingabewerte übersichtlich darstellen und leicht korrigieren kann.

Als einfaches Beispiel betrachten wir die Lösung eines linearen Gleichungssystems mit hier, willkürlich festgelegt, maximal 15 Gleichungen mit 15 Unbekannten. Das können mittlerweile auch Taschenrechner; wer es damit bei so vielen Gleichungen einmal versucht hat, sieht sofort ein, daß Excel für diese Aufgabe besser geeignet ist.


Messwerte ablegen

Wir gehen mal davon aus, daß das Gleichungssystem irgendwo geordnet steht, auf Papier oder einem Ort, von dem aus es elektronisch importiert werden kann. Die übliche Darstellung eines linearen Gleichungssystems ist:

a11* x1+ a12* x2+ ... + a1n* xn= b1
...                                                ...
an1* x1+ an2* x2+ ... + ann* xn= bn

Die Koeffizienten aij des Systems aus n Gleichungen mit n Unbekannten werden reihenweise in die Tabelle geschrieben, die rechten Seiten direkt daneben. Die xi erscheinen in der Exceltabelle natürlich zunächst nicht. Wie das aussehen könnte, zeigen wir gleich. Die Ränder mit ihren Beschriftungen dienen hier nur dem Verständnis. Für die Funktion sind sie entbehrlich. Ein geratenes Gleichungssystem ist schon eingegeben, damit man später probieren kann.

Start

Excel enthält nun das Gleichungssystem; um daraus die Koeffizientenmatrix zu erzeugen, die wir für das noch nicht vorhandene Gleichungsprogramm brauchen, ist Programmierung nötig.

hoch zum Anfang


Programmierung mit vba

Um in Excel Dinge zu tun, die Excel selbst nicht kann, nutzt man die eingebaute Makrosprache vba (= "Visual Basic for Applications"). Unter <Extras>/<Makro>/<Visual Basic-Editor> klickt man sich in die Entwicklungsumgebung, genannt IDE, zu Deutsch : Integrated Development Environment, und holt sich dort aus der Menüleiste unter <Einfügen>/<Modul> ein Codeblatt, in das hinein das notwendige Programm geschrieben werden soll.

Nun sind mehrere Dinge notwendig. Wir müssen

und das alles nicht unbedingt in dieser Reihenfolge.

Wir beginnen mit dem Makro, das später die ganze Aktivität starten soll. Es möge "Gleichung" heißen. Dann sieht unser Start nach der Kopfzeile und dem ersten "Return" so aus:

Modul

Schon jetzt kennt Excel dieses Makro, wovon man sich leicht überzeugen kann. (Im Menü <Extras>/<Makro>/<Makros...> wählen.)
Nun werden in diese Prozedur die folgenden Programmaktivitäten hinein komponiert.

Wenn das System so platziert ist, wie oben gezeigt, kann man darauf zugreifen, ohne es erst markieren zu müssen.
Zuerst müssen wir feststellen, wie viele Gleichungen und wie viele Unbekannte es im Gleichungssystem gibt. Dazu könnte man natürlich eine Variableneingabe organisieren. Aber wenn schon Programmhilfe, dann richtig. Excel soll das anhand unserer eingetragenen Wertematrix ruhig allein herausbekommen. Wir prüfen, wie viele beschriebene Spalten und Zeilen vorhanden sind. Bei Unstimmigkeiten müssen wir natürlich die Rechnung unterbinden.

Dim zeile As Integer, spalte As Integer, grad As Integer
'Wie groß ist das System?
zeile = 2
spalte = 2
While Cells(zeile, spalte).Text <> Empty
   spalte = spalte + 1
Wend
spalte = spalte - 1
While Cells(zeile, spalte).Text <> Empty
   zeile = zeile + 1
Wend
zeile = zeile - 1

'Stimmt die Zahl der Gleichungen?
If zeile <> spalte - 1 Then
   MsgBox "Fehlerhafte Auswahl, bitte überprüfen Sie die Zahl der Variablen bzw. der Gleichungen!"
   Exit Sub
End If
'Nun ist der Grad n des GS bestimmbar!
grad = zeile - 1

Bisschen unklar mit den 1en?
Ja, das sind die Ränder, die wir jeweils berücksichtigen müssen. Vornehmerweise könnte man denen Variablennamen verpassen, dann wären sie variabel, aber brauchen wir das?

Wenn der Grad des Gleichungssystems bekannt ist, können wir die Werte in eine Matrix einlesen, die wir natürlich zuerst dimensionieren müssen. Deshalb fügen wir hinter die erste Dim-Zeile ein:

Dim A(15, 16) As Double, x(15) As Double
Dim i As Integer, j As Integer
Dim b As Double

Nun haben wir Platz für die Koeffizienten von 15 Gleichungen mit 15 Unbekannten, die wir in x() anzeigen können. Falls es doch lieber 150 sein sollen, müssen an dieser Stelle die Werte entsprechend verändert werden. Die anderen Variablen werden auch benötigt.
Denn nun wird vorbereitet und sogleich gerechnet:

'Werte einlesen und GS lösen
For i = 1 To grad
   For j = 1 To grad + 1
      A(i, j) = Cells(1 + i, 1 + j)
   Next
Next
gauss grad, A, x

Hallo, mechanische Abschreiber! Testet doch mal! Die letzte Zeile bedeutet den Aufruf einer Prozedur, die es nicht gibt.
Wir brauchen eine Prozedur, die ein lineares Gleichungssystem löst und wissen, da gibt es doch diesen Gauss-Algorithmus. Ich, der Autor werde schnell fündig in meinem Visual-Basic-Kurs und hole mir von dort die gewünschte Prozedur:

Sub gauss(n%, A() As Double, x() As Double)
Dim i%, j%, k%, jmax%, kmax%, merk() As Integer
Dim s As Double, max As Double, skal() As Double
ReDim merk(n), skal(n)

'Reihenfolge sichern
   For i = 1 To n
       merk(i) = i
   Next

'Normalisierung
   For i = 1 To n
      s = 0
      For j = 1 To n
         s = s + Abs(A(i, j))
      Next
      skal(i) = 1 / s
   Next

'Vorwärtselimination
   For k = 1 To n - 1
      max = skal(k) * Abs(A(k, k))
      kmax = k
'Spalte mit max
      jmax = k'Zeile mit max
      For j = k To n'Pivotzelle suchen
         For i = k To n
            If skal(j) * Abs(A(j, i))> max Then
               jmax = j
               kmax = i
               max = skal(j) * Abs(A(j, i))
            End If
         Next
      Next
      If jmax <> k Then
'Zeilentausch, wenn nötig
         For j = k To n + 1
            s = A(k, j)
            A(k, j) = A(jmax, j)
            A(jmax, j) = s
         Next
         s = skal(k)
         skal(k) = skal(jmax)
         skal(jmax) = s
      End If
      If kmax <> k Then
'Spaltentausch, wenn nötig
         For i = 1 To n
            s = A(i, k)
            A(i, k) = A(i, kmax)
            A(i, kmax) = s
         Next
         j = merk(k)
         merk(k) = merk(kmax)
         merk(kmax) = j
      End If

'eigentliche Elimination
      For i = k + 1 To n
         s = A(i, k) / A(k, k)
         A(i, k) = 0#
         For j = k + 1 To n + 1
            A(i, j) = A(i, j) - s * A(k, j)
         Next
      Next
   Next

'Auflösung rückwärts
   x(merk(n)) = A(n, n + 1) / A(n, n)
   For i = n - 1 To 1 Step -1
      s = A(i, n + 1)
      For j = i + 1 To n
         s = s - A(i, j) * x(merk(j))
      Next
      x(merk(i)) = s / A(i, i)
   Next
End Sub

Die wird natürlich nicht mehr in, sondern hinter  Sub Gleichung() gesetzt!
Nun sollte, nach Ausführung des Programms in x() unsere Lösung liegen. Deshalb muss noch eine Ausgabe in die Sub Gleichung() eingefügt werden. Außerdem soll sogleich eine Probe-Rechnung mit aufgenommen werden.

'Ergebnisse und Probe zeigen
For i = 1 To grad
   Cells(1 + grad + 1, 1 + i) = Format(x(i), "Standard")
Next
For i = 1 To grad
   b = 0
   For j = 1 To grad
      b = b + Cells(1 + i, 1 + j).Value * x(j)
   Next
   Cells(1 + i, 1 + grad + 2) = Format(b, "Standard")
Next

Jetzt stehen die x-Werte unterhalb der Gleichung selbst in den richtigen Spalten, die Probewerte direkt neben den ehemaligen rechten Seiten, sogar alles schön formatiert, damit wir nicht von Nachkommastellen erschlagen werden. Wir sind fertig, aber so richtig gut sieht das alles trotzdem nicht aus. Auch käme nun bei neuem Start des Makros "Gleichung" Unsinn heraus.

Ergebnis, unschön
hoch zum Anfang


Etwas Design

Man könnte ja, etwa die Ausgabezellen rot unterlegen. Solche roten Zelle kann man evtl. auch später brauchen, um eine Lösung sauber wieder entfernen zu können.
Wie macht man das aus dem Programm heraus? Wenn einem der Code für so eine Aktivität nicht über den Weg läuft, was dann? Kleiner Tipp: Man nutze den Makrorekorder: <Extras></Makro>/<Aufzeichnen...>. Also nur starten, tun, was man tun möchte, dann so tun, als wolle man das Makro bearbeiten. Schon liegt der Code vor einem, mit den passenden Schlüsselwörtern. Die heißen hier, abgesehen von der vorherigen Markierung einer Zelle:

Cells(x, y).Interior.ColorIndex = 3

Wir lernen, es geht um Farb-Nummern ( ColorIndex) , auf die man nicht unbedingt von alleine kommt. Die sind spezifisch für Excel. Wer andere Farben mag, dem zeige ich hier mal die verfügbaren Nummern :

Farbnummern

Nun kann der Codeschnipsel zur Ausgabe noch etwas korrigiert werden. Daß die nicht betroffenen Teile der Tabelle auch angehübscht werden können, versteht sich ja von selbst.

'Ergebnisse und Probe zeigen
For i = 1 To grad
   Cells(1 + grad + 1, 1 + i).Interior.ColorIndex = 3
   Cells(1 + grad + 1, 1 + i) = Format(x(i), "Standard")
Next
Cells(1 + grad + 1, 1 + i) = "<Lösungen"
Cells(1 + grad + 1, 2 + i) = "^ Probe"
For i = 1 To grad
   b = 0
   For j = 1 To grad
      b = b + Cells(1 + i, 1 + j).Value * x(j)
   Next
   Cells(1 + i, 1 + grad + 2).Interior.ColorIndex = 3
   Cells(1 + i, 1 + grad + 2) = Format(b, "Standard")
Next

Dies ist das Ergebnis nach der letzten Operation.

Ergebnis schöner

Das wär es ... fast.
Es gibt noch Arbeit:

Deshalb geht es noch weiter.
hoch zum Anfang


Makroaufruf mit Button

Zuerst soll nun die Bedienbarkeit gesichert werden. Dazu wird ein Button auf der Tabelle benötigt. Den holt man, indem man mit <Ansicht>/<Symbolleisten>/<Formular> einen Werkzeugkasten holt. Daraus übernimmt man einen Button, dem man anschließend das zu startende Makro zuweist:

Button einfügen

Also auf "Gleichung" klicken und "OK" geben.

Wenn man den neuen Button ausgiebig testet, passiert gleich beim zweiten Klick ein Unglück: Durch die erste Berechnung ist ja der belegte Tabellenbereich größer geworden. Das Probieren mit dem Gleichungssystem wird dadurch erheblich erschwert. Wenn man seine Excel-Anwendung speichert, würde die Lösung mit ihren roten Balken stehen bleiben und bei neuer Verwendung im Wege sein. Deshalb brauchen wir nun die Löschroutine, die diese Ränder samt Inhalt beseitigt:

hoch zum Anfang

Löschroutine

Wozu wirklich? An sich ist man ja froh, wenn die Lösung vorliegt. Bloß, der zweite Druck auf den Rechne-Button schafft schon Probleme, wie oben festgestellt. Auch wenn man mit dem Gleichungssystem etwas experimentieren will, braucht man ihn.
Also gibt es ein neues Makro:

Sub Löschen()
Dim spalte As Integer, grad As Integer, i As Integer, muss As Boolean

'müssen wir etwas Löschen?
   muss = False
   For i = 2 To 17
      If Cells(1, i).Interior.ColorIndex = 3 Then muss = True
   Next
   If muss Then
      spalte = 2
      While Cells(2, spalte).Text <> Empty
         spalte = spalte + 1
      Wend
      grad = spalte - 4
      Cells(1 + grad + 1, 1).Interior.ColorIndex = 4
      Cells(1 + grad + 1, 1) = ""
      For i = 1 To grad + 2
         Cells(1 + grad + 1, 1 + i).Interior.ColorIndex = 0
         Cells(1 + grad + 1, 1 + i) = ""
      Next
      Cells(1, 1 + grad + 2).Interior.ColorIndex = 4
      Cells(1, 1 + grad + 2) = ""
      For i = 1 To grad
         Cells(1 + i, 1 + grad + 2).Interior.ColorIndex = 0
         Cells(1 + i, 1 + grad + 2) = ""
      Next
   End If
End Sub

Hier wird nicht einfach gelöscht, sondern nur dann, wenn es etwas zu Löschen gibt. Deshalb die anfängliche Abfrage und die nur bedingte Löschung. Umgekehrt darf nur dann neu gerechnet werden, wenn zuvor noch nicht gerechnet oder aber gerade gelöscht wurde. Deshalb muss das Löschmakro am Beginn des Makros "Gleichung" eingefügt werden.
Um eventuelle Probierarbeit zu erleichtern und um das Tabellenblatt "sauber", also ohne rot unterlegte Lösungsfelder speichern zu können, erhält die Löschroutine einen eigenen Button.
Nun sind alle Erfordernisse befriedigt und Fehlbedienungen der beiden Makros nicht mehr möglich.

Fertiges Rechenblatt

Was nun noch zu tun bleibt, ist die Sicherung des Eingabebereiches. Dazu gleich mehr.

hoch zum Anfang

Sicherung

Die Sicherung von Excelprojekten soll die Bedienung durch Uneingewiesene Personen ermöglichen, ohne daß Schaden entstehen kann. Es wäre wünschenswert, nur den Bereich der Gleichung beschreibbar zu machen, während der Rest der Tabelle geschützt, also unveränderlich ist.
Der Schutz wird bei Excel im Menü <Extras>/<Schutz>/<Blattschutz ...> gesetzt oder aufgehoben. Man kann die Bereiche, die veränderlich bleiben sollen, zuvor aus dem Schutz ausnehmen. Dazu müssen sie markiert werden. Dann kann man unter <Format>/<Zellen>/<Sicherheit> diese Einstellung vornehmen.
Leider sind auch die vom Schutz ausgenommenen Zellen bei eingeschaltetem Blattschutz zwar beschreibbar und löschbar, aber nicht mehr formatierbar. Im geschützten Zustand der Tabelle funktioniert die hier vorgesehene Einfärbung bzw. Einfärbung der Zellen nicht mehr.

Ausweg:

So, das wäre alles.
Viel Erfolg beim Rechnen!
hoch zum Anfang

zurück zur ÜbersichtDownload
Kurs-Unterlagen Informatik
© Rolf Hirte, zuletzt bearbeitet: 30.11.2003