Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[VBA] Schleifen über Zeilen

10 views
Skip to first unread message

Holger Schulz

unread,
Dec 25, 2009, 11:02:42 AM12/25/09
to
Hall�le,

ich m�chte eine Funktion schreiben, die zwei Zeilenst�cke als Parameter
�bergeben bekommt, z.B. A1:J1 und A5:J5.

Jetzt m�chte ich eine Schleife �ber eine der Zeilen, sagen wir die
untere, laufen lassen. Wenn dann z.B. f�r den Wert von C5 eine bestimmte
Bedingung erf�llt ist, m�chte ich mit der entsprechenden Zelle der
oberen Zeile, als C1, etwas berechnen.

�bergebe ich jetzt die beiden Zeilen als ParamArray h�ngen die beide in
einem Range zusammen und ich wei� nicht genau, wie ich die in sagen wir
zwei Listen oder �hnliches zerlegen kann.

Ich hoffe meine Ausf�hrungen sind halbwegs verst�ndlich und mir kann
jemand einen Tipp geben. Daf�r w�re ich dankbar.

hs

Andreas Killer

unread,
Dec 26, 2009, 2:01:54 AM12/26/09
to
Holger Schulz schrieb:

> ich m�chte eine Funktion schreiben, die zwei Zeilenst�cke als Parameter
> �bergeben bekommt, z.B. A1:J1 und A5:J5.
>
> Jetzt m�chte ich eine Schleife �ber eine der Zeilen, sagen wir die
> untere, laufen lassen. Wenn dann z.B. f�r den Wert von C5 eine bestimmte
> Bedingung erf�llt ist, m�chte ich mit der entsprechenden Zelle der
> oberen Zeile, als C1, etwas berechnen.

Mit einer UDF wird das nicht gehen, weil eine UDF �bergebene Bereiche
nicht modifizieren darf.

> �bergebe ich jetzt die beiden Zeilen als ParamArray h�ngen die beide in
> einem Range zusammen und ich wei� nicht genau, wie ich die in sagen wir
> zwei Listen oder �hnliches zerlegen kann.

Hier kann ich Dir nicht folgen.

> Ich hoffe meine Ausf�hrungen sind halbwegs verst�ndlich und mir kann
> jemand einen Tipp geben. Daf�r w�re ich dankbar.

Ist recht einfach, man kann ein Range genau wie ein Array ansprechen,
wobei die obere linke Zelle des Range immer die Indices 1,1 hat:

Sub Test()
Dim Bereich1 As Range, I As Long
Set Bereich1 = Range("A1:J1")
Set Bereich2 = Range("A5:J5")

For I = 1 To Bereich1.Columns.Count
If Bereich2(1, I) = 3 Then Bereich1(1, I) = "Hier"
Next
End Sub

Andreas.

Holger Schulz

unread,
Dec 26, 2009, 12:55:40 PM12/26/09
to
Andreas Killer <andreas...@gmx.net> wrote:

> Holger Schulz schrieb:
>
> > ich m�chte eine Funktion schreiben, die zwei Zeilenst�cke als Parameter
> > �bergeben bekommt, z.B. A1:J1 und A5:J5.
> >
> > Jetzt m�chte ich eine Schleife �ber eine der Zeilen, sagen wir die
> > untere, laufen lassen. Wenn dann z.B. f�r den Wert von C5 eine bestimmte
> > Bedingung erf�llt ist, m�chte ich mit der entsprechenden Zelle der
> > oberen Zeile, als C1, etwas berechnen.
> Mit einer UDF wird das nicht gehen, weil eine UDF �bergebene Bereiche
> nicht modifizieren darf.

Nur nebenbei: Was ist UDF? Modifizieren m�chte ich den �bergebenen
Bereich auch nicht, ich m�chte die darin enthalteten Werte lediglich als
Eingaben verwenden.

>
> > �bergebe ich jetzt die beiden Zeilen als ParamArray h�ngen die beide in
> > einem Range zusammen und ich wei� nicht genau, wie ich die in sagen wir
> > zwei Listen oder �hnliches zerlegen kann.
> Hier kann ich Dir nicht folgen.

Der �bergebene Bereich besteht aus zwei Zeilen, ich h�tte gerne jede
dieser beiden Zeilen in einem eigenen Array.

>
> > Ich hoffe meine Ausf�hrungen sind halbwegs verst�ndlich und mir kann
> > jemand einen Tipp geben. Daf�r w�re ich dankbar.
> Ist recht einfach, man kann ein Range genau wie ein Array ansprechen,
> wobei die obere linke Zelle des Range immer die Indices 1,1 hat:
>
> Sub Test()
> Dim Bereich1 As Range, I As Long
> Set Bereich1 = Range("A1:J1")
> Set Bereich2 = Range("A5:J5")
>
> For I = 1 To Bereich1.Columns.Count
> If Bereich2(1, I) = 3 Then Bereich1(1, I) = "Hier"
> Next
> End Sub

Dabke f�r das Beispiel. Es hilft mir nur bedingt. Erstens leigen hier
bereits zwei Bereiche vor und zeitens werden diese nicht als Parameter
an die Funktion �bergeben.

Ich m�sste wissen, wie ich von einem �bergebenem ParamArray z.B. Zeilen-
und Spaltenzahl bestimmen kann.

Danke.

hs
>
> Andreas.

Peter Schleif

unread,
Dec 27, 2009, 6:10:47 AM12/27/09
to
Holger Schulz schrieb am 25.12.2009 17:02 Uhr:
>
> ᅵbergebe ich jetzt die beiden Zeilen als ParamArray hᅵngen die beide in
> einem Range zusammen und ich weiᅵ nicht genau, wie ich die in sagen wir
> zwei Listen oder ᅵhnliches zerlegen kann.

Vielleicht suchst Du ja die Eigenschaft .Areas die jeder Bereich in VBA
hat: Eine 1-basierte Collection der Teil-Bereiche. Bei nicht
zusammenhᅵngenden Bereichen ist Areas.Count >1. Zugriff auf die
Teil-Bereiche bekommst Du mit Areas(1), Areas(2), usw. Das sind dann
wieder normale Range-Objekte, die Du mit einer Schleife durchlaufen
kannst. Mir ist nicht klar, was Du machen willst. Daher steht unten mal
ein allgemeines Beispiel.

Peter


Sub test()
ZweiBereiche Union([A1:J1], [A5:J5])
End Sub

Sub ZweiBereiche(r As Range)
Dim s As Integer

If r.Areas.Count < 2 Then
MsgBox "zu wenige Teil-Bereiche"
Exit Sub
End If

For s = 1 To r.Areas(2).Columns.Count
If s > r.Areas(1).Columns.Count Then
MsgBox "Ende von Bereich 1 erreicht"
Exit For
End If

If r.Areas(2)(1,s) = "x" Then
r.Areas(1)(1,s).Interior.ColorIndex = 3
End If
Next
End Sub

Thomas Ramel

unread,
Dec 27, 2009, 6:20:06 AM12/27/09
to
Gr嚙箴zi Holger

Holger Schulz schrieb am 25.12.2009

> ich m嚙箱hte eine Funktion schreiben, die zwei Zeilenst嚙箱ke als Parameter
> 嚙箭ergeben bekommt, z.B. A1:J1 und A5:J5.
>
> Jetzt m嚙箱hte ich eine Schleife 嚙箭er eine der Zeilen, sagen wir die
> untere, laufen lassen. Wenn dann z.B. f嚙緝 den Wert von C5 eine bestimmte
> Bedingung erf嚙締lt ist, m嚙箱hte ich mit der entsprechenden Zelle der


> oberen Zeile, als C1, etwas berechnen.
>

> 嚙箭ergebe ich jetzt die beiden Zeilen als ParamArray h嚙緯gen die beide in
> einem Range zusammen und ich wei嚙�nicht genau, wie ich die in sagen wir
> zwei Listen oder 嚙篁nliches zerlegen kann.

Warum 嚙箭ergibst Du die beiden Bereiche nicht getrennt?

Die folgenden Zeilen berechnen die Summe der Werte im ersten Bereich wenn
dieselbe Zelle im zweiten Bereich >1 ist:

Public Function tr(Bereich1 As Range, Bereich2 As Range)
Dim lngZelle As Long
Dim dblSum As Double
For lngZelle = 1 To Bereich2.Cells.Count
If Bereich2(lngZelle).Value > 1 Then
dblSum = dblSum + Bereich1(lngZelle).Value
End If
Next lngZelle
tr = dblSum
End Function


Mit freundlichen Gr嚙編sen
Thomas Ramel

--
- MVP f嚙緝 Microsoft-Excel -
[Vista Ultimate SP-1 / xl2007 SP-1]

Holger Schulz

unread,
Dec 27, 2009, 7:30:10 AM12/27/09
to
Thomas Ramel <t.r...@MVPs.org> wrote:

> Gr�ezi Holger

>
> Holger Schulz schrieb am 25.12.2009
>

> > ich m�chte eine Funktion schreiben, die zwei Zeilenst�cke als Parameter
> > �bergeben bekommt, z.B. A1:J1 und A5:J5.
> >
> > Jetzt m�chte ich eine Schleife �ber eine der Zeilen, sagen wir die
> > untere, laufen lassen. Wenn dann z.B. f�r den Wert von C5 eine bestimmte

> > Bedingung erf�llt ist, m�chte ich mit der entsprechenden Zelle der


> > oberen Zeile, als C1, etwas berechnen.
> >

> > �bergebe ich jetzt die beiden Zeilen als ParamArray h�ngen die beide in
> > einem Range zusammen und ich wei� nicht genau, wie ich die in sagen wir
> > zwei Listen oder �hnliches zerlegen kann.
>
> Warum �bergibst Du die beiden Bereiche nicht getrennt?

Das habe ich mich dann auch gefragt. Wom�glich, weil ich Ranges und
ParamArrays durcheinander geworfen habe.


>
> Die folgenden Zeilen berechnen die Summe der Werte im ersten Bereich wenn
> dieselbe Zelle im zweiten Bereich >1 ist:

Das ist so ziemlich das, was ich suche. Wenn man erst mal wei�, was man
sucht, findet's sich nochmal so leicht.

Vielen Dank, auch an Peter und Andreas.

hs

Bernd P

unread,
Dec 27, 2009, 7:45:39 AM12/27/09
to
Hallo Holger,

Vielleicht helfen am besten einige UDF (user defined functions =
benutzerdefinierte Funktionen) Beispiele:
http://sulprobil.com/html/listfreq.html

Ansonsten wären für uns ein oder zwei genaue Rechenbeispiele (was Du
erreichen möchtest) gut.

Dass Du keine Eingabebereiche überschreiben willst, halte ich für
sinnvoll (sonst entsteht leicht ein Rekursionsproblem: was soll
geschehen, wenn die Berechnung mehrfach durchgeführt wird?).

Viele Grüße,
Bernd

Andreas Killer

unread,
Dec 28, 2009, 3:53:44 AM12/28/09
to
Holger Schulz schrieb:

>> Mit einer UDF wird das nicht gehen, weil eine UDF �bergebene Bereiche
>> nicht modifizieren darf.
> Nur nebenbei: Was ist UDF? Modifizieren m�chte ich den �bergebenen

Entschuldigung, UDF ist "Excel-Slang": User Defined Function

Also eine benutzerdefinierte Funktion. In der Regel wird so ein Makro,
welches den Prozedurtyp Function haben muss, bezeichnet das in einem
Tabellenblatt aufgerufen werden kann.

> Bereich auch nicht, ich m�chte die darin enthalteten Werte lediglich als
> Eingaben verwenden.

Dann ist das Okay wenn Du das Ergebnis �ber die UDF zur�ckgibst.

>>> �bergebe ich jetzt die beiden Zeilen als ParamArray h�ngen die beide in
>>> einem Range zusammen und ich wei� nicht genau, wie ich die in sagen wir
>>> zwei Listen oder �hnliches zerlegen kann.
>> Hier kann ich Dir nicht folgen.
> Der �bergebene Bereich besteht aus zwei Zeilen, ich h�tte gerne jede
> dieser beiden Zeilen in einem eigenen Array.

Wenn Du nur 2 Zeilen �bergeben m�chtest, dann ist es sinnvoller diese
zwangsweise abzufordern:

function MyTest(Bereich1 as Range, Bereich2 as Range) as Variant
dim I as Long


For I = 1 To Bereich1.Columns.Count

If Bereich1(1, I) = 3 Then
MyTest = Bereich2(1, I)
Exit Function
End If
Next
end function

Somit wirst Du bei der Eingabe der Formel im Tabellenblatt
=MyTest(A1:J1;A5:J5)
zur �bergabe der beiden Bereiche gezwungen.

Wenn Du die Bereiche �ber ein ParamArray �bergibst geht das zwar auch

Function MyTest2(ParamArray Bereich()) As Variant
Dim I As Long
For I = 1 To Bereich(1).Columns.Count
If Bereich(1)(1, I) = 3 Then
MyTest2 = Bereich(2)(1, I)
Exit Function
End If
Next
End Function

jedoch ist das schon bei der Eingabe irref�hrend, weil dann Excel auch
A10 =MyTest2() '#WERT!
A10 =MyTest2(A1:J1;A2:J2;A3:J3;A4:J4) '0
als g�ltige Eingabe akzeptiert.

Und in der UDF m�sstest Du pr�fen ob �berhaupt und wieviele Parameter
�bergeben wurden und zus�tzlich ob das �berhaupt Bereiche
(Zelle/Range) sind, da ParamArray leider keine Typisierung ala
Function MyTest(ParamArray Bereich() as Range ) As Variant
erlaubt.

> Ich m�sste wissen, wie ich von einem �bergebenem ParamArray z.B. Zeilen-
> und Spaltenzahl bestimmen kann.

Das hat nichts mit einem ParamArray zu tun, ein ParamArray erlaubt
einfach gesagt die �bergabe einer beliebigen Anzahl von Argumenten.

Wenn Du erzwingen m�chtest das Du einen Zellbereich �bergeben
bekommst, dann definiere das Argument "as Range". Nun kann man zwar
trotzdem im Tabellenblatt =MyTest(1;2) eingeben, bekommt aber sofort
den Fehler #WERT! zur�ck und der Code der UDF wird nicht ausgef�hrt,
da Excel selber erkennt die Argumente keine Bereiche sind.

Wenn nun Bereiche �bergeben wurden, dann kann man diesen sehr einfach
pr�fen, weil
a.) man immer einen 2dimensionalen Bereich (Array) bekommt
b.) dieser immer bei Bereich(1,1) anf�ngt
c.) immer bis Bereich(Bereich.Rows.Count, Bereich.Columns.Count) geht

Anzahl Zeilen = Bereich.Rows.Count, Spalten = Bereich.Columns.Count

Jetzt bleibt eigentlich nur noch die Frage was macht man die beiden
Bereiche gepr�ft und festgestellt hat das sie unterschiedlich gro�
sind: Einen Fehler mit CVErr() zur�ckgeben.

Excel hat hier ein paar vordefinierte Konstanten f�r Fehlerwerte:

'xlErrDiv0 = "#DIV/0!"
'xlErrNA = "#NV"
'xlErrName = "#NAME?"
'xlErrNull = "#NULL!"
'xlErrNum = "#ZAHL!"
'xlErrRef = "#BEZUG!"
'xlErrValue = "#WERT!"

Function MyTest(Bereich1 As Range, Bereich2 As Range) As Variant
Dim I As Long, J As Long

If Bereich1.Rows.Count <> Bereich2.Rows.Count Or _
Bereich1.Columns.Count <> Bereich2.Columns.Count Then
MyTest = CVErr(xlErrRef)
Exit Function
End If

For J = 1 To Bereich1.Rows.Count


For I = 1 To Bereich1.Columns.Count

If Bereich1(J, I) = 3 Then
MyTest = Bereich2(J, I)
Exit Function
End If
Next
Next
End Function

Ich denke nun sollte einiges klarer sein. Noch Fragen?

Andreas.

0 new messages