Run-Time Error '1004': Application Defined or Object-Defined Error - excel

I am trying to copy and paste data from one sheet to the next from a selected range entered by the user. TxtDateStart takes the start date, and TxtDateEnd takes the end date. Then it would copy and paste the data from the range of dates to a new sheet.
When I run the code in a form, it works but I rather have the form call the module. This is where I get the run-time error. I'm no expert in VBA, help would be appreciated.
The sheet where the data is is called Unit2Data, and the sheet i want to paste the data is Graphing Sheet.
The error occurs in this line
Sheets("Unit2Data").Range(Cells(i, 1), Cells(i, 73)).Select
Sub Unit2Data()
Dim lrow As Long, i As Long, x As Date, y As Date, erow As Long
x = TxtDateStart
y = TxtDateEnd
'Find the Last Row of Sheet1
lrow = Sheets("Unit2Data").Range("A" & Rows.Count).End(xlUp).Row
'start counting from row 3 to last row
For i = 4 To lrow
' Date value converted as numeric value by multiplying with number 1
If Cells(i, 1) * 1 >= x * 1 Then
If Cells(i, 1) * 1 <= y * 1 Then
'If above conditions matched then select the matched range/ entire column
Sheets("Unit2Data").Range(Cells(i, 1), Cells(i, 73)).Select
'copy the selected row
Selection.Copy
'to make sheet2 active where we want to paste the selected row
Sheets("Graphing Sheet").Activate
'to find the empty row from where the copied row of sheet1 to be pasted in sheet2
erow = Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'to activate or select the empty row of sheet2
ActiveSheet.Cells(erow, 1).Select
'paste the copied data
ActiveSheet.Paste
'to deselect the copy and selected mode
Application.CutCopyMode = False
'for above the if we need 3 end if to close if conditions
End If
End If
'to activate sheet1 for searching the matched data
Sheets("Unit2Data").Activate
'continue for look until above matched found
Next i
End Sub
Date Data
01/01/2019 2
02/02/2019 3

First you should avoid using Select in VBA. There, almost always, are better ways to achieve whatever you are using Select for.
In your case, and regarding only the specific error/question raised, delete the error-causing line and the next line (Selection.Copy) and replace with this:
With Sheets("Unit2Data")
.Range(.Cells(i, 1), .Cells(i, 73)).Copy
End With
Rewriting your entire code to avoid using Select:
Sub Unit2Data()
Dim lrow As Long, i As Long, x As Date, y As Date, erow As Long
x = TxtDateStart
y = TxtDateEnd
With Sheets("Unit2Data")
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 4 To lrow
If .Cells(i, 1) * 1 >= x * 1 Then
If .Cells(i, 1) * 1 <= y * 1 Then
With Sheets("Graphing Sheet")
erow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
End With
.Range(.Cells(i, 1), .Cells(i, 73)).Copy _
Destination:= Sheets("Graphing Sheet").Cells(erow, 1)
End If
End If
Next i
End With
End Sub

Related

How to set zero in the cells if the cells are empty using VBA

I have an excel file with 3 sheets inside:
Starting Date and Ending Date in Sheet1 (1st screenshot)
A database in Sheet2 (2nd screenshot)
Filtered data in Sheet3 based on the date in Sheet1 (3rd screenshot)
I have a script that copy the data from Sheet2 to Sheet3 based on the date in Sheet1. I want the script to be able to put a zero in the empty space if it is detected instead of leaving it as blank.
For example, in the 2nd screenshot above, there is no value in Row 8 for Group 4 and Group 6, so I want the script to be able to put a zero in Group 4 and Group 6 for Row 8 when the data is copied to Sheet3.
I managed to achieve this but some how there will be zero in Row 9 as well (shown in the 3rd screenshot). There should be no zero in Row 9 since the date in Sheet1 is only from December-20 to February-21 (3 months). May I know how should I modified my script so that I'm able to eliminate the zero in Row 9? Any help will be greatly appreciated!
This is my script:
Sub extractdata()
Dim LastRow As Long, erow As Long, i As Long, j As Long, LastRow2 As Long
Dim mydate As Date
LastRow2 = Sheet3.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
Sheet3.Range("B6:H" & LastRow2).ClearContents
LastRow = Sheet2.Cells(Rows.Count, 2).End(xlUp).Row
For i = 6 To LastRow
mydate = Sheet2.Cells(i, 2)
If mydate >= Sheet1.Cells(7, 19) And mydate <= Sheet1.Cells(8, 19) Then
erow = Sheet3.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
Sheet2.Range(Sheet2.Cells(i, 2), Sheet2.Cells(i, 57)).Copy Destination:=Sheet3.Cells(erow, 2)
End If
For j = 3 To 8
If IsEmpty(Sheet3.Cells(i, j).Value) = True Then
Sheet3.Cells(i, j) = 0
End If
Next j
Next i
End Sub
Edit
Sub extractdata()
Dim LastRow As Long, erow As Long, i As Long, j As Long, LastRow2 As Long
Dim mydate As Date
LastRow2 = Sheet3.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
Sheet3.Range("B6:H" & LastRow2).ClearContents
LastRow = Sheet2.Cells(Rows.Count, 2).End(xlUp).Row
For i = 6 To LastRow
mydate = Sheet2.Cells(i, 2)
If mydate >= Sheet1.Cells(7, 19) And mydate <= Sheet1.Cells(8, 19) Then
erow = Sheet3.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
Sheet2.Range(Sheet2.Cells(i, 2), Sheet2.Cells(i, 57)).Copy Destination:=Sheet3.Cells(erow, 2)
End If
Next i
ZeroIsteadBlank
End Sub
I call the function after For loop, but this is what I get:
Row 9 still exist with bunch of zero with additional date in Cell B9
Please, use this code at the end. Iterating during the copying code is waste of time and Excel resources:
Sub ZeroIsnteadBlank()
Dim sh As Worksheet, rngEmpty As Range, LastRow2 As Long
Set sh = Sheet3
LastRow2 = sh.Cells(Rows.Count, 2).End(xlUp).Row + 1 '+ 1 for an extra row...
On Error Resume Next 'Otherwise, the following line will return an error in case of no empty cells...
Set rngEmpty = sh.Range("C6:H" & LastRow2).SpecialCells(xlCellTypeBlanks)
If Not rngEmpty Is Nothing Then
rngEmpty.value = 0
Else
MsgBox "No empty cells..."
End If
On Error GoTo 0
End Sub
In order to avoid the case of an empty cell of the column C:C (C8 in your example), it should be good to calculate LastRow2 for two columns and choose the bigger one...

If cell A1 is greater than B1, cut and paste row to first empty row

If cell in column I1-I14 is greater than cell in column J1-J14, I want to cut the entire row and paste values to the first empty row. (From row 16 and down.)
If cell i is greater than cell j, cut row and paste values to first empty row (row 16 in this example)
This code just pastes in the first row:
Sub Knapp6_Klicka()
Dim i As Long
Dim j As Long
j = 1
For i = 3 To 500
If Cells(i, 9).Value > Cells(i, 10).Value Then
Cells(i, 12).EntireRow.Cut Sheets("Blad1").Range("A" & j)
j = j + 1
End If
Next i
End Sub
I tried to combine the paste with two different solutions.
One like this, where I recorded a macro and went to the last cell, then up to the first empty cell:
Range("A1048576").Select
Selection.End(xlUp).Select
ActiveCell.Offset(1, 0).Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
And one solution that I found on an Excel community:
Sub compareresult()
Dim row1 As Integer
Dim row2 As Integer
row2 = 1
For row1 = 8 To 500
If sheet1.Cells(row1, 11).value > sheet1.Cells(row1, 9).value Then
sheet1.Cells(row1, 1).EntireRow.Copy Sheets(11).Cells(row2, 1)
row2 = row2 + 1
End If
Next row1
End Sub
If cell in column I1-I14 is greater than cell in column J1-J14, i want to cut entire row and paste values to the first empty row. (From row 16 and down)
Here is a method which doesn't cut and paste in a loop. Since you are not deleting the row or "cutting and inserting" the row, here is a simple approach. The below code follows a basic logic
Logic
Loop and identify the range.
If found, then copy the range in 1 go.
Finally clear the range which was copied (if copied).
Code
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rngToCopy As Range
Dim i As Long
'~~> Change this to relevant sheet
Set ws = Sheet1
With ws
'~~> Loop and identify the range
For i = 2 To 14
If .Range("I" & i).Value2 > .Range("J" & i).Value2 Then
If rngToCopy Is Nothing Then
Set rngToCopy = .Rows(i)
Else
Set rngToCopy = Union(rngToCopy, .Rows(i))
End If
End If
Next i
'~~> If found then copy and clear
If Not rngToCopy Is Nothing Then
rngToCopy.Copy .Rows(16)
rngToCopy.Clear
End If
End With
End Sub
EDIT:
To incorporate new edits
Works perfectly! Thanks! :) I failed to fully describe my problem.. What i also need is to paste it as special (only paste the value and not the formulas). Do you got any quick solution for that? – Johl 5 hours ago
Replace
rngToCopy.Copy .Rows(16)
to
rngToCopy.Copy
DoEvents
.Rows(16).PasteSpecial Paste:=xlPasteValues
Have a try with this.
It's based on the range you gave. Skipped over row 1 since you have headers in it.
Dim i As Long, lRow As Long, ws As Worksheet
Set ws = Sheets("Blad1") 'Your sheet name
lRow = ws.Range("I" & Rows.Count).End(xlUp).Row + 1 'Finding the last row
If lRow < 16 Then lRow = 16 'The starting row you want to cut to
For i = 2 To 14 'Your range of rows to check
If ws.Range("I" & i) > ws.Range("J" & i) Then
ws.Range("I" & i).EntireRow.Cut ws.Range("A" & lRow) 'Cutting the whole row so you use column A to cut to
lRow = lRow + 1 'Move down 1 row for where to cut to
End If
Next i
Edit:
Because you only want the values to copy accross we can't use Cut and PasteSpecial xlValues so instead we will duplicate the value of the entire row to the new location, then clear the row (filling in for the cutting part). If clear is too much we can just ClearContents to remove the values in the cells instead of the formatting if that happens. Make sure to always save before running VBA code for the first time.
Dim i As Long, lRow As Long, ws As Worksheet
Set ws = Sheets("Blad1") 'Your sheet name
lRow = ws.Range("I" & Rows.Count).End(xlUp).Row + 1 'Finding the last row
If lRow < 16 Then lRow = 16 'The starting row you want to cut to
For i = 2 To 14 'Your range of rows to check
If ws.Range("I" & i) > ws.Range("J" & i) Then
ws.Range("A" & lRow).EntireRow.Value = ws.Range("I" & i).EntireRow.Value 'Copying the values over
ws.Range("I" & i).EntireRow.Clear 'Clear the row
lRow = lRow + 1 'Move down 1 row for where to cut to
End If
Next i
Your code is doomed to failure because you do not take into consideration that you are cutting the found row. Think about what that means. Your row with the In,Out is row 15 and you wish to paste to row 16. If you cut row 5 (for example) then rows 15 and 16 will become rows 14 and 15. It also means that your next row (which you think will be row 6) will actually be what was row 7 before the cut.

Cut a table halfway in Excel

My sheet contains of cars that are placed at a certain location and need to be checked. This list is made twice a day and sometimes contains of 10 rows, sometimes 14, sometimes 12 etc. Now I would like to cut half of the rows and place it next to the other rows (in this case paste it in cell E). I would like to automate this process so in the VBA should be:
Count number of rows (X)
Cut the rows from X/2 to X
Paste the data in cell E1
I found this function which returns the middle cell. However, I would like to put this together in a sub.
Function Middle(r As Range) As Variant
Dim i As Long, j As Long
If r.Columns.Count > 1 Then
Middle = [#N/A]
Exit Function
End If
i = r.Row
j = r.Rows.Count
Middle = Cells(i + (j - 1) / 2, r.Column).Address
End Function
Sub cutting()
Range("Middle:C" & Range("A" & Rows.Count).End(xlUp).Row).Select
Selection.Cut
Range("E2").Select
ActiveSheet.Paste
Range("A1:C1").Select
Selection.Copy
Range("E1").Select
ActiveSheet.Paste
Cells.Select
Cells.EntireColumn.AutoFit
Range("E8").Select
End Sub
Before
After
You don't need to select the data to work with it.
Try:
Sub Test()
Dim lLastRow As Long
Dim lCutRow As Long
With ThisWorkbook.Worksheets("Sheet1") 'Change Sheet1 to the name of your sheet.
lLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'Find last row in column A.
If lLastRow > 1 Then
lCutRow = (lLastRow / 2) + 1
.Range(.Cells(lCutRow, 1), .Cells(lLastRow, 3)).Cut Destination:=.Cells(1, 5) 'Paste to row 1, column 5 (E1).
End If
End With
End Sub

Attempting copy paste cells from one sheet to another?

I am attempting to copy column B from sheet called "Activity Overview" (Only filled cells) and paste in a sheet called "V&VFile" in column E from row 11 onwards, however when i run the macro the cells arent copied and seems to paste blank cells.
The source of the data uses excel formula index match, is this why as it can copy the data as its found from an excel formula?
Sub VVfileFILL()
Dim Lastrow As Double
Lastrow = Worksheets("Activity Overview").Cells(Rows.Count, "B").End(xlUp).Row
ThisWorkbook.Worksheets("Activity Overview").Range("B" & Lastrow).Copy
ThisWorkbook.Sheets("V&V").Range("E" & Rows.Count).End(xlUp).Offset(10, 0).PasteSpecial xlPasteValues
End Sub
Don't think one can avoid a loop in this situation.
Sub VVfileFILL()
Dim Lastrow As Long, r As Long, n As Long
n = Worksheets("V&V").Range("E" & Rows.Count).End(xlUp).Offset(10, 0).Row
With Worksheets("Activity Overview")
Lastrow = .Cells(Rows.Count, "B").End(xlUp).Row
For r = 2 To Lastrow
If Len(.Cells(r, "B")) > 0 Then 'check not blank
If WorksheetFunction.CountIf(Worksheets("V&V").Range("E1:E" & n), .Cells(r, "B")) = 0 Then 'check not already in E
Worksheets("V&V").Cells(n, "E").Value = .Cells(r, "B").Value 'transfer value
n = n + 1 'add 1 to destination row
End If
End If
Next r
End With
End Sub

VBA- Copying Values from one cell to another offset cell

I am trying to go through row 6 and from column 1 to 26 and search for the sentence Earned Cumulative Hours. Once that is done then I am trying to go from row 8 to the last row(30 in this case) for the column that has Earned Cumulative Hours in row 6.
Then I am trying to paste the values of the cells from this column to 2 cells left in the same row. But I keep getting errors and the code doesn't work.
Can someone please point me in the right direction ? Thanks
Sub project()
Dim lastrow As Long
Dim i As Long
Dim j As Long
lastrow = Sheets("Progress").Cells(Rows.Count, 26).End(xlUp).Row
For j = 1 To 26
If Cells(6, j) = "Earned Cumulative Hours" Then
For i = 8 To lastrow
Cells(i, j).Copy
Cells(i, j).Offset(0, -2).Select
Selection.PasteSpeical Paste:=xlPasteValues
Next i
End If
Next j
End Sub
There are a few problems I can see straight away with your code. Firstly if you are offsetting back two columns .Cells(i, j).Offset(0, -2) then you will be overwriting existing values. If this is what you intend to do then weird but ok.
The next issue is that you have a problem if 'Earned Cumulative Hours' is in Column A. If this is your case Excel will be most unhappy trying to offset two columns to the left and will give an error.
In this case instead of copying and pasting it will be more efficient to set values in one column to the other which you can see in my code. Finally, your Cell references will be valid for the active sheet only. You need to qualify what worksheet you interest in as shown in my code. I normally put this at the start of the code if it is a self contained block.
You could also eliminate the i loop and set ranges of values at a time but we'll save that for next time!
I haven't test this code but it should be fine.
Sub projectawesome()
Dim lastrow as Long, i as Long, j as Long
'Qualify the sheet (assuming its in the activeworkbook)
With Sheets("Progress")
lastrow = .Cells(.Rows.Count, 26).End(xlUp).Row
'I've changed this to column three to prevent offset errors.
For j = 3 to 26
If .Cells(6, j) = "Earned Cumulative Hours" Then
For i = 8 to lastrow
'Assuming overwriting data is ok.
'No need to copy and paste
.Cells(i, j - 2).Value = .Cells(i, j).Value
Next i
End If
Next
End With
End Sub
Try this and we can get rid of those selects
Sub project()
Dim lastrow As Long
Dim i As Long
Dim j As Long
lastrow = Sheets("Progress").Cells(Rows.Count, 26).End(xlUp).Row
For j = 1 To 26
If Cells(6, j) = "Earned Cumulative Hours" Then
For i = 8 To lastrow
Cells(i, j).Copy
With Cells(i, j)
.Offset(0, -2).PasteSpecial xlPasteValues
End With
Next i ' next row
End If
Next j ' next col
End Sub

Resources