Nothing Happening a Simple Condition in VBA - vba

In excel, I want to impose a cell to be 0 if a condition is matched, but editable if not. My condition is that another cell's value = 1. This is my minimal example VBA line:
If Range("B4").Value = 1 Then Range("C4").Value = 0
But nothing is happening even though B4 is set to 1! Is there something missing in this code? Thanks!

Qualify the Range objects with the specific worksheets you want to analyze / alter. This is best practice for VBA and ensures the code acts on the specific places you need it to.
For example:
With Worksheets("Sheet1")
If .Range("B4").Value = 1 Then .Range("C4").Value = 0
End With
Or
If Worksheets("mySheet").Range("B4").Value = 1 Then
Worksheets("yourSheet").Range("C4").Value = 0
End If

You have to refer to the sheet as well. E.g.,
If ActiveSheet.Range("B4").Value = 1 Then ActiveSheet.Range("C4").Value = 0
To see the sheet, which you were referring to, try this:
Sub TestMe()
If Range("B4").Value = 1 Then Range("C4").Value = 0
MsgBox (Range("B4").Parent.Name)
End Sub

Related

VBA if A = B and C= Text

I have been looking on stackoverflow but could not get an definitive answer to my little problem. I am fairly new to coding and am still dealing with syntax sometimes.
Right now I have a little loop reading an array, inside the loop it checks for an if statement. I have been checking the loop which works fine, and the array as well. The if statement works until im starting to use "isText".
After searching a bit I noticed "isText" is not a function, is there something equivalent?
Right now my if statement goes as follows: IF A = B and C (Contains ANY value at all) then Write something somewhere in a cell
Right now the code I am using is:
Sub KnopKlik()
Dim Soorten(10)
Dim Teller As Integer
Dim Column1 As String
Column1 = Sheets(2).Range("C1").Value
MsgBox (Column1)
Sheets(1).Select
Range("E2").Select
For Teller = 0 To 10
Soorten(Teller) = ActiveCell.Offset(Teller).Value
Next Teller
For Teller = 0 To 10
If Sheets(2).Range("B9") = Soorten(Teller) And Application.IsText(Column1) Then
MsgBox ("Check")
Sheets(2).Range("E9").Value = ActiveCell.Offset(Teller, 3)
Sheets(2).Select
Range("B9").Select
Teller = 10
Else
End If
Next Teller
End Sub
Right now the last part of the if statement is the problem
And Application.IsText(Column1) Then
EDIT**
This is how I solved it now. Basically whenever there is ANYTHING at all in that cell it will pass through.
If Sheets(2).Range("B9") = Soorten(Teller) Then
'Als B9 Gelijk is aan (database) DAN!>>>
If Not Column1 = "" Then
Sheets(2).Range("E9").Value = ActiveCell.Offset(Teller, 3)
End If
Else
End If
Thanks in advance.
You can do it like this:
If Sheets(2).Range("B9") = Soorten(Teller) And Len(Trim(Column1)) > 0 Then
The len will return the length of the string. The Trim will remove the empty spaces from left and right, thus if it is an empty string it will be true.

Can I use IsEmpty to refer to a different sheet and hide a column?

Is it possible to use IsEmpty to refer to a cell on a different sheet from where the macro is being fired from? Also, is it possible to hide the queried column if the result of that query is True?
Here's what I've built so far:
My first version looked like this:
If IsEmpty(L1) Then
Columns("L").EntireColumn.Hidden = True
Else
Columns("L").EntireColumn.Hidden = False
End If
Straightforward enough. But, that only works if it's fired from the worksheet where I want the query/hide to occur. When I launch the macro from the different sheet, it hides the column in that sheet (of course, duh).
So, after several iterations and errors, I got to this:
If IsEmpty(Sheets("Results").Cells(10, 1).Value) Then
Worksheets("Results").Columns(10).EntireColumn.Hidden = True
Else
Worksheets("Results").Columns(10).EntireColumn.Hidden = False
End If
Which at least doesn't throw any errors from the VBA. It also does a grand total of squat. :$ I'm starting to wonder if it's even possible to use IsEmpty on a different sheet? Or the EntireColumn.Hidden command? Also, given that I need to run this check on 9 columns, maybe there's a better way than 9 If/Then statements?
To get away from a loop through 9 columns' row 1, use SpecialCells(xlCellTypeBlanks).
dim blnks as range
with workSheets("Results")
with .range(.cells(1, "B"), .cells(1, "K"))
.entirecolumn.hidden = false
set blnks = .specialcells(xlCellTypeBlanks)
if not blnks is nothing then blnks.entirecolumn.hidden = true
end with
end with
Essentially this unhides all 9 columns then hides the columns with blank cells in the first row. Note that a zero-length string (e.g. "") returned by a formula is not the same thing as a truly blank cell.
I think you're very close, just you have the cells inputs the wrong way around:
If IsEmpty(Sheets("Results").Cells(1, 10).Value) Then
Worksheets("Results").Columns(10).EntireColumn.Hidden = True
Else
Worksheets("Results").Columns(10).EntireColumn.Hidden = False
End If
Additionally as mentioned in the comments you can create a loop to check many columns:
Dim i As Integer
Dim maxi As Integer
i = 1
maxi = 20
While i < maxi
If IsEmpty(ThisWorkbook.Worksheets("Results").Cells(1, i)) Then
Worksheets("Results").Columns(i).EntireColumn.Hidden = True
Else
Worksheets("Results").Columns(i).EntireColumn.Hidden = False
End If
i = i + 1
Wend

Excel - lots of conditional formatting converted to VBA

For an Excel spreadsheet order form, I need a way to apply conditional formatting to all rows with one macro, from row 78 down until there is no more data.
Each column has its own conditional formatting formulas. Some have multiple formulas. I tried using the Record Macro function, but since there is so much going on, the resulting VBA code is messy, and I'm not sure how to combine it all.
I don't need someone to write all the code for me, but I'm hoping I can get a little guidance to figure out how to do all of it.
There are about 15 columns that need conditional formatting applied to them. Here are a few columns to show what I'm working with:
A78:
Formula: =AND($A$78="",COUNTA(78:78)>=1) | white text, red fill | Stop
If True
C78:
Format only cells that contain > Specific Text > beginning with > M |
no format | Stop If True
Format only cells that contain > Specific Text > beginning with > F |
no format | Stop If True
Format only cells that contain > No Errors | red background, white
text
D78:
Cell value is greater than 300
You can do this fairly easily with a DO-WHILE Loop. I'll give a start for "D78" and you should be able to finish the rest.
sub formatCells()
Dim count as Integer
Range("D78").Activate
count = 0
Do While ActiveCell.Offset(count, 0).Value <> ""
If ActiveCell.Offset(count, 0).Value > 300 Then
'Do Stuff
End If
count = count + 1
Loop
End Sub
You need to create a FormatCondition object for each rule you want to set. Here are the basics for setting up a formula-based conditional format.
'Set a variable for the formatcondition to make it easier to work with.
Dim fc As FormatCondition
'Create the formatcondition.
strFormula = "=$A1=$B1"
Set fc = Range("A:A").FormatConditions.Add(Type:=xlExpression, Formula1:=strFormula) '(There is a "Formula2" property that only applies if you are using one of the built-in conditional formatting rule types. It does not apply if you are using an xlExpression rule type).
'Move it to the top of the list (optional).
fc.SetFirstPriority
'Set "Stop if True" (optional).
fc.StopIfTrue = True
'Set interior Color (optional).
fc.Interior.Color = RGB(255,0,0) 'red
'Set borders (optional).
arBorders = Array(xlLeft, xlRight, xlTop, xlBottom)
For Each borderConst In arBorders
fc.Borders(borderConst).LineStyle = xlContinuous
Next
'Set font (optional).
fc.Font.Italic = True
fc.Font.Bold = True
fc.Font.Underline = True
I would recommend setting up a procedure as below to simplify this process. I created this one for my own use. It can only set borders and fill color, but could be modified to set font attributes, etc.
Sub AddFormatCondition(rgAppliesTo, strFormula, Optional bSetFirstPriority, Optional FillColor, Optional bBorders, Optional bStopIfTrue)
Dim fc As FormatCondition
Set fc = rgAppliesTo.FormatConditions.Add(Type:=xlExpression, Formula1:=strFormula)
If Not IsMissing(bSetFirstPriority) Then
If bSetFirstPriority Then fc.SetFirstPriority
End If
If Not IsMissing(FillColor) Then
With fc.Interior
.Color = FillColor
End With
End If
If Not IsMissing(bBorders) Then
If bBorders <> 0 Then
arBorders = Array(xlLeft, xlRight, xlTop, xlBottom)
For Each borderConst In arBorders
fc.Borders(borderConst).LineStyle = xlContinuous
Next
End If
End If
fc.StopIfTrue = bStopIfTrue
End Sub

Delete entire row when a value exist (With sheets) [duplicate]

I have 2 sheets: sheet1 and sheet2. I have a value in cell A3 (sheet1) which is not constant. And many files in sheets2.
What I would like to do, is when the value in cell A3 (Sheet1) is the same as the value in the column A (Sheet2), it will delete the entire row where is find this value (Sheet2).
This is my attempt. It doesn't work: no rows are deleted.
If Worksheets("Sheet1").Range("A3").Text = Worksheets("Sheet2").Range("A:A").Text Then
Dim f As String
f = Worksheets("Sheet1").Range("A3")
Set c = Worksheets("Sheet2").Range("A:A").Find(f)
Worksheets("Sheet2").Range(c.Address()).EntireRow.Delete
End If
My guess is that you're not finding anything with the .Find(). Since you're not checking it for is Nothing you don't know. Also, .Find() retains all the search parameters set from the last time you did a search - either via code or by hand in your spreadsheet. While only the What parameter is required, it's always worth setting the most critical parameters (noted below) for it, you may want to set them all to ensure you know exactly how you're searching.
Dim f As String
If Worksheets("Sheet1").Range("A3").Text = Worksheets("Sheet2").Range("A:A").Text Then
f = Worksheets("Sheet1").Range("A3")
Set c = Worksheets("Sheet2").Range("A:A").Find(What:=f, Match:=[Part|Whole], _
LookIn:=[Formula|value])
if not c is Nothing then
Worksheets("Sheet2").Range(c.Address()).EntireRow.Delete
else
MsgBox("Nothing found")
End If
End If
Go look at the MS docs to see what all the parameters and their enumerations are.
Sub Test()
Dim ws As Worksheet
For x = 1 To Rows.Count
If ThisWorkbook.Sheets("Sheet2").Cells(x, 1).Value = ThisWorkbook.Sheets("Sheet1").Cells(3, 1).Value Then ThisWorkbook.Sheets("Sheet2").Cells(x, 1).EntireRow.Delete
Next x
End Sub

Error 424 Object needed

well my idea is to refer the alphabet in cell J9 of the first worksheet called Table1 and to automatically color the shape called "Test" on the active worksheet. So basically if the alphabet entered is "a" in the cell J9 on the first worksheet, the shape "Test" on worksheet 2 should give out color 1, and if "b", color 2 and so on. I have written a code for it but sadly I keep receiving Error 424 Object Required. Any help would be deeply appreciated! Thanks!
Sub test()
If Table1.Range("J9") = "a" Then
ActiveSheet.Shapes("Test").Fill.ForeColor.SchemeColor = 1
ElseIf Table1.Range("J9") = "b" Then
ActiveSheet.Shapes("Test").Fill.ForeColor.SchemeColor = 2
ElseIf Table1.Range("J9") = "c" Then
ActiveSheet.Shapes("Test").Fill.ForeColor.SchemeColor = 3
ElseIf Table1.Range("J9") = "d" Then
ActiveSheet.Shapes("Test").Fill.ForeColor.SchemeColor = 4
Else
ActiveSheet.Shapes("Test").Fill.ForeColor.SchemeColor = 5
Does changing all Table1 references to Worksheets("Table1") fix it? For example:
If Worksheets("Table1").Range("J9") = "a" Then
ActiveSheet.Shapes("Test").Fill.ForeColor.SchemeColor = 1
It looks like is not with the shape code but with the Table1. Tables use a special structured addressing system (see Select, get and set data in Table). If you just want the value from cell J9 then this should do.
With Sheets("Table 1")
Select Case LCase(.Range("J9").Value)
Case "a"
.Shapes("Test").Fill.ForeColor.SchemeColor = 1
Case "b"
.Shapes("Test").Fill.ForeColor.SchemeColor = 2
Case "c"
.Shapes("Test").Fill.ForeColor.SchemeColor = 3
Case Else
' do nothing
End Select
End With
If a simple reference to J9 is insufficient, you will have to provide more information on the exact nature of Table1.
EDIT:
You may not be referencing the shape's name correctly. This code will enumerate all of hte shapes on the Table 1 worksheet and return their names to the VBE's Immediate window (in the VBE as Ctrl+G).
Dim i As Long
With Sheets("Table 1")
For i = 1 To .Shapes.Count
Debug.Print .Shapes(i).Name
Next i
End With
Is Test there as one of the names? can you determine the name of the shape you want to change?
#Jeeped Is it the same if I were to use apple, orange and lemon instead of alphabets? I changed my code to make it similar like yours. This time there is no error message but nothing happens
Sub test()
With ActiveSheet
Select Case LCase(.Range("J9").Value)
Case "apple"
.Shapes("Test").Fill.ForeColor.SchemeColor = 1
Case "orange"
.Shapes("Test").Fill.ForeColor.SchemeColor = 2
Case "lemon"
.Shapes("Test").Fill.ForeColor.SchemeColor = 3
Case Else
' do nothing
End Select
End With
End Sub
Is there anything wrong in this code? and by the way, what is LCase??
Sub SO()
ActiveSheet.Shapes("Test").Fill.FillColor.SchemeColor = Asc(UCase(Sheets("Table 1").Range("J9"))) - 64
End Sub