Range accepts sometimes only semicolons instead of commas - vba

I have reduced my problem to the following code example. I am using a German Excel version in which separators in normal Excel formulas are semicolons ";" instead of "," (e.g. =SUMME(A1;A3) instead of =SUM(A1,A3)).
Now the code which works different from time to time:
Sub CommasDoNotWorkAnymore()
Dim a()
Dim i%
a = Array("A1,A3,A5", "B1", "B2")
i = 0
Debug.Print Sheets(1).Range(a(i)).Address
End Sub
Normally, when starting Excel, this code works. But sometimes Excel seem to switch the accepted separators used in the Range() to semicolons untill I restart Excel. This occurs most times when rerunning the code after a runtime error.
Is this a general Excel bug? Does anybody know what is behind this behaviour? Is there some Excel-wide "local option" for the Range class?
EDIT: I just tried to convert the a(i) with CStr(a(i) but this does also not work. So no ByRef kind of problem...

If you want to control it, check first what separator is currently in use. What I guess is that you want to know the list separator:
Application.International(xlListSeparator)
Check other separators here:
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-international-property-excel
The other time I had a problem with identifying decimal separator in VBA. Finnally I was able to get it in this way:
Function GetVBAdecimalSep()
Dim a(0) As Variant
a(0) = 1 / 2
GetVBAdecimalSep = Mid(a(0), 2, 1)
End Function
Changing separator not always works. Please see this: Changing decimal separator in VBA (not only in Excel)
The best solution is to check/change locale, even temporary.
Application.LanguageSettings.LanguageID(msoLanguageIDUI)
gives the LCID which would be 1033 for English (US)

Related

How to set decimal separator in MS Access using VBA?

My software creates PAIN001.XML files directly from an Access financial database. The decimal separator must always be a dot. The numbers are formatted with:
MyText = Format(MyNumber, "#0.00")
However, the format string's dot is automatically replaced by the system decimal separator, which might be "," instead of "." !
In Excel there are easy solutions, for example:
Application.DecimalSeparator = "."
...
However, MS Access doesn't recognize this application property.
Is there a simple way to define a decimal separator within Access vba code ?
Of course, one can create a function which scans each MyText number for wrong decimal separators and replaces them with a dot, but this function would have to be called separately for each number, slowing down the code quite a lot…
The decimal separator must always be a dot.
Then use Str:
MyText = Str(MyNumber)
To convert such a string to a number use Val:
MyNumber = Val(MyText)
I guess the problem is not solveable with the decimal separator Application.DecimalSeparator = ".", even if it was supported by the Access library. It is a rather complicated issue, for the non-US users, as we are used to have , as a decimal separator.
In general, VBA considers only . as a decimal separator. Without taking care of the application default separator, the location of the user and their settings. Thus, some interesting cases could happen:
Sub TestMe()
Dim myText As String
myText = "123,42"
Debug.Print Replace(Format(myText, "#0.00"), ",", ".")
End Sub
A possible solution, that I have implemented some time ago was to use Replace() and to replace as in the gif above. It could be a bit slow indeed, but taking into account the usage of VBA and Access, extreme speed is not something the app could achieve anyway.

INDEX+MATCH ArrayFormula Return 1004

I've been using StackOverflow for months and it has answered all of my questions, expect for the issue I'm currently having. I can't seem to fix the issue, no matter the options posted on this site. Maybe you can see the issue, that I'm not seeing at the moment.
I have one FormulaArray in VBA that takes the index of an external file, matches one value (Q2) with a value in column B of the external file. Then it matches a second value (P2) with a value in column D of the external file. If there's a match on both, it'll return a value that is in column C of the external file.
Works great in Excel, but the moment I create a Selection.FormulaArray = this formula, I get a 1004 in return. The line itself is shorter than 255 characters and even breaking up the INDEX and MATCH formulas into two parts (by Dim formulapart1 and formulapart2 as string) it doesn't work.
=INDEX([ISOCODE.xlsx]ISOCODE!$A:$D;MATCH(1;([ISOCODE.xlsx]ISOCODE!$B:$B=Q2)*([ISOCODE.xlsx]ISOCODE!$D:$D=P2);0);3)
I tried the following solution that was posted on this website that worked for others, but it's not working for me, no matter what I do:
Dim theFormulaPart1 As String
Dim theFormulaPart2 As String
theFormulaPart1 = "=INDEX([ISOCODE.xlsx]ISOCODE!$A:$D;XX"
theFormulaPart2 = "MATCH(1;([ISOCODE.xlsx]ISOCODE!$B:$B=Q2)*([ISOCODE.xlsx]ISOCODE!$D:$D=P2);0);3)"
With ActiveSheet.Range("DS2")
.FormulaArray = theFormulaPart1
.Replace "XX", theFormulaPart2
End With
There are issues with how you have split the code (your theFormulaPart1 is not a valid formula on its own!) but that's not the real issue here - that's your "XY Problem".
The real issue is that when putting a Formula in via VBA, unless you are using .FormulaLocal, you must use the English localisations - this means using , intead of ; to separate the arguments. And, there is no .FormulaArrayLocal, so for an Array formula you always use the English localisation:
ActiveSheet.Range("DS2").FormulaArray = "=INDEX([ISOCODE.xlsx]ISOCODE!$A:$D,MATCH(1,([ISOCODE.xlsx]ISOCODE!$B:$B=Q2)*([ISOCODE.xlsx]ISOCODE!$D:$D=P2),0),3)"
Whenever working with excel-VBA (or with anything in general), try always to start from something smaller, that works. In your case, remove the opend worksheet and try to make it work with the one you have. Thus, here is something that works:
Sub TestMe()
Dim theFormulaPart1 As String
Dim theFormulaPart2 As String
theFormulaPart1 = "=INDEX(A:D,XX"
theFormulaPart2 = "MATCH(1,(B:B=Q2)*(D:D=P2),0),3)"
With ActiveSheet.Range("E1")
theFormulaPart1 = Replace(theFormulaPart1, "XX", theFormulaPart2)
.FormulaArray = theFormulaPart1
End With
End Sub
Once you fix it, go further and include [ISOCODE!.xlsx]

Mystery Excel semicolon mode for data validation, stops recognizeing standard comma for unknown reason

In Excel VBA how can I set cell validation so that it works in all locales?
This code works in my locale, semicolon separated
Dim mySheet As Worksheet
Set mySheet = ThisWorkbook.Worksheets("Sheet 1")
Dim myRange As Range
Dim validValues as String
validValues = "a;b;c"
Set myRange = mySheet.Cells(2, 2)
myRange.Validation.Add _
Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Formula1:=validValues
But I've seen that other locales needs comma separated
validValues = "a,b,c"
Essentially what I need is this, but I don't know how to determine 'id' in way that works in all locales.
' Internationalized delimiter
Dim id as String
id = ???
validValues = "a" & id & "b" & id & "c"
Edit:
There seems to be a "semicolon mode" of Excel that I do not understand and which I cannot reproduce reliably. I had a certain instance of Excel that got into this mode and all code run inside it worked with semicolon and not comma. I wrote a project in this instance and it worked, I would have thought I just made a mistake if not for all the code that I now have to rewrite...
Any hints in order to figure this out is appreciated.
Edit2:
After restarting Excel it changed it's mode to comma, I've been using it for a while but now this problem hit me again, Excel started using ';' (semicolon) instead of ',' (comma) as delimiter for my data validations.
This time I took a screenshot. Data validation is set to List.
Source is set to:
zero,one,both
This is the result, as you can see Excel does not care about my commas and displays all on the same line:
With source set like this it works:
zero;one;both
Result:
It is a mystery to me why Excel does this but I really need to find a way to make sure this never happens to my customer. Any help appreciated!
I have just dealed with a similar problem. I couldn't find a reason for why this happens, so I don't have a solution for good. Yet, I found a way around the problem that could be of use.
The only thing that you would need is to assign a valid value to the validated range before adding the validation.
After running your code, if the .Formula1 argument worked with semicolons, then there is no problem at all. If it didn't, the .Validation.Value property of the range returns False and you can use that as a trigger to rerun your code, replacing the semicolon separated list by a comma separated one. Then just rerun the validation.
For example:
myRange.value = "a" 'Assuming "a" is a valid value contained in the validvalues string
If myRange.Validation.Value = False Then
validvalues = replace(validvalues,";",",")
myRange.validation.modify Formula1:= validvalues
End if
Then you can clear the range value if you do not wish to have a default value shown.
I believe you are looking for a delimiter that would work on multiple scenarios (please let me know if this is not your query).
comma, semicolon, are sometimes good delimiter but often they pose serious syntax and some other string related errors .
Triple question mark ??? is also not a good choice in this case.
I prefer to go with | (the pipe) in these situations.
Sorry for the long answer :)
Microsoft says you need to use commas in VBA
https://support.microsoft.com/en-us/help/299490/data-validation-list-entries-all-on-one-line-in-excel

How to count the number of empty spaces in front of a String in VBA?

I have a YAML file which I am reading using VBA Excel plugin. I am getting a String of each line. I need to count the number of empty spaces in the front of the first line so that it will be a marker to find the next key. Let me know how to do that.
Option Explicit
Function empty_spaces(str_input)
empty_spaces = Len(str_input) - Len(LTrim(str_input))
End Function
harun24hr, your answer does not work with " My String " and similar.

Is there any way to align text in message box in vb or vba?

Is there any way to align text into the center in msgbox in VB or VBA? Does VB have any functionality to do the same?
No. The MsgBox() function is simply a wrapper for the Windows MessageBox() function and as such has no stylistic control over the dialog beyond the icon.
If you want to change it any further than this, you will need to create your own window and show that instead.
On Windows Vista+ you can use TaskDialogs that allow a lot more control.
no, but you can cheat by using spaces.
msgbox(" your message")
VBA
Some notes: http://access.mvps.org/access/bugs/bugs0035.htm AND http://www.tek-tips.com/viewthread.cfm?qid=435428 However, it is not so difficult to build your own message box, which solves all your problems.
When you are building your strings you could pad them at the beginning and end with spaces to achieve a target length. If you're using excel the worksheet function rept is handy for this.
function pad_n_center(byval mystring as string, lenmax as integer) as string
dim pad_by as integer
dim pad as string
pad_by = (lenmax - len(mystring))/2
'some more code to finesse that?
pad = worksheetfunction.rept(" ",pad_by)
pad_n_center = pad & mystring & pad
end function
As mentioned before if the msgbox still doesn't look good you can use textbox shape object (or other objects) to get the desired effect.