How to exit IIf() statement when no value is present - excel

Is there any way to terminate an IIf() statement if it doesn't return a value?
This is what my code looks like:
Do While Sheets("testsheet").Cells(1, Z) <> ""
text1 = Sheets("testsheet").Cells(1, Z).Value
vLook = Application.HLookup(text1, lookupRange, u, False)
Sheets("Kilepok").Cells(i, Z).Value = IIf(IsError(vLook), ????, vLook)
Z = Z + 1
Loop
The code runs through the header (z), and looks for a value. If it finds a value, I would like to paste this in those cases (when there is no error in vlook). In other cases, I don't want to modify the value of the current cell.

Either
Sheets("Kilepok").Cells(i, Z).Value = IIf(IsError(vLook), Sheets("Kilepok").Cells(i, Z).Value, vLook)
or
If Not IsError(vLook) Then Sheets("Kilepok").Cells(i, Z).Value = vLook
will do the job.
But note that the first will re-write the cell's value (which makes it slow) and if there is a forumla in it, it will be converted into a value. So the second one would be the preferred solution.

Related

if statement compare inputbox to cell.value

Sub Botão34_Clique()
Dim x As String
Dim z As Integer
InputBox "FIND PRODUCT", "TYPE" = x
For z = 2 To 143
If Range("B" & z).Value = x Then
MsgBox Range("B" & z)
End If
Next z
End Sub
Hi guys,
I don't understand why the above code is not working.
The user's input will be compared with an existing product list.
When the input is equal to an existing product, the msgbox should indicate the cell in which it is present.
Unfortunately, I don't understand why the statement Range("B" & z).Value = x doesn't work...
Any ideas?
You don't write the result of the InputBox into the variable x.
What you do is to call the InputBox with 2 parameters.
The first parameter ("FIND PRODUCT") is the text that is shown in the input box as label.
The second parameter is used as form caption. You pass the expression "TYPE" = x as second parameter, and VBA will happily compare the string "TYPE" with the content of the variable x, resulting in either True or (most likely) False. So if you carefully look at the input box window, you will see the string "False" as caption.
Now the user enters something into the box and presses the "OK"-button. The entered value is returned, but you don't assign it to anything and the value is send to the big Computer Nirvana.
What you want is to assign the value to x. The correct syntax for this is
x = InputBox("FIND PRODUCT", "TYPE")
Note that in VBA, you have to put parenthesis around the list of parameters when you are calling a function and use the return value.

How to specify last character in 1 cell ( Inside IF )

i have a code that copies and rewrites anything thats between "(" and ")", but now i have different type of data which do not end with ")" so, i need it to stop when it reaches the last character in cell. Maybe it is dumb question but i cant seem to find how to fix my problem. I am a student and total newbie in vba (5 days ago i didn't know what vba is...) also sorry for my bad english.
I've tried to search (in here, google, youtube) but i couldnt find anything i need
'zaciatok=start koniec=end dlzka=length
Do While Mid(LookInHere, y, 1) <> ""
If Mid(LookInHere, Z, 1) = "(" Then
zaciatok = Z
End If
If Mid(LookInHere, y, 1) = ")" Then
koniec = y
dlzka = (koniec - 1) - zaciatok
dlzka = Abs(dlzka)
SplitCatcher = Mid(LookInHere, zaciatok + 1, CStr(dlzka))
MsgBox SplitCatcher
End If
y = y + 1
Z = Z + 1
Loop
In your specific implementation, one option is to modify your Do While ... loop to also test against the length of the string. That line would look something like:
Do While Mid(LookInHere, y, 1) <> "" And y < Len(LookInHere)
That modification tells the statement that it should terminate the loop when the iterating variable y goes past the length of the statement.
Another option is to change it from a Do While loop to a For loop. It would read something like:
For i = 1 to Len(LookInHere)
MsgBox Mid(LookInHere, i, 1)
'Input your logic here
Next i
The problem is that each of these versions is relatively inefficient, looping through each letter in a string a performing a calculation. Consider using built-in Excel functions. The Instr returns the position of a character, or a zero if it is not found. As an example, Instr("Abcdef", "b") would return the number 2, and Instr("Abcdef", "k") would return zero. You can replace the entire loop with these two function calls.
Z = Instr(LookInHere, "(")
y = Instr(LookInHere, ")")
If y = 0 Then y = Len(LookInHere)
Final note: if your patterns begin to get more and more complex, consider reviewing and implementing regular expressions.
You can use Right(LookInHere, 1) to get the last character of LookInHere

How to use "contains" function in VBA?

This is my Excel table with 3 input columns. The last column is the output column with the result I need.
Excel Input and Output data
Here is the sample macro I have:
Function month(x As string, y As string, z As String) As String
If (((x = "January.Winter") Or (y = "January.Winter")) And (z = "jan")) Then
month= "true"
Else If (((x = "January.2016") Or (y = "January.2016")) And (z = "jan")) Then
month= "true"
Else If (((x = "January.today") Or (y = "January.today")) And (z = "jan")) Then
month= "true"
Else
month= False
End If
End Function
My worksheet contains thousands of rows which includes "january" as a substring as a text in the cells. Instead of writing multiple checks like "if "x=January.winter"", I would like to use simplify the macro by checking if the string "x" or string "y" contains the string "January". Is there a way I could change the macro to do that?
Three ways that spring to mind:
If LCase$(x) Like "january*" Or LCase$(y) Like "january*" Then
...
If InStr(LCase$(x), "january") Or InStr(LCase$(x), "january") Then
...
If LCase$(Left$(x, 7)) = "january" Or LCase$(Left$(y, 7)) = "january" Then
...
It really just depends how inventive you want to get.
Note that I've used LCase$() to force text to lower case and prevent any issues with capitilisation - always something worth thinking about when comparing strings.
You can use the InStr function. Example use:
If (InStr(x,"January") > 0 Or InStr(y,"January")>0) And (z = "Jan") Then
...
It returns 0 if your substring isn't found, otherwise it returns the position of your substring.
More info here
Also careful with upper and lower casing. "January" will not match "january". Use LCase and UCase functions to force upper or lower casing, as Macro Man did in his answer.

Excel if function

I've made this large excel sheet and at the time i didn't know i'd need to sort this table through categories.
I have in a column (J here ) the description of the line and the category joint. (example: "Shipment of tires for usin'ss")
The only way i was able to sort the table the way i wanted was to build a category column using this :
=IF(COUNTIF(J3;"*usi*");"Usins";IF(COUNTIF(J3;"*remis*");"Remise";IF(COUNTIF(J3;"*oe*");"Oenols";IF(COUNTIF(J3;"*KDB*");"KDB";IF(COUNTIF(J3;"*vis*");"cvis";IF(COUNTIF(J3;"*amc*");"AMC";0))))))
usi for instance is a segment of a category name, that i sometimes wrote as
usin'ss
usin
usin's
usins
'cause you know smart.
Anyway, how do i translate =If(If(If...))) into something readable in VBA like:
If...then
If... then
Example of "IF ... ELSE" in EVBA
IF condition_1 THEN
'Instructions inside First IF Block
ELSEIF condition_2 Then
'Instructions inside ELSEIF Block
...
ELSEIF condition_n Then
'Instructions inside nth ELSEIF Block
ELSE
'Instructions inside Else Block
END IF
Example of Case Switch in EVBA
Select Case score
Case Is >= 90
result = "A"
Case Is >= 80
result = "B"
Case Is >= 70
result = "C"
Case Else
result = "Fail"
End Select
Both cases work off a waterfall type logic where if the first condition is met, then it does not continue, but if condition 1 is not met then it checks the next, etc.
Example usage:
Function makeASelectAction(vI_Score As Integer) As String
Select Case vI_Score
Case Is >= 90
makeASelectAction = "A, fantastic!"
Case Is >= 80
makeASelectAction = "B, not to shabby."
Case Is >= 70
makeASelectAction = "C... least your average"
Case Else
makeASelectAction = "Fail, nuff said."
End Select
End Function
Function makeAnIfAction(vS_Destination As String, vS_WhatToSay As String, Optional ovR_WhereToStick As Range, Optional ovI_TheScore As Integer)
If vS_Destination = "popup" Then
MsgBox (vS_WhatToSay)
ElseIf vS_Destination = "cell" Then
ovR_WhereToStick.value = vS_WhatToSay
ElseIf vS_Destination = "select" Then
MsgBox makeASelectAction(ovI_TheScore)
End If
End Function
Sub PopMeUp()
Call makeAnIfAction("popup", "Heyo!")
End Sub
Sub PopMeIn()
Call makeAnIfAction("cell", "Heyo!", Range("A4"))
End Sub
Sub MakeADescision()
Call makeAnIfAction(vS_Destination:="select" _
, vS_WhatToSay:="Heyo!" _
, ovI_TheScore:=80 _
)
End Sub
It will show you how to send variables to functions and how to call said function, it will show you how use optional parameters, how a function and interact with another function or sub, how do write a value to a sheet or spit out a messagebox. The possabilities are endless. Let me know if you need anything else cleared up or coded out.
You seem to be using CountIf just to see if the contents of the cell matches a certain pattern and, if so, give a replacement string. In VBA you can use the Like operator for pattern matching. In any event -- here is a function I wrote which, when passed a string and a series of pattern/substitution strings, loops through the patterns until it finds a match and then returns the corresponding substitution. If no match is found, it returns an optional default value (the last argument supplied). If no default is supplied, it returns #N/A.
The code illustrates that sometimes complicated nested ifs can be replaced by a loop which iterates through the various cases. This is helpful when you don't know the number of cases before hand.
Function ReplacePattern(s As String, ParamArray patterns()) As Variant
Dim i As Long, n As Long
n = UBound(patterns)
If n Mod 2 = 0 Then n = n - 1
For i = 0 To n Step 2
If s Like patterns(i) Then
ReplacePattern = patterns(i + 1)
Exit Function
End If
Next i
If UBound(patterns) Mod 2 = 0 Then
ReplacePattern = patterns(n + 1)
Else
ReplacePattern = CVErr(xlErrNA)
End If
End Function
Your spreadsheet formula is equivalent to
=ReplacePattern(J3,"*usi*","Usins","*remis*","Remise","*oe*","Oenols","*KDB*","KDB","*vis*","cvis","*amc*","AMC",0)

Comparing Strings in VBA

I have a basic programming background and have been self sufficient for many years but this problem I can't seem to solve. I have a program in VBA and I need to compare two strings. I have tried using the following methods to compare my strings below but to no avail:
//Assume Cells(1, 1).Value = "Cat"
Dim A As String, B As String
A="Cat"
B=Cell(1, 1).Value
If A=B Then...
If A Like B Then...
If StrCmp(A=B, 1)=0 Then...
I've even tried inputting the Strings straight into the code to see if it would work:
If "Cat" = "Cat" Then...
If "Cat" Like "Cat" Then...
If StrCmp("Cat" = "Cat", 1) Then...
VBA for some reason does not recognize these strings as equals. When going through Debugger it shows that StrComp returns 1. Do my strings have different Char lengths? Thanks for any help.
Posting as answer because it doesn't fit in the comments:
I find it hard to believe that something like:
MsgBox "Cat" = "Cat"
Would not display True on your machine. Please verify.
However, I do observe that you are most certainly using StrComp function incorrectly.
The proper use is StrComp(string, anotherstring, [comparison type optional])
When you do StrComp(A=B, 1) you are essentially asking it to compare whether a boolean (A=B will either evaluate to True or False) is equivalent to the integer 1. It is not, nor will it ever be.
When I run the following code, all four message boxes confirm that each statement evaluates to True.
Sub CompareStrings()
Dim A As String, B As String
A = "Cat"
B = Cells(1, 1).Value
MsgBox A = B
MsgBox A Like B
MsgBox StrComp(A, B) = 0
MsgBox "Cat" = "Cat"
End Sub
Update from comments
I don't see anything odd happening if I use an array, just FYI. Example data used in the array:
Modified routine to use an array:
Sub CompareStrings()
Dim A As String, B() As Variant
A = "Cat"
B = Application.Transpose(Range("A1:A8").Value)
For i = 1 To 8
MsgBox A = B(i)
MsgBox A Like B(i)
MsgBox StrComp(A, B(i)) = 0
MsgBox "Cat" = B(i)
Next
End Sub
What I would check is how you're instantiating the array. Range arrays (as per my example) are base 1. If it assigned some other way, it is most likely base 0, so check to make sure that you're comparing the correct array index.

Resources