Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Nutzung von Matrixfunktionen mit VBA array

Forumthread: Nutzung von Matrixfunktionen mit VBA array

Nutzung von Matrixfunktionen mit VBA array
Matrixfunktionen
Hallo, ich wollte fragen ob mir jemand mit helfen kann. Ich möchte gerne die Matrixfunktionen (Multiplikation, Transposition, Inversion) in VBA anwenden und zwar auf Arrays (Vektoren, Matrizen), die in VBA erstellt habe.
Die Ausgabe soll als User Defined

Function geschehen.
Leider sagt mir Excel bei der Ausgabe der Daten, dass der falsche Datentyp verwendet wurde.
Da ich kein VBA Profi bin, definiere ich ohnehin nur Zählvariablen als Integer. Alles andere  _
lasse ich undefiniert, sodass sowohl die Funktion als auch die Arrays automatisch als Variant deklariert werden müssten.
Die Berechnungen der Arrays innerhalb von VBA wird richtig berechnet, das habe ich soweit geprfü _
ft.
Ziel ist für eine Vielzahl an Zeitreihen eine Multifaktor Regression durchzuführen. Ich weiss,  _
dass es natürlich mit der RGP Funktion bzw. Linest möglich ist. Die Zeitreihen sind jedoch alle unterschiedlich lang und beginnen bzw. enden zu unterschiedlichen Zeitpunkten. Daher definiere ich eben die Vektoren in VBA individuell.
Der Code sieht folgendermaßen aus (ist sicherlich nicht der effizienteste und schnellste)

Function linreg_rowdata(r, x)
Dim m As Integer, n As Integer, j As Integer, i As Integer, k As Integer, l As Integer
Dim y, Z
Dim beta
m = WorksheetFunction.Max(r.Rows.Count, r.Columns.Count)
n = WorksheetFunction.Min(x.Rows.Count, x.Columns.Count)
j = WorksheetFunction.Count(r)
ReDim y(1 To j)
ReDim Z(1 To j, 1 To n + 1)
ReDim beta(1 To n + 1)
k = 1
For i = 1 To m
If r(i)  "" Then
y(k) = r(i)
For l = 2 To n + 1
Z(k, 1) = 1
Z(k, l) = x(l - 1, i)
Next l
k = k + 1
End If
Next i
beta = WorksheetFunction.MMult(WorksheetFunction.MInverse(WorksheetFunction.MMult( _
WorksheetFunction.Transpose(Z), Z)), WorksheetFunction.MMult(WorksheetFunction.MInverse(Z), y))
linreg_rowdata = beta
End Function

Anzeige
Vielleicht solltest du es ab und zu mal mit ...
03.12.2011 00:36:20
Luc:-?
Long statt Integer versuchen, Jan … ;->
Gruß + schöWE, Luc :-?
AW: Vielleicht solltest du es ab und zu mal mit ...
05.12.2011 09:07:22
Jan
Hallo Luc:-?, vielen Dank für deine Antwort.
Was ist der Hintergrund der Umdefinierung von Zählvariablen zu Long, statt Integer - abgesehen von dem größeren Datenbereich. Eigentlich reichen 32.000 Zählvariablen, so lang sind meine Zeitreihen nicht. Arbeitet Long besser mit Matrix-Formeln zusammen?
Anzeige
Du hast beta vor der Berechnung ...
06.12.2011 03:07:13
Luc:-?
…redimensioniert, Jan,
das dürfte der Fehler sein, denn dimensionierte Felder kann man nicht mit einer kompletten Matrix überschreiben, sondern nur elementweise. Lass also das Redim beta(…) weg! Außerdem ist folgende Notation doch wesentl übersichtlicher als deine … ;-)
With WorksheetFunction
beta = .MMult(.MInverse(.MMult(.Transpose(Z), Z)), .MMult(.MInverse(Z), y))
End With
Gruß Luc :-?
Anzeige
AW: Du hast beta vor der Berechnung ...
06.12.2011 08:04:36
Jan
Hallo Luc:-?,
vielen Dank, der Tip vereinfacht die Notation erheblich. Ich wusste zwar, dass es diese With - End With Geschichte gibt, habe sie aber noch nie angewendet.
Leider Funktioniert es mit dem Weglassen der Redimensionierung von Beta auch nicht, weiterhin kommt als Fehler, dass ein verwendeter Wert vom Falschen Datentyp ist.
Viele Grüße,
Jan
Anzeige
Habe das mal etwas näher untersucht, ...
07.12.2011 02:03:37
Luc:-?
…Jan,
und glaube, dass da ein Fehler in Z entsteht, denn ich hatte bei meinen sicher nicht fachgerechten Testdaten 2 #NV-Löcher in einem Spaltenvektor der Matrix, bei Zt waren die dann weg. MMULT ist aber nicht so tolerant, da gibt's dann Fehler. Außerdem wird die Fkt bei Zm-Berechnung rekursiv und bricht ergebnislos ab. Damit du das besser testen kannst (Einzelschrittmodus!), habe ich dir das mal wie folgt aufgedröselt …
Function linreg_rowdata(ByVal r As Range, ByVal x As Range)
Dim i As Integer, j As Integer, k As Integer, l As Integer, _
m As Integer, n As Integer, y(), Z(), Zi, Zm, Zt
With WorksheetFunction
m = .Max(r.Rows.Count, r.Columns.Count)
n = .Min(x.Rows.Count, x.Columns.Count)
j = .Count(r)
ReDim y(1 To j), Z(1 To j, 1 To n + 1)  ', Zt(1 To n + 1, 1 To j)
k = 1
For i = 1 To m
If r(i)  "" Then
y(k) = r(i)
For l = 2 To n + 1
Z(k, 1) = 1                 ': Zt(1, k) = 1
Z(k, l) = x(l - 1, i)       ': Zt(l, k) = x(l - 1, i)
Next l
k = k + 1
End If
Next i
Zt = .Transpose(Z)  ': linreg_rowdata = Zt  'bzw Z --+ nur f.Test!
Zm = .MMult(Zt, Z)  ': linreg_rowdata = Zm  'hier rekursiv m.Abbr!
Zi = .MInverse(Z)   ': linreg_rowdata = Zi
linreg_rowdata = .MMult(.MInverse(Zm), .MMult(Zi, y))
End With
End Function
Transpose ist jedenfalls nicht schuld, obwohl du Zt eigentl auch direkt anlegen könntest. Aber auch dann fehlen die #NV, was auch ein Ansatz zur Fehlersuche sein könnte.
As Range im Fktskopf ist besser als gar keine, also Variant-Deklaration, denn die würde auch Ausdrücke und (Matrix-)Konstanten zulassen, die bei .Rows/Columns.Count zu Fehlerabbruch führen. Alternativ könntest du bei TypeName(r)≠"Range" mit LBound bzw UBound(…, 1 bzw 2) arbeiten. Das wäre die universellere Lösung! Das ginge auch generell, wenn du vorher alle Bereichsbezüge in Datenfelder Arrays umwandelst, 2x .Transpose reicht dafür in der Regel, den mit 1 multiplizieren klappt in VBA nur einzelwertweise.
Viel Erfolg bei der Fehlersuche, Gruß Luc :-?
Anzeige
AW: Habe das mal etwas näher untersucht, ...
08.12.2011 09:53:18
Jan
Hallo Luc:-?, vielen Dank für den Code ich werde das vermutlich erst Freitag testen können. Ich melde mich dann wieder, wenn der Test durch ist.
Viele Grüße,
Jan
AW: Nutzung von Matrixfunktionen mit VBA array
03.12.2011 10:14:05
Matrixfunktionen
Hallo Jan!
Wie rufst Du diese Funktion auf?
Gruß Gerd
AW: Nutzung von Matrixfunktionen mit VBA array
05.12.2011 09:04:14
Matrixfunktionen
Hallo, vielen Dank für deine Antwort.
Die Funktion möchte ich gerne ganz normal aufrufen, mittels einer Eingabe im Excel Sheet. Ich Ich hatte zum Test mal probiert den Mittelwert mittels worksheet.function.average(y) auslesen zu lassen, das war kein Problem. Der Vektor y wurde somit korrekt bestückt, und kann also auch von anderen Worksheet Funktionen ausgelsen werden, nur die Matrixfunktionen scheinen nicht zu laufen.
Anzeige
AW: Nutzung von Matrixfunktionen mit VBA array
05.12.2011 19:31:29
Matrixfunktionen
Hallo Jan,
bin ein ewiger Formellaie, Ich kann mir nur vorstellen, dass Du das Teil in einer Arrayformel mit den geschweiften Klammern in einem passenden mehrzelligen Bereich aufrufst.
Aber wie gesagt, ist nicht mein Ding.
Gruß Gerd
AW: Nutzung von Matrixfunktionen mit VBA array
06.12.2011 07:57:16
Matrixfunktionen
Hallo Gerd,
im Excel Sheet habe ich die Formel natürlich als Array-Formel eingegeben, sprich über Strg+Shift+Enter, daran lag es leider nicht.
Dennoch vielen Dank und viele Grüße,
Jan
Anzeige
;
Anzeige

Infobox / Tutorial

Nutzung von Matrixfunktionen in Excel VBA


Schritt-für-Schritt-Anleitung

Um Matrixfunktionen wie Multiplikation, Transposition und Inversion in Excel VBA zu nutzen, kannst du die folgenden Schritte befolgen:

  1. VBA-Editor öffnen: Drücke ALT + F11, um den VBA-Editor zu öffnen.

  2. Neues Modul erstellen: Klicke mit der rechten Maustaste auf den VBA-Projektbaum, gehe zu Einfügen und wähle Modul.

  3. Code eingeben: Füge den folgenden Code in das Modul ein:

    Function linreg_rowdata(r As Range, x As Range) As Variant
       Dim m As Integer, n As Integer, j As Integer, k As Integer, l As Integer
       Dim y() As Variant, Z() As Variant
       With WorksheetFunction
           m = .Max(r.Rows.Count, r.Columns.Count)
           n = .Min(x.Rows.Count, x.Columns.Count)
           j = .Count(r)
           ReDim y(1 To j)
           ReDim Z(1 To j, 1 To n + 1)
           k = 1
           For i = 1 To m
               If r(i) <> "" Then
                   y(k) = r(i)
                   For l = 2 To n + 1
                       Z(k, 1) = 1
                       Z(k, l) = x(l - 1, i)
                   Next l
                   k = k + 1
               End If
           Next i
           linreg_rowdata = .MMult(.MInverse(.MMult(.Transpose(Z), Z)), .MMult(.MInverse(Z), y))
       End With
    End Function
  4. Funktion im Excel-Sheet aufrufen: Verwende die Funktion in einer Zelle, indem du sie als Array-Formel eingibst (Strg + Shift + Enter).


Häufige Fehler und Lösungen

  • Falscher Datentyp: Achte darauf, dass alle Eingabewerte den richtigen Datentyp haben. Wenn du mit Matrizen arbeitest, sollten die Werte als Range oder Variant deklariert sein.

  • Dimensionierung von Arrays: Wenn du ein Array redimensionierst, achte darauf, dass du dies vor der Verwendung oder Zuweisung machst. Ein ReDim in der falschen Reihenfolge kann zu Fehlern führen.

  • #NV-Fehler: Stelle sicher, dass es keine #NV-Werte in deinen Bereichen gibt, da dies bei der Berechnung mit MMULT zu Problemen führen kann.


Alternative Methoden

Wenn du Matrixoperationen in Excel ohne VBA durchführen möchtest, kannst du die folgenden Funktionen verwenden:

  • MINVERSE: Diese Funktion berechnet die Inverse einer Matrix.
  • MMULT: Diese Funktion multipliziert zwei Matrizen.
  • TRANSPOSE: Damit kannst du eine Matrix transponieren.

Diese Funktionen können direkt in Excel eingegeben werden, ohne dass VBA erforderlich ist.


Praktische Beispiele

Hier ist ein einfaches Beispiel, wie du die oben definierte linreg_rowdata-Funktion in einem Excel-Sheet verwenden kannst:

  1. Angenommen, du hast zwei Bereiche in deinem Excel-Sheet:

    • Bereich A1:A10 (Zeitreihe Y)
    • Bereich B1:B10 (Zeitreihe X)
  2. In einer Zelle (z.B. C1) kannst du die Funktion aufrufen:

    =linreg_rowdata(A1:A10, B1:B10)
  3. Drücke Strg + Shift + Enter, um das Ergebnis als Array-Formel einzufügen.


Tipps für Profis

  • Verwende Long statt Integer für Zählvariablen, um sicherzustellen, dass du den maximalen Bereich nutzen kannst.

  • Nutze die With...End With-Notation, um deinen Code zu vereinfachen und die Lesbarkeit zu erhöhen.

  • Achte darauf, dass du bei der Arbeit mit großen Matrizen die Leistung im Auge behältst. Matrixoperationen können rechenintensiv sein.


FAQ: Häufige Fragen

1. Was sind Matrixfunktionen in Excel VBA?
Matrixfunktionen in Excel VBA sind Funktionen, die auf Arrays (Matrizen) angewendet werden, um mathematische Operationen wie Multiplikation, Transposition und Inversion durchzuführen.

2. Wie kann ich Fehler in meiner Matrixformel beheben?
Überprüfe, ob alle Eingaben den richtigen Datentyp haben und ob es keine #NV-Werte in deinen Bereichen gibt. Außerdem solltest du sicherstellen, dass Arrays korrekt dimensioniert sind.

3. Kann ich auch ohne VBA mit Matrizen arbeiten?
Ja, du kannst die Funktionen MINVERSE, MMULT und TRANSPOSE direkt in Excel verwenden, um Matrixoperationen durchzuführen.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige