30. september 2005 - 13:55Der er
23 kommentarer og 2 løsninger
VBA: Håndtering af dubletter i tekster (tilføj løbenummer)
Hej.
Jeg har en kolonne med en lang række tekster hvor der kan være dubletter i. Teksterne skal dog være unikke, så derfor skal jeg have tilføjet et løbenummer til de tekster hvor der er dubletter.
Eksempel:
Tekst Tekst igen Noget mere tekst Tekst Tekst Tekst igen En anden tekst Noget mere tekst Test tekst Tekst
Skal blive til:
Tekst Tekst igen Noget mere tekst Tekst (1) Tekst (2) Tekst igen (1) En anden tekst Noget mere tekst (1) Test tekst Tekst (3)
Hver tekst skal altså have sit eget løbenummer.
Hvordan gør jeg det nemmest og ikke mindst effektivt da der godt kan være ca. 1.000 tekster!
har ikke testet, men hvis du kan benytte en makro, prøv denne Denne sjekker i kolonne A, rad 5 til 100, dette endrer du lett selv
Sub DublettListe() i = 1 For Each c In [A5 : A100] For Each t In [A5 : A100] If t.Value = c.Value And Not t.Value = "" Then t.Value = c.Value & i i = i +1 End If Next Next End Sub
For Each c In [A5 : A100] i = 1 For Each t In [A5 : A100] If t.Value = c.Value And Not t.Value = "" Then t.Value = c.Value & i i = i +1 End If Next Next End Sub
Den først celle den sjekker er A5 og den siste A100 ( r ) det har ikke noe å si om r er større enn siste rad med data ( håper du forstår mitt språk (norsk), god helg ;-)
Sub DublettListe() r = 100 For Each c In Range(Cells(5, 1), Cells(r, 1)) For Each t In Range(Cells(5, 1), Cells(r, 1)) If c.Row < t.Row And t.Text = c.Text And Not t.Value = "" Then i = i + 1 t.Value = t.Text & " (" & i & ")" End If If t.Row = r Then i = 0 Next Next End Sub
Sub DublettListe() Dim rng As Range Dim c As Range Dim t As Range Dim i As Long
Set rng = [A5:A100] For Each c In rng temp = c.Value i = 0 For Each t In rng If t.Value = temp And Not t.Value = "" Then If i > 0 Then t.Value = temp & " (" & i & ")" i = i + 1 End If Next Next End Sub
snowball skriver: Hvordan gør jeg det nemmest og ikke mindst effektivt da der godt kan være ca. 1.000 tekster!
jeg laget en liste på ca 1300 tekster, der det kunne være over 100 like tekster. Når jeg testet bak's kode mot mitt forslag, var bak's kode 4 x hurtigere.
Prøvde derfor å laste alle tekstene i en Array. For så å gjøre operasjoenen på selve Arrayet.
Public Sub Duplicatverdier()
Dim c As Long, t As Long, i As Long, x As Long Dim vTab() As Variant Dim fRow As Long 'first row Dim lRow As Long 'last row
For c = 1 To UBound(vTab) - 1 i = 1: x = c + 1 For t = x To UBound(vTab) If Not vTab(t, 1) = "" And vTab(t, 1) = vTab(c, 1) Then vTab(t, 1) = vTab(t, 1) & " (" & i & ")" i = i + 1 End If Next Next
Range(Cells(fRow, 1), Cells(lRow, 1)) = vTab
End Sub
den ble ca. 25 x raskere enn bak's kode.
Men kjenner jeg bak rett, kan han gjøre den ennå mye mere effektiv ;-) Kanskje man kan lage en liste med unike verdier, for så å teste mot den? Eller en collection, der man benytter remove på hver tekst som alt er benyttet?
oyejo -> Du har lavet koden næsten optimalt, så der er ikke meget at hente her :-) Flot kode, jeg kan se at du har fået greb om array-operationerne og du læser ikke hele arrayet igennem i din anden løkke, god detajle her. Hvis jeg bruger 3000 linier og min tudsegamle 1200 mhz computer tager din kode 4 sek. Hvis du ændrer koden lidt således at sætningen If Not vTab(t, 1) = "" And vTab(t, 1) = vTab(c, 1) Then kun chekker for en ting og kun hvis dette er sandt chekker for, om den er blank tager det kun 2 sek.
For c = 1 To UBound(vTab) - 1 i = 1: x = c + 1 For t = x To UBound(vTab) If vTab(t, 1) = vTab(c, 1) Then If Not IsEmpty(vTab(t, 1)) Then vTab(t, 1) = vTab(t, 1) & " (" & i & ")" i = i + 1 End If End If Next Next
skulle da lige teste med collection. Tid 0,65 sek Public Sub DuplicatverdierCollection() Dim i As Long, x As Long Dim xcol As New Collection Dim vTab() As Variant Dim fRow As Long 'first row Dim lrow As Long Dim elem Dim it
fRow = 2 'first row lrow = Cells(Rows.Count, 1).End(xlUp).Row vTab = Range(Cells(fRow, 1), Cells(lrow, 1)) On Error Resume Next For Each elem In vTab xcol.Add elem, elem Next On Error GoTo 0
For Each it In xcol i = 0 For x = 1 To UBound(vTab, 1) If vTab(x, 1) = it Then If Not i = 0 Then vTab(x, 1) = vTab(x, 1) & " (" & i & ")" End If i = i + 1 End If Next Next Range(Cells(fRow, 1), Cells(lrow, 1)) = vTab
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.