xlrd Excel 脚本将“#N/A”转换为至 42

发布于 2024-10-16 21:23:01 字数 274 浏览 5 评论 0 原文

我有一个脚本,可以使用 xlrd 模块(特别是 row_values() 方法)从 Excel 电子表格中提取数据。它似乎做得很好,除了以前的 VLookups 自动生成的“#N/A”,在这种情况下,xlrd 将“#N/A”获取为整数 42。

我查看了字符串格式化方法,但是不明白这是怎么回事。

除了有一个发现生命意义的脚本(42)之外,有人能提出问题可能是什么吗?

干杯

注意:该工作表中不再包含 Vlookups,所有值都已从其他工作表复制,一切都是纯值,没有公式。

I have a script that pulls data out of an excel spreadsheet using the xlrd module, specifically the row_values() method. It appears to do a great job, except for where "#N/A" has been auto-generated by previous VLookups, in which case xlrd gets "#N/A" as integer 42.

I had a look at string formatting methods but couldn't see how that was the issue.

Apart from having a script that has discovered the meaning of life (42), can anyone suggest what the issue may be?

Cheers

Note: The sheet no longer has the Vlookups in it, all values have been copied from other sheets, everything is plain values, no formulas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

如梦初醒的夏天 2024-10-23 21:23:01

我发现这很有用。感谢约翰最初的帮助。

def xls_proc_text(cell, value_proc=None, text_proc=None):
    """Converts the given cell to appropriate text."""
    """The proc will come in only when the given is value or text."""
    ttype = cell.ctype
    if ttype == xlrd.XL_CELL_EMPTY or ttype == xlrd.XL_CELL_TEXT or ttype == xlrd.XL_CELL_BLANK:
        if text_proc is None:
            return cell.value
        else:
            return text_proc(cell.value)
    if ttype == xlrd.XL_CELL_NUMBER or ttype == xlrd.XL_CELL_DATE or ttype == xlrd.XL_CELL_BOOLEAN:
        if value_proc is None:
            return str(cell.value)
        else:
            return str(value_proc(cell.value))
    if cell.ctype == xlrd.XL_CELL_ERROR:
        # Apply no proc on this.
        return xlrd.error_text_from_code[cell.value]

I found this useful. Thanks to John's initial help.

def xls_proc_text(cell, value_proc=None, text_proc=None):
    """Converts the given cell to appropriate text."""
    """The proc will come in only when the given is value or text."""
    ttype = cell.ctype
    if ttype == xlrd.XL_CELL_EMPTY or ttype == xlrd.XL_CELL_TEXT or ttype == xlrd.XL_CELL_BLANK:
        if text_proc is None:
            return cell.value
        else:
            return text_proc(cell.value)
    if ttype == xlrd.XL_CELL_NUMBER or ttype == xlrd.XL_CELL_DATE or ttype == xlrd.XL_CELL_BOOLEAN:
        if value_proc is None:
            return str(cell.value)
        else:
            return str(value_proc(cell.value))
    if cell.ctype == xlrd.XL_CELL_ERROR:
        # Apply no proc on this.
        return xlrd.error_text_from_code[cell.value]
鹤仙姿 2024-10-23 21:23:01

网络上的 xlrd 文档(或在您的计算机上;在浏览器中打开文档并执行 Ctrl-F #N/A)为您提供 Excel 内码到文本的转换表

查看 sheet.row_types() 可能有用方法,以及 Cell 类文档为您提供由sheet.row_types()和其他返回的类型号之间的交叉引用。请注意,测试这些类型编号通常比对值使用 isinstance() 更有效,并且使用类型编号不会产生歧义。

xlrd docs on the web (or on your computer; open the docs in your browser and do Ctrl-F #N/A) give you the conversion table from Excel internal codes to text.

It might be of use to look at the sheet.row_types() method, and the Cell class docs which give you the cross-reference between type numbers as returned by sheet.row_types() and others. Note that it is generally more efficient to test for those type numbers than it is to use isinstance() on the values, AND there is no ambiguity using type numbers.

栖竹 2024-10-23 21:23:01

正如 Andrew 所列,如果单元格中有错误,xlrd 会写入错误代码,您可以看到 此处

0x00: '#NULL!',  # Intersection of two cell ranges is empty
0x07: '#DIV/0!', # Division by zero
0x0F: '#VALUE!', # Wrong type of operand
0x17: '#REF!',   # Illegal or deleted cell reference
0x1D: '#NAME?',  # Wrong function or range name
0x24: '#NUM!',   # Value range overflow
0x2A: '#N/A',    # Argument or function not available

将代码 0x2A 从十六进制转换为十进制,您可以获得 42 值。
为了避免这种情况,您可以在代码中使用类似的内容:

for rownum in xrange(sh.nrows):
    wr.writerow(['#N/A' if col.ctype == xlrd.XL_CELL_ERROR else col.value for col in sh.row(rownum)])

As Andrew listed if you have error in the cell, xlrd writes the code of the error, which you can see here:

0x00: '#NULL!',  # Intersection of two cell ranges is empty
0x07: '#DIV/0!', # Division by zero
0x0F: '#VALUE!', # Wrong type of operand
0x17: '#REF!',   # Illegal or deleted cell reference
0x1D: '#NAME?',  # Wrong function or range name
0x24: '#NUM!',   # Value range overflow
0x2A: '#N/A',    # Argument or function not available

Converting code 0x2A from hex to dec you can get that 42 value.
To avoid that you can use something like this in your code:

for rownum in xrange(sh.nrows):
    wr.writerow(['#N/A' if col.ctype == xlrd.XL_CELL_ERROR else col.value for col in sh.row(rownum)])
烈酒灼喉 2024-10-23 21:23:01
  • 我已经简化了解决方案,谢谢楼上各位。你可以
    根据单元格类型识别错误单元格。
  • 我们拥有的数据是 #N/A
  • 值 = 42 的 ctype(而不是 #N/A),
  • ctype 将为 5

简单的解决方案可能是识别错误单元格并输入“无”而不是 42

textType = sheet.cell(r,0).ctype #Get the type of the cell

        if textType == 5:
            text = None
        else:
            text = sheet.cell(r, 0).value

XLRD 文档

您可以识别所有另一种类型基于以下文档

XL_CELL_ERROR 5 int 表示内部 Excel 代码;对于文本表示,请参阅提供的字典 error_text_from_code

  • I have simplified the solution, Thanks to everyone above. You can
    Identify Error cell based on cell type.
  • The data we have is ctype of #N/A
  • value = 42 (instead of #N/A)
  • ctype will be 5

Simple solution might be Identify Error cell and put 'None' instead of 42

textType = sheet.cell(r,0).ctype #Get the type of the cell

        if textType == 5:
            text = None
        else:
            text = sheet.cell(r, 0).value

XLRD Documentation:

You can identify the all the other type based on below documentation

XL_CELL_ERROR 5 int representing internal Excel codes; for a text representation, refer to the supplied dictionary error_text_from_code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文