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.
Related
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;
x = Application.GetOpenFilename(Title:="Please Select the required File")
lNewBracketLocation = InStrRev(x, Application.PathSeparator)
x = Left$(x, lNewBracketLocation) & "[" & Right$(x, Len(x) - lNewBracketLocation)
Sheets("T0").Range("AC2").FormulaR1C1 = "=IFERROR(VLOOKUP(LEFT(RC[-28],8),'" & x & "]SheetName'!C1:C3,3,0,)""Not Available"")"
I am asking the user to select the file which the user needs to perform the mapping task and for that I am using the above code, but it isn't working.
The error comes from a syntax error in your formula. So Excel (not VBA) complains about that error by raising an "application-defined" error to VBA, and VBA shows it to you. You simply cannot enter an invalid formula into a cell. If you try manually from Excel, you will get something like "There is an error with that formula".
Now, while it's hard to write a complicated formula in Excel, it's even harder to get it right from VBA. Following things can help to find the problem:
(1) Don't write the formula direct into the excel range. Use an intermediate variable:
Dim formula as string
formula = "=IFERROR(VLOOKUP(LEFT(RC[-28],8),'" & x & "]SheetName'!C1:C3,3,0,)""Not Available"")"
Debug.Print formula
Sheets("T0").Range("AC2").FormulaR1C1 = formula
(2) Write the formula into Excel manually, keep the cell active, switch to the VBA environment and type in the immediate window:
? activecell.FormulaR1C1
Compare the result with the content of the formula-variable. If they are not identically, you probably have found your problem.
In your case, you have a misaligned comma in the formula. Look at C1:C3,3,0,) - it should have the closing parenthesis before the comma: C1:C3,3,0),
"=IFERROR(VLOOKUP(LEFT(RC[-28],8),'" & x & "]SheetName'!C1:C3,3,0),""Not Available"")"
I cannot guarantee that this the only error in the formula - but I hope it can help to narrow down such problems.
I have a database dump of data I need to regularly format. I'm trying to make a macro for this and am about 90% there.... The data dump is in a CSV elsewhere. My macro is in a workbook (Toolwb) and contains a couple macros, a look up table sheet(LookUpSheet), and a sheet with some formulas on it(FormulaSheet).
I'm coming across an issue with my formula that I am copying from my FormulaSheet that uses VLOOKUP on my LookUpSheet. Since I am running the code on a different workbook, I need to copy the formula over with the reference to Toolwb in it... And from what I can tell, Toolwb does not like formulas that specify Toolwk in the formula. It just edits them out and then breaks when the vba copies it over to the data dump. So to get around this I changed the cell to be Text type instead of general. Perfect! Copies over great.... But... I can't seem to get the formula to "refresh" once its in data dump cell. I have to open the cell and hit enter for it to refresh and evaluate the data.
I've tried changing the cell General after pasting it and then set it to auto calculate. I've also tried the formula refresh buttons. What am I missing?
I would just as happily paste this from vba instead of a cell, but I'm having a hard time getting the quotes in syntax.
=RIGHT(VLOOKUP(VALUE(CONCATENATE(B2,".",IF(LEN(C2)<2,CONCATENATE("0",C2),C2))),'[Toolwb]LookUpSheet'!$C$2:$D$4419,2,TRUE),LEN(VLOOKUP(VALUE(CONCATENATE(B2,".",IF(LEN(C2)<2,CONCATENATE("0",C2),C2))),'[Toolwb.xlsm]LookUpSheet'!$C$2:$D$4419,2,TRUE))-6)
"." can be replaced with CHAR(46).
CONCATENATE(0,C2) is the same as CONCATENATE("0",C2). The result will still be a string with a leading zero.
.Address(External:=True) will produce a fully qualified workbook/worksheet/range reference as an address string including any necessary punctuation.
I'm a little unclear on why $C$2:$D$4419 needs to be specified instead of $C:$D.
IF(LEN(C2)<2,CONCATENATE("0",C2),C2) is simpler as RIGHT("00"&C2, 2)
Code:
dim Toolwb as workbook, Toolws as worksheet, Toolrng as range
set Toolwb = workbooks("some workbook")
set Toolws = Toolwb.worksheets("LookUpSheet")
set Toolrng = Toolws.Range("C2:D4419")
Range("A1").Formula = _
"=RIGHT(VLOOKUP(VALUE(CONCATENATE(B2, CHAR(46), RIGHT(""00""&C2, 2))), " & Toolrng.Address(External:=True) & ", 2, TRUE), LEN(VLOOKUP(VALUE(CONCATENATE(B2, CHAR(46), RIGHT(""00""&C2, 2))), " & Toolrng.Address(External:=True) & ", 2, TRUE))-6)"
I haven't tested that but it looks right.
You might also try this adaptation using REPLACE that removes the first 6 characters and effectively cuts your formula in half.
Range("A1").Formula = _
"=REPLACE(VLOOKUP(VALUE(CONCATENATE(B2, CHAR(46), RIGHT(""00""&C2, 2))), " & Toolrng.Address(External:=True) & ", 2, TRUE), 1, 6, """")"
Ricardo A solved this for me in a comment.
"Have you tried in VBA newWorkbook.Sheets("Sheet1").Range("A2").Formula = formulaWorkbook.Sheets("FormulaSheet").Formula"
Worked perfectly!
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.
I am trying to have some vba code to place the value of a formula and text into a specific cell. I want the code to say Leads:(value of formula). Currently my code runs the formula and places the value in the correct box. I just do not know how to add the text with it. The code I have is written below.
ws.Range("$B$1").Formula = "=COUNTIF(E:E,""Lead"")"
A custom Range.NumberFormat property will give you the displayed result while leaving the actual raw value in a numerical form for possible further computation or comparison.
with ws
with .range("B1") '<~~ no need for absolute $ anchors here
.formula = "=COUNTIF(E:E,""Lead"")"
.numberformat = "[=1]L\e\a\d\: 0;L\e\a\d\s\: 0"
end with
end with
Try this:
ws.Range("$B$1").Formula = "=""Leads:("" & COUNTIF(E:E,""Lead"")&"")"""
so that it ends up like the following when applied:
="Leads:(" & COUNTIF(E:E,"Lead")&")"