Genel Bakış
LongPtr (LongPtr data type), VBA7 ile gelen ve bellek adreslerini ya da Windows tutamaçlarını (handle) saklamak için kullanılan veri türüdür. 32 bit Excel'de 4 baytlık Long, 64 bit Excel'de 8 baytlık LongLong gibi davranır. Özellikle Declare deyimiyle tanımlanan Windows API işlevlerinin hem 32 bit hem 64 bit Excel'de çalışmasını sağlar.
Koşullu derleme sabitleri şunlardır:
Integer için 2, Long için 4 bayt yazılır; bu iki değer hiçbir ortamda değişmez. LongPtr için yazılan 4 bayt değeri Excel'in sürümüne bağlıdır: 32 bit Excel'de 4, 64 bit Excel'de 8 çıkar. C4 hücresindeki 32 bit Excel ifadesi de makronun hangi ortamda çalıştığını gösterir.
Üç işlev de geçerli bir bellek adresi döndürdüğü için B sütununda DOĞRU, DOĞRU ve DOĞRU değerleri görünür. C sütunu, adresi tutan LongPtr değişkenin tür adını gösterir: Long. 32 bit Excel'de bu ad Long, 64 bit Excel'de LongLong olur. Adresleri Long değişkende saklamak 64 bit Excel'de değer kaybına yol açacağından bu işlevlerin sonucunu daima LongPtr değişkene atayın.
Makro çalıştırıldığında GetDesktopWindow'dan gelen tutamaç hPencere değişkenine alınır ve bir ileti kutusunda gösterilir. Kod #If VBA7 bloklarıyla yazıldığı için Excel 2007'de Long, Excel 2010 ve sonrasında LongPtr kullanılır. Tablodaki ilke şudur: tutamaç ve işaretçi taşıyan parametreler LongPtr olur, boyut ve bayrak gibi sayısal değerler Long olarak kalır.
Söz dizimi
LongPtr bir değişken türü olarak As sözcüğüyle kullanılır. Declare deyimlerinde ise dönüş değeri ya da parametre türü olarak yazılır:
VBA
2 satır
Dim degiskenAdi As LongPtr
Private Declare PtrSafe Function IslevAdi Lib "kutuphane" (ByVal tutamac As LongPtr) As LongPtr
- degiskenAdi: Zorunlu. Adres ya da tutamaç tutacak değişkenin adı. Başlangıç değeri 0'dır.
- As LongPtr: Zorunlu. Değişkenin türünü belirler. Yalnızca VBA7 (Excel 2010 ve sonrası) tarafından tanınır.
- PtrSafe: Declare deyiminde 64 bit Excel için zorunludur. API tanımının 64 bit uyumlu olduğunu bildirir. 32 bit Excel 2010 ve sonrasında da yazılabilir.
- ByVal: İsteğe bağlı. Parametrenin değerle iletilmesini sağlar. Tutamaç parametrelerinde genellikle gerekir; varsayılan aktarım biçimi ByRef'tir.
Boyut ve değer aralığı
LongPtr gerçek bir bağımsız tür değildir; çalışılan Excel sürümüne göre başka bir türün takma adı gibi davranır:- 32 bit Excel: 4 bayt, Long ile aynıdır. Aralığı -2.147.483.648 ile 2.147.483.647 arasındadır.
- 64 bit Excel: 8 bayt, LongLong ile aynıdır. Aralığı -9.223.372.036.854.775.808 ile 9.223.372.036.854.775.807 arasındadır.
Koşullu derleme ve eski sürümler
Excel 2007 ve öncesi (VBA6) LongPtr türünü tanımaz. Aynı dosyanın eski sürümlerde de açılması gerekiyorsa koşullu derleme kullanın:
VBA
5 satır
#If VBA7 Then
Dim h As LongPtr
#Else
Dim h As Long
#End If
- VBA7: VBA7 altyapısında (Excel 2010 ve sonrası) True olur.
- Win64: Yalnızca 64 bit Excel'de True olur.
1. Veri türlerinin bellek boyutu
Aşağıdaki makro Integer, Long ve LongPtr değişkenlerinin bayt cinsinden boyutunu LenB ile okur. Ayrıca Excel'in 32 bit mi 64 bit mi olduğunu koşullu derleme ile yazar. Kodu standart bir modüle yapıştırın; sayfa adı Bellek Boyutu olmalıdır.
VBA
23 satır
Sub BoyutlariYaz()
Dim i As Integer
Dim l As Long
Dim p As LongPtr
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Bellek Boyutu")
' LenB, değişkenin bellekte kapladığı bayt sayısını verir
ws.Range("B2").Value = LenB(i)
ws.Range("B3").Value = LenB(l)
ws.Range("B4").Value = LenB(p)
ws.Range("C2").Value = "Her ortamda sabit"
ws.Range("C3").Value = "Her ortamda sabit"
' Win64 yalnızca 64 bit Excel'de True olur
#If Win64 Then
ws.Range("C4").Value = "64 bit Excel"
#Else
ws.Range("C4").Value = "32 bit Excel"
#End If
End Sub
LongPtr
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Veri Türü | Bayt Sayısı | Ortam |
| 2 | Integer | 2 | Her ortamda sabit |
| 3 | Long | 4 | Her ortamda sabit |
| 4 | LongPtr | 4 | 32 bit Excel |
Bellek BoyutuExcelDepo v1.0.0
2. Bellek adresi döndüren işlevler
VarPtr, StrPtr ve ObjPtr işlevleri bir değişkenin, metnin ya da nesnenin bellek adresini LongPtr olarak döndürür. Makro her adresin sıfırdan farklı olup olmadığını ve LongPtr değişkenin türünü yazar. Adresin kendisi her çalıştırmada değişeceği için sayfaya yazılmaz. Kodu standart modüle yapıştırın; sayfa adı Adres Testi olmalıdır.
VBA
26 satır
Option Explicit
Sub AdresleriKontrolEt()
Dim sayi As Long
Dim metin As String
Dim p As LongPtr
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Adres Testi")
metin = "Excel"
' Long değişkenin adresi
p = VarPtr(sayi)
ws.Range("B2").Value = (p <> 0)
ws.Range("C2").Value = TypeName(p)
' Metin verisinin adresi
p = StrPtr(metin)
ws.Range("B3").Value = (p <> 0)
ws.Range("C3").Value = TypeName(p)
' Nesnenin (çalışma sayfasının) adresi
p = ObjPtr(ws)
ws.Range("B4").Value = (p <> 0)
ws.Range("C4").Value = TypeName(p)
End Sub
LongPtr
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | İşlev | Adres Var mı? | Değişken Türü |
| 2 | VarPtr(sayi) | DOĞRU | Long |
| 3 | StrPtr(metin) | DOĞRU | Long |
| 4 | ObjPtr(ws) | DOĞRU | Long |
Adres TestiExcelDepo v1.0.0
3. API tanımında LongPtr kullanımı
Bu örnek, Windows API işlevi GetDesktopWindow'u hem eski hem yeni Excel sürümlerinde çalışacak biçimde tanımlar. Declare, MsgBox ve API çağrısı içerdiği için makro burada çalıştırılmaz. Kodu standart modülün en üstüne yapıştırın. Tablo, bir API tanımında hangi parametrelerin LongPtr olması gerektiğini özetler.
VBA
21 satır
Option Explicit
' VBA7 (Excel 2010 ve sonrası) için PtrSafe ve LongPtr kullanılır
#If VBA7 Then
Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
#Else
Private Declare Function GetDesktopWindow Lib "user32" () As Long
#End If
Sub MasaustuTutamaciniGoster()
' Tutamaç tutan değişken de koşullu tanımlanır
#If VBA7 Then
Dim hPencere As LongPtr
#Else
Dim hPencere As Long
#End If
hPencere = GetDesktopWindow()
MsgBox "Masaüstü pencere tutamacı: " & hPencere
End Sub
LongPtr
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Parametre Türü | Eski (VBA6) | VBA7 |
| 2 | Pencere tutamacı (hWnd) | Long | LongPtr |
| 3 | Bellek adresi (işaretçi) | Long | LongPtr |
| 4 | Uzunluk ya da sayaç | Long | Long |
| 5 | Bayrak değeri | Long | Long |
API TanımıExcelDepo v1.0.0
Kullanırken dikkat edin
- Tutamaç ve adresler için Long kullanmayın: Long, 64 bit Excel'de bir adresi tam taşıyamaz. Kod 32 bit Excel'de sorunsuz çalışsa bile 64 bit Excel'de hata verebilir ya da Excel kapanabilir. Adres, işaretçi ve tutamaç için her zaman LongPtr kullanın.
- PtrSafe unutulmamalı: 64 bit Excel'de PtrSafe içermeyen bir Declare deyimi derleme hatası verir. Ayrıca API'nin gerçek imzasını kontrol edin: yalnızca işaretçi ve tutamaç parametrelerini LongPtr yapın. Boyut ve bayrak gibi 32 bitlik parametreler Long olarak kalmalıdır.
- Eski sürümlerde derleme hatası: Excel 2007 ve öncesi LongPtr sözcüğünü tanımaz ve Kullanıcı tanımlı tür tanımlanmamış gibi bir hata verir. Dosyayı eski sürümlerde de kullanacaksanız #If VBA7 Then ... #Else ... #End If yapısını kullanın.
- LongPtr her sorunu çözmez: LongPtr yalnızca adres ve tutamaç içindir. Sıradan hesaplamalarda, döngü sayaçlarında ve satır numaralarında Long kullanın. LongLong türü ise 32 bit Excel'de bulunmaz; kodunuzda doğrudan LongLong yazarsanız 32 bit Excel'de derleme hatası alırsınız.
- Sayfaya adres yazmayın: VarPtr, StrPtr ve ObjPtr ile alınan adresler her çalıştırmada değişir ve yalnızca o anki oturumda geçerlidir. Bu değerleri hücrede saklayıp sonradan kullanmaya çalışmayın.
- İlgili konular:
- Long: 4 baytlık tam sayı veri türü.
- LongLong: Yalnızca 64 bit Excel'de bulunan 8 baytlık tam sayı türü.
- CLngPtr: Bir ifadeyi LongPtr türüne dönüştüren işlev.
- Declare deyimi ve PtrSafe: Windows API işlevlerini VBA'ya tanıtma.
- VarPtr, StrPtr, ObjPtr: Bellek adresi döndüren işlevler.
- #If ... Then ... #Else ... #End If: Koşullu derleme; VBA7 ve Win64 sabitleri.
- LenB: Bir değişkenin bayt cinsinden boyutunu veren işlev.