I would like to write a macro which goes through all cells in column and if it finds any formula in cell then it simply ignores this cells and simply 'DO NOTHING'.
I know about HasFormula property in VBA but not really sure it works for cells where I sum two cells simply (for instance, =C4+C5). Here is an example:
'loop (if the cell has formula then loop ignores that cell
i = 1
For i = 5 To 100
If InStr(1, Sheets("Corporate Detailed").Cells(i, "F"), "+") > 0 Then
could be also used---'If Sheets("Corporate Detailed").Cells(i, "G").HasFormula = True Then
Else
'Do some operations
End If
Next i
End Sub
Related
I'm having problems with combined cells.
The following ranges are combined: G42:Q42, G43:Q43 and so on and so forth until G47:Q47
This code works fine when the cells arenĀ“t combined as descripted above, but I can't get it to work when the cells are merged
For Each cell In ventas.Range("G42:G47")
If (cell.Value = "") Then cell.ClearContents
Next
I've tried this but it's useless:
For Each cell In ventas.Range("G42:Q47")
If (cell.Value = "") Then cell.ClearContents
Next
Try this
Sub clearRange()
Dim c As Range
For Each c In ventas.Range("G42:Q47").Cells
If c.MergeCells = True Then
If c.MergeArea.Cells(1, 1) = "" Then c.MergeArea.ClearContents
Else
If c.Value = "" Then c.ClearContents
End If
Next
End Sub
The code checks if the cell is part of a merge and then only works on the first cell.
Working with merged cells can be very tricky.
combined cells can also be addressed as a single cell.
Say I combine C3:G7 I can run
ActiveWorkbook.Sheets(1).Cells(3, 3).Value = "test"
and the cell will display"test"
You can look up the name of the cell in the top left
I need check if any cell in Range is empty, using VBA in Excel. If so, then write a messing box.
I have data similar to this
ID ColumnB
1 a
2 aa
3
4 ab
I tried many codes, but always it write the messing box, even when the columnB has no empty cell.
One of the code is
For Each cell In Range(Range("A4").End(xlDown).Offset, Range("A4").End(xlDown).End(xlUp)).Offset(0, 1)
If IsEmpty(cell) = True Then
GoTo Done1
End If
Done1:
MsgBox "In column B are empty cells.", vbInformation
Next cell
I have data from row 4 and Column A doesn't have empty cell (that is why I use Offset())
I always see messing box 5 times (because the range has 5 rows), even when I modify the data, so ColumnB doesn't have any empty cells.
I also tried
If cell.Value = "" Then
Or
If WorksheetFunction.CountA(Range(Range("A4").End(xlDown).Offset, Range("A4").End(xlDown).End(xlUp)).Offset(0, 1)) = 0 Then
' GoTo Done3
And many others, but nothing work.
Any idea?
Thanks
I am writing and Excel VBA if statement, but I can't figure out why it is not working.
I have 1 Sheet called "Data" and I want to check if some variables in column I are the same as in my ActiveSheet row 2, column B (which is number 2). I used the following code which ends automatically because it is not working. Anybody an idea?
Example:
Sub test()
If Sheets("Data").Range("I:I") = ActiveSheet(2, 2) Then
MsgBox ("Yes")
Else
MsgBox ("No")
End If
End Sub
You should create a loop in column I if you want to validate every item in that column; use a flag to bail out as soon as you find a mismatching value, so as to avoid looping through all cells once you already know the outcome:
Dim x as long, result As Boolean
result = True
For x = 1 to 100 'let's say up to row 100
If Worksheets("Data").Range("I" & x).value <> ActiveSheet.Cells(2, 2).value Then
result = False
End If
If Not result Then Exit For
Next x
If result Then
MsgBox "Yes"
Else
MsgBox "No"
End If
You compare a whole column (i.e. 1048576 values) with a single value which obviously does not work. Furthermore if you want to access a specific cell you have to use the Cells-collection of your worksheet i.e. ActiveSheet.Cells(2,2)
If you want to compare each cell in column I individually, use a Loop. If you only want to know if the search-value exists somewhere within the column, you can use the Range.Find method.
I am trying to set conditional formatting in 18 cells in third column ("C"). I have merged each 6 cells in first column ("A"), and unmerged (normal) cells in second column ("B"). I am trying to check for each next cell in row of column "C" if there is a "yes" in first row of column "A" or whether there is a "no" in "A" column and "pass" in "B" column. The trick is, I want to check only first row of "A" column, seventh, thirteenth and nineteenth (so with the step = 6) and check every row in "B" column. I try something like this:
Sub try()
Dim i As Integer
Dim j As Integer
i = 1
For j = 1 To 12
With Range("C1:C18")
.FormatConditions.Delete
.FormatConditions.Add Type:=xlExpression, Formula1:="=OR(Cells(i, 1) = ""Yes""; AND(Cells(i, 1) = ""No""; Cells(j, 2) = ""Pass""))"
End With
If j Mod 6 = 0 Then
i = i + 6
Next j
End Sub
But it does not work like that, I saw examples with specific Cells like "A1" or "A3" but I want a number to increase with every loop (so I tried it with Cells(row,column)).
You can do it in one statement on the whole range by using relative addresses, so what applies to C1 relatively to A1 and B1 will follow automatically in the subsequent rows of the range.
The only trick is to retrieve the value in column A, since this value is only available in cells A1, A7, etc. This is achieved by the expression OFFSET(A1,-MOD(ROW(C1)-1,6),0).
Sub doIt()
With Sheet1.Range("C1:C30").FormatConditions
.Delete
.Add(xlExpression, , _
"=OR(OFFSET(A1,-MOD(ROW(C1)-1,6),0)=""yes"",AND(OFFSET(A1,-MOD(ROW(A1)-1,6),0)=""no"",B1=""pass""))") _
.Interior.ColorIndex = 6
End With
End Sub
You can also do it from the GUI using the same formula; select cell C1 then select the whole range C1:C30, and click
Conditional Fomatting -> New rule -> Use a formula... and enter the same formula.
BTW, the expression can be further simplified if you dont care to check for "no", meaning if column A is assured to be either "yes" or "no".
So, in Sheet1 I have base of some names and it looks like this:
In Sheet2 I'm working with these names from Sheet1. I'm doing that in a way that I'm entering Code value in column A and in column B I get the Name, in column C I get the Last Name. That looks like this:
I've done this with formulas, entering it in the formula bar. For column A(or Name) I've used this formula: =IFERROR(VLOOKUP(A2;Sheet1!A:C;2;FALSE);"") and for column B(or Last Name) I've used this one: =IFERROR(VLOOKUP(A2;Sheet1!A:C;3;FALSE);""). I've dragged these formulas to row 20 and it works great.
Now, what I'd like to do is to put these formulas into Excel VBA code and them to work for noted range. I've just started to use VBA and I don't know how to do it in it, tried something but doesn't work, ..., I've done this so far. I'm new to this Excel/Macro/VBA thing so any help would be appreciated.
The below code will work if you type in your Code values in sheet2 and highlight them, and run this macro:
Selection.Offset(0, 1).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-1],Sheet1!C[-1]:C,2,FALSE),"""")"
Selection.Offset(0, 2).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-2],Sheet1!C[-2]:C,3,FALSE),"""")"
Selection.Offset(0, 1).Value = Selection.Offset(0, 1).Value
Selection.Offset(0, 2).Value = Selection.Offset(0, 2).Value
Edit: If you are wanting to update values as you type use (thank you #PeterAlbert for added optimisation!):
Private Sub Worksheet_Change(ByVal Target As Range)
'end if the user made a change to more than one cell at once?
If Target.Count > 1 Then End
'stop system activating worksheet_change event while changing the sheet
Application.EnableEvents = False
'continue if column 1(A) was updated
'and
'dont continue if header or row 1 was changed
If Target.Column = 1 And Target.Row <> 1 Then
With Target.Offset(0, 1) 'alter the next cell, current column +1 (column B)
'RC1 = current row and column 1(A) e.g. if A2 was edited, RC1 = $B2
'C1:C2 = $A:$B
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C2,2,FALSE),"""")"
.Value = .Value 'store value
End With
With Target.Offset(0, 2) 'alter the next cell, current column +2 (column C)
'C1:C3 = $A:$C
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C3,3,FALSE),"""")"
.Value = .Value 'store value
End With
End If
Application.EnableEvents = True 'reset system events
End Sub
Explinatioin of RC:
The FormulaR1C1 formula types are good to use when referencing a cell with respect to the current cell. There a few rules to remember:
The R stands for Row and C is for Column and the integer after it, if any, defines the row or column;
As a basis the RC formula references itself;
Any number following the R or C wraped in [] is an offset to itself, e.g. if you are in cell A1 and use R[1]C[1] you would be referencing cell B2;
Also any number following the R and C is an exact, e.g. if you reference R2C2 no matter the cell you are in would also point to B2; and
To complicate things if you were in cell C5, e.g. using Range("C5").FormulaR1C1 = and coded the follwing:
"=RC[-1]" references cell B5
"=RC1" references cell A5, more rightly $A5
"=R[1]C[-2]" references cell A6
"=Sum(C[-1]:C5)" is =Sum(B:E), more rightly =Sum(B:$E)
If I understand your question and comments correctly, you want to ensure that columns B&C always show you the right values based on your formula, but also want to protect (and maybe even hide the formula) from the users.
I'd suggest you use sheet protection instead: all you need to do is to unlock the cells you want the users to edit, i.e. select column A and in the _ Format cells_ dialog uncheck "Locked" in the Protection tab. Similarly for columns B&C, check "Hidden". Now right click the sheet name and select Protect Sheet. Once this is done, the user can edit column A - but will not see the formula in B&C and cannot edit those cells.
If for some reasons you need to ensure this in VBA, use the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False 'to prevent endless loop
With Target.Offset(, 2 - Target.Column).Resize(, 2)
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C3,COLUMN(RC),0),"""")"
.Value = .Value
End With
Application.EnableEvents = True
End Sub
You need to place this in the module of the worksheet.