Seite 1 von 1

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

Verfasst: Fr 24. Jan 2025, 10:46
von Proma
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

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Fr 24. Jan 2025, 12:23
von mikele
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).

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Fr 24. Jan 2025, 14:03
von Proma
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

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Fr 24. Jan 2025, 16:49
von mikele
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: )

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Fr 24. Jan 2025, 17:43
von Proma
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)

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Fr 24. Jan 2025, 18:05
von karolus

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

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Fr 24. Jan 2025, 19:18
von Proma
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

Re: Verwenden von Calc-Funktionen in LO-Basic

Verfasst: Mo 27. Jan 2025, 12:55
von Proma
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