Anasayfa | Akademik Forum | Sizden Gelenler | Sipariş
Menü Açıklamaları
Sorular - Cevaplar
Makaleler
Makrolar
Yerleşik İşlevler
Animasyonlar
Yumurtalar
Fonksiyonlar
MTK Programlar
ExcelCE
Dosya İndir
Neler Yaptık?
İletişim
Makaleler
ListBox nesnesine veri almak ve bunları A-Z düzeninde sıralamak Muhammet Aytaş - 26.08.2008 (Düzenlenmiş Yeni Makale)
Bu makalemde ListBox nesnesine veri alma yöntemlerini ve bunları sıralama konusunu anlatmaya çalışacağım. Örneğin çalışma sayfamızda alttaki gibi bir tablomuz olsun:
 

Adı

Soyadı

İkamet

Maaşı

Doğum Tarihi

M.Temel

Korkmaz

Bursa

2.500.000

01.01.1969

Cemil

Gökmen

Ankara

2.250.000

05.05.1963

Salih

Koca

İstanbul

1.250.000

06.06.1975

Orhan

Kaplan

Orhangazi

800.000

07.07.1965

Muhammet

Aytaş

Bursa

1.400.000

08.08.1965

Ali

Uyanık

İzmir

500.000

09.09.1960

Ahmet

Cesur

Antalya

750.000

10.10.1964

Murat

Yolcu

Balıkesir

1.100.000

25.12.1967

İbrahim

Korkmaz

Düzce

2.750.000

05.03.1962

Şimdi bu listeyi ListBox nesnesine alalım.

1. Bunun için döngü ile birlikte AddItem metodunu kullanarak verileri tek tek ListBox’a alabiliriz:

  Dim SonSatir As Integer, Satir As Integer
  SonSatir =   WorksheetFunction.CountA(ActiveSheet.Range("A1:A100"))
  For Satir = 2 To SonSatir
    ListBox1.AddItem ListBox1.List(Satir - 2, 0) = ActiveSheet.Range("A" & Satir)
    ListBox1.List(Satir - 2, 1) = ActiveSheet.Range("B" & Satir)
    ListBox1.List(Satir - 2, 2) = ActiveSheet.Range("C" & Satir)
    ListBox1.List(Satir - 2, 3) = ActiveSheet.Range("D" & Satir)
    ListBox1.List(Satir - 2, 4) = ActiveSheet.Range("E" & Satir)
  Next

Bildiğimiz gibi ListBox nesnesinde ilk endeks 0.

Bu kodları çalıştırınca alttaki görüntüyü aldık:



Gördüğünüz gibi çalışma sayfasındaki veriler istediğimiz formatta olduğu halde ListBox nesnesine aldığımızda herhangi bir format almamakta. Bu tür nesneler verileri metin formatında alırlar. İstediğimiz formatı vermek için ise kodlarda düzeltme yapmamız gerekiyor:

   ListBox1.List(Satir - 2, 3) = Format(ActiveSheet.Range("D" & Satir), "#,##0")
  ListBox1.List(Satir - 2, 4) = Format(ActiveSheet.Range("E" & Satir), "dd.mm.yyyy")

Bu düzeltmeden sonra aldığımız görüntü:

2. Döngü kullanmadan dizi olarak ListBox nesnesine alabiliriz.

  ListBox1.ColumnCount = 5
  ListBox1.List = ActiveSheet.Range("A2:E10").Value

Bu şekilde aldığımız veriler de formatsız olarak alınacaktır. Ancak bu durumda verileri blok halinde aldığımız için AddItem metodunda olduğu gibi veri alma esnasında kodlarda herhangi bir düzeltme yapma şansımız yok. Tabi bu çözüm yok anlamına gelmiyor, ListBox nesnesindeki verileri döngü kullanarak istediğimiz formata getirebiliriz:;

  For Satir = 0 To ListBox1.ListCount - 1
    ListBox1.List(Satir, 3) = Format(ListBox1.List(Satir, 3), "#,##0") 
    ListBox1.List(Satir, 4) = Format(ListBox1.List(Satir, 4), "dd.mm.yyyy")
  Next

Bizim format vermek istediğimiz 4. ve 5. sütunlar olduğu için kodları sadece onlar için hazırladık. Kodların içerisinde sütun numaraları 4 ve 5 yerine 3 ve 4 olarak geçmesinin sebebini anladınız herhalde. Üstte de belirttiğimiz gibi ListBox nesnesinde ilk endeks 0’dır.

3. ListBox’un RowSource özelliğini kullanarak da alabiliriz.

  ListBox1.ColumnCount = 5
  ListBox1.RowSource = "Sayfa1!A2:E10"

Bu yöntem doğrudan çalışma sayfasındaki bir aralıkla bağlantı oluşturduğu için verilerin ListBox nesnesinde çalışma sayfasındaki formatını koruduğunu görüyoruz.



Bu arada ListBox nesnesindeki verileri temizlemek için kullanılan kodları da hatırlatayım:

Bunlar da doğal olarak verilerin alış biçimine göre değişmekte.

RowSource
metoduyla alınan verileri temizlemek için:

  ListBox1.RowSource = ""
‘Bu şekilde çalışma sayfası ile bağlantıyı koparmış oluyoruz.

Dizi ve AddItem metoduyla alınan veriyi temizlemek için:

ListBox1.Clear

Şimdi sıra geldi verileri A-Z düzeninde sıralamaya.

ListBox nesnesine aldığımız çok sütunlu bir tabloyu istediğimiz sütunu baz alarak sıralatabiliriz. Bunun için her sütuna birer Label başlık oluşturduk. Baz almak istediğimiz sütunun başlığını tıklamak suretiyle sıralamayı gerçekleştirebiliriz. Bu sebeple Label nesnelerinin Click olayına gerekli kodları yazdık:

Private Sub Label1_Click()
  Liste = ListBox1.List 'Değişkenimize ListBox'taki listeyi aldık 
  ListBox1.RowSource = "" 'Eğer veriler bu metot ile alınmışsa bağlantıyı koparmamız gerekiyor
  ListBox1.List = Sirala(Liste, ListBox1.ColumnCount, 1)
End Sub

Bu kodlar 1.başlık için geçerli, sıralama kriteri olarak 1.sütundaki verileri baz almakta. Bu şekilde diğer Label nesnelerinin de Click olayına ayni kodları yazabiliriz, sadece baz aldığımız sütunlara göre sütun numaraları değiştirmemiz yeterli olacaktır. Dikkat ederseniz bu kodlar içerisinde Sirala adında bir fonksiyon çağırmaktayız. Bu fonksiyon sıralama işlemini yaptırmak için bizim hazırladığımız Kullanıcı Tanımlı Fonksiyon (KTF).

Private Function Sirala(Liste As Variant, Sutun_Adedi As Byte, Siralanacak_Sutun_No As Byte)
  Dim i As Integer, j As Integer, say As Byte, x As Variant

  For i = LBound(Liste) To UBound(Liste) - 1
    For j = i + 1 To UBound(Liste)
      If StrComp(Liste(i, Siralanacak_Sutun_No - 1), Liste(j, Siralanacak_Sutun_No - 1), vbTextCompare) = 1 Then
        For say = 0 To Sutun_Adedi - 1
          x = Liste(j, say)
          Liste(j, say) = Liste(i, say)
          Liste(i, say) = x
        Next
      End If
    Next j
  Next i
  Sirala = Liste
End Function

Fonksiyondaki Siralanacak_Sutun_No argümanı bize sıralamak istediğimiz sütunu seçme imkânı veriyor.

Sütun başlıklarını tıklamak suretiyle istediğimiz sütuna göre sıralama yapabiliriz, yani ListView nesnesinde olan bu özelliği ListBox’a da katmış oluyoruz.

Bu KTF’de sıralama işlemini gerçekleştiren StrComp fonksiyonu.

M.Temel Korkmaz Hoca’mızın EXCEL ile PROGRAMLAMA–1 kitabının 307.sayfasında StrComp fonksiyonu şu şekilde açıklanmış.

StrComp – İki String (metinsel) ifadenin karşılaştırma sonucunu verir.
    StrComp ( ifade1, ifade2 , Karşılaştırma )
Karşılaştırma: Bu argümana 0 (sıfır) değeri ( vbBinaryCompare ) verilirse büyük küçük harf ayrımı yapılır. Bu argüman 1 değerini ( vbTextCompare ) alırsa bu ayrım yapılmaz.

DİKKAT: Sadece “i” harfi problem çıkartabilir. “i” karakteri “I” karakterine dönüştürülebilir. Yani burada 2 karakter sırası karşılaştırılıyor ve sonuç bir tamsayı döndürüyor. Döndürülen sonuç “1” ise ifade1 büyüktür, “-1” ise ifade2 büyüktür, “0” ise ifade1=ifade2.

Özetle fonksiyonumuz bir sırada her üst ve alttaki metinleri karşılaştırıyor ve bunun sonucunda döndürülen değere göre bunların yerlerini değiştiriyor ve ya olduğu gibi bırakıyor.

Normalde, yani tüm verilerimiz metin olsaydı üstteki KTF işimizi görürdü. Ancak bizim örneğimizde formatlı sayı ve tarih içeren tablomuz olduğu için metin içeren sütunlara göre sıralama yapsak bile sayı ve tarih formatlarının bozulmasıyla karşı karşıya kalırız:

 

Üstteki resimden de görüleceği üzere Adi sütununa göre sıralama yaptık, ancak Maaşı ve Doğum Tarihi sütunlarındaki formatların bozulduğunu görüyoruz. Ayrıca Maaşı’na veya Doğum Tarihi’ne göre sıralama yapmak istersek, sıralamanın doğru olmadığını görürüz. Alttaki resimde Maaşı’na göre yaptığımız sıralamayı görmektesiniz.

 

Bu şekilde sıralamanın sebebine gelince StrComp fonksiyonunun karşılaştırdığı ifadelerin hepsini metin olarak görmesidir. Bunlar bizim istemediğimiz sonuçlar ve dolayısıyla biz bu kodları biraz daha geliştirmemiz lazım.

Private Function Sirala(Liste As Variant, Sutun_Adedi As Byte, Siralanacak_Sutun_No As Byte)
  Dim i As Integer, j As Integer, say As Byte, x As Variant, sira As Integer

  For i = LBound(Liste) To UBound(Liste) - 1
    For j = i + 1 To UBound(Liste)
      If Siralanacak_Sutun_No = 4 Then
        sira = IIf(CDbl(Liste(i, Siralanacak_Sutun_No - 1)) > CDbl(Liste(j, Siralanacak_Sutun_No - 1)), 1, -1)
        ElseIf Siralanacak_Sutun_No = 5 Then
          sira = IIf(CDbl(CDate(Liste(i, Siralanacak_Sutun_No - 1))) > CDbl(CDate(Liste(j, Siralanacak_Sutun_No - 1))), 1, -1)
        Else:
          sira = StrComp(Liste(i, Siralanacak_Sutun_No - 1), Liste(j, Siralanacak_Sutun_No - 1), vbTextCompare)
        End If
        If sira = 1 Then
          For say = 0 To Sutun_Adedi - 1
            x = Liste(j, say)
            If say = 3 Then
              Liste(j, say) = Format(Liste(i, say), "#,##0")
              Liste(i, say) = Format(x, "#,##0")
           ElseIf say = 4 Then
              Liste(j, say) = Format(Liste(i, say), "dd.mm.yyyy")
              Liste(i, say) = Format(x, "dd.mm.yyyy")
           Else:
              Liste(j, say) = Liste(i, say)
              Liste(i, say) = x
          End If
        Next
      Else:
         For say = 0 To Sutun_Adedi - 1
           If say = 3 Then
              Liste(j, say) = Format(Liste(j, say), "#,##0")
           ElseIf say = 4 Then
              Liste(j, say) = Format(Liste(j, say), "dd.mm.yyyy")
           Else:
              Liste(j, say) = Liste(j, say)
           End If
        Next
      End If
    Next j
   Next i
   Sirala = Liste
End Function

Bu KTF’un içerisinde 4.sütunun Sayı, 5.sütunun ise Tarih formatları içerdiğini bildirmek suretiyle doğru sıralama yapabiliyoruz. Örneğin Maaşı’na göre yapalım:



Bir de Doğum Tarihi’ne göre deneyelim:



Gördüğümüz gibi artık doğru sonuçlar alıyoruz. İnşallah bu makale ile kafanızdaki bazı sorulara cevap vermiş oluruz

Destek
M.ÖZTÜRK - Y.KARAMAN
Bu siteyi, "Hayatını çocuklarının Ahlâklı ve Dürüst yetişmesi için harcamış olan Cefakar ve Fedakar, Canım ANNEM'e adadım."
Copyright © 1998-2011 M. Temel Korkmaz - Tüm hakları saklıdır.