VBA insert rows_dynamic - excel

Below is the piece of code in VBA which basically insert no of rows based on a count present in a specific cell, Now I want to change the code so that no of rows that will be inserted is to be one less then the count present in a specific cell.
for eg- if in a specific column and specific cell count=N then macro will runn and add N no of rows.Now I want rows is to be added is one less i.e N-1
Sub InsertRowsIf()
Dim lr As Long, R As Range, i As Long
lr = Range("R" & Rows.Count).End(xlUp).Row
Set R = Range("R3", "R" & lr)
Application.ScreenUpdating = False
For i = R.Rows.Count To 1 Step -1
If IsNumeric(R.Cells(i, 1).Value) And Not IsEmpty(R.Cells(i, 1)) Then
R.Cells(i, 1).Offset(1, 0).Resize(R.Cells(i, 1).Value).EntireRow.Insert
End If
Next i
End Sub

I think by trying to insert the use of R as a Range is causing issues. It is not needed.
Sub InsertRowsIf()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1") ' Change to your sheet
Dim lr As Long
lr = ws.Range("R" & Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
Dim i As Long
For i = lr To 3 Step -1
If IsNumeric(ws.Cells(i, 18).Value) And ws.Cells(i, 18) <> "" Then
ws.Cells(i, 1).Offset(1,0).Resize(ws.Cells(i, 18).Value - 1).EntireRow.Insert
End If
Next i
Application.ScreenUpdating = True
End Sub

You forgot to turn ScreenUpdating back on. Updated code to skip last row and applied standard indentation.
Option Explicit
Sub InsertRowsIf()
Dim lr As Long, R As Range, i As Long
lr = Range("R" & Rows.Count).End(xlUp).Row
Set R = Range("R3:R" & lr - 1)
Application.ScreenUpdating = False
For i = R.Rows.Count To 1 Step -1
If IsNumeric(R.Cells(i, 1).Value) And Not IsEmpty(R.Cells(i, 1)) Then
R.Cells(i, 1).Offset(1, 0).Resize(R.Cells(i, 1).Value).EntireRow.Insert
End If
Next i
Application.ScreenUpdating = True
End Sub

Related

Clear adjacent duplicates only

This sub clears duplicate rows between two columns.
If it finds a new pair in columns F & G, it will clear that pair throughout F & G.
I'm trying to clear values that are directly below the original values.
I'm trying to reset after a duplicate been cleared, so that it doesn't clear values that aren't directly below the original values.
Sub clearDups1()
Dim lngMyRow As Long
Dim lngMyCol As Long
Dim lngLastRow As Long
Dim objMyUniqueData As Object
Application.ScreenUpdating = False
lngLastRow = Range("F:G").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).row
Set objMyUniqueData = CreateObject("Scripting.Dictionary")
For lngMyRow = 1 To lngLastRow 'Assumes the data starts at row 1. Change to suit if necessary.
If objMyUniqueData.Exists(CStr(Cells(lngMyRow, 6) & Cells(lngMyRow, 7))) = False Then
objMyUniqueData.Add CStr(Cells(lngMyRow, 6) & Cells(lngMyRow, 7)), Cells(lngMyRow, 6) & Cells(lngMyRow, 7)
Else
Range(Cells(lngMyRow, 6), Cells(lngMyRow, 7)).ClearContents
End If
Next lngMyRow
Set objMyUniqueData = Nothing
Application.ScreenUpdating = True
End Sub
Any input appreciated.
You don't need a dictionary for this:
Sub clearDups1()
Dim lngMyRow As Long, lngLastRow As Long, ws As Worksheet
Dim k As String, kPrev As String
Set ws = ActiveSheet
lngLastRow = ws.Range("F:G").Find("*", SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).row
Application.ScreenUpdating = False
kPrev = Chr(0) 'won't occur in your data
For lngMyRow = 1 To lngLastRow 'Assumes the data starts at row 1. Change to suit if necessary.
k = CStr(ws.Cells(lngMyRow, 6).Value) & "<>" & CStr(ws.Cells(lngMyRow, 7).Value)
If kCurr = k Then 'same as previous row?
ws.Cells(lngMyRow, 6).Resize(1, 2).ClearContents
End If
kPrev = k 'set as key for previous row
Next lngMyRow
Application.ScreenUpdating = True
End Sub
You can also try this code. It does what you have asked.
Leave the first occurring of the same dups
Start from the bottom to delete them and leave the final which in our case will be original
Using the above ways you can achieve what you have asked for.
Sub clearDups()
Dim lR As Long, r As Long
Dim x As 99999
Dim f(x), g(x) As String
Dim lRow As Long, lCol As Long, i As Long
lRow = Range("F" & Rows.Count).End(xlUp).Row
For lR = 2 To lRow
f(lR - 1) = Cells(lR, "F").Value
g(lR - 1) = Cells(lR, "G").Value
Next
For Each s In f
i = i + 1
If Application.CountIf(Range("F1:G" & lRow), s) = 2 Then
Cells(i, "F").Value = ""
Cells(i, "G").Value = ""
End If
Next
End Sub

Insert Row when 2 conditions are met

I have created below code which works like IF Col"B" any cell <> "" And Col"L" any cell = "Leop" then add row below to the active cell.
I mean I'm trying to achieve is to insert single row after certain row which contain in column B any value, and if column L in same row contains value = "Leop". Then add the row after that certain row.
But an error is appear. Compile Error: Invalid use of property on xlDown
Your help will be appreciated to fix it.
From this:
to this:
Sub firstcondition()
Dim ws As Worksheet
Dim LRow As Long
Dim rng As Range
Dim rng2 As Range
Dim i As Long
Dim p As Long
Dim dat As Variant
Dim datt As Variant
Dim IRow As Long
Set ws = Thisworkbooks.Sheets("Sheet2")
With ws
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("B2:B" & LRow)
Set rng2 = .Range("L2:L" & LRow)
dat = rng
datt = rng2
IRow = Selection.Row
For i = LBound(dat, 1) To UBound(dat, 1)
For p = LBound(datt, 1) To UBound(datt, 1)
If dat(i, 1) <> "" And datt(p, 1) = "Leop" Then
Rows(IRow + 1).Select
Selection.Insert Shift: xlDown
End If
End Sub
It will be like in formula:
IF(AND(B2<>"",L2="Leop"),"InsertRowBelow to Row 2 If condition is met","")
and will drag it down to the lastRow.
Thisworkbooks.Sheets("Sheet2") should be Thisworkbook.Sheets("Sheet2") and missing = in Selection.Insert Shift:= xlDown
Inserting or deleting rows will change the last row number so start at the bottom and work upwards.
Option Explicit
Sub firstcondition()
Dim ws As Worksheet, LRow As Long, r As Long
Dim n As Long
Set ws = ThisWorkbook.Sheets("Sheet2")
With ws
LRow = .Range("B" & .Rows.Count).End(xlUp).Row
For r = LRow To 2 Step -1
If .Cells(r, "B") <> "" And .Cells(r, "L") = "Leop" Then
.Rows(r + 1).Insert shift:=xlDown
n = n + 1
End If
Next
End With
MsgBox n & " rows inserted", vbInformation
End Sub
Try this with autofilter, you dont have to loop through each row. So it will work faster for larger data.
Option Explicit
Sub firstcondition()
Dim ws As Worksheet
Dim LRow As Long, cl As Range
Set ws = ThisWorkbook.Sheets("Sheet2")
LRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range("L1:L" & LRow).AutoFilter 1, "Leop"
For Each cl In ws.Range("_FilterDatabase").SpecialCells(12).Cells
If ws.Range("B" & cl.Row) <> "" Then
cl.Offset(1).EntireRow.Insert Shift:=xlDown
End If
Next
ws.AutoFilterMode = False
End Sub

Excel VBA, Check values from columns between sheets and delete duplicate

I need some help with comparing values from one column to another and delating it.
so far I have this:
Sub DelateDuplicates()
delArray = Sheets("Save").Range("B1:B") ' saved values
toDelate = Sheets("Validation").Range("B2:B").Value ' values to be checked and delated
lastRow = toDelate.Range("B1000").End(xlUp).Row ' last row
Firstrow = toDelate.Range("B2").End(xlDown).Row ' First row
Dim i As Long
For Lrow = lastRow To Firstrow Step -1
With Worksheets("Validation").Cells(Lrow, "A")
For i = 0 To UBound(delArray) ' arrays are indexed from zero
If Not IsError(.Value) Then
If .Value = delArray(i) Then
.EntireRow.Delete
Exit For
End If
End If
Next
End With
Next Lrow
End Sub
And I do have an error.
"1004 "Application-defined or Object-defined error" "
I have spent 2 days trying to figure it out so far no luck.
Any help will be appreciated.
I modified your code little bit. You can define your first rows and last row the want you want, I have kept it simple for the sake of concept
Option Explicit
Sub DelateDuplicates()
Dim Lrow As Long
Dim delarray()
With Worksheets("Save")
delarray = .Range("B1:B" & .Cells(.Rows.Count, "B").End(xlUp).Row).Value
End With
Dim i As Long
Dim lastrow As Long
Dim firstrow As Long
firstrow = 1
With Worksheets("Validation")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
For Lrow = lastrow To firstrow Step -1
For i = 1 To UBound(delarray)
If Not IsError(.Cells(Lrow, "A").Value) Then
If .Cells(Lrow, "A").Value = delarray(i, 1) Then
.Cells(Lrow, "A").EntireRow.Delete
Exit For
End If
End If
Next i
Next Lrow
End With
End Sub
You can avoid loops within loops by using a Dictionary Object
Option Explicit
Sub DeleteDuplicates()
Dim wsSave As Worksheet, wsValid As Worksheet
Dim iLastRow As Long, iFirstRow As Long, i As Long, n As Long
Dim dict As Object, key, cell As Range
With ThisWorkbook
Set wsSave = .Sheets("Save")
Set wsValid = Sheets("Validation")
End With
Set dict = CreateObject("Scripting.Dictionary")
' get values to delete from Column B
For Each cell In wsSave.Range("B1", wsSave.Cells(Rows.Count, "B").End(xlUp))
key = Trim(cell)
If Len(key) > 0 Then
dict(key) = cell.Row
End If
Next
' scan Validation sheet and delete matching from Save
With wsValid
iFirstRow = .Cells(2, "B").End(xlDown).Row
iLastRow = .Cells(Rows.Count, "B").End(xlUp).Row
For i = iLastRow To iFirstRow Step -1
key = .Cells(i, "A")
If dict.exists(key) Then
.Rows(i).Delete
n = n + 1
End If
Next
End With
' resutl
MsgBox n & " rows deleted between row " & _
iFirstRow & " and " & iLastRow, vbInformation
End Sub

Delete blank cells in a column

The following code converts a table of values to a single column.
The problem is, with my table the number of rows in each column decreases by one for each successive column. Similar to the table shown below.
I am VERY new to writing code and only know the very basics. I copied a script found online to convert a range of values to a single column. The portion of code that I wrote to delete any blank cells is slowing the code tremendously. To convert around 250,000 points to a column is taking roughly 9 hours. I am hoping to reduce the processing time as this is a script I expect to use regularly.
Sub CombineColumns()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim rng As Range
Dim iCol As Long
Dim lastCell As Long
Dim K As Long
K = 484
'set K equal to the number of data points that created the range
Set rng = ActiveCell.CurrentRegion
lastCell = rng.Columns(1).Rows.count + 1
For iCol = 2 To rng.Columns.count
Range(Cells(1, iCol), Cells(rng.Columns(iCol).Rows.count, iCol)).Cut
ActiveSheet.Paste Destination:=Cells(lastCell, 1)
lastCell = lastCell + rng.Columns(iCol).Rows.count
Next iCol
Dim z As Long
Dim m As Long
z = K ^ 2
For Row = z To 1 Step -1
If Cells(Row, 1) = 0 Then
Range("A" & Row).Delete Shift:=xlUp
Application.StatusBar = "Progress: " & Row & " of z: " & Format((z - Row) / z, "Percent")
DoEvents
End If
Next
Application.StatusBar = False
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Sample Table Structure
Because I gave errant information on where this should be posted.
The following code will do what you want nearly instantly.
I used arrays to limit the number of interactions with the worksheet.
Sub foo5()
Dim ws As Worksheet
Dim rng() As Variant
Dim oarr() As Variant
Dim i&, j&, k&
Set ws = ThisWorkbook.Worksheets("Sheet19") 'Change to your sheet
With ws
rng = .Range("A1", .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, .Cells(1, .Columns.Count).End(xlToLeft))).Value
ReDim oarr(1 To Application.WorksheetFunction.CountA(rng), 1 To 1)
k = 1
For i = LBound(rng, 1) To UBound(rng, 1)
For j = LBound(rng, 2) To UBound(rng, 2)
If rng(i, j) <> "" Then
oarr(k, 1) = rng(i, j)
k = k + 1
End If
Next j
Next i
.Range("A1", .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, .Cells(1, .Columns.Count).End(xlToLeft))).Clear
.Range("A1").Resize(UBound(oarr), 1).Value = oarr
End With
End Sub

I need to insert rows according to the condition

I need to insert rows according to the condition that the cell in DQ column is non-blank then I have to insert a new row, and also paste the row data in the new row data.
The problem is that I am not able to insert a row above the matched column and also I don't know how to copy the text.
Following is the code that I have:
Sub Macro()
nr = Cells(Rows.Count, 5).End(xlDown).Row
For r = 4 To nr Step 1
If Not IsEmpty(Cells(r, 121).Value) Then
Rows(r + 1).Insert Shift:=xlDown
Rows(r + 1).Interior.ColorIndex = 16
End If
Next
End Sub
For this you will have to use a reverse loop. I quickly wrote this code and it is not tested. Let me know if you get any error.
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, r As Long
'~~> Change this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Get the last row which has data in Col DQ
lRow = .Cells(.Rows.Count, 121).End(xlDown).Row
'~~> Reverse Loop
For r = lRow To 4 Step -1
If Not IsEmpty(.Cells(r, 121).Value) Then
.Rows(r + 1).Insert Shift:=xlDown
.Rows(r + 1).Interior.ColorIndex = 16
End If
Next
End With
End Sub
I actually found the answer in this forum itself. Pasting the code and the link. Thanks a lot people.
Insert copied row based on cell value
Sub BlankLine()
Dim Col As Variant
Dim BlankRows As Long
Dim LastRow As Long
Dim R As Long
Dim StartRow As Long
Col = "DQ"
StartRow = 3
BlankRows = 1
LastRow = Cells(Rows.Count, Col).End(xlUp).Row
Application.ScreenUpdating = False
With ActiveSheet
For R = LastRow To StartRow + 1 Step -1
If .Cells(R, Col) <> "" Then
.Cells(R, Col).EntireRow.Copy
.Cells(R, Col).EntireRow.Insert Shift:=xlDown
.Cells(R, Col).EntireRow.Interior.ColorIndex = 4
End If
Next R
End With
Application.ScreenUpdating = True
End Sub

Resources