Nümerik Fonksiyonlar

Excel VBA'de Nümerik Fonksiyonlar

Excel VBA'de kullanılmak üzere çok fazla nümerik fonksiyon bulunmamaktadır. Bununla birlikte Excel'in kendisiyle gelen nümerik fonksiyonların birçoğunu WorksheetFunction fonksiyonu aracılığı ile kullanabiliriz. Bununla ilgili detaylı bilgiye ilgili sayfada değineceğiz.

Şimdi VBA içindeki birkaç faydalı numerik fonksiyona bakalım.

Dönüştürme Fonksiyonları

Ön bilgi: Türkiye'de biz "," işaretini ondalık ayraç olarak kullanırken ABD ve dolayısıyla bir ABD firmasının ürünü olan Excel ve VBA "." işaretini ondalık ayraç olarak kullanır. Binlik ayraç olarak ise tersi. Gerçi regional settings (bölgesel ayarlar) ayarlaması yapıldığında Excel'in kendisi de (Sadece Excel, VBA değil) ondalık ayraç olarak "," kullanabilmektedir. Ve nitekim Türkiye'deki bilgisayarların çoğunda bu ayar yapılı haldedir. Ancak VBA "." karakterini her zaman ondalık ayraç için kullanırken, binlik ayraç diye bir şey kullanmaz. VBA dünyasında "," karakteri parametre ayracı olarak kullanılır. Dolayısıyla VBA'deki 2.22 ifadesi Türkçe 2,22 algılanırken 2,22 ifadesi ise 2 ve 22 şeklinde iki ayrı parametre olarak algılanır. Bu 2,22 ifadesi tırnak içinde değilse birçok durumda tek parametre alan fonksiyonlarda hataya neden olurken, tırnak içindeyse metinsel bir ifade olarak algılanır.

Val(String): Parametre olarak aldığı stringi rakama çevirir. Dönüş tipi Double'dır.

Val fonksiyonu, dönüştüreceği değer içindeki ilk sayısal olmayan kısıma kadar olan kısmı sayıya çevirir. Ör: 123asr45 değerini 123'e çevirir.

                        
                            Debug.Print Val("00123") '123
                            Debug.Print Val("123asr45") '123
                            Debug.Print Val("2,22") '2 döndürür. çünkü virgülü non-numerik algılar ve ilk non-numerik karakterden önceki kısmı döndürür
                            Debug.Print Val("2.22") '2,22 döndürür
                            'Debug.Print Val(2, 22) 'hata verir, sanki iki parametre var gibi algılar
                            Debug.Print Val(2.22) '2 döndürür, noktayı non-numerik algılar. Burada 2,22 dönmesini beklediyseniz yukarıda yazılanları tekrar okuyun lütfen
                                
                                

Val'in tarihleri nasıl değiştirdiğini de görelim.

                        
                            Debug.Print Val("21.01.1979") '21,01 döndürür, çünkü ikinci noktayı sayısal olmayan karakter olarak algılar
                        
                        

CInt, CDbl vs (İfade): Bunlar da dönüştürme görevi görürler. C'den sonraki tipe dönüşüm yaparlar. Ör: CInt, içindeki değeri Integer'e dönüştürken, CDbl, Double'a, CLng Long'a. İfade olarak bir string olabileceği gibi daha küçük boyutlu bir numerik değer de olabilir.

Şunu merak etmiş olabilirsiniz. CDbl da Val de double türüne dönüştürüyor. Ne fark var? Neden 2 tane fonksiyon var? Aşağıdaki kodları ve sonuçları ile yukarıdaki Val'in sonuçlarını incelerseniz farkı görebilirsiniz.

                        
                            Debug.Print CDbl("00123") '123
                            'Debug.Print CDbl("123asr45") 'hata alır. numerik olmasını bekler
                            Debug.Print CDbl("2,22") '2,22 döndürür
                            Debug.Print CDbl("2.22") '222 döndürür
                            'Debug.Print CDbl(2, 22) 'hata verir, sanki iki parametre var gibi algılar
                            Debug.Print CDbl(2.22) '2,22 döndürür
                                
                                

Biraz karışık gelmiş olabilir. Özeti şu: Val'i sanki Str fonksiyonu ile string hale gelmiş sayısal ifadeleri sayıya çevirmek için kullanmanız gerekirken, CDbl'i kullanıcı tarafından girilen bir sayısal metni sayıya çevirmek için kullanın.

Yuvarlama Fonksiyonları

Int(Number) ve Fix(Number): İkisi de küsurlu sayıların küsuratını atar. Fark şu: Int, negatif sayılarda aşağı doğru yuvarlarken, Fix sadece küsurat atar. Ör: 3,85 için ikisi de 3 döndürürken, -3,85 için Int -4, Fix ise -3 döndürür.

Round(Number, Duyarlılık): Excel'in built-in (yerleşik) Round fonksiyonundan farklıdır. Excel fonksiyonunda negatif değer girerek sayı 10'un katları şeklinde de yazılabilirken, VBA'de sadece pozitif rakamlar girilebilmektedir. Round(95.458, 1) bize 95.5 değerini verir. Ondalık olarak virgül yerine nokta karakteri yazıldığına dikkat edin.

Negatif değer girip 10'un katları şeklinde yuvarlamak ve RoundUp/RoundDown gibi seçenekleri ele almak için WorksheetFunction'dan faydalanabiliriz.

                        
                                Debug.Print Round(95.458, 1) '95,5
                                Debug.Print worksheetfunction.Round(95.498, -1) '100
                                Debug.Print worksheetfunction.RoundUp(95.498, 0) '96
                                Debug.Print worksheetfunction.RoundDown(95.498, 0) '95
                                    
                                    
Matematiksel Fonksiyonlar

NOT: Trigonometrik fonksiyonlar gibi MIS dünyasında kullanımı az olan veya hiç olmayan fonksiyonlara yer verilmemiştir.

Randomize ve Rnd(Number)

Rasgele sayı üretmek için kullanılırlar. Rasgele sayı üretimi bilgisayarın sistem saati baz alınarak üretilir. Rnd ile 0-1 arasında rasgele sayı üretilir. Sayı üretildikten sonra, teknik olarak bir sonraki rasgele sayının ne olacağı tahmin edilebilir, bu da sonraki sayının rasgeleliğine şüphe düşürür. Bununla birlikte her Rnd işleminden önce Randomize fonksiyonu tek başına kullanılırsa sistemin baz alacağı değer bir nevi resetlendiği için bir sonraki rasgele sayının tahmini imkansızlaşır ve gerçek bir rasgele sayı üretilmiş olur. Özellikle birden fazla rasgele sayı üretmeniz gerektiği durumlarda Rnd öncesinde Randomize kullanmanız önerilir, diğer durumlarda tek başına Rnd iş görecektir.

Rnd, Excel'in RAND fonksiyonu gibi işlemektedir. Aşağıda örnekte 1 ile 100 arasında bir sayı üretilip x değişkenine atanmakta, bu da RANDBETWEEN(1,100) gibi çalışmaktadır.

                        
                            Randomize
                            x = CInt(Rnd * 100)

                            'ancak 10-20 gibi daha üst seviyelerde bir rasgele rakam istenirse
                            x = WorksheetFunction.RandBetween(10, 20)
                                
                                

Abs(number): Mutlak değer üretir. Ör. Abs(-100) 100 değerini verir.

Sayı Formatlama

Sayıları formatlamak için iki fonksiyon bulunmakta: Format ve FormatNumber. Bunların ikisi de aslında String modülünün bir fonksiyonudur. Ama konsept olarak sayılarla ilgili olduğu için burada ele almayı uygun buldum.

Ben bunlardan FormatNumber yerine Format'ı kullanmayı tercih ediyorum. Zaten FormatNumber üzerine de çok fazla online bilgi de bulunmuyor. Format fonksiyonuyla ilgili detay bilgilere ise buradan ulaşabilirsiniz.

Sayılarda formatlama yaparken dikkat edilecek hususlar bellidir: Binlik ayraç, ondalık ayracı, yuvarlamalar ve gerekirse belirli miktarda fazladan 0 gösterimi.

Formatlamada iki temel karakter kullanıyoruz: 0 ve #. Ben bunlardan en çok #'i kullanıyorum. 0'ın farkı şu: Eğer sayının başında belirli miktar 0 olsun istenirse bu kullanılır. Neden böyle bir şey gereksin? Mesela BT ekibine bir liste hazırlıyorsunuzdur, listeyi sizden 10 haneli sayılar şeklinde (başta 0 olacak şekilde) isterler. Mesela sizin göndereceğiniz listedeki sayılardan biri 123 ise bunu 0000000123 şeklinde isterler. 0, aynı zamanda küsuratlarda da fazladan 0 gösterebilir. Mesela 4 haneli küsurat olsun isteniyorsa 3,18'in gösterimi 3,1800 şeklinde olur.

Gerek 0 gerek #, eğer gerekenden az miktarda kullanılmışsa otomatikman gereken adede tamamlanır. (Aşağıda hem 0'ın hem #'in ilk örneklerinde görüldüğü gibi). Ondalık ayraçın solunda sadece 1 adet 0/# olmasına rağmen dört rakamın dördü de gösterilmiştir.

Aşağıdaki örneklerle anlattıklarımızı pekiştirelim. Başlamadan önce "ön bilgi" bölümünde yazan '.' ve ',' işaretlerinin kullanımına tekrar bakmanızı öneririm.

                        
                            Sub formatting()
                                Debug.Print Format(8315.4, "0.000") '8315,400
                                Debug.Print Format(8315.4, "0,000") '8.315
                                Debug.Print Format(8315.4, "0.0") '8315,4
                                Debug.Print Format(8315.4, "0,0") '8.315
                                Debug.Print Format(8315.4, "0000.0") '8315,4
                                Debug.Print Format(8315.4, "0000000.0") '0008315,4

                                Debug.Print vbNewLine
                                Debug.Print Format(8315.4, "#.###") '8315,4. 0 formatından farklı olarak takip eden 0lar görünmez.
                                Debug.Print Format(8315.4, "#,###") '8.315
                                Debug.Print Format(8315.4, "#.#") '8315,4
                                Debug.Print Format(8315.4, "#,#") '8.315
                                Debug.Print Format(8315.4, "####.#") '8315,4
                                Debug.Print Format(8315.4, "#######.#") '8315,4. 0 formatından farklı olarak baştaki fazla 0lar görünmez.

                                'nokta ve virgül beraber
                                Debug.Print vbNewLine
                                Debug.Print Format(8315.4, "0,000.00") '8.315,40
                                Debug.Print Format(8315.4, "#,###.##") '8.315,4
                                Debug.Print Format(8125648315.486, "#,###.##") '8.125.648.315,49
                            End Sub