Ask Your Question

How to create a Macro to insert the current date in the current language. [closed]

asked 2017-10-30 06:58:57 +0100

holy-harp gravatar image

I write documents in Thai and English sometimes using both in one document. I would like to create a macro to insert the current date for me in whatever language is currently being used in the document. I can do this manually with: Insert > Field > More Fields > Date > Date (Fixed) > Additional Formats > Language = Automatic I created a Macro to do this (see below) but it comes out only in English. What can I do to my Macro to make the date format come out in the language currently being used in the document? How can I insert as a field?

sub Insert_Date
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("")

rem ----------------------------------------------------------------------
dim sText as string
sText = Format(Now(),"D MMMM YYYY")

dim args1(5) as new
args1(2).Name = "Text"
args1(2).Value = sText

dispatcher.executeDispatch(document, ".uno:InsertText", "", 0, args1())

end sub
edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by Alex Kemp
close date 2020-10-19 03:29:52.081682

3 Answers

Sort by » oldest newest most voted

answered 2017-10-30 15:30:09 +0100

updated 2017-10-31 08:03:57 +0100

My experiments show the following:

  1. StarBasic Format() run-time function accepts all the number format codes mentioned here.
  2. You may use the [$-langid] syntax to use the desired locale in the Format() output, like:

    sText = Format(Now(),"[$-41e]D MMMM YYYY") ' Thai
  3. The LangIDs might be taken from this page.

This, however, needs the parts from @Lupp's answer to get the current char locale to create complete solution.

EDIT 2017-10-31

To go with field creation, you may use this code:

sub Insert_Date_Auto
    dim document   as object
    dim dispatcher as object
    dim oLocale    as object
    oLocale = ThisComponent.CurrentController.GetViewCursor.CharLocale

    dim nFmtId as Long
    nFmtId = ThisComponent.NumberFormats.queryKey("DD MMMM YYYY", oLocale, False)
    if nFmtId = -1 then
       nFmtId = ThisComponent.NumberFormats.addNew("DD MMMM YYYY", oLocale)
    end if

    dim args1(3) as new
    args1(0).Name = "Type"
    args1(0).Value = 0 ' date
    args1(1).Name = "SubType"
    args1(1).Value = 0 ' fixed
    args1(2).Name = "Name"
    args1(2).Value = "" ' to avoid opening dialog
    args1(3).Name = "Format"
    args1(3).Value = nFmtId

    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("")
    dispatcher.executeDispatch(document, ".uno:InsertField", "", 0, args1())
end sub
edit flag offensive delete link more


@Mike Kaganski Thanks! It was time for me to learn this usage of the [$-n] prefixes to format codes.
However, there is surely an internal reference to a lookup table (even more complete) containing the info from the MS page you linked?

Lupp gravatar imageLupp ( 2017-10-30 16:10:25 +0100 )edit

Yes, this is lang.h. The LCIDs there hexadecimals with leading 0x, which should be omitted in format strings.

Mike Kaganski gravatar imageMike Kaganski ( 2017-10-30 17:48:40 +0100 )edit

A running LibO also needs to lookup the pairs of lang-description in strings and the HEX representations, most likely in both directions. How does it? How can I do by user code?

Lupp gravatar imageLupp ( 2017-10-30 23:36:58 +0100 )edit

Well, C++ implementation is using mslangid.hxx (see also isolang.cxx). I don't see direct mapping of the class to UNO.

Mike Kaganski gravatar imageMike Kaganski ( 2017-10-31 06:10:49 +0100 )edit

answered 2017-10-30 14:19:00 +0100

Lupp gravatar image

updated 2017-10-30 18:45:36 +0100

I'm afraid the answer won't help yo much because I don't know a way to get the Format fucntion of BASIC to apply locale specific format codes in a locale specific way. I post the answer nonetheless to encourage you or somone else to add the missing part. Sorry! The present state of the localization field (formatting and recognition of numbers and "special numbers") is a mess, imo. One clearly worded related question I found here. The thread did not lead to a usable answer in the end.

Based on the comments by @Mike Kaganski I reworked the answer below.

The incomplete recharged answer now:
Your code line sText = Format(Now(),"D MMMM YYYY") needs to be replaced by code where the format code depends on the current language. I cannot test with Thai.

currentLoc = getCurrentCharLocale(ThisComponent)
If TypeName(currentLoc)="Empty" Then Exit Sub 
REM Otherwise the next statement would throw an error.
Select Case currentLoc.Language REM You may concatenate additional attributes if needed.
    Case "en" : fmtC = "D MMMM YYYY"
    Case "th" : fmtC = "[$-41E]__Whatever you need__" 
                       REM I cannot test with Thai. Credits to Mike Kaganski.
    Case Else : fmtC = "YYYY-MM-DD" 
                      REM We should always use ISO 8601 except in historical texts.
End Select
sText = Format(Now(),fmtC)

To get the needed language information for the decision when selecting the case there is used a function you will also need to add to the respective BASIC module:

Function getCurrentCharLocale(pDoc)
theCtrl = pDoc.CurrentController
theVC   = theCtrl.GetViewCursor
theLoc  = theVC.CharLocale
REM If the current selection is not unambiguous regarding the Locale then
REM TypeName(theLoc) = "Empty".
REM Otherwise a CharLocale has three attributes: .Language .Country .Variant
REM A cursor with nothing selected ("Caret") should always return 
REM non-empty CharLocale except it was actually set empty (no language).
getCurrentCharLocale = theLoc
End Function

Please report everybody about ideas concerning the formatting for different locales not depending on the general UI and locale settings. Comments welcome anyway.

edit flag offensive delete link more

Comments :

You can set the locale used for controlling the formatting numbers, dates and currencies in LibreOffice Basic in Tools - Options' - Language Settings - Languages.

The same applies to the locale settings for date, time and currency formats. The Basic format code will be interpreted and displayed according to your locale setting.
Mike Kaganski gravatar imageMike Kaganski ( 2017-10-30 14:28:26 +0100 )edit

Concerning the question under discussion:
There is one locale set. The different languages used in a document are disregarded by the user code. They are regarded when inserting fields (in Writer) or when formatting numeric results in Calc cells. They are neither regarded by the TEXT() function in Calc nor by the Format() function in BASIC.
>200 locales now!. Locales seem to be the most important thing in the world. Neither Calc formulae depending on them nor user code are equipped.

Lupp gravatar imageLupp ( 2017-10-30 14:48:50 +0100 )edit

FYI, The format is the same D MMMM YYYY in Thai or English.

holy-harp gravatar imageholy-harp ( 2017-10-31 02:47:06 +0100 )edit

The Language input boxes in character properties allow for arbitrary (correct) language code input. So, despite Thai isn't there in list, you may simply enter th-TH manually (you will see that both th and th-TH turn black, while incomplete (illegal) codes will be red), and the selection language will be marked Thai (allowing to test the code). However, I still don't know if Thai locale is written to CharLocale in real life (don't we need to take it from CharLocaleComplex on a condition?).

Mike Kaganski gravatar imageMike Kaganski ( 2017-10-31 07:21:04 +0100 )edit

answered 2017-10-31 02:50:58 +0100

holy-harp gravatar image

Thanks to @Mike Kaganski, I looked at the Options - Language Settings - Languages in Writer. I changed the Locale setting to Thai. This brought up a Complex Text layout (CTL) with the default of Hindi; I changed it to Thai. I had tried to record a macro before and it inserted Hindi instead of Thai. This is why. So, I recorded a new macro. It works! Below is the code it generated. Perhaps someone can comment it so we can understand it better. It seems the trick is in the Format value of 20121. Where could we look this up? I must say I''m impressed by the caliber and depth of responses to my question - thanks!

sub Insert_Date_Auto
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("")

rem ----------------------------------------------------------------------
dim args1(5) as new
args1(0).Name = "Type"
args1(0).Value = 0
args1(1).Name = "SubType"
args1(1).Value = 0
args1(2).Name = "Name"
args1(2).Value = ""
args1(3).Name = "Content"
args1(3).Value = "0"
args1(4).Name = "Format"
args1(4).Value = 20121
args1(5).Name = "Separator"
args1(5).Value = " "

dispatcher.executeDispatch(document, ".uno:InsertField", "", 0, args1())

end sub
edit flag offensive delete link more


Do you actually claim this code can isert a date depending on the language of the surrounding text?
I would suppose it inserts a date in one specific format defined for your documents and identified by the number 20120. This is what Mike Kaganski had introduced the variable nFmtId for. Concerning the correct assignment you need to complete the 5 respective lines of his code with an alternative based on the function I posted and with your correct Thai DateFormatCode.

Lupp gravatar imageLupp ( 2017-11-01 18:36:44 +0100 )edit

Question Tools



Asked: 2017-10-30 06:58:57 +0100

Seen: 3,185 times

Last updated: Oct 31 '17