我有一个SAS程序,需要许多输入文件,每个月的名称不同。而不是将Windows资源管理器中的单个文件名更新为SAS中的硬编码别名,或者将新文件名复制并粘贴到宏变量中,我希望SAS启动文件提示,我可以在其中选择输入。我在Windows 7上使用SAS 9.4。
为此,我编写了一个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将I / O流读取到数据集中。我想如果我能做到这一点,那么我至少可以使用CALL SYMPUT
然后将返回值赋给宏变量。但是,我无法让SAS读取返回值。
我一直在尝试的一个例子是,
filename getfile pipe "C:\temp\GetFilePath.vbs";
data test;
infile getfile;
input path $;
run;
提示会打开,但返回值未分配给path
。
答案 0 :(得分:3)
只需替换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在调用.vbs时是必要的(对我来说,在Windows 2012中),以保持输出在控制台中 - 而不是将其作为窗口反弹回来。 / p>
顺便说一下,赞一个干净利落的方法。我不理解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;