首页 > 解决方案 > VBScript (.vbs) 从第二个 .vbs 执行时产生错误

问题描述

我们有一个供应商向我们发送 CSV 索引文件,以便与我们的 OnBase 文档导入软件一起使用。如果 CSV 文件是使用我们的一种机构形式生成的,OnBase 会在没有错误的情况下摄取它们,因为我们已经设置了与 CSV 文件中第一个分隔值匹配的相应文档类型。但是,如果 CSV 文件是使用供应商表单生成的,则第一个分隔值会略有不同,并会产生 OnBase 索引错误。我们的供应商为他们的许多客户使用这种 CSV 格式,并表示无法对其进行自定义以匹配我们当前的 OnBase 文档类型(不含 $$$)。

我的任务是确定一种解决方法,并找到另一个机构使用 VBScript 在 OnBase 处理之前创建 CSV 索引文件。经过一些合作,我能够使用 VBScript 编写类似的方法。然而,由于我们已经收到索引文件,我们的方法识别目标文件夹中有多少 CSV 文件,通过循环打开每个文件,识别 CSV 文件中的第一个分隔值,通过 switch case 方法比较该值,更新基于 switch case 方法的第一个分隔的 CSV 值,然后保存文件,直到循环结束(循环值 = 目标文件夹中的文件数 - 1...考虑 vbs 文件)。当我单击 vbs 文件时,它就像一个魅力!

这就是麻烦开始的地方。如果我尝试从另一个 vbs 文件运行 vbs 文件,脚本会产生错误:找不到文件。我包含了一些调试代码,我可以看到它正确地计算了目标文件夹中的文件数量等。当我认为它没有找到目标文件夹时,我通过在测试期间对路径进行编码来解决这个问题。即使我确定它找到了正确的目标文件夹,我也会收到相同的 File Not Found 错误。如果我双击完全相同的 vbs 文件,它会正常运行并且所有 CSV 文件都已正确更新。

更新@Ansgar Wiechers 解决了查找和保持正确文件路径值的问题。但是,我仍然在第 163 行收到 File Not Found 错误。

错误消息的屏幕截图。

第 163 行
字符 1
错误:找不到文件
代码:800A0035
源:Microsoft VBScript 运行时错误

顺便说一句,我还注意到我的 vbs 脚本只会运行一次,然后您必须在目标文件夹中复制/粘贴一个新实例,然后再再次运行它。这让我认为我的循环永远不会结束,所以我MsgBox在循环结束(或认为它已经结束)之后和命令之前显示了一个调试WScript.Quit。这些是脚本中的最后两行,消息框成功显示。我将从我的两个 vbs 文件中包含以下代码。

VBScript 文件 #1(星号掩盖个人信息):

Dim CurrentDirectory

Set FSO = CreateObject("Scripting.FileSystemObject")
CurrentDirectory = "C:\Users\*******\Desktop\ProVerify\Testing\ERROR_FILES\"
FSO.CopyFile "C:\Users\*******\Desktop\ProVerify\Testing\Old Source Files\VBScript_PV_Form_conversion.vbs", CurrentDirectory

Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "C:\Users\*******\Desktop\ProVerify\Testing\ERROR_FILES\VBScript_PV_Form_conversion.vbs"
WshShell.Popup "VBS file will be deleted in 10 seconds...", 10
FSO.DeleteFile "C:\Users\*******\Desktop\ProVerify\Testing\ERROR_FILES\VBScript_PV_Form_conversion.vbs"

WScript.Quit

VBScript 文件 #2(在包含 CSV 文件的目标文件夹中;删除了这篇文章的切换案例代码以节省空间):

' Declare vars
Dim intDebug, sFile, strDirectory, numFiles, sLine, aLine

intDebug = 1

' Find path of folder where script file resides & Set Object vars
Set objFSO = CreateObject("Scripting.FileSystemObject")
strDirectory = objFSO.GetParentFolderName(WScript.ScriptFullName)

Set objFolder = objFSO.GetFolder(strDirectory)  

' Count number of files in folder 
numFiles = objFolder.Files.Count - 1

If intDebug = 1 Then
    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Popup "File Count: " & numFiles, 2
    WshShell.Popup "File Path: " & strDirectory, 2
Else
End If

If numFiles <= 1 Then
    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Popup "No Files to Process", 2
    WScript.Quit
Else
End If  

'Loop through each file in folder
For Each folderIdx In objFolder.Files
    Set oStream = folderIdx.OpenAsTextStream

    'Read file and capture first delimeted value
    sLine = oStream.ReadLine
    oStream.Close
    aLine = Split(sLine, ",")

    ' Compare delimeted value & update to OnBase DocType naming convention
    Select Case aLine(0)
        [*****case method here*****]
    End Select

    ' Create replacement delimited value
    sLine = ""

    For i = LBound(aLine) To UBound(aLine)
        sLine = sLine + aLine(i) + ","
    Next

    'Open file and replace updated delimeted value
    Set oStream = objFSO.OpenTextFile(folderIdx.Name, 2)
    oStream.WriteLine Left(sLine, Len(sLine)-1) ' Remove comma from updated delimeted value
    oStream.Close
Next

'Reset Object vars
Set oStream = Nothing
Set objFSO = Nothing
Set objFolder = Nothing

If intDebug = 1 Then
    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Popup "Conversion Complete", 2
Else
End If

WScript.Quit

总之:

  1. 当我双击时,这段代码可以正常工作(一次);然后需要将一个新实例复制/粘贴到目标文件夹中,然后双击将再次运行该文件。

  2. 代码通过另一个 vbs 文件运行时产生错误,第 163 行,未找到文件。

  3. 我很确定这可以在 OnBase 中完成,但我们的 OnBase 系统管理员坚持认为我不正确。51 OnBase 用户指南提到 VBScipting 超过 1,500 次,否则告诉我。也就是说,目前我的任务是在 OnBase 之外寻找解决方案。也可以随意评论这个话题。

标签: arrayscsvvbscriptonbase

解决方案


像您描述的错误通常是由对脚本工作目录的错误假设引起的。

您的文件夹结构显然有点像这样(为简洁起见,名称缩写):

C:\基地\文件夹
├── ERROR_FILES
│ ├── a.csv
│ ├── b.csv
: :
│ └── second.vbs
└── 第一个.vbs

双击脚本second.vbs时,工作目录为C:\base\folder\ERROR_FILES. 但是,当您双击first.vbs工作目录时是C:\base\folder. C:\base\folder\ERROR_FILES\second.vbs从那里调用不会更改second.vbs.

现在让我们看一下第二个脚本中的代码:

strDirectory = objFSO.GetAbsolutePathName(".")

'***********FOR TESTING ONLY**********************
If strDirectory = "C:\Users\*******\Desktop\ProVerify\Testing" Then
    strDirectory = objFSO.GetAbsolutePathName(".") & "\ERROR_FILES"
Else
End If
'***********FOR TESTING ONLY**********************

Set objFolder = objFSO.GetFolder(strDirectory)

...

For Each folderIdx In objFolder.Files
    Set oStream = objFSO.OpenTextFile(folderIdx.Name, 1)
    ...
Next

“仅用于测试”部分尝试通过将“\ERROR_FILES”附加到 来解释工作目录的差异strDirectory,这允许您枚举该文件夹的内容。但是,运行objFSO.OpenTextFile(folderIdx.Name, 1)仍然会尝试从当前工作目录打开每个文件,该目录仍然是C:\base\folder.

为避免此问题运行objFSO.OpenTextFile(folderIdx.Path),或者更好的是,使用对象的OpenAsTextStream方法。此外,当您的脚本与数据文件位于同一文件夹中时,最好从脚本路径获取目录,而不是将特定子文件夹附加到工作目录(这可能不是您认为的那样)。

把上面的代码片段改成这样,它会做你想做的事:

strDirectory  = objFSO.GetParentFolderName(WScript.ScriptFullName)
Set objFolder = objFSO.GetFolder(strDirectory)

...

For Each folderIdx In objFolder.Files
    Set oStream = folderIdx.OpenAsTextStream
    ...
Next

打开文件进行写入时使用相同的方法:

Set oStream = folderIdx.OpenAsTextStream(2)

推荐阅读