Domanda

Devo porta un algoritmo da un foglio Excel per codice Python , ma devo decodificare l'algoritmo dal file di Excel .

Il foglio Excel è piuttosto complicato, contiene molte cellule in cui ci sono formule che fanno riferimento ad altre cellule (che può anche contiene una formula o una costante).

La mia idea è quella di analizzare con uno script python il foglio di costruire una sorta di tabella delle dipendenze tra le cellule, che è il seguente:

A1 dipende B4, C5, E7 formula:
"= sqrt (B4) + C5 * E7" A2 dipende B5, C6 formula: "= sin (B5) * C6"
...

Il XLRD pitone modulo consente di leggere una cartella di lavoro XLS, ma al momento posso accedere a la valore di una cella, non il formula .

Ad esempio, con il seguente codice posso ottenere semplicemente il valore di una cella:

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)

In ogni caso, sembra avere alcun modo per ottenere il Formul dall'oggetto cellulare restituito dal (...) metodo di .cell . In documentazione dicono che è possibile ottenere una versione stringa della formula (in inglese perché non ci sono informazioni sulla traduzione dei nomi funzione memorizzata nel file Excel). Parlano di formule (espressioni) nel Nome e Operando le classi, in ogni caso non posso capire come ottenere le istanze di queste classi da parte del Cell istanza di classe che deve li contiene.

Potrebbe suggerire un frammento di codice che ottiene il testo formula da una cella?

È stato utile?

Soluzione

[Dis] claimer:. Sono l'autore / manutentore di xlrd

I riferimenti di documentazione per il testo della formula sono sulle formule "nome"; leggere la sezione "Nome riferimenti, costanti, formule e macro" vicino all'inizio dei documenti. Queste formule sono associati a foglio largo o un libro in tutto a un nome; essi non sono associati con singole celle. Esempi: PI mappe di =22/7, SALES mappe a =Mktng!$A$2:$Z$99. Il decompilatore nome formula è stato scritto per l'ispezione sostegno degli usi più semplici e / o che si trovano comunemente di nomi definiti.

Le formule in generale sono di diversi tipi: cellule, condiviso e array (tutto associato ad una cellula, direttamente o indirettamente), il nome, la convalida dei dati, e la formattazione condizionale

.

decompilazione formule generali da bytecode a testo è un "work in progress-", lentamente. Si noti che supponendo fosse disponibile, si sarebbe poi necessario analizzare la formula di testo per estrarre i riferimenti di cella. Di analisi di Excel formule correttamente non è un lavoro facile; come con HTML, utilizzando espressioni regolari sembra facile, ma non funziona. Sarebbe meglio per estrarre i riferimenti direttamente dal bytecode formula.

Si noti inoltre che le formule a base di cellule possono fare riferimento a nomi, e le formule nome può riferirsi sia alle cellule e ad altri nomi. Quindi sarebbe necessario estrarre sia cellulare e nome riferimenti da entrambe le formule a base di cellule e il nome. Può essere utile per voi di avere informazioni sulle formule condivise disponibili; altrimenti dopo aver analizzato il seguente:

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

si avrebbe bisogno di dedurre la somiglianza tra i B3:B60 formule te.

In ogni caso, nessuna di queste è probabile che sia disponibile in tempi brevi -. Priorità xlrd sono altrove

Altri suggerimenti

Aggiorna : sono andato e realizzato una piccola biblioteca per fare esattamente ciò che si descrive: estrarre le cellule e le dipendenze da un foglio di calcolo di Excel e convertirli in codice Python. è su GitHub , patch benvenuti :)


solo aggiungere che si può sempre interagiscono con Excel utilizzando win32com (non molto veloce ma funziona). Ciò consente di ottenere la formula. Un tutorial può essere trovato qui e dettagli possono essere trovati in questo capitolo [copia cache] .

In sostanza basta fare:

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

Per quanto riguarda la costruzione di una tabella delle dipendenze di cella, una cosa difficile è l'analisi delle espressioni excel. Se non ricordo male il codice Trace lei ha citato non sempre farlo in modo corretto. Il migliore che ho visto è l'algoritmo di E. W. Bachtal , di cui un'implementazione pitone è disponibile che funziona bene.

Quindi so che questo è un post molto vecchio, ma ho trovato un modo dignitoso di ottenere le formule di tutti i fogli di un lavoro, oltre ad avere la cartella di lavoro appena creato mantenere tutta la formattazione.

Il primo passo è quello di salvare una copia del file xlsx in xls - Utilizzare la .xls, come il nome del file nel seguente codice

Usare 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

Struttura del dizionario 'sheet_formulas'

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

Esempio risultati:

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

Sembra che sia impossibile ora di fare ciò che vuoi con XLRD. Si può avere uno sguardo al questo messaggio per la descrizione dettagliata del motivo per cui è così difficile da implementare la funzionalità necessaria.

Si noti che il team sviluppando fa un grande lavoro per il supporto al python-excel gruppo Google.

So che questo post è un po 'tardi ma c'è un suggerimento che non è stato trattato qui. Tagliare tutte le voci del foglio di lavoro e incollare con colla speciale (OpenOffice). Questo permette di convertire le formule ai numeri quindi non c'è alcuna necessità di programmazione supplementare e questa è una soluzione ragionevole per i piccoli cartelle di lavoro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top