【问题标题】:How to select a dynamic range based on a cell value in Excel with Python如何使用 Python 在 Excel 中根据单元格值选择动态范围
【发布时间】:2021-10-12 20:34:29
【问题描述】:

我很难找到与我的问题相关的任何内容。到目前为止,我发现的只是根据静态范围选择范围,但不幸的是,数据可能每周都在变化。

在同一张工作表中有多个具有不同行和列的数据块,但在数据上方有标题。我的目标是找到一个标题,即第 36 行或第 40 行,向下移动一行并基本上执行 ctrl+down ctrl+right 来选择一个范围,然后创建一个表格并根据标题命名一个表格。

import openpyxl

def tables(title):
    for cell in pws_sheet["A"]: #pws_sheet["A"] will return all cells on the A column until the last one
        if (cell.value is not None): #check if cell is not empty
            if title in cell.value: #check if the value of the cell contains the title
                row_coord = cell.row #put row number into a variable

tables("All Call Distribution by Hour")

我目前能够根据标题找到行,将标题保存到变量中,但我不知道如何选择每个数据块的右下角并将其选择为范围并创建该范围内的表格。

编辑 1: 标题行是正确的,结束行的行为类似于 max_rownum_cols 显示的是 cell.values 而不是该表的单个最大列。

def find_table(title, sheet):
    title_row = None
    for row in sheet.iter_rows():
        if row[0].value == title:
            #Find the title row
            title_row = row[0].row
        if row[0].value is None and title_row:
            end_row = row[0].row - 1
            num_cols = [cell.value for cell in sheet[title_row+1] if cell.value is not None]
    else:
        #The last row in the sheet
        end_row = row[0].row
    print(f"Row: {title_row}, Column: {num_cols}, End Row: {end_row}")
    return title_row, num_cols, end_row

输出:Row: 40, Column: ['Within', '# Calls', '% Calls'], End Row: 138

【问题讨论】:

  • 我尝试了 max_row 和 max_column 的变体,但无论我在哪个数据块中,max_column 都会给出最远的列。
  • 您是否尝试过检测空单元格/行/列来确定表格的限制?
  • 不幸的是,从某种意义上说,这些都是使用过的单元格。所以我不太确定如何将它插入到循环中。理想情况下,由于所有内容都可以在“A”列中找到,我可以搜索:标题,找到空白行,从标题下方的行到空白行上方选择,创建表格。在这一点上,虽然我只想能够选择标题下面的行到空白行并称之为好。我已经研究了一周,但我发现的一切都与静态范围有关。
  • 理想情况下应该是Loop until BLANK cell, select row below title(top-left cell) and max_column(bot-right cell), create table
  • 一种可能会有所帮助(甚至可能需要让您解决问题的策略)是每个工作表只有一个表格,因此表格总是从左上角向下延伸,没有撞到另一张桌子的风险

标签: python excel openpyxl


【解决方案1】:

要选择您想要的单元格,请尝试这样的操作

def find_table(sheet, title):
    title_row = None
    for row in sheet.iter_rows():
        if row[0].value == title:
            # Find the title row
            title_row = row[0].row
        if row[0].value is None and title_row:
            end_row = row[0].row - 1
            break
    else:
        # The last row in the sheet
        end_row = row[0].row
return title_row, end_row

您可以找到给定表格的具体列数;

num_cols = len([cell.value for cell in sheet[title_row+1] if cell.value is not None])

这应该为您提供开始行和结束行以及列数。然后,您可以选择这些单元格并使用它们以适合您的特定示例的任何形式“制作表格”。

如果您想使用 Excel 的“A1”样式表示法选择一系列单元格,您始终可以使用 openpyxl.utils.cell.get_column_letter(idx) 将数字列号转换为相应的字母。

这个解决方案非常简单,并且对 Excel 表格的格式做出了一些假设,例如数据始终从 ColumnA 开始,ColumnA 中的空单元格表示完全为空的行,并且标题行始终紧随其后标题行。您可能还想添加一些错误处理 - 例如,如果找不到标题行怎么办? 希望这可以让您朝着正确的方向开始,并尝试一些想法。

【讨论】:

  • 这正是我的目标。只要我能找到范围,我就能进步。就像他们总是说 20/20 事后诸葛亮,因为它是如此简单,我不敢相信我没有想到它。非常感谢!
  • 运行代码后,它会像我上面的编辑一样输出。标题行是正确的,最后一行显示的是整个工作表的最后一行,这是不正确的,num_cols 显示的是列标题,而不是表中最后一个列的数字。
  • 确定。请参阅上面我编辑的答案。这是我的错误,我是从头上写的,并没有实际测试它!您需要在 for 循环中使用 break,因此您不会一直迭代到工作表的另一端。至于num_cols,我们正在查找列名列表,所以您需要做的就是取其中的len()。看看有没有帮助。
  • 你在没有测试的情况下做得很好!该编辑解决了这个问题,该函数现在给出了正确的开始行(标题)、结束行(空白单元格/行之前的行)和该范围的最大列
猜你喜欢
  • 2012-08-17
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多