VBA function to get a Windows Region setting from Access using Excel's International property.
I'm getting ready to post a CalendarMaker tool for Access to make monthly calendars by drawing on an Access report. One of the things it does is use whatever language you've set up with Windows for the day headings and month names. It also lets you change which day of the week you want to start with, since some start weeks with Sunday, Monday, or maybe another day. Initially, the combo list is set with English day names. If you're in another country, the list of day names can be in your language.
When the language in the Windows Region settings isn't English, there's a command button you can click to read Windows Region settings. The VBA code calls the Get_Excel_International function to get the ListSeparator (5) and then constructs a value list of day numbers and day names for the combobox RowSource so when you pick the first day for each week, the day names can be in whatever language you're using.
After you read a setting, you might wish to store it so loading is faster next time. You can use a field in a table, or an object property. Here is code to get and set properties.
'*************** Code Start ***************************************************** ' module name: mod_aExcel_International_s4p ' http://msaccessgurus.com/VBA/Code/aExcel_International.htm '------------------------------------------------------------------------------- ' Purpose : read Windows Region International settings using Excel ' Author : crystal (strive4peace) ' License : below code ' Code List: www.msaccessgurus.com/code.htm '------------------------------------------------------------------------------- ' module level variables '------------------------------------------------------------------------------- 'dimension Excel Application object 'LATE BINDING Dim oExcel As Object 'Excel.Application 'EARLY BINDING 'Dim oExcel As Excel.Application 'does Excel need to be Quit? Dim pBooQuit As Boolean '------------------------------------------------------------------------------- ' ExcelOpen '------------------------------------------------------------------------------- Private Function ExcelOpen() As Boolean '180307 strive4peace, 191129 'Open or Use Excel so it can be used. Set oExcel 'this procedure is Private and will be called if needed On Error Resume Next ExcelOpen = False pBooQuit = False Err.Clear 'use Excel if it is already running Set oExcel = GetObject(, "Excel.Application") If Err.Number <> 0 Then 'not running, open Excel Set oExcel = CreateObject("Excel.Application") 'Quit Excel when done pBooQuit = True End If 'set return value. True if oExcel is set ExcelOpen = Not (oExcel Is Nothing) End Function '------------------------------------------------------------------------------- ' ExcelClose '------------------------------------------------------------------------------- Public Sub ExcelClose() 'quit Excel and release oExcel object variable 'this procedure is Public and must be explicitely called On Error Resume Next If pBooQuit Then If Not oExcel Is Nothing Then oExcel.Quit End If pBooQuit = False End If Set oExcel = Nothing Debug.Print Now() & ", Excel released" End Sub '------------------------------------------------------------------------------- ' Get_Excel_International '------------------------------------------------------------------------------- Function Get_Excel_International( _ piIndex As Integer _ , Optional pvDefaultValue As Variant _ ) As Variant 'strive4peace 180309, 180718, 191122 'RETURN ' Windows region setting using Excel 'PARAMETERS ' piIndex = the numeric value of a constant 'EXAMPLE ' sListSeparator = Get_Excel_International(5, ";") ' sColumnSeparator = Get_Excel_International(14, ",") ' 'set up error handler On Error GoTo Proc_Err Dim vValue As Variant 'initialize return value If Not IsNull(pvDefaultValue) Then Get_Excel_International = pvDefaultValue Else Get_Excel_International = Null End If 'open Excel if necessary If oExcel Is Nothing Then 'this is kept open so you can get more than one setting 'without having to initialize Excel again If Not ExcelOpen() Then Exit Function End If 'get value for setting vValue = oExcel.International(piIndex) Get_Excel_International = vValue Proc_Exit: On Error Resume Next Exit Function Proc_Err: Resume Proc_Exit End Function '------------------------------------------------------------------------------- ' launch '------------------------------------------------------------------------------- Sub launch_Get_Excel_International() '191129 strive4peace 'show various international settings 'CALLS ' Get_Excel_International Dim sMsg As String 'get CountryCode using Excel international property sMsg = "CountryCode Is " & Get_Excel_International(1) '24HourClock, 33 sMsg = sMsg & vbCrLf _ & "Clock Is " & _ IIf(CBool(Get_Excel_International(33)), "24", "12") _ & "-hour clock" 'ListSeparator, 5 sMsg = sMsg & vbCrLf _ & "ListSeparator is" & Get_Excel_International(5) Debug.Print sMsg MsgBox sMsg, , "International Settings" 'close Excel (quit and release) Call ExcelClose End Sub ' You may freely use and share this code ' provided this license notice and comment lines are not changed; ' code may be modified provided you clearly note your changes. ' You may not sell this code alone, or as part of a collection, ' without my handwritten permission. ' All ownership rights reserved. Use at your own risk. ' ~ crystal (strive4peace) www.msaccessgurus.com '*************** Code End *******************************************************
When Get_Excel_International is called, if an Excel object variable (reference) needs to be set (oExcel Is Nothing), ExcelOpen is called. If Excel is already open, that reference is used so loading is faster. If Excel isn't open, a new instance is created. Then the Excel application International property is read for the passed index number. That value is assigned as the function return value. Read however many values you want. When done, call ExcelClose to quit Excel if you started it, and release the Excel reference.
This module has three procedures: one to open Excel, one to close Excel, and one to read an international setting, given an index. It is done this way so you can initialize Excel and then get however many settings you want before releasing Excel.
create or use an existing Excel application and set module level object variable, oExcel, so it can be used multiple times
Quit Excel if it was started, and release the oExcel Excel application object variable.
Return a Windows region setting given an index number. A list of index numbers for the Excel application International property is below.
piIndex = the numeric value you want the setting for. Numbers between 1 and 45 are documented. Refer to one of the lists below for the number you want to use.
Excel is a comfort zone for a lot of developers and power-users. Using it to get a single setting is a lot of extra overhead, and not very efficient. Never-the-less, it is a way.
As Branislav pointed out, it is slow and not without problems. If you see this dialog box:
you can switch to Excel and get out of the formula bar, or dialog box, or whatever is preventing Access from using Excel. Once the problem is corrected, the code running in Access can finish.
You can get international settings using other methods. See Daniel Pineault's blog article on devhut, "Special Characters and Internationalization of an Application"
Click
HERE
to download the zipped BAS file to get International settings using automation with Excel.
This can be run from Access, or any Microsoft Office application usng VBA.
It can run from Excel too -- but oExcel would simply be Application,
and you wouldn't use OpenExcel or CloseExcel.
(2 kb, unzips to a module BAS file)
index | Setting Name | Constant Name | Data Type | Category |
---|---|---|---|---|
1 | CountryCode | xlCountryCode | Long | Country / Region Settings |
2 | CountrySetting | xlCountrySetting | Long | Country / Region Settings |
3 | DecimalSeparator | xlDecimalSeparator | String | Separators |
4 | ThousandsSeparator | xlThousandsSeparator | String | Separators |
5 | ListSeparator | xlListSeparator | String | Separators |
6 | UpperCaseRowLetter | xlUpperCaseRowLetter | String | Brackets and Braces |
7 | UpperCaseColumnLetter | xlUpperCaseColumnLetter | String | Brackets and Braces |
8 | LowerCaseRowLetter | xlLowerCaseRowLetter | String | Brackets and Braces |
9 | LowerCaseColumnLetter | xlLowerCaseColumnLetter | String | Brackets and Braces |
10 | LeftBracket | xlLeftBracket | String | Brackets and Braces |
11 | RightBracket | xlRightBracket | String | Brackets and Braces |
12 | LeftBrace | xlLeftBrace | String | Brackets and Braces |
13 | RightBrace | xlRightBrace | String | Brackets and Braces |
14 | ColumnSeparator | xlColumnSeparator | String | Separators |
15 | RowSeparator | xlRowSeparator | String | Separators |
16 | AlternateArraySeparator | xlAlternateArraySeparator | String | Separators |
17 | DateSeparator | xlDateSeparator | String | Date and Time |
18 | TimeSeparator | xlTimeSeparator | String | Date and Time |
19 | YearCode | xlYearCode | String | Date and Time |
20 | MonthCode | xlMonthCode | String | Date and Time |
21 | DayCode | xlDayCode | String | Date and Time |
22 | HourCode | xlHourCode | String | Date and Time |
23 | MinuteCode | xlMinuteCode | String | Date and Time |
24 | SecondCode | xlSecondCode | String | Date and Time |
25 | CurrencyCode | xlCurrencyCode | String | Currency |
26 | GeneralFormatName | xlGeneralFormatName | String | Country / Region Settings |
27 | CurrencyDigits | xlCurrencyDigits | Long | Currency |
28 | CurrencyNegative | xlCurrencyNegative | Long | Currency |
29 | NoncurrencyDigits | xlNoncurrencyDigits | Long | Currency |
30 | MonthNameChars | xlMonthNameChars | Long | Date and Time |
31 | WeekdayNameChars | xlWeekdayNameChars | Long | Date and Time |
32 | DateOrder | xlDateOrder | Long | Date and Time |
33 | 24HourClock | xl24HourClock | Boolean | Date and Time |
34 | NonEnglishFunctions | xlNonEnglishFunctions | Boolean | Measurement Systems |
35 | Metric | xlMetric | Boolean | Measurement Systems |
36 | CurrencySpaceBefore | xlCurrencySpaceBefore | Boolean | Currency |
37 | CurrencyBefore | xlCurrencyBefore | Boolean | Currency |
38 | CurrencyMinusSign | xlCurrencyMinusSign | Boolean | Currency |
39 | CurrencyTrailingZeros | xlCurrencyTrailingZeros | Boolean | Currency |
40 | CurrencyLeadingZeros | xlCurrencyLeadingZeros | Boolean | Currency |
41 | MonthLeadingZero | xlMonthLeadingZero | Boolean | Date and Time |
42 | DayLeadingZero | xlDayLeadingZero | Boolean | Date and Time |
43 | 4DigitYears | xl4DigitYears | Boolean | Date and Time |
44 | MDY | xlMDY | Boolean | Date and Time |
45 | TimeLeadingZero | xlTimeLeadingZero | Boolean | Date and Time |
Using a Numberz table with sequential Num field, you can get a list of your international settings using the Get_Excel_International function by making a query in Access with this SQL Statement:
SELECT Numberz.Num AS idx , Get_Excel_International([num]) AS Valu FROM Numberz WHERE ( Numberz.Num Between 1 And 45 ) ORDER BY Numberz.Num;
Here is a list of index with US value by category and setting name that shows English (United States) values gotten by using the query above :
Category | Setting Name | index | Value, US |
---|---|---|---|
Brackets and Braces | LeftBrace | 12 | { |
Brackets and Braces | LeftBracket | 10 | [ |
Brackets and Braces | LowerCaseColumnLetter | 9 | c |
Brackets and Braces | LowerCaseRowLetter | 8 | r |
Brackets and Braces | RightBrace | 13 | } |
Brackets and Braces | RightBracket | 11 | ] |
Brackets and Braces | UpperCaseColumnLetter | 7 | C |
Brackets and Braces | UpperCaseRowLetter | 6 | R |
Country / Region Settings | CountryCode | 1 | 1 |
Country / Region Settings | CountrySetting | 2 | 1 |
Country / Region Settings | GeneralFormatName | 26 | General |
Currency | CurrencyBefore | 37 | -1 |
Currency | CurrencyCode | 25 | $ |
Currency | CurrencyDigits | 27 | 2 |
Currency | CurrencyLeadingZeros | 40 | -1 |
Currency | CurrencyMinusSign | 38 | 0 |
Currency | CurrencyNegative | 28 | 0 |
Currency | CurrencySpaceBefore | 36 | 0 |
Currency | CurrencyTrailingZeros | 39 | -1 |
Currency | NoncurrencyDigits | 29 | 2 |
Date and Time | 24HourClock | 33 | 0 |
Date and Time | 4DigitYears | 43 | -1 |
Date and Time | DateOrder | 32 | 0 |
Date and Time | DateSeparator | 17 | / |
Date and Time | DayCode | 21 | d |
Date and Time | DayLeadingZero | 42 | 0 |
Date and Time | HourCode | 22 | h |
Date and Time | MDY | 44 | -1 |
Date and Time | MinuteCode | 23 | m |
Date and Time | MonthCode | 20 | m |
Date and Time | MonthLeadingZero | 41 | 0 |
Date and Time | MonthNameChars | 30 | 3 |
Date and Time | SecondCode | 24 | s |
Date and Time | TimeLeadingZero | 45 | 0 |
Date and Time | TimeSeparator | 18 | : |
Date and Time | WeekdayNameChars | 31 | 3 |
Date and Time | YearCode | 19 | y |
Measurement Systems | Metric | 35 | 0 |
Measurement Systems | NonEnglishFunctions | 34 | 0 |
Separators | AlternateArraySeparator | 16 | @ |
Separators | ColumnSeparator | 14 | , |
Separators | DecimalSeparator | 3 | . |
Separators | ListSeparator | 5 | , |
Separators | RowSeparator | 15 | ; |
Separators | ThousandsSeparator | 4 | , |
Access is powerful, but can't do everything. Fortunately, Access works well with other Microsoft Office Applications to do what needs to be done.
It seems like there should be a way to get settings with Access, nice that Excel can step in ~
here's the link to copy:
http://msaccessgurus.com/VBA/Code/aExcel_International.htm
Let's communicate, collaborate, and appreciate ... we all get better by sharing.
Email me anytime at info@msAccessGurus
Do you have a project that could benefit from an expert developer helping you? Let's connect and build your application together. I love teaching and developing, and look forward to hearing from you. ~ crystal