Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
868to872
868to872
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Prozedur in prozedur

Prozedur in prozedur
14.05.2007 09:47:35
Julia
'Hallo zusammen!!
Ich habe hier ein - für mich großes - Problem. _
Ich schriebe ein Programm zur Berechnung linearer Gleichungssysteme nach Gauß und möchte gerne _
Programm in kleineren Programmen teilen, damit alles übersichtlicher und einfach schöner wird _
(außerdem will ich ja was dazu lernen!!) _
'Ich möchte, dass mein "Hauptprogramm" hier "Schritt_3" genannt, die kleineren Prozeduren _
"tauschen " und "einsen" selbstständig einliest und diese korrekt ausführt. Aber es klappt nicht. _
Ich kenne mich mit solchen Situationen nicht aus. In den Bücher, die ich habe , konnte ich bis jetzt _
keine passende Lösung gefunden.
'In der Prozedur "Schritt_3" soll ein Datenfeld eingelesen werden:
'________________________________________________

Public Sub Schritt_3()
Dim A#()
Dim i%, j%, l%
Dim n%
n=3   			'Eigentlich wird n durch Dialogabfrage übergeben, aber hier nehmen
'wir mal an, dass n=3 ist.
'Matrix A der Größe n*n und der Vektor b werden eingelesen, insgesamt
'ergibt es sich ein n*(n+1) großes Feld
ReDim A(n, n + 1)		‘
For i = 1 To n
For j = 1 To n + 1
A(i, j) = Cells(15 + i, 1 + j)
'Debug.Print A(i, j)
Next j
Next i
'hier soll die Vertauschung vorgenommen werden
For l = 1 To n
If A(l, l) = 0 Then
tauschen
End If
'nach dem es keine Nullen Auf der Diagonalen der n*n Matrix mehr gibt, sollen alle Zeilen _
A(l,….) durch ihr Diagonaleintrag A(l,l) geteilt werden. Dies soll die Prozedur „einsen“  _
bernehmen.
einsen			‚Aufruf der Prozedur
'Ausgabe für Kontrolle
For l = 1 To n
For j = 1 To n + 1
Cells(15 + l, 10 + j) = A(l, j)
Next j
Next l
End Sub


'___________________________________________________________________
'Nach dem die einträge eingelesen sind, muss überprüft werden, ob sich auf der Diagonalen, dass _
sind die A(l,l)-Einträge für die l-te Zeile, Nullen befindet. _
Wenn dass der Fall ist, sollen dann die betroffenen Zeilen vertauscht werden. _
Eigentlich soll es so sein, dass die l-te Zeile ihren Platzt mit der Zeile l+1 tauscht, _
und die letzte Zeile, wenn sie getauscht werden soll, auf den ersten Platz kommt und _
nicht auf die Stelle l+1, die es ja gar nicht gibt und damit es nicht aus dem gültigen Berecht fällt. _
Ich weiß bis jetzt noch nicht wie ich dass machen soll, und habe es so gemacht:
'Hat die Zeile l an der Stelle A(l,l) eine Null stehen, dann soll sie ihr Platz verlassen, und zwar auf die _
Stelle n-l+1. Diese Methode IST ABER FEHLERHAFT!!!
'Wie die Vertauschung im Allgemeinen aussieht, ist eigentlich egal, nur es soll für alle Zeilen möglich sein _
einen anderen Platzt zu bekommen, ohne dass sich da was überschneidet. _
Meine Methode schafft das nicht. D.h. für n=3 sieht es dann so aus: _
1=>3, 3=>1 und 2 wird überhaupt nicht vertauscht. Bis ich dieses Problem gelöst habe, versuche _
ich solche 3x3 Matrizen zu bearbeiten, bei denen die 2-te Zeile nicht vertauscht werden soll. _
Ist natürlich ziemlich blöd, aber im Moment habe ich keine andere Lösung. _
Wenn jemand ein Vorschlag hat, bitte meldet euch!!!
'_________________________________________________________________________


Public Sub tauschen()
Dim S#(), A#()
Dim i%, j%, l%, n%
n=3
ReDim A(n, n + 1)
ReDim S(n, n + 1)
'Hier werden die Zeilen, wenn es nötig, vertauscht
For l = 1 To n
If A(l, l) = 0 Then
For j = 1 To n + 1
S(l, j) = A(l, j)
A(l, j) = A(n - l + 1, j)  	‘Hier wird findet die  Vertauschung statt
A(n - l + 1, j) = S(l, j)
Next j
End If
Next l
End Sub


‘_________________________________________________________________________


Public Sub einsen()
Dim  A#()
Dim i%, j%, l%, n%
n=3
ReDim A(n, n + 1)
For l = k To n
For j = 1 To n + 1
A(l, j) = CLng(A(l, j)) / A(l,l)      'Hier bekomme ich immer die Meldung "Laufzeitfehler   _
_
6, Überlauf",
'Debug.Print A(l, l)                            'wieß aber nicht, warum
Next j
Next l
End Sub


'Ich weiss, dass man dies hier alles in einer Prozedur machen kann, aber ich will es lernen!!!
Bitte meldet euch, sagt mir was ich hier falsch mache.
Liebe Grüße
Julia

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Prozedur in prozedur
14.05.2007 22:59:55
Kai
Hallo Julia,
endgütlig beurteilen will ich es nich nicht, dafür habe ich mich nicht lang genug befasst. Aber wenn ich diese drei Prozeduren in ein Modul kopiere und laufen lasse erhalte ich den selben Fehler, 'Überlauf'.
Wen ich mir dann im Direktfenster mal die Werte anzeigen lasse, die in dem Array sind, dann sind die alle 0. Soll heißen, wenn du durch A(l,l) teilst, dann teilst du durch 0. Wenn du statt A(l,l) einfach mal 0 dahinschreibst, gibt's den selben Fehler. Und dann siehst du wohl auch ganz schnell warum ;).
Entweder da ist also was ganz grundsätzliches faul, weil das Array nicht da ist, oder hier im Post hast du nur die halbe Wahrheit zur Verfügung gestellt. Lade doch einfach mal deine .xls Datei mit FileUpLoad hier ins Forum hoch, das ist bei solchen Dinge etwas einfacher, als so lang Monster-Posts.
Also, erstmal suchen, warum da ein leeres Array ankommt. Wo keine Daten sind, da geht auch keine Prozedur die mit ihnen rechnen will. sub einsen() muss also fehlschlagen.
Tipp: Einzelne Schritte ausführen und im Direktfenster immer die Werte der Variablen und Ausdrücke kontrollieren [mit Print A(l,l) ], dann siehst du, was da los ist.
Grüße aus Mexiko,
Kai

Anzeige
AW: Prozedur in prozedur
15.05.2007 09:34:00
Julia
Hallo Kai,
danke für Deine Antwort.
Mein ganzes programm wollte ich nicht ins Nezt stellen, da es viel zu viel ist. Das, was Du da siehst ist nur ein Teil, dass unabhängig vom rest funktionieren soll. Du hast Recht, ich habe vergessen zu sagen, dass in dem Zellbereich, wo aus die Einträge der A_matrix eingelesen werden, müssen die Werte per hald eingetragen werden, sonst ist es kein wunder, dass die division durch null nicht klappt. Aber selbst wenn die Matrix keine nullen enthält kommt es zu Überlauf.
Gruß
Julia

AW: Prozedur in prozedur
14.05.2007 23:02:05
MichaV
Hallo,


Option Explicit
Public Sub Schritt_3()
Dim A#()
Dim i%, j%, l%
Dim n%
n = 3           'Eigentlich wird n durch Dialogabfrage übergeben, aber hier nehmen
                'wir mal an, dass n=3 ist.
'Matrix A der Größe n*n und der Vektor b werden eingelesen, insgesamt
'ergibt es sich ein n*(n+1) großes Feld
ReDim A(n, n + 1)
For i = 1 To n
    For j = 1 To n + 1
         A(i, j) = Cells(i, j)
         Debug.Print A(i, j)
    Next j
Next i
'A = Range(Cells(1, 1), Cells(n, n + 1))
'hier soll die Vertauschung vorgenommen werden
For l = 1 To n
    If A(l, l) = 0 Then
    Call tauschen(A, l, n)
    End If
Next
'nach dem es keine Nullen Auf der Diagonalen der n*n Matrix mehr gibt, sollen alle Zeilen _
A(l,\'85.) durch ihr Diagonaleintrag A(l,l) geteilt werden. Dies soll die Prozedur \'84einsen\ldblquote  _
bernehmen.

Call einsen(A, n)         'Aufruf der Prozedur
'Ausgabe für Kontrolle
For i = 1 To n
    For j = 1 To n + 1
         Cells(10 + i, j) = A(i, j)
    Next j
Next i
End Sub
Public Sub tauschen(ByRef A#(), l%, n%)
Dim s#
Dim j%, t%
If l = n Then
    t = 1 'und die letzte Zeile, wenn sie getauscht werden soll, auf den ersten Platz kommt
Else
    t = l + 1 'Eigentlich soll es so sein, dass die l-te Zeile ihren Platzt mit der Zeile l+1 tauscht
End If
For j = 1 To n + 1 'Tauschen
    s = A(l, j)
    A(l, j) = A(t, j)
    A(t, j) = s
Next j
End Sub
Public Sub einsen(ByRef A#(), n%)
Dim j%, l%
For j = 1 To n
    For l = 1 To n
        A(j, l) = A(j, l) / A(j, n + 1)
    Next l
Next j
End Sub


Gruß- Micha
PS: Rückmeldung wäre nett.

Anzeige
AW: Prozedur in prozedur
15.05.2007 11:55:00
Julia
Hallo Micha,
danke für Deine Mühe.
ich werde Dein Vorschlag sofort erproben.
Was mir neu ist, sind die Befehle Call und ByRef, da muss ich mich informieren, wie sie funktionieren und ob die mit dem rest meines Programms kompatibel sind.
Dann was ich noch nicht verstehe, ich dieses hier

Public Sub einsen(ByRef A#(), n%)
Dim j%, l%
For j = 1 To n
For l = 1 To n
A(j, l) = A(j, l) / A(j, n + 1)   'Hier soll es doch eigentlich so sein:
Next l
Next j
End Sub



Public Sub einsen(ByRef A#(), n%)
Dim j%, l%
For j = 1 To n
For l = 1 To n+1
A(j, l) = A(j, l) / A(j,j)   'denn nach Gauß, soll jede Zeile durch ihr Diagonaleintrag  _
geteilt werden,
Next l                       'aber vielleicht ist auch richtig, wie Du es gemacht hast.
Next j
End Sub


Ich probiere es gleich aus und sage Dir Bescheid.
Gruß aus Wuppertal
Julia

Anzeige
AW: Prozedur in prozedur
15.05.2007 13:15:09
Julia
Hallo Micha,
ich habe dein Vorschlag ausprobier und musste ein paar Änderungen vornehmen, es funktioniert jetzt.
ich habe mit '### meine Kommentare markiert, wo ich etwas verändert habe:

Public Sub tauschen(ByRef A#(), l%, n%)
'### warum ist hier noch l% mit in den Klammern drin,
'###in "einsen" ist es anders, da ist nur (ByRef A#(), n%)  was macht das für ein  _
Unterschied?
'###hier musste ich noch l laufen lassen,also
For l=1 To n
'###das habe ich noch dazu genommen und dann natürlich Next l am Ende
For j = 1 To n + 1 'Tauschen
s = A(l, j)
A(l, j) = A(t, j)
A(t, j) = s
Next j
Next l
'###ohne dies wurde die leitzten Einträge in jeder Spalte nicht vertauscht.
'###hast Du vielleicht l einfach nur vergessen, oder war das so gemeint, wenn ja, warum?
End Sub



Public Sub einsen(ByRef A#(), n%)
Dim j%, l%
For j = 1 To n
For l = 1 To n                           '##hier nich bis n, sondern bis n+1,  _
A ist doch (n,n+1) groß
A(j, l) = A(j, l) / A(j, n + 1)
'###hier wurden nicht alle Einträge durch A(j,n+1) geteilt. immer nur
'###bis j, d.h (1,1), (2,1),(2,2), (3,1), (3,2),(3,3).
'####statt /A(j,n+1) habe ich /daig(j) genommen und diag(j)=A(j,j)
'####entsprechend definiert.
Next l
Next j
End Sub


Ansonsten ist alles in ordnung, danke Dir.
ich habe versuch in Hilfe nach ByRef zu suchen, wurde aber nicht fündig, kannst Du mir vielleicht in ein Paar worte erklären was diesr Befehl macht, ich habe sonst das niergendwo gesehen.
Danke Dir nochmals!!
Gruß aus Wuppertal
Julia

Anzeige
AW: Prozedur in prozedur
15.05.2007 13:48:23
MichaV
Hi Julia,
Dir ging es ja vorrangig darum, funktionierende Prozeduren einzubauen. Ich hab nicht soo darauf geachtet, daß diese Prozeduren in sich richtig rechnen, zumal ich bei Deinem Code nicht so richtig gesehen habe, was Du machen willst. Und von der Theorie hab ich derzeit keine Ahnung :o) Und ich dachte mir, daß Du das alleine hinbekommst, Du hast dir da ja schon viele Gedanken gemacht. Und das hast Du ja bestätigt.
Zum Call und ByRef: Beides ist nicht notwendig und Du kannst es löschen. Wenn Du mehr erfahren willst, setze den Cursor auf das Wort "Call" und drücke F1. Keine Ausreden, daß Du es nicht in der Hilfe findest! Lies Dir alles in Ruhe durch und klicke mal auf "Beispiel". 2 Klicks weiter kommst Du zur Erklärung von ByVal und ByRef.
Zum Punkt '###in "einsen" ist es anders, da ist nur (ByRef A#(), n%) was macht das für ein _
Unterschied?

Alle Variablen, die in einer Sub deklariert werden, sind nur gültig für diese Sub. Wenn Du sie an eine andere Sub übergeben willst, mußt Du das im Sub- Aufruf (Call DeineSub(Variable1, Variable2) ) tun. An die Sub "Tauschen" übergibst Du 3 Variablen, nämlich A, die Position des zu tauschenden Wertes l, und die Anzahl der Zeilen n. Da für die Sub "einsen" nur A und die Anzahl der Zeilen n notwendig ist, musst Du nur A und n an die Sub übergeben.
Das ByRef habe ich nur hingeschrieben um zu verdeutlichen, daß A als Referenz übergeben wird (wird es sowieso, denn das ist die Grundeinstellung, ist dann aber nicht so gut nachvollziehbar). Das heißt, Du übergibst aus der Sub Schritt_3 die Variable A an eine andere Sub. Innerhalb dieser Sub wird A verändert. Weil A als Referenz übergeben wurde, wirken sich diese Änderungen auch auf das A in der Sub Schritt_3 aus.
Viele Grüße aus Trondheim! 5 Grad und Regen....
Micha

Anzeige
AW: Prozedur in prozedur
15.05.2007 18:01:32
Julia
Alles klar,
da ist mir völlig klar, dass Du dich mit Theorie nicht beschäftigen musst, aber ich dachte, da gibt es ein
ziemlich kluges Verfahren, wie man alles eleganter machen kann, daher meine Fragen.
ByVal habe ich gefunden, Call noch nicht gesucht und byRef nicht, nur ein Beispiel, aber in diesem Beispiel ging es um etwas anderes.
Ehrlich gesagt, ich finde diese Hilfe ganz blöd furmuliert, komme meinstens damit nicht zurecht, verstehe nicht ganz, ich habe da so ein Gefühl, als ob diese Hilfe automatsich aus dem englischen übersetzt wurden, manch Sätze haben kein Sinn.
Aber egal...
Ich hoffe nur, mei Proff wird mir nicht all zu viele Fragen zu meinem programm stellen.
Danke nochmals
Wir haben Sonne, schon den ganzen Tag!!!!
Schöne Grüße
Julia
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige