2016-10-27 2 views
2

У меня есть программа SAS, для которой требуется множество входных файлов, имена которых меняются каждый месяц. Вместо того, чтобы обновлять отдельные имена файлов в проводнике Windows до жестко обозначенных псевдонимов в SAS или копировать и вставлять новые имена файлов в макропеременные, я хочу, чтобы SAS инициировал приглашение файла, где я могу выбрать входы. Я использую SAS 9.4 в Windows 7.Прочитайте возвращаемое значение из VBScript в SAS

С этой целью я написал VBScript, который открывает диалоговое окно и возвращает путь к выбранному файлу или пустой строке, если диалог отменен или закрыт.

' GetFilePath.vbs 

Option Explicit 

Function GetFilePath() 

    Dim objExec, strMSHTA, wshShell 

    GetFilePath = "" 

    strMSHTA = "mshta.exe ""about:<input type=file id=FILE>" _ 
      & "<script>FILE.click();new ActiveXObject('Scripting.FileSystemObject')" _ 
      & ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>""" 

    Set wshShell = CreateObject("WScript.Shell") 
    Set objExec = wshShell.Exec(strMSHTA) 

    GetFilePath = objExec.StdOut.ReadLine() 

    Set objExec = Nothing 
    Set wshShell = Nothing 

End Function 

'WScript.Echo GetFilePath() 

GetFilePath() 

В идеале я хотел бы, чтобы присвоить возвращаемое значение GetFilePath.vbs к макропеременной. Однако мне непонятно, как мне это сделать. Единственная релевантная информация, которую я нашел, касается чтения потоков ввода-вывода в наборе данных с использованием unnamed pipe. Я полагаю, что если я могу это сделать, тогда я мог бы хотя бы использовать CALL SYMPUT, чтобы присвоить возвращаемое значение макропеременной. Однако я не могу получить SAS для чтения в возвращаемом значении.

Пример того, что я пытался есть

filename getfile pipe "C:\temp\GetFilePath.vbs"; 

data test; 
    infile getfile; 
    input path $; 
run; 

открывается подсказка, но возвращаемое значение не присваивается path.

ответ

2

Просто замените последнюю строку файла VBScript следующим образом:

WScript.StdOut.Write GetFilePath() 

и настраивайте свой Sas код таким образом (нет необходимости объявлять имя файла):

data test; 
    infile "cscript.exe C:\temp\GetFilePath.vbs" pipe; 
    input path:$100.; /* adjust length as appropriate */ 
run; 

Основная хитрость " должен был записать вывод в STDOUT, а не эхо. Кроме того, в соответствии с этим answer, cscript.exe был необходим (для меня, в Windows 2012) при вызове .vbs, чтобы сохранить вывод в консоли - вместо того, чтобы отскакивать от него в виде окна.

К слову, престиж для аккуратного подхода. Я не оценил, как SAS можно использовать для запуска (и чтения) графических приложений таким образом!

Вот минимальный рабочий пример я использовал для тестирования:

' GetFilePath.vbs 
Option Explicit 
Function GetFilePath() 
    GetFilePath = InputBox("Provide a value for SAS") 
End Function 
WScript.StdOut.Write GetFilePath() 

На стороне SAS:

data _null_; 
    infile "cscript.exe C:\Temp\aaa.vbs" pipe; 
    input; putlog _infile_; 
run; 
+0

Это хороший материал! Если вы создадите набор данных, вы заметите, что введены два наблюдения; первый - отказ от Microsoft, второй - путь к файлу. Кажется, что '// NoLogo' - это возможность отключить отказ от ответственности. Если я выполняю 'cscript.exe // NoLogo C: \ temp \ GetFilePath.vbs' в оболочке, я действительно получаю только путь к файлу. Однако, когда я пытаюсь сделать то же утверждение в SAS, никакие замечания не записываются в набор данных. Есть идеи? –

+0

Не уверен в опции '// NoLogo', но чтобы игнорировать эти первые строки в SAS, просто добавьте следующую строку в свой файл данных:' if _n _> = 4 then output; '(скорректируйте число, соответствующее) –

+0

Я обнаружил, что это также помогло: «тест данных; длина пути $ 260.; infile "cscript.exe C: \ temp \ GetFilePath.vbs" pipe firstobs = 3; входной путь $ 260; run; 'Длина пути 260, потому что это максимальная длина пути в Windows 7. –