Error 1004 application defined or object defined error - excel

Here the code:
Sub deleterow2()
Dim a As Integer
Dim n As Integer
Dim c As Integer
LastRow = Range("F" & Rows.Count).End(xlUp).Row
For n = 0 To LastRow
a = 1
c = 0
Do Until c = 1
Cells(n + a, 6).Select
If Selection.value = Cells(n, 6) And Selection.value > 30 Then
Selection.EntireRow.Delete
Else
c = 1
End If
a = a + 1
Loop
Next n
End Sub
What s wrong with that?

Please see below corrected code... instead of starting n at 0, start with a at 0. Plus, avoid using .Select everything... and you should try to declare your ranges fully:
Sub deleterow222()
Dim lastRow As Long, R As Long
Dim ws As Worksheet: Set ws = ActiveWorkbook.ActiveSheet
Dim idColumn as Long: idColumn = 6
Dim diffColumn as Long: diffColumn = 19
lastRow = ws.Range("F" & ws.Rows.Count).End(xlUp).Row
For R = lastRow To 2 Step -1
With ws
If .Cells(R, idColumn) = .Cells(R - 1, idColumn) And .Cells(R, diffColumn) > 30 Then
.Cells(R, idColumn).EntireRow.Delete
End If
End With
Next R
End Sub

Some Tips:
You could not use n = 0 because you will create an error. Rows start from 1.
When you loop in order to delete you start from the end.
For n = LastRow To 1 Step -1
If there are a lot of lines and you will use For Loop declare you variable As Long.
If you have a lot of rows it s better to use an Array.
Try to avoid .Select by creating a With Statement with the sheet name
With ThisWorkbook.Worksheets("Sheet1") and refer to cell using .Cells(n + A, 6).Value
Do Until should start also from high to low due to the fact that you go from bottom to top.

enter image description here
Sub deleterow2()
Dim lastRow As Long, R As Long
Dim ws As Worksheet: Set ws = ActiveWorkbook.ActiveSheet
lastRow = ws.Range("F" & ws.Rows.Count).End(xlUp).Row
For R = lastRow To 2 Step -1
With ws
If .Cells(R, 6).value = .Cells(R - 1, 6) And .Cells(R, 19).value > 30 Then
.Cells(R, 6).EntireRow.Delete
End If
End With
Next R
End Sub

Related

sorting with vba

please help i want to sort the name column such that each name starts after every blank cell.
I want it look something like this..pls help it's a pretty long column
Option Explicit
Sub SetNamePosition()
Dim arr As Variant
Dim i As Long: i = 1 ' for Loop
Dim j As Long: j = 1 ' for Array
Dim lastRow As Long: lastRow = Cells(Rows.Count, 1).End(xlUp).Row
Dim rngColB As Range: Set rngColB = Range("B2:B" & lastRow)
Dim rngNames As Range: Set rngNames = Range("C1") ' Temporary range
' Get column B names only
rngColB.SpecialCells(xlCellTypeConstants, 2).Copy
rngNames.PasteSpecial (xlPasteValues)
Application.CutCopyMode = False
Set rngNames = Range(rngNames, rngNames.End(xlDown))
' Load rngNames to array
arr = Application.Transpose(rngNames)
' Clear rng of column B and rngNames
rngColB.Clear
rngNames.Clear
' Insert names
For i = 2 To lastRow
' set name
Cells(i, 1).Offset(0, 1).Value = arr(j)
' find next cell
i = Cells(i, 1).End(xlDown).Row + 1
j = j + 1
Next i
End Sub
I's probably better to remove the empty ranges before making the array, but here's one way to distribute the names:
Loading the range ito an array, then go through the numbers and look for empty ranges.
This assumes that we are working with column "A" and "B" (1 and 2), starting at the top.
Sub test()
Dim arr As Variant
Dim lastRow As Long, i As Long, j As Long
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
arr = Application.Transpose(Range("B2:B" & lastRow))
Range("B2:B" & lastRow).Clear
j = 1
For i = 2 To lastRow
Cells(i, 2) = arr(j)
j = j + 1
If j >= UBound(arr) Then Exit For
While arr(j) = "" And j < UBound(arr)
j = j + 1
Wend
While Not Cells(i, 1).Value = ""
i = i + 1
Wend
Next i
End Sub
Any leftover names will be removed

VBA to seperate and transpose data into rows [duplicate]

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

VBA error with ISTEXT function in IF statement

Just started using VBA and I'm basically looking to check if an item in a column is text and then copy it to another sheet in a row. I get stopped at the first line of the IF statement with
Error 424 - Object Required
Have looked at a few of these questions and websites and can't seem to figure out where I've gone wrong.
Thanks very much.
Sub Copier()
Dim i As Integer
Dim j As Integer
j = 1
For i = 1 To 100
If IsText.Sheets("Strategies").Cells(i, 6) = True Then
Sheets("Strategies").Select
Cells(i, 6).Select
Selection.Copy
Sheets("Stats").Select
Cells(2, j).Select
Sheets("Stats").Paste
j = j + 1
End If
Next i
End Sub
IsText is a method of the WorksheetFunction class.
You have got your syntax wrong, the correction would be:
If WorksheetFunction.IsText(Sheets("Strategies").Cells(i, 6)) = True Then
The IsText() method should not be called with a ., but rather using (), like this:
For i = 1 To 100
s = Sheets("Strategies").Cells(i, 6).Value
If Application.WorksheetFunction.IsText(s)Then
Sheets("Strategies").Select
Cells(i, 6).Select
Selection.Copy
Sheets("Stats").Select
Cells(2, j).Select
Sheets("Stats").Paste
j = j + 1
End If
Next i
Using Variant is so fast.
Sub test()
Dim i As Integer
Dim j As Integer
Dim Wf As WorksheetFunction
Dim fromWs As Worksheet, ToWs As Worksheet
Dim vDB, vR()
Set fromWs = Sheets("Strategies")
Set ToWs = Sheets("Stats")
Set Wf = WorksheetFunction
vDB = fromWs.Range("f1").Resize(100)
For i = 1 To UBound(vDB, 1)
If Wf.IsText(vDB(i, 1)) Then
j = j + 1
ReDim Preserve vR(1 To j)
vR(j) = vDB(i, 1)
End If
Next i
If j > 0 Then
ToWs.Range("a2").Resize(1, j) = vR
End If
End Sub
You could tidy the whole thing up as follows:
Dim i As Integer, j As Integer
Dim sourcesheet As Worksheet, targetsheet As Worksheet
j = 1
Set sourcesheet = Sheets("Strategies")
Set targetsheet = Sheets("Stats")
With sourcesheet
For i = 1 To 100
s = .Cells(i, 6).Value
If Application.WorksheetFunction.IsText(s) Then
.Cells(i, 6).Copy targetsheet.Cells(2, j)
j = j + 1
End If
Next i
End With

Excel macro -Split comma separated entries to new rows [duplicate]

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

Insert row xlUP not working

I found the code below over here: Insert row below based on cell value excel macro
It works but, like the poster in the other message, I want the new row to be inserted below the existing row (here the row with a "2" in it), rather than above. I've tried changing Shift:=xlDown to xlUp but that has no effect. What am I missing something?
Sub BlankLine()
Dim Col As Variant
Dim BlankRows As Long
Dim LastRow As Long
Dim R As Long
Dim StartRow As Long
Col = "C"
StartRow = 1
BlankRows = 1
With ActiveSheet
For R = LastUsedRow() To StartRow + 1 Step -1
If .Cells(R, Col) = "2" Then
.Cells(R, Col).EntireRow.Insert Shift:=xlDown
End If
Next R
End With
End Sub
To insert the row below R use R + 1. Is this what you are trying?
Dim R As Long, LastRow As Long
LastRow = LastUsedRow()
With ActiveSheet
For R = LastRow To 2 Step -1
If .Range("C" & R).Value = 2 Then _
.Range("C" & R + 1).EntireRow.Insert Shift:=xlDown
Next R
End With

Resources