Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1240to1244
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
Inhaltsverzeichnis

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

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?
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
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

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige