运行 命令提示符中的目录来自 vba
Running dir in command prompt from vba
尝试在命令提示符下使用 shell 命令将 VBA 转到 运行 目录:
Call Shell("Dir \rtserver\controlleddocuments\""incoming reports""\" & Left(cmbComponent.Column(1), 3) & "" & Left(lstComponentLots.Column(1), 2) & "\*" & lstComponentLots.Column(1) & "* /b /a-d > C:\users\public\tmpcomponentsearch.txt", vbNormalFocus)
DoCmd.TransferText acImportDelim, "pathImport", "z_tmpcomponentsearch",
"C:\users\public\tmpcomponentsearch.txt"
Me.listScannedRecords.Requery
如果我 debug.print shell 命令中的字符串,我得到:
Dir \rtserver\controlleddocuments\"incoming reports"917\*1702-1015* /b /a-d > C:\users\public\tmpcomponentsearch.txt
在命令提示符下 运行 没问题,但是当我尝试在 VBA 中 运行 时出现 'file not found' 错误。我宁愿不创建批处理文件来执行此操作。
提前致谢。
为什么要使用 shell
?尝试使用 FileSystemObject(添加对 Microsoft Scripting Runtime 的引用)。尝试以下方式:
Dim fso As New FileSystemObject
Dim oFolder As Folder
Dim oFile As File
Dim strFolderName As String
strFolderName = "\rtserver\controlleddocuments\""incoming reports""917"
Set oFolder = fso.GetFolder(strFolderName)
For Each oFile In oFolder.Files
If oFile.Name Like "*1702-1015*" Then
CurrentDb.Execute "INSERT INTO z_tmpcomponentsearch (col_name) " & _
"VALUES ('" & Replace(oFile.Name, "'", "''") & "')"
End If
Next oFile
Set oFile = Nothing
Set oFolder = Nothing
Set fso = Nothing
我找到了答案 - 有点像。基本上使用 dir 命令动态创建批处理文件,然后 运行 it:
Public Function search_with_batch_file(searchStr As String)
Const my_filename = "C:\Users\Public\qsd_search.bat"
Dim FileNumber As Integer
Dim wsh As Object
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
FileNumber = FreeFile
'creat batch file
Open my_filename For Output As #FileNumber
Print #FileNumber, "Dir " & searchStr & " /b /a-d >
C:\users\public\tmpcomponentsearch.txt"
Print #FileNumber, "exit"
Close #FileNumber
'run batch file and wait to complete
Set wsh = VBA.CreateObject("WScript.Shell")
wsh.Run my_filename, windowStyle, waitOnReturn
'Delete batch file
Kill my_filename
End Function
FSO 方法每次搜索大约需要 4-5 秒,但此方法执行时间不到 1 秒。动态地将命令直接输入命令提示符而无需每次都创建批处理文件仍然很好,但这目前有效。
这个问题(几乎)已经回答 here。
要从 VBA 中使用 Shell 运行 DOS 命令,命令行需要以 cmd.exe 和 /c 参数开头,然后是您的 DOS命令,像这样:
Shell "cmd.exe /c [your DOS command here]".
例如,要使用 DOS 的高效 DIR 命令查找文件(在本例中为公共控件库),将(裸)结果放入文本文件中:
Shell "cmd.exe /c dir ""C:\Program Files (x86)\mscomctl.ocx"" /b /s > ""C:\MyResults.txt"""
注意Shell命令returns控制立即交给VBA并没有等待DOS命令完成,所以我们需要等待文件创建,并在使用之前释放写锁。
例如:
Sub ShellTest()
'Uses VBA Shell command to run DOS command, and waits for completion
Dim Command As String
Dim FileName As String
Dim FileHan As Long
Dim ErrNo As Long
'Set output file for results (NB folder must already exist)
FileName = "C:\Temp\Test.txt"
'Remove output file if already exists
If Dir(FileName) > "" Then Kill FileName
'Set command string
Command = "cmd.exe /c dir ""C:\Program Files (x86)\mscomctl.ocx"" /b /s >""" & FileName & """"
'Shell out to DOS to perform the DIR command
Shell Command
'Wait for file creation
Do While Dir(FileName) = ""
Debug.Print "Waiting for file creation...", Time
DoEvents
Loop
'Wait for write lock release
ErrNo = -1
Do While ErrNo <> 0
FileHan = FreeFile 'Find an available file handle
On Error Resume Next 'Disable error trapping while attempting to gain write lock
Open FileName For Append As #FileHan 'Attempt to gain write lock - will fail with error while write lock is held by DOS
ErrNo = Err.Number 'Save error number
On Error GoTo 0 'Re-enable error trapping
Close #FileHan 'Release write lock just obtained (if successful) - fails with no error if lock not obtained
Debug.Print "Waiting for write lock release...", Time
DoEvents
Loop
'Now we can use the results file, eg open it in Notepad
Command = "cmd.exe /c notepad.exe """ & FileName & """"
Shell Command
Debug.Print "Done"
End Sub
WScript.Shell对象有一个运行方法,运行是一个DOS命令并等待完成,这导致代码更简单(但你不能在VBA 等待完成)。
Sub ShellTest2()
'Uses WScript.Shell object to run DOS command and wait for completion
Dim Command As String
Dim FileName As String
Dim FileHan As Long
Dim ErrNo As Long
'Set output file for results (NB folder must already exist)
FileName = "C:\Temp\Test.txt"
'Remove output file if already exists
If Dir(FileName) > "" Then Kill FileName
'Set command string
Command = "cmd.exe /c dir ""C:\Program Files (x86)\mscomctl.ocx"" /b /s >""" & FileName & """"
'Use the WScript shell to perform the DOS command (waits for completion)
CreateObject("WScript.Shell").Run Command, 1, True 'Change 2nd parameter to 0 to hide window
'Now we can use the results file, eg open it in Notepad
Command = "cmd.exe /c notepad.exe """ & FileName & """"
Shell Command
Debug.Print "Done"
End Sub
尝试在命令提示符下使用 shell 命令将 VBA 转到 运行 目录:
Call Shell("Dir \rtserver\controlleddocuments\""incoming reports""\" & Left(cmbComponent.Column(1), 3) & "" & Left(lstComponentLots.Column(1), 2) & "\*" & lstComponentLots.Column(1) & "* /b /a-d > C:\users\public\tmpcomponentsearch.txt", vbNormalFocus)
DoCmd.TransferText acImportDelim, "pathImport", "z_tmpcomponentsearch",
"C:\users\public\tmpcomponentsearch.txt"
Me.listScannedRecords.Requery
如果我 debug.print shell 命令中的字符串,我得到:
Dir \rtserver\controlleddocuments\"incoming reports"917\*1702-1015* /b /a-d > C:\users\public\tmpcomponentsearch.txt
在命令提示符下 运行 没问题,但是当我尝试在 VBA 中 运行 时出现 'file not found' 错误。我宁愿不创建批处理文件来执行此操作。
提前致谢。
为什么要使用 shell
?尝试使用 FileSystemObject(添加对 Microsoft Scripting Runtime 的引用)。尝试以下方式:
Dim fso As New FileSystemObject
Dim oFolder As Folder
Dim oFile As File
Dim strFolderName As String
strFolderName = "\rtserver\controlleddocuments\""incoming reports""917"
Set oFolder = fso.GetFolder(strFolderName)
For Each oFile In oFolder.Files
If oFile.Name Like "*1702-1015*" Then
CurrentDb.Execute "INSERT INTO z_tmpcomponentsearch (col_name) " & _
"VALUES ('" & Replace(oFile.Name, "'", "''") & "')"
End If
Next oFile
Set oFile = Nothing
Set oFolder = Nothing
Set fso = Nothing
我找到了答案 - 有点像。基本上使用 dir 命令动态创建批处理文件,然后 运行 it:
Public Function search_with_batch_file(searchStr As String)
Const my_filename = "C:\Users\Public\qsd_search.bat"
Dim FileNumber As Integer
Dim wsh As Object
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
FileNumber = FreeFile
'creat batch file
Open my_filename For Output As #FileNumber
Print #FileNumber, "Dir " & searchStr & " /b /a-d >
C:\users\public\tmpcomponentsearch.txt"
Print #FileNumber, "exit"
Close #FileNumber
'run batch file and wait to complete
Set wsh = VBA.CreateObject("WScript.Shell")
wsh.Run my_filename, windowStyle, waitOnReturn
'Delete batch file
Kill my_filename
End Function
FSO 方法每次搜索大约需要 4-5 秒,但此方法执行时间不到 1 秒。动态地将命令直接输入命令提示符而无需每次都创建批处理文件仍然很好,但这目前有效。
这个问题(几乎)已经回答 here。
要从 VBA 中使用 Shell 运行 DOS 命令,命令行需要以 cmd.exe 和 /c 参数开头,然后是您的 DOS命令,像这样:
Shell "cmd.exe /c [your DOS command here]".
例如,要使用 DOS 的高效 DIR 命令查找文件(在本例中为公共控件库),将(裸)结果放入文本文件中:
Shell "cmd.exe /c dir ""C:\Program Files (x86)\mscomctl.ocx"" /b /s > ""C:\MyResults.txt"""
注意Shell命令returns控制立即交给VBA并没有等待DOS命令完成,所以我们需要等待文件创建,并在使用之前释放写锁。
例如:
Sub ShellTest()
'Uses VBA Shell command to run DOS command, and waits for completion
Dim Command As String
Dim FileName As String
Dim FileHan As Long
Dim ErrNo As Long
'Set output file for results (NB folder must already exist)
FileName = "C:\Temp\Test.txt"
'Remove output file if already exists
If Dir(FileName) > "" Then Kill FileName
'Set command string
Command = "cmd.exe /c dir ""C:\Program Files (x86)\mscomctl.ocx"" /b /s >""" & FileName & """"
'Shell out to DOS to perform the DIR command
Shell Command
'Wait for file creation
Do While Dir(FileName) = ""
Debug.Print "Waiting for file creation...", Time
DoEvents
Loop
'Wait for write lock release
ErrNo = -1
Do While ErrNo <> 0
FileHan = FreeFile 'Find an available file handle
On Error Resume Next 'Disable error trapping while attempting to gain write lock
Open FileName For Append As #FileHan 'Attempt to gain write lock - will fail with error while write lock is held by DOS
ErrNo = Err.Number 'Save error number
On Error GoTo 0 'Re-enable error trapping
Close #FileHan 'Release write lock just obtained (if successful) - fails with no error if lock not obtained
Debug.Print "Waiting for write lock release...", Time
DoEvents
Loop
'Now we can use the results file, eg open it in Notepad
Command = "cmd.exe /c notepad.exe """ & FileName & """"
Shell Command
Debug.Print "Done"
End Sub
WScript.Shell对象有一个运行方法,运行是一个DOS命令并等待完成,这导致代码更简单(但你不能在VBA 等待完成)。
Sub ShellTest2()
'Uses WScript.Shell object to run DOS command and wait for completion
Dim Command As String
Dim FileName As String
Dim FileHan As Long
Dim ErrNo As Long
'Set output file for results (NB folder must already exist)
FileName = "C:\Temp\Test.txt"
'Remove output file if already exists
If Dir(FileName) > "" Then Kill FileName
'Set command string
Command = "cmd.exe /c dir ""C:\Program Files (x86)\mscomctl.ocx"" /b /s >""" & FileName & """"
'Use the WScript shell to perform the DOS command (waits for completion)
CreateObject("WScript.Shell").Run Command, 1, True 'Change 2nd parameter to 0 to hide window
'Now we can use the results file, eg open it in Notepad
Command = "cmd.exe /c notepad.exe """ & FileName & """"
Shell Command
Debug.Print "Done"
End Sub