Page 1 of 1

Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 10:33 am
by eeigor
Please tell me how to use missing parameters in StarBasic correctly.

My code is using option VBASupport:
Option VBASupport 1

1. Function UDF(Optional bStatus As Boolean = True)
The following statement works without failures in VBA, but here I had to drop it.
<Optional bStatus As Boolean = True> works unstable, crashes (of course, in my context)
2. Function UDF(Optional bStatus As Boolean)
If IsMissing(bStatus) Then: End If
And bStatus will automatically be set to False after calling the IsMissing function. Why?
If IsMissing(bStatus) Then bStatus = True
Alas, the missing parameter after the call to the IsMissing function is set to False and is no longer considered missing and will not be assigned a new value of True. Is this a bug?
3. Function UDF(Optional bStatus)
If IsMissing(bStatus) Then bStatus = True
This is how it works. Variant/Boolean type. But then the "b" prefix is ​​not entirely correct.

Re: Missing parameter problem

Posted: Sat Apr 24, 2021 10:59 am
by Zizi64
Try to use two variables to handle the optional parameter.

Code: Select all

Function UDF(Optional bPassedStatus As Boolean)

 dim bInnerStatus as boolean

   If IsMissing(bPassedStatus) then bInnerStatus = True

   REM Use the bInnerStatus in the next parts of the function...
The conventional "b" prefix never will determine the type of the variable. It is only a helper mark for the programmer.

Re: Missing parameter problem

Posted: Sat Apr 24, 2021 11:13 am
by eeigor
Thanks.
Yes, I've seen this practice. This was not the case in VBA. However, I'm not entirely sure if it really should have been done exactly as you advise. It just leads to an increase in the variables. My UDF has 7 parameters, of which only 2 are required.
Just in case, I will ask if there are other opinions?

UPD
Why doesn't the code below work?
If you try to assign a string to an optional parameter of type Variant, an error will occur. The reason is that the parameter will initially be evaluated as an Object because there is a call to the object method .CellRange in the code. Is this a bug?
E.g. Pseudocode
Call a UDF from a sheet cell by passing a cell or range reference and the name (address) should be output.
Call the TestIt procedure and there will be a parameter type error.

Code: Select all

Option VBASupport 1
Sub TestIt()
    Call UDF("TestIt")
End Sub
Function UDF(Optional Caller)
    Dim sCallerName$

    If Not IsMissing(Caller) Then
        If TypeName(Caller) = "Range" Then  'Excel VBA
            ' Retrieve the fully qualified reference to the Caller.
            sCallerName = Caller.CellRange.AbsoluteName
        ElseIf TypeName(Caller) = "String" Then
            sCallerName = Caller
        End If
        MsgBox sCallerName
    End If
End Function
In VBA, there is no such connection between an input parameter and a procedure code. And moreover, with code that will not be executed in a particular case. This is where the second variable is really needed, but of the Variant type. Some kind of nonsense...

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 1:07 pm
by Zizi64
It is not a good idea to use the VBA procedures in the LibreOffice, in the Apache OpenOffice. Use the API functions and procedures. The MS VBA and the AOO/LO never will be fully compatible.

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 1:35 pm
by eeigor
No, no, I only use VBA for the sole purpose of passing a range reference to the UDF, but the question was different. Understand how variables are handled.

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 2:10 pm
by JeJe
Same solution to avoid an error.

Code: Select all

Option VBASupport 1
Sub TestIt()
    Call UDF("TestIt")
End Sub
Function UDF(Optional Caller)
    Dim sCallerName$,t

    If Not IsMissing(Caller) Then
        If TypeName(Caller) = "Range" Then  'Excel VBA
            ' Retrieve the fully qualified reference to the Caller.
            
            t = caller
            sCallerName =t.CellRange.AbsoluteName
        ElseIf TypeName(Caller) = "String" Then
            sCallerName = Caller
        End If
        MsgBox sCallerName
    End If
End Function
In Basic you can't set a variable to a value on declaration so you can't put "optional varname =" or "varname ="

Edit: and you'll need to check to see if "Range" is implemented as a typename.

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 3:41 pm
by eeigor
@JeJe, thank you. Now a complete understanding has been reached. You enter a variable t of type Variant. What is the reason for this approach? In VBA, everything is simpler and, if you want, cleaner. Give your opinion on the reasons for all that I have touched upon here. Is StarBasic not finalized yet?

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 3:44 pm
by eeigor
JeJe wrote:In Basic you can't set a variable to a value on declaration so you can't put "optional varname =" or "varname ="
I'm sorry, I didn't read your post to the end :)

Really, I can, if VBA Support mode is enabled.
Function UDF(Optional bStatus As Boolean = True)

This is not the first time I have encountered this feature. For example, why is the obj variable introduced in the code below? Try this: oDoc.SupportsService(), and get an error.

Code: Select all

Sub Test_IsCalcDocument()
	Print IsCalcDocument("Hello"); Chr$(9); IsCalcDocument(ThisComponent)
End Sub

Function IsCalcDocument(oDoc) As Boolean
	On Error GoTo Failed
	Dim obj: obj = oDoc  'avoids the error

'	IsCalcDocument = False
	If obj.SupportsService("com.sun.star.sheet.SpreadsheetDocument") Then
		IsCalcDocument = True
	End If

Failed:
End Function
And why does a parameter of the Variant type get the Object subtype even before assigning a value just because there is a method call in the procedure body? That's the question.
In short, I don't understand something here:
Dim obj: obj = oDoc 'avoids the error

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 4:19 pm
by JeJe
Really, I can, if VBA Support mode is enabled.
Function UDF(Optional bStatus As Boolean = True)
You're right! Didn't know that... that could be useful!

*

Wild guess... maybe the compiler checks through the sub/function to make sure any variables there and in the sub declaration match for type?

I think you just have to accept how OOBasic does things and work with it... Office API aside its almost a clone of the VB family of languages. There are quirks like with the split function:

viewtopic.php?f=20&t=95717

You just have to live with them and work round it.

Re: Missing parameter problem & its evaluation

Posted: Sat Apr 24, 2021 4:26 pm
by eeigor
Yes, of course. It's just that I'm still at the stage of mastering these compiler features. In the Pitonyak manual, these details are not reflected in the details. Although I tend to consider these features a disadvantage.

Re: Missing parameter problem & its evaluation

Posted: Wed Apr 28, 2021 2:03 pm
by Lupp
To be honest: I only had a fly over this thread. Too much VBA.

However, it might be releated somehow to this bug: https://bugs.documentfoundation.org/sho ... ?id=102381.
Concerning optional parameters which actually were omitted in the call, the behaviour gravely depends on whether the call came from the Calc evaluator or from a different Basic routine. Calc wrongly passes 0 (Double) for a missing optional parameter to a user function in Basic.

(In addition there is a fundamental problem with trying to omit a parameter when calling a standard function via the FunctionAccess service. The implications of omitting parameters are "a bit" messed up.)

Re: Missing parameter problem & its evaluation

Posted: Wed Apr 28, 2021 2:44 pm
by Villeroy
You can dump layers and layers and more layers on this API until you end up with dependency hell, security issues, performance issues in very poor and unmaintained amateur code. Look at website development and all the layers of silly JavaScript libraries for the stupid.

Re: Missing parameter problem & its evaluation

Posted: Wed Apr 28, 2021 3:49 pm
by eeigor
@Lupp thanks for the valuable observations. And the bug you mentioned is still present.
My procedure just assumes two calls: from the sheet and from the code.
I plan to take the time and test everything as it should. I do not have complete clarity today. This makes the UDF look unfinished.

Everything works if you declare the parameters as Variant and assign the passed values to internal variables. But I want to get rid of the redundancy of the code.

Re: Missing parameter problem & its evaluation

Posted: Wed Apr 28, 2021 9:04 pm
by eeigor
Compare two calls.
Run PassParamsByType func from a sheet cell (screenshot 1), and then run Test_PassParamsByTypeFromModule (screenshot 2). Complete confusion... And @Lupp was right.

A1: =PASSPARAMSBYTYPE(1;;;;;)

Code: Select all

Function PassParamsByType(pRequired _
 , Optional pVariant, Optional pLong&, Optional pDouble#, Optional pString$, Optional pBoolean As Boolean)

	If IsMissing(pBoolean) Then
		pBoolean = True
	End If
	MsgBox "Parameters Passed" _
	 & Chr(10) & "TypeName(pRequired):=" & TypeName(pRequired) _
	 & Chr(10) & "pVariant:=" & pVariant _
	 & Chr(10) & "pLong:=" & pLong _
	 & Chr(10) & "pDouble:=" & pDouble _
	 & Chr(10) & "pString:=" & pString _
	 & Chr(10) & "pBoolean:=" & pBoolean _
	 , , "macro:PassParamsByType"
End Function

Sub Test_PassParamsByTypeFromModule()
	Call PassParamsByType(1 _
	 , , , , ,)
End Sub
Pay attention to the boolean parameter handling and look at my remarks in the start post. And the string parameter is set to zero. :(
Zizi64 wrote:Try to use two variables to handle the optional parameter.
It seems that yes.

Screenshots 1 & 2:

Re: Missing parameter problem & its evaluation

Posted: Thu Apr 29, 2021 7:03 am
by Zizi64
When you call the function in this way from the cell

Code: Select all

= PASSPARAMSBYTYPE(1;;;;;)
then the parameters are NOT missing, but they have empty (zero) values.


Try it from the cell:

Code: Select all

=PASSPARAMSBYTYPE(1)

In this case the params are missing really.

You can check irf a parameter is missing or not - really:

Code: Select all

REM  *****  BASIC  *****

Function PassParamsByType(pRequired, Optional pVariant, Optional pLong&, Optional pDouble#, Optional pString$, Optional pBoolean As Boolean)

   If IsMissing(pBoolean) Then
      pBoolean = True
      print "is missing" REM ------------------------- inserted by Zizi64
   End If
   MsgBox "Parameters Passed" _
    & Chr(10) & "TypeName(pRequired):=" & TypeName(pRequired) _
    & Chr(10) & "pVariant:=" & pVariant _
    & Chr(10) & "pLong:=" & pLong _
    & Chr(10) & "pDouble:=" & pDouble _
    & Chr(10) & "pString:=" & pString _
    & Chr(10) & "pBoolean:=" & pBoolean _
    , , "macro:PassParamsByType"
End Function

Sub Test_PassParamsByTypeFromModule()
   Call PassParamsByType(1, , , , ,)
End Sub
I checked it WITHOUT the VBA compatibility option!!!!%!!!!!

Re: Missing parameter problem & its evaluation

Posted: Thu Apr 29, 2021 7:54 am
by eeigor
Zizi64 wrote:…then the parameters are NOT missing, but they have empty (zero) values.
Yes, they have. But aren’t the params missing? That is the question.

Re: Missing parameter problem & its evaluation

Posted: Thu Apr 29, 2021 8:28 am
by Zizi64
It seems there is such logic in the Calc: If you marked the place of the passed variables (by the semicolons), then they will be recognized as existing but empty passed parameters in a formula.

Re: Missing parameter problem & its evaluation

Posted: Thu Apr 29, 2021 8:53 am
by eeigor
We'll have to give up. Such bugs cannot live so long... This is a feature

Re: Missing parameter problem & its evaluation

Posted: Tue Aug 03, 2021 6:07 pm
by mikekaganski
FTR:

1. Basic behavior WRT Optional arguments is explained in https://git.libreoffice.org/core/+/8e32 ... 6b9bf20f78:
In LO Basic, optional parameters are allowed, but without
any default values. Missing parameters will not be initialized
to their respective default values of its datatype, either.

With option Compatible, optional parameters are allowed
with default values. Missing optional parameters that
don't have explicit default values will not be initialized
to their default values of its datatype.

With option VBASupport, optional parameters are allowed with
default values. Missing optional parameters that don't have
explicit default values will be initialized to their default
values of its datatype.
Hence, this quote:
eeigor wrote:2. Function UDF(Optional bStatus As Boolean)
If IsMissing(bStatus) Then: End If
And bStatus will automatically be set to False after calling the IsMissing function. Why?
If IsMissing(bStatus) Then bStatus = True
Alas, the missing parameter after the call to the IsMissing function is set to False and is no longer considered missing and will not be assigned a new value of True. Is this a bug?
should be either some mistake, or a bug in an (unspecified) version. It works as expected e.g. in my current 7.2.0.2.

2. Calc behavior WRT optional arguments is described in comments to many Calc functions, e.g., STYLE:
In the LibreOffice Calc functions, parameters marked as "optional" can be left out only when no parameter follows. For example, in a function with four parameters, where the last two parameters are marked as "optional", you can leave out parameter 4 or parameters 3 and 4, but you cannot leave out parameter 3 alone.
3. Wrt this quote:
Zizi64 wrote:Try to use two variables to handle the optional parameter.

Code: Select all

Function UDF(Optional bPassedStatus As Boolean)

 dim bInnerStatus as boolean

   If IsMissing(bPassedStatus) then bInnerStatus = True

   REM Use the bInnerStatus in the next parts of the function...
It is completely unclear how this should even behave differently compared to

Code: Select all

Sub Foo(Optional Bar As Boolean)
  If IsMissing(Bar) Then Bar = True
End Sub
If it does, then it is a bug, and should be filed and fixed.

4.
Zizi64 wrote:The conventional "b" prefix never will determine the type of the variable. It is only a helper mark for the programmer.
See DefBool statement.

Re: Missing parameter problem & its evaluation

Posted: Wed Aug 04, 2021 8:55 pm
by Zizi64

Code: Select all

If IsMissing(Bar) Then Bar = True
It is impossible to give a value to a variable what is not exist.

Use a local variable for the boolean value with a locally defined default value for that case when the passed variable is not exist.

Re: Missing parameter problem & its evaluation

Posted: Wed Aug 04, 2021 9:28 pm
by Villeroy
Zizi64 wrote:It is impossible to give a value to a variable what is not exist.
No, it works like this in VB, VBA and StarBasic since the 90ies of the past millenium. The variable is declared as optional. It is not initialized when the calling routine does not pass it over. Its vartype is 10, isMissing(bar)=True and you can assign a value to it.

Stupid Basic where a variable can be empty, missing, null, nothing in addition to the regular types:

Code: Select all

Sub foo(optional bar)
if isMissing(bar) then bar = true
This is how Python handles mising parameters:

Code: Select all

def foo(bar=True):
If you call foo(), the value of bar will be True by default.
If you call foo(False), the value of bar will be False because you override the default value.
 Edit: changed "vartype is 9" to "vartype is 10". Thank you JeJe 

Re: Missing parameter problem & its evaluation

Posted: Thu Aug 05, 2021 1:51 am
by JeJe
Optional parameters are of the Error value type (10) so we could also put:

Code: Select all

Sub foo(optional bar)
if vartype(bar) =10 then bar = true
end sub

Re: Missing parameter problem & its evaluation

Posted: Wed Dec 29, 2021 10:00 am
by mikekaganski
JeJe wrote:Optional parameters are of the Error value type (10) so we could also put:

Code: Select all

Sub foo(optional bar)
if vartype(bar) =10 then bar = true
end sub
Note that errors are not limited to "missing", and there may be valid cases of passing errors as arguments; so IsMissing is more specific and correct check. Also using an error to pass "missing" argument is an undocumented implementation detail, which might change at some point (e.g., it prevents from passing that error as value to a function taking optional "error" argument - so it might be useful to introduce some explicit mechanism of marking missing argument value internally) - so use of VarType for that is conceptually unreliable/not future-proof. (Although of course, if we introduce that explicit internal "missing" flag, we likely would still use same error value, just with that flag set, to minimize breakage of existing code.)

Re: Missing parameter problem & its evaluation

Posted: Thu Dec 30, 2021 10:24 pm
by LeslieS
Villeroy wrote:Stupid Basic where a variable can be empty, missing, null, nothing in addition to the regular types:

Code: Select all

# Online Python compiler (interpreter) to run Python online.
# Write Python 3 code in this online editor and run it.
def foo(s):
    print(type(s))
foo(12)
foo("foo")
foo(None)
# foo() obviously an error 
missing = object()
def foo(s = missing):
    print(type(s))
foo(12)
foo("foo")
foo(None)
foo()
print(type(foo))
foo = 12
print(type(foo))



Your comparing apples to oranges here:

Code: Select all

def foo(bar=True):

If you give your basic function parameter a default value it will work exactly like the python parameter.
Python doesn't have optional parameters. You either have a forced parameter or a defaulted one.