Simples Sortier-Makro gesucht

Hallo, ich hoffe ihr könnt einem Anfänger mit Brett vorm Kopf helfen.

Ich habe eine Calc Tabelle, in die per Dialog Daten eingetragen werden. Ich möchte die Daten nach jeder Eingabe alphabetisch sortiert bekommen.
Es handelt sich um eindimensionale Ranges, also Zeilenabschnitte, die demnach in horizontaler Richtung sortiert werden müssten.
Die betreffenden ranges kann ich mit GetCellRangeByPosition… abfragen, und dann komme ich nicht weiter.

Publique uma amostra do arquivo; isso facilitará a elaboração de sugestões.


Poste ein Beispiel der Datei; das erleichtert es, Vorschläge zu machen.

1 Like

snippet

Hier ist ein Beispiel. Meine Dialogbox fragt nach neuen Strings (z.B. diese ABBB,BBBA,CCDD usw.) Mein Makro rechnet aus, in welche Reihe sie gehören und trägt sie dann nebeneinander dort ein, in der Reihenfolge, in der sie eingegeben werden, immer in das nächste freie Feld.
Ich hätte gerne, dass die Felder nach der Eingabe eines neuen Strings alphabetisch sortiert werden, und zwar nur in derselben Zeile. Ich brauche nur eine Sortierfunktion, in den die Subroutine den zu bearbeitenden Bereich eingeben kann.
Ich kenne die Syntax nicht, irgendwas wie:

SortierRange = ThisComponent.Sheets(0).getCellRangeByPosition(3,X, 3+AnzahlStrings,X)
SortierRange.sort(horizontal=1)

sozusagen.

Es würde uns allen die Arbeit erleichtern, wenn du statt Prosa plus Screenshot, das tatsächliche Calc-dokument inclusive Dialog und Makrocode hochladen würdest! Danke.

2 Likes

Gematrikulator Libre test.ods (35.6 KB)
Ich hoffe, der Download funktioniert.
Ich habe inzwischen versucht, aus einem aufgezeichneten Makro einen Sortiercode zu basteln.
Es gibt nur ein Module1 und einen Dialog. Die Sortierfunktion steht ganz am Ende des Moduls.

Bisher funktioniert es noch nicht. Es wird zwar der richtige Bereich ausgewählt, der sortiert werden soll, aber dann passiert nichts weiter.
Außerdem wird, sobald ein oben oder unten angrenzendes Feld ausgefüllt ist, ein Dialog eingeblendet, mir der Frage, ob ich den Sortierbereich erwitern möchte, was natürlich unnötig ist.
Am liebsten würde ich es sowieso ganz ohne Dispatcher machen, aber damit bin ich bisher am weitesten gekommen.

Ps: Der Dialog ist noch nicht vernünftig beschriftet. Die neuen Strings sollen in das oberste Textfeld und werden mit dem Button bestätigt. Die anderen Textfelder sind Ausgabefelder.
Sorry, dass ich nicht gleich die Datei hochgeladen habe.

Hallo
Die »Arbeits-logik« in python:

import re
from string import punctuation

rex = re.compile(rf'\s(\s+)|[§{re.escape(punctuation)}]+')


def dump_data( raw ):
    clean = rex.sub("", raw).upper() 
    no_space = clean.replace(" ","")
    
    try:
        i_row = int(raw)
    except ValueError:
        ordinals = map(ord, no_space )
        i_row = sum(x-48 if x<58 else x-55 for x in ordinals )     
    
    doc = XSCRIPTCONTEXT.getDocument()
    sheet = doc.Sheets.Tabelle1
    the_row = sheet[i_row,4:]
    data = set(filter(None,the_row.DataArray[0]))
    data.add(clean)
    data = sorted(data)
    the_row[0,:len(data)].DataArray = [data]

def main( event ):       
    source = event.Source
    context = source.getAccessibleContext()
    parent = context.getAccessibleParent()    
    input_box = parent.getAccessibleChild(1)
    raw_text = input_box.getText()
    dump_data( raw_text )

Das TestDokument mit eingebettetem python-code
Gematrikulator_python.ods (34.8 KB)

Ich hab die umlaute vergessen, neue Version:

import re
from string import punctuation

rex = re.compile(rf'(\s)(\s+)|([§{re.escape(punctuation)}äöüßÄÖÜ])')

def repl( match ):
    umldict = {'ä':'AE',
               'ö':'OE',
               'ü':'UE',
               'ß':'SS'}
    return umldict.get(match.group().lower(), "")

def dump_data( raw ):
    clean = rex.sub(repl, raw).upper() 
    no_space = clean.replace(" ","")
    
    try:
        i_row = int(raw)
    except ValueError:
        ordinals = map(ord, no_space )
        i_row = sum(x-48 if x<58 else x-55 for x in ordinals )     
    
    doc = XSCRIPTCONTEXT.getDocument()
    sheet = doc.Sheets.Tabelle1
    the_row = sheet[i_row,4:]
    data = set(filter(None,the_row.DataArray[0]))
    data.add(clean)
    data = sorted(data)
    the_row[0,:len(data)].DataArray = [data]

def main( event ):       
    source = event.Source
    context = source.getAccessibleContext()
    parent = context.getAccessibleParent()    
    input_box = parent.getAccessibleChild(1)
    raw_text = input_box.getText()
    dump_data( raw_text )

Gematrikulator_python_2.ods (35.7 KB)

Ok, danke.