Seite 1 von 1

Suchen in Excel 2002, seltsames Phänomen

Verfasst: Dienstag 31. Januar 2006, 11:15
von N317V
Ahoi zusammen!

Unten stehende Methode macht mir Kummer. Beim Suchen im gesamten Arbeitsblatt werden korrekte Werte für die letzte Zelle zurück gegeben. Ebenso, wenn der Bereich bis ganz nach rechts geht (Spalte IV). Wenn der zu durchsuchende Bereich aber z.B. nur bis IN geht wird mir immer ein Spaltenwert zu wenig angegeben, also IM. Der Bereich wird angegeben in der Form 'A1:IR50'. Irgendwer ne Idee? Was überseh ich?

TIA

Greetings!

Code: Alles auswählen

    def findLastCell(self, bereich=None):
        """Findet die letzte Zeile im übergebenen Bereich oder im ganzen aktiven Blatt.
        
        Gibt ein Dictionary zurück mit der Spalte und der Zeile der letzte Zelle."""
        found = {}
        start = ''
        if type(bereich) == types.NoneType: # gesamtes Arbeitsblatt! Sollte eigentlich so funktionieren wie in Excel 97!
            letzteZelle = self.sheet.Cells.SpecialCells(self.constants.xlCellTypeLastCell)
            return {'Spalte':letzteZelle.Column, 'Zeile':letzteZelle.Row}
        else: # nur bestimmter Bereich
            matrix = self.readMatrix(bereich)
            imax = xrange(len(matrix))
            for i in imax:
                jmax = xrange(len(matrix[i]))
                for j in jmax:
                    if type(matrix[i][j]) == types.NoneType:
                        continue
                    else:
                        found['Spalte'] = i
                        found['Zeile'] = int(j)
            for i in bereich:# bestimmen der ersten Zelle im Bereich
                if i == ':':
                    break
                else:
                    start += i
            x = [e for e in start if e in ascii_uppercase] # x-Koordinate der ersten Zelle im Bereich
            y = [e for e in start if e in digits] # y-Koordinate der ersten Zelle im Bereich
            found['Spalte'] += self.xlIndex2Number(''.join(x)) # Hinzufügen des gefundenen x-Wertes zu dem der ersten Zelle
            found['Zeile'] += int(''.join(y)) # Hinzufügen des gefundenen y-Wertes zu dem der ersten Zelle
            return found

Verfasst: Dienstag 31. Januar 2006, 12:53
von helmut
Hallo N317V,

nachfolgend ein Zitat aus "Excel programmieren" (Addison-Wesley Verlag, (c) 2002, Michael Kofler, Fuer Excel 2000 und 2002), das das genannte Fehlverhalten eventuell erklaert:
Die Methoden SpecialCells und CurrentRegion funktionieren nicht, wenn sie bei der Ausfuehrung selbst definierter Tabellenfunktionen auftreten. Anstatt die Methoden einzusetzen, muessen sie deren Funktion durch Schleifen nachbilden, was bei der Programmierung muehsam und in der Ausf�hrung langsam ist. .....
Gruss Helmut

Verfasst: Dienstag 31. Januar 2006, 13:04
von N317V
Danke schonmal! Zumindest erklärt es, warum ich das überhaupt mach. In Excel 97 ging das nämlich einfach so. Warum mein Zähler aber eins zu wenig zählt ist mir aber ein Rätsel. Tatsächlich ist es auch so, wie in dem Zitat geschrieben, dass das Ding reichlich langsam ist. Das ist aber mein geringstes Problem, solange das Ganze nicht zuverlässig läuft.

Verfasst: Dienstag 31. Januar 2006, 15:48
von N317V
Ich nochmal! Konnte das Problem an einer anderen Methode festmachen. Aber auch da hab ich einen Denkfehler, den ich grad einfach nicht finde.

Code: Alles auswählen

    def columnIndex4xl(self, colnumber):
        """Rechnet eine Spaltenzahl in einen Excel-Index für die Spalte, gibt z.B. für 44 den Wert AR zurück."""
        x = colnumber / 26.0
        x1 = int(x)
        x2 = int((x - x1)*26)
        x1Letter = ascii_uppercase[x1-1]
        x2Letter = ascii_uppercase[x2-1]
        if x1Letter == 'Z':
            x1Letter = ''
        return x1Letter + x2Letter
Geht super bei 44 -> AR, aber für 53 bringt es den Index 'BZ'. Irgendwas scheint am x2-1 nicht zu stimmen...

Verfasst: Dienstag 31. Januar 2006, 16:48
von helmut
Hallo N317V,

mein Vorschlag:

Code: Alles auswählen

x1 = int((colnum-1)/26
x2 = (colnum-1)%26+1
if x1 != 0:
    x1letter = chr(x1+64)
else:
    x1letter = ''
x2letter = chr(x2+64)
Gruss Helmut

Verfasst: Dienstag 31. Januar 2006, 17:08
von N317V
In der ersten Zeile fehlt die letzte schließende Klammer, aber ansonsten kann ich nicht meckern. :-) Danke schön!

Verfasst: Dienstag 31. Januar 2006, 17:35
von helmut
Hallo N317V,

ok, hast eine Klammer gut.

Es besteht noch eine weitere Moeglichkeit, die Adresse im "A1"-Stil zu bekommen. Die Range, Cells, ... -Objekte haben die Eigenschaft "Address".
Im folgenden Beispiel wird die Adresse der "ausgewaehlten Zelle" in die Zelle A1 geschrieben.

Code: Alles auswählen

Cells(1, 1).Value = Selection.Address(ReferenceStyle:=xlA1, rowabsolute:=False, columnabsolute:=False)
Die Spaltenbezeichnung kann dann herausgezogen werden.

Gruss Helmut