veri karşılaştırma hızı

maliex

Altın Üye
Katılım
22 Eylül 2019
Mesajlar
227
Excel Vers. ve Dili
professional plus 2016-türkçe
Altın Üyelik Bitiş Tarihi
23-09-2025
Arkadaşlar merhaba,
2 veriyi karşılaştırma yapıyorum

2 sorum var
1-)aşağıda kodlardan da belirttiğim üzere 1. yöntemde 30 saniye sürerken , 2.yöntem 90 saniye sürmekte oysaki 2.yöntem çokdaha kısa sürmesi gerekmezmi ?
2-) 2.yöntemde sonuçları yazıdırken yanlış getiriyor oysaki "locals" penceresinden "oklar" dizinini kontrol ettiğimde sorun yok anlayamadım

C++:
Sub deneme()
Application.ScreenUpdating = False
b = Timer
Dim s1 As Worksheet
Set s1 = Sheets("sayfa1")

Dim ilkveri(1 To 15000)
Dim ikinciveri(1 To 15000)

For X = 1 To 15000
    ilkveri(X) = Cells(X, 1) & Cells(X, 2) & Cells(X, 3)
    ikinciveri(X) = Cells(X, 7) & Cells(X, 8) & Cells(X, 9)
Next X

'''''1 .yöntem'''''''

For X = 1 To 15000
    For y = 1 To 15000
        If ilkveri(X) = ikinciveri(y) Then Cells(X, 4) = "ok"
    Next y
Next X

''''2.yöntem'''''''''

Dim OKLAR(1 To 15000)
For X = 1 To 15000
    For y = 1 To 15000
        If ilkveri(X) = ikinciveri(y) Then OKLAR(X) = "VAR"
        If ilkveri(X) = ikinciveri(y) Then Exit For
        If ilkveri(X) <> ikinciveri(y) Then OKLAR(X) = "YOK"
    Next y
Next X

s1.Range("D1").Resize(15000) = OKLAR

c = Timer - b
MsgBox "İşlem Süresi : " & Int(c) & " saniye"
Application.ScreenUpdating = True
End Sub
 

Ekli dosyalar

Korhan Ayhan

Administrator
Yönetici
Admin
Katılım
15 Mart 2005
Mesajlar
42,745
Excel Vers. ve Dili
Microsoft 365 Tr-En 64 Bit
Merhaba,

Hız olarak en iyilerden birisi aşağıdaki yapıdır.

C++:
Option Explicit

Sub Fast_Vlookup()
    Dim Son As Long, Veri As Variant, Dizi As Object
    Dim X As Long, Say As Long, Zaman As Double
    
    Zaman = Timer
    
    Set Dizi = CreateObject("Scripting.Dictionary")
    
    Son = Cells(Rows.Count, 7).End(3).Row
    If Son = 2 Then Son = 3
    Veri = Range("G1:I" & Son).Value
    
    For X = LBound(Veri) To UBound(Veri)
        Dizi.Item(Veri(X, 1) & "|" & Veri(X, 2) & "|" & Veri(X, 3)) = X
    Next
    
    Son = Cells(Rows.Count, 1).End(3).Row
    If Son = 2 Then Son = 3
    Veri = Range("A1:C" & Son).Value
    
    ReDim Liste(1 To Son, 1 To 1)
    
    For X = LBound(Veri) To UBound(Veri)
        Say = Say + 1
        Liste(Say, 1) = IIf(Dizi.Exists(Veri(X, 1) & "|" & Veri(X, 2) & "|" & Veri(X, 3)), "VAR", "YOK")
    Next
    
    Range("D:D").ClearContents
    Range("D1").Resize(Say) = Liste
    
    Set Dizi = Nothing
    
    MsgBox "İşleminiz tamamlanmıştır." & Chr(10) & Chr(10) & _
           "İşlem süresi ; " & Format(Timer - Zaman, "0.00") & " Saniye", vbInformation
End Sub
 

maliex

Altın Üye
Katılım
22 Eylül 2019
Mesajlar
227
Excel Vers. ve Dili
professional plus 2016-türkçe
Altın Üyelik Bitiş Tarihi
23-09-2025
korhan bey

teşekkürler,,
bu sondaki "= x" neye yarıyor
"(Veri(X, 1) & "|" & Veri(X, 2) & "|" & Veri(X, 3))"=bu kısım key
"= x" = bu kısımda ıtem doğrumu
----ayrıca benim yapmış olduğum 2.örnek neden veriyi aktarırken hata veriyor ayrıca neden yavaş bi yorum yapabilriseniz çok memnun olurum

C++:
  For X = LBound(Veri) To UBound(Veri)
        Dizi.Item(Veri(X, 1) & "|" & Veri(X, 2) & "|" & Veri(X, 3)) = X
    Next
 

Korhan Ayhan

Administrator
Yönetici
Admin
Katılım
15 Mart 2005
Mesajlar
42,745
Excel Vers. ve Dili
Microsoft 365 Tr-En 64 Bit
Döngüleri iyi kavramak gerekiyor. Kullandığınız her "if" sorgusu döngüyü yavaşlatmaktadır.

Siz karşılaştırma yapmak için iç içe iki döngü kullanıyorsunuz. 15.000 satırlık iki dizi kontrol ediliyor. "Exit For" kullansanız da döngü "if" sorgularından dolayı yavaşlıyor.

Örneklersek;

X döngüsü 1 to 15000 olarak başlıyor. İlk döngü değeri 1 olacaktır. Sonrasında Y döngüsü 1 to 15000 olarak başlıyor. İki diziyi karşılaştırıyor. Eşleşme olmadığı sürece X değerine YOK ifadesini yazıyor. Diyelim ki eşleşme 15.000 ninci kayıtta sağlandı. Bu eşleşmeye kadar OKLAR(X) yani OKLAR(1) dizisine YOK ifadesini yazıyor. Bu işlemi de if sorgusuyla yaptığı için yavaşlama söz konusu oluyor.

Ek olarak diziyi tanımlarken sadece satır bilgisini Dim OKLAR(1 To 15000) şeklinde verdiğinizde hücrelere yazdırırken Application.Transpose kullanmanız gerekir.

C++:
s1.Range("D1").Resize(15000) = Application.Transpose(OKLAR)
Bunun yerine diziyi tanımlarken sütun bilgisi de eklerseniz sizin yazdığınız şekilde kullanabilirsiniz.

C++:
Dim OKLAR(1 To 15000, 1 To 1)
For X = 1 To 15000
    For y = 1 To 15000
        If ilkveri(X) = ikinciveri(y) Then OKLAR(X, 1) = "VAR"
        If ilkveri(X) = ikinciveri(y) Then Exit For
        If ilkveri(X) <> ikinciveri(y) Then OKLAR(X, 1) = "YOK"
    Next y
Next X

s1.Range("D1").Resize(15000) = OKLAR

Sizin döngüyü hızlandırmak için ben aşağıdaki yolu kullandım.

C++:
Dim OKLAR(1 To 15000, 1 To 1)
Dim Varmi As Boolean
For X = 1 To 15000
    Varmi = False
    For y = 1 To 15000
        If ilkveri(X) = ikinciveri(y) Then
            OKLAR(X, 1) = "VAR"
            Varmi = True
            Exit For
        End If
    Next y
    If Varmi = False Then OKLAR(X, 1) = "YOK"
Next X

s1.Range("D1").Resize(15000) = OKLAR
Bu şekilde denediğimde bende 16 saniyede işlem tamamlandı.
 

maliex

Altın Üye
Katılım
22 Eylül 2019
Mesajlar
227
Excel Vers. ve Dili
professional plus 2016-türkçe
Altın Üyelik Bitiş Tarihi
23-09-2025
harikasınız korhan bey çok teşekkür ederim.. udemy de scripting.Dictionary ve diziler özelinde A dan Z ye bir eğitim yaparsanız eminim bir çok kişi faydalanıcaktır...yerli kaynaklar maalesef çok yetersiz , yabancı kaynaklarda çok bölükpörçük..siz değerli üstadlarımızdan Türk gençliğine böle bir eser bırakmanızı rica ediyorum..
saygılarımla
 

Korhan Ayhan

Administrator
Yönetici
Admin
Katılım
15 Mart 2005
Mesajlar
42,745
Excel Vers. ve Dili
Microsoft 365 Tr-En 64 Bit
Merhaba,

Bu işlerin üzerine biraz eğilmek gerekiyor. Bol bol pratik yapılarak konu daha rahat kavranabilir. Takıldığınız yerlerde sorularınızı sorarak kendinizi geliştirebilirsiniz.
 
Üst