• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

Indien bepaalde cellen niet ingevuld zijn > delete rij

Status
Niet open voor verdere reacties.

DEWCAP

Gebruiker
Lid geworden
14 dec 2006
Berichten
79
Hallo,

Via access doe ik een export van een query naar excel. Tot hier gaat alles goed. Maar nu zou ik een macro willen die opzoekt welke cellen in de file leeg zijn. Als een bepaalde combinatie van cellen leeg is, zou de rij moeten verwijderd worden.

In bijlage kan je duidelijker zien wat ik bedoel.

Bedankt voor de hulp!

DEWCAP
 

Bijlagen

Dewcap, De hulp hangt een beetje af van je antwoord op deze vraag. Is het altijd alleen de combinatie van kolom 2, 3, 5 en 6 wanneer een regel verwijderd moet worden? Of mag je stellen dat bijvoorbeeld ALTIJD kolom 2 leeg is als de andere kolommen (3 5 6) ook leeg zijn?

Bij de 1e (dus combinatie) zou ik zeggen, maak een extra kolom naast je tabel waarin je de 4 kolommen (cellen) test op aanwezige inhoud. Als ze alle 4 leeg zijn, geef je als resultaat TRUE en anders FALSE. Zet deze formule in cel I2 en verder naar onder(sorry, ik heb hier alleen een engelse versie van Excel)
Code:
=COUNTA(B2:C2;E2:F2)=0
Sorteer hierna je tabel op kolom I waardoor de True en de False netjes bij elkaar komen te staan. Delete de regels met True en je tabel is geschoond.

In het andere geval (dat je alleen maar naar kolom 2 hoeft te kijken) zou ik zeggen: zet een autofilter op je tabel en filter je tabel op kolom B met als criterium 'blancs'. Je houdt dan een tabel over met alleen de regels met lege cellen in kolom 2. Deze kan je dan heel makkelijk deleten en je tabel is geschoond.

Groet, Leo
 
Met deze macro gebeurt het automatisch, hier is het alleen bij de combinatie van cellen 2,3,5,6

Code:
Sub RijVerwijderen()
Dim Teller As Integer
Dim Berijk As Range
    
    Range("A1").Select
    
    Do Until Selection = Empty
    Teller = 0
    Set Berijk = Selection
        Selection.Offset(0, 1).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        Selection.Offset(0, 1).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        Selection.Offset(0, 2).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        Selection.Offset(0, 1).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        If Teller = 4 Then
            Selection.Offset(1, -5).Select
            Berijk.EntireRow.Delete Shift:=xlUp
        Else
            Berijk.Offset(1, 0).Select
        End If
    Loop
        
End Sub

gr Paul
 
Het gaat inderdaad om de combinatie van verschillende kolomen. Ik ga de oplossing van Paul even proberen. Ik houd jullie op de hoogte.

Bedankt!
 
Hallo Paul,

ik weet dat het niet de bedoeling is om VBA les te geven, maar zou je even wat uitleg kunnen geven bij je macro? Zo kan ik deze ook gebruiken bij andere combinaties.

bedankt!

DEWCAP
 
Opnieuw Hallo,

De macro lijkt te werken MAAR hij neemt niet alle rijen.

Heb hem even uitgetest op een sheet waar 10 rijen normaal verwijderd moeten worden en hij nam er maar 5. Heb de macro 3 maal moeten starten alvorens alle rijen gedelete waren.

Heeft iem hier een verklaring/oplossing voor?

Bedankt!
 
De macro gaat van boven naar onder door de rijen.

Maar aangezien er rijen verwijderd worden, worden dus niet de juiste rijen gedaan.

Je moet van beneden naar boven werken bij het verwijderen van rijen.

Wigi
 
Ik zou - om eerlijk te zijn - van 0 terug beginnen, en niet proberen bovenstaande code aan te passen. Dit wil niet zeggen dat de hulp van Paul Groote S niet gewaardeerd wordt, integendeel.

Wigi
 
Ik heb een nieuwe versie gemaakt, niet rekening houdend met de oude versie. Ze is niet getest maar zou wel moeten werken naar mijn mening :)

Code:
Sub Rij()
Dim iRow As Long
Dim BeginRow As Long
Dim ShtNaam As String

BeginRow = 1 'verander deze waarde naar de rij waar je willen beginnen
ShtNaam = "Sheet1" 'verander deze waarde naar de sheetnaam waar je de macro wilt op uitvoeren

Application.ScreenUpdating = False

For iRow = Sheets(ShtNaam).UsedRange.Rows.Count To BeginRow Step -1
    If Sheets(ShtNaam).Cells(iRow, 2) = "" And _
       Sheets(ShtNaam).Cells(iRow, 3) = "" And _
       Sheets(ShtNaam).Cells(iRow, 5) = "" And _
       Sheets(ShtNaam).Cells(iRow, 6) = "" Then
            Sheets(ShtNaam).Rows(iRow).Delete xlUp
    End If
Next iRow

Application.ScreenUpdating = True
End Sub
 
Nieuwe is helemaal niet nodig, die oude is makkelijk aan te passen.

De reden waarom het mis ging, is als je 1 rij verwijderd, alle rijden 1 omhoog gaat.

je volgende rij staat dus nu op de positie van de net verwijderde rij.

Je moet dus in het eerste script de "teller + 1" regels verwijderen, op het moment dat het script een regel verwijderd. Op die manier pakt hij na verwijdering van een rij, dezelfde regel nog een keer.

m.v.g,
Mark

EDIT: ik lees verkeerd, de teller wordt hier anders gebruik dan het tellen van rijen. In dit geval is het dus de bedoeling dat hij de loop voor dezelfde rij nogmaals doorloopt. Je kunt dus i.d.d. of vanaf beneden beginnen met checken, of je maakt het alsvolgt:

Code:
Sub RijVerwijderen()
Dim Teller As Integer
Dim Berijk As Range
    
    Range("A1").Select
    
    Do Until Selection = Empty
    Teller = 0
    Set Berijk = Selection
        Selection.Offset(0, 1).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        Selection.Offset(0, 1).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        Selection.Offset(0, 2).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        Selection.Offset(0, 1).Select
        If Selection = Empty Then
            Teller = Teller + 1
        End If
        If Teller = 4 Then
            Selection.Offset(0, -5).Select
            Berijk.EntireRow.Delete Shift:=xlUp
        Else
            Berijk.Offset(1, -5).Select
        End If
    Loop
        
End Sub

De regel bij teller is 4, inplaats van 1, -5 nu dus 0, -5 gedaan, dan pakt hij dus dezelfde regel nogmaals.
Zo niet, dan moet de else ook 1,-5 hebben, want met 1,0 gaat hij lijkt me in een verkeerd kolom beginnen. Is niet getest, dus laat maar horen wat hier nu van klopt.
 
Laatst bewerkt:
Nieuwe is helemaal niet nodig, die oude is makkelijk aan te passen.

De reden waarom het mis ging, is als je 1 rij verwijderd, alle rijden 1 omhoog gaat.

je volgende rij staat dus nu op de positie van de net verwijderde rij.

Je moet dus in het eerste script de "teller + 1" regels verwijderen, op het moment dat het script een regel verwijderd. Op die manier pakt hij na verwijdering van een rij, dezelfde regel nog een keer.

m.v.g,
Mark


Die teller + 1 regels zijn om te zijn hoeveel kolommen niet ingevuld zijn. Zijn er dit 4, dan mag de rij weg, anders niet. Dus volgens mij gaat jouw suggestie de oplossing niet geven.
Zonder te testen, maar de nodige aanpassing in de oorspronkelijke code is denk ik:

Code:
 If Teller = 4 Then
            Selection.Offset(1, -5).Select
            Berijk.EntireRow.Delete Shift:=xlUp
        Else
            Berijk.Offset(1, 0).Select
        End If

vervangen door

Code:
 If Teller = 4 Then
            Selection.Offset([COLOR="Red"]0[/COLOR], -5).Select
            Berijk.EntireRow.Delete Shift:=xlUp
        Else
            Berijk.Offset(1, 0).Select
        End If

Deze uitwerking is echter verschillend met de uitwerking hoe ik meestal werkt, vandaar mijn nieuwe versie. Deze is niet slechter ofzo (althans dat hoop ik :D), maar ligt me minder.
 
Je geeft zelfde antwoord als dat ik in mijn Edit gaf ;-)

Ik kwam er i.d.d. ook na het posten achter dat het woordt Teller hier voor Links naar Rechts gebruikt werd, en niet van boven naar beneden ;-)

edit:
Die 1,0 klopt i.d.d. wel. Ik las de functie naam niet goed.

Het is OF Berijk.Offset(1, 0).Select of je gebruikt Selection.Offset(1, -5).Select, deze hebben beiden hetzelfde effect.

Eigenlijk dus raar dat er in deze if else 2 verschillende maniere gebruikt werden ;-)
 
Laatst bewerkt:
Je geeft zelfde antwoord als dat ik in mijn Edit gaf ;-)

Ik kwam er i.d.d. ook na het posten achter dat het woordt Teller hier voor Links naar Rechts gebruikt werd, en niet van boven naar beneden ;-)

edit:
Die 1,0 klopt i.d.d. wel. Ik las de functie naam niet goed.

Het is OF Berijk.Offset(1, 0).Select of je gebruikt Selection.Offset(1, -5).Select, deze hebben beiden hetzelfde effect.

Eigenlijk dus raar dat er in deze if else 2 verschillende maniere gebruikt werden ;-)



Wat ik op het eerste zicht (weliswaar zonder testen) aan nadeel van deze methode vind is dat wanneer de eerste kolom van de nieuwe rij, waar hij heen sprint en de else case, niet is ingevuld hij denkt we aan het einde van de reeks waarden zijn, maar ik denk dat dat niet altijd het geval is. Wanneer kolom 1 steeds een waarde heeft, is er geen vuiltje aan de lucht.
 
De 2 mogelijkheden werken!!

Iedereen hartelijk bedankt voor de hulp!!

Vriendelijke groeten

DEWCAP
 
Wat ik op het eerste zicht (weliswaar zonder testen) aan nadeel van deze methode vind is dat wanneer de eerste kolom van de nieuwe rij, waar hij heen sprint en de else case, niet is ingevuld hij denkt we aan het einde van de reeks waarden zijn, maar ik denk dat dat niet altijd het geval is. Wanneer kolom 1 steeds een waarde heeft, is er geen vuiltje aan de lucht.

De teller heeft die functie. Er wordt per rij in elke kolom gekeken of het leeg is of niet.

Is het aantal lege velden 4 (dus de teller = 4), dan moet de lijn weg, anders niet. Dus daarmee werkt het in principe.

Je kunt er ook een combo van maken. Als je dus bij bepaalde combinaties van kolomen dit script wilt gebruiken. Wat je dan doet, is niet steeds een teller + 1 te doen, maar een verdubbeling.

Dus bij de eerste if else doe je Teller + 1, de volgende Teller +2, de volgender teller + 4, +8, + 16 en net zo lang tot je alle kolomen hebt gedaan.

Als je dan steld, indien teller = 1 Dan is alleen de 1e kolom leeg
Indien teller = 2, is alleen de 2e kolom leeg
Indien teller = 3, is de 1e en 2e kolom leeg
indien teller = 4, is alleen de 3e leeg
Indien teller = 5, dan is de 1e en 3e leeg.

Enzo voort, en zo voor. Op deze manier, kun je de regel dus voor een combinatie van lege vakken opstellen. Voor een bepaald waarde van teller wel verwijderen, en de overige niet.

Dus opzich is deze manier met verandering van de teller een idiaal aan te passen scriptje.

Dit grapje komt van het binear tellen af. Dit is in principe een Ja/nee verhaal. Dus een 0 of een 1.

Binaire getal 0001 => 1
Binaire getal 0010 => 2
Binaire getal 0100 => 4
Binaire getal 1000 => 8

Binaire getal 0001 => 1
Binaire getal 0010 => 2
Binaire getal 0011 => 3
Binaire getal 0100 => 4
Binaire getal 0101 => 5
..........
Binaire getal 0111 => 7
Binaire getal 1000 => 8
.........
Binaire getal 1101 => 13
Binaire getal 1110 => 14
Binaire getal 1111 => 15


Zo kun je dus voor 4 kolomen 16 verschillende situaties defineren. Komt wiskunde toch nog eens vanpas ;-)
 
De teller heeft die functie. Er wordt per rij in elke kolom gekeken of het leeg is of niet.

Is het aantal lege velden 4 (dus de teller = 4), dan moet de lijn weg, anders niet. Dus daarmee werkt het in principe.

Je kunt er ook een combo van maken. Als je dus bij bepaalde combinaties van kolomen dit script wilt gebruiken. Wat je dan doet, is niet steeds een teller + 1 te doen, maar een verdubbeling.

Dus bij de eerste if else doe je Teller + 1, de volgende Teller +2, de volgender teller + 4, +8, + 16 en net zo lang tot je alle kolomen hebt gedaan.

Als je dan steld, indien teller = 1 Dan is alleen de 1e kolom leeg
Indien teller = 2, is alleen de 2e kolom leeg
Indien teller = 3, is de 1e en 2e kolom leeg
indien teller = 4, is alleen de 3e leeg
Indien teller = 5, dan is de 1e en 3e leeg.

Enzo voort, en zo voor. Op deze manier, kun je de regel dus voor een combinatie van lege vakken opstellen. Voor een bepaald waarde van teller wel verwijderen, en de overige niet.

Dus opzich is deze manier met verandering van de teller een idiaal aan te passen scriptje.

Dit grapje komt van het binear tellen af. Dit is in principe een Ja/nee verhaal. Dus een 0 of een 1.

Binaire getal 0001 => 1
Binaire getal 0010 => 2
Binaire getal 0100 => 4
Binaire getal 1000 => 8

Binaire getal 0001 => 1
Binaire getal 0010 => 2
Binaire getal 0011 => 3
Binaire getal 0100 => 4
Binaire getal 0101 => 5
..........
Binaire getal 0111 => 7
Binaire getal 1000 => 8
.........
Binaire getal 1101 => 13
Binaire getal 1110 => 14
Binaire getal 1111 => 15


Zo kun je dus voor 4 kolomen 16 verschillende situaties defineren. Komt wiskunde toch nog eens vanpas ;-)


Dat begrijp ik en het gebruik van die teller is terecht, al is jouw manier flexibeler. Maar in de oorspronkelijke versie gaat de lus door tot dat de selectie leeg is.Wanneer je nu geen rij moet verwijderen ga je naar de volgende regel met het commando:

Code:
Berijk.Offset(1, 0).Select

Je komt dan altijd uit in een cel op kolom A, want je start in A1, en gaat telkens 1 rij naar beneden. Maar wanneer nu tijdens de uitvoering van je code je in een rij terecht komt waar de cel in kolom A niet is ingevuld, dan heb een lege selectie en gaat aan de voorwaarde gedaan zijn om te stoppen met het zoeken naar te verwijderen lijnen. Maar het is niet zeker dat onder deze lijn nog andere rijen staan die moeten gecheckt worden.

Daarover ging mijn opmerking.
 
Persoonlijk had ik ook liever dit stuk:

Code:
 If Teller = 4 Then
            Selection.Offset(1, -5).Select
            Berijk.EntireRow.Delete Shift:=xlUp
        Else
            Berijk.Offset(1, 0).Select
        End If

anders gezien, namelijk zo

Code:
 If Teller = 4 Then
            Selection.Offset(0, -5).Select  ' nogmaals dezelfde rij, aangezien er net 1 weg is
            Berijk.EntireRow.Delete Shift:=xlUp
        Else
            Selection.Offset(1, -5).Select ' volgende rij
        End If

Dit is meteen ook sneller, omdat je niet steeds vanaf boven aan opnieuw hoeft te beginnen.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan