Avatar billede hubertus Seniormester
28. juli 2015 - 16:32 Der er 13 kommentarer og
1 løsning

Optimering af kode

Gennemløbet af mit regneark tager lang tid. Der er mellem 1500 og 2000 linjer. Jeg har derfor brug for optimering / alternative kode til at løse opgaven. Nogle gode forslag efterlyses.


Sub FlytTilFejllliste(ark)

Dim num_of_rows As Integer
Dim i As Integer
Dim col As String
Dim text As String

Application.ScreenUpdating = False

Sheets(ark).Select

rows = optælAntalRækker(1, "B", ark)

col = "E"

    For i = rows To 1 Step -1
           
        text = Range(col & i)
            If Not IsNumeric(text) Then
                Sheets("Produkter").Range("A" & i & " : H" & i).Copy
                Worksheets("fejlliste").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial
                Sheets(ark).Range("A" & i & " : H" & i).Delete
            End If
    Next
       
Application.ScreenUpdating = True

End Sub
Avatar billede supertekst Ekspert
28. juli 2015 - 18:19 #1
Hvad er lang tid?
Prøv at vis koden i optælAntalRækker
Avatar billede hubertus Seniormester
28. juli 2015 - 21:13 #2
Det tager nogle minutter at gennemløbe 1500 linier. Koden der tæller antal rækker er ikke årsagen. Den burger jeg uden problemer I andre sammenhænge.

Private Function optælAntalRækker(intRow, strCol, Ark)
Dim Count
   
    Sheets(Arknavn).Select
   
    Count = 0
    While Cells(intRow, strCol).Value <> ""
        Count = Count + 1
        intRow = intRow + 1
    Wend
    optælAntalRækker = Count
   
  '  Sheets(Arknavn).Select
End Function
Avatar billede supertekst Ekspert
28. juli 2015 - 23:34 #3
Vender tilbage
Avatar billede finb Ekspert
29. juli 2015 - 13:58 #4
Prøv at lægge det hele i array,
det plejer at køre stærkt.
Avatar billede supertekst Ekspert
29. juli 2015 - 14:32 #5
rows = optælAntalRækker(1, "B", ark)

rows gav problemer i min VBA-kode - er reserveret - måske?

- du har jo definitionen: Dim num_of_rows As Integer - så var der ikke noget problem.
Avatar billede hubertus Seniormester
29. juli 2015 - 15:23 #6
#6 Det er min fejl det var en forkert udgave jeg fik postet. 
Den rigtige er:

Sub FlytTilFejllliste(ark)
Dim num_of_rows As Integer
Dim i As Integer
Dim col As String
Dim text As String
Application.ScreenUpdating = False
Sheets(ark).Select
num_of_rows = optælAntalRækker(1, "B", ark)
col = "E"
    For i = num_of_rows To 1 Step -1
      text = Range(col & i)
            If Not IsNumeric(text) Then
                Sheets("Produkter").Range("A" & i & " : H" & i).Copy
                Worksheets("fejlliste").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial
                Sheets(ark).Range("A" & i & " : H" & i).Delete
            End If
    Next
Application.ScreenUpdating = True

End Sub
Avatar billede hubertus Seniormester
29. juli 2015 - 15:24 #7
Og det er den del af koden der giver hastighedsproblemer.
Avatar billede Dan Elgaard Ekspert
30. juli 2015 - 06:21 #8
Hver gang du kopier og paster, og hver gang du sletter, så sker der en event og der sker en ny beregning.

Prøv at sætte disse to linjer i starten af koden:

Application.calculation = xlCalculationManual
Application.EnableEvents = False

Kør din kode og slut af med

Application.calculation = xlCalculationAutomatic
Application.EnableEvents = True
Avatar billede hubertus Seniormester
31. juli 2015 - 13:16 #9
#8 det hjalp mig en del af vejen. afviklingen blev væsentlig hurtigere, men jeg er ikke helt i mål endnu.

#4 det var også min tanke, men jeg vidste bare ikke, hvordan det skulle gøres i den konkrete opgave. Har du et bud på, hvordan koden kunne se ud?
Avatar billede Dan Elgaard Ekspert
31. juli 2015 - 13:29 #10
Du burde også lave dit loop på objektet, i stedet for en tæller.

Loop på objeket kan være op til 10 gange hurtigere, alt efter hvad der skal ske på objeket, og alt efter, hvordan din makro er opbygget.

http://www.EXCELGAARD.dk/Lib/Macros/GPP/Loops/

Og, i stedet for at slette, hver gang dit kriterie er opflydt, så marker i stedet linjen til sletning, når dit loop er færdig - at slette en linje kræver meget tid, men at sleete flere linjer på samme tid, kræver næsten blot den samme tid.

Du kunne evt. medtage linjen i et Array, som markering, og så slette hele Array, når du har gennemløbet alle linjerne...
Avatar billede hubertus Seniormester
31. juli 2015 - 17:51 #11
#10 Har du et kode eksempel på det sidste?
Avatar billede Dan Elgaard Ekspert
31. juli 2015 - 22:33 #12
Der er et godt eksempel her, hvor alle celler, der omfylder kriteriet først samles med 'Union' og til sidst vælges med 'Select'.

http://www.vbaexpress.com/kb/getarticle.php?kb_id=20

På den måde benyttes metoden .Select kun en eneste gang, men enorm hastighedsforøgelse til følge.

Det burde hurtigt kunne konvertes om til dit formål, og så slette af med .Delete på alle de fundne celler...
Avatar billede hubertus Seniormester
07. august 2015 - 05:49 #13
Åpistolprinsen: tak for input, det har hjulpet,s så meget at jeg har fået løst min opgave, så tak for det  :0)) Lægger du et svar, så er der point på vej.
Avatar billede Dan Elgaard Ekspert
07. august 2015 - 08:07 #14
Hold da op - jeg havde helt glemt denne tråd, indtil der lå en mail om dit sidste indlæg i min mailbox.

Undskyld, at jeg ikke fik svaret på det sidste, men godt, at du alligevel fik løst dit progblem :-)
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

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