29

アルゴリズムを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(...)メソッドによって返されるCellオブジェクトからformulを取得する方法がないようです。ドキュメントでは、数式の文字列バージョンを取得できると述べています(Excelファイルに関数名の変換に関する情報が保存されていないため、英語で)。彼らはNameクラスとOperandクラスの式(式)について話しますが、とにかく、それらを含まなければならないCellクラスインスタンスによってこれらのクラスのインスタンスを取得する方法を理解できません。

セルから数式テキストを取得するコードスニペットを提案できますか?

4

6 に答える 6

25

[Dis]claimer:私はの作者/メンテナーです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優先順位は他の場所にあります。

于 2011-01-14T20:16:46.673 に答える
14

更新:Excelスプレッドシートからセルと依存関係を抽出し、それらをPythonコードに変換するという、あなたが説明したことを正確に実行するための小さなライブラリを実装しました。コードはgithubにあり、パッチは大歓迎です:)


加えて、win32comを使用していつでもExcelを操作できます(それほど高速ではありませんが、機能します)。これにより、数式を取得できます。Aチュートリアルはここにあります [キャッシュされたコピー]と詳細を見つけることができますこの章では [キャッシュされたコピー]

基本的にあなたはただする:

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

セルの依存関係のテーブルを作成する場合、注意が必要なのは、Excelの式を解析することです。私が正しく覚えていれば、あなたが言及したトレースコードは必ずしもこれを正しく行うとは限りません。私が見た中で最高のものは、EW Bachtalによるアルゴリズムであり、Python実装が利用可能であり、これはうまく機能します。

于 2011-06-29T09:48:11.250 に答える
7

非常に古い投稿であることはわかっていますが、ブック内のすべてのシートから数式を取得し、新しく作成されたブックにすべての書式を保持させる適切な方法を見つけました。

最初のステップは、.xlsxファイルのコピーを.xlsとして保存することです-以下のコードでファイル名として.xlsを使用します

Python2.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),"")',
于 2016-11-13T08:31:30.797 に答える
2

xlrdでやりたいことが今は不可能のようです。必要な機能を実装するのが非常に難しい理由の詳細については、この投稿をご覧ください。

開発チームは、python-excelgoogleグループでのサポートに優れた仕事をしていることに注意してください。

于 2011-01-14T13:47:00.167 に答える
0

あなたがた!win32comでそれは私のために働きます。

import    win32com.client
Excel = win32com.client.Dispatch("Excel.Application")

# python -m pip install pywin32
file=r'path Excel file'
wb = Excel.Workbooks.Open(file)
sheet = wb.ActiveSheet

#Get value
val = sheet.Cells(1,1).value
# Get Formula
sheet.Cells(6,2).Formula
于 2019-11-28T04:44:37.937 に答える
-1

この投稿が少し遅れていることは知っていますが、ここで取り上げられていない提案が1つあります。ワークシートからすべてのエントリを切り取り、特別な貼り付け(OpenOffice)を使用して貼り付けます。これにより、数式が数値に変換されるため、追加のプログラミングは必要ありません。これは、小さなワークブックに適したソリューションです。

于 2013-07-27T13:10:14.367 に答える