VBA Runtime Error 1004 “Application-defined or Object-defined error” when setting Range in macro - vba

I'm going to preface this by saying that I am very new to VBA and this is my first project with it however, I'm trying quite hard because otherwise it is manual copy paste ~200 times.
Unfortunately, for a first project it has been difficult.
EDITED FOR CLARITY (HOPEFULLY): The main idea is that I need to start at the beginning of a drop down list, copy the first string listed, then paste that string down the column. This changes the numerical data adjacent to the right. I then want to select this newly changed numerical data and copy and paste it to a different sheet in the same workbook in the first blank space in column F. I then want the code to iterate through the drop down list and do this for all 51 strings in the drop down. However it needs to paste offset by 3 columns for each iteration to copy the data to the correct column in the other sheet.
Here is my code thus far
Option Explicit
Sub PtComp()
'
' PtComp Macro
'
'
Dim List1 As String
Dim Range1 As Range
Dim Line1 As Range
Dim i As Integer
Dim Begin As Range
ActiveWorkbook.Sheets("Sample Data Summary").Activate
List1 = Selection
Set Range1 = Evaluate(ActiveSheet.Range(List1).Validation.Formula1)
For Each Line1 In Range1
Selection.Copy
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select
ActiveSheet.Paste
ActiveCell.Offset(0, 1).Select
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
ActiveSheet.Selection.Copy
ActiveWorkbook.Sheets("Pt Comparison").Activate
Begin = ActiveSheet.Range("F1").End(xlDown).Offset(-1, 0)
For i = 0 To 148 Step 3
Begin.Offset(0, i).Select
ActiveSheet.PasteSpecial Paste:=xlPasteValues
Next i
Next Line1
End Sub
It is highlighting this line
Set Range1 = Evaluate(ActiveSheet.Range(List1).Validation.Formula1)
Any help would be greatly appreciated. Sorry if my code is trash, like I said, first timer hoping to get better.
EDIT: Also, I looked back at older questions with the same error and thought that it was maybe because it wasn't clear what worksheet I was trying to define the range in, hence why my code is full of 'ActiveSheet' but still no luck.

Your code assumes List1 contains a valid range address, and thus that the active cell on that "Sample Data Summary" worksheet, contains a valid range address.
Apparently that isn't always the case. Search for more details on the On Error statement for ideas about how you could go about handling that situation.
You need to read up on How to avoid using Select in Excel VBA macros, and know that clipboard operations in a tight loop is pretty much the single slowest thing you can do in Excel-VBA.
Seems you want something like this:
Set Range1 = Evaluate(Selection.Validation.Formula1)
Your code blows up on Range(List1) because List1 does not contain a valid range address.

Related

Copy and paste range to new destination

The function I'm trying to build into my spreadsheet is 'copy selected range and past to new range then every time I run the macro it will carry out the same copy.paste.range to new range but paste destination will follow on from previous pasted values. The function is collection stats on a weekly basis and the macro will automate the date collection.
I had the initial step working but its pasting formulas instead of just the values. I’ve added the paste special function but it’s not working at all now. Once this has been pasted in I’m looking for the next copy and paste to follow on from the data pasted into D21:J27 e.g. D28:J34 (Offset maybe?)
Sub CopyPaste_Weeklys()
Sheets("MI Build").Range("D7:J13").Copy
Sheets("MI Build").Activate
Range("D21:J27").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNoneActiveSheet.Paste
Application.CutCopyMode = False
End Sub
Any help would be much appreciated.
Thanks
Gary
If all you want to do is copy the value in D7:J13 to D21:J27, your entire sub can be replaced by:
Sub CopyPaste_Weeklys()
Sheets("MI Build").Range("D21:J27").Value = Sheets("MI Build").Range("D7:J13").Value
End Sub
In VBA, copy/paste should be reserved for situations where you need to copy things like formulas and formats. For values it is better to just use the Value property of the respective ranges.
Presumably the ranges are not always D7:J13 and D21:J27, but your question provides no information as to how the ranges are to be determined. The fixed ranges above can be replaced by range variables that can be set at run time. Something on the following lines:
Sub CopyPaste_Weeklys()
Dim i As Long
Dim target As Range
With Sheets("MI Build")
i = .Cells(.Rows.Count, "D").End(xlUp).Row + 1
Set target = Range(.Cells(i, "D"), .Cells(i + 6, "J"))
target.Value = .Range("D7:J13").Value
End With
End Sub
The variable i is determined by a standard Excel VBA trick to determine the row number of the last row in a columns which contains data.

Merging from multiple worksheets into one worksheet but its format is not like the original one

I'm new into coding, so please help me.
This code is from kutools.I want to merge all the worksheets into one sheet, but the "combined" sheet should be the last of the worksheets. So I have edited some parts of the code.
when I run, it turns abnormal, it's very different if you put the combined sheets in sheets(1).
it seems the format in original sheets like font, length of column, has varied a lot. The result is like I have done "PASTE VALUE" only. It's very different if I change the destination in sheets(1).
Sorry for bad English, here's one example of my sheet, all sheets have the same format and header.
Here's the result when I combined all data in new sheets, on the last sheet named "RAW" the format has gone.
The format is very important for presenting reports in a proper presentable way to Seniors.
would you please help me for better format?
And here's the code.
Sub merge()
Dim P As Integer
Dim lastws As Worksheet
On Error Resume Next
'Sheets(1).Select
'Worksheets.Add
'Sheets(1).Name = "RAW"
'Set lastsht = After:=Worksheets(Worksheets.Count)
'Worksheets(Worksheets.Count).Select
'Worksheets.Add
'Worksheets(Worksheets.Count).Name = "RAW"
Set lastws = Worksheets.Add(After:=Worksheets(Worksheets.Count))
lastws.Name = "RAW"
'nice udah bisa
Sheets(1).Active
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets("RAW").Range("A1")
For P = 2 To Sheets.Count
Sheets(P).Activate
Range("A5").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets("RAW").Range("A65536").End(xlUp)(2)
Next
Sheets("RAW").Select
MsgBox ("Here is merged data!")
End Sub
Get rid of On Error Resume Next and you'll be able to see errors in your own code, the reason you don't get a heading is because sheets(1).active is not valid code you're just copying the 1st row from raw back over itself at the moment. columns("a:k").autofit will resize the columns in your destination sheet. As for the rest of the formatting, you haven't actually shown it in your first sheet, but a straight .copy destination:=whatever as you have used should preserve cell formatting fine

Copy/Paste variable dataset between workbooks without clipboard

I've been trying to optimize some of my coding and managed to cut and speed it up a lot. However there are some things that are still quite clunky (and me still a noob). Backstory is that my code is opening source and target files, copies a lot of data of variable length, closes source and then does a lot of operations and finally saves target file.
One of the things Id like is to do if possible is a direct copy of data without using clipboard, activating workbooks, selecting sheets (whatever of this is possible to pack into more efficient code that I am currently having)
Windows("SOURCE.xlsm").Activate
Sheets("Data").Select
Range("A2:AX10").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Windows("TARGET.xlsm").Activate
Range("A2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Is it possible to do a selection (A2:AX10 and all the way down to last row) in SOURCE file-Data sheet and directly copy it to TARGET file-Data sheet cell A2 without using clipboard.
The reason why I use A2:AX10 and then selection down is because I have a lot of blank cells in the whole data set and this way I get entire data.
I would like to be able to to that selection and use it as a range in this line
Workbooks(“SOURCE”).Worksheets("Data").Range(“A2:AX10 & ALLTHEWAYDOWN”).Copy _Workbooks(“TARGET”).Worksheets("Data").Range(“A2")
I was trying to solve this but I dont end up with desired result. When I try doing selection and setting as range then both trying copy range with activitng workbooks and in the direct copy mode I get 1004 error.
Is it possible to optimize this chunk and make it work. It would improve a lot of my VBA.
Thanks,
You need something like this:
With Workbooks("SOURCE.xlsm").Sheets("Data")
.Range("A2:AX10", .Range("A2:AX10").End(xlDown)).Copy Workbooks("TARGET.xlsm").ActiveSheet.Range("A2")
End With
You could probably also use CurrentRegion rather than End(xlDown
You can set one range's values (the range where you would want to paste values) equal to a source range's values (the range which you would previously have copied).
Sub paste_values()
Dim wb_A As Workbook, ws_A As Worksheet
Dim wb_B As Workbook, ws_B As Worksheet
Dim last_row As Long
Set wb_A = ThisWorkbook
Set ws_A = wb_A.Sheets(1)
Set wb_B = Workbooks("WorkbookB")
Set ws_B = wb_B.Sheets(1)
With ws_A
last_row = .Range("A" & .Rows.Count).End(xlUp).Row
End With
ws_B.Range("A2:AX" & last_row).Value = ws_A.Range("A2:AX" & last_row).Value
End Sub
This code is setting the new range's values equal to the original range. It prevents the need to activate sheets or workbooks, whilst also copying data to a range without filling the clipboard.
I would also recommend using last_row = .Range("A" & .Rows.Count).End(xlUp).Row to find the last row of your data. Although you do need to ensure you use this on a column which you know contains continuous data.

excel click object stores value from one cell to another

I'm trying to work on something in excel VBA but I can't seem to make it work fine.
Here's how it should work:
I need to copy and paste value of "J21" cell from one sheet to another. BUT, value of J21 keeps on changing every week. So I thought what if I create a code where I'll just press an object (say "STORE!") and it copies the value of "J21" from Sheet1 to "C3" Sheet 2. Then when the value of J21 changes, I just press "STORE!" again and it will copy the value of J21 and paste it on "C4" Sheet 2 without changing the previous value on "C3" Sheet 2.
Here's my latest attempt:
Dim myCell As Range, myRange As Range, i As Long
i = 3
Set myRange = Sheets("Summary").Range("C3")
Set myRange = Range(myRange, myRange.End(xlDown))
Sheets("Sheet1").Select
Range("J21").Copy
Sheets("Summary").Select
Cells(i, 3).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks:=False, Transpose:=False
i = i + 1
myCell and myRange were used for my previous attempts, but it always go on an infinite copy-paste.
Selection and copy-paste in VBA is usually not needed. If you want to modify the value of a cell it is better to just directly use the value property of a range object. You seem to want to establish a reference to the first blank cell below C2 on Sheet2. The problem with your code is that Range(myRange, myRange.End(xlDown)) selects an entire block of cells (above the cell you want) rather than a single cell. While it would be possible to use .End(xlDown) appropriately to get to the cell you want, it is somewhat tricky to get right since it behaves differently depending on whether or not the cell underneath the current cell is blank. A while loop is one way to go. Something like:
Sub store()
Dim target As Range, source As Range
Set source = Sheets("Sheet1").Range("J21")
Set target = Sheets("Sheet2").Range("C3")
Do While Not IsEmpty(target.Value)
Set target = target.Offset(1)
Loop
target.Value = source.Value
End Sub
Chip's suggestion that you learn the basics of VBA is a good one. If you are someone (like me) who learns through books better than with online tutorials, I would recommend almost anything by John Walkenbach -- I first learned to program Excel by reading an early edition of his "Excel VBA Programming for Dummies."

VBA help in selecting entire rows on a dynamic range

Hi thanks everyone in advance.
I have a data set. lets say A3 to Z30. the number of rows and columns varies. also there are blanks in the set. So lets say i want to select the entire section but there's a blank in Z29 and X30 using
Range("A3").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
isn't going to work.
But the values in column A is continuous. So i think the first part will work
Range("A3").Select
Range(Selection, Selection.End(xlDown)).Select
now i know this may seem elementry but how the heck do i select all the rows i just highlighted? this needs to be dynamic because as i said the number of columns and rows vary.
Oh and bonus karma and kudos if you can help me to figure out the next part. I need to select the range and paste it immediately after the the last row but the value in the first cell or A31 in this case would need to change and that is being pulled from a list in sheet2
Use the .EntireRow method.
Here is an example:
Dim report as Worksheet
Set report = Excel.ActiveSheet
report.cells(1,1).EntireRow.Select
If you want to select the cells themselves, you can use the .UsedRange method.
Here is an example:
Dim report As Worksheet
Set report = Excel.ActiveSheet
report.Range(report.Cells(1, 1), report.Cells(1, report.UsedRange.Columns.Count)).Select
EDIT
Here is an example for part II of your question (as requested):
Sub test2()
Dim report As Worksheet
Set report = Excel.ActiveSheet
report.Cells(1, 1).EntireRow.Copy
report.Cells(report.UsedRange.Rows.Count + 1, 1).EntireRow.PasteSpecial xlPasteAll
End Sub
Be sure to note that the .UsedRange method also includes cells that have no values but have been formatted by the user; e.g., if you add bold font (even if you don't add the text itself) to a cell in row 1000, your .UsedRange.Rows.Count will be 1000.
Additionally, you can check my answer in the following link for more guidance. I've been told the notes are very helpful for beginners:
Excel Macro - Paste only non empty cells from one sheet to another (Stack Overflow)
You might want to look at this, and consider what you could do with Range.CurrentRegion, Range.Resize and Range.Offset, so you might get:
Range("A3").CurrentRegion.Copy
Additionally, there's no need to use Range.Select unless you want a user to see what is happening; instead of (for example) a Range.Select followed by a Selection.Copy() (which copies to the clipboard), you could just use a Range.Copy(Range), which copies direct to the target range.
As to the second part, you could:
Dim CopyRow as Long
CopyRow = Range("A3").CurrentRegion.Rows.Count
Range("A3").CurrentRegion.Copy(Range("A3").CurrentRegion.Offset(CopyRow))
Range("A3").Offset(CopyRow) = x ' Insert your reference to the Sheet 2 value here
I am aware that this thread is old, however I was looking for help with something similar. I knew my starting cell for my range, but the number of rows and columns were going to be dynamic. Using the following code worked for me:
Range("A2").Select
Range(Selection, Selection.End(xlDown).End(xlToRight)).Select
Hopefully anyone in the future can make use of this simple solution.