Невозможно удалить строки с определенным значением ячейки python openpyxl

1

У меня странная проблема, когда логика и код говорят мне, что она должна работать, но это не так.

Мой код ниже

import shutil, sys
from distutils.version import StrictVersion
import openpyxl
from openpyxl import Workbook
from openpyxl import load_workbook

wb = load_workbook('testing.xlsx')
ws = wb.get_sheet_by_name('Sheet1')
x = ws.max_row
y = ws.max_column

for r in range(1,x+1):
        for j in range(1, y+1):
                d=ws.cell(row=r,column=j)
        if str(d.value).lower() == "false":
                ws.delete_rows(r)

wb.save("test_1.xlsx")

Превосходство состоит из 5 столбцов, ABCDE first Row имеет названия, поэтому их можно игнорировать. A2 имеет время, B2 имеет имя C2 имеет имя пользователя, путь D2, E2 содержит значение TRUE или FALSE

Пункт моего сценария - посмотреть на все ячейки, и если значение FALSE будет найдено, оно удалит эту строку. Так, например, строка 10

01.01.1999 John Smith JohnS/path/FALSE Это должно быть удалено, поскольку оно содержит FALSE или, более конкретно, E10 имеет FALSE. Значения TRUE FALSE отображаются только в столбце E, поэтому для скорости мы можем указать, что нас интересует только столбец E, но любая строка. Я сделал это в другой версии.

К проблеме Проблема в том, что мое тестирование excel имеет в общей сложности 25 строк и столбцов ABCDE, как указано выше, но сценарий удаляет только 5 строк, значение FALSE. Также кажется, что скрипт удаляет строки, которые содержат FALSE в случайном порядке, поэтому в моем тестировании excel всего 10 строк с ячейкой FALSE. имена пользователей по порядку будут равны t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, но скрипт только что удалил t1, t3, t5, t6, t7, t9, которые теперь смотрят на него проблема с логикой и ее проверка нечетных чисел

EDIT кажется, что, если я повторяю цикл достаточно, он удалит все строки, содержащие FALSE

текущий код, который работает

import shutil, sys
from distutils.version import StrictVersion
import openpyxl
from openpyxl import Workbook
from openpyxl import load_workbook

wb = load_workbook('testing.xlsx')
ws = wb.get_sheet_by_name('Sheet1')
x = ws.max_row
y = ws.max_column

for r in range(1,x+1):
        for j in range(1, y+1):
                d=ws.cell(row=r,column=j)
        if str(d.value).lower() == "false":
                ws.delete_rows(r)


for r in range(1,x+1):
        for j in range(1, y+1):
                d=ws.cell(row=r,column=j)
        if str(d.value).lower() == "false":
                ws.delete_rows(r)

for r in range(1,x+1):
        for j in range(1, y+1):
                d=ws.cell(row=r,column=j)
        if str(d.value).lower() == "false":
                ws.delete_rows(r)

for r in range(1,x+1):
        for j in range(1, y+1):
                d=ws.cell(row=r,column=j)
        if str(d.value).lower() == "false":
                ws.delete_rows(r)

wb.save("test_1.xlsx")

его не очень, поэтому любые советы будут оценены

  • 1
    Не могли бы вы опубликовать визуальное представление вашего файла Excel?
  • 0
    ibb.co/kKD2r8 Кажется, я исправил свою проблему: при вставке того же цикла x3 он удаляет то, что я хочу, по какой-то причине при запуске он удаляет каждый второй, поэтому, если вы вставляете цикл еще два раза, в конечном итоге он удаляет все это. Это один уродливый способ, и помощь в его улучшении ценится
Показать ещё 3 комментария
Теги:
excel
openpyxl

2 ответа

0
Лучший ответ

Я думаю, что проблема с отступом, попробуйте это:

import shutil, sys
from distutils.version import StrictVersion
import openpyxl
from openpyxl import Workbook
from openpyxl import load_workbook

wb = load_workbook('testing.xlsx')
ws = wb.get_sheet_by_name('Sheet1')
x = ws.max_row
y = ws.max_column

for r in range(1,x+1):
    for j in range(1, y+1):
        d=ws.cell(row=x+1-r,column=j)
        if str(d.value).lower() == "false":
            ws.delete_rows(x+1-r)
            break

wb.save("test_1.xlsx")

и я изменяю номер строки от r до x+1-r, что означает повторение строк от последнего до первого (так что, когда одна строка будет удалена, остальные строки не будут затронуты), и необходимо сломать внутренний цикл (за исключением того, что строка цикла удалена, вы больше не можете зацикливать эту строку)

  • 0
    Привет, спасибо за это, ваш ответ работает, как ожидалось. Не думал об увеличении количества удаленных ячеек, и весь цикл будет удалять ячейки, которые когда-то имели значение FALSE, но теперь могут иметь значение TRUE
0

Вы можете попробовать что-то вроде этого:

from openpyxl import load_workbook
from openpyxl.workbook import Workbook

# open workbook and get active worksheet
wb = load_workbook('original.xlsx')
ws = wb.active

# extract headers from row 1
headers = [cell.value for row in ws.iter_rows(min_row=1, max_row=1) for cell in row]

# want to keep headers by default
new_rows = [headers]

# go through every row(>=2) except headers
for row in ws.iter_rows(min_row=2):
    values = [cell.value for cell in row]

    # create dictionary of row 
    row_dict = dict(zip(headers, values))

    # only append if 'enabled' is True
    if row_dict['enabled']:
        new_rows.append(values)

# create a new workbook and sheet to write to
new_wb = Workbook()
new_ws = new_wb.active

# iterate though rows and columns of nested list
for row, line in enumerate(new_rows, start=1):
    for column, cell in enumerate(line, start=1):

        # write new cell to output worksheet
        new_ws.cell(row=row, column=column).value = cell

# save output workbook
new_wb.save('output.xlsx')

Что дает новый output.xlsx файл со всеми строками, содержащими FALSE в enabled колонке удалены.

Сначала он создает словарь для каждой строки, и если для ключа enabled значение " True, сохраните эту строку. В конце он выполняет итерацию по всем строкам и записывает их отдельно в выходной файл.

  • 0
    Traceback (последний вызов был последним): файл "t1.py", строка 9, в <module> headers = [cell.value for (cell,) в ws.iter_rows (min_row = 1, max_row = 1)] ValueError: too много значений для распаковки Стоит сказать, что в тесте Excel, который я использовал, не было много строк, но цель этого сценария - использовать его на экземплярах со строками 1500+
  • 0
    @ k3mp3r Смотрите обновленный ответ. Если вам нужно обрабатывать много строк, возможно, стоит перейти на решение для pandas .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню