Exceldatei (gefiltert) auslesen & neue Exceldatei schreiben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

Habe noch ein Problem:
Ich möchte in einem Unterordner alle benötigten Quell-Exceldateien ablegen und außerdem vermeiden, einen bestimmten Pfad für mein Hauptverzeichnis anzugeben, sondern der Code soll (egal wo sich mein Hauptordner mit den Modulen befindet und eben dieser Unterordner "Quelldateien") ohne Anpassung des Pfads bei z.B. Kopieren auf einen anderen PC laufen können.

Dafür habe ich folgendes verwendet:

Code: Alles auswählen

import os
pathQuell = 'Quelldateien'
for root, dirs, files in os.walk(pathQuell):
    xlsfiles = [_ for _ in files if _.endswith('xlsx')]
    for xlsfile in xlsfiles:
        file_name = str(xlsfile)
        sheet_name = file_name[:-5]
        quell_sheet =  quell.sheet_by_index(0)
        quell_sheet_filter(quell_sheet)
(quell_sheet_filter ist eine Methode, die mir letztlich pro Datei das gewünschte gefilterte Sheet in die neue Exceldatei schreibt.)

Seltsam hierbei:
- Wenn die Quelldateien nur im Hauptverzeichnis liegen, bleibt die Zieldatei leer.
- Wenn die Quelldateien nur im Unterverzeichnis "Quelldateien" liegen, vermisst PythonScripter diese im übergeordneten Verzeichnis (und zwar genau jene, die im Unterverzeichnis sind).
- Liegen die Dateien in beiden Verzeichnissen, läuft es einwandfrei.

Was kann ich tun, damit ein Vorhandensein der Dateien im Unterverzeichnis ausreichend ist?
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Bei os.walk stehen in files wirklich nur die Dateinamen, ohne Pfad, den mußt Du beim Öffnen der Dateien noch mit angeben: os.path.join(pathQuell,xlsfile).

Der _ als Variablenname sollte wirklich nur dann verwendet werden, wenn die Variable überhaupt nicht gebraucht wird.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

Super, so funktioniert es jetzt - danke:

Code: Alles auswählen

for root, dirs, files in os.walk(pathQuell):
        for xlsfile in files:
            if xlsfile.endswith('.xlsx'):
                quell_path =  os.path.join(pathQuell,xlsfile)
                quell = xlrd.open_workbook(quell_path)
                quell_sheet = quell.sheet_by_index(0)
                file_name = str(xlsfile)
                sheet_name = file_name[:-5]
                quell_sheet_filter(quell_sheet)
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

Du solltest den Pfad zur Datei mit root anstatt pathQuell zusammensetzen. Ansonsten wirst du bei Unterordnern Probleme haben. Wenn du keine hast dann benutze doch os.listdir
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

Danke für den Hinweis.

Nun habe ich leider noch ein Problem, auf das ich keine Antwort finde... ich muss in einigen Spalten Formeln eintragen, die sich auf andere Spalten beziehen (vom Gedanken, auf andere Exceldateien innerhalb der Formel zugreifen zu können habe ich mich erstmal verabschiedet, da das mit xlwt nicht geht, wie ich gelesen habe).

Jedenfalls habe ich das Problem, dass der Zugriff auf Variablen innerhalb der Formel nicht zu funktionieren scheint. Dies benötige ich aber, um für die einzelnen Zeilen "runterzählen" zu können, also z.B. Bezug auf Zelle D2, in der nächsten Zeile dann D3 usw.

So sieht das bisher aus (für das Problem irrelevante Teile entfernt):

Code: Alles auswählen

row_counter = 1
for row in xrange(numRow):
    sheet.write(row_counter, 7, xlwt.Formula('IF("L"+int(row_counter+1)<>"N"+int(row_counter+1);"X";" ")'), style0)]
    row_counter +=1
Gibt es hierfür eine Lösung?
Zuletzt geändert von Remington Steele am Freitag 21. Dezember 2012, 15:44, insgesamt 1-mal geändert.
BlackJack

@Remington Steele: Natürlich kann Excel nicht auf Variablen zugreifen die mal in dem Programm existiert haben, mit denen die Tabelle erstellt wurde. Und es kann auch keinen Python-Quelltext ausführen. Du musst halt eine Zeichenkette mit der Formel erstellen wo die entsprechenden Werte hinein formatiert werden. Also Zeichenkettenformatierung in Python mittels ``%``-Operator oder `format()`-Methode auf Zeichenketten.

Du möchtest vor der Schleife vielleicht auch keinen Vergleich zwischen dem Wert von `row_counter` und 1 anstellen und das Ergebnis davon ignorieren, sondern den Namen `row_counter` an die 1 binden. Wobei die Variable hier total redundant ist. Denk mal über den Wert von `row` nach.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

danke. "row_counter hab ich erst nachträglich hier rein geschrieben und versehentlich == statt = verwendet, aber nicht im eigentlichen Code.
row_counter spielt hier überhaupt keine Rolle, im eigentlichen Code hat er schon seine Berechtigung ;). OK ich werd das mal ausprobieren, wenn ich wieder auf Arbeit bin thx.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

Danke nochmal, hat nun so funktioniert:

Code: Alles auswählen

sheet.write(row_counter, 7, xlwt.Formula('IF(L{}<>'.format(row_counter+1) + 'N{}'.format(row_counter+1) + ';"X";" ")'), style0)
Leider gibt es (weitere Formel) bei dem so umgesetzten SVERWEIS

Code: Alles auswählen

sheet.write(row_counter, 4, xlwt.Formula('VLOOKUP(D{}'.format(row_counter+1) + "; 'C:\Temp\[{}".format(sheet_name) + '_dat.xlsx]' + "Sheet1'!$E$2:$F$352;2;FALSE)"), style0)
die FM "Unknown sheet name", obwohl ich den Pfad mehrfach überprüft habe. Hat jemand eine Idee, woran dies liegen könnte?
Zuletzt geändert von Remington Steele am Donnerstag 27. Dezember 2012, 12:37, insgesamt 1-mal geändert.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

So sieht die FM aus:
Exception: Formula: unknown sheet name C:\Temp\[5346_dat.xlsx]Sheet1
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ein Backslash in einer Zeichenkette leitet eine Escape-Sequence ein. \n ist in Wirklichkeit nur ein Zeichen, nämlich "newline", \r der Wagenrücklauf, \t der Tabulator, ...
Wenn du einen Backslash in einer Zeichenkette verwenden willst, dann maskiere ihn: \\ -> \

Und was ist denn das?

Code: Alles auswählen

'C:\Temp\[{}".format(sheet_name) + '_dat.xlsx]'
Du benutzt schon .format() und stückelst dann doch noch die Zeichenkette mit + zusammen? Warum? Man fährt doch auch nicht die Hälfte der Strecke mit dem Auto weil es einfach ist, und dann den Rest mit dem Fahrrand, weil man schon irgendwie ankommt...
BlackJack

@Remington Steele: Wie kommt man auf die Idee `format()` und ``+`` *so* zu vermischen, wo es einem `format()` doch erlaubt die Zeichenkettenvorlage und die Werte so schön voneinander zu trennen, so dass man die Formel lesen kann ohne im Kopf die ganzen ``+`` und verschiedenen ' und " ”auswerten” zu müssen‽

Code: Alles auswählen

sheet.write(
    row_counter,
    4,
    xlwt.Formula(
        "VLOOKUP(D{0};"
        " 'C:\\Temp\\MK_Preisabgleich\\[{1}_mean.xlsx]Sheet1'"
        "!$E$2:$F$352;2;FALSE)".format(row_counter + 1, sheet_name)
    ),
    style0
)
Wäre das Ergebnis denn überhaupt ein gültiger Arbeitsblattname in Excel? Das sieht mir etwas komisch aus. Insbesondere die Platzierung der eckigen Klammern.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

Hm da habt Ihr recht... wusste nicht, dass man mit {1}, {2} usw. auf mehrere Stellen referenzieren kann.
Wäre das Ergebnis denn überhaupt ein gültiger Arbeitsblattname in Excel?
Ich denke schon, es sieht zumindest genauso aus wie in meinem (korrekten) SVERWEIS der Vorlagedatei.

Obwohl ich den Code nun entsprechend angepasst habe:

Code: Alles auswählen

sheet.write(row_counter, 4, xlwt.Formula("VLOOKUP(D{0}; 'C:\\Temp\\[{1}_dat.xlsx]Sheet1'!$E$2:$F$352;2;FALSE)".format(str(row_counter+1), str(sheet_name))), style0)
kommt weiterhin die Fehlermeldung:
Exception: Formula: unknown sheet name C:\Temp\[5346_dat.xlsx]Sheet1
Was ist denn da nur los? :(

Am Rande - auch wenn das Blatt "Tabelle1" in meiner Excel heisst, muss ich natürlich das englische "Sheet1" angeben, das ist schon korrekt oder? Mit Tabelle1 habe ich es auch schon probiert, hat das Problem nicht beseitigt.
BlackJack

@Remington Steele: Wenn das Arbeitsblatt bei Dir 'Tabelle1' heisst, dann musst Du das natürlich auch über diesen Namen referenzieren. Welche Software dachtest Du denn würde diese Übersetzung von dem Namen für Dich von Englisch nach Deutsch erledigen?

Die `str()`-Aufrufe in `format()` kannst Du Dir sparen.

Bist Du überhaupt sicher das `xlwt` das Referenzieren von anderen Dateien in Formeln unterstützt. Ich hätte da so den Verdacht, dass es das nicht tut.
Remington Steele
User
Beiträge: 51
Registriert: Donnerstag 22. November 2012, 21:50

Hi BlackJack, das mit den strs war nur ein verzweifelter zusätzlicher Versuch, der wie Du ja angemerkt hast nichts bringt (hab die inzwischen schon wieder entfernt).
BlackJack hat geschrieben:Bist Du überhaupt sicher das `xlwt` das Referenzieren von anderen Dateien in Formeln unterstützt. Ich hätte da so den Verdacht, dass es das nicht tut.
*Major facepalm* Genau das habe ich neulich selbst gelesen! So ist es nämlich! Danke für den Hinweis... werde versuchen, auf ein Sheet innerhalb der Datei zuzugreifen.
Antworten