Выполнение файла VBScript из макросов Excel VBA

#vbscript #excel #vba

#vbscript #excel #vba

Вопрос:

Мне нужно несколько примеров Excel vba, где с помощью кода VBA (макроса Excel) я мог бы вызвать VBScript и получить некоторые значения, такие как имя файла и информация о каталоге из vbscript, и присвоить их переменным в коде VBA. Заранее благодарю вас

Что-то вроде этого

Макрос VBA:

 Sub Foo2Script
Dim x As Long
x=2
'Call VBscript here
MsgBox scriptresult
End Sub
  

VBScript:

 Dim x, y ,Z
x = x_from_macro
y = x   2
Z = X Y
scriptresult = y,Z
  

Комментарии:

1. Разве вы не можете просто запустить код непосредственно в VBA? VBScript является подмножеством VB и может выполняться практически без изменений в среде VB.

2. Смотрите, требование заключается в том, что мне нужно присвоить динамические значения (в основном пути к файлам и имена файлов) переменным в макросах Excel. Я не хочу обращаться к макросам каждый раз, когда меняю путь, поэтому, если мы сможем назначить эти значения через VBS, тогда было бы легко назначать и изменять значения.

3. Это на 100% не дает ответа на вопрос в моем комментарии.

4. Я согласен с @Tomalak. Я не знаю ничего, что VBS может делать, чего не может Excel VBA, и обычно лучше. Если это вопрос внешнего управления параметрами, то я бы предложил использовать значения ячеек Excel для этой цели. Или текстового файла, подобного INI. Или настроек реестра. Или Active Directory. Или, …

5. @S .. Пожалуйста, отформатируйте свой код как code , иначе читать его будет настоящей болью. На этот раз я сделаю это за вас.

Ответ №1:

Это можно сделать, но я должен согласиться с Томалаком и другими, что это не лучший способ. Однако, говоря это, VBScript иногда может творить чудеса, если вы используете его как своего рода механизм запуска и забывания. Его можно довольно эффективно использовать для имитации многопоточности в VBA, при которой вы разбиваете полезную нагрузку и распределяете ее по отдельным VBScripts для независимого запуска. Например, вы могли бы организовать «рой» отдельных VBScripts для массовой загрузки с веб-сайтов в фоновом режиме, пока VBA продолжает работу с другим кодом.

Ниже приведен некоторый код VBA, который я упростил, чтобы показать, что можно сделать, и записывает простой VBScript «на лету». Обычно я предпочитаю запускать его с помощью, 'wshShell.Run """" amp; SFilename amp; """" что означает, что я могу забыть об этом, но я включил в этот пример этот метод, Set proc = wshShell.exec(strexec) который позволяет проверить объект на завершение

Поместите это в MODULE1

 Option Explicit

Public path As String

Sub writeVBScript()
Dim s As String, SFilename As String
Dim intFileNum As Integer, wshShell As Object, proc As Object


Dim test1 As String
Dim test2 As String

test1 = "VBScriptMsg - Test1 is this variable"
test2 = "VBScriptMsg - Test2 is that variable"

    'write VBScript (Writes to Excel Sheet1!A1 amp; Calls Function Module1.ReturnVBScript)
    s = s amp; "Set objExcel = GetObject( , ""Excel.Application"") " amp; vbCrLf
    s = s amp; "Set objWorkbook = objExcel.Workbooks(""" amp; ThisWorkbook.Name amp; """)" amp; vbCrLf
    s = s amp; "Set oShell = CreateObject(""WScript.Shell"")" amp; vbCrLf
    s = s amp; "Msgbox (""" amp; test1 amp; """)" amp; vbCrLf
    s = s amp; "Msgbox (""" amp; test2 amp; """)" amp; vbCrLf
    s = s amp; "Set oFSO = CreateObject(""Scripting.FileSystemObject"")" amp; vbCrLf
    s = s amp; "oShell.CurrentDirectory = oFSO.GetParentFolderName(Wscript.ScriptFullName)" amp; vbCrLf
    s = s amp; "objWorkbook.sheets(""Sheet1"").Range(""" amp; "A1" amp; """) = oShell.CurrentDirectory" amp; vbCrLf
    s = s amp; "Set objWMI = objWorkbook.Application.Run(""Module1.ReturnVBScript"", """" amp; oShell.CurrentDirectory amp; """")  " amp; vbCrLf
    s = s amp; "msgbox(""VBScriptMsg - "" amp; oShell.CurrentDirectory)" amp; vbCrLf
    Debug.Print s

    ' Write VBScript file to disk
    SFilename = ActiveWorkbook.path amp; "TestVBScript.vbs"
    intFileNum = FreeFile
    Open SFilename For Output As intFileNum
    Print #intFileNum, s
    Close intFileNum
    DoEvents

    ' Run VBScript file
    Set wshShell = CreateObject("Wscript.Shell")
    Set proc = wshShell.exec("cscript " amp; SFilename amp; "") ' run VBScript
    'could also send some variable
    'Set proc = wsh.Exec("cscript VBScript.vbs var1 var2") 'run VBScript passing variables

    'Wait for script to end
    Do While proc.Status = 0
    DoEvents
    Loop

    MsgBox ("This is in Excel: " amp; Sheet1.Range("A1"))
    MsgBox ("This passed from VBScript: " amp; path)

    'wshShell.Run """" amp; SFilename amp; """"

    Kill ActiveWorkbook.path amp; "TestVBScript.vbs"
End Sub


Public Function ReturnVBScript(strText As String)
path = strText
End Function
  

Это продемонстрировало несколько способов передачи переменных.

Комментарии:

1. спасибо за ваши усилия и ответ …. который заставил меня изучить несколько других концепций в VBA, но я ищу что-то вроде этого ~ ~ Макрос VBA ~ ~ Sub Foo2Script Dim x As Long x = 2 Вызовите VBScript здесь MsgBox scriptresult End Sub ~ ~ VBScript ~~ Dim x, y, Z x = x_from_macro y = x 2 Z = X Y scriptresult = y, Z

2. @S.. — Microsoft Script Control 1.0 может сделать это за вас.

3. Поправьте меня, если я ошибаюсь, но опубликованный вами код будет работать только с 1 запущенным экземпляром Excel? Судя по тому, как у вас работает GetObject(), это было бы так. Если да, то есть ли способ более точно получить экземпляр Excel, который запустил vbscript?

4. Ну, в скрипте указаны лист и ячейка; просто измените, чтобы указать конкретную книгу.

5. если вы укажете полный путь к рабочей книге в качестве единственного параметра для GetObject, то у вас может быть запущено более одного экземпляра Excel