Avatar billede hjald8 Nybegynder
09. oktober 2004 - 17:26 Der er 21 kommentarer og
2 løsninger

Makro til sletning af rækker, hvor værdi i bestemt kolonne er 0.

Hej

Jeg har en skabelon, hvor der læses ca. 1600 bogføringsrækker ind i et ark. Afhængig af emne kan det variere, hvor mange rækker der udnyttes.

For at importere disse til bogføring, skal rækker, hvor værdien i kolonne G er 0, slettes. Til dette ønskes en makro.

Jeg forestillede mig en makro tilknyttet en knap.

På forhånd tak.
Avatar billede sjap Praktikant
09. oktober 2004 - 18:00 #1
Prøv med

For i = 1 To 100
    If Range("H" & i) = 0 Then ActiveSheet.Rows(i).Delete Shift:=xlUp
Next i

100 er antallet af rækker, der skal undersøges (kan være op til 65536, men jeg har bare sat den til 100 for at spare tid)

koden undersøger om tallet i kolonne H er 0.
Avatar billede hjald8 Nybegynder
09. oktober 2004 - 19:04 #2
Jeg fik vist ikke konkretiseret, at knappen (for makroen) er i et andet ark end det ark, hvor der skal slettes. Hvordan gør man det for et navngivet ark?
Avatar billede sjap Praktikant
09. oktober 2004 - 19:17 #3
Jamen så prøver vi da bare med:

For i = 1 To 100
  If Range("Ark1!H" & i) = 0 Then Sheets("Ark1").Rows(i).Delete Shift:=xlUp
Next i

Bemærk at navnet står to steder (jeg går du fra at 0'er og rækker, der skal slettes, står i samme ark)
Avatar billede hjald8 Nybegynder
09. oktober 2004 - 19:23 #4
Tak for svar. Jeg har testet det. Jeg har åbenbart ikke beskrevet det godt nok. I de pågældende celler i kolonne H er der formler, som har hentet dataene ind. Formentlig derfor bliver der ikke slettet én eneste række.

Dernæst. Det er faktisk meget hurtigere, at sortere på denne kolonne ved den alm. sorteringsfunktion i Excel, og dernæst selv slette disse rækker. Den 'tygger' meget på hver eneste række. Kan det løses anderledes?
Avatar billede sjap Praktikant
09. oktober 2004 - 19:33 #5
Nej, jeg må da medgive, at jeg jo ikke har læst spørgsmålet godt nok. Nogen af de ting som jeg har lavet forudsætninger for, findes jo i spørgsmålet (utroligt hvor hurtigt ting kan smutte ind og ud af den der klump oven på halsen).

Prøv med den her (husk at rette "Ark1" begge steder til dit arknavn)

For i = 1 To 2000
  If Range("Ark1!G" & i) = 0 Then Sheets("Ark1").Rows(i).Delete Shift:=xlUp
Next i
Avatar billede hjald8 Nybegynder
09. oktober 2004 - 19:39 #6
Sjap, tak for svar igen. Jeg havde selv taget højde for problematikken med G og H. Derfor er min kommentar fortsat gældende. Jeg håber, at du kan hjælpe:

I de pågældende celler i kolonne H er der formler, som har hentet dataene ind. Formentlig derfor bliver der ikke slettet én eneste række.

Dernæst. Det er faktisk meget hurtigere, at sortere på denne kolonne ved den alm. sorteringsfunktion i Excel, og dernæst selv slette disse rækker. Den 'tygger' meget på hver eneste række. Kan det løses anderledes?
Avatar billede hjald8 Nybegynder
09. oktober 2004 - 19:43 #7
Der er 'dømt' familie. Vender tilbage senere.
Avatar billede sjap Praktikant
09. oktober 2004 - 20:00 #8
OK.

Jeg forstår ikke helt problemet. Er der nogen tunge formler, der genberegnes hele tiden? Jeg har prøvet med 16.000 rækker, og det tager

ca. 6 sekunder når hver 10. række skal slettes - dvs. ialt 1.600 sletninger.
ca. 2 sekunder når hver 100. række skal slettes - dvs. ialt 160 sletninger.
ca. 1 sekunder når ingen rækker skal slettes.
Avatar billede sjap Praktikant
09. oktober 2004 - 20:02 #9
Det er selvfølgelig muligt at lave en makro, der foretager den manøvre, som du har fundet er hurtigere end ovenstående kode. Prøv evt. at bruge funktionen "indspil ny makro" - så vil du være tæt på.
Avatar billede hjald8 Nybegynder
09. oktober 2004 - 20:34 #10
Jeg har nu lavet en makro, der ændrer indholdet i cellerne til 'værdier'. Reelt er det værdierne der skal bruges. Det er jo en simpel kopi-funktionalitet, som er indspillet:

Cells.Select
Selection.Copy
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select

Derved når jeg også rigtige gode hastigheder, når din makro sættes i gang - måske ikke så gode som dine - men meget tilfredsstillende.

Mit problem er, at det ikke er forudsigeligt, hvor mange rækker, der skal slettes pr. gang. Derfor er undersøgelsen af om det er 'relevant at slette rækken' rigtig god.

Selvom hastigheden er der - så lykkes det ikke, at slette en eneste række. Jeg har følgende kode inde i makroen:

For i = 1 To 100
If Range("bogføringsfil!G" & i) = 0 Then Sheets("bogføringsfil").Rows(i).Delete Shift:=xlUp
Next i
Avatar billede sjap Praktikant
09. oktober 2004 - 21:25 #11
Er bogføringsfil et faneblad i det aktuelle regneark, eller ligger den i et helt andet regneark?
Avatar billede sjap Praktikant
09. oktober 2004 - 21:46 #12
Nedenstående kan i øvrigt snuppe lidt mere tid programkørslen. Application.Calculation = xlCalculationManual slår automatisk beregning fra, så det skulle ikke være nødvendigt at bruge din kopifunktionalitet (Application.Calculation = xlCalculationAutomatic slår automatisk beregning til igen).

Dim c As Range
Application.Calculation = xlCalculationManual
tid = Now()
For Each c In Range("bogføringsfil!G1:G16000")
    If c = 0 Then Sheets("bogføringsfil").Rows(c.Row).Delete Shift:=xlUp
Next c
tid = Now - tid
Application.Calculation = xlCalculationAutomatic
Avatar billede sjap Praktikant
09. oktober 2004 - 21:57 #13
Jeg har forsøgt med nogen simple beregninger i regnearket, og hele proceduren (på 16.000 rækker) tager 17 sekunder med automatisk beregning slået til. Slås automatisk beregning fra er tiden reduceret til 11 sekunder. Det er da en slat.

Så fik jeg selvfølgelig endnu en ide:

Dim c As Range
Application.Calculation = xlCalculationManual
tid = Now()
For Each c In Range("bogføringsfil!G1:G16000")
    If c = 0 Then c.EntireRow.Delete
Next c
tid = Now - tid
Application.Calculation = xlCalculationAutomatic

På denne måde kan koden nu afvilkes på 8 sekunder - eller ca. dobbelt så hurtigt som det første forslag.
Avatar billede sjap Praktikant
09. oktober 2004 - 21:59 #14
Nåh, ja du kan jo godt undvære de to tid=... -sætninger. Det er nogen jeg har brugt til at undersøge hvilken kode der er hurtigst.
Avatar billede sjap Praktikant
09. oktober 2004 - 22:20 #15
Hvis der skal slettes rækker i et andet regneark (altså ikke bare i en andet faneblad), kan du bruge følgende kode:

Dim c As Range
Application.Calculation = xlCalculationManual
For Each c In Workbooks("Mappe3.XLS").Sheets("bogføringsfil").Range("G1:G16000")
    If c = 0 Then c.EntireRow.Delete
Next c
Application.Calculation = xlCalculationAutomatic
Avatar billede hjald8 Nybegynder
09. oktober 2004 - 23:56 #16
Tusind tak for undersøgelserne. Jeg vil sætte point op, således at du kan få point i forhold til indsats.

Hastigheden hvormed den arbejder igennem rækkerne er meget flot. Men den sletter fortsat ikke rækker hvor cellen i kolonnen er 0. Der er ikke slettet én eneste række.

Således er min makro bygget op:

Sub SletRækker()
Dim c As Range
Application.Calculation = xlCalculationManual
tid = Now()
For Each c In Range("bogføringsfil!g1:g16000")
    If c = 0 Then c.EntireRow.Delete
Next c
tid = Now - tid
Application.Calculation = xlCalculationAutomatic
End Sub

Jeg ved sørme ikke hvad jeg gør forkert. Jeg er taknemmelig for indsatsen.
Avatar billede sjap Praktikant
10. oktober 2004 - 01:07 #17
Mit eneste muligheder jeg kan se er

- at "bogføringsfil!g1:g16000" er den forkerte reference
- værdien ikke er 0

Til den sidste mulighed kan du f.eks. erstatte

if c = 0 Then c.EntireRow.Delete

med

If Int(c) = 0 Then c.EntireRow.Delete

Pas På! Så sletter den alle rækker hvor kolonnen er < 1!

Hvis dette ikke hjælper, så er du velkommen til at sende filen til mig. Så skal jeg kigge på det i morgen formiddag.
Avatar billede hjald8 Nybegynder
10. oktober 2004 - 08:49 #18
Dette ændrede ikke noget. Jeg må have lavet en eller anden grundlæggende fejl.
Avatar billede sjap Praktikant
10. oktober 2004 - 10:43 #19
Hvis det er muligt, så prøv at sende filen til mig. Slet eventuelt vigtige oplysninger (som du gerne vil holde for dig selv), men sørg for at fejlen stadig sker, efter du har slettet. Når du har gjort det, så send filen til

sjap9000 snabela hotmail punktum com
Avatar billede hjald8 Nybegynder
10. oktober 2004 - 10:53 #20
Sendt. Tak.
Avatar billede sjap Praktikant
10. oktober 2004 - 12:35 #21
Problemet opstår når der er 0 i to rækker umiddelbart efter hinanden. Programmet sletter den første række og gå så til den næste række. Men programmet skal - på grund af sletningen - faktisk ikke gå til den næste række, men blive hvor den er.

Problemet har jeg løst ved at starte bagfra i stedet. Så påvirker sletningen ikke rækkenumrene:

Sub SletRækker()

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

tid = Now()
With Range("bogføringsfil!g1:g1600")
    rCount = .Rows.Count
    For r = rCount To 1 Step -1
        If .Cells(r, 1) = 0 Then
            .Rows(r).EntireRow.Delete
        End If
    Next r
End With
Debug.Print Format(Now - tid, "s") & " sekunder"

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

End Sub

HUSK at du til enhver tid kan slette linierne:

tid = Now()
Debug.Print Format(Now - tid, "s") & " sekunder"

da de kun bruges i optimeringsøjemed.
Avatar billede hjald8 Nybegynder
10. oktober 2004 - 12:46 #22
Tusind tak. Det er virkelig flot.
Avatar billede sjap Praktikant
10. oktober 2004 - 12:47 #23
:0)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Excel kurser for alle niveauer og behov – find det kursus, der passer til dig

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester