VBA Find (BUL) Fonksiyonu
Son zamanlarda Excel ile ilgili gelen sorularda sık sık VBA (Makro) içerisinde Find (Bul) ve FindNext (Sonrakini Bul) soruları gelmeye başladığı için sizlere bu konu hakkında detaylı bir yazıyı yazma kararı aldım. Bu kararı almamdaki en önemli sebeplerden birisi de detaylı bir şekilde İnternet üzerinde bu konuya maalesef Türkçe kaynaklarda pek değinilmemiş. Ancak yazıyı tamamen örnekleri uygulayarak incelediğinizde Find komutunun ne kadar kolay olduğunu anlayacağınıza eminim.
Ayrıca bu yazıyı tamamladıktan sonra ilk fırsatta da Youtube videosunu çekip sizlere sunacağım.
Excel üzerinde hazırladığımız hemen hemen bütün makrolar da bulma fonksiyonundan yani find komutundan yararlanırız. Bende bundan sonra bulma komutu için Find diye bahsedeceğim. Bu komut hakkında bilinmesi gereken en önemli üç şey ise şunlardır.
- Find komutu bir Range (Hücre) üyesidir.
- Find komutu belirli bir değer veya biçim içeren hücre aralığında arar.
- Esasen bir Excel çalışma sayfasındaki Ctrl+F ile ulaşacağımız bul komutu ile aynı işlevi görür.
Find komutu parametreleri
Find işlevi excel vba‘daki diğer elemanlar gibi bazı parametlere de sahiptir. Bu parametler ile Find komutuna esneklik ve özellik kazandırılabilir. Ancak bu parametlerin hepsini kullanma zorunluluğu yoktur. Sadece ilk parametreyi zorunluluğumuz vardır ki o da aradığımız değeri komuta tanıtmak içindir. Şimdi bu parametlere ve anlamlarına bakalım.
What | Aranacak veri, bu komutta ki tek zorunlu parametredir. |
After | Aramanın başlamasını istediğimiz hücre. Ancak belirtilen hücre dahil değildir. Örneğin Range(“C3”) dediğimizde arama C4’den başlar. |
LookIn | Arama yapılacak yer, xlValues(Değerler), xlFormulas(Formüller), xlComments(Açıklamalar), xlCommentsThreaded(Yorumlar) |
LookAt | Aramada hücredeki veri ile xlWhole(tam eşleşme) veya xlPart(kısmi eşleşme) |
SearchOrder | Arama bölümü xlByRows (Satırdan) veya xlByColumns (Sütundan) |
SearchDirection | Arama Yönü xlNext (Sonraki) veya xlPrevious (Önceki) |
MatchCase | Aramayı büyük küçük harfe duyarlı hale getirmek için kullanılır. Varsayılan değer False dir. |
MatchByte | Sadece Çift byte kullandıysanız kontrol True veya False |
SearchFormat | Biçimsel aramalarda kullanılır. Application.FindFormat |
Parametre | Açıklama |
Parametreleri Kullanırken Dikkat Etmemiz Gerekenler
Yukarıdaki tabloda yer alan Find komutunun parametrelerinde seçimimizi yaparken dikkatli olmamız gerekmektedir. Parametrelerin yukarıdaki tabloda da yazmış olduğum gibi sadece ilki yani aranacak veri kısmı zorunludur. Diğerleri hakkında çok spesifik bir özellik istemiyorsak hataya düşmemek için kullanmamız daha uygun olacaktır.
Örneğin LookIn parametresini xlComments olarak ayarlarsanız , yalnızca yorumlarda bir değer arar. Siz ise Find’ı komutunu VBA üzerinde herhangi bir yerde ilk defa kullandığınız için verilen parametreler bir nevi hafızaya alınır ve sonraki sefere herhangi bir yerde tekrar Find komutunu kullandığımızda ve LookIn parametresine değer vermediğinizde mevcut LookIn ayarı Comments (Yorumlar) olarak kalacaktır. Bu sorunu çözmek için gerekmedikçe parametre kullanmaktan kaçınmak veya her seferinde parametreleri tam olarak kullanmak gerekmektedir.
Bu işlem sadece LookIn parametresi için değil LookAt, SearchOrder ve MatchByte parametreleri için de geçerlidir.
Find işlemi belirtilen arama aralığının sonuna ulaştığında, aralığın başlangıcına kadar geri gider. Bu başa dönme işlemi gerçekleştiğinde bir aramayı durdurmak için yapmamız gereken ise bulunan ilk hücrenin adresini kaydetmek ve tekrar edilen her hücre adresini de bu kaydedilen hücre ile kontrol etmek gerekir.
Find İşleminde Çıkan Sonuç Değeri
Şayet aranan değer bulunursa sonucu hücre olarak yani Range değeri olarak bulur ve gösterir. Ancak aranan değer bulunmazsa bize sonucu Nothing olarak gösterir.
Örnek Kullanım – Aşağıda Basit bir Find yani Ara Bul örneğini görebilirsiniz. Bu örnekte A1 ile A5 arasındaki hücrelerde “10” değerini arar bulunca da bulduğu hücreyi seçili hale getirir.
Sub basit_arama() 'Aşağıdaki kod A1 ile A5 aralığında 10 değerini arar ve bulduğu hücreyi seçili hale getirir. Range("A1:A5").Find(10).Select End Sub
Örnek Kullanım – En basit haliyle sonucunda Nothing değerini döndüren yani aradığı değeri bulamayan bir örnekte ise aşağıdaki hatayı verecektir.
Sub basit_arama() 'A1 ile A5 aralığında 15 değerini arar ve bulduğu hücreyi seçili hale getirir. Range("A1:A5").Find(15).Select End Sub
Bu hata ile karşılaşmamak için aşağıdaki gibi basitçe bir kontrol yaptırabiliriz. Böylelikle find fonksiyonu aradığımız değeri bulamasa bile bir hata ile karşılaşmamış olacağız.
Sub kontrollü_basit_arama() 'Kontrollü bir şekilde A1 ile A5 aralığında 15 değerini arar ve bulduğu hücreyi seçili hale getirir. Dim kontrol As Range Set kontrol = Range("A1:A5").Find(15) If Not kontrol Is Nothing Then kontrol.Select End If End Sub
Find İşleminde En Önemli Parametrelerden After Özelliğini Kullanma
Yukarıda da kısaca bahsettiğim gibi After özelliği belirtilen hücreden sonra arama döngüsüne başlar.
Örnek Kullanım – Aşağıdaki örnekte “10” değerini A1 ile A5 hücreleri arasında aratıyoruz ama After özelliği ile aramaya A1 hücresinden sonra başla diyoruz. Böylelikle resimde de gördüğünüz gibi A1 hücresini değil A3 hücresini seçiyor.
Sub After_basit_arama() 'A1 hücresinden sonra aramaya başlar. Dim kontrol As Range Set kontrol = Range("A1:A5").Find(10, After:=Range("A1")) If Not kontrol Is Nothing Then kontrol.Select End If End Sub
Tabi elimizde iki adet aynı değer bulunduğundan bu şekilde A3 hücresini seçiyor. Şayet A3 hücresindeki değeri değiştirir ve listemizde aranan değerden bir adet kalmasını sağlarsak Find fonksiyonu A2’den itibaren aramaya devam eder ama sonra başa dönerek A1 hücresinde aranan değeri bulur. Daha iyi anlayabilmek için bir üstteki örneği inceledikten sonra hemen alttaki örneği ve resmi inceleyiniz.
Örnek Kullanım –
Sub After_basit_arama() 'A1 hücresinden sonra aramaya başlar. Dim kontrol As Range Set kontrol = Range("A1:A5").Find(10, After:=Range("A1")) If Not kontrol Is Nothing Then kontrol.Select End If End Sub
Yani bu örnekte yazdığımız basit kod işleyiş sırasına göre A2>A3>A4 ve son olarak A1‘di.
Find fonksiyonunda Lookin parametresini kullanma
LookIn parametresi aramamızda Değerler, Formüller, Açıklamalar veya Yorumlar içinde ayırım yaparak sonuca ulaşmamızı sağlar.
Bir hücrenin yalnızca metni olduğunda, bu metin formül VE değer olarak kabul edilir . Ayrıntılar için aşağıdaki tabloya bakın
Not: Ancak burada dikkat etmemiz gereken önemli bir nokta var. Bir hücrede yalnızca metin varsa bu metni xLFormulas ile aramalıyız. Fakat bir formül varsa yada hem metin hemde formül sonucunu arıyorsak o zaman xLValues ile aratmak zorundayız. Daha iyi anlayabilmek adına aşağıdaki tabloya göz atmalısınız.
Not2: xlComments Excel sürümlerinin her birisinde açıklamalarda arama yapmak için kullanılabilir. xlCommentsThreaded ise sadece Office 365 ve üzeri sürümlere eklenen yorum özelliğinden dolayı bu sürümlerde aranabilir.
Find Komutundaki Seçenekler | |
---|---|
Kullanılabilecek Argümanlar | Arama Yeri |
xlFormulas | Metinleri Arar |
xlValues | Hem Metin Hemde Formülleri Arar |
xlComments | Sadece Açıklamaları Arar |
xlCommentsThreaded | Sadece Yorumları Arar |
Find fonksiyonunda LookAt parametresini kullanma
Find LookAt işlevi basit net bir kullanıma sahiptir.
- xlWhole , arama değerinin tüm hücre içeriğiyle eşleşmesi gerektiği anlamına gelir.
- xlPart , arama değerinin hücrenin bir kısmıyla eşleşmesi gerektiği anlamına gelir.
Örnek Kullanım – Basit örnekle göstermek gerekirse;
Sub LookAt_Kullanımı() Dim ilk_bulunan, ikinci_bulunan As Range 'Dilaver kelimesi aranıyor ancak sonuç olarak A3 yerine A2'deki yazı çıkıyor Set ilk_bulunan = Range("A1:A20").Find("Dilaver", Lookat:=xlPart) 'Dilaver kelimesi aranıyor ve tam olarak bulunup A3 seçiliyor Set ikinci_bulunan = Range("A1:A20").Find("Dilaver", Lookat:=xlWhole) MsgBox "Aranan Dilaver kelimesi olduğu halde" & vbCrLf & "1. Bulunan = " & ilk_bulunan & vbCrLf & "2. Bulunan = " & ikinci_bulunan End Sub
Find fonksiyonunda SearchOrder parametresini kullanma
Find SearchOrder parametresi, satır veya sütuna göre arama yapmamıza olanak tanır. xlByRows (Satırdan) veya xlByColumns (Sütundan) arama yapılabilir.
Örnek Kullanım – Bu parametreyi de basit bir örnekle açıklamak gerekirse;
Sub SearchOrder_Kullanımı() Dim KonTRoL1, KonTRoL2 As Range ' Aramada önceliği satıra verir. Set KonTRoL1 = Range("B1:C6").Find("Ahmet", SearchOrder:=xlByRows) Debug.Print KonTRoL1.Address ' Aramada önceliği sütuna verir. Set KonTRoL2 = Range("B1:C6").Find("Ahmet", SearchOrder:=xlByColumns) Debug.Print KonTRoL2.Address End Sub
Find SearchDirection parametresini kullanma
Find SearchDirection parametresinde ileri veya geri arama yapabiliriz. xlNext bir sonrakine doğru arama yapmamızı sağlarken xlPrevious bir öncekine doğru arama yapmamızı sağlar.
- xlNext parametresini kullanarak yapılan arama sıralaması
A1, A2, A3, A4, A5, A6, A7
- XlPrevious parametresini kullanarak yapılan arama sıralaması
A7, A6, A5, A4, A3, A2, A1
şeklinde olacaktır. Basit bir örnekle göstermek gerekirse,
Örnek Kullanım –
Sub SearchDirection_Kullanımı() Dim KonTRoL As Range 'Excel seçili olan hücre A4 hücresi 'Aşağıya doğru arama yapıldığı için sonuç A6 hücresi çıkıyor Set KonTRoL = Range("A1:A7").Find("Ahmet", SearchDirection:=xlPrevious) Debug.Print KonTRoL.Address 'Yukarıya doğru arama yapıldığı için sonuç A3 hücresi çıkıyor Set KonTRoL = Range("A1:A7").Find("Ahmet", SearchDirection:=xlNext) Debug.Print KonTRoL.Address End Sub
Find MatchCase parametresini kullanma
Find fonksiyonunun MatchCase parametresi ile yaptığımız aramalarda büyük/küçük harflerin dikkate alınıp alınmayacağını kontrol edebiliriz. True ve False olarak kullanılabilir.
True – seçeneğinde harfler birebir eşleşmelidir. Büyük küçük kontrolü yapar.
False – seçeneğinde ise büyük küçük eşlemesine bakmaz. Varsayılandır.
Örnek Kullanım – Aşağıdaki örneği inceleyebilirsiniz.
Sub MatchCase_Kullanımı() Dim KonTRoL As Range 'küçük harflerle ahmet'i aratıyoruz Set KonTRoL = Range("A1:A7").Find("ahmet", MatchCase:=False) Debug.Print KonTRoL.Address 'küçük harflerle ahmet'i aratıyoruz Set KonTRoL = Range("A1:A7").Find("ahmet", MatchCase:=True) Debug.Print KonTRoL.Address End Sub
Find MatchByte parametresini kullanma
MatchByte parametresi, çift baytlık karakter kümesine sahip diller için kullanılır. Bunlar Çince / Japonca / Korece gibi dillerdir. Şahsen bugüne kadar bana kullanmak hiç nasip olmadı.
Bunları kullanmıyorsanız, o zaman bu parametre sizinle ilgili değildir.
- Doğru, yalnızca çift baytlık karakterleri çift baytlık karakterlerle eşleştirmek anlamına gelir.
- False, çift baytlık karakterlerin tek veya çift baytlık karakterlerle eşleşmesi anlamına gelir.
Find fonksiyonunda joker “*” karakter kullanma
Excel üzerinde birçok yerde yapabildiğimiz gibi bul işlemlerinde de joker karakter kullanabiliyoruz. Bilinmeyen karakterleri temsil etmek için yıldız “*” işaretini kullanabiliriz.
Konuya birkaç örnek vererek daha fazla anlaşılmasını sağlayalım.
Örnek Kullanım –
Sub Joker_Karakter_Kullanımı() Dim KonTRoL As Range 'İlk iki harfi So ile başlayan ismi arıyoruz. Set KonTRoL = Range("A1:A7").Find("So*") Debug.Print KonTRoL.Address 'Kelimenin içinde yü harfleri geçen ismi arıyoruz. Set KonTRoL = Range("A1:A7").Find("*yü*") Debug.Print KonTRoL.Address 'Son harfleri im ile biten ismi arıyoruz Set KonTRoL = Range("A1:A7").Find("*im") Debug.Print KonTRoL.Address End Sub
Find ile SearchFormat parametresini kullanma
Arama Biçimi diğer parametrelerden biraz farklıdır. Yazı tipi veya hücre rengi gibi bir hücre biçimini aramanızı sağlar.
İlk olarak Application.FindFormat özelliğini kullanarak biçimi ayarlamanız gerekir . Ardından SearchFormat ile aramamızı yapıyoruz.
Örnek Kullanım – Aşağıdaki örnek de A3 hücresi aynı isimle normal ve A6 hücresi aynı isimle koyu olarak ayarlanmış. İki farklı arama türü ile nasıl tespit edilebiliyor bunu görelim.
Sub SearchFormat_Kullanma() Dim KonTRoL As String KonTRoL = "Ahmet" 'Önceki formatları temizle ve yeni format ayarla Application.FindFormat.Clear Application.FindFormat.Font.Bold = True Dim Bulunan As Range 'Bulunan A6 hücresi Set Bulunan = Range("A1:A7").Find(KonTRoL, SearchFormat:=True) Debug.Print "Hücrede bulunan isim "; KonTRoL & " Adresi: " & Bulunan.Address 'Bulunan A3 hücresi Set Bulunan = Range("A1:A7").Find(KonTRoL, SearchFormat:=False) Debug.Print "Hücrede bulunan isim "; KonTRoL & " Adresi: " & Bulunan.Address Application.FindFormat.Clear End Sub
Bir hücreyi yalnızca formatına göre arayabilirsiniz. Başka bir deyişle hücredeki içerik aramada yok sayılır. Bunu da arama dizesine “*” koyarak yapabilirsiniz.
Örnek Kullanım – Sadece dolgu rengine göre bir arama yapacağımız diğer bir örnekte aşağıdaki gibidir. Hücrenin içeriğine bakmadan arama yapılmıştır.
Sub SearchFormat_Kullanma2() ' Önceki formatları temizle ve yeni format ayarla Application.FindFormat.Clear Application.FindFormat.Interior.Color = rgbRed ' Biçimi yok sayar ve herhangi bir içeriğe sahip ilk hücreyi bulur A2 Dim KoNTroL As Range Set KoNTroL = Range("A1:A7").Find("*", SearchFormat:=False) Debug.Print "Bulunan Hücre Adresi "; KoNTroL.Address ' İçeriğe bakmadan dolgu rengi kırmızı olan ilk hücreyi bulur A7 Set KoNTroL = Range("A1:A76").Find("*", SearchFormat:=True) Debug.Print "Bulunan Hücre Adresi "; KoNTroL.Address Application.FindFormat.Clear End Sub
Not: Burada önemli bir hatırlatma yapmak istiyorum. Farkındaysanız örneklerim de hem öncesinde hem sonrasın da Application.FindFormat.Clear ile önceden belirlenmiş sorgu biçimlerini temizledim. Buna dikkat ederek daha önceden yaptığımız Find işlemindeki biçim aramalarını temizlemiş oluyoruz. Aksi takdirde örnekteki gibi bir daha ki aramalarımızda sadece dolgu rengi kırmızı olanlarda arama yapacaktır.
FindNext (Sonrakini Bul) Fonksiyonunun Kullanımı
Find fonksiyonu ile dosyalarımızda nasıl arama yapılacağına yeterince değindik. Ancak ya birden fazla aynı değer var ise ve diğerlerini de görmemiz gerekiyorsa ne yapacağız. Bu işlem için Öncelikle Find fonksiyonunu ardından FindNext (sonrakini bul) fonksiyonunu yani birden çok arama modülünü kullanacağız. FindNext komutunda sadece yukarıda detaylıca bahsettiğim After parametresi kullanılmaktadır.
Örnek Kullanım – İlk örneğimizde basit bir sonrakini bulma işlemi yapıyoruz. Bunun için A1 hücresinden A10 hücresine kadar yazılı olan isimler de Ahmet ismini arıyoruz. Yazdığımız kodlara göre de ilk iki Ahmet ismini bizim için buluyor. Ancak fark edeceğiniz üzere bu örnekte üçüncü Ahmet ismini bulmuyor. Örneği inceleyelim;
Sub FindNext_Kullanma() Dim KoNTroL As Range 'Ahmet'i Find metoduyla aradı ve A3 dekini buldu. Set KoNTroL = Range("A1:A10").Find("Ahmet") Debug.Print KoNTroL.Address 'Ahmet'i FindNext metoduyla tekrar aradı ve A6'dakini buldu. Set KoNTroL = Range("A1:A10").FindNext(KoNTroL) Debug.Print KoNTroL.Address End Sub
Kendini tekrar eden veriler şayet 2’den fazla ise yada kaç adet olduğu hakkında kesin bilgimiz yoksa bu takdirde olası hepsini bulabilmek için kontrol ve döngü yöntemini kullanmalıyız.
İlk öğeyi bulmak için .Find kullanıyoruz . Bir öğe bulursak, diğer öğeleri bulmak için ise .FindNext ile bir Do Loop döngüsü kullanırız .
FindNext aranacak hücreleri tarar. Yani, A10’u bulduktan sonra A1’deki aramaya devam edecektir. Bu da gereksiz bir sonsuz döngüye girecektir. Bu nedenle, bulduğumuz ilk hücrenin adresini saklıyoruz. FindNext bu hücreyi tekrar döndürdüğünde tüm öğeleri bulduğumuzu artık biliyoruz.
Aşağıdaki kod ile Ahmet’in tüm yerlerini bulacağız.
Örnek Kullanım – Yukarıda da açıklamasını yaptığımız bir döngü ile FindNext kullanımını görelim.
Sub FindNext_Kullanma() Dim Aranan, ilkAdres As String Dim KoNTroLYeRi, Bulunan As Range Aranan = "Ahmet" Set KoNTroLYeRi = Range("A1:A10") Set Bulunan = KoNTroLYeRi.Find(Aranan) If Bulunan Is Nothing Then Debug.Print "Not found" Exit Sub End If ilkAdres = Bulunan.Address Do Debug.Print "Bulundu: " & Bulunan.Address Set Bulunan = KoNTroLYeRi.FindNext(Bulunan) Loop While ilkAdres <> Bulunan.Address End Sub
Örnekte gördüğünüz gibi üç hücrede de Ahmet yazısı arandı ve bulundu. Arkadaşlar Find ve FindNext konularındaki eğitimimiz tamamlandı. Zaman zaman konuya güncelleme yapabilirim ancak bu konuda bol örnek yaparak olayı daha iyi anlayabilirsiniz. Sizler için yazıya youtube kanalımdan da örnekler çözdükçe buraya girmeye çalışacağım.
12 yorum