Suchen nach nächst kleinerer Zahl?

Antwort erstellen


BBCode ist eingeschaltet
[img] ist ausgeschaltet
[url] ist eingeschaltet
Smileys sind ausgeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: Suchen nach nächst kleinerer Zahl?

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Mo, 24.03.2025 16:01

Damit ihr mal seht wie ein Benutzerfreundliches modernes interaktives Werkzeug ( Jupyter-notebook ) im Vergleich zur »BÄHSICK«-IDE aussieht:
Dateianhänge
20250324_18h03m03s_grim.png
20250324_18h03m03s_grim.png (82.85 KiB) 2855 mal betrachtet

Re: Suchen nach nächst kleinerer Zahl?

von MT326 » Mo, 24.03.2025 15:07

Faszinierend....
wie das auf einmal aussieht wenn jemand programmiert anstatt zu basteln.
meine Hochachtung...
Zu deinen Bedenken wegen dem ZählenWenn.
Sicherer ist auf jeden Fall >= aber die Zahlen in Tabelle 2 sind Artikelnummern die nur einmal vorkommen dürfen.
Gruß MT

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Mo, 24.03.2025 14:27

Ich hab das nochmal etwas angepasst und an das Ereignis »Inhalt geändert« von Tabelle3 gebunden:

Code: Alles auswählen

from bisect import bisect_left

def search_and_select(event):    
    if not event.AbsoluteName.endswith("$D$2"):
        return
    nummer = event.Value
    if not nummer:
        return    
    doc = XSCRIPTCONTEXT.getDocument()
    tab_2 = doc.Sheets[1]
    tab_3 = event.Spreadsheet
    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] )
Zum Testen:
Artikelnummer_suche.ods
(16.89 KiB) 127-mal heruntergeladen

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Mo, 24.03.2025 11:05

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] )

Re: Suchen nach nächst kleinerer Zahl?

von MT326 » Mo, 24.03.2025 09:46

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

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » So, 23.03.2025 21:51

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!

Re: Suchen nach nächst kleinerer Zahl?

von MT326 » So, 23.03.2025 14:51

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

Re: Suchen nach nächst kleinerer Zahl?

von mikeleb » So, 23.03.2025 13:06

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.

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Do, 20.03.2025 12:05

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.

Re: Suchen nach nächst kleinerer Zahl?

von MT326 » Do, 20.03.2025 11:09

Hallo Karolus,
Vielen Dank nochmal....
Es funktioniert.
Verstehe aber die Funktion noch nicht warum es funktioniert.
Gruß MT

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Mi, 19.03.2025 20:39

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

Re: Suchen nach nächst kleinerer Zahl?

von MT326 » Mi, 19.03.2025 18:27

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

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Mi, 19.03.2025 15:41

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])

Re: Suchen nach nächst kleinerer Zahl?

von MT326 » Mi, 19.03.2025 15:03

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

Re: Suchen nach nächst kleinerer Zahl?

von Karolus » Mi, 19.03.2025 10:47

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))

Nach oben