Avatar billede jih Nybegynder
18. juli 2008 - 16:20 Der er 11 kommentarer og
1 løsning

nested for loop - simplere måde?

Hej,

jeg har fået løst følgende problem:

Jeg har en liste af DSL numre (numre som starter med teksten "DSL") - sammen med andre numbre: VPN, WMX osv..
(Problemet var at alle DSL numrene havde dubletter- somme tider var der 2 forekomster af samme tal, somme tider op til 7)

jeg skulle så lede igennem den liste for at finde kun DSL numrene, smide dem over fra ark1 til ark3 (kolonne A)..

Så skulle jeg tjekke hele kolonne A i ark3, om det samme tal (som er i den celle, mit for loop kører igennem) findes i kolonne B.. hvis ikke (blnMatch = False), smid da det tal over i kolonne B..
(Så vil det næste tal - hvis det er det samme som tallet før - blive fundet i kolonne B og der: blnMatch = True)

..

det her virker fint, men det arbejder utroligt langsomt.. det bruge 5 sekunder på at finde ca. 42 tal - som vil sige at alt i alt (igennem 8801 tal) vil det tage 17 minutter?

er der nogen der ved en hurtigere måde?

koden er som følge:

---
Option Explicit

Private Sub Worksheet_Activate()
    Dim intI As Integer
    Dim intJ As Integer
    Dim intK As Integer
    Dim arrDSL() As String
    Dim arrNew(1 To 5634) As String
    Dim strDSL As String
    Dim blnMatch As Boolean
   
    For intI = 1 To 8801
        strDSL = strDSL & ThisWorkbook.Sheets(1).Cells.Range("A" & intI) & " "
    Next intI
    arrDSL = Split(strDSL, " ")
   
    intJ = 0
   
   
    ThisWorkbook.Sheets(3).Cells.Range("A1") = "Processing numbers..."
    For intI = LBound(arrDSL) To UBound(arrDSL)
        ThisWorkbook.Sheets(3).Cells.Range("A" & intI + 2) = arrDSL(intI)
    Next intI
   
    For intI = LBound(arrDSL) To UBound(arrDSL)
        If (Mid(arrDSL(intI), 1, 4) = "DSL5") Then
            intJ = intJ + 1
            arrNew(intJ) = arrDSL(intI)
            ThisWorkbook.Sheets(3).Cells.Range("A" & intI + 1) = ""
        End If
    Next intI
   
   
    For intI = LBound(arrNew) To UBound(arrNew)
        ThisWorkbook.Sheets(3).Cells.Range("A" & intI + 1) = arrNew(intI)
    Next intI
   
    blnMatch = False
    intK = 2
   
    For intI = LBound(arrNew) To UBound(arrNew)
        With ThisWorkbook.Sheets(3).Cells
            For intJ = 1 To 3636
                If (arrNew(intI) = .Range("B" & intJ)) Then
                    blnMatch = True
                End If
            Next intJ
            If (blnMatch = False) Then
                .Range("B" & intK) = arrNew(intI)
                intK = intK + 1
            End If
        End With
        blnMatch = False
    Next intI
   
    ThisWorkbook.Sheets(3).Cells.Range("A1") = "Processing complete!"
End Sub
---


På forhånd tak,

// jih
Avatar billede kabbak Professor
18. juli 2008 - 17:37 #1
her er en test, den tjekker alt for dubletter.

Den skriver i samme ark, kolonne 10, dem der er tomme er dubletter.

Private Sub Worksheet_Activate()
    Dim intI As Integer
    Dim intJ As Integer
    Dim arrDSL As Variant
    Dim arrDSL1 As Variant
    Dim RW As Long
   
    RW = Range("A65536").End(xlUp).Row
    arrDSL = ThisWorkbook.Sheets(1).Cells.Range("A1:A" & RW)
    arrDSL1 = arrDSL
    For intI = LBound(arrDSL) To UBound(arrDSL)
    If IsEmpty(arrDSL(intI, 1)) Then Exit For
        For intJ = intI + 1 To UBound(arrDSL1)
            If arrDSL(intI, 1) = arrDSL1(intJ, 1) Then arrDSL1(intJ, 1) = Empty
        Next
    Next

    ThisWorkbook.Sheets(1).Range(Cells(1, 10), Cells(RW, 10)) = arrDSL1
End Sub
Avatar billede jih Nybegynder
21. juli 2008 - 10:30 #2
får "type mismatch" på
--
    For intI = LBound(arrDSL) To UBound(arrDSL)
--
Avatar billede kabbak Professor
21. juli 2008 - 11:37 #3
Private Sub Worksheet_Activate()
    Dim intI As Integer
    Dim intJ As Integer
    Dim arrDSL As Variant
    Dim arrDSL1 As Variant
    Dim RW As Long
 
    RW = ThisWorkbook.Sheets(1).Range("A65536").End(xlUp).Row
    arrDSL = ThisWorkbook.Sheets(1).Cells.Range("A1:A" & RW)
    arrDSL1 = arrDSL
    For intI = LBound(arrDSL) To UBound(arrDSL)
    If IsEmpty(arrDSL(intI, 1)) Then Exit For
        For intJ = intI + 1 To UBound(arrDSL1)
            If arrDSL(intI, 1) = arrDSL1(intJ, 1) Then arrDSL1(intJ, 1) = Empty
        Next
    Next

    ThisWorkbook.Sheets(1).Range(Cells(1, 10), Cells(RW, 10)) = arrDSL1
End Sub

prøv nu
Avatar billede jih Nybegynder
21. juli 2008 - 11:52 #4
Application-defined or object-defined error:

--
ThisWorkbook.Sheets(1).Range(Cells(1, 10), Cells(RW, 10)) = arrDSL1
--
Avatar billede kabbak Professor
21. juli 2008 - 12:40 #5
ThisWorkbook.Sheets(1).Range("J1:J" & RW) = arrDSL1
Avatar billede jih Nybegynder
21. juli 2008 - 12:50 #6
den fjerner ingen dubletter.. kopierer blot alle cellerne i kolonne A til kolonne J..
Avatar billede kabbak Professor
21. juli 2008 - 12:55 #7
prøv lige at sende et eksempelark
kabbak snabela tiscali dot dk
Avatar billede jih Nybegynder
21. juli 2008 - 13:01 #8
er sendt
Avatar billede kabbak Professor
21. juli 2008 - 14:14 #9
Prøv denne

Sub FjernDubletter()
    Dim intI As Integer
    Dim intJ As Integer
    Dim arrDSL As Variant
    Dim arrDSL1 As Variant
    Dim RW As Long


    RW = ThisWorkbook.Sheets(1).Range("A65536").End(xlUp).Row
    arrDSL = ThisWorkbook.Sheets(1).Cells.Range("A1:A" & RW)
    arrDSL1 = ThisWorkbook.Sheets(1).Cells.Range("A1:C" & RW)
    For intI = LBound(arrDSL) To UBound(arrDSL)
        Application.StatusBar = "Processing numbers..." & intI & " of " & UBound(arrDSL)
        If Left(arrDSL(intI, 1), 4) = "DSL5" Then
            For intJ = intI + 1 To UBound(arrDSL1)
                If arrDSL(intI, 1) = arrDSL1(intJ, 1) Then
                    arrDSL1(intJ, 1) = Empty
             
                If InStr(1, arrDSL1(intI, 3), arrDSL1(intJ, 3)) = 0 Then
                    arrDSL1(intI, 3) = arrDSL1(intI, 3) & " , " & arrDSL1(intJ, 3)
                    arrDSL1(intJ, 3) = Empty
                    arrDSL1(intJ, 2) = Empty
                End If
                End If
            Next
        Else
            arrDSL1(intI, 1) = Empty
            arrDSL1(intI, 2) = Empty
            arrDSL1(intI, 3) = Empty
        End If
    Next
    ThisWorkbook.Sheets(3).Activate
      ThisWorkbook.Sheets(3).Range("A1:C" & UBound(arrDSL1)) = arrDSL1

    Columns("A:C").Select
    Range("A2").Activate
    Selection.Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
                  OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
                  DataOption1:=xlSortNormal
    Application.StatusBar = "complete!"
End Sub
Avatar billede kabbak Professor
21. juli 2008 - 14:22 #10
Sub FjernDubletter()
    Dim intI As Integer
    Dim intJ As Integer
    Dim arrDSL As Variant
    Dim arrDSL1 As Variant
    Dim RW As Long


    RW = ThisWorkbook.Sheets(1).Range("A65536").End(xlUp).Row
    arrDSL = ThisWorkbook.Sheets(1).Cells.Range("A1:A" & RW)
    arrDSL1 = ThisWorkbook.Sheets(1).Cells.Range("A1:C" & RW)
    For intI = LBound(arrDSL) To UBound(arrDSL)
        Application.StatusBar = "Processing numbers..." & intI & " of " & UBound(arrDSL)
        If Left(arrDSL(intI, 1), 4) = "DSL5" Then
            For intJ = intI + 1 To UBound(arrDSL1)
                If arrDSL(intI, 1) = arrDSL1(intJ, 1) Then
                    arrDSL1(intJ, 1) = Empty
                End If
            Next
        Else
            arrDSL1(intI, 1) = Empty
        End If
    Next
    ThisWorkbook.Sheets(3).Activate
      ThisWorkbook.Sheets(3).Range("A1:A" & UBound(arrDSL1)) = arrDSL1

    Columns("A:A").Select
    Range("A2").Activate
    Selection.Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
                  OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
                  DataOption1:=xlSortNormal
    Application.StatusBar = "complete!"
End Sub
Avatar billede kabbak Professor
21. juli 2008 - 14:37 #11
Sub FjernDubletter()
    Dim intI As Integer
    Dim intJ As Integer
    Dim arrDSL As Variant
    Dim arrDSL1 As Variant
    Dim RW As Long

Application.ScreenUpdating = False
    RW = ThisWorkbook.Sheets(1).Range("A65536").End(xlUp).Row
    arrDSL = ThisWorkbook.Sheets(1).Cells.Range("A1:A" & RW)
    arrDSL1 = ThisWorkbook.Sheets(1).Cells.Range("A1:C" & RW)
    For intI = LBound(arrDSL) To UBound(arrDSL)
        Application.StatusBar = "Processing numbers..." & intI & " of " & UBound(arrDSL)
        If Left(arrDSL(intI, 1), 4) = "DSL5" Then
            For intJ = intI + 1 To UBound(arrDSL1)
                If arrDSL(intI, 1) = arrDSL1(intJ, 1) Then
                    arrDSL1(intJ, 1) = Empty
                End If
            Next
        Else
            arrDSL1(intI, 1) = Empty
        End If
    Next
    ThisWorkbook.Sheets(3).Activate
      ThisWorkbook.Sheets(3).Range("A1:A" & UBound(arrDSL1)) = arrDSL1

  Range("A:A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
  Application.ScreenUpdating = True

  Application.StatusBar = "complete!"
End Sub
Avatar billede jih Nybegynder
21. juli 2008 - 14:40 #12
det blev det sidstnævnte - tak for hjælpen :-)
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