Каждый язык программирования хорош в своей нише. Вызов программ, написанных на одном языке, из программ на другом языке позволяет быстрее и проще решать некоторые задачи, чем программировать решение с использованием единственного языка.
Рассмотрим наиболее удобный (для меня) способ выполнения программ на языке Perl из программ, написанных на VBA.
Я не затрагиваю такие вопросы, как создание нового макроса и/или модуля для VBA-приложений. Подразумевается, что читатель знаком.
Для работы потребуется ссылка на Microsoft Scripting Runtime, которая ставится в диалоговом окне Tools > References...:
Далее пишем код:
Вся работа выполняется в функции RunProgram, которая имеет следующие параметры:
Результаты выполнения программы представлены в виде структуры RunResult со следующими полями:
В процедуре RunPerl показаны различные примеры вызова (2 из них закомментированы). Для Perl использовался следующий скрипт:
Программисты оценят захват содержимого потоков ввода-вывода, поскольку они чаще всего служат для передачи информации между скриптами.
Полезно почитать:
http://www.script-coding.com/WSH/WshShell.html (обзор свойств объекта WshShell)
Рассмотрим наиболее удобный (для меня) способ выполнения программ на языке Perl из программ, написанных на VBA.
Я не затрагиваю такие вопросы, как создание нового макроса и/или модуля для VBA-приложений. Подразумевается, что читатель знаком.
Для работы потребуется ссылка на Microsoft Scripting Runtime, которая ставится в диалоговом окне Tools > References...:
Далее пишем код:
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Private Type RunResult
ExitCode As Integer
StdOut As String
StdErr As String
StdIn As String
ProcessID As Integer
End Type
Function RunProgram(sProgram As String, Optional sParams As String = "", _
Optional sCurrentDir As String = "", Optional sStdIn As String = "") As RunResult
Dim oShell As Object
Set oShell = CreateObject("WScript.Shell")
If sCurrentDir <> "" Then
oShell.CurrentDirectory = sCurrentDir
End If
Dim sCmd As String
sCmd = sProgram & " " & sParams
Dim oExec As Object
Set oExec = oShell.Exec(sCmd)
' Если есть данные стандартного потока ввода, то передаём их программе
If sStdIn <> "" And oExec.Status <> 1 Then
oExec.StdIn.WriteLine sStdIn
End If
oExec.StdIn.Close
' Ожидаем окончания программы
Do While oExec.Status <> 1
Sleep 500
Loop
RunProgram.ExitCode = oExec.ExitCode
RunProgram.StdOut = oExec.StdOut.ReadAll()
RunProgram.StdErr = oExec.StdErr.ReadAll()
RunProgram.StdIn = sStdIn
RunProgram.ProcessID = oExec.ProcessID
Set oShell = Nothing
End Function
Sub RunPerl()
Dim Результат As RunResult
Результат = RunProgram("c:\perl\bin\perl.exe", sParams:="1.pl")
Результат = RunProgram("c:\perl\bin\perl.exe", sParams:="""d:\Мой полигон\test.pl""", sStdIn:="12345")
Результат = RunProgram("d:\Мой полигон\test.cmd", sParams:="111 222")
MsgBox ("STDOUT " + Результат.StdOut)
MsgBox ("STDERR " + Результат.StdErr)
End Sub
Вся работа выполняется в функции RunProgram, которая имеет следующие параметры:
- sProgram - это путь к запускаемому файлу. Им может быть интерпретатор Perl, командный файл (*.cmd) и т.д. Как видно из примера, допускается использование символов пробела в пути и/или в имени файла.
- sParams задаёт параметры для вызываемой программы. При вызове функции программист должен сам следить на разделение параметров пробелами.
- sCurrentDir позволяет задать текущую рабочую папку при выполнении программы.
- sStdIn позволяет задать содержимое стандартного потока ввода.
Результаты выполнения программы представлены в виде структуры RunResult со следующими полями:
- ExitCode - хранит код завершения программы (программисты на C/C++ возвращают это значение с помощью return в main).
- StdOut - содержимое стандартного потока вывода.
- StdErr - содержимое стандартного потока ошибок.
- StdIn - содержимое стандартного потока ввода.
- ProcessID - идентификатор запущенного процесса.
В процедуре RunPerl показаны различные примеры вызова (2 из них закомментированы). Для Perl использовался следующий скрипт:
#!/usr/bin/perl my $str = <STDIN>; print STDOUT ">>STDOUT>>$str<<"; print STDERR ">>STDERR>>$str<<";а для командного интерпретатора Windows этот:
@echo off echo %%1=%1 echo %%2=%2
Программисты оценят захват содержимого потоков ввода-вывода, поскольку они чаще всего служат для передачи информации между скриптами.
Полезно почитать:
http://www.script-coding.com/WSH/WshShell.html (обзор свойств объекта WshShell)

Комментариев нет:
Отправить комментарий