64位Excel VBA中URLDownloadToFile函数声明报编译错误的原因
错误根因
该编译错误和你写的64位兼容API声明本身的语法无关,核心触发原因是:你将API声明、模块级常量的代码放在了某个已有过程(Sub/Function/Property)的代码块内部,而非模块的通用声明区域(所有过程之外的模块最顶部)。
VBA语法有明确约束:
Declare形式的外部API声明、模块级Const常量定义,都属于模块级代码,必须写在所有自定义过程的代码块外部,不能嵌套在任何Sub/Function/Property的首尾语句之间。- 当VBA编译器在过程内部读到仅允许出现在模块级的声明语句,或是在某段过程的
End Sub/End Function/End Property语句后读到非注释的声明/可执行代码,就会抛出你看到的报错。
修复方法
- 打开VBA编辑器定位到当前代码,检查是否误将API声明段粘贴到了其他已有宏的
Sub xxx()和End Sub之间。 - 将从
#If VBA7 Then开始的条件编译API声明块、4个公共常量定义的所有代码,剪切到模块最顶部,紧接在Option Explicit语句下方,所有自定义过程的上方。 - 确认模块内代码的层级顺序符合要求即可正常编译,正确结构参考下方代码示例:
Option Explicit ' 模块级API声明段(所有过程外) #If VBA7 Then Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" _ Alias "URLDownloadToFileA" ( _ ByVal pCaller As LongPtr, _ ByVal szURL As String, _ ByVal szFileName As String, _ ByVal dwReserved As Long, _ ByVal lpfnCB As LongPtr _ ) As Long Private Declare PtrSafe Function DeleteUrlCacheEntry Lib "Wininet.dll" _ Alias "DeleteUrlCacheEntryA" ( _ ByVal lpszUrlName As String _ ) As Long #Else Private Declare Function URLDownloadToFile Lib "urlmon" _ Alias "URLDownloadToFileA" ( _ ByVal pCaller As Long, _ ByVal szURL As String, _ ByVal szFileName As String, _ ByVal dwReserved As Long, _ ByVal lpfnCB As Long _ ) As Long Private Declare Function DeleteUrlCacheEntry Lib "Wininet.dll" _ Alias "DeleteUrlCacheEntryA" ( _ ByVal lpszUrlName As String _ ) As Long #End If ' 模块级常量定义(所有过程外) Public Const ERROR_SUCCESS As Long = 0 Public Const BINDF_GETNEWESTVERSION As Long = &H10 Public Const INTERNET_FLAG_RELOAD As Long = &H80000000 Public Const folderName As String = "c:\temp\" ' 自定义宏过程 Sub downloadImages() Dim i As Long, ret As Long, sWAN As String, sLAN As String With Worksheets("Sheet1") For i = 2 To .Cells(Rows.Count, "B").End(xlUp).Row sLAN = folderName & .Cells(i, 1).Value & ".jpg" sWAN = .Cells(i, 2).Value ' 可选:调用该语句清除缓存避免下载到历史旧图 Call DeleteUrlCacheEntry(sWAN) ret = URLDownloadToFile(0&, sWAN, sLAN, BINDF_GETNEWESTVERSION, 0&) If ret = 0 Then .Cells(i, 3) = "File successfully downloaded" Else .Cells(i, 3) = "Unable to download the file" End If Next i End With End Sub
注:你当前写的VBA7 64位兼容声明中
LongPtr的用法是正确的,只要放对代码位置就不会触发该编译错误。
内容的提问来源于stack exchange,提问作者shampouya
相关产品推荐
相关产品推荐

