Need for "XPropertySet" object when calling "getDec2Hex"

Platform: LO Basic, v7.3.2.2 (Community), build 49f2b1bff42cfccbd8f788c8dc32c1c309559be0, running on OSX 10.15.7

Am curious about the need for the add-in function getDec2Hex’s first parameter, an “XPropertySet” object.

According to
a portion of the Libre help site, the function is part of the com.sun.star.sheet.addin.XAnalysis service.

In a spreadsheet you’d call “Dec2Hex(VALUE [, PLACES])”, but in a macro it’s “ADD-IN OBJECT.getDec2Hex(XProps Object, VALUE, PLACES)”

The add-in service is shown here

XPropertySet is an interface, shown here

To use any add-in function in a macro, one must first create a reference to the service:
Dim myAddInFuncs As Object
myAddInFuncs = createUnoService(“com.sun.star.sheet.addin.Analysis”)

The XPropertySet is also required:
Dim myXProps As Object
myXProps = com.sun.star.beans.XPropertySet

Declaring myXProps results in a variant with two “Out of Scope” sub-entries - Name, and Parent - though they’re not properties, as attempting to assign values to them (i.e, myXProps.Name = “MyName”) results in a “Property or method not found” error.

Let’s convert a decimal value to its hex equivalent, storing the result in a string variable, “sHex”.

LO source shows that getDec2Hex has three parameters:
An object, “myXProps” (shown above)
A Double, “Value” (the number being converted)
A Variant, “Places” (the number of digits to be returned)

Note that unlike calling Dec2Hex in a spreadsheet, with its one required parameter (the number to convert, and the optional number of places - up to 10 - to display), all three parameters to getDec2Hex are required, and even though the “Places” parameter is shown to be a variant, it needs to be quoted as if it’s a string or you’ll get an error.

Also, while the resulting hex value will be zero-padded to the number of places, the value of that parameter must must at least enough digits to accommodate the output - though not more than 10 - or you’ll also get an error:
Dim sHex As String
sHex = myAddInFuncs.getDec2Hex(myXProps, “9024416”, “6”)

Here, we’ve converted the decimal number 9024416, with the contents of sHex becoming “89B3A0”.

The limit on the “Places” parameter to 10 digits appears to be due to the “Value” parameter, it being a Double, or “Long” integer, which has a maximum of value 2147483647.

However, since that max value translates in hex to “7FFFFFFF”, it’s unclear why the maximum value for “Places” is not instead 8.

It’s also the case that, as the result gets zero-padded to the value of the “Places” parameter, chances are you’ll end up with leading zeros. (With places of “9” instead of “6”, the above result would instead be “00089B3A0”). By making the “Places” parameter required, you might as well always set it to “8” just to be safe, and unless you need them, remove any extra zeros from the start of the result.

Perhaps this particular function, or the add-in service in general, is being refactored, and this behavior, along with the way Dec2Hex is called, will change in the future.

Otherwise, it’s a bit of a mystery, perhaps a holdover from some super-old, crufty OpenOffice code. :wink:

As things stand now, since the two members of XPropertySet contain no apparent data, besides the obvious answer of “because it’s in the function declaration”, what purpose does it serve in the function call?

The maximum value that translates in hex is not 7FFFFFFF, it’s 7FFFFFFFFF (decimal 549755813887.0).

By the way, you can also use empty string "", or Empty, as places, to make the function calculate places automatically.

Hmmm, had thought the max value of a long integer was 2147483647, which translates to 7FFFFFFF.

At least, that’s what the docs say.

Thanks for the tip on using an empty string for Dec2Hex. Hadn’t thought of trying that.

Yes, the docs tell the truth: the max value of a long integer is 2147483647. However, there is no mention anywhere that what getDec2Hex takes is treated as long int :wink:

Wow, a month has gone by already!

You’re right, but if scaddins/source/analysis/analysis.cxx:725 is correct,
it accepts a “double”, which should be a float. Weird.

It is a consequence of creation of the function to be primarily used in Calc, which uses doubles (double-precision floating-point numbers) exclusively for all numbers, even when you think you use “integers”. So only doubles come from Calc, and the developer didn’t consider calling from Basic case, where the repertoire of passed types may be wider.

English FormulaLocal in B1: =DEC2HEX(A1;4)
Unlocalized getFormula of cell B1: =com.sun.star.sheet.addin.Analysis.getDec2Hex(A1;4)

Having the correct function name, service FunctionAccess in stupid StarBasic goes like this:

Const Dec2Hex = "com.sun.star.sheet.addin.Analysis.getDec2Hex"
nValue = 1234
srv = createUnoService("com.sun.star.sheet.FunctionAccess")
sHex = srv.callFunction(Dec2Hex, Array(nValue, 4))

StarBasic has a hex function: Hex Function

1 Like

This is a bug. Or rather, two bugs: one in the add-in function implementation, and one in documentation (wow, you did a good detective job untangling it all!). Please file them.

The XPropertySet argument is, in case of Calc, inserted by ScInterpreter::ScExternal (when aCall.NeedsCaller() is true). It is expected to represent conversion options - used to convert text to numbers. And in getDec2Hex, it is used to handle the places argument, which is not required to be a string, but may be either a string, or a double. ScaAnyConverter::getDouble doesn’t accept other UNO types, which Basic integers are marshalled as - which is a bug (it is not OK that we simply discard e.g. Long).

   oService = createUNOService("com.sun.star.sheet.addin.Analysis")
   MyDec2Hex = oService.getDec2Hex(Nothing, 1234, 4.1) ' 4.1 is a double, and will get rounded to 4

And of course, we need to improve the existing documentation for the set of functions requiring the XPropertySet in the help.

This does not create a proper object, but just an empty reference.
This empty reference would be detected in the code handling places (when it’s string), the same way as if you used Nothing, and then the string would be handled using default conversion.

'k,that makes sense. Was just fiddling with getDec2Hex to make it not error out…

tdf#148645, tdf#148646

servicecom_1_1sun_1_1star_1_1beans_1_1PropertyBag.html

Implementation of this service can keep any properties and is useful when an XPropertySet is to be used, for example, as parameters for a method call.

Well, yes. But how? And which properties?
Allegedly, it has a function createDefault()

pbsrv =  createUnoService("com.sun.star.beans.PropertyBag")
pbsrv.createDefault() 'no such element exception

And what if some UNO object provides method initialized(args)? How can I know anything about valid arguments?

I’m sorry, I can’t see what are you asking, and how PropertyBag is relevant to this question. Note that the IDE documentation is not relevant here, too; the documentation improvement request is mentioned above: tdf#148646.

Maybe the “Implementation of this service … is useful when an XPropertySet is to be used, for example, as parameters for a method call” makes it look like it could be useful here - but it’s not, and that is why we need better documentation in help. In fact, whoever created the Analysis add-in back then, should had used not XPropertySet, but XNumberFormatsSupplier to correctly express what this argument is about. Maybe at some point, the number format-related stuff had no own supplier … who knows, it may only be discovered using git archaeology :slight_smile:

Quote from the PropertyBag documentation:

Implementation of this service can keep any properties and is useful when an XPropertySet is to be used, for example, as parameters for a method call.

I even quoted that. Please re-read :slight_smile: