I am trying to match all the cells of the "M" column in Sheet1 and Sheet3, and copy and delete all the rows from Sheet1 that contain any value from Sheet3's "M" column.
Also, I want the records to get copied into "Sheet2" (all records to be deleted).
However, it is deleting all the records but copying only the first row and not all the required rows.
Below is the code:
Sub DeleteRows()
Dim rng As Range
Dim r As Long
Dim lr1 As Long
Dim lr3 As Long
Dim str As Variant
Dim i As Long: i = 1
Application.ScreenUpdating = False
lr3 = Sheets("Sheet3").Cells(Rows.Count, "M").End(xlUp).Row
Set rng = Sheets("Sheet3").Range("M2:M" & lr3)
lr1 = Sheets("Sheet1").Cells(Rows.Count, "M").End(xlUp).Row
For r = lr1 To 2 Step -1
str = Sheets("Sheet1").Cells(r, "M")
If Application.WorksheetFunction.CountIf(rng, str) > 0 Then
Sheets("Sheet1").Range(Cells(r, "A"), Cells(r, "N")).Cut Sheets("Sheet2").Cells(i, "A")
Sheets("Sheet1").Range(Cells(r, "A"), Cells(r, "N")).Delete (xlShiftUp)
i = i + 1
End If
Next r
Application.ScreenUpdating = True
End Sub
Well here's your almost exact same code just added With blocks and .'s because that might've been the problem
Sub DeleteRows()
Dim rng As Range
Dim r As Long
Dim lr1 As Long
Dim lr3 As Long
Dim str As Variant
Dim i As Long: i = 1
Application.ScreenUpdating = False
With ThisWorkbook.Worksheets("Sheet3")
lr3 = .Cells(.Rows.Count, "M").End(xlUp).Row
Set rng = .Range("M2:M" & lr3)
End With
With ThisWorkbook.Worksheets("Sheet1")
lr1 = .Cells(.Rows.Count, "M").End(xlUp).Row
For r = lr1 To 2 Step -1
str = .Cells(r, "M").Value
If Application.WorksheetFunction.CountIf(rng, str) > 0 Then
Sheets("Sheet2").Range(Sheets("Sheet2").Cells(i, "A"), Sheets("Sheet2").Cells(i, "N")).Value = _
.Range(.Cells(r, "A"), .Cells(r, "N")).Value
.Range(.Cells(r, "A"), .Cells(r, "N")).Delete (xlShiftUp)
i = i + 1
End If
Next r
End With
Application.ScreenUpdating = True
End Sub
Related
Need some solution in VBA ->If the blank value in column A then takes value from column B.
I wrote some code, but I don't have any idea why this is not working.
dim LastR as Long
LastR = Worksheets("Sheet1").Range("BU" & Worksheets("Sheet1").Rows.Count).End(xlUp).Row
dim i as long
For i = LastR To 2 Step -1
If IsEmpty(Cells(i, "a")) Then Cells(i, "a").Value = Cells(i, "b").Value
Next i
You should check if the value is empty.
See two examples:
Dim LastR As Long
LastR = Worksheets("Sheet1").Range("BU" & Worksheets("Sheet1").Rows.Count).End(xlUp).Row
Dim i As Long
For i = LastR To 2 Step -1
'If Sheets("Sheet1").Cells(i, "a") = "" Then Sheets("Sheet1").Cells(i, 1).Value = Cells(i, 2).Value
If IsEmpty(Sheets("Sheet1").Cells(i, "a").Value) = True Then Sheets("Sheet1").Cells(i, 1).Value = Cells(i, 2).Value
Next i
Loop Through the Cells of a Column
All three versions do the same and are about equally efficient.
Option Explicit
Sub FillEmptiesConstants()
Const wsName As String = "Sheet1" ' Worksheet Name
Const fRow As Long = 2 ' First Row
Const lrCol As String = "BU" ' Last Row Column
Const lCol As String = "A" ' Lookup Column
Const dCol As String = "A" ' Destination Column
Const sCol As String = "B" ' Source Column
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, lrCol).End(xlUp).Row
If lRow < fRow Then Exit Sub
Dim r As Long
For r = fRow To lRow
If IsEmpty(ws.Cells(r, lCol)) Then
ws.Cells(r, dCol).Value = ws.Cells(r, sCol).Value
End If
Next r
End Sub
Sub FillEmptiesSimple()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, "BU").End(xlUp).Row
If lRow < 2 Then Exit Sub
Dim r As Long
For r = 2 To lRow
If IsEmpty(ws.Cells(r, "A")) Then
ws.Cells(r, "A").Value = ws.Cells(r, "B").Value
End If
Next r
End Sub
Sub FillEmptiesSimpleWith()
With ThisWorkbook.Worksheets("Sheet1")
Dim lRow As Long: lRow = .Cells(.Rows.Count, "BU").End(xlUp).Row
If lRow < 2 Then Exit Sub
Dim r As Long
For r = 2 To lRow
If IsEmpty(.Cells(r, "A")) Then
.Cells(r, "A").Value = .Cells(r, "B").Value
End If
Next r
End With
End Sub
I have been trying to looping through a range to add 1 in ColB while looking at ColA values and I want to add 1 from high to low values where 0 will be empty.
Your help will be appreciated.
My try.
Dim lastRow As Integer
lastRow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
If Sheet1.Range("A2" & lastRow).Value > 0 Then
Range("B2" & lastRow).Value = 1
ElseIf Sheet1.Range("A2").Value = 0 Then
Range("B2" & lastRow).Value = ""
End If
2nd try
Dim lastRow As Integer
lastRow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
Dim c As Range
For Each c In Range("A2:A50")
If c.Value > 0 Then
Sheet1.Range("B2" & lastRow).Value = 1
End If
Next c
like this
Write to Column If the Value in Another Column is Not Equal to 0
Note that both solutions do the same.
For the array version, it is assumed that the range has at least two cells (A2:A3). If A2:A2, it will fail.
Option Explicit
Sub SlowRange()
Dim LastRow As Long
LastRow = Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Row
Dim rg As Range: Set rg = Sheet1.Range("A2:A" & LastRow)
Dim c As Range
For Each c In rg.Cells
If c.Value <> 0 Then
c.Offset(, 1).Value = 1
'Else
' c.Offset(, 1).Value = Empty
End If
Next c
End Sub
Sub FastArray()
Dim LastRow As Long
LastRow = Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Row
Dim rg As Range: Set rg = Sheet1.Range("A2:A" & LastRow)
Dim Data As Variant: Data = rg.Value
Dim r As Long
For r = 1 To UBound(Data, 1)
If Data(r, 1) <> 0 Then
Data(r, 1) = 1
Else
Data(r, 1) = Empty
End If
Next r
rg.Offset(, 1).Value = Data
End Sub
I have been trying to come up with/find a VBA code that copies blocks of data under my first block. Each block is 19 columns followed by a blank. The number of rows per block can vary.
See my screenshot below:
Therefore, I would like all my data continuous in the first columns A:S. Any help is highly appreciated.
I found the following code online, but this only pastes everything into the first column
Sub Column()
Dim iLastcol As Long
Dim iLastRow As Long
Dim jLastrow As Long
Dim ColNdx As Long
Dim ws As Worksheet
Dim myRng As Range
Dim ExcludeBlanks As Boolean
Dim mycell As Range
ExcludeBlanks = (MsgBox("Exclude Blanks", vbYesNo) = vbYes)
Set ws = ActiveSheet
iLastcol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Alldata").Delete
Application.DisplayAlerts = True
Sheets.Add.Name = "Alldata"
For ColNdx = 1 To iLastcol
iLastRow = ws.Cells(ws.Rows.Count, ColNdx).End(xlUp).Row
Set myRng = ws.Range(ws.Cells(1, ColNdx), _
ws.Cells(iLastRow, ColNdx))
If ExcludeBlanks Then
For Each mycell In myRng
If mycell.Value <> "" Then
jLastrow = Sheets("Alldata").Cells(Rows.Count, 1) _
.End(xlUp).Row
mycell.Copy
Sheets("Alldata").Cells(jLastrow + 1, 1) _
.PasteSpecial xlPasteValues
End If
Next mycell
Else
myRng.Copy
jLastrow = Sheets("Alldata").Cells(Rows.Count, 1) _
.End(xlUp).Row
mycell.Copy
Sheets("Alldata").Cells(jLastrow + 1, 1) _
.PasteSpecial xlPasteValues
End If
Next
Sheets("Alldata").Rows("1:1").EntireRow.Delete
ws.Activate
End Sub
Basic approach:
Sub Tester()
Dim c As Range, addr
Set c = ActiveSheet.Range("T1")
Do
Set c = c.End(xlToRight)
If c.Column = Columns.Count Then Exit Do
addr = c.Address 'strire the address since Cut will move c
c.CurrentRegion.Cut c.Parent.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Set c = ActiveSheet.Range(addr) '<< reset c
Loop
End Sub
This is a little more basic than #TimWilliams
With ThisWorkbook.Sheets("Alldata")
Dim lRow As Long, lCol As Long, cpyrng As Range
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 21 To lCol Step 20
If .Cells(1, i).Value <> "" And .Cells(1, i).Offset(, -1).Value = "" Then
lRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set cpyrng = .Cells(1, i).CurrentRegion
cpyrng.Cut
Sheets("Sheet2").Cells(lRow, 1).Offset(2).Insert Shift:=xlDown
End If
Next i
End With
I am trying to create a macro to copy and paste data from one Sheet to another sheet when Header and Column A data is matching and want to paste into the specific cell.
below code is working fine for me when Row(headers) order is the same in both sheets. but I need a solution for when the row (Headers) are not in the order.
"I hope I was able to explain my problem"
Sub transfer()
Dim i As Long, j As Long, lastrow1 As Long, lastrow2 As Long
Dim myname As String
lastrow1 = Sheets("sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow1
myname = Sheets("sheet1").Cells(i, "A").Value
Sheets("sheet2").Activate
lastrow2 = Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row
For j = 2 To lastrow2
If Sheets("sheet2").Cells(j, "A").Value = myname Then
Sheets("sheet1").Activate
Sheets("sheet1").Range(Cells(i, "B"), Cells(i, "F")).Copy
Sheets("sheet2").Activate
Sheets("sheet2").Range(Cells(j, "D"), Cells(j, "H")).Select
ActiveSheet.Paste
End If
Next j
Application.CutCopyMode = False
Next i
Sheets("sheet1").Activate
Sheets("sheet1").Range("A1").Select
End Sub
if i understood your goal then may try something like (code is tested with makeshift data)
Sub test()
Dim SrcWs As Worksheet, TrgWs As Worksheet
Dim Col As Long, TrgLastRw As Long, SrclastRw As Long, SrcLastCol As Long, TrgLastCol As Long
Dim SrcRng As Range, TrgRng As Range, C As Range, Hd As String
Set SrcWs = ThisWorkbook.Sheets("Sheet1")
Set TrgWs = ThisWorkbook.Sheets("Sheet2")
SrcLastCol = SrcWs.Cells(1, Columns.Count).End(xlToLeft).Column
TrgLastCol = TrgWs.Cells(1, Columns.Count).End(xlToLeft).Column
For Col = 1 To SrcLastCol
Hd = SrcWs.Cells(1, Col).Value
If Hd <> "" Then
SrclastRw = SrcWs.Cells(Rows.Count, Col).End(xlUp).Row + 1
Set SrcRng = SrcWs.Range(SrcWs.Cells(2, Col), SrcWs.Cells(SrclastRw, Col))
With TrgWs.Range(TrgWs.Cells(1, 1), TrgWs.Cells(1, TrgLastCol))
Set C = .Find(Hd, LookIn:=xlValues) 'each column header is searched in trgWs
If Not C Is Nothing Then
TrgLastRw = TrgWs.Cells(Rows.Count, C.Column).End(xlUp).Row + 1
Set TrgRng = TrgWs.Cells(TrgLastRw, C.Column).Resize(SrcRng.Rows.Count, 1)
SrcRng.Copy Destination:=TrgRng
End If
End With
End If
Next Col
End Sub
This question already has answers here:
Split comma separated entries to new rows [closed]
(2 answers)
Closed 1 year ago.
I currently have this data in a sheet
Col A Col B Col C
1 A angry birds, gaming
2 B nirvana,rock,band
What I want to do is split the comma separated entries in the third column and insert in new rows like below:
Col A Col B Col C
1 A angry birds
1 A gaming
2 B nirvana
2 B rock
2 B band
I am sure this can be done with VBA but couldn't figure it out myself.
variant using Scripting.Dictionary
Sub ttt()
Dim dic As Object: Set dic = CreateObject("Scripting.Dictionary")
Dim x&, cl As Range, rng As Range, k, s
Set rng = Range([C1], Cells(Rows.Count, "C").End(xlUp))
x = 1 'used as a key for dictionary and as row number for output
For Each cl In rng
For Each s In Split(cl.Value2, ",")
dic.Add x, Cells(cl.Row, "A").Value2 & "|" & _
Cells(cl.Row, "B").Value2 & "|" & LTrim(s)
x = x + 1
Next s, cl
For Each k In dic
Range(Cells(k, "A"), Cells(k, "C")).Value2 = Split(dic(k), "|")
Next k
End Sub
source:
result:
If you have a substantial amount of data, you willfind working with arrays beneficial.
Sub Macro2()
Dim i As Long, j As Long, rws As Long
Dim inp As Variant, outp As Variant
With Worksheets("sheet2")
inp = .Range(.Cells(1, "A"), .Cells(.Rows.Count, "C").End(xlUp)).Value2
For i = LBound(inp, 1) To UBound(inp, 1)
rws = rws + UBound(Split(inp(i, 3), ",")) + 1
Next i
ReDim outp(1 To rws, 1 To 3)
rws = 0
For i = LBound(inp, 1) To UBound(inp, 1)
For j = 0 To UBound(Split(inp(i, 3), ","))
rws = rws + 1
outp(rws, 1) = inp(i, 1)
outp(rws, 2) = inp(i, 2)
outp(rws, 3) = Trim(Split(inp(i, 3), ",")(j))
Next j
Next i
.Cells(1, "A").Resize(UBound(outp, 1), UBound(outp, 2)) = outp
End With
End Sub
This is not a polished solution, but I need to spend some time with the wife.
But still another way of thinking about it.
This code assumes that the sheet is called Sheet4 and the range that needs to be split is col C.
Dim lastrow As Integer
Dim i As Integer
Dim descriptions() As String
With Worksheets("Sheet4")
lastrow = .Range("C1").End(xlDown).Row
For i = lastrow To 2 Step -1
If InStr(1, .Range("C" & i).Value, ",") <> 0 Then
descriptions = Split(.Range("C" & i).Value, ",")
End If
For Each Item In descriptions
.Range("C" & i).Value = Item
.Rows(i).Copy
.Rows(i).Insert
Next Item
.Rows(i).EntireRow.Delete
Next i
End With
This will do what you want.
Option Explicit
Const ANALYSIS_ROW As String = "C"
Const DATA_START_ROW As Long = 1
Sub ReplicateData()
Dim iRow As Long
Dim lastrow As Long
Dim ws As Worksheet
Dim iSplit() As String
Dim iIndex As Long
Dim iSize As Long
'Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With ThisWorkbook
.Worksheets("Sheet1").Copy After:=.Worksheets("Sheet1")
Set ws = ActiveSheet
End With
With ws
lastrow = .Cells(.Rows.Count, ANALYSIS_ROW).End(xlUp).Row
End With
For iRow = lastrow To DATA_START_ROW Step -1
iSplit = Split(ws.Cells(iRow, ANALYSIS_ROW).Value2, ",")
iSize = UBound(iSplit) - LBound(iSplit) + 1
If iSize = 1 Then GoTo Continue
ws.Rows(iRow).Copy
ws.Rows(iRow).Resize(iSize - 1).Insert
For iIndex = LBound(iSplit) To UBound(iSplit)
ws.Cells(iRow, ANALYSIS_ROW).Offset(iIndex).Value2 = iSplit(iIndex)
Next iIndex
Continue:
Next iRow
Application.CutCopyMode = False
Application.Calculation = xlCalculationAutomatic
'Application.ScreenUpdating = True
End Sub