Macro doorloopt steeds alle cellen

Status
Niet open voor verdere reacties.

remcop1989

Gebruiker
Lid geworden
29 mrt 2012
Berichten
492
Ik heb een excel document waarin bijgehouden wordt op welke datum een bedrijf teruggebeld moet worden (dit staat in kolom i).
Het document bevat een niet te bepalen aantal rijen. Dit wisselt dagelijks. Zie bijlage voor een voorbeeld.

Ik heb de volgende macro in dit document:

Code:
Private Sub Worksheet_Change(ByVal Target As Range)

For Each i In Range("I2:I500")
For Each j In Range("J2:J500")

If i = "" Then
i.Offset(0, 1) = ""
ElseIf i <= Date Then
i.Offset(0, 1) = "Terugbellen"
End If

Next j
Next i

End Sub

Deze macro loopt bij een wijziging alle rijen door en dat neemt heel veel tijd in beslag. Het document is daardoor niet bruikbaar meer.

Hoe kan ik ervoor zorgen dat hij niet steeds alle rijen doorloopt, maar toch zijn werk goed doet?
 
Het kan nog veel eenvoudiger maar waar gebruik je die J loop voor?
Kolom J wordt in de code niet gebruikt dus heeft die hele loop daar geen zin.
 
Ik heb informatie over dat stukje code moeten opzoeken. Daar stond die J loop bij. Ik zal hem er uit halen.

De code werkt prima. Maar hoe kan hij sneller / eenvoudiger?
 
Ik heb het niet getest, maar probeer dit eens:

Code:
Private Sub Worksheet_Change(ByVal Target As Range)
    
    For i = 2 To Range("I" & Rows.Count).End(xlUp).Row
        If Range("I" & i).Value = "" Then
            Range("J" & i).Value = ""
        ElseIf i <= Date Then
            Range("J" & i).Value = "Terugbellen"
        End If
    Next i

End Sub

Maar moet dat echt gebeuren bij een wijziging in iedere cel of alleen als zo'n cel in een bepaalde kolom staat?
Nu gebeurd dat dus bij iedere wijziging in het werkblad.
 
Laatst bewerkt:
Zodra een cel in kolom i geüpdate wordt en de datum niet meer voldoet aan "<=Date" moet hij kolom j bijwerken.
 
Ik bedoel dat die macro nu bij iedere wijziging in het hele werblad wordt uitgevoerd en dat lijkt me niet de bedoeling.
De vraag is dus op welk moment die macro zijn werk moet gaan doen.
Dat is dus als er een cel in kolom I wijzigt?

*Edit:
Ik heb de macro er alvast op aangepast. Probeer deze maar:

Code:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Rowcount As Integer
    
    Rowcount = Range("I" & Rows.Count).End(xlUp).Row
    If Not Intersect(Target, Range("I1:I" & Rowcount)) Is Nothing Then
        For i = 2 To Rowcount
            Select Case Range("I" & i).Value
                Case ""
                    Range("J" & i).Value = ""
                Case Is <= Date
                    Range("J" & i).Value = "Terugbellen"
            End Select
        Next i
    End If
End Sub
 
Laatst bewerkt:
Alleen als 'ie het goed doet, anders heeft dat zo weinig zin ;)
En moet 'ie echt alle gebruikte regels in kolom I elke keer doorlopen?
 
Laatst bewerkt:
Enkel de regel waarbij cel i is gewijzigd.

De macro moet gaan werken zodra ik in kolom i een datum invoer. Hij moet dan nagaan of die datum vandaag of eerder is (in dit geval "terugbellen" in j vermelden) of dat de datum NA vandaag ligt (in dit geval niets doen).

Als de macro start hoeft hij dat alleen voor de regel te doen waarin cel i is gewijzigd
 
Laatst bewerkt:
Jou laatste stukje code werkte deels.
Als ik namelijk een datum in kolom i weghaalde of aanpaste, dan werkte hij kolom j niet bij.

Ik heb een 3e case toegevoegd en nu doet hij het wel.

Ik begrijp de cases maar half. Kun je mij uitleggen hoe e.e.a. in onderstaande code werkt en wat ermee gedaan wordt? Ik wil hier graag van leren.

Code:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Rowcount As Integer
    
    Rowcount = Range("I" & Rows.Count).End(xlUp).Row
    If Not Intersect(Target, Range("I1:I" & Rowcount)) Is Nothing Then
        For i = 2 To Rowcount
            Select Case Range("I" & i).Value
                Case ""
                    Range("J" & i).Value = ""
                Case Is <= Date
                    Range("J" & i).Value = "Terugbellen"
                Case Is > Date
                    Range("J" & i).Value = ""
            End Select
        Next i
    End If

End Sub
 
Zoals ik al zei werkt hij nu alleen als er een cel in kolom I wordt aangepast.
Dat moet hij dus ook doen bij een aanpassing in kolom J?
Denk eraan dat dit soort dingen erg nauw luistert en een goede uitleg van je wens dus zeer van belang is.
 
Laatst bewerkt:
Nee, kolom j geeft enkel aan dat een bedrijf teruggebeld moet worden.
Kolom j is dus eigenlijk enkel een weergave kolom.
 
Probeer deze dan eens. Als een cel in kolom I wordt aangepast wordt er in kolom J op dezelfde regel het woord "Terugbellen" gezet als de waarde in kolom I een datum is die voor vandaag ligt. In ieder ander geval wordt de cel in kolom J leeg gemaakt.
De loop is eruit omdat deze niet nodig is.

Code:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Rowcount As Integer
    
    Rowcount = Range("I" & Rows.Count).End(xlUp).Row
    If Not Intersect(Target, Range("I1:I" & Rowcount)) Is Nothing Then
        Select Case Target
            Case vbNullString, ""
                Range("J" & Target.Row).Value = ""
            Case Is <= Date
                Range("J" & Target.Row).Value = "Terugbellen"
            Case Else
                Range("J" & Target.Row).Value = ""
        End Select
    End If

End Sub

Hier een uitleg van de Select Case:
http://nl.wikibooks.org/wiki/Programmeren_in_VB&VBA#Select_Case_...
 
Laatst bewerkt:
Oké, super.

Waar zegt hij dan dat hij alleen de bijgewerkte regel moet nakijken?
 
Dat doet dit stukje:
If Not Intersect(Target, Range("I1:I" & Rowcount)) Is Nothing Then

In het object Target staat het o.a. adres van de cell en daarmee wordt vergeleken.

Het zou nu een heel stuk in snelheid moeten schelen :)
 
Target is het adres van de cell die bijgewerkt is?
Wat is dan dat not intersect nothing enzo? Kun je die hele regel niet eens in pseudocode schrijven?
 
Target is een zogenaamd range object en bevat een aantal attributen. Het standaard attribuut is de waarde van de cel waar de cursor staat maar het bevat ook het adres van die cel (Target.Address). De Intersect methode vergelijkt dat adres met de tweede parameter en kijkt of dat adres in het range object van de tweede parameter valt. Zoja, dan wordt de code uitgevoerd en anders niet.

Code:
If Not Intersect(Target, Range("I1:I" & Rowcount)) Is Nothing Then

Pseudo:
Als het adres van de actieve cel in het in het opgegeven bereik valt dan
 
Oké helder. Moet ik dat "not" en "nothing" dan zien als dubbele ontkenning en feitelijk een "wel"? En waarom worden not en nothing precies gebruikt en kunnen ze niet weggelaten?
 
Dat is inderdaad een beetje vreemde controle maar voor objecten moet dat op die manier.
Je controleert of het NIET NIETS is in plaats van of het IETS is omdat de controle
If Intersect(Target, Range("I1:I" & Rowcount)) Is Something er simpelweg niet is.
Dit gebruik je alleen voor objecten, niet voor variabelen.

Overigens sta ik open voor een betere uitleg als iemand die heeft ;)
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan