How to copy all rows from one column that contains two specific values to a different sheet on Excel - excel

I am trying to copy all rows from an excel sheet (Sheet1) that have a specific value that is referenced from a different cell. and then paste them into a new sheet(Sheet2).
My specific example is I have figured out that I want to copy the rows that have a '0' and/or '35' in column A. these values can change however due to what ever is in "B6" and "B7".
The problem that I am having is it only copys rows that contain the value from "B6" which is 0 and ignoring my command that wants the "B7" value which is 35 in my instance. My code is below for reference
Sub Temp_copy()
set i = Sheets("Sheet1")
set e = Sheets("Sheet2")
Dim d
Dim j
d = 1
j = 2
Do Until IsEmpty(i.Range("A" & j))
If i.Range("A"&j) = Range("B6"&j) Then
d=d+1
e.Rows(d).Value=i.Rows(j).Value
End If
j = j+1
Loop
Do Until IsEmpty(i.Range("A" & j))
If i.Range("A"&j) = Range("B7"&j) Then
d=d+1
e.Rows(d).Value=i.Rows(j).Value
End If
j = j+1
Loop
End Sub
I am new to VBA so any help or guidance to achieve what I need would be muchly appreciated.

Instead of looping through cells, you may use Autofilter to copy the desired data like below...
Sub CopyRows()
Dim sws As Worksheet, dws As Worksheet
Dim lr As Long
Application.ScreenUpdating = False
Set sws = Sheets("Sheet1")
Set dws = Sheets("Sheet2")
lr = sws.Cells(Rows.Count, 1).End(xlUp).Row
dws.Cells.Clear
sws.AutoFilterMode = False
'Assuming Row1 is the Header Row on Sheet1
With sws.Range("A1:A" & lr)
.AutoFilter field:=1, Criteria1:=sws.Range("B6").Value, Operator:=xlOr, Criteria2:=sws.Range("B7").Value
.SpecialCells(xlCellTypeVisible).EntireRow.Copy
dws.Range("A1").PasteSpecial xlPasteValues
End With
sws.AutoFilterMode = False
Application.CutCopyMode = 0
Application.ScreenUpdating = True
End Sub

The simple or operator will help you get this done!
Sub Temp_copy()
Set i = Sheets("Sheet1")
Set e = Sheets("Sheet2")
Dim d
Dim j
d = 1
j = 2
Do Until IsEmpty(i.Range("A" & j))
If i.Range("A" & j) = Range("$B$6") Or i.Range("A" & j) = Range("$B$7") Then
d = d + 1
e.Rows(d).Value = i.Rows(j).Value
End If
j = j + 1
Loop
End Sub

Related

Excel VBA - Delete empty columns between two used ranges

I would like to delete all empty columns between 2 used ranges, based on the screenshot:
However, these two used ranges may have varying column length, thus the empty columns are not always Columns D to K.
Here is my code:
Sub MyColumns()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Workbooks.Open ("BOOK2.xlsx")
Workbooks("BOOK2.xlsx").Activate
Workbooks("BOOK2.xlsx").Sheets(1).Activate
Workbooks("BOOK2.xlsx").Sheets(1).Cells(1, 4).Value = "NON-EMPTY"
Dim finalfilledcolumn As Long
finalfilledcolumn = Workbooks("BOOK2.xlsx").Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column
Dim iCol As Long
Dim i As Long
iCol = firstfilledcolumn + 1
'Loop to delete empty columns
For i = 1 To firstfilledcolumn + 1
Columns(iCol).EntireColumn.Delete
Next i
Workbooks("BOOK2.xlsx").Close SaveChanges:=True
MsgBox "DONE!"
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
However, the empty columns still remain.
Do note that the last filled column for the first used range, Place = "USA", Price = "110" and Category = "Mechanical" may not be fixed at Column C, but could go to Column D, E, etc.
Many thanks!
Please, try the next way:
Sub deleteEmptyColumn()
Dim sh As Worksheet, lastCol As Long, rngColDel As Range, i As Long
Set sh = ActiveSheet 'use here your necessary sheet, having the workbook open
'if not open, you can handle this part...
lastCol = sh.cells(1, sh.Columns.count).End(xlToLeft).column
For i = 1 To lastCol
If WorksheetFunction.CountA(sh.Columns(i)) = 0 Then
If rngColDel Is Nothing Then
Set rngColDel = sh.cells(1, i)
Else
Set rngColDel = Union(rngColDel, sh.cells(1, i))
End If
End If
Next i
If Not rngColDel Is Nothing Then rngColDel.EntireColumn.Delete
End Sub
Try this ..
Dim rng As Range, i As Long
Set rng = Workbooks("BOOK2.xlsx").Sheets(1).UsedRange
For i = rng.Columns.Count To 1 Step -1
If WorksheetFunction.CountA(rng.Columns(i)) = 0 Then
rng.Columns(i).EntireColumn.Delete
End If
Next i

Why wont my Row of data paste on the next available row?

I have the below code which takes rows of data from one worksheet(DataSheet) that has "Actioned" in Column C and should paste it to the next available row on the worksheet (Actioned). The issue at hand is that it doesn't paste it on the next available row, its pasting to Row 2700.
I've cleared contents on all the cells and restarted the workbook but it still doesn't paste it onto the next free row.
can anyone see where I'm going wrong?
Dim xRg As Range
Dim xCell As Range
Dim i As Long
Dim J As Long
Dim K As Long
i = Worksheets("DataSheet").UsedRange.Rows.Count
J = Worksheets("Actioned").UsedRange.Rows.Count
If J = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Actioned").UsedRange) = 0 Then J = 0
End If
Set xRg = Worksheets("DataSheet").Range("C2:C" & i)
On Error Resume Next
Application.ScreenUpdating = False
For K = 1 To xRg.Count
If CStr(xRg(K).Value) = "Actioned" Then
xRg(K).EntireRow.Copy Destination:=Worksheets("Actioned").Range("A" & J + 1)
xRg(K).EntireRow.Delete
If CStr(xRg(K).Value) = "Actioned" Then
K = K - 1
End If
J = J + 1
End If
Next
Application.ScreenUpdating = True
End Sub ```
I am still a novice at VBA so please bare with my ignorance.
UsedRange can take into account the formatting of empty cells which is not visible to you.
I suggest to use the following method to get the last row of a specific column:
i= Worksheets("DataSheet").Range("C" & Worksheets("DataSheet").Rows.Count).End(xlUp).Row
or:
Dim wsDS As Worksheet: Set wsDS = Worksheets("DataSheet")
Dim iRows As Long
iRows = wsDS.Range("C" & wsDS.Rows.Count).End(xlUp).Row

wrap text of a sheet with merged and not merged cells

I have a sheet with some cells are merged in rows, and some are not. I want to wrap all the cells and if rows contains merged cells, set the rows height to max of all cells height
In the excel file, you can find the sheet I am working with, what I want to have, the excel macro I wrote, what I get with that macro. I also put them here.
This is what I have: (column D is a hidden column)
This is what I want to have: (for the rest of the sheet see attached excel file)
I wrote an excel VBA macro to do the job, but there is no luck.
Sub MergeCells2()
Application.DisplayAlerts = False
Dim allRange As Range
Dim xCell As Range
On Error Resume Next
Dim i_row As Integer
Dim nRowsToMerge As Integer
Dim rangeToMerge As Range
Worksheets("What I have").Activate
LastCol = ActiveSheet.Range("a1").End(xlToRight).Column
LastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, LastCol).End(xlUp).Row
Set allRange = Application.Range("a1", ActiveSheet.Cells(LastRow, LastCol))
allRange.WrapText = True
If allRange Is Nothing Then Exit Sub
nRowsToMerge = 1
Set heightToSet = Range("A2").RowHeight
For i_row = 2 To LastRow
Set i_rowRange = allRange.Rows(i_row - 1)
If (allRange.Cells(i_row, 1) = "") Then
nRowsToMerge = nRowsToMerge + 1
ElseIf nRowsToMerge = 1 Then
heightToSet = i_rowRange.RowHeight
Else
Set rangeToMerge = ActiveSheet.Range(ActiveSheet.Cells(i_row - nRowsToMerge, 1), ActiveSheet.Cells(i_row - 1, LastCol))
For Each xCell In rangeToMerge
cellrow = xCell.Row
If (rangeToMerge.Cells(cellrow, 1) = "") Then
If xCell.Value = "" Then
Range(xCell, xCell.Offset(-1, 0)).Merge
End If
End If
Next
rangeToMerge.RowHeight = heightToSet
heightToSet = i_rowRange.RowHeight
nRowsToMerge = 1
End If
Next i_row
End Sub
This is what I get:
I don't know what is wrong with it and I have to say that I don't know much about VBA programming.
I hope I was clear with my question.
Please help, I am working on this for days now :(
Cheers,
Eda
The idea:
Start by wrapping all cells, and using AutoFit for all rows. This way Excel will automatically set the row height properly.
Loop through the rows merging the cells and dividing the height of the row with the wrapped text over the rows to be merged.
This is how:
Sub NewMerger()
Dim r As Long, rMax As Long, re As Long, cMax As Long, c As Long, n As Long, h As Single, mr As Long
Application.DisplayAlerts = False
'Create a copy of the input
Sheets("What I have").Copy After:=Sheets(Sheets.Count)
On Error Resume Next
Sheets("New Result").Delete
ActiveSheet.Name = "New Result"
'merge and use autofit to get the ideal row height
Cells().WrapText = True
Rows.AutoFit
'get max row and column
cMax = Cells(1, 1).End(xlToRight).Column
rMax = Cells(Rows.Count, 1).End(xlUp).Row
'loop through rows, bottom to top
For r = rMax To 2 Step -1
If Cells(r, 1).Value = "" Then
If re = 0 Then re = r 'If we don't have an end row, we do now!
ElseIf re > 0 Then 'If re has an end row and the current row is not empty (AKA start row)
h = Rows(r).RowHeight 'Get the row height of the start row
n = re - r + 1 'calculate the number of rows
If n > 0 Then Rows(r & ":" & re).RowHeight = h / n 'devide the row hight over all rows
For c = 1 To cMax 'And merge
For mr = re To r Step -1 'Merge only empty cells
If Cells(mr, c).Value = "" Then
Range(Cells(mr, c), Cells(mr - 1, c)).MergeCells = True
End If
Next
Next
re = 0 'We don't have an end row now
End If
Next
Application.DisplayAlerts = True
End Sub

Delete rows based on values of two columns

I want to retain any rows in excel which only contain "ECGS2A" or "ECGS2B" in column E and "Customer Opt In" in column M but having difficulty with trying different VBA codes.
I need to retain headers on row 4 but when trying to add range other than column E on:
j = Range("E" & Rows.Count).End(xlUp).Row
I get an error or "Run time error '1004': Method of 'Range' of object_Global' failed
' Deleting entire rows with MyTarget
Sub myDeleteRows2()
Const MyTarget = "*ECGS2A*"
Dim Rng As Range, DelCol As New Collection, x
Dim I As Long, j As Long, k As Long
' Calc last row number
j = Range("E" & Rows.Count).End(xlUp).Row
' Collect rows range with MyTarget
For I = 1 To j
If WorksheetFunction.CountIf(Rows(I), MyTarget) = 0 Then 'changed from > 0
k = k + 1
If k = 1 Then
Set Rng = Rows(I)
Else
Set Rng = Union(Rng, Rows(I))
If k >= 100 Then
DelCol.Add Rng
k = 0
End If
End If
End If
Next
If k > 0 Then DelCol.Add Rng
' Turn off screen updating and events
Application.ScreenUpdating = False
Application.EnableEvents = False
' Delete rows with MyTarget
For Each x In DelCol
x.Delete
Next
' Update UsedRange
With ActiveSheet.UsedRange: End With
' Restore screen updating and events
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
also tried
Sub DeleteRowsBasedOnMultipleCriteria()
lRow = 13 ' Your last row with the data
Do While lRow >= 1
'1=Column A,6=Column F, 18=Column R
If Cells(lRow, 5) = "ECGS9" _
Or Cells(lRow, 13) = "Customer Opt Out" Then
Rows(lRow).Delete
End If
lRow = lRow - 1
Loop
End Sub
I expect to be left with column E only displaying anything with ECGS2A or ECGS2B and column M as Customer Opt In. If the columns display anything other than those mentioned, I want them deleted.
Sub Macro1()
Dim LRow As Long, i As Long
Application.ScreenUpdating = False
With ThisWorkbook.Worksheets("Sheet1") 'Change to your sheet name
LRow = .Range("E" & .Rows.Count).End(xlUp).Row
For i = LRow To 5 Step -1
If Not ((.Cells(i,5) Like "ECGS2A*" Or .Cells(i,5) Like "ECGS2B*") And .Cells(i, 13) Like "Customer Opt In*") Then
.Rows(i).Delete
End If
Next i
End With
Application.ScreenUpdating = True
End Sub

Editing Excel Macro VBA to have it fill in Column C and right, instead of Column A

I am currently using the Macro below for excel to move data from one one sheet to another. It is set up to fill from Row 2 down, as long as the rows are empty. I not want to have it already contain data in Columns 2 & 3. I have tried a number of things and am not having a lot of luck. I am new to this and "fixing" someone else's macro.
Sub MergeSheets()
Sheets("New").Activate
LastRowNew = Application.WorksheetFunction.CountA(Columns(1))
For i = 2 To LastRowNew
OrderNumber = Cells(i, 3)
Sheets("PRIOrders").Activate
LastRowPRI = Application.WorksheetFunction.CountA(Columns(1))
For j = 2 To LastRowPRI
If Cells(j, 3) = OrderNumber Then
Exit For
ElseIf j = LastRowPRI Then
Sheets("New").Rows(i).Copy Destination:=Sheets("PRIOrders").Rows(LastRowPRI + 1)
Sheets("PRIOrders").Rows(2).Copy
Sheets("PRIOrders").PasteSpecial xlPasteFormats
End If
Next
Sheets("New").Activate
Next
Sub MergeSheets()
Dim shtNew As Worksheet, shtOrders As Worksheet
Dim rngOrder As Range, rngNewOrders As Range
Dim f As Range, lastRow As Long
Set shtNew = ActiveWorkbook.Sheets("New")
Set rngNewOrders = shtNew.Range(shtNew.Range("C2"), _
shtNew.Cells(Rows.Count, 3).End(xlUp))
Set shtOrders = ActiveWorkbook.Sheets("PRIOrders")
For Each rngOrder In rngNewOrders.Cells
Set f = shtOrders.Columns(3).Find(Trim(rngOrder.Value), , xlValues, xlWhole)
If f Is Nothing Then
'find the last occupied row in Col B or C
lastRow = Application.Max(shtOrders.Cells(Rows.Count, 2).End(xlUp).Row, _
shtOrders.Cells(Rows.Count, 3).End(xlUp).Row)
rngOrder.EntireRow.Copy shtOrders.Cells(lastRow + 1, 1)
End If
Next rngOrder
End Sub

Resources