- Katılım
- 31 Aralık 2005
- Mesajlar
- 4,384
- Excel Vers. ve Dili
- Office 365 (64 bit) - Türkçe
Geçici sayfaya gerek yok. Kodu yarın revize edeceğim.
DOSYA İndirmek/Yüklemek için ÜCRETLİ ALTIN ÜYELİK Gereklidir!
Altın Üyelik Hakkında Bilgi
Sub Baran_Listele()
Dim rs As Object, son As Long, arr(1 To 5) As Variant, b As Integer, c As Long
Dim t1 As Single, t2 As Single, d As Integer
Sayfa2.[k1:l1].ClearContents
Sayfa2.[k1] = Now
t1 = Timer
Sayfa2.Range("B2:F21").ClearComments
Sayfa2.Range("B2:F21").ClearContents
son = Sayfa1.[I100000].End(3).Row
'İyi performans için belleğe al
arr(1) = Sayfa1.Range("I8:I" & son).Value2
arr(2) = Sayfa1.Range("M8:M" & son).Value2
arr(3) = Sayfa1.Range("N8:N" & son).Value2
arr(4) = Sayfa1.Range("Q8:Q" & son).Value2
arr(5) = Sayfa1.Range("EA8:EZ" & son).Value2
For b = 1 To 5
Set rs = CreateObject("ADODB.Recordset")
rs.Fields.Append "Ad", 200, 100 'varchar(100)
rs.Fields.Append "Sıklık", 3 '32 bit integer
rs.Open , , 0, 3 'forward,optimistic
rs("Ad").Properties("Optimize") = True '~~ %50 performans(index oluşturur)
For c = 1 To UBound(arr(b), 1)
If Trim(arr(b)(c, 1)) <> "" Then 'Aralarda boş hücreler var
If b < 5 Then
rs.Filter = "Ad = '" & arr(b)(c, 1) & "'"
If rs.RecordCount = 0 Then
rs.AddNew Array("Ad", "Sıklık"), Array(arr(b)(c, 1), 1)
Else
rs.Fields("Sıklık") = rs.Fields("Sıklık") + 1
End If
Else
For d = 1 To UBound(arr(b), 2)
If Trim(arr(b)(c, 1)) <> "" Then
If Trim(arr(b)(c, d)) = "" Then Exit For
rs.Filter = "Ad = '" & arr(b)(c, d) & "'"
If rs.RecordCount = 0 Then
rs.AddNew Array("Ad", "Sıklık"), Array(arr(b)(c, d), 1)
Else
rs.Fields("Sıklık") = rs.Fields("Sıklık") + 1
End If
End If
Next
End If
End If
Next
rs.Filter = 0 'Filitre deaktif
rs.Sort = "[Sıklık] Desc" 'Azalan sıralama
rs.MoveFirst 'İlk kayda git
For c = 1 To Sayfa1.[n4] 'Ham sayfasının N4 hücresindeki sayı kadar.
Sayfa2.Cells(c + 1, b + 1) = rs.Fields("Ad")
Sayfa2.Cells(c + 1, b + 1).AddComment _
"::..www.excel.web.tr..::" & vbCr & String(30, "-") & _
vbCr & """" & rs("Ad") & """ " & rs("Sıklık") & " defa tekrarlandı."
rs.MoveNext
If rs.EOF Then Exit For '20 kayıt yoksa döngüden çık
Next
Next
t2 = Timer
Sayfa2.[l1] = t2 - t1 & " saniye"
End Sub
Value, tip dönüşümlü, value2 ise ham veri olarak getirir. Bu farkı boş bir dosyada A1 hücresine =bugün() formülü verin ve aşağıdaki prosedur sonucuna bakın. Value2 ile veriler belleğe daha hızlı yüklenir.(Dikkat; Tarihler sayı olarak gelir)... Örneğin Value2 nedir? Value ile Value2 farkı nedir? CreateObject("ADODB.Recordset") bu hangi işlemi gerçekleştiriyor? Hangi durumlarda bu ifade kullanılır?
Sub test()
Debug.Print [a1].Text
Debug.Print [a1].Value
Debug.Print [a1].Value2
End Sub
Option Explicit
Sub BENZERSİZ_VERİLERİ_LİSTELE()
Dim S1 As Worksheet, S2 As Worksheet
Dim Son As Long, X As Long, Y As Long, Z As Long, Adet As Long
Dim Liste(1 To 5), Dizi As Object, Zaman As Double
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Zaman = Timer
Set S1 = Sheets("Veri")
Set S2 = Sheets("Özet")
S2.Range("A2:F" & S2.Rows.Count).ClearContents
S2.Range("A2:F" & S2.Rows.Count).ClearComments
S2.Range("K1") = Now
On Error Resume Next
Son = S1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
If Son = 0 Then Son = 10000
On Error GoTo 0
Liste(1) = S1.Range("I8:I" & Son).Value2
Liste(2) = S1.Range("M8:M" & Son).Value2
Liste(3) = S1.Range("N8:N" & Son).Value2
Liste(4) = S1.Range("Q8:Q" & Son).Value2
Liste(5) = S1.Range("EA8:EZ" & Son).Value2
Set Dizi = CreateObject("Scripting.Dictionary")
For X = 1 To 5
For Y = 1 To UBound(Liste(X))
For Z = 1 To UBound(Liste(X), 2)
If Liste(X)(Y, Z) <> "" Then
If Not Dizi.Exists(Liste(X)(Y, Z)) Then
Dizi.Add Liste(X)(Y, Z), 1
Else
Dizi.Item(Liste(X)(Y, Z)) = Dizi.Item(Liste(X)(Y, Z)) + 1
End If
End If
Next
Next
S2.Cells(2, X + 1).Resize(Dizi.Count, 2) = Application.Transpose(Array(Dizi.Keys, Dizi.Items))
S2.Range(S2.Cells(1, X + 1), S2.Cells(S2.Rows.Count, X + 2)).Sort S2.Cells(1, X + 2), xlDescending, , , , , , xlYes
Adet = S1.Range("N4")
For Z = 2 To Adet + 1
If S2.Cells(Z, X + 1) <> "" Then
S2.Cells(Z, 1) = Z - 1
S2.Cells(Z, X + 1).AddComment "Tekrar Sayısı : " & Format(S2.Cells(Z, X + 2).Text, "#,##0")
S2.Cells(Z, X + 2).ClearContents
End If
Next
S2.Range(S2.Cells(Adet + 2, X + 1), S2.Cells(S2.Rows.Count, X + 2)).ClearContents
S2.Range("G:G").ClearContents
Dizi.RemoveAll
Next
S2.Cells.EntireColumn.AutoFit
S2.Range("K2") = Format(Timer - Zaman, "0.0000000") & " Saniye"
Set S1 = Nothing
Set S2 = Nothing
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
MsgBox "İşleminiz tamamlanmıştır.", vbInformation
End Sub
Konuyu kapatmışsınız ama ben bir örnek dosya daha hazırlamıştım. Boşa gitmesin.
İnceleyiniz.
Not : Özellikle veri sayısını 500.000 farklı ya da daha fazla veri üzerinde deneyip hızı test ediniz.