如何比较两列匹配和不匹配的值,并以所需的格式获取它?

时间:2019-03-25 21:10:03

标签: excel vba

如何查找两列之间的匹配值和不匹配值,并按以下方式设置其格式?

输入:

| expected | match | forward | backward | actual |
|----------|-------|---------|----------|--------|
| a        |       |         |          | b      |
| b        |       |         |          | c      |
| c        |       |         |          | r      |
| d        |       |         |          | s      |
| e        |       |         |          |        |

输出:

| expected | match | forward | backward | actual |
|----------|-------|---------|----------|--------|
| a        | b     | a       | r        | b      |
| b        | c     | d       | s        | c      |
| c        |       | e       |          | r      |
| d        |       |         |          | s      |
| e        |       |         |          |        |

forward-存在于expected中,但没有出现在actualSQL left outer join

backward-存在于actual中,但没有出现在expectedSQL right outer join

match-在expectedactualSQL inner join)中都出现

expected是我从SQL查询中获得的。在RDBMS中没有actual列的情况下,我有很多情况,因此我必须使用excel进行比较。我通常可以使用VLOOKUP进行比较,但是这很耗时,并且没有提供我想要的格式。我想要一种可以重要使用上述格式进行操作的解决方案。

我愿意提出建议。我个人使用python / pandas来执行此操作,但是我的同事不习惯使用python,因此我更喜欢一种解决方案,该解决方案可以通过单击按钮来完成,或者通过VBA自动化,或者通过Excel来实现,基本上可以我可以与我的Excel同事共享,这可以使他们的流程更快。目前,他们对所有三列都执行VLOOKUP->Filter->Copy->Paste to another sheet漂洗重复操作。

提供了一个解决方案-https://superuser.com/a/1417235/954024,但是它运行非常缓慢且效率低下,我的系统只使用了该方法:(

我的python解决方案:

import pandas as pd
import sys


def find_discrepancies(input_file):
    """
    input: df
    output: formatted df
    """
    df = pd.read_excel(input_file)
    df['match'] = df.loc[df['expected'].isin(df['actual'])].reset_index()[
        'expected']
    df['forward'] = df.loc[df['expected'].isin(
        df['actual']) == False].reset_index()['expected']
    df['backward'] = df.loc[df['actual'].isin(
        df['expected']) == False].reset_index()['actual']
    df = df[['expected', 'match', 'forward', 'backward', 'actual']]
    counts = df.count()
    df.columns = [df.columns[i].capitalize() + ' - ' + str(counts.values[i]) for i in range(5)]
    df.fillna('', inplace=True)

    return df


def main(inputFile, outputFile):
    df = find_discrepancies(inputFile)
    df.to_excel(outputFile, index=False)


if __name__ == '__main__':

    inputFile = sys.argv[1]
    outputFile = sys.argv[2]

    main(inputFile, outputFile)

1 个答案:

答案 0 :(得分:1)

这不是最干净的解决方案,但这足够了。我将需要更多有关您的数据设置的信息以进行配置。

Option Explicit
Sub PopulateColumns()

    Dim i As Long, lastrow As Long
    Dim testitem As String

    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
        testitem = Cells(i, 1).Value

        If Application.CountIf(Range("E:E"), testitem) = 0 Then
            lastrow = Cells(Rows.Count, 3).End(xlUp).Row
            Cells(lastrow + 1, 3).Value = testitem
        ElseIf Application.CountIf(Range("E:E"), testitem) > 0 Then
            lastrow = Cells(Rows.Count, 2).End(xlUp).Row
            Cells(lastrow + 1, 2).Value = testitem
        End If
    Next i

    For i = 2 To Cells(Rows.Count, 5).End(xlUp).Row
        testitem = Cells(i, 5).Value

        If Application.CountIf(Range("A:A"), testitem) = 0 Then
            lastrow = Cells(Rows.Count, 4).End(xlUp).Row
            Cells(lastrow + 1, 4).Value = testitem
        End If
    Next i

Cells(1, 1).Value = "Expected - " & Cells(Rows.Count, 1).End(xlUp).Row - 1
Cells(1, 2).Value = "Match - " & Cells(Rows.Count, 2).End(xlUp).Row - 1
Cells(1, 3).Value = "Forward - " & Cells(Rows.Count, 3).End(xlUp).Row - 1
Cells(1, 4).Value = "Backward - " & Cells(Rows.Count, 4).End(xlUp).Row - 1
Cells(1, 5).Value = "Actual - " & Cells(Rows.Count, 5).End(xlUp).Row - 1

Columns("A:E").AutoFit

For i = 1 To 5
    Cells(1, i).Interior.Color = RGB(168, 207, 141)
    Cells(1, i).Font.Bold = True
    Cells(1, i).HorizontalAlignment = xlCenter
    Cells(1, i).Borders.LineStyle = xlContinuous
Next i


End Sub

img