从第二个 .vbs 执行时,VBScript (.vbs) 产生错误
VBScript (.vbs) Produces Errors When Executed From A 2nd .vbs
我们有一家供应商向我们发送 CSV 索引文件,以便与我们的 OnBase 文档导入软件一起使用。如果 CSV 文件是使用我们的一种机构形式生成的,OnBase 会摄取它们 w/o 错误,因为我们已经设置了与 CSV 文件中第一个分隔值匹配的相应文档类型。但是,如果 CSV 文件是使用供应商表格生成的,则第一个分隔值会略有不同,并会产生 OnBase 索引错误。我们的供应商为其许多客户使用此 CSV 格式,并表示无法对其进行自定义以匹配我们当前的 OnBase 文档类型 (w/o $$$)。
我的任务是确定一个解决方法,并找到了另一家使用 VBScript 在 OnBase 处理之前创建 CSV 索引文件的机构。经过一些合作,我能够使用 VBScript 编写类似的方法。然而,由于我们已经收到索引文件,我们的方法识别目标文件夹中有多少 CSV 文件,通过循环打开每个文件,识别 CSV 文件中的第一个分隔值,通过 switch case 方法比较该值,更新第一个基于 switch case 方法的定界 CSV 值,然后保存文件,直到循环结束(循环值 = 目标文件夹中的文件数 - 1 ... 占 vbs 文件)。当我点击 vbs 文件时,它就像一个魅力!
麻烦就在这里开始了。如果我尝试 运行 来自另一个 vbs 文件的 vbs 文件,脚本会产生错误:找不到文件。我包含了一些调试代码,我可以看到它正确地计算了目标文件夹中的文件数量等。当我认为它没有找到目标文件夹时,我通过在测试期间对路径进行硬编码来解决这个问题。即使我确定它正在找到正确的目标文件夹,我也会收到相同的“未找到文件”错误。如果我双击完全相同的 vbs 文件,它 运行 没有错误并且所有 CSV 文件都正确更新。
Update @Ansgar Wiechers 解决了查找和保持正确文件路径值的问题。但是,我仍然在第 163 行收到“未找到文件”错误。
Line 163
Char 1
Error: File Not Found
Code: 800A0035
Source: Microsoft VBScript runtime error
附带一提,我还注意到我的 vbs 脚本只会 运行 一次,然后你必须 copy/paste 在目标文件夹中 运行 之前的一个新实例再次宁它。这让我认为我的循环永远不会结束,所以我包含了一个调试 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 文件的目标文件夹中;删除了此 post 的 switch case 代码以保存 space):
' 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
总结:
当我双击时这段代码工作正常(一次);然后需要将新实例 copied/pasted 放入目标文件夹,然后双击将再次 运行 文件。
代码在通过另一个 vbs 文件 运行 时产生错误,第 163 行,未找到文件。
我很确定这可以在 OnBase 中完成,但我们的 OnBase 系统管理员坚持认为我是错误的。 51 个 OnBase 用户指南提到 VBScipting 超过 1,500 次,告诉我不是这样。也就是说,目前我的任务是在 OnBase 之外寻找解决方案。也欢迎就此主题发表评论。
像您描述的那样的错误通常是由对脚本工作目录的错误假设引起的。
您的文件夹结构看起来有点像这样(为简洁起见缩短了名称):
C:\base\folder
├── ERROR_FILES
│ ├── a.csv
│ ├── b.csv
: :
│ └── second.vbs
└── first.vbs
当您 double-click 脚本 second.vbs
时,工作目录是 C:\base\folder\ERROR_FILES
。但是,当您 double-click 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
"FOR TESTING ONLY" 部分试图通过将“\ERROR_FILES”附加到 strDirectory
来解决工作目录差异,这允许您枚举该文件夹的内容。但是,运行ning 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)
我们有一家供应商向我们发送 CSV 索引文件,以便与我们的 OnBase 文档导入软件一起使用。如果 CSV 文件是使用我们的一种机构形式生成的,OnBase 会摄取它们 w/o 错误,因为我们已经设置了与 CSV 文件中第一个分隔值匹配的相应文档类型。但是,如果 CSV 文件是使用供应商表格生成的,则第一个分隔值会略有不同,并会产生 OnBase 索引错误。我们的供应商为其许多客户使用此 CSV 格式,并表示无法对其进行自定义以匹配我们当前的 OnBase 文档类型 (w/o $$$)。
我的任务是确定一个解决方法,并找到了另一家使用 VBScript 在 OnBase 处理之前创建 CSV 索引文件的机构。经过一些合作,我能够使用 VBScript 编写类似的方法。然而,由于我们已经收到索引文件,我们的方法识别目标文件夹中有多少 CSV 文件,通过循环打开每个文件,识别 CSV 文件中的第一个分隔值,通过 switch case 方法比较该值,更新第一个基于 switch case 方法的定界 CSV 值,然后保存文件,直到循环结束(循环值 = 目标文件夹中的文件数 - 1 ... 占 vbs 文件)。当我点击 vbs 文件时,它就像一个魅力!
麻烦就在这里开始了。如果我尝试 运行 来自另一个 vbs 文件的 vbs 文件,脚本会产生错误:找不到文件。我包含了一些调试代码,我可以看到它正确地计算了目标文件夹中的文件数量等。当我认为它没有找到目标文件夹时,我通过在测试期间对路径进行硬编码来解决这个问题。即使我确定它正在找到正确的目标文件夹,我也会收到相同的“未找到文件”错误。如果我双击完全相同的 vbs 文件,它 运行 没有错误并且所有 CSV 文件都正确更新。
Update @Ansgar Wiechers 解决了查找和保持正确文件路径值的问题。但是,我仍然在第 163 行收到“未找到文件”错误。
Line 163
Char 1
Error: File Not Found
Code: 800A0035
Source: Microsoft VBScript runtime error
附带一提,我还注意到我的 vbs 脚本只会 运行 一次,然后你必须 copy/paste 在目标文件夹中 运行 之前的一个新实例再次宁它。这让我认为我的循环永远不会结束,所以我包含了一个调试 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 文件的目标文件夹中;删除了此 post 的 switch case 代码以保存 space):
' 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
总结:
当我双击时这段代码工作正常(一次);然后需要将新实例 copied/pasted 放入目标文件夹,然后双击将再次 运行 文件。
代码在通过另一个 vbs 文件 运行 时产生错误,第 163 行,未找到文件。
我很确定这可以在 OnBase 中完成,但我们的 OnBase 系统管理员坚持认为我是错误的。 51 个 OnBase 用户指南提到 VBScipting 超过 1,500 次,告诉我不是这样。也就是说,目前我的任务是在 OnBase 之外寻找解决方案。也欢迎就此主题发表评论。
像您描述的那样的错误通常是由对脚本工作目录的错误假设引起的。
您的文件夹结构看起来有点像这样(为简洁起见缩短了名称):
C:\base\folder ├── ERROR_FILES │ ├── a.csv │ ├── b.csv : : │ └── second.vbs └── first.vbs
当您 double-click 脚本 second.vbs
时,工作目录是 C:\base\folder\ERROR_FILES
。但是,当您 double-click 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
"FOR TESTING ONLY" 部分试图通过将“\ERROR_FILES”附加到 strDirectory
来解决工作目录差异,这允许您枚举该文件夹的内容。但是,运行ning 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)