使用Python查找Excel单元格引用

这里是有问题的Excel文件:

上下文:我正在写一个程序,它可以从PDF中提取值,并将它们放在Excel文件的适当单元格中。

问题:我想写一个函数,它将一个列值(例如2014)和一个行值(例如'COGS')作为参数,并返回这两个相交的单元格引用(例如,2014年COGS的“C3”)。

def find_correct_cell(year=2014, item='COGS'): #do something similar to what the =match function in Excel does return cell_reference #returns 'C3' 

我已经尝试使用这样的openpyxl来更改一些随机空单元格的值,我可以存储这些值:

  col_num = '=match(2014, A1:E1)' row_num = '=match("COGS", A1:A5)' 

但我想抓住这些值,而不必随意写入这些随机的空单元格。 另外,即使使用这种方法,当我读取这些单元格(F5和F6)时,它将读取这些单元格中的公式,而不是3的面值。

任何帮助表示赞赏,谢谢。

考虑一个翻译的VBA解决scheme,因为匹配function可以充分处理您的需求。 Python可以使用win32com模块的COM接口访问Excel VBA对象库。 请注意,此解决scheme假定您正在使用Excel for PC。 下面包括对应的VBAfunction。

VBAfunction(本机界面)

如果将以下函数放置在Excel标准模块中,则可以在电子表格cell =FindCell(..., ###)调用函数

 ' MATCHES ROW AND COL INPUT FOR CELL ADDRESS OUTPUT Function FindCell(item As String, year As Integer) As String FindCell = Cells(Application.Match(item, Range("A1:A5"), 0), _ Application.Match(year, Range("A1:E1"), 0)).Address End Function debug.Print FindCell("COGS", 2014) ' $C$3 

Python脚本(外部接口,需要声明所有对象)

Try / Except / Finally用于正确closuresExcel进程,无论脚本是成功还是失败。

 import win32com.client # MATCHES ROW AND COL INPUT FOR CELL ADDRESS OUTPUT def FindCell(item, year): return(xlWks.Cells(xlApp.WorksheetFunction.Match(item, xlWks.Range("A1:A5"), 0), xlApp.WorksheetFunction.Match(year, xlWks.Range("A1:E1"), 0)).Address) try: xlApp = win32com.client.Dispatch("Excel.Application") xlWbk = xlApp.Workbooks.Open('C:/Path/To/Workbook.xlsx') xlWks = xlWbk.Worksheets("SHEETNAME") print(FindCell("COGS", 2014)) # $C$3 except Exception as e: print(e) finally: xlWbk.Close(False) xlApp.Quit xlWks = None xlWbk = None xlApp = None 

有一个令人惊讶的数量的细节,你需要正确的操作Excel文件这种方式与openpyxl。 首先,值得知道的是,xlsx文件包含每个单元格的两个表示 – 公式和公式的当前值。 openpyxl可以返回,如果你想要值,你应该在打开文件的时候指定data_only=True 。 此外,当您更改单元格公式时,openpyxl无法计算新值 – 只有Excel本身可以执行此操作。 所以插入一个MATCH()工作表函数不能解决你的问题。

下面的代码做你想要的,主要是在Python中。 它使用“A1”参考样式,并进行一些计算以将列号转换为列字母。 如果你过去的列Z,这将不能保持良好。在这种情况下,你可能想切换到行和列的编号引用。 这里和这里有更多的信息。 但希望这会让你在路上。

注意:此代码假定您正在阅读名为“test.xlsx”的工作簿,并且“COGS”位于“Sheet1!A2:A5”中的项目列表中,2014在“Sheet1!B1: E1' 。

 import openpyxl def get_xlsx_region(xlsx_file, sheet, region): """ Return a rectangular region from the specified file. The data are returned as a list of rows, where each row contains a list of cell values""" # 'data_only=True' tells openpyxl to return values instead of formulas # 'read_only=True' makes openpyxl much faster (fast enough that it # doesn't hurt to open the file once for each region). wb = openpyxl.load_workbook(xlsx_file, data_only=True, read_only=True) reg = wb[sheet][region] return [[cell.value for cell in row] for row in reg] # cache the lists of years and items # get the first (only) row of the 'B1:F1' region years = get_xlsx_region('test.xlsx', 'Sheet1', 'B1:E1')[0] # get the first (only) column of the 'A2:A6' region items = [r[0] for r in get_xlsx_region('test.xlsx', 'Sheet1', 'A2:A5')] def find_correct_cell(year, item): # find the indexes for 'COGS' and 2014 year_col = chr(ord('B') + years.index(year)) # only works in A:Z range item_row = 2 + items.index(item) cell_reference = year_col + str(item_row) return cell_reference print find_correct_cell(year=2014, item='COGS') # C3