Genel Bakış
CDec (Type conversion functions), bir ifadeyi Variant veri türünün Decimal alt türüne dönüştüren VBA işlevidir. Çok sayıda ondalık basamak gerektiren hesaplarda, Double veri türünün ikili kesir yapısından doğan küçük yuvarlama farklarından kaçınmak için kullanılır. Para, oran ve bilimsel hesaplarda ara sonuçları kesin tutmanıza yardımcı olur.
Metinden sayıya dönüşümde bilgisayarın bölgesel ayarları (Regional Settings) geçerlidir: Türkçe ayarlarda ondalık ayırıcı virgüldür, İngilizce ayarlarda noktadır. Aynı metin farklı bilgisayarlarda farklı yorumlanabilir veya hata verebilir.
Her satırda E sütunu Double ile bulunan farkı, F sütunu CDec ile bulunan farkı gösterir. Birinci satırda Double farkı 5,55112E-17, Decimal farkı 0 olarak yazıldı; ikinci satırda -1,11022E-16 ile 0, üçüncü satırda 4,44089E-16 ile 0 değerleri oluştu. CDec kullanan hesapta fark beklenen değere yakın ya da sıfır çıkar; Double hesabında ise ikili kesir kaynaklı çok küçük artıklar görülebilir.
Klavye için KDV tutarı 27,00, genel toplam 176,99 olarak hesaplandı. Monitör satırında KDV 233,91, toplam 1.533,41; Kitap satırında KDV 6,40, toplam 86,35; Kulaklık satırında KDV 44,98, toplam 294,88 değerini aldı. Ara çarpım Decimal olarak yapıldığından yuvarlama öncesi değer kesindir; sonuç hücreye yazılırken Excel bunu Double olarak saklar.
İlk satırdaki sayı sorunsuz dönüşür: sonuç 125,75, alt tür Decimal, hata kodu 0. İkinci satırdaki metin sayıya çevrilemediği için hata kodu 13 (Type mismatch) olur. TRUE değeri Decimal olarak -1 sonucunu verir. Boş hücre 0 gibi işlenir; sonuç 0, hata kodu 0 olur. Son satırdaki 1E+30 değeri Decimal sınırını aştığı için hata kodu 6 (Overflow) üretir.
Söz dizimi
İşlevin söz dizimi şöyledir:
VBA
5 satır
CDec(expression)
' Örnek kullanım
Dim x As Variant
x = CDec(0.1) + CDec(0.2)
- expression: Dönüştürülecek ifade; sayı, sayıya çevrilebilen metin, Boolean, tarih ya da hücre değeri olabilir. Zorunludur, varsayılan değeri yoktur.
Decimal nedir ve sınırları
VBA'da Decimal ayrı bir değişken türü olarak bildirilemez; yalnızca Variant içinde bir alt tür olarak bulunur. Bu yüzden Dim x As Decimal yazarsanız derleme hatası alırsınız; değişkeni Variant olarak tanımlayıp CDec ile doldurmanız gerekir.- Hassasiyet: 28 anlamlı basamağa kadar ondalık değer tutar ve değeri ikili kesir yerine ondalık ölçekle saklar; bu yüzden 0,1 gibi değerler tam saklanır.
- Aralık (ondalık noktasız): yaklaşık -79.228.162.514.264.337.593.543.950.335 ile +79.228.162.514.264.337.593.543.950.335 arası.
- Aralık (28 ondalık basamakla): yaklaşık -7,9228162514264337593543950335 ile +7,9228162514264337593543950335 arası; sıfırdan farklı en küçük değer 0,0000000000000000000000000001'dir.
- Hatalar: Aralığın dışındaki değerde Overflow (Taşma, hata 6), sayıya çevrilemeyen metinde hata 13, Null değerde hata 94 (Geçersiz Null kullanımı) oluşur. Empty değeri 0 olarak dönüşür, True değeri -1 olur.
Diğer dönüştürme işlevleriyle karşılaştırma
CDec, CInt, CLng, CDbl, CSng, CCur, CStr, CBool, CByte, CDate ve CVar ile aynı işlev ailesindendir. Bu ailede CCur 4 ondalık basamakla sabit noktalı hesap yapar; daha fazla basamak gerektiğinde CDec tercih edilir. CDbl hızlıdır ama yaklaşık 15 anlamlı basamakla sınırlıdır.Metinden sayıya dönüşümde bilgisayarın bölgesel ayarları (Regional Settings) geçerlidir: Türkçe ayarlarda ondalık ayırıcı virgüldür, İngilizce ayarlarda noktadır. Aynı metin farklı bilgisayarlarda farklı yorumlanabilir veya hata verebilir.
1. Double ve Decimal farkını görmek
Sayfada her satırda iki değer ve beklenen toplam vardır. Makro, toplamdan beklenen değeri çıkararak farkı önce Double, sonra CDec ile hesaplar. Kodu standart bir modüle (Ekle > Modül) yapıştırın.
VBA
21 satır
Option Explicit
Sub HassasFarkHesapla()
Dim ws As Worksheet
Dim r As Long
Dim dblFark As Double
Dim decFark As Variant
Set ws = ActiveSheet
For r = 2 To 4
' Double ile hesap: ikili kesir kaynaklı küçük artık kalabilir
dblFark = ws.Cells(r, 2).Value + ws.Cells(r, 3).Value - ws.Cells(r, 4).Value
' CDec ile hesap: değerler ondalık ölçekle işlenir
decFark = CDec(ws.Cells(r, 2).Value) + CDec(ws.Cells(r, 3).Value) - CDec(ws.Cells(r, 4).Value)
ws.Cells(r, 5).Value = dblFark
ws.Cells(r, 6).Value = decFark
Next r
End Sub
CDec
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | F | |
|---|---|---|---|---|---|---|
| 1 | Hesap | Değer 1 | Değer 2 | Beklenen | Double Farkı | Decimal Farkı |
| 2 | Birinci hesap | 0,1 | 0,2 | 0,3 | 5,55112E-17 | 0 |
| 3 | İkinci hesap | 0,7 | 0,1 | 0,8 | -1,11022E-16 | 0 |
| 4 | Üçüncü hesap | 1,1 | 2,2 | 3,3 | 4,44089E-16 | 0 |
Hassas FarkExcelDepo v1.0.0
2. KDV hesabında CDec
Sayfada net fiyatlar ve KDV oranları var. Makro her ürün için KDV tutarını iki ondalık basamağa yuvarlar ve genel toplamı yazar. Kodu standart bir modüle yapıştırın.
VBA
23 satır
Option Explicit
Sub KdvHesapla()
Dim ws As Worksheet
Dim r As Long
Dim net As Variant
Dim oran As Variant
Dim kdv As Variant
Set ws = ActiveSheet
For r = 2 To 5
' Değerleri Decimal alt türüne çeviriyoruz
net = CDec(ws.Cells(r, 2).Value)
oran = CDec(ws.Cells(r, 3).Value)
' KDV tutarını iki basamağa yuvarla
kdv = CDec(Round(net * oran, 2))
ws.Cells(r, 4).Value = kdv
ws.Cells(r, 5).Value = net + kdv
Next r
End Sub
CDec
Formülünü incelemek için bir hücre seçin.| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Ürün | Net Fiyat | KDV Oranı | KDV Tutarı | Genel Toplam |
| 2 | Klavye | 149,99 | 18% | 27,00 | 176,99 |
| 3 | Monitör | 1.299,50 | 18% | 233,91 | 1.533,41 |
| 4 | Kitap | 79,95 | 8% | 6,40 | 86,35 |
| 5 | Kulaklık | 249,90 | 18% | 44,98 | 294,88 |
KDV TablosuExcelDepo v1.0.0
3. Hatalı girdileri yakalamak
A sütunundaki farklı türde değerler CDec ile dönüştürülür. Makro hatayı yakalar; sonucu, alt tür adını ve hata kodunu yazar. Kodu standart bir modüle yapıştırın.
VBA
31 satır
Option Explicit
Sub GirdiDonustur()
Dim ws As Worksheet
Dim r As Long
Dim v As Variant
Dim kod As Long
Set ws = ActiveSheet
For r = 2 To 6
v = Empty
Err.Clear
On Error Resume Next
v = CDec(ws.Cells(r, 1).Value)
kod = Err.Number
On Error GoTo 0
If kod = 0 Then
ws.Cells(r, 2).Value = v
ws.Cells(r, 3).Value = TypeName(v)
Else
ws.Cells(r, 2).Value = "Hata"
ws.Cells(r, 3).Value = "-"
End If
' Hata kodu: 0 ise sorun yok, 13 tür uyuşmazlığı, 6 taşma
ws.Cells(r, 4).Value = kod
Next r
End Sub
CDec
Formülünü incelemek için bir hücre seçin.| A | B | C | D | |
|---|---|---|---|---|
| 1 | Girdi | Sonuç | Alt Tür | Hata Kodu |
| 2 | 125,75 | 125,75 | Decimal | 0 |
| 3 | abc | Hata | - | 13 |
| 4 | DOĞRU | -1 | Decimal | 0 |
| 5 | 0 | Decimal | 0 | |
| 6 | 1E+30 | Hata | - | 6 |
Girdi DenetimiExcelDepo v1.0.0
Kullanırken dikkat edin
- Decimal olarak bildirilemez: Dim x As Decimal yazmayın; derleme hatası verir. Değişkeni Variant olarak tanımlayın ve değeri CDec ile atayın. Değişkeni As Double gibi bir türle bildirirseniz Decimal'in hassasiyeti kaybolur.
- Hücreye yazınca hassasiyet sınırı: Excel hücreleri sayıları Double olarak saklar. Decimal sonucu hücreye yazdığınızda yaklaşık 15 anlamlı basamak kalır. 28 basamaklı sonucu korumak istiyorsanız değeri hücreye değil, Variant değişkende tutun veya CStr ile metin olarak yazın.
- Bölgesel ayarlara dikkat: Metin içeren bir ifadeyi CDec ile çevirirken ondalık ayırıcı bilgisayarın bölgesel ayarlarına göre yorumlanır. Metin kaynaklı verilerde önce IsNumeric ile denetim yapın veya On Error ile hatayı yakalayın.
- Null ve Double ile karışık işlemler: Null değeri CDec ile çevrilemez ve hata 94 verir; veritabanı kaynaklı alanları önce denetleyin. Decimal ile Double'ı aynı işlemde karıştırırsanız hassasiyet kaybolabilir; işlemdeki tüm değerleri CDec ile çevirmeniz daha güvenlidir.
- Hız ve alternatifler: Decimal işlemleri Double'a göre daha yavaştır; çok büyük döngülerde gereksiz kullanmayın. 4 ondalık basamak yeterliyse CCur (Currency) daha hızlı ve basit bir seçenektir.
- İlgili konular: