我正在尝试从Excel工作表中提取单元格值,使用它们进行数学运算,并将输出写入新工作表。我一直在收到ErrorType。我之前已成功运行代码,但只是添加了它的这方面,因此代码已被提炼到下面:
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
因此,如果指定的单元格为空,则会被忽略并跳过。
答案 0 :(得分:0)
您是否100%确定(已经验证)您正在访问的所有单元格实际上都有值? (编辑:执行print("dbg> cell value of {}, {} is {}".format(row, 1, ws.cell(row=row, column=1).value))
验证内容)
我建议使用openpyxl内省方法迭代现有行,而不是通过固定范围(1,1000)。 E.g:
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
作为一般说明:x
和y
是2D坐标的有用变量名称。不要将它们用于行。它会误导其他必须阅读代码的人。您可以使用x
或start_row
或类似内容来代替row_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()
。