Excel VBA Macro Find, Find Next Konu Anlatımları ve Cozumlu Ornekler

FIND - FIND NEXT

İÇİNDEKİLER

1 - Find/Find Next Nedir?

    Belirlediğimiz bir satırda, sütunda, tabloda, listede veya bir çalışma sayfasında eğer özel bir sayı, kelime veya hücre hatta aradığımız bir kişiye ait telefon numarası adres veya her türlü önceden girilmiş bir veri arıyorsak, en kısa yoldan Find ve Find Next metotlarını kullanarak, istediğimiz her türlü sonuca ulaşabiliriz. Aradığımız herhangi bir şeye ait verileri MsgBox kullanarak ekranda görebiliriz.

    İsterseniz iş yerinizde çalşıan bir personelin dil sınavından aldığı notu öğrenmek isteyin, ister de oto servis sahibi olun ve kimin hangi plakalı hangi model arabaya sahip olduğunu öğrenmek isteyin. Sadece isim girerek bu verilerin ekranda MsgBox ile yazdırılmasını sağlayabilirsiniz. Aynı şekilde bir oto parçacı olun. Envanterinize kaydettiğiniz ürünlerden kaç tane kaldığını, hangi otomobile ait olduğunu ve en basitinden fiyatına Find ve Find Next kullanarak hemen ulaşabilirsiniz. 

    

FIND

    Çoğunlukla üzerinde duracağımız detaylı bir şekilde inceleyeceğimiz kısım Find(Bul-Ara) metodur. Çünkü kelime anlamından da çıkartılabileceği için asıl arama olayını bu metot gerçekleştirir. Find metotu aradığı içeriğin bulunduğu ilk hücreyi bulduğu zaman işlem sonlanır. 

FIND NEXT

Eğer listede aradığımız isimden, numaran vb birden çok varsa ve biz sırayla aradığımız kelimenin içerisinde bulunduğu bütün hücrelerde bir arama yapmak istiyorsak, o zaman FindNext kullanırız. Çünkü Find bir sonuca eriştiği zaman işlem sonlanır. Örnek vermek gerekirse ard arda Rambo 1, Rambo 2,..Rambo 6 gibi filmlerin sıralandığını varsayalım. Eğer Find ile Rambo kelimesini aratırsak, Find bize Rambo 1’i bulur ve işlem sonlanır. Ancak FindNext ile tek tek bütün Rambo filmlerini görebiliriz. Tabi bu esnada FinNext için ek bir kaç satır daha kod yazmamız gerekecek ancak ulaşmak istediğimiz bütün verilere de ulaşmış olacağız.

Örnek 1

    Daha önceki örneklerimizde de bir çok kez kullandığımız ‘MARKA VE MODELINE GORE OTOMOBIL FIYATLARI’ tablosu üzerinde Find ve FindNext metodunun uygulamasını yapalım. Öncelikle aşağıdaki tablomuzu bir kez daha hatırlayalım.  Şimdi bununla ilgili birkaç alternatif oluşturalım. Elimizdeki tablo sadece 15 farklı arabadan oluştuğu için burada bu metotları kullanmak anlamsız gelebilir. Ancak bu tabloyu sadece dersi anlayabilmek için kullanıyoruz. Binlerce satırlık verilerde, özellikle seri numaralar ile numaralandırılmış envanterde bu işlemin ne kadar faydalı olabileceğini ders sonunda kavramış olacaksınız.

    Peki biz bu tabloda neyi sorgulayabiliriz ve öğrenmek istediğimiz veriye nasıl ulaşabiliriz.

    – Araç modeli girerek fiyat,

    -Aynı markanın farklı modellerine ait fiyatlar,

    -Bir modelin yakıt tipi,

    -Bir modelin Donanımı,

    -Bir modelin Yıllık MTV’si

    -Marka veya modelin yılı

    kısaca, sütunlarda yazan her türlü veriyi istediğimiz veri cinsini girerek sorgulayabiliriz. 

Find ve Find Next Döngüleri Örnek 1

 

1.1 - Find Metoduna Ait Parametreler

    İlk olarak Find metodunu ve bu metoda ait olan parametreleri tanıyalım. Yazacağımız Sub-Routine içerisinde .Find(  yazdığımız zaman aşağıdaki parametreler listesini göreceksiniz.

Find ve Find Next Döngüleri Örnek 2

    Bu parametrelerin görevlerini Find metodu üzerinde tıklayıp ‘F1’ e basarak Help menüsünden de görebilirsiniz. Bu kısımda Help sayfasındaki açıklamalara ek olarak biraz da  yorum eklenerek parametrelerin görevleri aşağıda açıklanmıştır.

 

 

What: 

    Aranılan veridir. String, integer gibi excel veri tiplerinden herhangi biri olabilir. Tek mecburi parametredir.

After: 

    Sonrasında arama işleminin başlatılmasını istediğiniz hücredir. Arama işlemi sizin bu girdiğiniz hücreden sonra başlar. Seçtiğiniz o hücreyi kapsamaz. Sadece tek bir hücre girebilirsiniz. Arama işlemi bir döngü oluşturmadığı sürece bu hücrede arama yapılmaz. Eğer bu parametreyi boş bırakırsanız arama işlemi seçtiğiniz alanın en üst sol köşesinden başlatılır.

LookAt: 

    XlPart ve XlWhole olmak üzere iki adet constant sadece bu parametreye yazılabilir. XlPart; yazdığınız veri başka bir verinin içerisinde dahi geçiyorsa, aramayı sonlandırır. Örnek eğer ‘Dam’ kelimesini aratmak istiyorsunuz. Eğer ‘XlWhole’ yani birebir olsun yerine ‘XlPart’ constantını kullanırsanız, ‘Damat’, ‘Damar’, ‘Damla’ gibi sözcükleri de Find metodu bulacaktır.

LookIn: 

Bilgi tipidir. 

SearchOrder: 

Aramanın Sütun boyunca mı satır boyunca mı yapılacağıdır. XlByRows(satır), XlByColumn(Sütun)

SearchDirection: 

Aramanın yönünü tayin eder.

MatchCase: 

Aramanın büyük küçük harfe karşı hassas olup olmama durumudur. Default ayarlarında bu parametre ‘False’ olarak seçilidir, yani arama işlemi büyük küçük harfe karşı hassas değildir. 

MatchByte: 

Sadece Double-type dil desteği seçildiyse veya yüklendiyse kullanılır. Kullanılmayacağı için açıklama kısa kesilmiştir.

SearchFormat:

Arama formatıdır.

 

    Artık Find metodunun parametrelerinin görevleri açıklandığına göre, küçük örneklerde Find metodunun kullanımına geçilebilir.

İlk örneğimizde hücreleri, hücrenin içerisinde yazan renge boyama çalışması yapalım.

 

    Sol tarafta sadece içerisinde renklerin yazılı olduğu, başlık hariç 6 hücreden oluşan bir sütun var. Çalışma olarak bu tablo içerisinde renkleri Find metodu ile arayacağız ve aynı rengin içinde yazılı olduğu hücrenin içinde yazılı olan renkte boyanmasını sağlayacağız.

    1-Bu tablo arama yapılacak aralığı oluşturduğundan, ilk olarak Sub-Routine’de bu tablonun alanının tam olarak belirlenmesi gereklidir. Çalışma sayfasında bu alan tam olarak Range(“c4:c6”) hücrelerini kapsamaktadır. Artık Range belli olduğuna göre ikinci aşamaya geçebiliriz.

    2-Find metodu ile arama yapıldığında, aradığımız veriyi barındıran hücre bulunur. Yani metot yanıt olarak bir hücre(yani bir alan/range) geri dönmektedir. Bu kapsamda metodun arama sonucu olarak geri döndüğü alan verisini tutabilecek bir değişkene ihtiyaç duyulmaktadır. Bu sebepten ötürü Range veri tipinde bir değişken tanımlanmalıdır. Daha sonrasında ise Find’ın sonucu ‘Set’ ile bu range veri tipinde oluşturulan değişkene atanır.

    3-Son olarak  da değişkenin adı ile istenilen özelliği değiştirilir. 

        Degisken.Interior.Color=vbRed / vbYellow/ vbPurple / vbBlack / vbBlue / vbGreen 

    Şimdi yukarıdaki maddeler göz önünde bulundurularak hazırlanmış olan Sub-Routine’i inceleyelim.

    Find metodu kullanılırken mecburi parametre olan What parametresi ile birlikte, mecvuri olmayan parametrelerden LookAt ve MatchCase parametreleri de kullanılmıştır. Burada amaç; hem büyük küçük harfe duyarlı hem de sadece yazılan verinin birebir aynısının bulunmasının istenmesidir. Find metodunda parametreleri vigül ile atlayarak gitmekten ziyade parametrelerin adları ile parametrelerin yazılması tercih edilmiştir. Bunun sebebi hem ortaya çıkabilecek karışıklıkların engellenmesi hem de kodun parametrelerin belirtilmesiyle daha kolay anlaşılabilir olmasıdır.

                                                                       Set Range Tipi Degisken = Range(…).Find(What:=”Sarı”, LookAt:=XlWhole, MatchCase:=True)

Find ve Find Next Döngüleri Örnek 4

    En basit haliyle yazılan bu Sub-Routine’in çözümlenmesi;

-Alışkanlık olması gereken sayfa seçimi

-Range tipi değişken tanımlanması

-Degiskenin Find metodu ile bulunan Range verisine tayini

-Degisken hücresinin içinin renginin sarıya boyanması

Bu 2 numaralı örnekte ise Sarı rengin arandığı alan, Renkler adında Range tipi bir değişkene atanmıştır. Bu aşamadan sonra Find metodu kullanılırken de;

Set RenkHucresi=Renkler.Find(…     şeklinde değiştirlmiştir.

3 numaralı örnekte ise sonradan başka renklerin de eklenebileceği düşünülerek, Renkler değişkeni dinamik hale getirilmiştir. Artık renkler listesinin sonuna istediğimiz kadar renk ekleyebiliriz. Yapılan basit değişiklikten sonra listenin altına ne eklenirse eklensin, renklerin aranacağı alan aşağı doğru uzayacaktır.

     Set Renkler = Range(“C4”, Range(“C4”).End(xlDown))

 

Önemli Uyarı

     Find metodu ile yapılan arama işleminde eğer yanlış kelime girdiysek veya gerçekten aradığımız veriyi metot bulamadıysa, metot bir Range yerine ‘Nothing’ döner, yani ‘Nothing’ yanıtı verir. Range olarak tanımlanmış olan değişkene ‘Nothing’ değeri atanırken herhangi bir sorun yaşanmaz. Yani Range tipinde bir veri ‘Nothing’ olabilir, yani boş olabilir. Ancak biz ne zamanki bu değişken üzerinde bir değişiklik yapmak istersek, mesela rengini değiştirmek veya seçmek gibi, işte o zaman Sub-Routine ‘Run-Time Error’ verir. Bu nedenle Sub-Routine’in bu şekilde arıza yapma durumuna karşın If bloğu kullanılarak yapılan değişkenin ‘Nothing’ olması durumunun kontrol altına alınması, kodun daha verimli ve kesintisiz çalışmasında yardımcı olacaktır. 

 

 

      Hata oluşturabilmek için örneğimizde aradığımız “Sarı” kelimesini “Sar” kelimesine değiştirdik.

   İlk görselde, F8 ile Sub-Routine çalıştırıldıktan sonra RenkHucresi değişkenine başarılı bir şekilde ‘Nothing’ in atandığı görülebilmektedir.  Sub-Routine’in bu aşamasında herhangi bir sorun ortaya çakmamaktadır. 

    





    Ancak F8 ile alt satıra geçildiğinde yani değeri ‘nothing’ olarak atanan değişkenin yani olmayan bir range değişkeninin içinin rengi değiştirilmeye çalışdığında ise bu sefer alt görselde gördüğünüz ‘Run-Time Error’ meyadana gelmektedir. Çünkü Sub-Routine olmayan bir range’in değerini değiştirmeye çalışmaktadır.

 

    Yazdığımız basit If bloğu ile artık Find birşey bulamadığı zaman kodun hata vermesi engellendi ve ayrıca da ekrana MsgBox yardımyla “Aradığınız şey bulunamamıştır.” yazılması sağlandı. 

    Find metodunun ‘Nothing’ dönmediği durumda ise yine Else ifadesinin altındaki kod çalışacak ve ilgili hücrenin içi sarıya boyanacaktır. 

    Dersin bir sonraki aşamasında, aranmasını istediğimiz veriyi InputBox yardımıyla kullanıcıdan alıp, Sub-Routine’i biraz daha geliştireceğiz.

Örnek 2

    Yukarıda aranılan verinin yazılı olduğu hücre bulunup, hücre içinin rengi değiştirtirildi. Şimdi ise yukarıdaki ‘MARKA VE MODELINE GORE OTOMOBIL FIYATLARI’ tablosunda nasıl sorgulama yapılabildiğini göreceğiz. İstenilen verilere ulaşmak için Find metodu kullanılacak olup, yeni öğrenilen Find metodunun kullanılmasını, önceki Appliciation.InpuBox ve düğmelere makro eklemek gibi konular ile birleştirerek, basit sorgu işlemleri gerçekleştirilecek.

    Otomobil envanterinde 11 markaya ait toplam 15 farklı model bulunmaktadır. Sorgulama için kısa görünen bu envanter listesi üzerinde yapacağımız bütün işlemler, çok uzun listeler için de geçerli olacağı için, örnek olarak üzerinde çalışılmasında sakınca yoktur. 

    Model isimlerinin tamamiyle birbirinden farklı olmasından dolayı Find metodu hatasız bir şekilde çalışacaktır. Eğer Find metodunu Find Next olmaksınız marka ile sorgulama yapmak için kullansaydık, birden fazla modele sahip markaların sadece listenin üst sırasındaki ulaşabilirdik. Bu nedenle örneğin 2. aşamasında marka ile sorgulama yaparken Find Next metodunu kullanılarak bir markaya ait bütün modellerin fiyatları görülebilecektir.

    Hatırlanması amacıyla ‘MARKA VE MODELINE GORE OTOMOBIL FIYATLARI’;

Alt kısımda modele göre fiyatın sorgulanmasını sağlayan Sub-Routine ve Sub-Routine’i oluşturan 3 aşama detaylı bir şekilde açıklanmıştır.

    İlk aşama değişkenlerin tanımlanmasıdır. 

    İlk Değişken olan AramaBolgesi, istenilen verinin aranacağı aralığı değer olarak alacaktır. Yani 2.Aşamada bu değişkene bir aralık tanımlandığı zaman AramaBolgesi, Range(“C5:F32”) gibi bir aralığı tanımlıyor olacaktır. Ve Find ile kullandıldığında uzunca aralığı yazmak yerine sadece değişken ismi kullanılarak, daha temiz ve basit bir kod yazılabilecektir.

    Model_Ismi değişkeni ise InputBox ile kullanıcıdan alınan veriyi bünyesinde tutacaktır. Bu sayede bir arama yaparken kodun ilgili satırına gidip de aranacak kelimeyi değiştirmeye gerek kalmamaktadır. Aranacak kelimeyi InputBox ile aldığımız ve Find metodunda değişken kullanıldığından herhangi bir revizyon olmadan her seferinde farklı bir kelime aranabilecektir. Değişken kullanmanın faydaları bu örnekte net bir şekilde görülmektedir. 

    Model_Sonuc değişkeni ise Find metodunun verdiği Range veri tipini bünyesinde tutacaktır.

 

    Bu aşamda ise değişkenlere değer atanması işlemi gerçekleştirilmektedir. Range tipinde olan AramaBolgesi’ne tanımlayacağı alan belirtilmiştir. Daha sonradan listeye onlarca hatta yüzlerce araç eklense dahi, End(XlDown) ile  oluşturulmuş olan dinamik alan, her seferinde bütün model sütununu en son satıra kadar kapsayacaktır.

    String veri tipinde olan Model_Ismi değişkenine değeri InputBox ile atanmaktadır. Kod içerisinde değişken ve InputBox kullanımı, Sub-Routine her çalıştırıldığında kodun içerisinde bir değişiklik yapmaksızın, farklı bir model sorgulanabilmesine olanak vermektedir..

    Model_Sonuc değişkenine ise AramaBolgesi içerisinde yer alan, Model_Ismi değişkeninin bulunduğu hücrenin referansı[Range(“C8”) gibi] atanacaktır. 

    Bu aşamada ise Find metodundan ‘Nothing’ olarak dönen sonuçların, hata gibi değerlendirilmesinin önleyebilmesi adına If bloğu kullanılmıştır.

    Yapılan kurguya göre, eğer Find metodu Nothing yanıtını verirse, bir MsgBox açılıp kullanıcının aradığı araç modelinin envanterde bulunmadığını kullanıcıya bildirecektir.  

    Ancak aranan modele ait bilgiler envanterde varsa bu sefer yine bir MsgBox açılacak ve marka model ve fiyat bilgisini ekrandan kullanıcıya iletecektir. MsgBox üzerindeki ‘OK’ tuşuna basıldığında ise Sub-Routine sonlanacaktır.

    Sub-Routine’in 3.Aşamasında yer alan If bloğunun Else ifadesinin altında yer alan MsgBox ile ilgili yaşanabilecek karışıklıkları önleyebilmek adına birkaç not;

    Find metoduna ait parametreler girilirken aranılan kelimenin aramalarda birebir olmamasına karar verilmiştir. LookAt:=XlPart ile bu seçim yapılmıştır. Bunun sonucunda örneğin Focus modelini aramak için sadece fo yazmamız yetecektir. Ancak Msgbox ta eğer biz aranan kelimeyi yani Model_Ismi değişkenini yazdırmak istersek,  fo kelimesi yazdırılmış olur. Bunu engellemek için MsgBox ta yazdırılan kelimeyi Model_Sonuc alanının değeri olarak güncelledik. 

    Range veri tipinde olan Model_Sonuc değeri de bir hücre referansı olarak kullanılarak, marka ve fiyat verilerini taşıyan hücrelere Offset kullanarak ulaşılmış ve değerleri MsgBox’ta kullanılmıştır.

 

    Aşağıdaki videoda yazılmış olan Sub-Routine'in, tablomuz üzerinde yaptğımız sorgulamalara nasıl yanıt verdiğini görebilirsiniz.

2- FINDNEXT Metodu

    Şimdi FindNext metodu yazılmış olan Modeli Girerek Fiyat Sorgulaması yaptığımız Sub-Routine içerisine entegre edilecek. Bu işleme geçmeden önce FindNext metodunu biraz daha yakından tanıyalım. 

    FindNext, metodu eğer sorgulama işleminde bulunan bir veri varsa ve hatta aynı verinin farklı varyasyonları varsa, işte bu varyasyonların gözden kaçırılmaması için kullanılmaktadır. Ancak bu metodun da özelliği yine bir kereliğine kullanıldıktan sonra Sub-Rouitne’in en baştan çalıştırılması gerekmesidir. Şimdi bu duruma karşı biz FindNext metodunu bir döngü içerisinde kullanacağız. Do Until döngüsü içerisine yerleştirilecek olan FindNext metodu için, ilk başta döngünün son bulabilmesine olanak sağlayacak bir koşul veya hedef belirlememiz gerekmektedir. Bu aşamada listenin en üstünde yer alan ve referansı (Range(“c5”) bir referanstır) bir değişkene kaydedeceğiz ve FindNext ile Sub-Routine aradığımız kelimeleri başka bir satırlarda ararken, her seferinde o ilk hücre referansıyla aynı olup olmadığını kontrol etmesini sağlayacağız. Bu sayede Do Until döngüsünü liste başına döndüğü zaman kendi kendini sonlandırabilek.

    FindNext metodunun yalnızca bir adet parametresi vardır. O da ‘After’ yani ‘sonra’ parametresidir. Bu parametre yerine, arama kelimemizin değerini tutan Model_Sonuc değişkeni yazılarak, Sub-Routine tamamlanmış olur.

    Şimdi Sub-Routine’i ve ilk koda göre yapılan değişiklikleri inceleyelim

 

    İlk olarak Do Until döngüsünde koşul olarak kullanılacak olan değişken tanımlandı. Bu değişken aranılan verinin yer aldığı, listenin en üstünde yer alan hücrenin referansını saklayacaktır.

 

 

 

 

    Ek 2’de Ek 1’de tanımlanmış olan Ilk_Sonuc değişkenine, Find metodunun verdiği ilk sonucun, yani hücrenin referansı atanmaktadır. (Range(“C6”)) gibi.

    Ek 3′ te Do Until döngüsü Sub-Routine’e ekleniyor.

        Ek 4 de FindNext metodu kullanılıyor. Burada tek parametre, hangi kelimeden sonra veri aranmaya devam edilecekse o kelimedir, o veridir. Onun için buraya Marka_Sonuc değişkenini parametre olarak giriyoruz. Bu sayede her seferinde bir sonraki benzer veri / kelime aranabiliyor.

 

    NOT:

    Bu arada AramaBolgesi model sütunu yerine marka sütunu olarak tanımlanmış ve Range(“C5”, Range(“C5”).End(XlDown)) olarak alan güncellenmiştir.

Dünya Çapında Araştırmacılara Ait Çalışmaları Okumak İsterseniz https://www.researchgate.net/profile/Ender_Dagdelen adresini Ziyaret Edebilirsiniz. Ana Sayfaya Dönmek İsterseniz De Aşağıdaki Tuşu Tıklayınız.

Herkese İyi Çalışmalar…

Soru ve Önerileriniz İçin;

[email protected]