Deleting cells and corresponding row if criteria is met - excel

I have a spreadsheet that has columns from A5 to AA5 and has data from A6 to AA10000. In cells A1, a user inputs a value, in cell A2 is a drop box that contains the headers of columns X to AA (A, B, C, D), and in A3 I have a dropdown of logical operators (<,>,<>,=). I'm trying to write a script that goes through columns X to AA and remove the cells that met a criteria that a user sets, e.g. user inputs a value of 300, a header "B" and a logical operator "<" and the macro goes through column Y which has the header "B" and deletes all values that are less than 300, the deletes the row from A to AA.
So far I've attempted this:
Sub removedata()
Dim ws As Worksheet
Dim rng As Range
Dim headerval As Variant
Dim sign As Variant
Dim inputval As Variant
Dim b_header As Range
Dim Cell As Range
Set ws = Worksheets("Sheet1")
Set rng = ws.Range("X5:AA5000")
Set b_header = ws.Range("X5:X5000")
inputval = cells(1, 1).Value
headerval = cells(2, 1).Value
sign = cells(3, 1).Value
For Each Cell In b_header.cells
If (headerval = "B") And (sign = "<") And (inputval < Cell.Value) Then
Cell.Delete
End If
Next Cell
End Sub
I've only attempted it for B column as a test to see whether or not I could get something to happen. When I run this Macro, it just buffers for a second and then nothing else happens.
Any help would be greatly appreciated!
Edit: Actually I realised it deletes the values that are greater than the input (Cell A1), however it only deletes a few of them each time I run it, it also moves the cells below it to its position.

The COUNTIF/COUNTIFS worksheet function accepts and interprets criteria as strings. You can use with Evaluate or directly through an application object.
Option Explicit
Sub delSpecial()
Dim lr As Long, i As Long, c As String, cl As Long
With Worksheets("sheet6")
c = .Cells(3, "A").Value & .Cells(1, "A").Value
cl = Application.Match(.Cells(2, "A").Value, .Rows(5), 0)
lr = Application.Max(.Cells(.Rows.Count, "X").End(xlUp).Row, _
.Cells(.Rows.Count, "Y").End(xlUp).Row, _
.Cells(.Rows.Count, "Z").End(xlUp).Row, _
.Cells(.Rows.Count, "AA").End(xlUp).Row)
For i = lr To 6 Step -1
If CBool(Application.CountIf(.Cells(i, cl), c)) Then
.Cells(i, "A").Resize(1, 27).Interior.Color = vbYellow
'.Rows(i).EntireRow.Delete
End If
Next i
End With
End Sub

Related

Split zip code in a column into 2 columns

This is what my end result should look like. If there is not the four digits to move over to the second column then fill with 4 zeros.
How can I split zip code in a column into 2 columns and fill empty cells in column 2 if first column has only 5 digits?
Here is what I have been working with
Dim ws As Worksheet
Dim cell As Range
Set ws = Worksheets("sheet1")
For Each cell In ws.Range("K2:K500").Cells
cell.Offset(0, 1).Value = Left(cell.Value, 5)
Next cell
Dim cel As Range, rngC As Range, rngB As Range
Dim lastRowA As Long, lastRowB As Long
With ws
lastRowK = .Cells(.Rows.Count, "K").End(xlUp).Row 'last row of column A
lastRowL = .Cells(.Rows.Count, "L").End(xlUp).Row 'last row of column B
For Each cel In .Range("K2:K" & lastRowL) 'loop through column L
'check if cell in column A exists in column B
If WorksheetFunction.CountIf(.Range("K2:K" & lastRowL), cel) = 0 Then
cel.Offset(0, 3).Value = Right(cel.Value, 4)
'.Range("M" & cel.Row) = Right(cell.Value, 4)
Else
.Range("M" & cel.Row) = "0000"
End If
Next
End With
In case you want to bypass VBA and use formulas, you can do this.
Cell B2:
=LEFT(A2,5)
Cell C2:
=IF(LEN(A2)=9,RIGHT(A2,4),"0000")
One of the simplest ways to solve this problem is to supplement the original string with a large number of zeros and take the values ​​of the first and second five characters for two cells:
Sub setZIPandZeros()
Const TEN_ZEROS = "0000000000" ' 10 times
Dim ws As Worksheet
Dim cell As Range
Dim sLongString As String
Set ws = Worksheets("Sheet1")
For Each cell In ws.Range("K2:K" & ws.Cells(ws.Rows.Count, "K").End(xlUp).Row).Cells
sLongString = Trim(cell.Text) & TEN_ZEROS
cell.Offset(0, 1).Resize(1, 2).NumberFormat = "#"
cell.Offset(0, 1).Resize(1, 2).Value = Array(Left(sLongString, 5), _
Mid(sLongString, 6, 5))
Next cell
End Sub
Update The modified code is much faster and gives a result that more closely matches the description of the task:
Sub setZipZeros()
Dim ws As Worksheet
Dim rResult As Range
Set ws = Worksheets("Sheet1")
' Addressing R1C1 is used in the formulas - If the original range
' is shifted to another column, you will need to change the letter
' of the column "K" only in this line
Set rResult = ws.Range("K2", ws.Cells(ws.Rows.Count, "K").End(xlUp)).Offset(0, 1)
' If the columns L:M are already in text format, then instead of
' the results we will get the texts of formulas
rResult.Resize(, 2).NumberFormat = "General"
' These two lines do most of the work:
rResult.Formula2R1C1 = "=LEFT(TRIM(RC[-1])&""00000"",5)"
rResult.Offset(0, 1).Formula2R1C1 = "=MID(TRIM(RC[-2])&""000000000"",6,4)"
' We don't know if auto-recalculation mode is on now
' Application.Calculation = xlAutomatic
ActiveSheet.Calculate
Set rResult = rResult.Resize(, 2)
' Set the text format for the cells of the result
' to prevent conversions "00123" to "123"
rResult.NumberFormat = "#"
' Replace formulas with their values
rResult.Value = rResult.Value
End Sub

Auto Fill Sequential Dates Until Next Row Down has Value

I am trying to pull down the date column to fill in the next sequential dates in the blank cells until the next cell down has a value in it. For example, the blank cells in the highlighted date range should read 3/23/2019 & 3/24/2019 (see screenshot, Column C):
Here is the code that I have crudely put together. But I am so new to this, I am not sure where I am going wrong. In my logic, I execute the code starting from Range C2:
Sub fillInDates()
Dim cellEndRange As Range
Dim cellStartRange As Range
Selection.End(xlDown).Select
ActiveCell.Offset(RowOffset:=-1, ColumnOffset:=0).Activate
cellEndRange = ActiveCell
Selection.End(xlUp).Select
cellStartRange = ActiveCell
cellStartRange.AutoFill Destination:=cellStartRange & cellEndRange
This can be done without VBA code.
select column C
hit F5 or Ctrl-G to open the Go To dialog
click Special
tick Blanks and hit OK
now all blank cells are selected. Without changing the selection, type a = character
hit the up arrow to reference the cell above the current cell
type +1 to add one day to the date from the cell above
hold down the Ctrl key and hit Enter.
Now that formula is in all the cells that were previously blank. You can use copy/Paste Values to replace the formula with the values it calculated.
Try, you can work with below.
Sub test()
Dim Ws As Worksheet
Dim vDB As Variant
Dim rngDB As Range
Dim myDate As Date
Dim i As Long
Set Ws = ActiveSheet
With Ws
Set rngDB = .Range("c2", .Range("c" & Rows.Count).End(xlUp))
End With
vDB = rngDB
For i = 1 To UBound(vDB, 1)
If vDB(i, 1) = "" Then
myDate = myDate + 1
vDB(i, 1) = myDate
Else
myDate = vDB(i, 1)
End If
Next i
rngDB = vDB
End Sub

Calculation of values based on the color of cells in Excel VBA

The code shows a simple average calculation based on the values in the defined cells. Those cells are highlighted in three colors. The aim is to take the values into the calcuation which cell color is e.g. green. I know the "if" command is needed, I just dont know where excatly to put it in:
Dim wb As Workbook, wq As Object
Dim ws As Worksheet, datdatum
Dim cell As Range, cell2 As Range, col As Long
ws.Range("H104:U104").Formula = "= Average(H34,H39,H68,H71,H83)"
I'll assume that entire rows are not green and that each column needs to be looked at independently.
Loop through each column from H to U. Loop through each cell in each column. Build a union of the cells that are green and average the union. Move on to the next column.
There is no point in building a formula for each column since any change would require rerunning the sub procedure. These will work on both manually set and conditional formatted cell colors.
.DisplayFormat does not work within a User Defined Function.
dim c as long, r as long, rng as range
with worksheets("sheet1")
for c =8 to 21
for r=2 to 103
if .cells(r, c).displayformat.interior.color = vbgreen then
if rng is nothing then
set rng = .cells(r, c)
else
set rng = union(rng, .cells(r, c))
end if
end if
next r
if not rng is nothing then _
.cells(104, c) = application.average(rng)
'alternate
'if not rng is nothing then _
'.cells(104, c).formula = "=average(" & rng.address(0,0) & ")"
next c
end with
Alternate,
dim c as long
with worksheets("sheet1")
if .autofiltermode then .autofiltermode = false
for c =8 to 21
with .range(.cells(1, c), .cells(103, c))
.AutoFilter Field:=1, Criteria1:=vbgreen, Operator:=xlFilterCellColor
.cells(104, c) = application.subtotal(101, .cells)
.AutoFilter
end with
next c
end with

VBA code that will look for certain criteria and if it matches place data from a different column into a another one

I need help with a VBA code that will look for certain criteria and if it matches place data from a different column into a another one.
If column C says "Circum + spa" and D says "100" then the values in row F need to move over two columns to H
until column C says "Circum + spa" and D says "0" (where it will stay in column F.)
finished result will looks like a snake.
The code I have started with this process with is:
Dim l As Long
With ActiveSheet
l = .Cells(.Rows.Count, "C").End(xlUp).Row
For i = 1 To l
If .Cells(i, "C").Value2 = "CIRCUM + SPA" And
.Cells(i, "D") = "100" Then
.Cells(i + 1, "F").Value = .Cells(i + 1, "H").Value
Next
End With
But currently it just makes one row down in column F empty... I have also attempted cut/paste and an offset but all I get are error messages.
I also know that using +1 isn't going to work in final result because I need it to grab everything until the other condition is met.
I have not started on that yet, but would appreciate any advise on a Do-Until loop.
I have attached pictures of what my worksheet looks like now vs what I need it to look like after the macro runs. Also, the rows that move will not always contain 4 cells, sometimes there will be more that's why I need the do until rather than a set range.
before[1]
after (2)
Try this
Sub Demo()
Dim ws As Worksheet
Dim cel As Range, fCell As Range, lCell As Range
Dim lastRow As Long
Dim flag As Boolean
Set ws = ThisWorkbook.Sheets("Sheet4") 'change Sheet4 to your data sheet
flag = False
With ws
lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row 'last row with data in Column C
For Each cel In .Range("C2:C" & lastRow) 'loop through each cell in Column C
If UCase(cel.Value) = "CIRCUM + SPA" Then 'check if Command Name is "CIRCUM + SPA"
If cel.Offset(, 1).Value = 100 Then 'check if SP is 100
Set fCell = cel.Offset(1, 0) 'set first cell to be copied in fCell
flag = True
ElseIf cel.Offset(, 1).Value = 0 Then 'check if SP is 0
If flag Then 'move ahead only if ("CIRCUM + SPA" & 100) already found
Set lCell = cel.Offset(-1, 0) 'set last cell to be copied in lCell
Set rng = .Range(fCell, lCell).Offset(, 3) 'set range using fCell and lCell
rng.Cut rng.Offset(, 2) 'move data from Column F to Column H
flag = False
End If
End If
End If
Next cel
End With
End Sub

Write cell value from one column to a location specified by other cells

I have a value in Column A which I want to write to a separate sheet, there are column and row numbers which specify the location I want to write that value in the same row as the value in column A.
For instance the value in A8 has column number "2" in Q8 and row number "118" in S8. So I want to write a formula in the new sheet which puts the value of A8 into cell B118 in the new sheet. And for this to go down with all the values in A:A as the first sheet continues to be filled in.
I've tried doing this with sumifs formula here but its not quite working out;
=IF(SUMIFS(sheet1!$A:$A,sheet1!$Q:$Q,COLUMN(B8),sheet1!$S:$S,ROW(B8))," ",sheet1!$A:$A)
If you want the formula in the new sheet to reference the cell in Sheet1 then:
Sub marine()
Dim cl As Long, rw As Long, source As String
cl = Range("Q8").Value
rw = Range("S8").Value
Sheets("new").Cells(rw, cl).Formula = "=Sheet1!A8"
End Sub
and if you simply want A8's value transferred to the new sheet, then:
Sub marine2()
Dim cl As Long, rw As Long, source As String
cl = Range("Q8").Value
rw = Range("S8").Value
Sheets("new").Cells(rw, cl).Value = Range("A8").Value
End Sub
EDIT#1:
Here is a version that will handle the entire column:
Sub marine3()
Dim cl As Long, rw As Long, source As String
Dim i As Long, N As Long
N = Cells(Rows.Count, "A").End(xlUp).Row
For i = 8 To N
cl = Range("Q" & i).Value
rw = Range("S" & i).Value
If cl <> 0 And rw <> 0 Then
Sheets("new").Cells(rw, cl).Value = Range("A" & i).Value
End If
Next i
End Sub
Here is my answer.
Sub movindData()
'take all the data from sheet1 and move it to sheet2
Dim sht2 As Worksheet
Dim r
Dim c
Dim i
Dim rng As Range
Dim A 'for each value in column A
Dim Q 'for each value in column Q (the column)
Dim S 'for each value in column S (the row)
r = Range("A1").End(xlDown).Row 'the botton of columns A, the last row
'I take the inicial cells as a A1, but you
'can change it as you need.
c = 1 'the column A
Set rng = Range(Cells(1, 1), Cells(r, c)) 'this takes just the range with the data in columns A
Set sht2 = Sheets("Sheet2")
For Each i In rng
A = i.Value 'Store the value of every cell in column A
Q = i.Offset(0, 16).Value 'Store the value of every cell in column Q (the destination column in sheet2)
S = i.Offset(0, 18).Value 'Store the value of every cell in column s (the destination row in sheet2)
sht2.Cells(Q, S).Value = A
Next i
End Sub

Resources