Question

Je dois port un algorithme à partir d'une feuille Excel à code python mais je dois ingénieur inverse l'algorithme à partir du fichier Excel .

La feuille Excel est assez compliqué, il contient beaucoup de cellules dans lesquelles il existe des formules qui font référence à d'autres cellules (qui peut aussi contenir une formule ou une constante).

Mon idée est d'analyser avec un script python la feuille construction d'une sorte de table des dépendances entre les cellules, qui est:

  

A1 dépend de B4, C5, formule E7: "= sqrt (B4) + C5 * E7"
  A2 dépend B5, formule C6: "= sin (B5) * C6"
  ...

Le xlrd le module python permet de lire un classeur XLS mais pour le moment je peux accéder à valeur d'une cellule, et non le formule .

Par exemple, le code suivant, je peux simplement obtenir la valeur d'une cellule:

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)

Quoi qu'il en soit, il semble avoir aucun moyen d'obtenir le formul de l'objet de cellule retournée par .Cellule (...) méthode . ils disent qu'il est possible de obtenir une version de chaîne de la formule (en anglais parce qu'il n'y a pas d'information sur la traduction du nom de fonction stockée dans le fichier Excel). Ils parlent de formules (expressions) dans le Nom et Opérande cours, je ne peux quand même pas à comprendre comment obtenir les instances de ces classes par le Cellule instance de classe qui doit les contient.

Pouvez-vous suggérer un extrait de code qui obtient le texte de la formule d'une cellule?

Était-ce utile?

La solution

[Dis] claimer. Je suis l'auteur / mainteneur de xlrd

Les références de documentation au texte de la formule sont sur les formules « nom »; lire la section « références nommées, des constantes, des formules et macros » près du début de la documentation. Ces formules sont associées à feuilles larges ou livre à l'échelle à un nom; ils ne sont pas associés à des cellules individuelles. Exemples: PI cartes à =22/7, SALES cartes à =Mktng!$A$2:$Z$99. Le nom formule décompilateur a été écrit à l'inspection du soutien des plus simples et / ou usages on trouve couramment des noms définis.

Les formules en général sont de plusieurs types: cellules, partagée, et le réseau (toutes associées à une cellule, directement ou indirectement), le nom, la validation des données et la mise en forme conditionnelle

.

décompilation formules générales de bytecode au texte est un « travail en cours », lentement. Notez que supposer qu'il était disponible, vous devez ensuite analyser la formule de texte pour extraire les références de cellules. Excel correctement parsing formules ne sont pas une tâche facile; comme avec HTML, en utilisant des expressions rationnelles semble facile, mais ne fonctionne pas. Il serait préférable d'extraire les références directement à partir de la formule bytecode.

Notez également que les formules à base de cellules peuvent se référer à des noms et des formules de nom peuvent se référer à la fois aux cellules et à d'autres noms. Il serait donc nécessaire d'extraire les deux cellules et les références de nom des deux formules à base de cellules et le nom. Il vous est peut-être utile d'avoir d'informations sur les formules disponibles Partagés; autrement avoir analysé le texte suivant:

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

vous devez déduire la similitude entre les formules de B3:B60 vous-même.

Dans tous les cas, aucun de ce qui précède est susceptible d'être disponible dans un proche avenir -. Les priorités de xlrd sont ailleurs

Autres conseils

Mise à jour : Je suis allé et mis en œuvre une petite bibliothèque pour faire exactement ce que vous décrivez: extraire les cellules et les dépendances d'une feuille de calcul Excel et les convertir en code python. est sur github , patches :) bienvenue


Juste pour ajouter que vous pouvez toujours interagir avec Excel à l'aide win32com (pas très rapide mais cela fonctionne). Cela ne vous permet d'obtenir la formule. Un tutoriel est disponible ici et les détails peuvent être trouvés dans ce chapitre [mises en cache copier] .

Essentiellement, vous faites juste:

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

En ce qui concerne la construction d'une table de dépendances de cellules, une chose délicate est l'analyse syntaxique des expressions Excel. Si je me souviens bien le code de trace que vous avez mentionné ne pas toujours le faire correctement. Le meilleur que je l'ai vu est l'algorithme par E. W. Bachtal , dont une implémentation de Python est disponible qui fonctionne bien.

Je sais que c'est un poste très vieux, mais je l'ai trouvé un moyen convenable d'obtenir les formules de toutes les feuilles dans un classeur, ainsi que d'avoir le classeur nouvellement créé conserve tout le formatage.

La première étape consiste à enregistrer une copie de votre fichier .xlsx .xls - Utilisez le .xls comme le nom du fichier dans le code ci-dessous

En utilisant 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

Structure 'sheet_formulas' Dictionnaire

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

Résultats Exemple:

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

Il semble qu'il est impossible maintenant de faire ce que vous voulez avec xlrd. Vous pouvez jeter un oeil à ce poste pour la description détaillée des raisons pour lesquelles il est si difficile à mettre en œuvre les fonctionnalités dont vous avez besoin.

Notez que l'équipe fait un excellent développer travail pour le soutien au python-Excel groupe Google.

Je sais que ce post est un peu en retard, mais il y a une suggestion qui n'a pas été abordé ici. Couper toutes les entrées de la feuille de calcul et coller à l'aide de collage spécial (OpenOffice). Cela vous permet de convertir les formules en nombres donc il n'y a pas besoin de programmation supplémentaire et c'est une solution raisonnable pour les petits classeurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top