# Base Macro to Determine Control Type

Is there a property or method of a control that reliably reveals its type? For example, can I determine if a given object is a form, table control, list box or text box? I am trying to simplify some of my subroutines and functions so that inside them, they can determine the control type and take different actions accordingly. Or better yet, write a function that receives a control object, and returns a string telling the type of the control so I could reuse the function throughout my code. I'm particularly interested at the moment to determine if a given object is a table control, but the other types would be useful to determine as well.

I did finally figure out how to use MRI, so I can generally view the methods and properties of any object. I'm just not sure how to test for the type of a control. I suppose I could find some property that is unique to a table control or list box and check whether those methods/properties exist or something like that.

It would also be cool if there was a way to determine the format of the data in a control (kind of the same as the first question/paragraph). For example, is it numerical, currency, text, date, time, etc.? In some of my functions I pass a string parameter that tells the type in advance, like sFormat = "string", "currency", "long", "integer", "double", "float", "listbox", "null", etc. If there was a way to determine the data type programmatically, I could skip having to tell the functions what the type is, which would be nice.

edit retag close merge delete

Sort by » oldest newest most voted

Reliably; Funny guy. Of course there is.

Each control model has a service name property. That is what you want

Here is an example routine which will walk down every control on a form looking for certain types of controls. And then go over what is happening. (actually it should be fairly self explanatory)

sub setNativeWidgetLook( aDataForm as variant, aYesNo as Boolean )
dim enControlModels
dim oControlModel as object

'thisComponent.LockControllers    '

if enControlModels.hasMoreElements then
do
oControlModel = enControlModels.nextElement
if oControlModel.ServiceName = "stardiv.one.form.component.Form" then
setNativeWidgetLook( oControlModel, aYesNo )
else
if oControlModel.ServiceName <> "stardiv.one.form.component.Grid" then
if oControlModel.ServiceName <> "stardiv.one.form.component.Hidden" then
oControlModel.NativeWidgetLook = aYesNo
end if
else
setNativeWidgetLook( oControlModel, aYesNo )
end if
end if
loop while enControlModels.hasMoreElements = True
end if

'thisComponent.UnLockControllers    '
end sub


Of course a dataform can nest include other dataforms (ie. for a master/slave type form) so in these lines:

if oControlModel.ServiceName = "stardiv.one.form.component.Form" then
setNativeWidgetLook( oControlModel, aYesNo )


if the current control is another dataform the routine uses recursion to walk down the controls on this sub-dataform first.

Then it looks it checks that the control model is neither a grid control nor a hidden control (which is not just any control hidden, it is separate type of control) and if not then it sets the property NativeWidetLook (yes for OS, no for LO).

If the current control was a grid, that again has a collection of controls so again it uses recursion to call itself and walk down those also.

You will want to get a copy of SDK from the LO download site, with that is the documentation that will give you the needed ServiceNames, etc and this document can be linked to from MRI so you can use it to get details while you are working.

When you say datatype of the control are you actually asking to find the dataytpe of the database field the control is linked to? (I'll assume you are)

so here is an example of another working routine which uses that:

sub PrettyControl( aControl as variant, aReqColor as double, setDisplaySize as boolean )
if  aControl.ServiceName = "stardiv.one.form.component.Edit" _
or  aControl.ServiceName = "stardiv.one.form.component.TimeField" _
or  aControl.ServiceName = "stardiv.one.form.component.DateField" _
then
if aControl.BoundField.isNullable = 0  and aReqColor <> -1 then
aControl.BackgroundColor = aReqColor
end if
if aControl.BoundField.TypeName = "VARCHAR"_
OR aControl.BoundField.TypeName = "CHAR"_
then
if setDisplaySize then
aControl.MaxTextLen = aControl.BoundField.DisplaySize
end if
end if
if aControl.HelpText = "" then
aControl.HelpText = aControl.BoundField.Helptext
end if
end if
end sub


Each data awara UI control has a property BoundField which is the database column and here the routine checks that for certain things like whether is can be null and if not colors the UI controls background, the only thing that might need explaining are the last lines:

if ...
more

Golden. While some of this is a bit above my head, I can perceive the answer is here if I slowly parse through. I like that there is a "service name property." All the stuff about recursion and whatnot is great additional info too. More than likely my situation will only require a subset of what you have offered as an answer, but for those who want to go deeper, you've provided them fodder as well. Thanks a lot!

( 2018-11-13 13:34:37 +0200 )edit

.hasMoreElements... nooice!

( 2018-11-13 13:40:57 +0200 )edit

My question concerned the Base control type. As in, when I "replace with" and choose text field, numerical, currency, etc. Obviously I don't have to use "replace with" to make new controls, but it's faster to CTRL+drag an existing control (to copy it), replace with to change its type, and change its properties. Then all the size, font and color stuff is consistent. Knowing the underlying type of the MySQL column is just as good or better, as long as I use the roughly matching control in Base.

( 2018-11-13 13:56:04 +0200 )edit

That help text thing is cool. Since I'm using MySQL, I wonder if it would grab the MySQL field descriptions. That would be kinda cool. Though most of my stuff doesn't require much user instruction. "This is an address field, so type an address in it." Heh heh.

( 2018-11-13 14:00:26 +0200 )edit

One of the reasons I want to know the type is so I can know which .updateXXX() method to use. For example .updateString(), .updateLong(). Same goes for .getXXX methods. Also, list boxes are unique & need .commit & not .boundField. I pass an array of fieldnames to functions & a matching array of field types. It's not terrible, and it works, but it would be cool if I didn't have to pass that extra array. I think I'll be able to write a function to determine the control types with your info. Sweet!

( 2018-11-13 14:09:08 +0200 )edit

Ah, well some real over kill on my part then - but knowing how to work with the boundField property at runtime can have its advantages.

( 2018-11-13 14:17:58 +0200 )edit

IIRC, you can not get to the MySQL table column descriptions at least not with this property. It would be nice if you could. Maybe there is a way, I'll ponder that a bit.

( 2018-11-13 14:20:48 +0200 )edit

One method to get MySQL field comments is through Information Schema:

SELECT column_name, column_comment
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='YOUR_TABLE_NAME'


This will get you all columns with their comments for a particular table.

( 2018-11-13 20:34:31 +0200 )edit

+1. Thanks! Also added a trailing ' (single quote) on comment lines to work around bug in Ask.Libreoffice.org which diesplay's comments wrong, so your code displays a bit better at this web site.

( 2018-11-14 21:12:29 +0200 )edit