Inserting Formula ONLY visible Cells - vba

I have data in 3 Columns
A B & C, in which a Filter is active on column A, I want to apply a code so that the formula is applied on Column C - from the 2nd visible row till the last visible row.
Here is the code I have written, However It doesn't work if I change the Range("C:C") or Range("C2:C")
Sub Test()
Dim rng As Range
Range("C1").Select
Set rng = Application.Intersect(ActiveSheet.UsedRange, Range("**C2:C2000**"))
rng.Select
Selection.Formula = "=RC[-1]+RC[-2]"
End Sub

With an active AutoFilter method, presumably your first row contains column header labels and the data is below that. The Range.CurrentRegion property is a better fit for this situation than the Worksheet.UsedRange property.
The Range.SpecialCells method with xlCellTypeVisible will reference the visible cells. I find that the worksheet's SUBTOTAL function provides a nice non-destructive method of seeing iof there are visible cells before trying to access them.
A few With ... End With statements will help you progressively isolate the cells you are looking for.
Sub test()
'note that not a single var is necessary
With Worksheets("Sheet1") '<~~ surely you know what worksheet you are on
With .Cells(1, 1).CurrentRegion
With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0) '<~~one row down
If CBool(Application.Subtotal(103, .Cells)) Then
'there are visible cells
With .Columns(3).SpecialCells(xlCellTypeVisible)
.Cells.FormulaR1C1 = "=RC[-1]+RC[-2]"
End With
End If
End With
End With
End With
End Sub
I've used the Range.FormulaR1C1 property (as opposed to your original Range.Formula property) single you were using xlR1C1 not xlA1 formula syntax.

Related

VBA check for empty cells in column and print value

In column J there are empty rows and rows with a value such as checked.
I have tried to write VBA code that prints "unchecked" where there is an empty cell AND this works, but when it hits a cell with a value (checked) it stops. And it won't go down to the next cell probably because I have formulas in the cell that prints nothing if not fullfilled, but it still contains that formula. In my case I have empty cells until J7 and then it starts again at J15. But this can change from time to time regarding source data.
The reason I want to do it like this is because I have a formula in column J that already have printed some values and then some VBA code that checks for other values in a different column and prints to column J. Column J is the filter master column sort of. So this is the way I have to do it I guess.
My code right now is,
Sub DoIfNotEmpty()
Dim ra As Range, re As Range
With ThisWorkbook.Worksheets("Sheet1")
Set ra = .Range("J:j25")
For Each re In ra
If IsEmpty(re.Value) Then
re.Value = "unchecked"
End If
Next re
End With
End Sub
Can I print to empty cells if the cell contains a formula which in this case has an if statement that is not filled?
Except from #Maxime Porté's points out that it should be .Range("J1:j25"). I guess the cells only look empty, but they are not.
A cell that contains an empty string, "", is not empty anymore, but it looks like it. You can test it like this:
In a new worksheet write in A1: ="" (there is no space in between!)
Copy A1 and special paste values in A1. A1 now looks to be empty.
Run Debug.Print IsEmpty(Range("A1").Value) in VBA and you get a FALSE.
The cell A1 is not empty any more, because it contains an empty string.
What can you do?
Sub DoIfNotEmpty()
Dim ra As Range, re As Range
With ThisWorkbook.Worksheets("Sheet1")
Set ra = .Range("J1:J25")
For Each re In ra
If IsEmpty(re.Value) or re.Value = vbNullString Then
re.Value = "unchecked"
End If
Next re
End With
End Sub
This will mark pseudo empty cells as "unchecked" too. But be aware that it also kills formulas that result in an empty string, "".
You could exploit the Specialcells() method of Range object:
Sub DoIfNotEmpty()
ThisWorkbook.Worksheets("Sheet1").Range("J1:J25").SpecialCells(xlCellTypeBlanks).Value = "unchecked"
End Sub
Or, if you have formulas returning blanks, then AutoFilter() "blank" cells and write in them
Sub DoIfNotEmpty()
With ThisWorkbook.Worksheets("Sheeet1").Range("J1:J25") '<--| reference your range (first row must be a "header")
.AutoFilter Field:=1, Criteria1:="" '<--| filter its empty cells
If Application.WorksheetFunction.Subtotal(103, .cells) > 1 Then .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible).Value = "unchecked" '<--| if any cell filtered other than headers then write "unchecked" in them
.Parent.AutoFilterMode = False
End With
End Sub

Excel vba Autofill only empty cells

I have a column A with data up to A300.
In this range, some of theses cells are empty, some contain values.
In VBA, I set the formula of the cell A1 then I use the autofill function to set it all over my column (up to A300) like this :
ws.Range("A1").Select
Selection.AutoFill Destination:=ws.Range(ws.Cells(1, 1), ws.Cells(300, 1))
My problem is that datas contain on some cells are erased too ! I'm trying to autofill like it but only throught the empties cells.
I tried to add a filter on my worksheet like this :
ws.Range("$A$1:$A$300").AutoFilter Field:=1, Criteria1:="="
Then I reused the autofill function, but it seems to fill thourght the filtered cells...
Can't we add a parameter like "only empties cells" to the autofill function ? Something like this :
Selection.AutoFill Destination:=ws.Range(ws.Cells(1, 1), ws.Cells(300, 1)), Criteria1:="="
Thanks for your replies !
with data like:
I would do a single copy rather than a fill-down:
Sub luxation()
Range("A1").Formula = "=ROW()"
Dim rDest As Range
Set rDest = Intersect(ActiveSheet.UsedRange, Range("A1:A300").Cells.SpecialCells(xlCellTypeBlanks))
Range("A1").Copy rDest
End Sub
with this result:
NOTE:
The formulas adjust after being copied.
EDIT#1:
Please note that there are some circumstances under which this code will not work. It is possible that UsedRange my not extend down to cell A300.
For example, if the worksheet is totally empty except for a formula in A1 and some value in A3. In this case Rdest will only include the single cell A2. The code will leave A4 through A300 untouched.
Assuming you want static values, I would use a loop. The one below will fill all empty cells with poop:
Sub AllFillerNoKiller()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
For Each c In ws.Range("A1:A300")
If c.Value = "" Then c.Value = "poop"
Next
End Sub
Apologies, I miss-understood you question - Want to fill all blank cells with the value in A1? - here you go:
Sub Replace()
If Trim(Range("A1").Value) = "" Then
MsgBox "There's no value in A1 to copy so there's nothing to copy to all blank cells", vbInformation, "Nothing in A1"
Exit Sub
Else
Range("A1:A300").SpecialCells(xlCellTypeBlanks).Select
Selection.Value = Range("A1").Value
End If
End Sub
You can also use below code:
stAddress = Sheet1.Range("A1").CurrentRegion.SpecialCells(xlCellTypeBlanks).Address
Sheet1.Range(st).Value = "Empty"

vba find first non-blank row

I'm new to VBA and struggling with the piece of code.
I need to find the first non-empty row where the conditions are simultaneously met. There must be text in col B and C and number in col D and G (all 4 conditions must be met).
I'd very grateful for help
s
write like below code using and if & and note:lastrow is end of column values.
for i = 1 to lastrow
if cells(i,"b")<>"" and cells(i,"c")<>"" and isnumber(cells(i,"d"))= true and isnumber(cells(i,"g"))= true then
'do something
end if
next i
you may want to nest SpecialCells() method as follows:
Sub main()
With Worksheets("Conditions") '<--| change "Conditions" to your actual worksheet name
With .Range("B1", .Cells(.Rows.Count, "B").End(xlUp)) '<-- refer to column "B" cells down to last non empty one
With .SpecialCells(XlCellType.xlCellTypeConstants, xlTextValues) '<-- refer to its "text" cells only
With .Offset(, 1).SpecialCells(XlCellType.xlCellTypeConstants, xlTextValues) '<-- refer to adjacent column "text" cells only
With .Offset(, 1).SpecialCells(XlCellType.xlCellTypeConstants, xlNumbers) '<-- refer to adjacent column "number" cells only
With .Offset(, 1).SpecialCells(XlCellType.xlCellTypeConstants, xlNumbers) '<-- refer to adjacent column "number" cells only
MsgBox .Cells(1, 1).row '<--| get first "multifiltered" cells row
End With
End With
End With
End With
End With
End With
End Sub
you may need to add test before each SpecialCells() to check that "current" column actually has some text/numbers value, using a mix of Count() and CountA() method

Excel VBA macro to remove formulas for a dynamic range not working

I have a range of four cells. The furthest left cell (column A) is a unique value. The next three cells to the right are populated with formulas. Columns B and C are Vlookups that pull values from sheet 2 when column A is populated (otherwise the cells have a value of ""). Column D populates with the current date when a value is put into Column A (otherwise the cells have a value of "" as well).
What I'm trying to do is run a macro when a unique value is put into column A that will kill the formulas in B,C,D and keep their values. Then it automatically selects the cell in the subsequent row in column A. A3 is fixed which is why I used the End(xlDown) method and then Activecell.Offset.
This is what I have that is bombing Excel when it runs:
Private Sub Worksheet_Change(ByVal Target As Range)
Range(ActiveCell, ActiveCell.Offset(0, 3)).Value = Range(ActiveCell, ActiveCell.Offset(0, 3)).Value
Range("A3").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
End Sub
Always turn off event handling before changing a value in a Worksheet_Change. If you don't, the routine will try to run on top of itself.
If a change in column A is what dictates the need to remove formulas then restrict the processing to when there is a change in column A.
ActiveCell is not a good choice here. Use Target instead. Target may be one or more than one cell.
Look for the first empty cell in column A from the bottom up, not the top down.
Use error control to ensure that the VLOOKUPs have returned values, not errors.
Here is some general code that should get you started.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Columns("A")) Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
Dim rng As Range
For Each rng In Intersect(Target, Columns("A"))
If Not IsError(rng.Offset(0, 1)) Then
rng.Resize(1, 3) = rng.Resize(1, 3).Value
End If
Next rng
With Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
'optionally put in new VLOOKUP formulas in column B and C
'.Offset(0, 1).FormulaR1C1 = "=VLOOKUP(RC1, Sheet2!C1:C3, 2, FALSE)"
'.Offset(0, 2).FormulaR1C1 = "=VLOOKUP(RC1, Sheet2!C1:C3, 3, FALSE)"
.Select
End With
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub

VBA Macro to Autofill a cell

I am trying to find a simple autofill solution to copy the formula in cell C3 into C2 after a new line has been inserted. Here is what I have that I thought would work:
Sub AutoFill()
Set SourceRange = Worksheets("Sheet 1").Range("C3")
Set fillRange = Worksheets("Sheet 1").Range("C2")
SourceRange.AutoFill Destination:=fillRange
End Sub
Basically, in C3 (and every cell in column C after row 3) has a average function that takes the previous 20 days and creates an average. I am trying to get the macro to input that formula everytime a new row gets put in (I have the code to input the new row it just won't apply the function after the new row comes in)
The cells to be filled. The destination must include the source range.
As quoted from MSDN.
So try:
Set SourceRange = Worksheets("Sheet 1").Range("C3")
Set fillRange = Worksheets("Sheet 1").Range("C2")
SourceRange.AutoFill Destination:=Range(fillRange, SourceRange)
Another note is to use Named ranges if you are inserting rows in between.
Other ways to get formulas with updated cell references
Option Explicit
Public Sub getFormula()
With Sheet1
.Range("C3").Copy
.Range("C2").PasteSpecial xlPasteFormulas
If .ListObjects.Count = 1 Then
With .ListObjects(1) 'for tables
.Cells(2, 3).Formula = .Cells(3, 3).Formula
End With
End If
End With
End Sub
.
Also, you should not use the name of VBA method as a sub name (AutoFill)
A fast way to determine VBA keywords: click on the sub name and press F1
If the help page shows Keyword Not Found your sub name should be Ok