🙏 Bitte helfen Sie uns das LibreOffice Forum zu erhalten. 🙏
Ihre Spende wird für die Deckung der laufenden Kosten sowie den Erhalt und Ausbau 🌱 des LibreOffice Forums verwendet.

🍀 Wir hoffen auf Ihre Unterstützung - vielen Dank!🍀

❤️ DANKE >> << DANKE ❤️

>> Dank Ihrer Unterstützung -> Keine Werbung für alle registrierten LibreOffice-Forum User! <<
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗

[Gelöst] Verwenden von Calc-Funktionen in LO-Basic

Alles zur Programmierung im LibreOffice.
Antworten
Proma
Beiträge: 37
Registriert: Di 24. Sep 2024, 16:53

[Gelöst] Verwenden von Calc-Funktionen in LO-Basic

Beitrag von Proma » Fr 24. Jan 2025, 10:46

Hallo liebe Experten,
Michael Dannenhöfer zeigt in seinem Werk "StarBasic / OpenOffice.org Basic FAQ" unter Ziffer 7.5.7 ein für mich sehr interessantes Beispiel für die Funktion LCM (errechnet das kleinste gemeinsame Vielfache - KGV), wie man die eingebauten "Worksheet-Funktionen" von Calc auch in Star-Basic (und hoffentlich auch in LO-Basic?) verwenden kann.
Nun habe ich mir eine kleine Prozedur gebastelt, mit deren Hilfe ich auch andere Funktionen aus Calc nützen kann; das funktioniert zwar bei LCM, aber schon bei der Function SUM (Summe bilden) bin ich kläglich gescheitert.

Code: Alles auswählen

Private Sub Demo_pCalcFunctions()
  MsgBox pCalcFnc("LCM", "8;4;12")                              'KGV   (kleinstes gemeinsames Vielfaches) klappt
  MsgBox pCalcFnc("SUM", "8;4;12")                              'SUMME (Summe aus übergebenen Werten)     Fehler
  MsgBox pCalcFnc("SUM", "$A$2:$A$4")                           'SUMME (Summe aus übergebenem Bereich)    Fehler
  MsgBox pCalcFnc("SUM", "$Tabelle6.$A$2:$A$4")                 'SUMME (Summe aus übergebenem Bereich)    Fehler
End Sub

Private Function pCalcFnc(ByVal strFnc As String, _
                          ByVal strArg As String) as Variant
                          
  Const strSvc  As String = "com.sun.star.sheet.FunctionAccess" 'Service für den Zugriff auf die Calc-Funktionen
  Dim varArgs() As Variant                                      'Array für die zu übergebenden Parameter
  Dim objFncAcs As Object                                       'Objekt für den Zugriff auf die Calc-Funktionen

  varArgs() = Split(strArg, ";")                                'Parameter in Array schreiben
  objFncAcs = createUnoService(strSvc)                          'Service starten
  pCalcFnc = objFncAcs.callFunction(strFnc, varArgs())          'Funktion aufrufen und Resultat zurückgeben
End Function
In der letzten Code-Zeile wird die Verarbeitung abgebrochen mit dieser Fehlermeldung:
< BASIC- Laufzeitfehler.
< Es ist eine Ausnahme aufgetreten
< Type: com.sun.star.lang.IllegalArgumentException
< Message: at
< C:/cygwin64/home/buiIdslave/source/libo-core/sc/source/ui/unoobj/funcuno.cxx:648

Ist speziell dieser Code von Dannenhöfer grundsätzlich für LO-Basic nicht oder nicht mehr geeignet oder habe ich etwas falsch verstanden oder einfach nur einen Wurm hineingebracht?

Vielleicht gibt es auch eine aktuellere Version für den Zugriff auf die Calc-Funktionen? Ich bin für jede Hilfe dankbar!

Meine Ausstattung:
Windows 11, LibreOffice 24.2.6.2 (X86_64)

Vorab schon recht herzlichen Dank für die Unterstützung und liebe Grüße
vom Martin
Zuletzt geändert von Proma am Mo 27. Jan 2025, 13:03, insgesamt 1-mal geändert.

mikele
* LO-Experte *
Beiträge: 1929
Registriert: Mo 1. Aug 2011, 20:51

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von mikele » Fr 24. Jan 2025, 12:23

Hallo,
an sich ist das alles schon richtig. Die spannende Frage ist bei jeder einzelnen Funktion, in welcher Form die Parameter übergeben werden müssen. Ich bin mir nicht sicher, ob es da eine allgemeingültige Aussage gibt.
LCM kann offensichtlich mit einem Array von Strings umgehen.

Code: Alles auswählen

ergebnis=objFncAcs.callFunction("LCM", array("3","4","5"))
funktioniert.
Bei der Summe geht es schief:

Code: Alles auswählen

ergebnis = objFncAcs.callFunction("SUM", array("3","4","5"))
Mit einem Array von Zahlen funktioniert es

Code: Alles auswählen

ergebnis = objFncAcs.callFunction("SUM", array(3,4,5))
Mit Zellbereichen geht es auch:

Code: Alles auswählen

bereich=thiscomponent.sheets(0).getcellrangebyname("$A$5:$c$5")
  ergebnis=objFncAcs.callFunction("SUM", array(bereich))
Es wird also darauf hinauslaufen, die details jeder einzelnen Funktion auszuprobieren (insbesondere wie robust sie gegenüber den Argumenten sind).
Gruß,
mikele

Proma
Beiträge: 37
Registriert: Di 24. Sep 2024, 16:53

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von Proma » Fr 24. Jan 2025, 14:03

Hallo mikele,

vielen Dank für Deine Nachricht!
Das klingt interessant und spannend, aber auch nach Arbeit! :D
Ich mach mich mal drüber und berichte dann wieder (kann aber schon etwas dauern...).

Liebe Grüße
vom Martin

mikele
* LO-Experte *
Beiträge: 1929
Registriert: Mo 1. Aug 2011, 20:51

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von mikele » Fr 24. Jan 2025, 16:49

Hallo,
interessanterweise liefert

Code: Alles auswählen

=KGV("3";"4")
das Ergebnis 12, wohingegen

Code: Alles auswählen

=SUMME("3";"4")
zu einem Fehler führt.
Insofern ist der Funktionsaufruf in Basic mit dem in Calc konsistent. (Wobei wir uns darüber einig sind, dass niemand den Funktionsaufruf nutzen wird, um 3+4 zu rechnen :lol: )
Gruß,
mikele

Proma
Beiträge: 37
Registriert: Di 24. Sep 2024, 16:53

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von Proma » Fr 24. Jan 2025, 17:43

Hallo mikele,

ja, das deckt sich mit meinen (bislang noch recht bescheidenen) Erfahrungen auf diesem Gebiet! Lass' doch z.B. mal diese Sub laufen, schau' Dir das Ergebnis an und staune:

Code: Alles auswählen

Private Sub pCalcFnc_2()
  Const strSvc  As String = "com.sun.star.sheet.FunctionAccess" 'Service für den Zugriff auf die Calc-Funktionen
  Dim strFnc    As String
  Dim varArgs(0) As Variant                                      'Array für die zu übergebenden Parameter
  Dim objFncAcs As Object                                       'Objekt für den Zugriff auf die Calc-Funktionen
  
  strFnc = "EASTERSUNDAY"
  varArgs(0) = 2025
  
  objFncAcs = createUnoService(strSvc)                          'Service starten
  MsgBox Date(objFncAcs.callFunction(strFnc, varArgs()))        'Funktion aufrufen und Resultat zurückgeben
End Sub
Nach dieser Berechnung wäre der Ostersonntag schon heute. Frohe Ostern! :D
Woran mag das liegen? Gibt es eine aktuellere Variante, die Calc-Funktionen für Berechnungen in LO-Basic zu verwenden?
Falls JA, lass' es mich bitte wissen.

Schönes Wochenende und liebe Grüße
vom Martin (und auch vom Osterhasen)

Benutzeravatar
karolus
* LO-Experte *
Beiträge: 2533
Registriert: Fr 10. Dez 2010, 10:01

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von karolus » Fr 24. Jan 2025, 18:05

Code: Alles auswählen

MsgBox Date(objFncAcs.callFunction(strFnc, varArgs()))
Der Laufzeitfunktion »Date« kannst du alles mögliche als Argument übergeben, zurückgeben wird sie trotzdem immer das aktuelle Datum

Code: Alles auswählen

MsgBox format(objFncAcs.callFunction(strFnc, varArgs())  ,"yyyy-mm-dd")  
LO7.4.7.5 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.0.3 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)

Proma
Beiträge: 37
Registriert: Di 24. Sep 2024, 16:53

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von Proma » Fr 24. Jan 2025, 19:18

Hallo karolus,

oops, da hast Du natürlich Recht - ich bin einfach überarbeitet und brauche jetzt dringend ein Wochendende! Vielleicht teste ich als nächstes die WORKDAY-FunKtion! :D

Danke für den Hinweis, allseits ein schönes Wochenende und liebe Grüße
vom Martin

Proma
Beiträge: 37
Registriert: Di 24. Sep 2024, 16:53

Re: Verwenden von Calc-Funktionen in LO-Basic

Beitrag von Proma » Mo 27. Jan 2025, 12:55

Hallo liebes Forum, Wissende und Suchende,

Dank der nimmermüden Unterstüzung durch die Experten dieses Forums ist es mir wieder einmal gelungen, eine Frage zu klären; nun ist es mir möglich, Calc-interne Funktionen per Makro (LO-Basic) aufzurufen. Und weil so ein Forum nicht zuletzt auch von den Rückmeldungen seiner Mitglieder lebt, stelle ich das Ergebnis meiner Bastelei einfach mal hier ein.

Vielen Dank an allle, die mich hier - nicht nur bei dieser Anfrage - mit ihrem Wissen und ihrer Erfahrung unterstützt haben! Ihr seid einfach großartig!

Liebe Grüße
vom Martin

Code: Alles auswählen

Private Sub Demo_pCalcFnc()
' Calc-Funktionen mit LO-Basic aufrufen
  
  Dim v      As Variant                                         'Der zu erwartende Rückgabewert
  Dim strFnc As String:  strFnc = "edate"                       'Name der Funktion
  Dim strArg As String:  strArg = "24.03.2025;-3"               'Funktions-Argumente (mehrere Args durch ";" trennen)
  Dim bolDtm As Boolean: bolDtm = True                          'TRUE=Rückgabewert anzeigen als TRUE=Datum  FALSE=Zahl

  v = pCalcFnc(strFnc, strArg)                                  'Rufe die Funktion auf (v=Rückgabewert)
  If bolDtm = True Then v = Format(v, "dd.MM.yyyy")             'Ggf. Rückgabewert als Datum formatieren
  MsgBox v                                                      'Rückgabewert anzeigen
End Sub


Private Function pCalcFnc(ByVal strFnc As String, _
                          ByVal strArg As String, _
                 Optional ByVal bolDtm As Boolean) As Variant

' Ruft eine Calc-interne Funktion mit den benötigten
' Argumenten auf. Wird als Rückgabewert ein Datum erwartet,
' sollte der Schalter bolDtm auf TRUE gesetzt werden.
' !!  ACHTUNG  !! Makro befindet sich noch in der Test-Phase

' Parameter:
' strFnc               Name der aufzurufenden Funktion. !!  ACHTUNG  !!  Bitte immer den ENGLISCHEN Nsamen verwenden!
' strArg               String mit den Argumenten. Mehrere Argumente durch Strichpunkt (;) trennen.
' bolDtm    [Optional] Weil viele Funktionen kein Datum sondern dessen Index zurückgeben, erscheint es mir sinnvoll,
'                      in solchen Fällen die Umrechnung in ein Datum gleich hier in dieser Function vorzunehmen.
'                      TRUE=Zurückgegebener Wert wird in Datum umgewandelt   FALSE=Es erfolgt keine Umwandlung
'                      Standard=FALSE
'
' Rückgabe:            Rückgabewert der Calc-Funktion

  Const strSvc  As String = "com.sun.star.sheet.FunctionAccess" 'Service für den Zugriff auf die Calc-Funktionen
  Dim i         As Integer                                      'Incdex-Variable
  Dim v         As Variant                                      'Rückgabewert
  Dim varArgs() As Variant                                      'Array für die zu übergebenden Parameter
  Dim objFncAcs As Object                                       'Objekt für den Zugriff auf die Calc-Funktionen

  If IsMissing(bolDtm) Then bolDtm = False                      'Standard-Wert für bolDtm festlegen

' ARGUMENTE IN ARRAY SCHREIBEN
  varArgs() = Split(strArg, ";")                                'Parameter in Array schreiben (Problem bei Zahlwerten)
  For i = 0 To Ubound(varArgs())                                'Schleife durch alle Argumente
    If Not IsDate(varArgs(i)) And IsNumeric(varArgs(i)) Then    '  Wenn Args(i) eine Zahl, aber kein Datum ist 
    varArgs(i) = Cdbl(varArgs(i))                               '    Wandle die Zahl um in Typ Double
    End If                                                      '  Ende Wenn
  Next i                                                        'Ende Schleife

' CALC-FUNKTION AUFRUFEN
  objFncAcs = createUnoService(strSvc)                          'Service starten
  v = objFncAcs.callFunction(strFnc, varArgs())                 'Funktion aufrufen und Resultat zurückgeben
  If IsNumeric(v) And bolDtm = True Then                        'Wenn Datum erwartet aber Zahl zurückgegeben wurde
    v = Format(v, "dd.MM.yyyy")                                 '  Rückgabewert ggf. in ein Datum umwandeln
  End If                                                        'Ende Wenn
  pCalcFnc = v                                                  'Rückgabewert setzen
End Function


An alle, die das LibreOffice-Forum gern nutzen und unterstützen wollen:


Bitte helfen Sie uns mit 7 Euro pro Monat.
Durch Ihren Beitrag tragen Sie dazu bei, unsere laufenden Kosten für die kommenden Monate zu decken.
Unkompliziert per Kreditkarte oder PayPal.
Als ein kleines Dankeschön werden Sie im LO-Forum als SUPPORTER gekennzeichnet.



Antworten