EXCEL 64 位命令行 vba 代码
EXCEL 64 bit command line vba code
我有打开 excel 书时获取命令行参数的代码(64 位;但是 #if 子句下也有 32 位代码)。
例如,当我在命令提示符下 运行 以下代码行时,我希望能够获取输入字符串作为命令行参数:
开始Excel ".\AwajiPush.xlsm" /p/"kjh%dg.pdf"
(顺便说一下,"start" 存在的原因是它可以在 .bat 批处理文件中工作)
我期待能够捕获
".\AwajiPush.xlsm" 和
/p/"kjh%dg.pdf"
作为参数。
代码不会那样做。
为什么不获取第二个参数?
我不太了解指针的工作原理。
有没有一段代码可以用来捕获至少一个包含两个参数的字符串,以便我可以解析它。如果它包含更多,那很好。我总是可以解释它,只要它是一致的。
我在程序(MsgBox)中放入了存根,但我不确定为什么第二个存根显示为空白。
代码如下:
'Put this code in a new module called Parameters
Option Explicit
#If Win64 Then
Private Declare PtrSafe Function GetCommandLineL Lib "kernel32" _
Alias "GetCommandLineA" () As LongPtr
Private Declare PtrSafe Function lstrcpyL Lib "kernel32" _
Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As LongPtr) As Long
Private Declare PtrSafe Function lstrlenL Lib "kernel32" _
Alias "lstrlenA" (ByVal lpString As LongPtr) As Long
#Else
Private Declare Function GetCommandLineL Lib "kernel32" _
Alias "GetCommandLineA" () As Long
Private Declare Function lstrcpyL Lib "kernel32" _
Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Private Declare Function lstrlenL Lib "kernel32" _
Alias "lstrlenA" (ByVal lpString As Long) As Long
#End If
Function GetCommandLine() As String
Dim strReturn As String
#If Win64 Then
Dim lngPtr As LongPtr
#Else
Dim lngPtr As Long
#End If
Dim StringLength As Long
'Get the pointer to the commandline string
lngPtr = GetCommandLineL
'get the length of the string (not including the terminating null character):
StringLength = lstrlenL(lngPtr)
MsgBox StringLength
'initialize our string so it has enough characters including the null character:
strReturn = String$(StringLength + 1, 0)
'copy the string we have a pointer to into our new string:
MsgBox strReturn
lstrcpyL strReturn, lngPtr
'now strip off the null character at the end:
MsgBox strReturn
GetCommandLine = Left$(strReturn, StringLength)
End Function
和
'Put this code in "This Workbook"
Sub workBook_open()
MsgBox Parameters.GetCommandLine
End Sub
这是一个从当前进程获取命令行的函数:
Private Declare PtrSafe Function w_commandline Lib "kernel32.dll" Alias "GetCommandLineW" () As LongPtr
Private Declare PtrSafe Function w_strlen Lib "kernel32.dll" Alias "lstrlenW" (ByVal lpString As LongPtr) As Long
Private Declare PtrSafe Sub w_memcpy Lib "kernel32.dll" Alias "RtlMoveMemory" (dst As Any, src As Any, ByVal size As LongPtr)
Public Function GetCommandLine() As String
GetCommandLine = String$(w_strlen(w_commandline()), 0)
w_memcpy ByVal StrPtr(GetCommandLine), ByVal w_commandline(), LenB(GetCommandLine)
End Function
Sub Test()
Debug.Print GetCommandLine()
End Sub
请注意,您必须使用 /e
开关来避免重定向到已启动的 Excel 实例,从而保留提供的参数。例如:
excel.exe /e "C:\temp\myfile.xlsm" /p "myparam"
或 start
:
start "xl" excel.exe /e "C:\temp\myfile.xlsm" /p "myparam"
但是如果您的目标是从批处理中向 VBA 提供一些参数,那么请使用环境变量:
Set MyArguments=abcde
start "xl" excel.exe /e "C:\temp\myfile.xlsm"
,然后从 Excel 获取参数:
Debug.Print Environ("MyArguments") ' >> "abcde" '
我有打开 excel 书时获取命令行参数的代码(64 位;但是 #if 子句下也有 32 位代码)。
例如,当我在命令提示符下 运行 以下代码行时,我希望能够获取输入字符串作为命令行参数:
开始Excel ".\AwajiPush.xlsm" /p/"kjh%dg.pdf"
(顺便说一下,"start" 存在的原因是它可以在 .bat 批处理文件中工作)
我期待能够捕获 ".\AwajiPush.xlsm" 和 /p/"kjh%dg.pdf" 作为参数。
代码不会那样做。
为什么不获取第二个参数?
我不太了解指针的工作原理。 有没有一段代码可以用来捕获至少一个包含两个参数的字符串,以便我可以解析它。如果它包含更多,那很好。我总是可以解释它,只要它是一致的。
我在程序(MsgBox)中放入了存根,但我不确定为什么第二个存根显示为空白。
代码如下:
'Put this code in a new module called Parameters
Option Explicit
#If Win64 Then
Private Declare PtrSafe Function GetCommandLineL Lib "kernel32" _
Alias "GetCommandLineA" () As LongPtr
Private Declare PtrSafe Function lstrcpyL Lib "kernel32" _
Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As LongPtr) As Long
Private Declare PtrSafe Function lstrlenL Lib "kernel32" _
Alias "lstrlenA" (ByVal lpString As LongPtr) As Long
#Else
Private Declare Function GetCommandLineL Lib "kernel32" _
Alias "GetCommandLineA" () As Long
Private Declare Function lstrcpyL Lib "kernel32" _
Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Private Declare Function lstrlenL Lib "kernel32" _
Alias "lstrlenA" (ByVal lpString As Long) As Long
#End If
Function GetCommandLine() As String
Dim strReturn As String
#If Win64 Then
Dim lngPtr As LongPtr
#Else
Dim lngPtr As Long
#End If
Dim StringLength As Long
'Get the pointer to the commandline string
lngPtr = GetCommandLineL
'get the length of the string (not including the terminating null character):
StringLength = lstrlenL(lngPtr)
MsgBox StringLength
'initialize our string so it has enough characters including the null character:
strReturn = String$(StringLength + 1, 0)
'copy the string we have a pointer to into our new string:
MsgBox strReturn
lstrcpyL strReturn, lngPtr
'now strip off the null character at the end:
MsgBox strReturn
GetCommandLine = Left$(strReturn, StringLength)
End Function
和
'Put this code in "This Workbook"
Sub workBook_open()
MsgBox Parameters.GetCommandLine
End Sub
这是一个从当前进程获取命令行的函数:
Private Declare PtrSafe Function w_commandline Lib "kernel32.dll" Alias "GetCommandLineW" () As LongPtr
Private Declare PtrSafe Function w_strlen Lib "kernel32.dll" Alias "lstrlenW" (ByVal lpString As LongPtr) As Long
Private Declare PtrSafe Sub w_memcpy Lib "kernel32.dll" Alias "RtlMoveMemory" (dst As Any, src As Any, ByVal size As LongPtr)
Public Function GetCommandLine() As String
GetCommandLine = String$(w_strlen(w_commandline()), 0)
w_memcpy ByVal StrPtr(GetCommandLine), ByVal w_commandline(), LenB(GetCommandLine)
End Function
Sub Test()
Debug.Print GetCommandLine()
End Sub
请注意,您必须使用 /e
开关来避免重定向到已启动的 Excel 实例,从而保留提供的参数。例如:
excel.exe /e "C:\temp\myfile.xlsm" /p "myparam"
或 start
:
start "xl" excel.exe /e "C:\temp\myfile.xlsm" /p "myparam"
但是如果您的目标是从批处理中向 VBA 提供一些参数,那么请使用环境变量:
Set MyArguments=abcde
start "xl" excel.exe /e "C:\temp\myfile.xlsm"
,然后从 Excel 获取参数:
Debug.Print Environ("MyArguments") ' >> "abcde" '