Inexperienced Stackoverflow user, please feel free to point me to a different forum or subforum if needed.
I created the following VBA (then also looked at other code samples online, which all seem to follow the same logic). I test in the debug window and see exactly the result (multi-line string) I expect. However, when I type the formula in a worksheet cell, I get a #Value error.
The function is spelled correctly (I actually select it in Excel from the formula auto-complete)
Excel x64 v2108, local install on Win10 x64
Any ideas why this isn't populating back into the cell with the formula?
Function ConcatCells()
'just to be safe, clear the string
ConcatCells = ""
'Loop and add each cell text with a line break
For Each cell In Selection
ConcatCells = ConcatCells & Chr(13) & cell.Text
Next
'remove the leading line break
ConcatCells = Right(ConcatCells, Len(ConcatCells) - 1)
'is the string actually being created correctly? Yes
Debug.Print ConcatCells
End Function
Add Selection As Range as parameter into your function: Function ConcatCells(Selection As Range)
After this, your function will return a value like this: OneTwoThreeFourFive
When you copy this cell and paste as value,
and after hitting F2 and Enter, you will have a view like this:
I've got an Excel spreadsheet, with a Macro, that inserts a conditional formatting, like this:
Selection.FormatConditions.Add Type:=xlExpression, Formula1:="=UND($A3=""" & lastName & """; $B3=""" & firstName & """)"
As you can see, I've used the German formula for "AND" (i.e. "UND"), and obviously, this code doesn't work as soon as I use it on a French or English version of Excel.
Usually formulas are localized automatically, but how can I insert a formula during run-time that will work on ALL versions?
Ok, thanks for helping me with this, you've helped me crack this one.
It is indeed not possible to just use English. One can use English when operating on a formula, eg. by setting coding Range("A1").formula="AND(TRUE)", but this does not work with FormatConditions.
My solution is a function that writes a formula temporarily to a cell, reads it through the FormulaLocal property, and returns the localized formula, like so:
Function GetLocalizedFormula(formula As String)
' returns the English formula from the parameter in the local format
Dim temporary As String
temporary = Range("A1").formula
Range("A1").formula = formula
Dim result As String
result = Range("A1").FormulaLocal
Range("A1").formula = temporary
GetLocalizedFormula = result
End Function
The returned formula can be used on FormatConditions, which will be re-localized or un-localized when the document is later opened on a different-language version of Excel.
I just found a very elegant solution to the problem in a German Excel forum. This doesn't write to a dummy cell but rather uses a temporary named range. I used the original idea (credit to bst) to write a translating function for both directions.
Convert localized formula to English formula:
Public Function TranslateFormula_LocalToGeneric(ByVal iFormula As String) As String
Names.Add "temporaryFormula", RefersToLocal:=iFormula
TranslateFormula_LocalToGeneric = Names("temporaryFormula").RefersTo
Names("temporaryFormula").Delete
End Function
Convert English formula to localized formula:
Public Function TranslateFormula_GenericToLocal(ByVal iFormula As String) As String
Names.Add "temporaryFormula", RefersTo:=iFormula
TranslateFormula_GenericToLocal = Names("temporaryFormula").RefersToLocal
Names("temporaryFormula").Delete
End Function
This is very handy if you need to deal with formulas in conditional formatting, since these formulas are always stored as localized formulas (but you could need their generic version, e.g. to use Application.Evaluate(genericFormula)).
Store (a trivial version of) the formula in a (hidden) cell in your workbook.
Then when you open the workbook that formula will be translated automatically by excel for the user.
Now you just have to dissect this formula in your script (find the opening bracket "(" and take the past left of that:
Use something like:
strLocalizedFormula = Mid(strYourFormula, 2, InStr(1, strYourFormula, "(") - 2)
where strYourFormula will be a copy from the formula from your worksheet.
I hope this works as I only use an English environment.
Also from reading this:
http://vantedbits.blogspot.nl/2010/10/excel-vba-tip-translate-formulas.html
I am thinking you should (only) be able to use the english version of a cell formula from VBA.
Maybe try this (untested as I only have English version insatlled)
Write your international version of the formula to an out of the way cell using Range.Formula . Then read it back from Range.FormulaLocal, and write that string to the FormatConditions
I know this thread is ages old, and someone may have found an elegant solution, but I just had the same problem where I needed to apply conditional formatting without modifying the sheet, creating temporary cell contents or named ranges. All users use English language versions of Excel, so the functions used in the formulas are the same, but the regional settings vary by location, and therefore also the parameter separater; In Norwegian, it's ";" instead of ",", much like the rest of Europe, I guess.
For example, I needed to automatically create conditional formatting, using Excel formula for the following criterion:
.FormatConditions.Add xlExpression, Formula1:="=AND(ISNUMBER(B" & I & "),B" & I & ">=" & Ul1 & ")"
Where "Ul1" is a value defined in a previous step, and it's not important for the solution.
However, I needed to be able to run this on computers with both Norwegian and English settings
I and found a very short and simple solution from Andrew Pulsom here: https://www.mrexcel.com/board/threads/french-vba-vs-english-vba.729570/. He just made the parameter separator into a variable:
If Application.International(xlDecimalSeparator) = "," Then
Sep = ";"
Else
Sep = ","
End If
Cl1 = "=AND(ISNUMBER(B" & I & ")" & Sep & "B" & I & "<" & Ul1 & ")"
Worked like a charm for me :)
I know that this only solves part of the problem, but I assume that this could apply to many international companies which use English Office installations with local regional settings.
Thanks everyone! I found the post very useful.
My solution is a combination of others, I add it in case somebody finds it useful.
Dim tempform As String
Dim strlocalform1 As String
Dim strlocalform2 As String
' Get formula stored in WorksheetA Cell O1 =IFERROR(a,b)
tempform = Worksheets("Sheet").Range("O1").Formula
' Extract from the formula IFERROR statement in local language.
strlocalform1 = Mid(tempform, 2, InStr(1, tempform, "(") - 1)
' Extract from the formula separator , (comma) in local settings.
strlocalform2 = Mid(tempform, InStr(1, tempform, "a") + 1, 1)
' Add formula in local language to desired field.
pvt.CalculatedFields.Add Name:="NewField", Formula:="=" & strlocalform1 & "FORMULA" & strlocalform2 & ")"
Hope this helps!
Please refer to the link for more explanation: https://bettersolutions.com/csharp/excel-interop/locale-culture.htm
CultureInfo baseCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo(xlapp.LanguageSettings.LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI));
// do something
System.Threading.Thread.CurrentThread.CurrentCulture = baseCulture;
Not sure if my terminology is correct but the problem is that I have a vba module that I am using to analyze data(count unique values). The formula is fine and works when after I correct excels change.
VBA line to insert formula is
ws_MachineNumber.Range("D2").FormulaLocal = _
"=SUM(IF('Roh Daten_IA'!$B$2:$B$" & lastR_RDi & "= A2, 1/(COUNTIFS('Roh Daten_IA'!$B$2:$B$" & lastR_RDi & ",MachineNumber!A2,'Roh Daten_IA'!$G$2:$G$" & lastR_RDi & ",'Roh Daten_IA'!$G$2:$G$" & lastR_RDi & ")),0))"
Which I am expecting to show up in the cell as
=SUM(IF('Roh Daten_IA'!$B$2:$B$296= A2, 1/(COUNTIFS('Roh Daten_IA'!$B$2:$B$296,MachineNumber!A2,'Roh Daten_IA'!$G$2:$G$296,'Roh Daten_IA'!$G$2:$G$296)),0))
However for a reason unbeknownst to me excel keeps making it
=SUM(IF(#'Roh Daten_IA'!$B$2:$B$296= A2, 1/(COUNTIFS('Roh Daten_IA'!$B$2:$B$296,MachineNumber!A2,'Roh Daten_IA'!$G$2:$G$296,#'Roh Daten_IA'!$G$2:$G$296)),0))
not sure why it keeps referencing it that way. Prior to this I didn't have the abs ranges and figured that was the problem but the # symbol is somehow causing the formula to operate incorrectly and it gives a result of 0 for every occurrence regardless of what the correct evaluation should give.
Thank you
I am experiencing the following issue:
The relevant line in my VBA macro reads like this
Sheets("Sheet1").Range("N" & intv).Formula = "=SUM(Sheet2!" & Cells(row_1,col_1).Address(0,0) & ":" & Cells(row_2, col_2).Address(0,0) & ")"
where intv, row_1, row_2 and col_1, col_2 are integers that will only make sense in the context of the whole macro.
Using debug.print() on this formula yields exactly the result I intend, but for some reason when I run the macro, the cell
Sheets("Sheet1").Range("N" & intv)
only displays #NAME error.
What is even more peculiar, is I can remove this error by double clicking the cell and pressing Enter - without changing the content of the cell. Using
Sheets("Sheet1").Calculate
does not resolve the error, however.
Worth noting:
I am using
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
before this line. But putting
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
before does not change the outcome. Does anybody have an idea how to fix this, or has anyone experienced something similar ?
Edit: Here is the original code.
Sheets("Übersicht").Range("N" & tcurrencyc).Formula = "=SUMME(Ergebnisse!" & Cells(resultr - activet, resultc).Address(0, 0) & ":" & Cells(resultr, resultc).Address(0, 0) & ")"
and debug.print of the formula part reads:
=SUMME(Ergebnisse!P8:P8)
as atm the variable activet is set to 0.
.Formula only accepts english formulas like: =SUM(Ergebnisse!P8:P8, Ergebnisse!Q8:Q8) English separator is ,
.FormulaLocal accepts localized formulas. So on a german Excel it would accept: =SUMME(Ergebnisse!P8:P8; Ergebnisse!Q8:Q8) German separator is ;
With VBA code I recommend always to use .Formula in combination with the English formula. This will work on any Excel world wide! Don't worry on a German Excel you will see the German Formula in your cell (it get's translated automatically) only the VBA code has the English version.
.FormulaLocal changes with every Excel language. That means your code will only work in the same language version your code is written in. So if you run the German code in a French Excel it will not work. Version number 1 will always work in every language.
I'm trying to add a formula to a specific cell using VBA. The formula needs to contain a variable which I calculated before within the VBA script.
The formula is looking like this:
ActiveCell.FormulaR1C1 =
"=IFERROR(VLOOKUP(RC[-4],tbl_LTCSREP,rngCell_NoUsed.Column,FALSE),""NO LTCS
VALUE AVAILABLE"")"
The rngCell.Column variable is the one I calculated prior to that. When I do it this way, VBA just pastes the plain text in the cell and Excel itself is not able to use the value behind the variable and the VLOOKUP gives back an error.
Thank you in advance for your support.
It pastes your variable as text because you've written it as text, not a variable.
When you write "Hello someVariable", the compiler interprets someVariable as a piece of text instead of a variable.
Solution:
"Hello " & someVariable
Or for your case:
Dim str As String
str = "=IFERROR(VLOOKUP(RC[-4],tbl_LTCSREP, " & rngCell_NoUsed.Column & ",FALSE),""NO LTCS VALUE AVAILABLE"")"
ActiveCell.FormulaR1C1 = str
You'll see that we've closed off the first part of the string by adding a ". Then, we tell the compiler to concatenate (&) with the contents of the variable. Then we add another concatenation operator, and we've also added another " to signify that we are once again inputting pure text.
The result can be thought of more simply in this way:
"text" & content_from_a_variable & "more text"
That works perfectly fine.
I already tried to do that in one step like:
ActiveCell.FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-4],tbl_LTCSREP," & _
rngCell_NoUsed.Column & ",FALSE),""NO LTCS VALUE AVAILABLE"")"
This did not work either.
But I got it. Thanks again.