Вопрос

Я должен перенос алгоритма из таблицы Excel в код Python но я должен реинжиниринг алгоритма из файла Excel.

Лист Excel довольно сложный, он содержит много ячеек, в которых есть формулы, которые ссылаются на другие ячейки (которые также могут содержать формулу или константу).

Моя идея состоит в том, чтобы проанализировать с помощью скрипта Python лист, создающий своего рода таблицу зависимостей между ячейками, то есть:

A1 зависит от формулы B4, C5, E7:"=sqrt(B4)+C5*E7"
A2 зависит от формулы B5,C6:"=sin(B5)*C6"
...

Тот Самый xlrd модуль python позволяет читать рабочую книгу XLS, но на данный момент я могу получить доступ к значение ячейки, а не самого формула.

Например, с помощью следующего кода я могу просто получить значение ячейки:

import xlrd

#open the .xls file
xlsname="test.xls"
book = xlrd.open_workbook(xlsname)

#build a dictionary of the names->sheets of the book
sd={}
for s in book.sheets():
    sd[s.name]=s

#obtain Sheet "Foglio 1" from sheet names dictionary
sheet=sd["Foglio 1"]

#print value of the cell J141
print sheet.cell(142,9)

В любом случае, похоже, у него нет способа получить формулу из объекта Cell, возвращаемого .ячейка(...) способ.В Документация они говорят, что можно получить строковую версию формулы (на английском языке, поскольку в файле Excel нет информации о переводе названия функции).Они говорят о формулах (выражениях) в Имя и Операнд классы, во всяком случае, я не могу понять, как получить экземпляры этих классов с помощью Ячейка экземпляр класса, который должен их содержать.

Не могли бы вы предложить фрагмент кода, который извлекает текст формулы из ячейки?

Это было полезно?

Решение

Dis] претендент: я автор/сопровождающий xlrd.

Ссылки на документацию на текст формулы посвящены формулам «Имя»; Прочитайте раздел «Названные ссылки, константы, формулы и макросы» в начале документов. Эти формулы связаны с именем в листе или по всей книге; Они не связаны с отдельными клетками. Примеры: PI карты =22/7, SALES карты =Mktng!$A$2:$Z$99. Анкет Декомпилятор имени Формулы был написан для поддержки проверки более простых и/или обычно найденных использования определенных имен.

Формулы в целом имеют несколько видов: ячейки, общие и массив (все связаны с ячейкой, прямо или косвенно), именем, проверкой данных и условным форматированием.

Декомпилирование общих формул от байт-кода в текст-это «незавершенная работа», медленно. Обратите внимание, что предположим, что это было доступно, вам нужно проанализировать текстовую формулу, чтобы извлечь ссылки на ячейки. Правильно разбора формул Excel - нелегкая работа; Как и в случае с HTML, использование режимов выглядит легко, но не работает. Было бы лучше извлечь ссылки непосредственно из байт -кода формулы.

Также обратите внимание, что формулы на основе ячеек могут ссылаться на имена, а формулы имен могут ссылаться как на ячейки, так и на другие имена. Таким образом, было бы необходимо извлечь ссылки на ячейку и имени из формул на основе ячеек и имени. Вам может быть полезно иметь информацию о общих формулах; в противном случае проанализировав следующее:

B2 =A2
B3 =A3+B2
B4 =A4+B3
B5 =A5+B4
...
B60 =A60+B59

Вам нужно было сделать вывод сходства между B3:B60 Формулы сами.

В любом случае, ни одно из вышеперечисленного не будет доступно в ближайшее время - xlrd Приоритеты лежат в другом месте.

Другие советы

Обновлять: Я пошел и внедрил небольшую библиотеку, чтобы сделать именно то, что вы описываете: извлечение ячеек и зависимости из электронной таблицы Excel и преобразование их в код Python. Код на GitHub, патчи приветствуются :)


Просто чтобы добавить, что вы всегда можете взаимодействовать с Excel, используя Win32com (Не очень быстро, но это работает). Это позволяет вам получить формулу. А Учебное пособие можно найти здесь и подробности можно найти в этой главе Кэшированная копия.

По сути вы просто делаете:

app.ActiveWorkbook.ActiveSheet.Cells(r,c).Formula

Что касается построения таблицы зависимостей от клеток, то сложная вещь - анализ выражений Excel. Если я правильно помню, упомянутый вами код трассии не всегда делает это правильно. Лучшее, что я видел Алгоритм EW Bachtal, из которых доступна реализация Python, которая работает хорошо.

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

Первый шаг - сохранить копию вашего файла .xlsx как .xls - используйте .xls в качестве имени файла в коде ниже

Используя Python 2.7

from lxml import etree
from StringIO import StringIO
import xlsxwriter
import subprocess
from xlrd import open_workbook
from xlutils.copy import copy
from xlsxwriter.utility import xl_cell_to_rowcol
import os



file_name = '<YOUR-FILE-HERE>'
dir_path = os.path.dirname(os.path.realpath(file_name))

subprocess.call(["unzip",str(file_name+"x"),"-d","file_xml"])


xml_sheet_names = dict()

with open_workbook(file_name,formatting_info=True) as rb:
    wb = copy(rb)
    workbook_names_list = rb.sheet_names()
    for i,name in enumerate(workbook_names_list):
        xml_sheet_names[name] = "sheet"+str(i+1)

sheet_formulas = dict()
for i, k in enumerate(workbook_names_list):
    xmlFile = os.path.join(dir_path,"file_xml/xl/worksheets/{}.xml".format(xml_sheet_names[k]))
    with open(xmlFile) as f:
        xml = f.read()

    tree = etree.parse(StringIO(xml))
    context = etree.iterparse(StringIO(xml))

    sheet_formulas[k] = dict()
    for _, elem in context:
        if elem.tag.split("}")[1]=='f':
            cell_key = elem.getparent().get(key="r")
            cell_formula = elem.text
            sheet_formulas[k][cell_key] = str("="+cell_formula)

sheet_formulas

Структура словаря 'sheet_formulas'

{'Worksheet_Name': {'A1_cell_reference':'cell_formula'}}

Пример результатов:

{u'CY16': {'A1': '=Data!B5',
  'B1': '=Data!B1',
  'B10': '=IFERROR(Data!B12,"")',
  'B11': '=IFERROR(SUM(B9:B10),"")',

Кажется, что сейчас невозможно делать с xlrd то, что вы хотите.Вы можете взглянуть на этот пост за подробным описанием того, почему так сложно реализовать необходимый вам функционал.

Обратите внимание, что команда разработчиков отлично справляется со службой поддержки в Google Group python-excel.

Я знаю, что этот пост немного опоздал, но есть одно предложение, которое здесь не было покрыто. Вырежьте все записи из рабочего листа и вставьте, используя Paste Special (OpenOffice). Это преобразует формулы в числа, поэтому нет необходимости в дополнительном программировании, и это разумное решение для небольших рабочих книг.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top