0

我正在尝试从 Excel 工作表中提取单元格值,对它们进行数学运算,然后将输出写入新工作表。我不断收到错误类型。我之前已经成功运行过代码,但只是添加了它的这一方面,因此代码已被提炼到下面:

import openpyxl

#set up ws from file, and ws_out write to new file

def get_data():
    first = 0
    second = 0
    for x in range (1, 1000):
        if ws.cell(row=x, column=1).value == 'string':
            for y in range (1, 10):            #Only need next ten rows after 'string'

                ws_out.cell(row=y, column=1).value = ws.cell(row=x+y, column=1).value

                second = first                             #displaces first -> second
                first = ws.cell(row=x+y, column=1).value/100     #new value for first
                difference = first - second

                ws_out.cell(row=x+y+1, column=1).value = difference    #add to output
            break

抛出 TypeError 消息:

first = ws.cell(row=x+y, column=1).value)/100
TypeError: /: 'NoneType' 和 'int' 的操作数类型不受支持

我假设这分别指的是 ws.cell 值和 100,所以我也尝试过:

first = int(ws.cell(row=x, column=1))/100 #also tried with float

这引发了:

TypeError: int() 参数必须是字符串或数字

我已经确认该列中的每个单元格仅由数字组成。此外,openpyxl 的 cell.data_type 返回“n”(据我所知,据我所知,可能是数字)。

我还测试了更简单的数学,并且有同样的错误。

我所有的搜索似乎都指向 openpyxl 通常表现得像这样。我做错了什么,或者这仅仅是模块的限制?如果是这样,是否有任何程序化解决方法?

作为奖励,将不胜感激有关更简洁地编写代码的建议。我才刚刚开始,觉得必须有一种更干净的方式来写这样的想法。

Python 3.3、openpyxl-1.6.2、Windows 7


概括

cfi 的回答帮助我弄清楚了,尽管我使用了一个稍微不同的解决方法。在检查原始文件时,有一个空单元格(我之前错过了)。由于稍后我将在具有更多零星空单元格的列上重新使用此代码,因此我使用了:

if ws.cell(row=x+r, column=40).data_type == 'n':
    second = first                             #displaces first -> second
    first = ws.cell(row=x+y, column=1).value/100     #new value for first
    difference = first - second

    ws_out.cell(row=x+y+1, column=1).value = difference    #add to output

因此,如果指定的单元格为空,则会被忽略并跳过。

4

1 回答 1

0

您是否 100% 确定(=已验证)您正在访问的所有单元格实际上都包含一个值?(编辑:做一个print("dbg> cell value of {}, {} is {}".format(row, 1, ws.cell(row=row, column=1).value))来验证内容)

我建议不要使用固定范围(1,1000),而是使用 openpyxl 内省方法来迭代现有行。例如:

wb=load_workbook(inputfile)
    for ws in wb.worksheets:
        for row in ws.rows:
            for cell in row:  value = cell.value

获取值时不要忘记提取.value属性:

first = ws.cell(row=x+y, column=1).value/100    #new value for first

作为一般说明:xy是二维坐标的有用变量名。不要将它们都用于行。它会误导其他必须阅读代码的人。而不是x你可以使用start_roworrow_offset或类似的东西。而不是y你可以只使用row,你可以让它从第一个索引开始start_row+1

一些示例代码(未经测试):

def get_data():
    first = 0
    second = 0
    for start_row in range (1, ws.rows):
        if ws.cell(row=start_row, column=1).value == 'string':
            for row in range (start_row+1, start_row+10):

                ws_out.cell(row=start_row, column=1).value = ws.cell(row=row, column=1)

                second = first
                first = ws.cell(row=row, column=1).value/100
                difference = first - second

                ws_out.cell(row=row+1, column=1).value = difference
            break

现在有了这段代码,我仍然不明白你想要实现什么。break缩进是否正确?如果是,第一次匹配string时,外部循环将被break. 那么,变量first和的意义second何在?

编辑:还要确保您的阅读写入cell().value不仅仅是cell().

于 2013-07-08T07:43:20.840 回答