Microsoft Excel

Herbers Excel/VBA-Archiv

If-Funktion | Herbers Excel-Forum


Betrifft: If-Funktion von: Rocco
Geschrieben am: 25.01.2010 09:41:12

hallo leute,

brauche leider wiedermal hilfe, da ich nicht alleine weiterkomme.

habe ein excel file mit dem reporting der firma.

möchte nun alle zeilen mit dem farbindex 35 und dem wert in spalte AC "Ist-2009" löschen

folgende funktion hab ich mir gestrickt:

Dim zelle As range
For Each zelle In Sheets("flat").range("a4:ag" & Cells(Rows.Count, 1).End(xlUp).Row)
If zelle.Interior.ColorIndex = 35 And zelle = "Ist-2009" Then
zelle.EntireRow.delete
End If
Next zelle
das klappt auch ganz gut, außer dass excel einfach nach einer unbestimmten anzahl einfach aufhört zellen zu löschen. also es werden lediglich so etwa 20-30 zellen erfolgreich gelöscht und dann hört excel einfach auf. ich weiss aber nicht wieso.

jetzt hab ich einfach mal ein paar weitere IF-Funktionen angehängt:
  For Each zelle In Sheets("flat").range("a4:ag" & Cells(Rows.Count, 1).End(xlUp).Row)
  If zelle.Interior.ColorIndex = 35 And zelle = "Ist-2009" Then
  zelle.EntireRow.delete
  End If
  Next zelle 

.
.
.

doch 15 Mal die selbe IF-Funktion...? da muss ja irgendwas nicht stimmen oder?
vielleicht weiss ja einer von euch rat??

vielen dank
LG
rocco

  

Betrifft: Spalte AC wird nirgendwo direkt angesprochen! orT von: Luc:-?
Geschrieben am: 25.01.2010 09:48:14

Gruß Luc :-?


  

Betrifft: AW: If-Funktion von: Rocco
Geschrieben am: 25.01.2010 10:02:56

stimmt, aber müsste excel es nicht innerhalb der range("a4:ag".. finden?

oder muss ich ihm direkt die spalte AC angeben? bzw. wie würd ich das machen?


  

Betrifft: Wenn du mit einem Wert aus dieser Spalte direkt... von: Luc:-?
Geschrieben am: 25.01.2010 10:57:17

...vgl willst, Rocco,
musst du den auch direkt ansprechen, sonst dauert das alles nur länger und klappt auch nur, wenn dieser Wert nur in dieser Spalte auftaucht...

With Sheets("flat")
    For Each zelle In .Range("a4:ag" & .Cells(.Rows.Count, 1).End(xlUp).Row)
        If zelle.Interior.ColorIndex = 35 And .Cells(zelle.Row, 29) = "Ist-2009" Then
            zelle.EntireRow.Delete
        End If
    Next zelle
End With
Falls es Probleme mit dem Zyklus durch das fortwährende Löschen von Zeilen geben sollte, müsstest du die andere For-Variante wählen. Dessen Laufvariable könntest du nämlich nach jedem Löschen um 1 vermindern, damit auch tatsächlich mit der nächsten, nicht übernächsten Zeile fortgefahren wird. Außerdem ist dann eine Variable mitzuführen, die die Endzeile angibt. Die ist dann natürlich ebenfalls zu vermindern und bei jedem Durchlauf abzufragen, ob ihr Wert überschritten ist. Das Letztere könn-/solltest du allerdingings auch in den obigen Zyklus einbauen. Ist der Endwert überschritten (Platzierung noch vor dem Löschen in der Schleife), dann Exit For.
Gruß Luc :-?


  

Betrifft: AW: Wenn du mit einem Wert aus dieser Spalte direkt... von: Rocco
Geschrieben am: 25.01.2010 18:24:00

hallo luc,

vielen dank schonmal für die hilfe.
dein code funktioniert, aber leider nicht 100%ig! er dürfte wie du geschrieben hast wohl zeilen überspringen.
weisst du wie man dem entgehen könnte? bzw. wie die funktion dann aussehen müsste?

LG
rocco


  

Betrifft: So, dann nehmen wir mal den letzten... von: Luc:-?
Geschrieben am: 26.01.2010 00:23:40

...Code, Rocco,
und bauen darum herum einen Zeilenzyklus und eine Abbruchvariable ein...

Const vorzl As Long = 3, vglsp As Long = 29, anfsp As Long = 1, endsp As Long = 33
Dim bzanz As Long, zz As Long, bereich As Range, zelle As Range
With Sheets("flat")
    Set bereich = .Range(.Cells(vorzl + 1, anfsp), _
                  .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, endsp))
    bzanz = bereich.Rows.Count
    For zz = 1 To bzanz
        If zz > bzanz Then Exit For
        If .Cells(vorzl + zz, vglsp) = "Ist-2009" Then
            For Each zelle In bereich.Rows(zz)
                If zelle.Interior.ColorIndex = 35 Then
                    zelle.Row.EntireRow.Delete: bzanz = bzanz - 1: zz = zz - 1: Exit For
                End If
            Next zelle
        End If
    Next zz
End With
Set bereich = Nothing: Set zelle = Nothing
Das ist so notwendig, weil sich der äußere Zyklus nicht selbst korrigiert. Der Wert der Endvariablen bzanz wird nur 1x am Anfang zyklusrelevant festgestellt. Die späteren Verminderungen wdn von der Zyklusregie ignoriert. Deshalb muss der Abbruch am Anfang rein — die Schleife läuft sonst sinnlos weiter bis zz den ursprgl Wert von bzanz erreicht hat. Die Konstanten am Anfang erleichtern evtl spätere Korrekturen. Man muss nicht das ganze Pgm durchsuchen, wenn die sich mal ändern sollten...
Am PgmEnde bzw, wenn sie nicht mehr gebraucht wdn, gibt man Objektvariablen frei. Bei Objekten als Laufvariable in Zyklen wäre das nicht notwendig, wenn der Zyklus zu einem normalen Ende kommt. Da er hier aber idR abgebrochen wird, bleibt die Variable zelle weiter besetzt und muss deshalb auch Nothing gesetzt wdn.
Gruß Luc :-?


  

Betrifft: AW: So, dann nehmen wir mal den letzten... von: Rocco
Geschrieben am: 26.01.2010 08:42:27

Hi Luc,

wow netter code ;)
vielen dank schonmal, dass du so lieb bist und mir hilfst.
habe von dem code zwar nicht alles verstanden aber so im groben weiss ich was du gemeint hast mit schleife bzw. abbruchvariable einbauen.

habe das nun probiert doch irgendwie dürfte was nicht ganz richtig sein. der makro wird nicht ausgeführt und als fehler wird automatisch in der zeile:

zelle.Row.EntireRow.Delete: bzanz = bzanz - 1: zz = zz - 1: Exit For
das

.Row

markiert. könnte hir evtl. ein fehler drin stecken?


LG
Rocco


  

Betrifft: Ja, halte ich für möglich, weil das irgendwie... von: Luc:-?
Geschrieben am: 26.01.2010 10:39:47

...doppelt gemoppelt ist, Rocco,
hatte ich nur beibehalten, weil's bei dir analog stand und ich am Linux-Rechner saß und gerade wieder sitze. Wenn du .Row. durch . ersetzt und die VBE-Intellisense zeigt dir EntireRow an, funktioniert's ohne .Row...
Gruß Luc :-?


  

Betrifft: Es ist so; ohne .Row! Gruß owT von: Luc:-?
Geschrieben am: 26.01.2010 12:18:50

:-?


  

Betrifft: AW: komisch... von: Rocco
Geschrieben am: 26.01.2010 12:22:15

also irgendwas dürfte da noch nicht so ganz hinhauen.

hab noch ein paar parameter eingefügt aber leider funktioniert der code noch immer nicht :(

Sub test5()

'Parameter aktivieren
    Application.Calculation = xlCalculationManual
    Application.Interactive = False
    Application.ScreenUpdating = False

Const vorzl As Long = 3, vglsp As Long = 29, anfsp As Long = 1, endsp As Long = 33
Dim bzanz As Long, zz As Long, bereich As range, zelle As range
With Sheets("flat")
    Set bereich = .range(.Cells(vorzl + 1, anfsp), _
                  .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, endsp))
    bzanz = bereich.Rows.Count
    For zz = 1 To bzanz
        If zz > bzanz Then Exit For
        If .Cells(vorzl + zz, vglsp) = "Ist-2009" Then
            For Each zelle In bereich.Rows(zz)
                If zelle.Interior.ColorIndex = 35 Then
                    zelle.EntireRow.delete: bzanz = bzanz - 1: zz = zz - 1: Exit For
                End If
            Next zelle
        End If
    Next zz
End With
Set bereich = Nothing: Set zelle = Nothing
    
    'Parameter deaktivieren
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.Interactive = True
    
End Sub

bin ratlos :-(

LG
rocco


  

Betrifft: Also, ich hatte mich weitgehend nach deinem... von: Luc:-?
Geschrieben am: 26.01.2010 13:27:35

...Originalcode gerichtet, Rocco,
würde aber normalerweise Makros, die irgendwas löschen lieber vorher testen. Geht jetzt aber nicht! Muss ich also nochmal durchgehen, da es ja ohnehin ursprgl nicht meinem Pgmierstil entsprach. Üblicherweise lässt man solche Löschschleifen auch von hinten nach vorne durchlaufen (da hat Hajo recht!), also hier von zz = bzanz To 1 Step -1 und braucht dann idR keine Abbruchvariable und keine Zählerverminderung. Wenn das dein Problem lösen sollte, versuch's mal so! Wenn's dann immer noch nicht klappt, müsstest du mal genau sagen, was nicht klappt. Teste dazu mal schrittweise (z.B. Prozedurschritt im Debugger) oder/und setze Haltepkte (Klick auf linken Editorrand bzw Hand-Symbol).
Gruß Luc :-?