Excel VBA - using left function with find - vba

I'm trying to use the worksheet function "left" in conjunction with "find" to determine a string variable in VBA. However, excel interprets the find function as a VBA function, which yields an error message when resolving.
Below my code:
...
Else
MSa = MSa & Left(Range("D22"), Find(".", Range("D22")) - 1) & " " & Range("D25").Value & "."
Range("Q7").Value = MSa
End If
...
where MSa is a string. Can you please advise as to how I can best solve this problem?
Many thanks in advance.

The short answer is to use Application.WorksheetFunction.Find. However I wouldn't use that. Read below.
So on Sheet1 I enter abc.def into cell A1.
In another cell I enter =LEFT(A1,FIND(".",A1)-1) and get the value abc.
To call the same functions in VBA I would write
variable = Left(Sheet1.[A1],Application.WorksheetFunction.Find(".",Sheet1.[A1])-1)
Calling Excel worksheet functions from VBA does have some disadvantages though (it's harder to debug and slower). It's better to use the native VBA function InStr which works much like the worksheet function Find. The parameters are in a different order, but the results are the same. So I would write
variable = Left(Sheet1.[A1],InStr(Sheet1.[A1],".")-1)

The InStr method is the equivalent of the worksheet function Find, to use it:
MSa = MSa & Left(Range("D22"), InStr(Range("D22"), ".") - 1) & " " & Range("D25").Value & "."

In order to use the worksheet function Find you need to fully qualify it as follows;
Application.WorksheetFunction.Find
Using Find on its on and VBA will assume that it is a VBA function. Same goes for match.

Related

VBA coding for Sumproduct() function with condition and named column range

Excel 2013
I am trying to use my excel sumproduct function in VBA but no luck.
I have two formulas one is without condition that work fine in VB but the other one with condition is not working. Here are the formulas
formula with no condition work fine in Excel
=SUMPRODUCT(tblProduct[Qty],tblProduct[amount])
and its VBA code that working fine in VBA excel userform
vGrndTot = Application.SumProduct(Range("tblProduct[Qty]"), Range("tblProduct[amount]"))
Conditional SUMPRODUCT working fine in excel
=SUMPRODUCT(--(tblProduct[prodID]="XYZ"),tblProduct[Qty],tblProduct[amount])
and its VBA code that i am tying to use but it not work (error type missmatch)
vTot = Application.SumProduct(--(Range("tblProduct[prodID]") = "XYZ"), Range("tblProduct[Qty]"), Range("tblProduct[amount]"))
any hint what I am doing wrong ?
I read so many question some said use evaluate (that too didn't work) some said use +0, or * 1 but i had no luck.
It took my 2 days but finally I got it with 2 key point
to evaluate the formula must appears EXACTLY SAME as in the worksheet cell including doublequotes. and to have doublequotes it need to have 4 doublequotes, strange though (see the vbDoubleQuote value below).
here is the final solution
' vProdID = coming from tblProdList one by one
vbDoubleQuote = """"
vFormula2Evalaute = "=SUMPRODUCT(--(tblProduct[prodID]=" & vbDoubleQuote & vProdID & vbDoubleQuote & ") ,tblProduct[Qty],tblProduct[UP])"
MsgBox Evaluate(vFormula2Evalaute)

Insert formula into cell with VBA: Object-defined error

I'm trying to use this in my VBA code:
ActiveSheet.Range("A1:A1:).Formula = "='Sheet1'!A1" & Chr(34) & Chr(47) & Chr(34) & "'Sheet1'!A2"
This gives me Error: 1004, Object-defined error.
I'd like to see in the cell formula that:
='Sheet1'!A1"/"'Sheet1'!A2
And if the value of the A1 cell is 10 and the A2 value is 20, the cell value should look like that: 10/20
What can be the problem?
I assume you want the formula to either read:
='Sheet1'!A1&"/"&'Sheet1'!A2 (so: textual concatenation of A1 & A2 with a "/" in between)
or
='Sheet1'!A1/'Sheet1'!A2 (so: the result of dividing A1 by A2)
Check the result of your formula: it generates neither :) (it results in an invalid formula) And, as Jordan answered, your VBA used a colon instead of a double quote.
UPDATE (read over the fact that you asked for textual concatenation in your question, and also adding a solution)
It's best to check the result of your formula build-up while stepping through VBA with the debugger (F8): it generates an invalid formula, on which Excel will no doubt give you an error when you try to set it. The result doesn't contain any & characters to concatenate the values of A1 & A2 with the "/" in between.
The correct formula should be:
='Sheet1'!A1&"/"&'Sheet1'!A2
This is achieved by:
ActiveSheet.Range("A1").Formula = "='Sheet1'!A1&""/""&'Sheet1'!A2"
(note that you can embed a " in a VBA string by doubling it; in this case that is clearer to read than using Chr(34) for the "'s)
First of all you have a colon instead of a speech mark within Range. You could try something like:
ActiveSheet.Range("A1").Value = Sheet("Sheet1").Range("A1").Value & "/" & Sheet("Sheet1").Range("A2").Value
I'd also recommend not using ActiveSheet as much as possible and also referring to the workbook in references. If you want to refer to the workbook that contains the VBA code you can use ThisWorkbook.

Long nested IF statement creates runtime error 1004 in Excel VBA

I have a formula that works perfectly well in a spreadsheet, but when I try to automate the creation of the formula using VBA, I get the 1004 run time error.
I have a 3 stage process, each with a start and finish date (so 6 separate date columns). This formula looks at the series dates and calculates the time lost between each stage using the NETWORKDAYS function.
I thought the simple way to overcome this problem was to record a macro of me pasting this formula into a cell, which would generate the required VBA code that I could then adapt, but even using this method causes the 1004 error.
I'm wondering whether it's the length of the formula that's the problem? I've tried replacing the double quotation marks with & Chr(34) & Chr(34) & and I've tried assigning the formula to a variable. I can get it to work if I add it as text using .value instead of .formulaR1C1, or if I add an apostrophe to the start of the formula string. It appears to be the fact that its a formula that causes the problem. Any help is greatly appreciated.
The formula from the cell in the spreadsheet:
=IF(AND(I2="",J2="",K2="",L2=""),"",IF(AND(G2="",H2="",K2="",L2=""),"",IF(AND(G2="",H2="",I2="",J2=""),"",IF(AND(H2<>"",I2<>"",J2<>"",K2<>""),IF(NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2<1,"",NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2),IF(AND(H2<>"",I2<>""),IF(NETWORKDAYS(H2,I2)-2<1,"",NETWORKDAYS(H2,I2)-2),IF(AND(H2<>"",K2<>""),IF(NETWORKDAYS(H2,K2)-2<1,"",NETWORKDAYS(H2,K2)-2),IF(AND(J2<>"",K2<>""),IF(NETWORKDAYS(J2,K2)-2<1,"",NETWORKDAYS(J2,K2)-2),"")))))))
The code that the macro records when I enter the formula into the cell:
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC[-10]="""",RC[-9]="""",RC[-8]="""",RC[-7]=""""),"""",IF(AND(RC[-12]="""",RC[-11]="""",RC[-8]="""",RC[-7]=""""),"""",IF(AND(RC[-12]="""",RC[-11]="""",RC[-10]="""",RC[-9]=""""),"""",IF(AND(RC[-11]<>"""",RC[-10]<>"""",RC[-9]<>"""",RC[-8]<>""""),IF(NETWORKDAYS(RC[-11],RC[-10])-2+NETWORKDAYS(RC[-9],RC[-8])-2<1,"""",NETWORKDAYS(RC[-11],RC[-10])-2+NETWORKDAYS(RC[" & _
"8])-2),IF(AND(RC[-11]<>"""",RC[-10]<>""""),IF(NETWORKDAYS(RC[-11],RC[-10])-2<1,"""",NETWORKDAYS(RC[-11],RC[-10])-2),IF(AND(RC[-11]<>"""",RC[-8]<>""""),IF(NETWORKDAYS(RC[-11],RC[-8])-2<1,"""",NETWORKDAYS(RC[-11],RC[-8])-2),IF(AND(RC[-9]<>"""",RC[-8]<>""""),IF(NETWORKDAYS(RC[-9],RC[-8])-2<1,"""",NETWORKDAYS(RC[-9],RC[-8])-2),"""")))))))"
Consider:
Sub EvilFormula()
Dim st As String, DQ As String
DQ = Chr(34) & Chr(34)
st = "=IF(AND(I2=~,J2=~,K2=~,L2=~),~,IF(AND(G2=~,H2=~,K2=~,L2=~),~,IF(AND(G2=~,H2=~,I2=~,J2=~),~,IF(AND(H2<>~,I2<>~,J2<>~,K2<>~),IF(NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2<1,~,NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2),IF(AND(H2<>~,I2<>~),IF(NETWORKDAYS(H2,I2)-2<1,~,NETWORKDAYS(H2,I2)-2),IF(AND(H2<>~,K2<>~),IF(NETWORKDAYS(H2,K2)-2<1,~,NETWORKDAYS(H2,K2)-2),IF(AND(J2<>~,K2<>~),IF(NETWORKDAYS(J2,K2)-2<1,~,NETWORKDAYS(J2,K2)-2),~)))))))"
st = Replace(st, "~", DQ)
ActiveCell.Formula = st
End Sub
Here we first construct a String that represents the formula, but uses tildas in place of pairs of double-quotes. We replace the tildas and deposit the formula.I use this to avoid migraine headaches.

Writing formula into an Excel Range with Option Strict On

Is it possible to write formulas across a range in Excel from VB.Net? I'm using a String array to hold a list of formulas that I would like to apply to an Excel range, instead of looping through and writing them one at a time.
This line is what I am attempting to use to write to a range:
xlWorkSheet.Range("AF" & intCurrentRow.ToString & ":AG" & intCurrentRow.ToString).Formula = formulas
The formula is being written to Excel, but Excel is actually displaying the formula, instead of the calculated value. If I write each formula to each cell like this:
xlWorkSheet.Range("AF" & intCurrentRow.ToString).Formula = formulas(0)
xlWorkSheet.Range("AG" & intCurrentRow.ToString).Formula = formulas(1)
It works perfectly fine and Excel displays the calculated values as it should. Almost seems like I'm missing a step but I haven't been able to find anything in my research.
As soon as I hit post I figured out the problem. Instead of using the .Formula property of an Excel.Range, you have to use the .FormulaArray property instead.
xlWorkSheet.Range("AF" & intCurrentRow.ToString & ":AG" & intCurrentRow.ToString).FormulaArray = formulas

Excel Macro, inserting internationally valid formula during run-time

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;