Excel e documentos de trabalho

Detectar linhas duplicadas no Excel e separá-las para revisão

Busque linhas com as quatro colunas idênticas e reúna-as em um novo arquivo do Excel com os números das linhas originais. Confira cada grupo de duplicatas incluindo sua primeira ocorrência.

Ver o sumário

A tradução foi feita com IA. Confira o código, as unidades e os valores junto com o original. A revisão por falantes nativos de cada idioma ainda não foi concluída. 한국어

Para quem éProfissionais administrativos que conferem entradas duplicadas após reunir dados do Excel

Preparação
  • Prepare o Python 3.12 e um terminal. Confira a versão com python --version.
  • Extraia todo o ZIP baixado e abra o terminal na pasta que contém example.py.
  • Execute primeiro com os dados de prática incluídos e compare o resultado com o original.
  • São usados a planilha Orders de orders.xlsx e openpyxl. O aplicativo Microsoft Excel não é necessário para executar o código.

01Definir o que é considerado uma duplicata

Neste exemplo, uma linha é duplicada quando os quatro valores coincidem: order_id, customer, item e quantity. Ter apenas o mesmo número de pedido não basta. Também não são alterados automaticamente os espaços nem as maiúsculas e minúsculas das strings.

Antes de remover duplicatas, todas as linhas com o mesmo conteúdo são reunidas na planilha Duplicates, incluindo a primeira ocorrência. As linhas que aparecem uma única vez ficam em Unique, permitindo revisar as 8 linhas sem omissões.

02Conferir a estrutura do arquivo de entrada

A planilha de orders.xlsx deve se chamar Orders, e os nomes e a ordem das colunas na primeira linha devem corresponder aos indicados abaixo. Adicionar colunas também causa um erro de cabeçalho. Em vez de substituir diretamente o exemplo por um arquivo de trabalho, crie um arquivo de prática copiando as quatro colunas necessárias.

ColunaFunçãoExemplo
order_idNúmero do pedido como stringO-1001
customerNome do cliente como stringAlpha
itemItem como stringSensor
quantityQuantidade como inteiro positivo2

Linhas totalmente vazias são ignoradas. Se faltar algum valor ou houver uma fórmula, o programa para. O número do pedido, o nome do cliente e o item devem ser strings não vazias; números de pedido inseridos como valores numéricos não são convertidos automaticamente em texto.

03Preparar os arquivos e executar

  1. Extraia o ZIP e confira se o arquivo de entrada indicado em README.txt está no mesmo local que example.py. Não execute diretamente de dentro do ZIP.
  2. Execute os comandos abaixo, um por vez, na pasta que contém example.py. Se no Windows o comando python não estiver disponível, mas py estiver, substitua python por py -3.12 em cada comando.
  3. Quando aparecer a mensagem de conclusão, abra a nova pasta outputs. Se outputs já existir, guarde-a primeiro com outro nome e execute novamente.
bash
python --version
python -m pip install -r requirements.txt
python example.py

A instalação exige conexão com a internet. BASE define os caminhos de entrada e saída a partir da localização de example.py, não da localização atual do terminal.

04Código completo e sequência de processamento

O original é aberto no modo somente leitura com load_workbook, e Counter conta as ocorrências de cada linha. Os números das linhas do Excel original são registrados com enumerate usando start=2. Os resultados são salvos em um novo Workbook, portanto o arquivo original não é salvo novamente.

example.py
"""Find repeated business rows. Keep the source workbook unchanged."""
from collections import Counter
from pathlib import Path

from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font, PatternFill

BASE = Path(__file__).resolve().parent
HEADERS = ("order_id", "customer", "item", "quantity")


def main():
    destination = BASE / "outputs"
    if destination.exists():
        raise ValueError("outputs already exists; rename it before running again.")
    source = load_workbook(BASE / "orders.xlsx", read_only=True, data_only=False)
    try:
        if "Orders" not in source.sheetnames:
            raise ValueError("Orders sheet is missing.")
        worksheet = source["Orders"]
        rows = list(worksheet.iter_rows(values_only=True))
        if not rows or tuple(rows[0]) != HEADERS:
            raise ValueError(f"Expected headers: {HEADERS}")
        records = []
        for row_number, row in enumerate(rows[1:], start=2):
            if all(value is None for value in row):
                continue
            if any(value is None for value in row):
                raise ValueError(f"Row {row_number}: missing value.")
            if any(isinstance(value, str) and value.startswith("=") for value in row):
                raise ValueError(f"Row {row_number}: formulas are not supported.")
            if not all(isinstance(value, str) and value.strip() for value in row[:3]):
                raise ValueError(f"Row {row_number}: first three fields must be text.")
            if type(row[3]) is not int or row[3] <= 0:
                raise ValueError(f"Row {row_number}: quantity must be a positive integer.")
            records.append((row_number, tuple(row)))
        if not records:
            raise ValueError("No data rows were found.")
    finally:
        source.close()

    counts = Counter(row for _, row in records)
    repeated = [(number, row) for number, row in records if counts[row] > 1]
    unique = [(number, row) for number, row in records if counts[row] == 1]
    book = Workbook()
    book.remove(book.active)
    for name, selected in (("Duplicates", repeated), ("Unique", unique)):
        sheet = book.create_sheet(name)
        sheet.append(("source_row", *HEADERS, "occurrences"))
        for number, row in selected:
            sheet.append((number, *row, counts[row]))
        sheet.freeze_panes = "A2"
        sheet.auto_filter.ref = sheet.dimensions
        sheet.sheet_view.showGridLines = False
        for cell in sheet[1]:
            cell.font = Font(name="Arial", bold=True, color="FFFFFF")
            cell.fill = PatternFill("solid", fgColor="243B53")
        for column, width in zip("ABCDEF", (14, 16, 18, 20, 14, 16)):
            sheet.column_dimensions[column].width = width
    destination.mkdir(exist_ok=False)
    book.save(destination / "duplicate_review.xlsx")
    book.close()
    groups = sum(count > 1 for count in counts.values())
    print(f"Input rows: {len(records)}; duplicate groups: {groups}")
    print(f"Duplicate rows: {len(repeated)}; unique rows: {len(unique)}")
    print("Created outputs/duplicate_review.xlsx (source unchanged).")


if __name__ == "__main__":
    try:
        main()
    except (OSError, ValueError) as error:
        raise SystemExit(f"Stopped: {error}") from error

05Resultados gerados na execução

São criadas as planilhas Duplicates e Unique em outputs/duplicate_review.xlsx. source_row é o número da linha do Excel original, e occurrences indica quantas vezes o mesmo conteúdo aparece em toda a entrada.

ItemResultado com os dados incluídos
Linhas de dados de entrada8
Grupos de duplicatas2
Linhas de Duplicates4 (linhas originais 2, 3, 5, 8)
Linhas de Unique4 (linhas originais 4, 6, 7, 9)

As 4 linhas de Duplicates não significam que 4 linhas devam ser removidas. Se uma linha for mantida por grupo, há 2 linhas adicionais, mas é necessário conferir o original antes de decidir quais manter.

06Conferir o resultado por conta própria

  1. Confira em Duplicates se as linhas com source_row 2 e 5 correspondem a O-1001 e se ambas têm occurrences igual a 2.
  2. Confira se as linhas com source_row 3 e 8 correspondem a O-1002.
  3. Some as 4 linhas de Duplicates e as 4 de Unique e confira se correspondem às 8 linhas de entrada.
  4. Abra novamente orders.xlsx e confira se as 8 linhas de dados continuam intactas.

07Erros comuns e soluções

Mensagem ou sintomaO que conferir
Orders sheet is missingConfira se a planilha original se chama Orders.
Expected headersConfira os nomes, a ordem e as colunas extras.
missing value / formulas are not supportedConfira a linha original indicada e prepare valores em vez de fórmulas.
quantity must be a positive integerInforme a quantidade como um inteiro de 1 ou mais.
outputs already existsGuarde a pasta de resultados anterior com outro nome.
ModuleNotFoundErrorInstale os pacotes de requirements.txt usando o mesmo python com que você executa o código.

08O que este exemplo não cobre

  • Não são copiados a formatação, os gráficos, as macros, as conexões nem o estado das linhas ocultas. O resultado inclui apenas os valores necessários para a revisão e uma formatação básica.
  • Não são removidos espaços, não são padronizadas maiúsculas e minúsculas e não são identificadas strings semelhantes. Se a definição de duplicata mudar, será necessário projetar os critérios de comparação separadamente.
  • Como todo o arquivo é carregado na memória, o desempenho com grandes volumes não é garantido. Arquivos criptografados ou corrompidos não são suportados.
  • Alterar valores no arquivo de resultados não recalcula automaticamente o original nem os resultados. Para obter um novo resultado, altere uma cópia do original e execute novamente.

Registro de execução e verificação

Windows 11 (10.0.26200), CPython 3.12.14 (64 bits). openpyxl 3.1.5, Matplotlib 3.10.8. As versões das bibliotecas usadas em cada exemplo estão fixadas em requirements.txt.

  • Verificadas as contagens de linhas, os números das linhas originais e as frequências de duplicação com dados válidos
  • SHA-256 do original sem alterações e recusa de sobrescrita ao executar novamente
  • Verificados erros de cabeçalhos diferentes, valores ausentes, fórmulas e quantidades incorretas
Limites da verificação
  • Não foram verificados a exibição no aplicativo de desktop do Excel nem o desempenho com grandes volumes.

Princípios de redação e verificação de todo o site

Arquivos de exemplo para executar

Inclui código, dados de entrada e instruções de execução. Extraia o ZIP e leia primeiro o README.txt.

Baixar ZIP de exemplo

O código de exemplo, os nomes de arquivos e as chaves de entrada são mantidos como no original. Consulte também os comandos e os procedimentos de conferência do texto traduzido.

Material de prática original · Guarde os arquivos originais separadamente antes de executar.

Fontes de referência

As explicações e os exemplos são de elaboração própria. Os comportamentos e conceitos relacionados podem ser consultados nas fontes oficiais abaixo.