Avatar billede fhansen82 Mester
18. september 2013 - 10:33 Der er 10 kommentarer og
1 løsning

EXCEL VBA loop der tjekker for værdi som ikke findes

Hej

Jeg har nu siddet og nørklet med at få noget kode til at virke, men kan ikke overskue det. Jeg har brug for noget VBA kode, som tjekker en værdi i C2 op mod en række værdier i kolonne D startende fra D2. Hvis værdien ikke findes, skal værdien fra C2 kopieres til E2. Hvis værdien findes, skal der springes videre til C3, og igen søges forfra i kolonne D. Værdier i både kolonne C og D er begrænsede, så cell count ønskes benyttet for at udlede en stopværdi. Kolonne C indeholder en liste brugernavne, som kun fremgår én gang hver i denne kolonne. Kolonne D indeholder en liste over de brugernavne, som har været logget ind i et system, inden for en given skæringsdato. Det er brugernavnene som ikke har været logget ind, inden for den angivne skæringsdato, som jeg ønsker kopieret over. Brugernavne forekommer også kun én gang hver i denne kolonne, Koden skal derfor tygge sig igennem de unikke forekomster af brugernavne i kolonne C og søge efter dem i kolonne D, og hvis ikke de findes, kopieres til kolonne E.
Jeg kan godt regne ud at det er noget For loop, Do loop og If der skal bruges, men kan ikke få sat det sammen til noget jeg kan bruge.
Avatar billede tjp Mester
18. september 2013 - 12:01 #1
Til inspiration:

Sub FindManglendeVærdier()
  Dim i, j, k, fundet
  i = 2
  j = 2
  k = 2
  Do While Cells(k, 5) <> ""
      Cells(k, 5).Clear
      k = k + 1
  Loop
  k = 2
 
  fundet = False
  Do While Cells(i, 3) <> ""
      Do While Cells(j, 4) <> ""
     
        If Cells(i, 3) = Cells(j, 4) Then
            fundet = True
            Exit Do
        End If
        j = j + 1
      Loop
      If Not fundet Then
        Cells(k, 5) = Cells(i, 3)
        k = k + 1
      End If
      fundet = False
      j = 2
      i = i + 1
  Loop
End Sub
Avatar billede fhansen82 Mester
18. september 2013 - 13:12 #2
tjp, din kode ser jo ud som jeg havde drømt og mere til. Kan se du ikke har haft behov for at benytte cell count, hvilket jeg syntes ser rigtigt fornuftigt ud. Koden ser simpel og overskuelig ud. Dog kan jeg ikke få den til at fungere. Der kommer intet output, og jeg har lige prøvet at skimte koden igennem, om alt passede, og jeg kan ikke finde nogle fejl. Har du bekræftet at koden virker? Det første stykke kode du har skrevet, er det til at rydde op i kolonne E?
Avatar billede tjp Mester
18. september 2013 - 13:42 #3
Jeps, linjerne:
  k = 2
  Do While Cells(k, 5) <> ""
      Cells(k, 5).Clear
      k = k + 1
  Loop
er for at slette resultat af tidligere kørsel i E-kolonne.

Koden virker hos mig, så måske er det sammenligningerne der går galt - måske er det en idé at trimme og evt. bruge store bogstaver til sammenligning a la:
        If UCase(Trim(Cells(i, 3))) = UCase(Trim(Cells(j, 4))) Then
Avatar billede fhansen82 Mester
18. september 2013 - 17:14 #4
Det gav heller ikke noget resultat. Jeg testede din kode i en projektmappe, og her virker koden selvfølgelig perfekt. Så prøvede jeg at kopiere nogle enkelte data fra den originale projektmappe ind (fra kolonne C og D). Fungerede også perfekt. Så prøvede jeg at kopiere alle data fra kolonne C og D ind, og koden virker perfekt. Men jeg kan simpelthen ikke få den til at virke i den oprindelige projektmappe. Jeg har indsat alt koden, undtagen første og sidste linje af koden. Koden er indsat i

Sub Knap6_Klik()

End Sub

Når jeg klikker på knappen, sker der intet. Kodeafviklingen hænger heller ikke. Jeg har forsøgt at indsætte en MsgBox, og denne vises når jeg klikker på knappen. Al min kode ligger i et modul (Module1). Jeg er egentligt ikke klar over hvorfor det havnede i et modul. Mener jeg startede i et ark (Ark2 (Ark2)), og var pludselig et et modul. Tænkte "What the heck" og forsatte :O) Har det nogen betydning? Du kan nok gætte, at jeg er lidt grøn i VBA/programmering.

Jeg forsøgte også at udskifte

If Cells(i, 3) = Cells(j, 4) Then

med

If UCase(Trim(Cells(i, 3))) = UCase(Trim(Cells(j, 4))) Then

...uden held.
Avatar billede fhansen82 Mester
18. september 2013 - 22:24 #5
Nå, blev lige klogere. Hvis jeg trykker F8 VBA kodevinduet, og sætter den gule cursor ved starten af koden, og starter afviklingen, ja, så fungerer koden altså fint. Så det må være et eller andet med knappen. Er der forskel på om man har valgt blot en knap eller en kommandoknap?
Avatar billede tjp Mester
18. september 2013 - 23:55 #6
hmm, måske har koden fat i det forkert ark? Prøv at indsætte en MsgBox igen som viser værdien af fx A1, dvs: MsgBox Cells(1,1).
Avatar billede fhansen82 Mester
19. september 2013 - 08:40 #7
Oooooh myyyy gooood. Hvor dum kan man være. Jeg har også kun fire andre knapper, som netop præcist aktiverer det ark som koden skal køres i først. Det har jeg så ikke fået gjort i knappen med den nye kode. Idiot. Det var selvfølgelig det som skulle til. Mange tak for hjælpen tjp. Smid et svar for point :O)
Avatar billede tjp Mester
19. september 2013 - 09:58 #8
Shit happens... :-)
Avatar billede fhansen82 Mester
19. september 2013 - 10:03 #9
Ohh, yes it does :O) Så blev jeg så klogere. Tak for koden. Den var så flot opstillet, at selv jeg forstod den ;O) Skal se om jeg kan inkorporere den i noget af min tidligere kode. Har fx denne:

DateCriteria = Sheets("Ark2").Range("J28")
   
    Sheet1upA = 2
    Sheet1upB = 2
    Sheet1upC = 2
    Sheet1upD = 2
       
    Do
    DoEvents

    If Sheets("Ark1").Range("C" & Sheet1upC) = Sheets("Ark1").Range("B" & Sheet1upB) And Sheets("Ark1").Range("A" & Sheet1upA) >= DateCriteria Then

        Sheets("Ark1").Range("D" & Sheet1upD) = Sheets("Ark1").Range("C" & Sheet1upC)
        Sheet1upC = Sheet1upC + 1
        Sheet1upD = Sheet1upD + 1
        Sheet1upA = 2
        Sheet1upB = 2
       
    ElseIf Sheet1upA < CellCountA Then

        Sheet1upA = Sheet1upA + 1
        Sheet1upB = Sheet1upB + 1
   
    ElseIf Sheet1upA >= CellCountA Then

        Sheet1upC = Sheet1upC + 1
        Sheet1upA = 2
        Sheet1upB = 2
       
    End If

    Loop Until Sheet1upC = CellCountC

...som unægtelig kan gøres meget pænere og hurtigere. Det tager sin tid at køre denne del, da den skal køre igennem ca. 50.000 celler, for hvert brugernavn. Det må kunne gøres mere elegant.
Avatar billede fhansen82 Mester
19. september 2013 - 17:07 #10
Hvis du har lyst, kunne jeg godt bruge din hjælp igen :O)

http://www.eksperten.dk/spm/985867
Avatar billede fhansen82 Mester
19. september 2013 - 18:15 #11
Shit. Ændrede lige to linjer, og fik derved koden gjort over 10 gange hurtigere. Før tog det ca. en time. Nu tager de ca. 5 minutter. Utroligt hvad et par tweaks kan gøre :O) Fik ændret at søgningen ikke skulle starte forfra, når der blev fundet det søgte.

DateCriteria = Sheets("Ark2").Range("J28")
 
    Sheet1upA = 2
    Sheet1upB = 2
    Sheet1upC = 2
    Sheet1upD = 2
     
    Do
    DoEvents

    If Sheets("Ark1").Range("C" & Sheet1upC) = Sheets("Ark1").Range("B" & Sheet1upB) And Sheets("Ark1").Range("A" & Sheet1upA) >= DateCriteria Then

        Sheets("Ark1").Range("D" & Sheet1upD) = Sheets("Ark1").Range("C" & Sheet1upC)
        Sheet1upC = Sheet1upC + 1
        Sheet1upD = Sheet1upD + 1
        Sheet1upA = 2 (ændret til Sheet1upA = Sheet1upA + 1)
        Sheet1upB = 2 (ændret til Sheet1upB = Sheet1upB + 1)
     
    ElseIf Sheet1upA < CellCountA Then

        Sheet1upA = Sheet1upA + 1
        Sheet1upB = Sheet1upB + 1
 
    ElseIf Sheet1upA >= CellCountA Then

        Sheet1upC = Sheet1upC + 1
        Sheet1upA = 2
        Sheet1upB = 2
     
    End If

    Loop Until Sheet1upC = CellCountC
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
Kurser inden for grundlæggende programmering

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