Home » excel » excel vba – Using LOCALE_NAME_USER_DEFAULT system constant in vba

excel vba – Using LOCALE_NAME_USER_DEFAULT system constant in vba

Posted by: admin April 23, 2020 Leave a comment

Questions:

Questions

  • Can I use the LOCALE_NAME_USER_DEFAULT system constant in VBA, or do I need to use the GetUserDefaultLocaleName() function instead?
  • If I can use LOCALE_NAME_USER_DEFAULT system constant, how do I obtain its value?

Background

I use vba to convert the system List Separator value from , to |, restart Excel, use vba to make a needed csv with the | separator, then restore the List Separator value to default and close Excel.

Sometimes the list separator does not switch as expected, so now I am adapting the method found here
to develop a safeguard that checks the current value to make sure it is |.

Microsoft currently recommends that we use the more current GetLocaleInfoEx() instead of GetLocaleInfo() for interoperability purposes.

I’m having a hard time obtaining the value of the LOCALE_NAME_USER_DEFAULT system constant in VBA that the documentation mentions. Here’s the relevant snippet of what I have so far:

Private Const LOCALE_SLIST = &HC
Private Const LOCALE_NAME_MAX_LENGTH = 85
'Private Const LOCALE_NAME_USER_DEFAULT <-- stuck here, it wants me to declare it = to something, but I want the system value

'Get Locale Info
Private Declare Function GetLocaleInfoEx _
Lib "kernel32" ( _
ByVal lpLocaleName As String, _
ByVal LCType As Long, _
ByVal lpLCData As String, _
ByVal cchData As Long) As Long


Sub SubName()

    Dim lpLCData As String

        Long1 = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SLIST, lpLCData, 0)

Can you please help me figure out how to obtain the system constant for
LOCALE_NAME_USER_DEFAULT so I can use this function in VBA similarly to the C example found here:

https://stackoverflow.com/a/17674047/4691433

How to&Answers:

I don’t have ready access to a copy of winnls.h but if I recall, it should just be NULL.

That said, keep in mind that the calling convention you’re using will return the size of the buffer (in lpLCData) that you need to pass to GetLocaleInfoEx for the given parameters. For functions with this calling convention, I’d get into the habit of always checking for buffer size first, sizing your own string buffer, and then making the actual call with the returned buffer size. Also note that using GetLastError can make debugging API calls from much easier. Give this a shot:

Private Const LOCALE_SLIST = &HC
Private Const LOCALE_NAME_USER_DEFAULT = vbNullString

Private Declare Function GetLocaleInfoEx Lib "kernel32" ( _
    ByVal lpLocaleName As String, ByVal LCType As Long, ByVal lpLCData As String, _
    ByVal cchData As Long) As Long
Private Declare Function GetLastError Lib "kernel32" () As Long

Private Sub Example()

    Dim lpLCData As String
    Dim bufferSize As Long

    'Get return buffer size.
    retVal = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SLIST, lpLCData, 0)
    'GetLocaleInfoEx returns 0 on failure.
    If retVal <> 0 Then
        'Use that value to size your buffer...
        lpLCData = String(retVal, Chr$(0))
        '...and pass the appropriate buffer/size parameters.
        If GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SLIST, lpLCData, retVal) <> 0 Then
            Debug.Print lpLCData
        Else
            Debug.Print GetLastError
        End If
    Else
        Debug.Print GetLastError
    End If

End Sub