Genel Bakış
API (Application Programming Interface - Uygulama Programlama Arayüzü), Windows'un ve diğer kitaplıkların (DLL) dışarıya açtığı hazır işlevler topluluğudur. Excel VBA'da Windows API denince, Declare deyimiyle tanıtılıp VBA içinden çağrılan bu işlevler kastedilir. Böylece VBA'nın kendi nesne modelinde bulunmayan işlemleri (milisaniyelik bekleme, ekran ölçüleri, pencere tutamaçları gibi) yapabilirsiniz.
API kullanımı şu durumlarda işe yarar:
Makro çalışınca B2 hücresine VBA7 durumu (Evet), B3 hücresine Excel'in bit sürümü (32 bit) yazılır. B4 hücresindeki değer (4) LongPtr değişkeninin kapladığı bayt sayısıdır; 64 bit Excel'de 8, 32 bit Excel'de 4 çıkar. B5 hücresi (4) ise Long türünün her sürümde 4 bayt olduğunu gösterir. Bu yüzden tutamaçlar için LongPtr, sayaçlar için Long kullanılır.
Bu örnek Windows API çağırdığı için sayfada otomatik çalıştırılmaz; kendi bilgisayarınızda deneyin. Makro çalışınca B2 hücresine yaklaşık 500, B3 hücresine yaklaşık 1000 milisaniye yazılır. Windows sistem saatinin çözünürlüğü nedeniyle birkaç ile on beş milisaniye arasında küçük sapmalar olağandır. Sleep çalışırken Excel yanıt vermez; bu nedenle bekleme sürelerini kısa tutun.
Bu örnek Windows API çağırdığı için sayfada otomatik çalıştırılmaz. Kendi bilgisayarınızda çalıştırdığınızda B2 hücresine ana ekranın genişliği, B3 hücresine yüksekliği piksel olarak yazılır. Ekran ölçeklendirmesi (DPI) yüzde 100'ün üzerindeyse dönen değerler ekranın fiziksel çözünürlüğünden farklı çıkabilir.
Windows API nedir, ne zaman kullanılır
Windows API işlevleri kernel32, user32, gdi32 gibi sistem kitaplıklarında bulunur. VBA bu işlevleri kendiliğinden tanımaz; önce Declare deyimiyle işlevin adını, hangi kitaplıkta olduğunu ve parametre türlerini bildirirsiniz. Ardından işlevi sıradan bir VBA prosedürü gibi çağırırsınız.API kullanımı şu durumlarda işe yarar:
- Zamanlama: Sleep ile bekleme, GetTickCount ile milisaniye düzeyinde süre ölçme.
- Sistem bilgisi: GetSystemMetrics ile ekran çözünürlüğü gibi değerleri okuma.
- Pencere işlemleri: FindWindow, SetForegroundWindow gibi işlevlerle pencereleri bulma ve denetleme.
- Klavye ve fare durumu: GetKeyState, GetAsyncKeyState ile tuş durumunu sorgulama.
Söz dizimi
API işlevi, standart modülün en üstünde (diğer prosedürlerden önce, Option Explicit satırından sonra) tanıtılır:
VBA
2 satır
[Public | Private] Declare [PtrSafe] Sub ad Lib "kitaplık" [Alias "takmaAd"] [([bağımsız değişkenler])]
[Public | Private] Declare [PtrSafe] Function ad Lib "kitaplık" [Alias "takmaAd"] [([bağımsız değişkenler])] [As tür]
- Public / Private: Kapsamı belirler; isteğe bağlıdır, varsayılan Public'tir. Sınıf, sayfa ve UserForm modüllerinde yalnızca Private kullanılabilir.
- PtrSafe: 64 bit Excel'de (VBA7) zorunludur; 64 bit uyumlu olduğunu bildirir. Eski 32 bit sürümler bu sözcüğü tanımaz.
- Sub / Function: İşlev değer döndürmüyorsa Sub, döndürüyorsa Function yazılır.
- ad: VBA içinde kullanacağınız ad; zorunludur. Alias verilmezse DLL içindeki işlev adıyla aynı olmalıdır (büyük/küçük harfe duyarlıdır).
- Lib "kitaplık": İşlevin bulunduğu DLL'in adı; zorunludur (ör. "kernel32", "user32").
- Alias "takmaAd": DLL'deki gerçek işlev adı; isteğe bağlıdır. Metin alan işlevlerde sonu A (ANSI) ya da W (Unicode) ile biten adlar için kullanılır.
- bağımsız değişkenler: ByVal ya da ByRef (varsayılan) ile ad ve türden oluşur; isteğe bağlıdır. Hatalı ByVal/ByRef seçimi en sık çökme nedenidir.
- As tür: Function için dönüş değerinin türü; isteğe bağlıdır.
32 bit ve 64 bit uyumu
Excel 2010 ile birlikte VBA7 geldi ve 64 bit Excel sürümleri çıktı. Bu sürümlerde bellek adresi ve pencere tutamacı (handle) taşıyan parametreler 8 bayt olmalıdır. Bunun için LongPtr türü kullanılır; 32 bit'te 4 bayt, 64 bit'te 8 bayt yer kaplar. Tarihi 32 bit olan tanımlar için derleme sabitleriyle iki kol yazılır:
VBA
5 satır
#If VBA7 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
- VBA7: Excel 2010 ve sonrasında True olan derleme sabitidir.
- Win64: Yalnızca 64 bit Excel'de True olan derleme sabitidir.
- LongPtr: Tutamaç ve işaretçiler için kullanılır (ör. hWnd). Sayaç ve sayısal değerler için Long kalır.
- LongLong: 64 bit tam sayı türüdür; yalnızca 64 bit Excel'de bulunur.
Veri türü eşleşmeleri
API belgelerindeki C türlerini VBA'ya şöyle çevirirsiniz:- DWORD, int, UINT, BOOL: Long olarak tanımlanır.
- WORD, short: Integer olarak tanımlanır.
- HWND, HANDLE, HDC, işaretçi: VBA7'de LongPtr olarak tanımlanır.
- LPSTR, LPCSTR (metin): ByVal As String olarak tanımlanır.
- LPVOID, LPLONG (adres): ByRef bir değişken ya da LongPtr olarak tanımlanır.
1. Derleme sabitleriyle sürüm ve LongPtr boyutu
Önce API kullanımının temelini, yani 32/64 bit ayrımını sınayalım. Bu örnekte hiçbir API çağrılmaz; yalnızca VBA7 ve Win64 derleme sabitleri ile LenB işlevi kullanılır. Visual Basic Düzenleyicisi'nde (Visual Basic Editor) Ekle > Modül (Insert > Module) ile standart modül açın ve kodu oraya yapıştırın.
VBA
28 satır
Option Explicit
' Excel sürümüne ilişkin bilgileri sayfaya yazar
Sub SurumBilgisiYaz()
Dim ws As Worksheet
Dim sayi As Long
Set ws = ActiveSheet
' VBA7 sabiti: Excel 2010 ve sonrasında True
#If VBA7 Then
Dim isaretci As LongPtr
ws.Range("B2").Value = "Evet"
#Else
Dim isaretci As Long
ws.Range("B2").Value = "Hayır"
#End If
' Win64 sabiti: yalnızca 64 bit Excel'de True
#If Win64 Then
ws.Range("B3").Value = "64 bit"
#Else
ws.Range("B3").Value = "32 bit"
#End If
' Değişkenlerin bellekte kapladığı bayt sayısı
ws.Range("B4").Value = LenB(isaretci)
ws.Range("B5").Value = LenB(sayi)
End Sub
API
Formülünü incelemek için bir hücre seçin.| A | B | |
|---|---|---|
| 1 | Ölçüt | Sonuç |
| 2 | VBA7 kullanılıyor mu? | Evet |
| 3 | Excel kaç bit? | 32 bit |
| 4 | LongPtr bayt boyutu | 4 |
| 5 | Long bayt boyutu | 4 |
Sürüm BilgisiExcelDepo v1.0.0
2. Sleep ve GetTickCount ile süre ölçme
Bu örnekte kernel32 kitaplığından Sleep ve GetTickCount işlevleri tanıtılır. Makro iki ayrı bekleme yapar ve geçen süreyi milisaniye olarak sayfaya yazar. Kodu standart modülün en üstüne yapıştırın; Declare satırları prosedürlerden önce gelmelidir.
VBA
28 satır
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
Sub SureOlc()
Dim t0 As Long
Dim t1 As Long
Dim ws As Worksheet
Set ws = ActiveSheet
' Yarım saniyelik bekleme
t0 = GetTickCount
Sleep 500
t1 = GetTickCount
ws.Range("B2").Value = t1 - t0
' Bir saniyelik bekleme
t0 = GetTickCount
Sleep 1000
t1 = GetTickCount
ws.Range("B3").Value = t1 - t0
End Sub
API
Formülünü incelemek için bir hücre seçin.| A | B | |
|---|---|---|
| 1 | Deneme | Süre (ms) |
| 2 | Yarım saniyelik bekleme | |
| 3 | Bir saniyelik bekleme |
Zaman ÖlçümüExcelDepo v1.0.0
3. GetSystemMetrics ile ekran ölçüleri
Bu örnekte user32 kitaplığındaki GetSystemMetrics işlevi tanıtılır. İşlev, indeks olarak verilen sistem ölçüsünü döndürür. SM_CXSCREEN ekran genişliğini, SM_CYSCREEN ekran yüksekliğini piksel olarak verir. Kodu standart modüle yapıştırın.
VBA
19 satır
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#Else
Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#End If
' API belgesindeki indeks değerleri
Private Const SM_CXSCREEN As Long = 0
Private Const SM_CYSCREEN As Long = 1
Sub EkranOlculeriniYaz()
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Range("B2").Value = GetSystemMetrics(SM_CXSCREEN)
ws.Range("B3").Value = GetSystemMetrics(SM_CYSCREEN)
End Sub
API
Formülünü incelemek için bir hücre seçin.| A | B | |
|---|---|---|
| 1 | Ölçü | Piksel |
| 2 | Ekran genişliği | |
| 3 | Ekran yüksekliği |
Ekran ÖlçüleriExcelDepo v1.0.0
Kullanırken dikkat edin
- Kaydetmeden denemeyin: API çağrısındaki yanlış parametre türü ya da ByVal/ByRef hatası Excel'in aniden kapanmasına yol açabilir. Kodu çalıştırmadan önce çalışma kitabınızı kaydedin, ilk denemeleri boş bir kitapta yapın.
- 64 bit Excel'de PtrSafe zorunlu: PtrSafe olmayan bir Declare satırı 64 bit Excel'de derleme hatası verir. Eski kodlarda tutamaçları Long yerine LongPtr yapmayı da unutmayın. Hem eski hem yeni sürümde çalışacak kod için #If VBA7 Then kalıbını kullanın.
- Declare yeri: Declare deyimi prosedür içine yazılamaz; modülün bildirim bölümünde, prosedürlerden önce yer almalıdır. Sayfa, ThisWorkbook, sınıf ve UserForm modüllerinde yalnızca Private Declare kullanılabilir.
- Sık görülen çalışma zamanı hataları:
- Hata 453 (Specified DLL function not found): İşlev adı yanlış yazılmıştır ya da Alias gerekir; ad büyük/küçük harfe duyarlıdır.
- Hata 48 (Error in loading DLL): Kitaplık bulunamıyor ya da bit sürümü uyumsuzdur.
- Hata 49 (Bad DLL calling convention): Parametre sayısı ya da ByVal/ByRef seçimi yanlıştır.
- GetTickCount taşması: GetTickCount sistem açıldığından beri geçen milisaniyeyi Long olarak döndürür; yaklaşık 24,8 günlük çalışmadan sonra değer eksiye döner ve çıkarma işlemi taşma hatası verebilir. Uzun süreli sistemlerde bu durumu göz önünde bulundurun.
- Önce VBA'nın kendi çözümlerine bakın: Süre ölçmek için VBA'nın Timer işlevi, ekran ölçüleri için Application.Width gibi özellikler çoğu zaman yeterlidir ve API kadar risk taşımaz. API'yi yalnızca VBA'da karşılığı olmayan işlemlerde kullanın. Ayrıca Windows API'leri Mac için Excel'de çalışmaz.
- İlgili konular:
- Declare deyimi
- PtrSafe anahtar sözcüğü
- LongPtr ve LongLong veri türleri
- #If...Then...#Else derleme yönergeleri
- Timer işlevi
- Application.Wait yöntemi
- Application.OnTime yöntemi
- LenB işlevi