2017-01-17 10 views
0

Я пытаюсь использовать Python 3.4 для получения значения ячейки C1 файла Excel. Ячейка C1 представляет собой формулу: = A1 + B1. Примечание: значения A1 и B1 меняются, поэтому возвращаемое значение в C1 должно автоматически изменить соответственно.Python 3.4: Невозможно прочитать значение из Excel Формула

В Python 3.4, я использую следующие коды:

import openpyxl 
from openpyxl import Workbook 

wb = openpyxl.load_workbook('test.xlsx') 
sheet1 = wb['Sheet1'] 
C1Value = sheet1['C1'].value 
print('C1: ', C1Value) 

======

При запуске программы Python, я получаю: С1: = А1 + В1

то, что я хочу, чтобы получить это:

А1 = 1, В1 = 2, то С1: 3 (вместо С1: = А1 + В1)

и А1 = 10, B1 = 20, то автоматически С1: 30 (вместо C1: = А1 + В1)

Любая помощь, идея, было бы весьма признателен. Благодарю.

+1

Возможная дубликат [значения ячейки чтения Excel, а не формула вычисления это -openpyxl] (http://stackoverflow.com/q/28517508/1072229) –

+1

Возможный дубликат [openpyxl error: "can n ot convert string to float "] (http://stackoverflow.com/questions/41449712/openpyxl-error-could-not-convert-string-to-float) – e4c5

+0

Возможный дубликат [Читать значение ячейки Excel, а не вычисление формулы it -openpyxl] (http: // stackoverflow.com/questions/28517508/read-excel-cell-value-and-not-the-formula-computing-it-openpyxl) – Mxt

ответ

0

Очень быстрый взгляд на openpyxl docs и вы могли бы найти this page говоря

openpyxl never evaluates formula

Прежде чем идти дальше, следует отметить, что возможные дублирующие ссылки имеют ответы, относящиеся к другим модулям, и они, как правило, принятые ответы. С этими модулями вам не нужно выполнять собственный синтаксический анализ. Который может быть от сложных до почти невозможных для более сложных систем.

Если вы делаете довольно простые вещи, это не очень сложно с Tokenizer class. Использование:

>>> from openpyxl.formula import Tokenizer 
>>> tok = Tokenizer("""=IF($A$1,"then True",MAX(DEFAULT_VAL,'Sheet 2'!B1))""") 
>>> print("\n".join("%12s%11s%9s" % (t.value, t.type, t.subtype) for t in tok.items)) 
     IF(  FUNC  OPEN 
     $A$1 OPERAND RANGE 
      ,  SEP  ARG 
"then True" OPERAND  TEXT 
      ,  SEP  ARG 
     MAX(  FUNC  OPEN 
DEFAULT_VAL OPERAND RANGE 
      ,  SEP  ARG 
'Sheet 2'!B1 OPERAND RANGE 
      )  FUNC CLOSE 
      )  FUNC CLOSE 

Обратите особое внимание, все это строка, поэтому оценки формул лучше всего сделать с eval()

Итак, если вы редактировали код немного (новые/измененные строки, отмеченные #),

import openpyxl 
from openpyxl import Workbook 
from openpyxl.formula import Tokenizer  # 

wb = openpyxl.load_workbook('test.xlsx') 
sheet1 = wb['Sheet1'] 
C1Formula = sheet1['C1'].value    # 
C1Token = Tokenizer(C1Formula)    # 
C1Value = handle_token(sheet1, C1Token) # 
print('C1: ', C1Value) 

Где handle_token() зависит от вас за то, насколько сложно вам это хотелось. Пара простой и, возможно, взломать, у примеров C1: =A1 + B1 и другие бинарных операторов: (они не работают для ^, как питон использует это для побитового XOR)

def handle_token(sheet, token): 
    formula = "" 
    for t in token.items: 
     if t.type is 'OPERAND': 
      formula += str(sheet[t.value]) 
     else: 
      formula += str(t.value) 
    return eval(formula) 

Или, если вы предпочитаете (это может быть преобразовано к однострочника, не рекомендуется) с использованием генератора:

def handle_token(sheet, token): 
    parsed = str(sheet[t.value].value) if t.type is 'OPERAND' else t.value for t in token.items 
    formula = "".join(parsed) 
    return eval(formula) 
+0

Большое спасибо Grisha .. – Stan

+1

Он работает как шарм, используя: wb = openpyxl.load_workbook (' test.xlsx ', data_only = True) – Stan