Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
788to792
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
788to792
788to792
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Alle farbigen Zellen addieren

Alle farbigen Zellen addieren
07.08.2006 16:20:01
Tom
Hallo,
ich habe mit bedingter Formatierung einige Zellen gelb hinterlegt (bei Eingabe bei Zelle XY wird Zelle XY2 gelb usw).
Wie kann ich nun erreichen, dass in Zelle X13 alle gelb hinterlegten Zellen (D20:Z60) automatisch addiert werden?
Danke vorab
Tom

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Alle farbigen Zellen addieren
07.08.2006 16:30:25
harry
Hallo Tom,
for spalte=4 to 26
for zeile=20 to 60
if cells(zeile,spalte).interior.colorindex=6 then summe=summe+cells(zeile,spalte)
next
next
range("x13").value=summe
AW: Alle farbigen Zellen addieren
07.08.2006 16:34:25
Andi
Hi,
interior.colorindex hilft leider nicht weiter, wenn die Farbe über die bedingte Formatierung zustande kommt. In dem Fall die Farbe auszulesen ist weitaus komplizierter als in der Summe einfach die gleiche Bedingung nochmal zu verwenden, egal ob in der Formel oder im Makro.
Schönen Gruß,
Andi
AW: Alle farbigen Zellen addieren
07.08.2006 16:35:04
Tom
Hallo Harry,
kannst Du mir den kompletten Code angeben?
Ich bin leider nur mit Makrorekorder bewandert ...
Danke Tom
Anzeige
AW: Alle farbigen Zellen addieren
07.08.2006 16:44:11
Andi
Hi,
wie ich schon schrieb, wird Dir der komplette Code von Harry nix bringen, weil interior.colorindex bei bedingter Formatierung schlicht in den Wald führt.
Hier:
https://www.herber.de/forum/archiv/484to488/t485111.htm
ist folgender Code gepostet, der aber wohlgemerkt nur dazu dient die Zellfarbe auszulesen, sprich nur die beiden Worte interior.colorindex in Harrys Code ersetzt (hab's nicht getestet):

Function GetCellColor(cell As Range) As Integer
' Von Bernd bstrohhaecker@gmx.de
Dim i
Dim myVal
Dim myColor As Integer
Dim done As Boolean
On Error Resume Next
Names("testname").Delete
On Error GoTo 0
Application.ReferenceStyle = xlR1C1
myVal = cell.Value
myColor = cell.Interior.ColorIndex
done = False
For i = 1 To cell.FormatConditions.Count
With cell.FormatConditions.Item(i)
If .Type = 1 Then
Select Case .Operator
Case xlBetween
If myVal >= Evaluate(.Formula1) And myVal <= Evaluate(.Formula2) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlEqual
If myVal = Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlGreater
If myVal > Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlGreaterEqual
If myVal >= Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlLess
If myVal < Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlLessEqual
If myVal <= Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlNotBetween
If myVal < Evaluate(.Formula1) Or myVal > Evaluate(.Formula2) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlNotEqual
If myVal <> Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
End Select
ElseIf .Type = 2 Then
Names.Add Name:="testname", RefersToR1C1Local:=.Formula1
If Evaluate("testname") Then
myColor = .Interior.ColorIndex
done = True
End If
Names("testname").Delete
Else
MsgBox "Unbekannter Typ: " & .Type, , "PANIC: In 

Function GetCellColor"
Exit Function
End If
End With
If done Then Exit For
Next
Application.ReferenceStyle = xlA1
GetCellColor = myColor
End Function

Ob dies bei 'VBA nur mit Recorder' ein gangbarer Weg ist, wage ich zu bezweifeln...
Wie gesagt, frage die Bedigungen selbst ab, statt der Farbe.
Schönen Gruß,
Andi
Anzeige
Lösung
07.08.2006 17:04:13
Andi
Hi,
ich hab Dir mal basierend auf dem oben geposteten Code von Bernd eine Lösung gebastelt;
kopiere folgendes in ein Standard-Modul (kannst Du im VB-Editor unter Einfügen, Modul erzeugen). Du kannst dann in Deiner Tabelle die Funktion BedFarbsumme verwenden wie jede andere Funktion. Also so:
=BedFarbsumme(D20:Z60).

Function BedFarbsumme(bereich As Range)
Application.Volatile
Dim c As Range
For Each c In bereich
If GetCellColor(c) = 6 Then BedFarbsumme = BedFarbsumme + c.Value
Next c
End Function


Function GetCellColor(cell As Range) As Integer
' Von Bernd bstrohhaecker@gmx.de
Dim i
Dim myVal
Dim myColor As Integer
Dim done As Boolean
On Error Resume Next
Names("testname").Delete
On Error GoTo 0
Application.ReferenceStyle = xlR1C1
myVal = cell.Value
myColor = cell.Interior.ColorIndex
done = False
For i = 1 To cell.FormatConditions.Count
With cell.FormatConditions.Item(i)
If .Type = 1 Then
Select Case .Operator
Case xlBetween
If myVal >= Evaluate(.Formula1) And myVal <= Evaluate(.Formula2) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlEqual
If myVal = Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlGreater
If myVal > Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlGreaterEqual
If myVal >= Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlLess
If myVal < Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlLessEqual
If myVal <= Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlNotBetween
If myVal < Evaluate(.Formula1) Or myVal > Evaluate(.Formula2) Then
myColor = .Interior.ColorIndex
done = True
End If
Case xlNotEqual
If myVal <> Evaluate(.Formula1) Then
myColor = .Interior.ColorIndex
done = True
End If
End Select
ElseIf .Type = 2 Then
Names.Add Name:="testname", RefersToR1C1Local:=.Formula1
If Evaluate("testname") Then
myColor = .Interior.ColorIndex
done = True
End If
Names("testname").Delete
Else
MsgBox "Unbekannter Typ: " & .Type, , "PANIC: In 

Function GetCellColor"
Exit Function
End If
End With
If done Then Exit For
Next
Application.ReferenceStyle = xlA1
GetCellColor = myColor
End Function

Schönen Gruß,
Andi
Anzeige
AW: Alle farbigen Zellen addieren
07.08.2006 16:30:45
Andi
Hi,
einfacher isses, wenn Du nicht nach der Farbe gehst, sondern nach der Bedingung abfragst, die auch in der bedingten Formatierung verwendest. Die passende Funktion wäre SUMMEWENN
Schönen Gruß,
Andi
AW: Alle farbigen Zellen addieren
07.08.2006 16:33:35
Tom
Hi Andi,
es sind zu verschiedene Funktionen hinterlegt...
Ich habe diese Funktion schon einmal gesehen - leider finde ich in der Recherche nix ...
Frage daher noch offen
TOM
AW: Alle farbigen Zellen addieren
07.08.2006 21:57:56
bst
Abend auch,
das Teil war von mir. Mittlerweile habe ich es zwar etwas verbessert, aber es funktioniert immer noch NICHT in allen Situationen. Besonders häufig Ärger gibt's mit Namen...
Ich bezweifle mittlerweile stark, daß man es überhaupt in VBA lösen kann ;-)
Als Alternative könntest Du sowas probieren:
Schwimmer kopiert die Zelle als Bitmap in die Zwischenablage und zählt dann Pixel: http://michael-schwimmer.de/xlMain.htm (Nr. 82)
Zu unten stehendem Code siehe auch: http://www.office-loesung.de/ftopic73290_15_0_asc.php
Übrigens, das Teil funktioniert NICHT als UDF.
cu, Bernd
--
Option Explicit

Sub TestIt()
    MsgBox GetCFColor(ActiveCell), vbInformation, "Die Farbe der Zelle ist"
End Sub

Function GetCFColor(cell As Range, Optional OfText As Boolean = False) As Integer
    Dim CFCond As Integer
    
    ' Defaultwert festlegen
    GetCFColor = IIf(OfText, cell.Font.ColorIndex, cell.Interior.ColorIndex)
    
    CFCond = GetCFCondition(cell)
    If CFCond Then
        If OfText Then
            ' hmm, falls niemals solch ein Teil zugewiesen wurde steht hier halt noch NULL
            On Error Resume Next
            GetCFColor = cell.FormatConditions(CFCond).Font.ColorIndex
            On Error GoTo 0
        Else
            GetCFColor = cell.FormatConditions(CFCond).Interior.ColorIndex
        End If
    End If
End Function

Function GetCFCondition(cell As Range) As Integer
    Dim mycell As Range
    Dim myVal, myVal_1, myVal_2
    Dim i As Integer
    Dim done As Boolean
    
    GetCFCondition = 0
    Set mycell = cell(1) ' falls es mehrere Zellen sind, die 1. davon nehmen
    mycell.Select ' der muß wohl leider sein, :-(
    myVal = mycell.Value ' Der Wert der Zelle
    
    For i = 1 To cell.FormatConditions.Count
        With cell.FormatConditions.Item(i)
            myVal_1 = GetCFVal(mycell, .Formula1)
            If .Type = 1 Then
            If .Operator = xlBetween Or .Operator = xlNotBetween Then _
                myVal_2 = GetCFVal(mycell, .Formula2)
            End If
            ' Hier erfolgt dann die eigentliche Unterscheidung
            If .Type = 1 Then
                Select Case .Operator
                    Case xlBetween
                        done = (myVal >= myVal_1 And myVal <= myVal_2) Or _
                        (myVal >= myVal_2 And myVal <= myVal_1)
                    Case xlEqual
                        done = myVal = myVal_1
                    Case xlGreater
                        done = myVal > myVal_1
                    Case xlGreaterEqual
                        done = myVal >= myVal_1
                    Case xlLess
                        done = myVal < myVal_1
                    Case xlLessEqual
                        done = myVal <= myVal_1
                    Case xlNotBetween
                        done = (myVal < myVal_1 And myVal < myVal_2) Or _
                        (myVal > myVal_1 And myVal > myVal_2)
                    Case xlNotEqual
                        done = myVal <> myVal_1
                    Case Else
                        MsgBox "Unbekannter Operator: " & .Operator, , "PANIC: In Function GetCFCondition"
                        Exit Function
                End Select
                ElseIf .Type = 2 Then
                done = myVal_1 = True
            Else
                MsgBox "Unbekannter Typ: " & .Type, , "PANIC: In Function GetCFCondition"
                Exit Function
            End If
            On Error GoTo 0
            If done Then ' wir haben fertig
                GetCFCondition = i
                Exit Function
            End If
        End With
    Next
End Function
'
' Versucht den Wert der Formel der bedingten Formatierung (CF) zu bestimmen.
'
' Das funktioniert aber NICHT immer !!!
'
' Zuerst wird versucht mit Evaluate die Formel zu berechnen. Falls das nicht ging wird die Formel der
' bedingten Formatierung in die Zellformel kopiert und dieses ausgewertet
'
' Evaluate() funktioniert wohl nicht mit relativen Bezügen in anderen Namen, ZEILE(), SPALTE(), etc. ?
'
' Bsp für Namen: Setze Cursor nach B2, definiere abc als =A1 (OHNE $ !), schreibe in Zelle D4 =abc und schaue
' von dort aus mal nach wie denn abc definiert ist. Nimm sowas mal in eine CF auf.
'
' triviale Beispiele für Zeile/Spalte: =ZEILE() bzw =SPALTE(A6), beide gehen schon nicht.
'
' Das Umbiegen der CF-Formel in die Zellen-Formel geht nicht falls sich die CF-Formel auf die Zelle selber bezieht
'
' Beispiel:
' Formel in Zelle A6: =ZEILE(A5), CF in Zelle A6: Formel ist: =(A6=ZEILE()-1)=WAHR
'
' Und funktioniert so wohl noch NICHT mit den schrecklichen NAMEN !!!
'
Function GetCFVal(mycell As Range, formula As String) As Variant
    Dim ev, f$, fa$, myVal
    
    On Error Resume Next
    ' 1. Versuch via Evaluate(Name)
    Application.ReferenceStyle = xlR1C1
    Names.Add Name:="cfTestName", RefersToR1C1Local:=formula
    ev = Evaluate("cfTestName")
    Names("cfTestName").Delete
    Application.ReferenceStyle = xlA1
    
    Select Case TypeName(ev) ' ist wohl aus der Kategorie dubios ;-)
        Case "Variant()", "Error", "Empty": ' Es hat wohl nicht funktioniert, 2. Versuch
            myVal = mycell.Value
            If mycell.HasArray Then
                fa = mycell.FormulaArray
                f = ""
            Else
                fa = ""
                f = mycell.formula
            End If
            mycell.formula = "" ' der macht manchmal schon Sinn
            mycell.FormulaLocal = formula
            GetCFVal = mycell.Value ' Es gibt zwar noch Hoffnung, aber ... :-(
            If f = "" Then
                mycell.FormulaArray = fa
            Else
                mycell.formula = f
            End If
        Case Else: GetCFVal = ev ' Hurra, es hat funktioniert :-)
    End Select
    On Error GoTo 0
End Function

Anzeige
AW: Alle farbigen Zellen addieren
08.08.2006 13:21:43
Andi
Hi,
nachdem Tom sich ja offenbar aus dem thread verabschiedet hat, zumindest von mir vielen Dank für Deine Ergänzungen.
Schönen Gruß,
Andi
AW: Alle farbigen Zellen addieren
09.08.2006 08:08:49
Tom
Hi,
sorry ich war geschäftlich unterwegs - werde die für mich beste Lösung aussuchen.
Vielen Dank an alle!!!!
Gruß
TOM
Nachtrag: Alle farbigen Zellen addieren
09.08.2006 15:26:28
bst
Hallo,
mir ist da leider ein ziemlich dummer Fehler unterlaufen.
Die hier gepostete Version ist auch ein älteres Teil und enthält zudem noch einen Fehler.
Der Trick mit dem Übersetzen der Formel mit Hilfe eines Namens funktioniert hier nicht.
Dieses wird zwar dann (meistens) im 2. Versuch korrigiert, ist aber trotzdem daneben :-(
Anbei die aktuelle Version, die leider immer noch nicht alle Fälle erschlägt ...
Diese findet sich übrigens auch hier: http://home.media-n.de/ziplies/
Sorry und mea culpa,
Bernd
--
Option Explicit

Sub Test_aktuelle_Zelle()
    MsgBox GetCFColor(ActiveCell), vbInformation, "Die Farbe der Zelle ist"
End Sub

Function GetCFColor(cell As Range, Optional OfText As Boolean = False) As Integer
    Dim CFCond As Integer
    
    ' Defaultwert festlegen
    GetCFColor = IIf(OfText, cell.Font.ColorIndex, cell.Interior.ColorIndex)
    
    CFCond = GetCFCondition(cell)
    If CFCond Then
        If OfText Then
            ' hmm, falls niemals solch ein Teil zugewiesen wurde steht hier halt noch NULL
            On Error Resume Next
            GetCFColor = cell.FormatConditions(CFCond).Font.ColorIndex
            On Error GoTo 0
        Else
            GetCFColor = cell.FormatConditions(CFCond).Interior.ColorIndex
        End If
    End If
End Function

Function GetCFCondition(cell As Range) As Integer
    Dim mycell As Range
    Dim myVal, myVal_1, myVal_2
    Dim i As Integer
    Dim done As Boolean
    
    GetCFCondition = 0
    Set mycell = cell(1) ' falls es mehrere Zellen sind, die 1. davon nehmen
    mycell.Select ' der muß wohl leider sein, :-(
    myVal = mycell.Value ' Der Wert der Zelle
    
    For i = 1 To cell.FormatConditions.Count
        With cell.FormatConditions.Item(i)
            myVal_1 = GetCFVal(mycell, cell.FormatConditions.Item(i), False)
            If .Type = 1 Then
                If .Operator = xlBetween Or .Operator = xlNotBetween Then _
                    myVal_2 = GetCFVal(mycell, cell.FormatConditions.Item(i), True)
            End If
            ' Hier erfolgt dann die eigentliche Unterscheidung
            If .Type = 1 Then
                Select Case .Operator
                    Case xlBetween
                        done = (myVal >= myVal_1 And myVal <= myVal_2) Or _
                            (myVal >= myVal_2 And myVal <= myVal_1)
                    Case xlEqual
                        done = myVal = myVal_1
                    Case xlGreater
                        done = myVal > myVal_1
                    Case xlGreaterEqual
                        done = myVal >= myVal_1
                    Case xlLess
                        done = myVal < myVal_1
                    Case xlLessEqual
                        done = myVal <= myVal_1
                    Case xlNotBetween
                        done = (myVal < myVal_1 And myVal < myVal_2) Or _
                            (myVal > myVal_1 And myVal > myVal_2)
                    Case xlNotEqual
                        done = myVal <> myVal_1
                    Case Else
                        MsgBox "Unbekannter Operator: " & .Operator, , "PANIC: In Function GetCFCondition"
                        Exit Function
                End Select
            ElseIf .Type = 2 Then
                done = myVal_1 = True
            Else
                MsgBox "Unbekannter Typ: " & .Type, , "PANIC: In Function GetCFCondition"
                Exit Function
            End If
            On Error GoTo 0
            If done Then ' wir haben fertig
                GetCFCondition = i
                Exit Function
            End If
        End With
    Next
End Function
'
' Versucht den Wert der Formel der bedingten Formatierung (CF) zu bestimmen.
'
' Das funktioniert aber NICHT immer !!!
'
' Zuerst wird einfach die Formel via Cdbl() zugewiesen. Das funktioniert nur für
' ganz normale Zahlen, welche in der CF als String abgelegt sind, z.B.: als "1"
'
' Danach wird versucht mit Evaluate die Formel zu berechnen. Falls das auch nicht
' geht wird die Formel der bedingten Formatierung in die Zellformel kopiert
' und dieses ausgewertet
'
' Evaluate() funktioniert wohl nicht mit relativen Bezügen in anderen Namen, ZEILE(), SPALTE(), etc. ?
'
' Bsp für Namen: Setze Cursor nach B2, definiere abc als =A1 (OHNE $ !), schreibe in Zelle D4 =abc
' und schaue von dort aus mal nach wie denn abc definiert ist. Man tue sowas mal in eine CF-Formel.
'
' triviale Beispiele für Zeile/Spalte: =ZEILE() bzw =SPALTE(A6), beide gehen schon nicht.
' Funny, da hätte ich auch bereits früher draufkommen können, Zeile() bzw Spalte
' liefern ein Array zurück ;-) Entweder 1 oder 2 dimensional ...
'
' Das Umbiegen der CF-Formel in die Zellen-Formel geht nicht immer gut.
' Ein mögliches Problem ist hier das Entstehen eines Zirkelbezuges
'
' Beispiel:
' Formel in Zelle A13: =UNTEN, CF in Zelle A14: Zellwert ist gleich: =OBEN
' wobei OBEN und UNTEN jeweils relativ definierte Namen sind, die auf die
' entsprechende Zelle weisen, d.h. mit aktiver Zelle A2:
' OBEN: =Tabelle1!A1 sowie UNTEN: =Tabelle1!A3
'
' Böse Falle, man kann hier NICHT formula als String übergeben, da dann der Trick
' mit dem Übersetzen via Name hier nicht mehr funktioniert !!!
'
Function GetCFVal(mycell As Range, fc As FormatCondition, bUseFC2 As Boolean) As Variant
    Dim ev, f$, fa$, myVal
    
    On Error Resume Next
    ' 1. Versuch, der geht wenn's denn eine Zahl ist, z.B.: "1.2"
    If bUseFC2 Then
        ev = CDbl(fc.Formula2)
    Else
        ev = CDbl(fc.Formula1)
    End If
    If TypeName(ev) = "Double" Then
        GetCFVal = ev
        Exit Function
    End If
    ' 2. Versuch via Evaluate(Name)
    ' Durch die nächsten 2. Zeilen wird die Deutsche Formel der CF ins Englische übersetzt !
    Application.ReferenceStyle = xlR1C1
    If bUseFC2 Then
        Names.Add Name:="cfTestName", RefersToR1C1Local:=fc.Formula2
    Else
        Names.Add Name:="cfTestName", RefersToR1C1Local:=fc.Formula1
    End If
    ' und jetzt - mit englischer Formel in cfTestName geht Evaluate - nun ja - vielleicht ...
    ev = Evaluate("cfTestName")
    Names("cfTestName").Delete
    Application.ReferenceStyle = xlA1
    
    Select Case TypeName(ev) ' ist wohl aus der Kategorie dubios ;-)
        Case "Variant()": ' Ein Array, schaun wir mal in ev(1)
            ev = ev(1)
            If TypeName(ev) = "Variant()" Then
                GetCFVal = ev(1, 1)
            Else
                GetCFVal = ev
            End If
        Case "Error", "Empty": ' Es hat wohl nicht funktioniert, 3. Versuch
            myVal = mycell.Value
            If mycell.HasArray Then
                fa = mycell.FormulaArray
                f = ""
            Else
                fa = ""
                f = mycell.Formula
            End If
            mycell.Formula = "" ' der macht manchmal schon Sinn
            If bUseFC2 Then
                mycell.FormulaLocal = fc.Formula2
            Else
                mycell.FormulaLocal = fc.Formula1
            End If
            GetCFVal = mycell.Value ' Es gibt zwar noch Hoffnung, aber ... :-(
            ' Falls dieses denn nicht funktionierte, fehlt mir's an Ideen ::--(
            If fa = "" Then
                mycell.Formula = f
            Else
                mycell.FormulaArray = fa
            End If
        Case Else: GetCFVal = ev ' Hurra, es hat funktioniert :-)
    End Select
    On Error GoTo 0
End Function

Function FarbeZählen(Bereich As Range, Farbe As Byte) As Long
    Dim RaC As Range
    
    For Each RaC In Bereich
        If GetCFColor(RaC) = Farbe Then
            FarbeZählen = FarbeZählen + 1
        End If
    Next RaC
End Function

Function FARBSumme(Bereich As Range, Farbe As Byte) As Long
    Dim RaC As Range
    
    For Each RaC In Bereich
        If GetCFColor(RaC) = Farbe Then
            FARBSumme = FARBSumme + RaC.Value
        End If
    Next RaC
End Function



Anzeige

200 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige