如何在 VBA 中声明 PtrSafe Sub? Windows 7,Excel 2016,64 位
How can I declare a PtrSafe Sub in VBA? Windows 7, Excel 2016, 64-bit
我正在尝试将我的大数字 VBA 应用程序从 Long 数据类型升级到 LongLong 或 LongPtr 以便能够处理更多数字。
但是我不知道如何调用这个 PtrSafe Sub...一些帮助会很有帮助。
我尝试了一个简单的示例 Sub 来隔离问题。
但是不知道我应该调用哪个 Lib,最重要的是:这个 Sub 应该是 Private 还是 Public?
Public Declare PtrSafe Sub Example Lib "??????" (ByVal x, y, z As LongPtr)
Dim x, y, z As LongPtr
x = 123456789
y = 123456789
MsgBox z = x * y
End Sub
任何人都可以逐步向我解释如何调用 PtrSafe 的 Sub 吗?
PtrSafe
使用 PtrSafe 只是为了在 64 位系统上启用 32 位 API 调用,如下所示:
Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As Long
Public Sub TestScreenResolution()
Debug.Print ScreenResolution
End Sub
Private Function ScreenResolution() As Double
Dim hDC As LongPtr
hDC = GetDC(0)
ScreenResolution = GetDeviceCaps(hDC, 88)
ReleaseDC 0, hDC
End Function
条件编译
您可以通过条件编译同时使用两者
#If Win64 Then
Private Declare PtrSafe Function MakeSureDirectoryPathExists _
Lib "imagehlp.dll" (ByVal DirPath As String) As Boolean
#Else
Private Declare Function MakeSureDirectoryPathExists Lib _
"imagehlp.dll" (ByVal DirPath As String) As Boolean
#End If
你自己的带有 64 位变量的 Sub 或 Function
这些可以这样声明:
Public Sub TestMySub()
Call MySub(123456789, 123456789)
End Sub
Private Sub MySub(ByVal x As LongLong, ByVal y As LongPtr)
Dim z As LongLong
z = x * y
MsgBox z
End Sub
我希望 Private
尽可能长,并且 Public
仅在需要 "external" 访问权限时。
数据类型 LongLong 与 LongPtr 与 Decimal
在 64 位上 LongLong
和 LongPtr
都是一个 "LongLong Integer" 8 字节:
-9.223.372.036.854.775.808 到 9.223.372.036.854.775.807
但请注意:但是如果您使用 LongLong
,它只能在 64 位上工作,其中 32 位上的 LongPtr
将被简单地处理为 4 个字节的 Long
,这结果
-2.147.483.648 到 2.147.483.647
因此,如果您确实需要在两个系统上都使用高值并且 Long
还不够,请考虑使用 Double(8 字节,包括舍入效果!)或 Decimal
(14 字节,必须首先声明为 Variant
):
Private Sub DataTypeDecimal()
' Decimal only via declaration as Variant and type cast as Decimal
Dim d As Variant
d = CDec("79.228.162.514.264.337.593.543.950.335")
Debug.Print d
d = CDec("-79.228.162.514.264.337.593.543.950.335")
Debug.Print d
End Sub
我给你的例子没问题,谢谢你:-)。
但是现在实际的应用程序说 "type mismatch" 在我尝试用 'True'-布尔值填充 Arr(z)(摘录)(它对 Long 数据类型很好):
Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As Long
Public Sub TestScreenResolution()
Debug.Print ScreenResolution
End Sub
Private Function ScreenResolution() As Double
Dim hDC As Long
hDC = GetDC(0)
ScreenResolution = GetDeviceCaps(hDC, 88)
ReleaseDC 0, hDC
End Function
Public Sub TestMySub()
Call MySub(999999999)
End Sub
Private Sub MySub(ByVal x As LongLong)
Dim z As LongLong
Dim Max, Min As LongLong
Max = x * x
Min = (x - 2) * (x - 2)
Dim Arr() As Boolean 'Default Boolean type is False
ReDim Arr(Min To Max)
For z = Max To Min Step -2
Arr(z) = True
Next z
End Sub
我正在尝试将我的大数字 VBA 应用程序从 Long 数据类型升级到 LongLong 或 LongPtr 以便能够处理更多数字。 但是我不知道如何调用这个 PtrSafe Sub...一些帮助会很有帮助。
我尝试了一个简单的示例 Sub 来隔离问题。 但是不知道我应该调用哪个 Lib,最重要的是:这个 Sub 应该是 Private 还是 Public?
Public Declare PtrSafe Sub Example Lib "??????" (ByVal x, y, z As LongPtr)
Dim x, y, z As LongPtr
x = 123456789
y = 123456789
MsgBox z = x * y
End Sub
任何人都可以逐步向我解释如何调用 PtrSafe 的 Sub 吗?
PtrSafe
使用 PtrSafe 只是为了在 64 位系统上启用 32 位 API 调用,如下所示:
Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As Long
Public Sub TestScreenResolution()
Debug.Print ScreenResolution
End Sub
Private Function ScreenResolution() As Double
Dim hDC As LongPtr
hDC = GetDC(0)
ScreenResolution = GetDeviceCaps(hDC, 88)
ReleaseDC 0, hDC
End Function
条件编译
您可以通过条件编译同时使用两者
#If Win64 Then
Private Declare PtrSafe Function MakeSureDirectoryPathExists _
Lib "imagehlp.dll" (ByVal DirPath As String) As Boolean
#Else
Private Declare Function MakeSureDirectoryPathExists Lib _
"imagehlp.dll" (ByVal DirPath As String) As Boolean
#End If
你自己的带有 64 位变量的 Sub 或 Function
这些可以这样声明:
Public Sub TestMySub()
Call MySub(123456789, 123456789)
End Sub
Private Sub MySub(ByVal x As LongLong, ByVal y As LongPtr)
Dim z As LongLong
z = x * y
MsgBox z
End Sub
我希望 Private
尽可能长,并且 Public
仅在需要 "external" 访问权限时。
数据类型 LongLong 与 LongPtr 与 Decimal
在 64 位上 LongLong
和 LongPtr
都是一个 "LongLong Integer" 8 字节:
-9.223.372.036.854.775.808 到 9.223.372.036.854.775.807
但请注意:但是如果您使用 LongLong
,它只能在 64 位上工作,其中 32 位上的 LongPtr
将被简单地处理为 4 个字节的 Long
,这结果
-2.147.483.648 到 2.147.483.647
因此,如果您确实需要在两个系统上都使用高值并且 Long
还不够,请考虑使用 Double(8 字节,包括舍入效果!)或 Decimal
(14 字节,必须首先声明为 Variant
):
Private Sub DataTypeDecimal()
' Decimal only via declaration as Variant and type cast as Decimal
Dim d As Variant
d = CDec("79.228.162.514.264.337.593.543.950.335")
Debug.Print d
d = CDec("-79.228.162.514.264.337.593.543.950.335")
Debug.Print d
End Sub
我给你的例子没问题,谢谢你:-)。
但是现在实际的应用程序说 "type mismatch" 在我尝试用 'True'-布尔值填充 Arr(z)(摘录)(它对 Long 数据类型很好):
Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As Long
Public Sub TestScreenResolution()
Debug.Print ScreenResolution
End Sub
Private Function ScreenResolution() As Double
Dim hDC As Long
hDC = GetDC(0)
ScreenResolution = GetDeviceCaps(hDC, 88)
ReleaseDC 0, hDC
End Function
Public Sub TestMySub()
Call MySub(999999999)
End Sub
Private Sub MySub(ByVal x As LongLong)
Dim z As LongLong
Dim Max, Min As LongLong
Max = x * x
Min = (x - 2) * (x - 2)
Dim Arr() As Boolean 'Default Boolean type is False
ReDim Arr(Min To Max)
For z = Max To Min Step -2
Arr(z) = True
Next z
End Sub