Эта функция обеспечивает быстрый способ запуска команды командной строки с использованием объекта буфера обмена:
Вывод из командной строки захвата:
Function getCmdlineOutput(cmd As String)
CreateObject("WScript.Shell").Run "cmd /c """ & cmd & "|clip""", 0, True 'output>clipbrd
With CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}") 'latebound clipbrd obj
.GetFromClipboard 'get cmdline output from clipboard
getCmdlineOutput = .GetText(1) 'return clipboard contents
End With
End Function
Пример использования:
Sub Demo1()
MsgBox getCmdlineOutput("w32tm /tz") 'returns the system Time Zone information
End Sub
Используется команда WShell Run
, поскольку она необязательно допускает асинхронное выполнение, то есть будет ожидать завершения выполнения команды до продолжения VBA, что важно при использовании буфера обмена.
Он также использует встроенную, но часто забываемую утилиту командной строки, которая называется clip.exe
, в данном случае в качестве места назначения для переданного по конвейеру cmdline вывода.
Для работы с буфером обмена требуется ссылка на библиотеку Microsoft Forms 2.0 , которую в данном случае я создал с помощью ссылки Late-bound (которая отличается от MS Forms - иначе * 1027) *fm20.dll
- это библиотека Windows, а не VBA).
Сохранение существующих данных буфера обмена:
В моем случае проблема заключалась в том, что функция выше стирает существующие данные буфера обмена, поэтому функция ниже модифицируется для сохранения и замены существующего текста в буфере обмена.
Если в буфере обмена есть что-то, кроме текста, вы будете предупреждены, что оно будет потеряно. Некоторое тяжелое кодирование может позволить возвращать другие / любые типы данных буфера обмена ... но расширенные манипуляции с буфером обмена намного сложнее, чем понимают большинство пользователей, и у меня, честно говоря, нет необходимости или желания в них разбираться. Подробнее здесь .
Обратите внимание, что в этом методе MS Forms имеет значение Early-Bound , но может быть изменено при желании. (Но помните, как общее правило, позднее связывание обычно удваивает время обработки.)
Function getCmdlineOutput2(cmd As String)
'requires Reference: C:\Windows\System32\FM20.DLL (MS Forms 2.0) [Early Bound]
Dim objClipboard As DataObject, strOrigClipbrd As Variant
Set objClipboard = New MSForms.DataObject 'create clipboard object
objClipboard.GetFromClipboard 'save existing clipboard text
If Not objClipboard.GetFormat(1) Then
MsgBox "Something other than text is on the clipboard.", 64, "Clipboard to be lost!"
Else
strOrigClipbrd = objClipboard.GetText(1)
End If
'shell to hidden commandline window, pipe output to clipboard, wait for finish
CreateObject("WScript.Shell").Run "cmd /c """ & cmd & "|clip""", 0, True
objClipboard.GetFromClipboard 'get cmdline output from clipboard
getCmdlineOutput2 = objClipboard.GetText(1) 'return clipboard contents
objClipboard.SetText strOrigClipbrd, 1 'Restore original clipboard text
objClipboard.PutInClipboard
End Function
Пример использования:
Sub Demo2()
MsgBox getCmdlineOutput2("dir c:\") 'returns directory listing of C:\
End Sub