2011-02-08 1 views
3

У меня есть сценарий, который извлекает данные из таблицы Excel с помощью модуля xlrd, в частности метода row_values ​​(). Похоже, что он отлично справляется, кроме тех случаев, когда «# N/A» был автоматически сгенерирован предыдущими VLookups, и в этом случае xlrd получает «# N/A» как целое число 42.xlrd Преобразование сценария Excel «# N/A» в 42

Я взглянул на string, но не мог понять, как это проблема.

Помимо наличия сценария, который открыл смысл жизни (42), может ли кто-нибудь предложить, в чем проблема?

Приветствия

Примечание: Лист больше не имеет Vlookups в нем, все значения не были скопированы из других листов, все простые значения, без формул.

+0

Wild догадки: числовой код для Excel # N/A значения ошибки 2042 года я ничего не знаю о xlrd, но, возможно, это помогает. (Я бы предпочел, чтобы ваш сценарий думал о глубоких мыслях, хотя ...) – jtolle

ответ

4

xlrd docs в Интернете (или на вашем компьютере, откройте документы в своем браузере и сделайте Ctrl-F #N/A), дайте conversion table from Excel internal codes to text.

Возможно, было бы полезно посмотреть на sheet.row_types() method и Cell class docs, которые дают вам перекрестную ссылку между номерами типов, возвращаемыми sheet.row_types() и другими. Обратите внимание, что, как правило, более эффективно тестировать эти номера типов, чем использовать isinstance() для значений, и нет никакой двусмысленности с использованием номеров типов.

8

Я нашел это полезным. Благодаря первой помощи Джона.

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] 
2

Как указано Эндрю, если у Вас есть ошибка в ячейке, xlrd записывает код ошибки, который вы можете увидеть 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 

Преобразование кода 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)]) 
Смежные вопросы