Multiple nested if(ISNUMBER(FIND... is required - excel

Is it possible to do so?
Sub test()
r = ActiveSheet.Range("v" & Rows.Count).End(xlUp).Row
Range("$W2:$W" & r & " ").Formula=
IF(ISNUMBER(FIND("7212",K2)),"laptop",
IF(ISNUMBER(FIND("774",K2)),"laptop",
IF(ISNUMBER(FIND("7745",K2)),"laptop",
IF(ISNUMBER(FIND("234",K2)),"desktop","NO")))
End Sub
I have to apply conditions like this on if condition but I am unable to achieve this.
Kindly anyone help on this

You need to enclose your formula in double quotes, but in order to do so, you need to double the double quotes within your formula, something like this:
Range("$W2:$W" & r & " ").Formula = "IF(ISNUMBER(FIND(""7212"",K2)),""laptop"", IF(ISNUMBER(FIND(""774"",K2)),""laptop"", IF(ISNUMBER(FIND(""7745"",K2)),""laptop"", IF(ISNUMBER(FIND(""234"",K2)),""desktop"",""NO"")))"
(Sorry for the bad formatting, but VBA does not allow multiline strings)
By the way, I've just edited your formula in order for it to work, but I don't understand your logic: your logic says:
If <condition1>
then "laptop"
else if <condition2>
then "laptop"
else if <condition3>
then "laptop"
else "desktop"
end if
end if
end if
Generally, for such a situation, the following logic is used:
if <condition1> OR <condition2> OR <condition3>
then "laptop"
else "desktop"
end if
This reduces the number of if-loops and makes it more readable.

Related

VBA Dynamically Building A Formula From An Array

I am trying to dynamically construct a formula based on an array that I have generated from a cell (separated by commas), as there is a varying amount of elements in the array I need to append a new "formula block" with the updated element to use in a if statement that is generated after the for each loop. VBA is throwing a type mismatch error in the InvestigateFormula = line, here is my code:
For Each Type In ToIgnore()
InvestigateFormula = "(ISNUMBER(SEARCH(*" & ToIgnore(Type) & "*," & _
AssetTypesCol & "2)),"
FullFormula = InvestigateFormula & FullFormula
Next Asset
FinalInvestigateFormula = "=IF(OR" & FullFormula & "),""Ignore"", """")"
ActiveCell.Formula = FinalInvestigateFormula
Please let me know if there is an easier way of doing this or how I might be able to correct the above code. Btw I am not declaring a variant I am simply declaring ToIgnore() as String and using the split function from the variable which contains the comma separated values to generate the array/items to loop over.
"Type" is a reserved name? Try strType instead?

Excel TEXT(dd.mm.yyyy) function and different client languages

How can I make a function with a formatted date that will work in every language? I want to make the following function:
=CONCATENATE(TEXT(C8;"TT.MM.JJJJ");"/";G8)
The problem here is, that I use the english client but because I'm a german, excel forces me to use T for day and J for year. I think this will cause problem on a PC located in england (for example).
I think [$-409] won't work because I still have to use T for day and J for year. Is there a good solution for this (function wise)?
If you pass the value of a formula in "" then it cannot be changed based on the localisation settings.
A good way to do it is to use a custom function with VBA, returning "TT.MM.JJJJ" if you are in Germany and "DD.MM.YYYY" if you are in England.
Public Function CorrectString() As String
Select Case Application.International(XlApplicationInternational.xlCountryCode)
Case 1
CorrectString = "DD.MM.YYYY"
Case 49
CorrectString = "TT.MM.JJJJ"
Case Else
CorrectString = "ERROR"
End Select
End Function
Would allow you to call the function like this:
=CONCATENATE(TEXT(C8;CorrectString());"/";G8)
And depending on the excel language, it would give either the German or the English versions.
To simplify the formula, try calling only:
=TEXT(21322;CorrectString())
This should return 17.05.1958.
Source for the regional languages, mentioned by #Dan at the comments:
https://bettersolutions.com/vba/macros/region-language.htm
Or run this to see the corresponding number of your current Excel:
MsgBox xlApplicationInternational.xlCountryCode
Just dropping in another imho elegant (VBA free) alternative taken from: Stackoverflow answer by #Taosique
=IF(TEXT(1,"mmmm")="January",[some logic for English system],[some logic for non-English system])
I've had the same problem and solved it with similar VBA Function. My function accepts input in international format, and outputs the local version for user.
Please see code below:
Function DateFormater(sFI As String)
Dim aFI() As String
aFI = split(StrConv(sFI, vbUnicode), Chr$(0))
ReDim Preserve aFI(UBound(aFI) - 1)
For i = 0 To UBound(aFI)
Select Case (aFI(i))
Case "m", "M"
DateFormater = DateFormater & Application.International(xlMonthCode)
Case "y", "Y"
DateFormater = DateFormater & Application.International(xlYearCode)
Case "d", "D"
DateFormater = DateFormater & Application.International(xlDayCode)
Case Else
DateFormater = DateFormater & aFI(i)
End Select
Next i
End Function
A simpler solution is to use generic Excel functions.
=CONCATENATE(TEXT(DAY(C8;"00");".";TEXT(MONTH(C8);"00");".";YEAR(C8);"/";G8)

Extract URL from =Hyperlink()

I'm trying to extract the formula that is evaluated from a link generated with a formula:
=HYPERLINK("https://www.google.com/search?q="&A1&B1,"Link")
(A1 has vba and B1 has help)
I've seen many, many threads and even some SO threads with suggestions, but they only get me to the ...q= without considering I have more text to come.
The best luck I've had so far is from this thread, and I've tweaked it to search until B1 like this:
...
S = Left(S, InStr(S, "B17") + 2)
...
But it returns https://www.google.com/search?q="&A1&B1.
How can I get it to first evaluate what's in those cells, before returning the URL?
I was overthinking this I think. Thanks to #MacroMan for getting my head straight. I put together the following, rather clunky, macro.
Function hyperlinkText(rg As Range) As String
' Inspired by https://stackoverflow.com/questions/32230657/extract-url-from-excel-hyperlink-formula/32233083#32233083
Dim sFormula As String
Dim Test As String
sFormula = rg.Formula
Test = Mid(sFormula, WorksheetFunction.Search("""", sFormula), WorksheetFunction.Search(",", sFormula) - WorksheetFunction.Search("""", sFormula))
hyperlinkText = Evaluate("=" & Test)
End Function
This can take a URL that looks like:
=HYPERLINK("https://www.google.com/search?q="&A17&B17,"Link") and return the evaluated URL:

excel formulaR1C1 char length

Visual Basic in Excel is pushing a part of the formula below on a second line. How do i keep it on one line or make it work on multiple lines?
ActiveCell.FormulaR1C1 = "=IF(ISNUMBER(SEARCH(""*DUPLICATE*"",RC[+3])),""Duplicate"",IF(ISNUMBER(SEARCH(""*ABBREV*AM or PM*"",RC[+3])),""Prohibited Abbreviation"",IF(ISNUMBER(SEARCH(""*ABBREV*>*<*"",RC[+3])),""Prohibited Abbreviation"",IF(ISNUMBER(SEARCH(""*ABBREV*Q*"",RC[+3])),""Prohibited Abbreviation"",IF(ISNUMBER(SEARCH(""*ABBREV*U*IU*"",RC[+3])),""Prohibited Abbreviation"",IF(ISNUMBER(SEARCH(""*Out of Stock*"",RC[+3])),""CMOP Out of Stock"",IF(ISNUMBER(SEARCH(""*SIG TOO LONG*"",RC[+3])),""Sig Too Long To Process"",IF(ISNUMBER(SEARCH(""*CMOP STOC*"",RC[+3])),""Quantity"",IF(ISNUMBER(SEARCH(""MISSPELLIN*"",RC[+3])),""Misspelling"",IF(ISNUMBER(SEARCH(""*MANUF*B*ORDER*"",RC[+3])),""Manufacturer'S Backorder"",IF(ISNUMBER(SEARCH(""*EXPIRED ADDRES*"",RC[+3])),""Expired Address"",IF(ISNUMBER(SEARCH(""*NOT STOCKED*LOW USAGE*"",RC[+3])),""Not Stock-Low usage"",IF(ISNUMBER(SEARCH(""*PRODUCT D*C*"",RC[+3])),""Product Discontinued"",IF(ISNUMBER(SEARCH(""*REFRIG*PO BOX*"",RC[+3])),""Refrig Item/PO Box Address"",IF(ISNUMBER(SEARCH(""*CORRECT*RESUBMIT*"",RC[+3])),""Correct Qty & Resubmit"","" "")))))))))))))))"""
You can split formula text across lines in the VBA editor using carefully-placed quotes, underscores and ampersands:
Option Explicit
Sub Test()
ActiveCell.FormulaR1C1 = "=IF(15>10, " & _ '<~ quote, ampersand and underscore
"12345, " & _
"67890)"
End Sub
That being said, ActiveCell can be tricky, and the formula you're writing out is... complex. Could you perhaps design a Select...Case statement in your design to result in a more readable experience for folks who might be maintaining your code?

vba Using Eval but maintaing internal string

So I am using Instr with Evaluation and facing some difficulties
The code is as follows
myIneq=">"
myString1="Hello"
myString2="el"
Evaluate( "Instr(" & myString1 & "," & myString2 & ")" & myIneq & cstr(0)
I am getting an Error 2029. Based off this msdn link I am assuming it is trying to evaluate "Hello" as a variable name. What is the work around for this, I know there must be one.
Thanks
I infer from the Error 2029 (#NAME?) and the link that you're using Excel. In this case the answer is simple. Application.Evaluate evaluates Excel expressions, not VBA code. That is, any functions you call in your expression have to be things you could call from an Excel formula. (And you're correct that Excel is trying to evaluate the value of a symbol it doesn't recognize, and is thus giving you back a #NAME? error.)
There is an Excel worksheet function, FIND, that does pretty much the same thing that the VBA function Instr does, so if your example is not too simplified, that might be all you need to do.
I just typed this into the Immediate window:
x="Hello"
y="el"
?Evaluate("FIND(""" & y & """, """ & x & """)")
2
ineq = ">"
?Evaluate("FIND(""" & y & """, """ & x & """)" & ineq & "0")
True
and it seems to work.
Note that Evaluate is a function, so it expects to receive a string argument, and then return what that string evaluates to if treated as an Excel formula-syntax expression. In your example, you don't seem to be doing anything with the return value, so I thought I'd mention it.
"Evaluate" doesn't understand all excel functions.
For example, trying to evaluate "instr" will give an Error 2029. But there is a nice workaround:
"evaluate" recognizes all added vba functions of your excel sheet
so just wrap a single-line function around the reluctant function.
Code will be similar to this:
Sub test()
MsgBox Evaluate(" Instring(""Hello"",""el"") ")
Msgbox "\o/ ! ... I owe a beer to someone out there"
End Sub
Function Instring(a, b)
'make instr visible to 'evaluate'
Instring = InStr(a, b)
End Function
You're evaluating the string InStr(Hello,el).
Obviously, that's not what you want.
You need to use a quoted string literal.

Resources