Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 比较两个文件并输出任何不同的行_Excel_Vba - Fatal编程技术网

Excel 比较两个文件并输出任何不同的行

Excel 比较两个文件并输出任何不同的行,excel,vba,Excel,Vba,我每天都会收到一份报告,上面大约有8500行,我一直在尝试制作一个宏,来完成我一直在手动完成的工作。报告的问题是,所有行的格式都不相同(即第1行:数字、文本、文本、数字和第2行:文本、数字、数字、文本) 我想将新文件与旧文件进行比较,并输出新的差异。我可以让宏在这两个文件中运行,但它不会将任何行标记为不同,但我知道它们是不同的 Sub test() Dim yesterdayFile As String Dim todayFile As String yesterdayFile = Appl

我每天都会收到一份报告,上面大约有8500行,我一直在尝试制作一个宏,来完成我一直在手动完成的工作。报告的问题是,所有行的格式都不相同(即第1行:数字、文本、文本、数字和第2行:文本、数字、数字、文本)

我想将新文件与旧文件进行比较,并输出新的差异。我可以让宏在这两个文件中运行,但它不会将任何行标记为不同,但我知道它们是不同的

Sub test()

Dim yesterdayFile As String
Dim todayFile As String

yesterdayFile = Application.GetOpenFilename()
todayFile = Application.GetOpenFilename()
Dim yesterdayLine As String
Dim todayLine As String
Dim txt As String
Dim i, j, k, sameLine As Integer
Dim wkbTemp As Workbook
i = 1
j = 1
k = 1
sameLine = 0


Open yesterdayFile For Input As #1
Do Until EOF(1)
    sameLine = 1 'reset write operator
    Open todayFile For Input As #2
Line Input #1, yesterdayLine
    Do Until EOF(2)
        Line Input #2, todayLine
        If StrComp(yesterdayLine, todayLine) = 0 Then 'compare lines in files if same then flag write operator to 1
           sameLine = 1
        End If
        j = j + 1 'inner loop counter
    Loop
If sameLine = 0 Then 'if write operator is not active then output line
    Cells(i, 1) = yesterdayLine
    i = i + 1 'counter for cells
End If
Close #2
k = k + 1 'outer loop counter
Loop

'test line to see if its eof
Cells(1, 10) = i
Cells(2, 10) = j
Cells(3, 10) = k

Close #1



End Sub
用于更快地运行测试的测试文件:

昨日档案:

10001,April,Apple
10002,Book,Bush
10004,Dog,Days
10006,Free,Food
10008,Happy,Help
10009,Ikky,Icing
10010,Jamming,Jupiter
今日档案:

10001,April,Apple
10002,Book,Bush
10003,Cat,Cattle
10004,Dog,Days
10005,Echo,Eggg
10006,Free,Food
10007,Good,Game
10008,Happy,Help
10009,Ikky,Icing
10010,Jamming,Jupiter
注意:在真实数据中没有“唯一ID字段”

计数器以正确的数字结束,因此我知道它在递归中运行


编辑:我知道用其他语言可以很容易地做到这一点,但我只能从工作终端访问excel vba,不能将文件从网络上删除。

如果我理解的话,您在旧工作簿和新工作簿中使用了4个字段,假设每个wb中的行数/任务数相同。这并不漂亮,但您可以评估类似于:

Dim i as Long, j as Long, k as Long, l as Long, m as Long

If wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,4).Value OR Then
    j=1
End If

If wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,4).Value OR Then
    k=1
End If

If wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,4).Value OR Then
    l=1
End If

If wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,4).Value Then
    m=1
End If

If (i+j+k+l)=4 Then
    wbNew.shNew.Rows(i).Interior.Color=2
End If

j=0
k=0
l=0
m=0
使用wbNew和shNew表示使用最新工作簿,wbOld和shOld表示昨天的工作簿。这一切都在一个循环中,您需要找到最后一行


您还可以采用一种方法来使用Find()或Match(),例如:

z = Application.Match(wbNew.shNew.Cells(i,1),wbOld.sheOld.Columns(1)).Row
If wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 1).Value OR wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 2).Value OR wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 3).Value OR wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 4).Value Then
    j=1
End If
如果每行都有唯一的内容,这样就可以找到z,然后只需循环遍历一个工作簿/工作表就可以进行比较


编辑:

添加在列和行之间循环(嵌套循环)的示例,并将单元格内部标记为flag if true:

Dim r as long, c as Long

For r = 1 to LR
    For c = 1 to LC
        If Cells(r, c).Value = "Moo" Then
            If Cells(r, c).Interior.Color <> 2 Then
                Cells(r, c).Interior.Color=2
            End If
        End If
    Next c
Next r

这只会使编辑更容易,我想。

如果我理解的话,假设每个wb中的行数/任务数相同,那么新旧工作簿中都使用了4个字段。这并不漂亮,但您可以评估类似于:

Dim i as Long, j as Long, k as Long, l as Long, m as Long

If wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 1).Value = wbOld.shOld.CellS(i,4).Value OR Then
    j=1
End If

If wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 2).Value = wbOld.shOld.CellS(i,4).Value OR Then
    k=1
End If

If wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 3).Value = wbOld.shOld.CellS(i,4).Value OR Then
    l=1
End If

If wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,1).Value OR wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,2).Value OR wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,3).Value OR wbNew.shNew.Cells(i, 4).Value = wbOld.shOld.CellS(i,4).Value Then
    m=1
End If

If (i+j+k+l)=4 Then
    wbNew.shNew.Rows(i).Interior.Color=2
End If

j=0
k=0
l=0
m=0
使用wbNew和shNew表示使用最新工作簿,wbOld和shOld表示昨天的工作簿。这一切都在一个循环中,您需要找到最后一行


您还可以采用一种方法来使用Find()或Match(),例如:

z = Application.Match(wbNew.shNew.Cells(i,1),wbOld.sheOld.Columns(1)).Row
If wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 1).Value OR wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 2).Value OR wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 3).Value OR wbNew.shNew.Cells(i,1).Value = wbOld.shOld.Cells(z, 4).Value Then
    j=1
End If
如果每行都有唯一的内容,这样就可以找到z,然后只需循环遍历一个工作簿/工作表就可以进行比较


编辑:

添加在列和行之间循环(嵌套循环)的示例,并将单元格内部标记为flag if true:

Dim r as long, c as Long

For r = 1 to LR
    For c = 1 to LC
        If Cells(r, c).Value = "Moo" Then
            If Cells(r, c).Interior.Color <> 2 Then
                Cells(r, c).Interior.Color=2
            End If
        End If
    Next c
Next r

这使得编辑更容易,我想。

经过多次尝试和错误,我回答了我自己的问题,谢谢你的回答,但是从72mil迭代到3bil不是一个选择

我的代码最终是什么样子的

Sub test()
'Freeze window
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

'open files to edit
Dim fileA, fileB As String
fileA= Application.GetOpenFilename()
fileB = Application.GetOpenFilename()

'setting variables
Dim lineA, lineB, DQ As String 'read in lines and double quote     variables
Dim i, sameLine As Integer 'row counter and testing(could have used boolean?)
Dim newLine 'object creation for array of line
i = 1
DQ = Chr(34) 'character 34 is "

Open fileA For Input As #1 'open file 1 for append
Do Until EOF(1) 'Outter loop to run through file 1
    sameLine = 0 'reset write operator
    Open fileB For Input As #2 'open file 2 for append
    Line Input #1, lineA'read in line from file 1
    Do Until EOF(2) 'inner loop to run through file 2
        Line Input #2, lineB 'read in line from file 2
        If StrComp(lineA, lineB) = 0 Then 'compare lines in files if same then flag write operator to 1
            sameLine = 1
        End If
    Loop
    If sameLine = 0 Then 'if write operator is not active then output line
        count = Len(lineA) - Len(Replace(lineA, "|", ""))     'count number of columns needed for output
        lineA= Replace(lineA, DQ, "") 'removing all double     quotes from line
        newLine = Split(lineA, "|") 'spliting line into object with | as delimiter
        For counter = 1 To count 'placing line in row
            Cells(i, counter) = newLine(counter - 1)
        Next counter
        i = i + 1 'counter for cells
    End If
Close #2
Loop
Close #1
'unfreezing window
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

这适用于.txt和.csv,并在将输入行写入任何单元格之前直接比较它们。我的问题是独特的,因为每行末尾都有时间戳,我添加了几行来修复。

所以经过多次尝试和错误,我回答了我自己的问题,感谢所有的回答,但从72mil迭代到3bil不是一个选项

我的代码最终是什么样子的

Sub test()
'Freeze window
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

'open files to edit
Dim fileA, fileB As String
fileA= Application.GetOpenFilename()
fileB = Application.GetOpenFilename()

'setting variables
Dim lineA, lineB, DQ As String 'read in lines and double quote     variables
Dim i, sameLine As Integer 'row counter and testing(could have used boolean?)
Dim newLine 'object creation for array of line
i = 1
DQ = Chr(34) 'character 34 is "

Open fileA For Input As #1 'open file 1 for append
Do Until EOF(1) 'Outter loop to run through file 1
    sameLine = 0 'reset write operator
    Open fileB For Input As #2 'open file 2 for append
    Line Input #1, lineA'read in line from file 1
    Do Until EOF(2) 'inner loop to run through file 2
        Line Input #2, lineB 'read in line from file 2
        If StrComp(lineA, lineB) = 0 Then 'compare lines in files if same then flag write operator to 1
            sameLine = 1
        End If
    Loop
    If sameLine = 0 Then 'if write operator is not active then output line
        count = Len(lineA) - Len(Replace(lineA, "|", ""))     'count number of columns needed for output
        lineA= Replace(lineA, DQ, "") 'removing all double     quotes from line
        newLine = Split(lineA, "|") 'spliting line into object with | as delimiter
        For counter = 1 To count 'placing line in row
            Cells(i, counter) = newLine(counter - 1)
        Next counter
        i = i + 1 'counter for cells
    End If
Close #2
Loop
Close #1
'unfreezing window
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

这适用于.txt和.csv,并在将输入行写入任何单元格之前直接比较它们。我的问题是独特的,因为每行末尾都有时间戳,我添加了几行来修复。

确切的单元格必须不同?或者,如果一行的顺序不同,但值相同,则可以吗?测试的是来自文件而不是直接单元格的输入行,它们是CSV文件,因此整行列为“text”|“number”|“number”|“text”。定界是一个问题,当我能够实际获得要输出的行时,我将处理它。我认为您必须使用并匹配这两个多维数组。或者,您可以在单元格中输入csv数据,并在电子表格中进行匹配。确切的细胞必须是不同的?或者,如果一行的顺序不同,但值相同,则可以吗?测试的是来自文件而不是直接单元格的输入行,它们是CSV文件,因此整行列为“text”|“number”|“number”|“text”。定界是一个问题,当我能够实际获得要输出的行时,我将处理它。我认为您必须使用并匹配这两个多维数组。或者,您可以在单元格中输入csv数据,并在电子表格中进行匹配。示例代码只是几个字段,但实际数据的范围是19到42个字段。因此,将其用于42个字段将是相当多的,这就是为什么我要直接测试彼此之间的输入行。@Nealin页面上有标题吗?将使它更容易,以便您可以表示要处理的确切单元格。不幸的是,这些文件是CSV文件,包含大约8个单独的表,因此标题不能用于整个文件长度。是的,您有一个数组,循环比使用Match()更有效。还有一个在这里。最后,您必须为每个值使用一个循环,无论您选择哪种使用方式。@Nealin Dan都有支持它的帖子。我在一个循环示例中添加了行和列迭代。希望这能帮助您找到需要的地方。示例代码只是几个字段,但实际数据的范围是19到42个字段。因此,将其用于42个字段将是相当多的,这就是为什么我要直接测试彼此之间的输入行。@Nealin页面上有标题吗?将使它更容易,以便您可以表示要处理的确切单元格。不幸的是,这些文件是CSV文件,包含大约8个单独的表,因此标题不能用于整个文件长度。是的,您有一个数组,循环比使用Match()更有效。还有一个在这里。最后,您必须为每个值使用一个循环,无论您选择哪种使用方式。@Nealin Dan都有支持它的帖子。我在一个循环示例中添加了一个循环,以显示row和co