技術(shù) 點(diǎn)
- 技術(shù)
- 點(diǎn)
- V幣
- 點(diǎn)
- 積分
- 3705

|
本帖最后由 盜夢(mèng) 于 2015-6-25 17:21 編輯
Office32位和Office64位表面上沒(méi)有什么區(qū)別。
實(shí)際上,在vba方面要注意的是API和個(gè)別函數(shù)的使用。(該vba包括 Access vba,Excel vba,Word vba,PPT vba等)
以下是我最近寫代碼發(fā)現(xiàn)并總結(jié)出來(lái)的。
首先,說(shuō)說(shuō)API。
例如,在Office32位中API是這樣聲明的:
- Private Declare Function GetModuleHandleA Lib "kernel32" _
- (ByVal lpModuleName As String) As Long
復(fù)制代碼 而在Office64位需要在 Function 或者 Sub 前面加一個(gè)關(guān)鍵字,PtrSafe :
- Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" _
- (ByVal lpModuleName As String) As Long
復(fù)制代碼
PtrSafe 是 “指針安全” 的意思,到了64位,受影響最大的就是指針。
你可能會(huì)跳出了說(shuō)vba沒(méi)有指針。
實(shí)際上很多API函數(shù)是由C/C++編寫的,內(nèi)部實(shí)現(xiàn)機(jī)制有些會(huì)用到指針。
當(dāng)然,同樣的代碼,你不想寫兩個(gè)文件,可以這么做:
- #If vba7 Then
- '64位的代碼
- Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" _
- (ByVal lpModuleName As String) As Long
- #Else
- '32位的代碼
- Private Declare Function GetModuleHandleA Lib "kernel32" _
- (ByVal lpModuleName As String) As Long
- #End If
復(fù)制代碼
這個(gè)披上 # 號(hào)的 條件結(jié)構(gòu) 叫作 “條件編譯”,也就是系統(tǒng)在編譯的時(shí)候就去判斷里面的條件,選擇性編譯。
這樣處理就可以實(shí)現(xiàn)32位Office和64位Office 代碼兼容問(wèn)題。
除此之外,還有3點(diǎn)要注意:
1、 AddressOf 函數(shù)
在32位Office中,AddressOf 函數(shù)返回的類型是 Long;
而在64位Office中,將返回 LongPtr 類型。這個(gè)類型也是一種指針類型。
所以,調(diào)試編輯的時(shí)候,提示AddressOf 類型不符合的時(shí)候,就是返回的類型和你API函數(shù)的參數(shù)類型不一致。這是只需要把API函數(shù)對(duì)應(yīng)的變量類型改為 LongPtr 即可。
2、VarPtr函數(shù),ObjPtr函數(shù),StrPtr函數(shù)
這三個(gè)函數(shù)也是同樣的道理,在64位將返回 LongPtr類型。
3、部分屬性也要注意
像 Application.Hinstance ,在64位Office要用 Application.HinstancePtr 才不會(huì)出錯(cuò)。
這種在64位vba寫代碼時(shí)候,代碼提示發(fā)現(xiàn)有一個(gè)一樣的屬性名,但這個(gè)屬性名后面跟著 Ptr 后綴,不用看了,用它就沒(méi)錯(cuò)了。
|
|