Suchen in Excel 2002, seltsames Phänomen

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.
Antworten
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
helmut
User
Beiträge: 57
Registriert: Mittwoch 2. November 2005, 07:45
Wohnort: Dormagen

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
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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.
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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...
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
helmut
User
Beiträge: 57
Registriert: Mittwoch 2. November 2005, 07:45
Wohnort: Dormagen

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
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

In der ersten Zeile fehlt die letzte schließende Klammer, aber ansonsten kann ich nicht meckern. :-) Danke schön!
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
helmut
User
Beiträge: 57
Registriert: Mittwoch 2. November 2005, 07:45
Wohnort: Dormagen

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
Antworten