Suchen nach nächst kleinerer Zahl?

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Hallo erst mal...
Ich hab mir ein Makro gebastelt das mit searchdescriptor in einer Spalte nach Zahlen sucht.
und wenn vorhanden der Corsur dann zu dieser Zelle springt.
Das funktioniert auch.
Jetzt wollte ich gerne noch einbauen das wenn die Zahl nicht vorhanden ist,
der Corsur zur nächst kleineren Zahl springt.
Zahlenreihe:
100
110
150
200
also bei Eingabe von 115 soll er zur Zelle mit der 110 springen.
Da der searchdescriptor soweit ich weiß nur nach Strings sucht geht sowas überhaupt?
Und wenn ja wie?
Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

MT326 hat geschrieben: Di, 18.03.2025 10:26
Jetzt wollte ich gerne noch einbauen das wenn die Zahl nicht vorhanden ist,
der Corsur zur nächst kleineren Zahl springt.
Zahlenreihe:
100
110
150
200
also bei Eingabe von 115 soll er zur Zelle mit der 110 springen.
Da der searchdescriptor soweit ich weiß nur nach Strings sucht geht sowas überhaupt?
Und wenn ja wie?
Gruß MT
Du wolltest :lol:
… dann wenigstens mal deinen vorhandenen Code zeigen, oder glaubst du wir helfen per Glaskugel?

Zum Glück geht das ganz einfach per Formel (zumindest solange die Zahlen aufsteigend sortiert sind):

Code: Alles auswählen

=HYPERLINK("#A" & VERGLEICH($D$2;A:A) )
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Sorry hab vergessen den Code zu posten.
hier mein Makro:

Sub Artikelnummer_Suchen

sArtikel=Inputbox("Artikelnummer Suchen")

odoc = thiscomponent
oSheet = odoc.currentcontroller.activesheet.getCellRangeByPosition( 1, 0, 1, 101 )
oSearchDescriptor = oSheet.createSearchDescriptor()
oSearchDescriptor.Searchstring = sArtikel
oSearchDescriptor.SearchWords = True
oFound = oSheet.FindFirst(oSearchDescriptor)
odoc.CurrentController.Select(oFound)

End Sub

Die Zahlenreihe ist aufsteigend sortiert.

Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

Hallo

Was spricht dagegen zB. die oberste Zeile zu fixieren ( ⇒ Ansicht ⇒ Zellen fixieren ⇒ Erste Zeile fixieren ) um dann in D1 die »Suchnummer« einzugeben und daneben in C1 ctrl+klick auf die dort bereits vorhandene Hyperlinkformel:

Code: Alles auswählen

=HYPERLINK("#B" & VERGLEICH(D1; B1:B1000))
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Hallo Karolus

Ich wollte es gerne in einem Makro lösen,
habe aber keine Idee wie ich die nächst kleinere Zahl
ermitteln kann.

Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

MT326 hat geschrieben: Mi, 19.03.2025 15:03 Ich wollte es gerne in einem Makro lösen,
Gruß MT
Warum, irgendwie muss es ja ausgeführt werden (Button? Shortcut?), und um eine Eingabe der Nummer kommst du auch nicht drumdrum!?

wie auch immer:

Achtung python und du benötigst auch Libreoffice

Code: Alles auswählen

from bisect import bisect_left
import scriptforge as sf
bas = sf.CreateScriptService("BASIC")

def jump_to(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    ctrl = doc.CurrentController
    search_range = ctrl.ActiveSheet["B1:B3000"]
    search_data = tuple(zip(*search_range.DataArray))[0]
    position = bisect_left(search_data, int( bas.InputBox("welche Nummer _?:") ) )
    try:
        ctrl.select(search_range[position-1])
    except KeyError:
        ctrl.select(search_range[0])
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Hallo Karolus
Vielen Dank für deine Mühe.
Ich suche aber eine Lösung für Basic die ich in ein bestehendes Makro einbauen kann.
Mir fehlt der logische Ansatz wie ich die nächst kleinere Zahl finden kann.
Nochmal Danke vielleicht find ich noch irgendwas...
Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

Code: Alles auswählen

Sub jump
    doc = thisComponent
    fa = createUnoService("com.sun.star.sheet.FunctionAccess")
    ctrl = doc.CurrentController
    sheet = ctrl.ActiveSheet
    arr = sheet.getCellRangeByName("B1:B1000")
    num = int(inputbox("Welche Zahl:_"))
    position = fa.callFunction("match", array(num, arr))

    cell = sheet.getCellByPosition(1,position-1)
    'oder 
    'cell = sheet.getCellRangeByName("B" & position )
    ctrl.select(cell)
        
End Sub
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Hallo Karolus,
Vielen Dank nochmal....
Es funktioniert.
Verstehe aber die Funktion noch nicht warum es funktioniert.
Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

Hallo
Steht doch alles da!
fa ist ein Service der den Zugriff auf normale calc-funktionen erlaubt.

Der Zugriff selbst muss mit englischen Funktionsnamen in dieser seltsamen Syntax|Grammatik erfolgen.

Code: Alles auswählen

fa.callFunction("match", array(num, arr))
Das entspricht der Calc-formel:

Code: Alles auswählen

=MATCH( num ; B1:B1000) # englisch
oder auf deutsch
=VERGLEICH( num ; B1:B1000) # deutsch
diese Formel hab ich dir ja schon weiter oben als Teil der HYPERLINK-formel vorgeschlagen.
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
mikeleb
*******
Beiträge: 1400
Registriert: Fr, 09.12.2011 16:50

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von mikeleb »

Hallo,
Ich suche aber eine Lösung für Basic die ich in ein bestehendes Makro einbauen kann.
Vielleicht verrätst du uns, was du insgesamt vorhast, dann lässt sich das Detailproblem vielleicht effektiver lösen.
Gruß,
mikeleb
MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Ich hab es hinbekommen.
Danke für eure Mühe.
Mir war nur nicht bewusst das man mit der Vergleich funktion auch ungenau suchen kann.
Deswegen war ich irritiert das es funktioniert hat.
Bin halt kein Profi.
Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

MT326 hat geschrieben: So, 23.03.2025 14:51 Mir war nur nicht bewusst das man mit der Vergleich funktion auch ungenau suchen kann.
Deswegen war ich irritiert das es funktioniert hat.
Ich hab dir gleich zu Anfang zweimal gezeigt wie das per HYPERLINK plus VERGLEICH geht!
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
MT326
**
Beiträge: 20
Registriert: Mi, 28.08.2024 09:24

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von MT326 »

Hallo mikeleb,
Ich habe mir vor geraumer Zeit eine Lieferübersicht gebastelt.
In Tabelle 2 sind Artikelnummern in Tabelle 3 gebe ich dann die Lieferungen ein.
Jetzt habe ich mir ein Makro gebastelt das:
1. prüft ob die Artikelnummer schon da ist (tabelle 3)
wenn ja springt der Cursor zu dieser Nummer
2. prüft ob es die Artikelnummer gibt (tabelle 2),
wenn nicht springt der Cursor zur nächst kleineren Artikelnummer in Tabelle 2
3. wenn die Nummer nicht da ist sie in Tabelle 3 einfügt.

Das geht bestimmt auch eleganter als ich es gemacht habe, aber dank eurer Hilfe funktioniert es.
Hier mein Makro:

Sub Artikelnummer

Dim oZielzelle As Object

sArtikel=Inputbox("Artikelnummer")

odoc = thiscomponent
oSheet = odoc.currentcontroller.activesheet.getCellRangeByPosition( 1, 0, 1, 101 )
oSearchDescriptor = oSheet.createSearchDescriptor()
oSearchDescriptor.Searchstring = sArtikel
oSearchDescriptor.SearchWords = True
oFound = oSheet.FindFirst(oSearchDescriptor)
odoc.CurrentController.Select(oFound)

if oFound is Nothing then

oFunctionAccess = createUnoService("com.sun.star.sheet.FunctionAccess")

oXCellRange = thiscomponent.Sheets(1).getCellRangeByName("a2:a450")

Dim args( 1 ) As Variant
args(0) = oXCellRange
args(1) = sArtikel
result = oFunctionAccess.callFunction( "COUNTIF", args() )


if result = 1 then

oView = oDoc.CurrentController
oTab=ThisComponent.Sheets(2)
'Ermittlung der ersten freien Zeile in Spalte b
nZeile=oTab.Columns(1).queryEmptyCells.RangeAddresses(0).startrow
oZielzelle = oTab.getCellByPosition(1,nZeile)
oView.Select(oZielzelle)
oZielzelle.value = sArtikel

else

doc = thisComponent
fa = createUnoService("com.sun.star.sheet.FunctionAccess")
ctrl = doc.CurrentController
sheet = doc.Sheets(1)
arr = sheet.getCellRangeByName("a1:a450")
num = int(sArtikel)
position = fa.callFunction("match", array(num, arr))

cell = sheet.getCellByPosition(0,position-1)
'oder
'cell = sheet.getCellRangeByName("B" & position )
ctrl.select(cell)

end if
else
endif

End Sub

Makro ArtikelnummerTest.ods
Artikelnummer Testdatei
(13.8 KiB) 106-mal heruntergeladen
Vielen Dank nochmal Gruß MT
Karolus
********
Beiträge: 7517
Registriert: Mo, 02.01.2006 19:48

Re: Suchen nach nächst kleinerer Zahl?

Beitrag von Karolus »

Hallo

Deine Logik biegt falsch ab falls die Nummer aus Versehen? mehrmals in Tabelle2 vorkommt:
»if result = 1 then« ⇒ vielleicht? ⇒ »if result >= 1 then«

und in etwas aufgeräumter:

Code: Alles auswählen

Sub Artikelnummer

    sArtikel=Inputbox("Artikelnummer")
    doc = thisComponent
    tab_2 = doc.Sheets(1)
    tab_3 = doc.Sheets(2)
    ctrl = doc.CurrentController
    
    fa = createUnoService("com.sun.star.sheet.FunctionAccess")
 
    search = tab_3.createSearchDescriptor()
    search.Searchstring = sArtikel
    search.SearchWords = True
    oFound = tab_3.FindFirst( search )    

    if oFound is Nothing then        
        oXCellRange = tab_2.getCellRangeByName("a2:a450")
        result = fa.callFunction( "COUNTIF", array(oXCellrange, sArtikel ) )
        if result = 1 Then   ' was passiert falls die Nummer mehrmals vorkommt ??
            'Ermittlung der ersten freien Zeile in Spalte b
            nZeile= tab_3.Columns(1).queryEmptyCells.RangeAddresses(0).startrow
            oZielzelle = tab_3.getCellByPosition(1,nZeile)
            ctrl.Select(oZielzelle)
            oZielzelle.value = sArtikel    
        Else   
            arr = tab_2.getCellRangeByName("a1:a450")
            num = int(sArtikel)
            position = fa.callFunction("match", array(num, arr))
            cell = tab_2.getCellByPosition(0,position-1)
            ctrl.select(cell)    
        end If
    else
        ctrl.Select(oFound)
    end if
End Sub
Und weil es erst mit python richtig schön wird:

Code: Alles auswählen

from bisect import bisect_left

def search_and_select(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    nummer = float(input("welche?: "))
    tab_2 = doc.Sheets[1]
    tab_3 = doc.Sheets[2]
    ctrl = doc.CurrentController
    in_use = tab_3["B:B"].queryContentCells(7)[0].DataArray
    existing_nums = tab_2["A:A"].queryContentCells(7)[0].DataArray
    try:
        pos = in_use.index( (nummer,) )
        ctrl.select( tab_3[pos, 1] )
        return
    except ValueError:
        pos = bisect_left( existing_nums, (nummer,) )        
        if existing_nums[pos][0] == nummer:
            (t:=tab_3[len(in_use),1]).Value = nummer
            ctrl.select( t )
            return
        else:
            ctrl.select( tab_2[pos-1, 0] )
LO7.4.7.2 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.2.1 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)
Antworten