比较文本文件 - 使用 VB脚本对一些文本进行识别



首先,我不是编程背景,对VBscript完全陌生。出于某些原因,我必须在办公室执行此脚本任务。我想将其与快速测试专业版 11 一起使用。

我在这里浏览了许多帖子以及其他论坛,但找不到所需的信息。

好的,这就是我需要做的:

我必须比较两个文本文件并将差异写入第三个文件。这两个文件在某些字段中具有几乎相同的内容,即:日期,订单号等。

例如,File-1 的日期:00/11/1234 和订单号:1111,File-2 的日期:11/00/6789 和订单号:2222那么有什么方法可以忽略这些字段及其值吗?有什么方法可以创建可以添加的忽略列表,该列表将在比较期间使用并在比较期间跳过字段?所以我的差异文件不会有这些差异,因为这些值总是不同的。因此,我可以在我的结果文件中获取所有其他差异。

以下是示例文件供您参考。

到目前为止,我已经比较了这两个文件,但以一种最简单的方式,我不知道如何忽略这些字段。我想将这些任务作为一个函数,以便我可以在我的函数库中使用它。

文件-1

日期: 00/11/1234/订货号: 1111

价格 1: $1111.00

价格 2: $2222.00

价格 3: $1234.00

ABC def GHI kjl 1111

订货号: 1111

期限:2年

日期: 00/11/1234

文件-2

日期: 11/00/6789 和 订货号: 2222

价格 1: $1111.00

价格 2: $2222.00

价格 3: $5678.00

ABC def GHI kjl 1111

订货号: 2222

期限:3年

日期: 11/00/6789

结果文件应显示:

差异:

文件-1 第 4 行:价格 3:$1234.00

文件-2 第 4 行:价格 3:$5678.00

文件-1 第 7 行:期限:2 年

文件-2 第 7 行:期限:3 年

提前非常感谢你。

嗨@Ekkehard.霍纳 非常感谢您的帮助和时间,以及容忍我的尖锐问题。 事实是,我越是试图理解你的代码,我就越困惑。 当我将其以下代码放在快速测试Pro_11中时,它会抛出语法错误@"Dim oDifferent:Set oDiff = New cDiffer.init("C:..." QTP说"预期结束"之间"...New cDiffer"和".init" QTP在函数"TrailVersion"和函数"GoldVersion"中都显示错误

如果您对此有所了解,那就太好了。 是否有必要有"预期"文本文件...?因为我不想包含该部分,否则我必须为每次比较创建"预期"文件。

请原谅我狡猾的问题。

提前谢谢。

Class cDiffer   
Option Explicit  
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")  
    WScript.Quit TrialVersion() 
    WScript.Quit TinVersion()  
Function TinVersion()   
    WScript.Echo "can't compare files yet."   
    TinVersion = 1 
End Function ' TinVersion  
HERE I'VE COMMENTED TRIALVERSION FUNCTION 
Function TrialVersion()   
Dim oDiffer : Set oDiffer = New cDiffer.init("C:Documents and Settings24800My DocumentsPDF comparisonA_30120625003267.TXT", "C:Documents and Settingsaa24800My DocumentsPDFcomparisonB_30120502002776.TXT", Array("Quote ID:", "Quote Summary for:", "Quote Date:", "Tracking ID (A):", "Tracking ID (Z):", "Tracking ID:")
    ' the differ should be able to return a result - the differences   
    Dim sRes : sRes = oDiffer.diffs()   
    ' check actual vs. expected result   
    Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()  
    WScript.Echo "--------- Res"   
    WScript.Echo sRes   
    If sExp = sRes Then      
        WScript.Echo "ok"      
        ' save result      
        goFS.CreateTextFile("C:Documents and Settingsaa24800My DocumentsPDF comparisonResult.TXT", True).Write sRes      
        TrialVersion = 0   Else      
        ' show failure      
        WScript.Echo "--------- Exp"      
        WScript.Echo sExp      
        WScript.Echo "not ok"      
        TrialVersion = 1   
    End If 
End Function ' TrialVersion  
'trivial Differ 
'Class cDiffer   
    Dim m_sLFSpec : m_sLFSpec = "C:Documents and Settingsaa24800My DocumentsPDF comparisonA_30120625003267.TXT"
Dim m_sRFSpec : m_sRFSpec = "C:Documents and Settingsaa24800My DocumentsPDF comparisonB_30120502002776.TXT"   
    ' "constructor" with params   
    Public Function init(sLFSpec, sRFSpec)     
        Set init  = Me     
        m_sLFSpec = sLFSpec     
        m_sRFSpec = sRFSpec   
    End Function   
    Public Function diffs()     
        diffs = "cDiffer.diffs() not implemented yet."   
    End Function ' diffs 
'End Class ' cDiffer00
'gold Differ 
'Class cDiffer   
'   Private m_sLFSpec   ' file specs   
'   Private m_sRFSpec   
    Private m_sLFiNa    ' file names   
    Private m_sRFiNa   
    Private m_dicLabels ' store and efficiently find selective labels   
    ' "constructor" with params   
    Public Function init(sLFSpec, sRFSpec, aLabels)     
        Set init  = Me     
        m_sLFSpec = sLFSpec     
        m_sRFSpec = sRFSpec     
        m_sLFiNa  = goFS.GetBaseName(sLFSpec)     
        m_sRFiNa  = goFS.GetBaseName(sRFSpec)     
        Set m_dicLabels = CreateObject("Scripting.Dictionary")     
        m_dicLabels.CompareMode = vbTextCompare ' case-insensitive     
        Dim sKey     
        For Each sKey In aLabels         
            m_dicLabels(sKey) = 0     
        Next   
    End Function   
    Public Function diffs()     ' Use ArrayList to collect the results     
        Dim alRes : Set alRes = CreateObject("System.Collections.ArrayList")     
        ' requested title     
        alRes.Add "Differences:"     
        ' open both input files     
        Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)     
        Dim tsR   : Set tsR   = goFS.OpenTextFile(m_sRFSpec)     
        ' loop over lines     
        Do Until tsL.AtEndOfStream        
            Dim sLL : sLL = tsL.ReadLine()        
            Dim sRL        
            ' second file could be shorter        
            If tsR.AtEndOfStream Then           
                alRes.Add "tsR.AtEndOfStream"           
        Exit Do        
            Else           
                sRL = tsR.ReadLine()        
            End If        
            ' no need for work if lines are equal        
            If sLL <> sRL Then           
                If m_dicLabels.Exists(Split(sLL, ":")(0))Then                  
                Dim sLiNo : sLiNo = CStr(tsL.Line - 1)& ":"              
            alRes.Add Join(Array(m_sLFiNa, "Line", sLiNo, sLL))              
            alRes.Add Join(Array(m_sRFiNa, "Line", sLiNo, sRL))           
            End If        
        End If     
    Loop     
    tsL.Close     
    tsR.Close     
    diffs = Join(alRes.ToArray(), vbCrLf) & vbCrLf   
End Function ' diffs 
End Class ' cDiffer
Function GoldVersion()   
   ' the differ should know about the files to compare   
   ' and the info labels to select   
   Dim oDiffer : Set oDiffer = New cDiffer.init("C:Documents and Settingsaa24800My DocumentsPDF comparisonA_30120625003267.TXT", "C:Documents and Settingsaa24800My DocumentsPDF comparisonB_30120502002776.TXT", Array("Quote ID:", "Quote Summary for:", "Quote Date:", "Tracking ID (A):", "Tracking ID (Z):", "Tracking ID:")
   ' the differ should be able to return a result - the differences    
   Dim sRes : sRes = oDiffer.diffs()   
   ' check actual vs. expected result   
   Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()   
   WScript.Echo "--------- Res"   
   WScript.Echo sRes   
    If sExp = sRes Then      
       WScript.Echo "ok"      
       ' save result      
       goFS.CreateTextFile("C:Documents and Settingsaa24800My DocumentsPDF comparisonResult.TXT", True).Write sRes      
       GoldVersion = 0   Else      
       ' show failure      
       WScript.Echo "--------- Exp"      
       WScript.Echo sExp      
       WScript.Echo "not ok"      
       GoldVersion = 1   
    End If 
End Function ' GoldVersion

如果你是 VBScript 的新手,你可能会从解决当前的问题中受益一种可以帮助您解决下一个问题的方法。

从放置 SelFileComp.vbs 开始:

'' SelFileComp.vbs - selective file compare
Option Explicit
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
WScript.Quit TinVersion()
Function TinVersion()
  WScript.Echo "can't compare files yet."
  TinVersion = 1
End Function ' TinVersion

进入某个合适的目录。添加输入和预期结果文件。启动 SelFileComp.vbs:

cscript SelFileComp.vbs
can't compare files yet.
echo %ErrorLevel%
1

添加(并调用(准备和使用(普通(Different对象的TrialVersion要在适合健全的骨架中进行繁重的工作,请检查实现:

'' SelFileComp.vbs - selective file compare
Option Explicit
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
WScript.Quit TrialVersion()
WScript.Quit TinVersion()
Function TinVersion()
  WScript.Echo "can't compare files yet."
  TinVersion = 1
End Function ' TinVersion
Function TrialVersion()
  ' the differ should know about the files to compare
  ' we'll worry about the selection later
  Dim oDiffer : Set oDiffer = New cDiffer.init( _
     "File-1", "File-2" _
  )
  ' the differ should be able to return a result - the differences
  Dim sRes : sRes = oDiffer.diffs()
  ' check actual vs. expected result
  Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()
  WScript.Echo "--------- Res"
  WScript.Echo sRes
  If sExp = sRes Then
     WScript.Echo "ok"
     ' save result
     goFS.CreateTextFile("..dataResult", True).Write sRes
     TrialVersion = 0
  Else
     ' show failure
     WScript.Echo "--------- Exp"
     WScript.Echo sExp
     WScript.Echo "not ok"
     TrialVersion = 1
  End If
End Function ' TrialVersion
' trivial Differ
Class cDiffer
  Private m_sLFSpec
  Private m_sRFSpec
  ' "constructor" with params
  Public Function init(sLFSpec, sRFSpec)
    Set init  = Me
    m_sLFSpec = sLFSpec
    m_sRFSpec = sRFSpec
  End Function
  Public Function diffs()
    diffs = "cDiffer.diffs() not implemented yet."
  End Function ' diffs
End Class ' cDiffer00

输出:

cscript SelFileComp.vbs
--------- Res
cDiffer.diffs() not implemented yet.
--------- Exp
Differences:
File-1 Line 4: Price 3: $1234.00
File-2 Line 4: Price 3: $5678.00
File-1 Line 7: Term: 2-Year
File-2 Line 7: Term: 3-Year
not ok
echo %ErrorLevel%
1

如果随后重命名琐碎的 cDiff

' trivial Differ
Class cDiffer00

您可以重新使用名称(以及 TrialVersion((中的代码(来提出一个cDifferent至少做一些比较:

' simple Differ
Class cDiffer
  Private m_sLFSpec
  Private m_sRFSpec
  ' "constructor" with params
  Public Function init(sLFSpec, sRFSpec)
    Set init  = Me
    m_sLFSpec = sLFSpec
    m_sRFSpec = sRFSpec
  End Function
  Public Function diffs()
    ' Use ArrayList to collect the results
    Dim alRes : Set alRes = CreateObject("System.Collections.ArrayList")
    ' requested title
    alRes.Add "Differences:"
    ' open both input files
    Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)
    Dim tsR   : Set tsR   = goFS.OpenTextFile(m_sRFSpec)
    ' loop over lines
    Do Until tsL.AtEndOfStream
       Dim sLL : sLL = tsL.ReadLine()
       Dim sRL
       ' second file could be shorter
       If tsR.AtEndOfStream Then
          alRes.Add "tsR.AtEndOfStream"
          Exit Do
       Else
          sRL = tsR.ReadLine()
       End If
       ' no need for work if lines are equal
       If sLL <> sRL Then
          alRes.Add "??? " & sLL
          alRes.Add "??? " & sRL
       End If
    Loop
    tsL.Close
    tsR.Close
    diffs = Join(alRes.ToArray(), vbCrLf)
  End Function ' diffs
End Class ' cDiffer00

输出:

cscript SelFileComp.vbs
--------- Res
Differences:
??? Date: 00/11/1234 / Order no: 1111
??? Date: 11/00/6789 and Order no: 2222
??? Price 3: $1234.00
??? Price 3: $5678.00
??? Order no: 1111
??? Order no: 2222
??? Term: 2-Year
??? Term: 3-Year
??? Date: 00/11/1234
??? Date: 11/00/6789
--------- Exp
Differences:
File-1 Line 4: Price 3: $1234.00
File-2 Line 4: Price 3: $5678.00
File-1 Line 7: Term: 2-Year
File-2 Line 7: Term: 3-Year
not ok

这清楚地显示了哪些子任务仍有待完成:

  1. 选择相关差异
  2. 输出格式

让我们乐观一点,添加并调用GoldVersion((

Function GoldVersion()
  ' the differ should know about the files to compare
  ' and the info labels to select
  Dim oDiffer : Set oDiffer = New cDiffer.init( _
      "File-1", "File-2" _
    , Array("Price 3", "Term") _
  )
  ' the differ should be able to return a result - the differences
  Dim sRes : sRes = oDiffer.diffs()
  ' check actual vs. expected result
  Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()
  WScript.Echo "--------- Res"
  WScript.Echo sRes
  If sExp = sRes Then
     WScript.Echo "ok"
     ' save result
     goFS.CreateTextFile("..dataResult", True).Write sRes
     GoldVersion = 0
  Else
     ' show failure
     WScript.Echo "--------- Exp"
     WScript.Echo sExp
     WScript.Echo "not ok"
     GoldVersion = 1
  End If
End Function ' GoldVersion

具有更好的差异:

' gold Differ
Class cDiffer
  Private m_sLFSpec   ' file specs
  Private m_sRFSpec
  Private m_sLFiNa    ' file names
  Private m_sRFiNa
  Private m_dicLabels ' store and efficiently find selective labels
  ' "constructor" with params
  Public Function init(sLFSpec, sRFSpec, aLabels)
    Set init  = Me
    m_sLFSpec = sLFSpec
    m_sRFSpec = sRFSpec
    m_sLFiNa  = goFS.GetBaseName(sLFSpec)
    m_sRFiNa  = goFS.GetBaseName(sRFSpec)
    Set m_dicLabels = CreateObject("Scripting.Dictionary")
    m_dicLabels.CompareMode = vbTextCompare ' case-insensitive
    Dim sKey
    For Each sKey In aLabels
        m_dicLabels(sKey) = 0
    Next
  End Function
  Public Function diffs()
    ' Use ArrayList to collect the results
    Dim alRes : Set alRes = CreateObject("System.Collections.ArrayList")
    ' requested title
    alRes.Add "Differences:"
    ' open both input files
    Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)
    Dim tsR   : Set tsR   = goFS.OpenTextFile(m_sRFSpec)
    ' loop over lines
    Do Until tsL.AtEndOfStream
       Dim sLL : sLL = tsL.ReadLine()
       Dim sRL
       ' second file could be shorter
       If tsR.AtEndOfStream Then
          alRes.Add "tsR.AtEndOfStream"
          Exit Do
       Else
          sRL = tsR.ReadLine()
       End If
       ' no need for work if lines are equal
       If sLL <> sRL Then
          If m_dicLabels.Exists(Split(sLL, ":")(0)) Then
             alRes.Add Join(Array(m_sLFiNa, "Line", sLL))
             alRes.Add Join(Array(m_sRFiNa, "Line", sRL))
          End If
       End If
    Loop
    tsL.Close
    tsR.Close
    diffs = Join(alRes.ToArray(), vbCrLf)
  End Function ' diffs
End Class ' cDiffer

输出:

cscript SelFileComp.vbs
--------- Res
Differences:
File-1 Line Price 3: $1234.00
File-2 Line Price 3: $5678.00
File-1 Line Term: 2-Year
File-2 Line Term: 3-Year
--------- Exp
Differences:
File-1 Line 4: Price 3: $1234.00
File-2 Line 4: Price 3: $5678.00
File-1 Line 7: Term: 2-Year
File-2 Line 7: Term: 3-Year
not ok

选择完成,格式仍然不好。要提高输出,请执行以下操作:

       If sLL <> sRL Then
          If m_dicLabels.Exists(Split(sLL, ":")(0)) Then
'            alRes.Add Join(Array(m_sLFiNa, "Line", sLL))
'            alRes.Add Join(Array(m_sRFiNa, "Line", sRL))
             Dim sLiNo : sLiNo = CStr(tsL.Line - 1) & ":"
             alRes.Add Join(Array(m_sLFiNa, "Line", sLiNo, sLL))
             alRes.Add Join(Array(m_sRFiNa, "Line", sLiNo, sRL))
          End If
       End If

要添加尾随的 vbCrLf,请执行以下操作:

'   diffs = Join(alRes.ToArray(), vbCrLf)
    diffs = Join(alRes.ToArray(), vbCrLf) & vbCrLf

最终输出:

cscript SelFileComp.vbs
--------- Res
Differences:
File-1 Line 4: Price 3: $1234.00
File-2 Line 4: Price 3: $5678.00
File-1 Line 7: Term: 2-Year
File-2 Line 7: Term: 3-Year
ok
echo %ErrorLevel%
0

下一个问题,请!

更新 A(wrt 文件规范/文件名(

将文件-1 移动/复制到 ..\数据\, 更改

  Dim oDiffer : Set oDiffer = New cDiffer.init( _
      "File-1", "File-2" _
    , Array("Price 3", "Term") _
  )

  Dim oDiffer : Set oDiffer = New cDiffer.init( _
      "..dataFile-1", "File-2" _
    , Array("Price 3", "Term") _
  )

结果将是相同的,因为cDiff使用。

m_sLFSpec = sLFSpec
  to store the (full) path
m_sLFiNa  = goFS.GetBaseName(sLFSpec)
  to extract the file name for output formatting
Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)
  to open the file

更新 B(wrt 字典(

字典是将元素存储在唯一键(如与数组相反,数组使其项目可通过数字访问(。由使用标签查找作为字典的键,diffs((函数可以有效地(看妈,没有循环!(检查,是否行的第一部分直到:

  Split(sLL, ":")(0)

包含在字典中

  If m_dicLabels.Exists(Split(sLL, ":")(0)) Then

更新 C (wrt 类/构造函数(

类是(一组相似的(对象的定义/规范,即变量保存/组合数据(成员(功能(方法(。cDiff是一个定义对象的类,这些对象"知道"所有要比较的文件和要查找的标签(成员变量,如m_sLSpec(,并且可以"执行"比较(方法/函数,如diffs(((。New 语句用于根据规范构造/创建对象:

  Dim oDiffer : Set oDiffer = New cDiffer

由 New 创建的对象是空的,对于实际目的毫无用处;您可以实现一个 Class_Initialize(( 子(在类中...结束类块(,但就这样代码将用于类的所有对象,增益很小。

如果查看类语句的文档中的示例,您将意识到,无参数的"构造函数"(Class_Initialize( 是对于不按行/小时付费的程序员来说,几乎没有用。样板法典

   Private Sub Class_Initialize
      m_CustomerName = ""
      m_OrderCount = 0
      ... ad nauseam: set all other member data to 'nix'
   End Sub

特别恶心,因为 VBScript

  • 自动执行相当于空Class_Initialize一打电话给新
  • 将所有变量初始化为自动为空,并将为空
    适用于字符串和数字

补救措施是忘记Class_Initialize(特殊情况除外(和在一个或多个上投入一些精力

  Public Function initXXX(p1, p2, ... pn)
    Set initXXX = Me  ' return VBScript's this to caller
    ... use p1 ... pn to initialize member data to useful values
  End Function

相关内容

  • 没有找到相关文章

最新更新