Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1584to1588
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

Matrixformel mit relativen Bezügen

Matrixformel mit relativen Bezügen
22.10.2017 15:01:49
Frank
Hallo an die Excel-Spezialisten,
ich habe eine Excel-Datei, deren Arbeitsmappen ich mittels VBA aus einer CSV-Datei fülle. Die Menge an Datensätzen ist immer unterschiedlich. Unterhalb der Datentabelle soll dann jeweils eine kleine Tabelle mit einer Statistik erzeugt werden. Damit sie immer korrekt positioniert ist, habe ich mit relativen Bezügen gearbeitet:
' letzte genutzte Zeile der Tabelle ermitteln - dient als Ankerpunkt für alle weiteren Aktionen
LR = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
' darauf aufbauend die erste Zeile für die Tabelle festlegen, um anschließend mit Offset anstatt konkreter Werte zu arbeiten
FR = LR + 2
' erste Spalte für die Tabelle festlegen, um anschließend mit Offset anstatt konkreter Werte arbeiten zu können
FC = 2
Die statischen Zellen fülle ich dann so:
Cells(FR, FC + 2).Value = "negative min"
Cells(FR, FC + 3).Value = "negative median"
Cells(FR, FC + 4).Value = "negative max"
...
Der Screenshot zeigt, wie das Ganze aussieht:
Userbild
Jetzt müssen noch die Formeln eingetragen werden, wo im Moment die Platzhalter "Wert ..." stehen. Für die erste Tabelle, die hier als Muster dient, reicht der Datenbereich von Zeile 2 bis 64. Ich habe eine Arrayformel für die Zelle D67 erstellt:
=MIN(WENN(F2:F64<0;F2:F64))
Sie berücksichtigt nur die negativen Werte in Spalte F und ermittelt das Minimum, hier -10,20%. In anderen Zellen folgen dann Formeln für neg. Median und neg. Maximum plus die Pendants für die positiven Werte, wie man im Screenshot sieht.
Um sie per VBA in die entsprechende Zelle zu bringen, nutze ich dieses Statement:
Cells(FR + 1, FC + 2).FormulaArray = "=MIN(IF(R[-65]C[2]:R[-3]C[2]<0,R[-65]C[2]:R[-3]C[2]))"
Für die zweite Zelle D68, deren Formel im Arbeitsblatt so aussieht:
=MIN(WENN(N2:N64<0;N2:N64)) lautet die VBA-Version so:
Cells(FR + 2, FC + 2).FormulaArray = "=MIN(IF(R[-66]C[10]:R[-4]C[10]<0,R[-66]C[10]:R[-4]C[10]))"
(im Screenshot steht hier noch "Wert 2A")
Das funktioniert, aber ich habe vier Fragen:
- Ich kapiere den Aufbau der aufgezeichneten Array-Formel noch nicht. Wie sind dort Anfang und Ende und die Spalte übersetzt worden? Ich möchte es ungern immer aufzeichnen, sondern direkt in VBA schreiben können.
- Was soll das mit dem negativen Vorzeichen?
- Wie muss ich vorgehen, um auf die jeweils unterschiedliche Menge an Datensätzen zu reagieren? Die Zeile 2 als Beginn bleibt immer gleich, das Ende verschiebt sich. Wie kann ich die Variable "LR", mit der ich die letzte Datenzeile ermittele, einbeziehen?
Vielen Dank für Eure Unterstützung!
Viele Grüße
Frank

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Beispiel
22.10.2017 15:44:25
Fennek
Hallo,
vor kurzem hatte ich (vielleicht) ein ähnlichen Problem. Der Vorschlag von Experten war die "Name"-Funktion zu nutzen:

Sub M_snb()
[A1:A20000].name = "snb"
[snb] = "=Rand()"
[snb] = [index(rank(snb,snb),)]
End Sub
Es sollte auch mit Range("A1:A2000").name = "Frank" gehen.
Nach dieser Definition sollte die Nutzung in einer Formel recht einfach werden.
Berichte bitte, ob es geklappt hat.
mfg
AW: Beispiel
22.10.2017 16:25:55
Frank
Hallo Fennek,
danke für die schnelle Rückmeldung.
Leider kann ich Deine Idee aber nicht nachvollziehen und auf meinen Sachverhalt adaptieren. Inwieweit soll die Definition des Namens helfen? Ich wüsste nicht, wie ich diesen in die Formel integrieren soll und warum er besser als eine Variable geeignet sein könnte.
Zudem würde sich das Problem m.E. damit auch nur verschieben, denn bei der Definition des Namens gibtst Du ja einen Zellbereich an - der bei mir aber dynamisch ist. Ich kann ihn ja nicht einfach "bis irgendwohin" ausdehnen, denn dann würde ich ja einen Zirkelbezug in den Spalten produzieren, in denen sich sowohl die Datentabelle und darunter die Statistik-Tabelle befinden.
Ich bin gespannt, ob noch weitere Antworten kommen. Noch ist der Beitrag ja nicht so lange online, als dass ich die Hoffnung schon aufgebe.
Viele Grüße
Frank
Anzeige
AW: Matrixformel mit relativen Bezügen
22.10.2017 17:02:45
Luschi
Hallo Frank,
Cells(FR+2, FC + 2) definiert die Zielzelle der Formel
- bei FR+1=68 und FC+2 = 4 ist das Zelle 'D68'
- von dieser Zelle 66 Zeilen hoher [R-66] und Spalte 10 weiter rechts [C10]
  ergibt die Zelle 'N2'
- auch R[-4]C[10] wird von der Zelle 'D68' betrachtet, also
  Zeile 68 - 4 = Zeile 64
  Spalte 4 + 10= Spalte 14
  ergibt Zelle 'N64
- in Kurzform: von Zelle 'D68' aus interpretiert ergibt R[-4]C[10] den Zellbereich 'N2:N64'
Gruß von Luschi
aus klein-Paris
AW: Matrixformel mit relativen Bezügen
22.10.2017 17:26:17
Werner
Hallo Frank,
die Formel ist in der RC Schreibweise aufgezeichnet. R=Zeile, C=Spalte
Es ist ein relativer Zellbezug, ausgehend von der Zelle, in die die Formel geschrieben wird.
Du schreibst deine erste Formel in Zelle D67 =R67C4
Ausgehend von diesen RC Werten wird der Bereich für deine Formel übersetzt.
F2 wäre R2C6 das sind 65 Zeilen oberhalb von R67 also R[-65] und 2 Spalten rechts von C4 also C[2], also R[-65]C[2].
Negative Zahlen bei R(ow) bedeutet oberhalb der Ausgangszelle, positive Zahlen bedeuten unterhalb der Ausgangszelle. Negative Zahlen bei C(olumn) bedeuten links von deiner Ausgangszelle und positive Zahlen rechts von der Ausgangszelle.
Eine Variable für das Ende des Datenbereichs brauchst du doch gar nicht, den Wert hast du doch schon. Dir ist ja bekannt, dass das Ende immer 3 Zeilen oberhalb von der Zelle ist, in die du die Formel eintragen willst. Auch wenn du dich dabei in Zeile 100 befindest endet dein Datenbereich drei Zeilen darüber.
Der Rekorder zeichnet immer relativ auf, für F2 kannst du das dann auch absolut schreiben.
=MIN(IF(R2C6:R[-3]C[2]<0,R2C6:R[-3]C[2]))
Gruß Werner
Anzeige
AW: Matrixformel mit relativen Bezügen
22.10.2017 20:47:20
Frank
Hallo Werner,
danke für die Hilfestellung, zu der ich Anmerkungen / Nachfragen habe.
Nein, die Tabelle ist nicht statisch positioniert. Ich war so frei, dafür Parameter zu definieren, damit ich diese unzähligen Bezüge nicht immer einzeln anpassen muss. In einer Variable schreibe ich aktuell: "FR = LR + 2"
Die erste Zeile steht also in LR (letzte Zeile des Datenbereichs, hier 64) + 2 = 66.
Ändere ich die 2 in 3, rückt sie eine Zeile tiefer. Das gleiche gilt für die Spalte. Derzeit steht im Code: "FC = 2"
Die Tabelle beginnt also in Spalte 2 / B. Ändere ich es, beginnt sie eben in A oder C oder D, oder wo immer ich es will.
Alle statischen Text-Elemente und Formatierungen der Tabelle arbeiten ja mit errechneten Bezügen wie dem hier: "Cells(FR + 2, FC + 2)"
Sie passen sich dadurch entsprechend auf die Definition der linken oberen Ecke am Beginn des Codes an. Hat ein paar Durchläufe gedauert, bis alles passte, aber nun ist es "schön". Jetzt muss das auch noch mit den Formeln klappen...
Ausgehend von Deinen Erläuterungen habe ich mir nun überlegt, wie ich unter allen Positionen den korrekten Abstand von den Zellen mit den Formeln zu dem Bereich, auf den sie sich jeweils beziehen sollen, bekomme. Das Ergebnis war für die erste Formel folgendes:
* Die Zielspalte F ist 6. Spalte
* Formel #1 steht zwei Spalten weiter rechts von der linken obersten Zelle der Tabelle, also in FC + 2
* Abstand ermitteln: 6 - (FC + 2)
* Test #1: FC = 2 --> Formel in Spalte 4 (D), Abstand: 6 - (2 + 2) = 2 (D auf F sind 2 --> ok)
* Test #2: FC = 6 --> Formel in Spalte 8 (H), Abstand: 6 - (6 + 2) = -2 (H auf F sind -2 --> ok)
In der Theorie geht es zumindest mal auf - nicht schlecht... Also habe ich eine entsprechende Variable definiert und die Formel zugewiesen: "CF1F1 = 6 - (FC + 2)"
Ich hatte mich schon auf den Durchbruch gefreut und die Bezüge in der ersten Matrixformel ersetzt, statt:
Cells(FR + 1, FC + 2).FormulaArray = "=MIN(IF(R[-65]C[2]:R[-3]C[2]<0,R[-65]C[2]:R[-3]C[2]))"
steht nun also dies im Code:
Cells(FR + 1, FC + 2).FormulaArray = "=MIN(IF(R[-65]C[CF1Z1]:R[-3]C[CF1Z1]<0,R[-65]C[CF1Z1]:R[-3]C[CF1Z1]))"
Wenn es mit der Spalte klappt, klappt es auch mit der Zeile und wenn es mit einer Formel klappt, klappt es auch mit den anderen, würde ich meinen. Leider spielt Excel aber nicht mit, denn ich bekomme einen "Laufzeitfehler 1004 - Die FormularArray-Eigenschaft des Range-Objektes kann nicht festgelegt werden."
Ich hatte FC auf 2 stehen, also der Standard-Position und die neue Variable CF1F1 wird auch korrekt mit 2 berechnet, zeigt mir der VBA-Editor im Debug-Modus. Es gibt zwei Möglichkeiten:
* Ich habe einen Fehler bei der Ersetzung der Formelbestandteile gemacht.
* Excel / VBA unterstützt keine Variablen in einer solchen Formel.
Hast Du eine gute Idee oder einen Hinweis? Danke!
Viele Grüße
Frank
Anzeige
AW: Matrixformel mit relativen Bezügen
23.10.2017 08:23:48
Luschi
Hallo Frank,
sie Formel wird ja als String an FormulaArray übergeben; also kann man sie auch stückchenweise als String zusammensetzen:
Dim formel As String
formel = "=MIN(IF(R[-65]C[" & CF1Z1 & "]:R[-3]C[" & CF1Z1 & "]"
Cells(FR + 1, FC + 2).FormulaArray = formel
Desselbe muß man nun noch für die Zeile R[-65] und R[-3] machen.
In der Vba-Hilfe ist aber auch ein Beispiel genannt, so das die sogenannte A1-Schreibweise möglich ist, siehe:
https://msdn.microsoft.com/de-de/VBA/Excel-VBA/articles/range-formulaarray-property-excel
Gruß von Luschi
aus klein-Paris
Anzeige

299 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige