arrays - 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
总之:
当我双击时,这段代码可以正常工作(一次);然后需要将一个新实例复制/粘贴到目标文件夹中,然后双击将再次运行该文件。
代码通过另一个 vbs 文件运行时产生错误,第 163 行,未找到文件。
我很确定这可以在 OnBase 中完成,但我们的 OnBase 系统管理员坚持认为我不正确。51 OnBase 用户指南提到 VBScipting 超过 1,500 次,否则告诉我。也就是说,目前我的任务是在 OnBase 之外寻找解决方案。也可以随意评论这个话题。
解决方案
像您描述的错误通常是由对脚本工作目录的错误假设引起的。
您的文件夹结构显然有点像这样(为简洁起见,名称缩写):
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)
推荐阅读
- mysql - 如何在nodejs中执行sequelize bulk insert
- sql - Oracle 外连接
- excel - Excel 公式 - 如何将单元格中的公式值分成 2 个不同的单元格?
- java - 属性文件中的多重赋值
- angularjs - 将数据从弹簧引导控制器(重定向)传递到角度页面而不传递查询参数?
- python - 反复解压文件导致内存泄漏
- reactjs - 如何在反应原生的另一个组件中使用 ref?
- ruby-on-rails - 在没有更改任何字段的 Rails 应用程序中防止更新记录
- python - 需要用ajax调用实现django-filter
- android - 使用 LiveData 在 ImageView 上使用 DataBinding 时出现 IllegalArgumentException