REGEX usage in LibreOffice gives an error

Good afternoon to all participants of the forum.
Could you please help me with my simple macro in Libre Office 7.3.0.3 (x64) (I could not find an answer in forum discussions) I try to use a comand REGEX to tak out unnecessary symbols from a string text. When I try to run it, it gives the error:
BASIC syntax error. Parentheses do not match.
What I do wrong? How to write it correct, that it would work?
May be I have to add a line inside my macro of kind - dispatcher=CreateUnoService(“com.sun.star.util.TextSearch”)
or something similar?

Here I quote my somple macro:

Sub Master

Dim B1 as String

Dim Doc as Object
Dim currSheet as Object
Dim currCell as Object
dim dispatcher as object

Doc = ThisComponent
currSheet = Doc.Sheets(0)

dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")


currCell = currSheet.getCellByPosition(1, 8)
currCell.String = "+7913-256-5891 phone"


B1 = REGEX( "+7913-256-5891 phone"; "-"; ""; "g" )


currCell = currSheet.getCellByPosition(1, 14)
currCell.String = B1

End Sub

https://help.libreoffice.org/latest/en-US/text/sbasic/shared/calc_functions.html?DbPAR=BASIC

Good evening, Mikekaganski. Thank you for your answer. I am a beginer in creating a marco. May be you could give some explanation to my question. Inside the link you gave I can see different UNO services names, but I still do not understand, what I should do with them to solve my issue. What command exactly I should write into my macro in order to find a solution? What is the line of logic to understand why and which service I should use to some particular command in macro from the list you provided in that link? These are questions, which appear in my mind after the link you provided?

[I’m assuming here that you have limited programming experience, just from what you say…please forgive me if it sounds a little patronizing because I underestimated your experience level…]

The error is because you do not delimit arguments with “;” in BASIC, you use “,”. So the ; after …phone" is the error. But that is part of a much larger concern. Read on.

This error is really based on what mikekaganski is saying, which is that you cannot use Calc functions inside macros directly. Meanwhile Villeroy is saying that you don’t even need a macro for this, since you can just use the REGEX Calc function in the sheet itself.

To use REGEX inside a macro (there might be reasons for this), you would first create a FunctionAccess service object then call the callFunction method on that object. Yeah, if you are a beginner, it sounds like gobbledygook.

The upstart, though is that before your B1=REGEX... line, you would get rid of the dim dispatcher as Object and dispatcher createUnoService... (unless you need that for something else, which with luck you don’t); then you would add in

Dim oService As Object
oService = createUnoService("com.sun.star.sheet.FunctionAccess")

instead. In short, FunctionAccess is a service you need here, not Dispatcher.

Then instead of your B1=... line, you would have

B1 = oService.callFunction("REGEX", Array("+7913-256-5891 phone", "-", "", "g"))

What you think of as the ‘hard’ function REGEX becomes a ‘soft’ text string that is the first part of a request to use that function, and the arguments (parameters) for the REGEX function are then passed to callFunction as a single array, which is built in BASIC by using Array(…). You could stuff that array with the exact same arguments Villeroy gives you in answer, namely, the “\D”, etc. But you would separate them with commas, not semicolons, to avoid the error you are getting!

If you ever have to use Dispatcher in a macro then you should shed a tear or two. While the macro recorder uses it all the time, it is only used for tricky things that simulate user interaction in handwritten macros…like copy/paste scenarios, etc. In fact, it is often downright worthless, since, say, it will start up a dialog box for settings but then have no way to actually toggle the settings. Instead, those settings are done in a handwritten macro by directly understanding the object model (chunks of data) that the dialog box is meant to handle then setting attributes on that object model directly–or, almost directly through small data chunks called structs. More gobbledygook!

First consider and explain for what reason you think a “macro” is approiate. Even better you should descibe your actual issue.

  1. Is it about getting phone numbers the way you need them for dialing?
  2. Is it about learning how to get LibO-Basic-Code which actually would run?
  3. is it about …(your turn)

Please read XY problem - Wikipedia to understand my intention.

In the first case part of the answer will probably be that a macro is supposed to not be the appropriate means.

In the second case part of the answer will be that the attempt to assign a formula to a cell only can be reasonable in very rare cases, and that you need to start your studies at a different point.

In the third case it depends…

@Joshua4, thank you very much !! Now everything works perfectly. As it was intended. And it is nice, that you very clearly explained to me one thing, which I (as a beginner) did not know - that I can not just take LibreOffice Calc function and put it into a Macro. Somehow before our communication I did not see any explanations like this - nor in Guides about making macro, nor in educational videos people are posting. There are thing one can get only from professionals. Of course, you language, how you explain the topic - is not easy for me, I understand it on some 30%, I understand the essence, but when you gave exact directions and comand-lines, that I have to erase from my macro … line and put instead … lines (you typed exactly - how it should look like) - for me it became obvious and clear what to do. Once again, thank you. Now I feel, that I need to find some text book (guide), which would explain things for beginners like you did for me. If I just open Libre Office Help and find some function with short explanation - how it should look like, etc. there I do not see some other possible commands-functions-calling services which should be typed BEFORE using some particular command in macro. There in LibreOffice Help I do not see the way to implement it correctly. So now I continue my education and development in making macros. Have good day!

@Lupp, thank you for your advice. I have read an article in Wikipedia you quoted. Yes, I agree, that if a support personal asks more questions from a customer, it can give better picture, what a problem a customer have and what would be proper solution for the problem. In my case (1) I have many repeated actions inside a LibreOffice calc in correcting phone numbers and replies, people are providing after a survey, then making copy-paste it to create separate table of contacts and replies, and then prepare cards with few persons names and phone numbers. For me it is very clear, that macros can nicely make this analysis, correct syntax of phone numbers and then form a table and cards of participants. Some functions in Libre Office macro I already made working, and some I research. (2) So I need that my macro would work. And (3) I understand, that I need to find good textbook-guide about macros in LibreOffice, which would lead me through gradual process of learning - how to create sophisticated operations with survey data in Libre Office macro, how to make separate files with some data from surveys by commands from a macro, and may be it will be possible that macro will send replies by e-mail messages to survey participants. So these are some plans to develop for me.

t74097.ods (9.7 KB)

If the “+7” is for Russia (or probably for additional countries of the former Sovjet Union) the + character is all but unnecessary.
The RegEx used in the attached example should be replaced by [^\d\+] then.

Thank you for your answer and suggestion. It nicely works in Libreoffice calc, when it is inserted as formula in the cell when we use just a worksheet. But when I tried to do this command inside of the macro, it does not work and gives the error message: BASIC runtime error. Sub-procedure or function procedure not defined. The way I typed it inside the macro is: B1=REGEX("+7913-256-5891 phone","\D","",“g”) May be you know some subtle moment inside of my macro, which I miss?

@ilja_pi Go back and read my earlier comment again. You cannot use REGEX in a macro. In BASIC it is undefined, thus the error. Using Calc functions in BASIC isn’t how it works. You must use FunctionAccess and call REGEX via UNO. This is what mikekaganski was saying from the beginning.

I’m afraid you (@ilja_pi)) didn’t read my comment above on your original question. You probably won’t get anywhere if you ignore suich hints.

  1. Try to avoid macros in everyday work. Use your formula (or one of the suggested) in Calc cells.
  2. if you want to learn about them anyway, start with the basics.

Your B1 is explicitly defined as a string. The right side of your assignment isn’t anything meaningful as long as REGEX isn’t recognized by Basic as a function. Like any Calc function it isn’t. To call Calc functions from Basic, you need to use an instance of the service com.sun.star.sheet.FunctionAccess.
Start with the Basics.
To learn how LibreOffice Basic works with objects relevant for the document models, you need an introduction into the usage of the API (ApplicationPÜrogrammingInterface). Try Andrew Pitonyak’s “OpenOffice.org Macros Explained” available from https://pitonyak.org/https://www.pitonyak.org/oo.php

Thank you for your advice and link. I will definetly read Andrew Pitonyak book. One thing I am not sure. Pitonyak describes Open Office, not Libre Office. May it happen that after reading I will have later some porridge (mixture) of different programming concepts - something from OpenOffice set, somethig LibreOffice set ??

Everything is now split up. There are comments on the original question and on the two answers which may mix up the same issues in different ways and make us lose orientation.
(This Q&A software isn’t exactly my love.)
Anyway the topic might better have been

  1. “How to convert phone numbers from stubborn formats to a single standard? UDF preferred”. Whether or not the usage of REGEX() is a good idea can be freely discussed then.
  2. The actual issue needing to be solved to get it on a path you started with would then be “How to call a standard function of Calc by user code?”
    Now there is a specific issue concerning 2. only relevant for very few functions [INDEX() and REGEX() namely]
  3. “What do do if a conceptual mistake requires that a function be called by user code with a missing parameter in specific cases?” (Might @erAck be interested?)
    And as a background for much of all that:
  4. With what guides/books/help-pages should I start to study macro programming For LibO in Basic. You might also be open to ask then:
  5. Is there something more powerful than Basic for the creation of user code? (Python e.g. is preferred by some experienced users.).

I dont’t feel capable of getting this thread back to a path allowing for a cleary structured discussion.

If you decide to try a new start with something like question 1. I will again try to help. Don’t miss in this case to describe as clearly as possible what “formats” (complete strings!) you expect to find in your sources, For the target format only "the sequence of digits, probably with a prefixed + " is reasonable. Concerning the source I once found something like
(0)9999-888-777-66 (de: 0049); alternative: +1 987-654-123455
May in your case also slahes occur? …? ?

On API level 99% of LibreOffice and OpenOffice are identical. You talk to the same object hierarchy even if the corresponding feature looks different in the user interface.

Basic is a slightly rotten language from the 80ies and 90ies. Office macros are the last resort where this silly and cumbersome language is still in use. LibreOffice offers Python as a true programming language as alternative macro language. You may also write macros in JavaScript or BeanShell (Java). The true learning curve is not in the language. The thing you talk to in either langauge is the thing which can make adult programmers cry. Programming LibreOffice in either language is extremely complicated, particularly when you are new to programming.

A spreadsheet is no less than a simplified, more visual programming langauge for people who can’t program. The formula language is your primary language when working with spreadsheets. Without knowing the office suite very, very well, there is not much to do in Basic because without knowing the objects you are talking to, you either re-invent existing features or you run into open space where all your code solves one special problem with a maximum of effort (wasting days of time to save a couple of clicks).

If you are really interested in programming, do not start with Basic talking to a highly complicated API. Don’t start your pilots exam sitting on a garden chair mounted into a 747 cockpit.

What conceptual mistake? It is an incomplete implementation of css::sheet::FunctionAccess that passing an empty Sequence<Sequence<>> for an omitted argument to a spreadsheet function is not correctly accepted. If it was, then this

oService.callFunction("REGEX", Array("+7913-256-5891 phone", "..-", Array(Array()), 1))

would result in 13- (Array(Array()) because arrays are always passed 2-dimensional).

Fwiw, https://gerrit.libreoffice.org/c/core/+/130179 implements that.

1 Like

Thanks for the info and your interest/engagement.

I regard it as a conceptual mistake to accept cases where a “positive” information needed to get a subroutine to work as intended must be passed by the omission of a parameter.
Optional parameters (problematic anyway as you stated in a different place some time ago) should, if at all, be used to skate over an obsolete (depending on the values passed via different parameters) information, or (mainly) to state that a specified default should be used.
Afaik there is only one function in Calc based on a different judgement, and this only in V 6.2 or higher:

  • REGEX() when used to get an occurrence of a pattern selected by the following number 1-based.

The INDEX() function also sometimes used with an omitted parameter to get a complete row or a complete column also allows for a 0 (zero) in the respective place.

REGEX(given; pattern; mode; optionalReplacement ) and probably with mode=-i making the replacement disregarded, and returning the i_th occurrence would be a way.
An even better solution might have been be to use two names like RXREPLACE() and RXOCCURRENCE() where the second function also could return all the occurrences as a sequence (array) based on a mode parameter like “g” or similar. It could this way even be a sufficient surrogate for the still missing TEXTSPLIT() as the counterpart of TEXTJOPIN().

The alternatives would had been to either implement two functions, one to search and one to replace, or add another parameter to specify search|replace and in the search case ignore the replacement value.

While Regular Expressions are nice a

    =SUBSTITUTE(TEXT; "-"; "")

should also work for the original question
https://wiki.documentfoundation.org/Documentation/Calc_Functions/SUBSTITUTE

If you need it in a macro use the hints already to be found above.

1 Like