Compile Error: Object Required - Search Copy Paste Macro Excel VBA - excel

I'm trying to make a macro in Excel VBA 2007 that searches through the selected field and if it finds a certain string anywhere in a row, it copies and pastes that row into another sheet.
However, I'm getting a compile error: object required right on the sub level (line 1). My code so far is below.
Sub SearchCopyPaste()
'
' SearchCopyPaste Macro
' Searches for a string. If it finds that string in the line of a document then it copies and pastes it into a new worksheet.
'
' Keyboard Shortcut: Ctrl+Shift+W
'
Dim sourceSheet, destinationSheet As Worksheet
Set sourceSheet = Worksheets(1) 'Define worksheets
Set destinationSheet = Worksheets(2)
Dim selectedRange As Range 'Define source range
Set selectedRange = Selection
Dim numRows, numColumns As Integer 'Determine how many rows and columns are to be searched
Set numRows = Range(selectedRange).Rows.Count
Set numColumns = Range(selectedRange).Columns.Count
Set destinationRowCount = 1 'Counter to see how many lines have been copied already
'Used to not overwrite, can be modified to add header,etc
Dim searchString As String 'String that will be searched. Will eventually be inputted
Set searchString = "bccs" 'Will eventually be put into msgbox
For rowNumber = 1 To numRows
If InStr(1, selectedRange.Cells(i, numColumns), searchString) > 0 Then
selectedRange.Cells(rowNumber, numColumns).Copy Destination:=destinationSheet.Range(Cells(destinationRowCount, numColumns))
destinationRowCount = destinationRowCount + 1
Next rowNumber
End Sub

You are using the Set keyword wrong. In your code above you only need to use it to assign Worksheet and Range objects, not for integers and strings. Remove the Set keyword on those lines.
Also, you're missing an End If in your For loop.

Related

Copying 1 column from multiple sheets into one sheet in the same workbook and them copy/paste a 2nd column from the same final sheet

I am relative novice in VBA and my goal is to automatically copy one column (B) from 3 named sheets (source sheets) and paste them in a new sheet and them repeat the process for column C and so on until a defined column (see image for my goal, in this case I wanted until column D of the source sheets). The structure of all sheets is identical. Columns consist of numeric values.
I have tried to write a code (see below) however I am getting run-time error 1004 for the commented line. Also, not sure if the code will do what I want to. What am I doing wrong and any tips to improve it?
Sub CopyColumns3()
Dim sheetNames As Variant
sheetNames = Array("temp_column", "normalized_column", "derivative_column")
Dim columnLetters As Variant
columnLetters = Array("B", "C", "D")
Dim i As Integer
Dim j As Integer
' Create a new sheet after the last sheet in the workbook
sheets.Add After:=sheets(sheets.Count)
' Set the name of the new sheet
sheets(sheets.Count).Name = "A_final"
For i = 0 To UBound(sheetNames)
For j = 0 To UBound(columnLetters)
sheets(sheetNames(i)).columns(columnLetters(j)).Copy
' Check if there are any empty columns in the Destination sheet
If sheets("A_final").Range("A1").End(xlToRight).Column = 256 Then
' If there are no empty columns, add a new column to the end of the sheet
sheets("A_final").columns(sheets("A_final").columns.Count).EntireColumn.Insert
End If
sheets("A_final").Select
' The next line causes the problem
sheets("A_final").Range("A1").End(xlToRight).Offset(0, 1).PasteSpecial
Next j
Next i
End Sub
enter image description here
Copy Columns
Sub ColumnsToNewSheet()
' Define constants.
Const DST_NAME As String = "A_final"
Const DST_FIRST_COLUMN As String = "A"
Dim sNames(): sNames = Array( _
"temp_column", "normalized_column", "derivative_column")
Dim sColumns(): sColumns = Array("B", "C", "D")
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Add a new sheet, rename it and reference the first Destination column.
Dim dws As Worksheet
Set dws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
dws.Name = DST_NAME
Dim drg As Range: Set drg = dws.Columns(DST_FIRST_COLUMN)
' Copy the Source columns to the Destination columns.
' This does sh1-col1,sh2-col1,sh3-col3... as requested.
' If you need sh1-col1,sh1-col2,sh1-col3... switch the loops.
Dim srg As Range, sName, sColumn
For Each sColumn In sColumns
For Each sName In sNames
Set srg = wb.Sheets(sName).Columns(sColumn)
srg.Copy drg
Set drg = drg.Offset(, 1) ' next Destination column
Next sName
Next sColumn
' Inform.
MsgBox "Columns exported.", vbInformation
End Sub
I do not see why should you have that check for column 256.
However, when it is triggered, you call Range.Insert, which clears the CutCopyMode. Therefore, Range.PasteSpecial fails because there is nothing to paste.
You can move the check before the Range.Copy call, or get rid of it altogether.

Inserting rows at end of excel table macro - Method range of object _global failed

Background: I have a table in excel that data will get added to over time, and to give my coworkers (who, while lovely, do not like tinkering with things in excel in fear of messing something up) an easy option for expanding the table if it fills when I'm not around, I wanted to add a macro button to add more lines to the table and fill in the formatting (some cells have IF functions in & most have conditional formatting). The idea is they can fill up to but not including the last line of the table, then hit the button and it will add 20 or so new lines before the last line of table and copy the formatting of the last line into them.
So far this is my code:
Sub Add_Rows()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim tbl As ListObject
Set tbl = ws.ListObjects("Table1")
x = tbl.Range.Rows.Count
Range(x - 1, x + 19).Insert Shift:=xlShiftDown, CopyOrigin:=xlFormatFromRightOrBelow
End Sub
I am getting a "Run time error '1004'" "Method range of object _global failed" message when I try clicking the button, and it highlights the "insert" line as being the issue. I am new to vba so any advice is welcome. If my code is utter nonsense then an alternative direction would be appreciated.
Also this is the second version, my first looped Rows.Add which worked, but was taking a few seconds so my hope was inserting 20 would be faster than adding 1 20 times!
Try this.
Sub Add_Rows()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim tbl As ListObject
Dim lastRow As Range, newRng As Range
Dim newRows As Integer: newRows = 20
Set tbl = ws.ListObjects("Table1")
' Last row
On Error GoTo resizeOnly ' Listrows = 0
Set lastRow = tbl.ListRows(tbl.ListRows.Count).Range
On Error GoTo 0
' range of new rows
Set newRng = tbl.ListRows(tbl.ListRows.Count).Range.Resize(newRows).Offset(1)
' resize table
tbl.Resize tbl.Range.Resize(tbl.Range.Rows.Count + newRows, tbl.Range.Columns.Count)
' copy last format to new rows
lastRow.Copy
newRng.PasteSpecial xlPasteFormulasAndNumberFormats
Application.CutCopyMode = False
Exit Sub
resizeOnly:
' resize table
tbl.Resize tbl.Range.Resize(tbl.Range.Rows.Count + newRows, tbl.Range.Columns.Count)
End Sub
If you have no data below the table, you can just assign values to the rows immediately after the table. The table will automatically expand to encompass the new rows, as long as at least one cell in each row, has well defined data.
' Insert 3 new rows into the listoject
' We assume the ListObject already contains data
Public Sub Test(Lob As ListObject)
Dim Sht As Worksheet
Dim StartRow As Long, StartCol As Long, NumCols As Long
Dim Lst As Variant
Dim Rng As Range
' Allocate 3 new rows
NumCols = Lob.ListColumns.Count
ReDim Lst(1 to 3, 1 to NumCols)
' Get the first column of and the first row following the list table
StartCol = Lob.Range.Column
StartRow = Lob.Range.row + Lob.Range.Rows.Count
' Create a range big enough to hold the data, immediately under the last row of the table.
Set Sht = Lob.Parent
Set Rng = Sht.Cells(StartRow, StartCol).Resize(UBound(Lst), UBound(Lst, 2))
' Add some data to the new rows
Lst(1, 1) = "Test1"
Lst(2, 1) = "Test2"
Lst(3, 1) = "Test3"
' Copy data to the destination
Rng = Lst
End Sub
If the list object does not contain data, ie Lob.ListRows.Count = 0, then write data after the header otherwise write it after the last rows.
There are some mistakes in your code:
"Range(x , y)" will cause an error, when x and y are integers. If you want to refer to a cell. Try Cells(x, y). Or Range(Cells(x1, y1), Cells(x2, y2)) to refer to more cells.
And Resize() takes two arguments, and returns a range - it does not affect anything on the sheet.
See also how to insert rows if you want:
Excel Range.Insert:
Example from the doc:
With Range("B2:E5")
.Insert xlShiftDown
' Optionally clear formats, which you do not want, if you add to
' a table with well defined data and formats.
.ClearFormats
End With
The number of the rows inserted, will equal the number of rows in the range we call Insert on.

Copying an array of dynamic ranges, starting from searched cell value

I have a large sheet of data:
Updated Data
where i need to copy only a speacific part of this data to another worksheet:
The data i need to copy is always 4 cells wide however can be at any row and column. The first column cell at the top will allways be the same text value and i need to copy then from that found cell, 4 cells across to the right and then down to the cells are empty. All subsequent ranges after the first will use the same columns have several empty cells bother above and below each range needed. The macro will be run using a "button" so doesn't need to be checking the value of the cell all the time. The images are simplified versions of the data but are very accurate. 0 is used to show data surrounding range, HELLO is the data inside the range and INT_EXT_DOOR is my searched for cell value which can be in any column between data sets but will be the same inside each data set. The first range always starts at row 2.
Each range has to be numbered, defined by another worksheets cell value. For example, if my cell value is 1 i need it to copy range 1, if my value is 2 copy range 2 ect.
I have been trying to no luck to get anything that works like needed and would appreciate any help, thanks.
Test the next function, please:
Private Function testReturnBlock(strBlock As String, blkNo As Long)
Dim sh As Worksheet, ws As Worksheet, lastRow As Long, searchC As Range
Dim rng As Range
Set sh = ActiveSheet ' use here your sheet to be processed
Set ws = Worksheets("Return") 'use here your sheet where the data will be returned
Set searchC = sh.UsedRange.Find(strBlock)
If searchC Is Nothing Then MsgBox "No such a field in the worksheet...": Exit Function
lastRow = sh.Cells(Rows.Count, searchC.Column).End(xlUp).row
'The following part works well only if the blocks are separated by empty rows, as you said it is your sheet data case...
Set rng = sh.Range(searchC, sh.Cells(LastRow, searchC.Column)).SpecialCells(xlCellTypeConstants)
ws.Range("A1").Resize(rng.Areas(blkNo).Rows.Count, 4).Value = rng.Areas(blkNo).Resize(, 4).Value
End Function
The above function should be called like this:
Sub testRetBlock()
testReturnBlock "INT_EXT_DOOR", 2
End Sub
But in order to see that the correct range has been returned, you must adapt them in a way (in your test sheet), do differentiate. I mean the second one to contain "HELLO1" (at least on its first row), the following "HELLO2" and so on...
Try this routine if it does what you need. otherwise it should be a good start for adding whatever you need on top.
Option Explicit
Sub CopyBlock()
Dim wb As Excel.Workbook
Dim wsSource As Excel.Worksheet
Dim wsDest As Excel.Worksheet
Dim wsSelect As Excel.Worksheet
Dim lBlockNo As Long
Dim strCellID As String
Dim lBlock As Long
Dim lRow As Long
Dim lBlockRow As Long
Dim lBlockCol As Long
Dim searchRange As Excel.Range
Dim bRange As Excel.Range
Dim cRange As Excel.Range
Set wb = ActiveWorkbook
' set the worksheet objects
Set wsSource = wb.Sheets("Source")
Set wsDest = wb.Sheets("Dest")
Set wsSelect = wb.Sheets("Select") ' here you select which block you want to copy
' Identifier String
strCellID = "INT_EXT_DOOR"
' Which block to show. We assume that the number is in cell A1, but could be anywhere else
lBlockNo = wsSelect.Range("A1")
lRow = 1
' Find block with lBlockNo
For lBlock = 1 To lBlockNo
' Search the identifier string in current row
Do
lRow = lRow + 1
Set searchRange = wsSource.Rows(lRow)
Set bRange = searchRange.Find(strCellID, LookIn:=xlValues)
Loop While (bRange Is Nothing)
Next lBlock
lBlockRow = bRange.Row
lBlockCol = bRange.Column
' Search the first with empty cell
Do
lRow = lRow + 1
Loop While wsSource.Cells(lRow, lBlockCol) <> ""
' Copy the range found into the destination sheet
Range(Cells(lBlockRow, lBlockCol), Cells(lRow - 1, lBlockCol + 3)).Copy wsDest.Range("A1")
' Note the block copied
wsDest.Cells(1, 6) = "Block No:"
wsDest.Cells(1, 8) = lBlockNo
' Clean up (not absolutely necessary, but good practice)
Set searchRange = Nothing
Set bRange = Nothing
Set cRange = Nothing
Set wsSource = Nothing
Set wsDest = Nothing
Set wsSelect = Nothing
Set wb = Nothing
End Sub
Let me know if you need more help

VBA Excel Merging Several Different Structure Sheets Using Common Combined Sheet Headers

I have several sheets with different structure that i need to merge using some of the columns headers that are common
I gathered in the one sheet ("Combine") the common headers and tried to write a macro to find the same column and to its data to the combine sheet, the macro is only getting the first column and not proceeding.
Any guidance with this issue will be appreciated
Dim II%, XX%, ZZ%, I% ' Dim as long
Dim Sht As Worksheet ' Every Sheet on This Workbook
Dim Comb As Worksheet ' Combine Sheet
Set Comb = ThisWorkbook.Worksheets("Combine")
II = 2 ' Start on row 2 - Sheet1 & Sheet2
XX = 2 ' Start on row 2 - Combine sheet
'Looping through the worksheets in the workbook
For Each Sht In ThisWorkbook.Worksheets
' ignore Sheet "Combine" and "Val"
If Sht.Name <> "Combine" And Sht.Name <> "Val" Then
For ZZ = 1 To 100
For I = 1 To 100
If Sheets(Sht.Name).Cells(1, I).Value = Comb.Cells(1, ZZ).Value Then
Do Until IsEmpty(Sht.Columns(1).Cells(II))
Comb.Cells(XX, ZZ).Value = Sheets(Sht.Name).Cells(II, I).Value
II = II + 1
XX = XX + 1
Loop
End If
Next I
I = 1
Next ZZ
End If
II = 2 ' Reset 1st Loop to capture the new sheet data
Next
If I understand your question correctly, you have multiple sheets that have a heading row of some number of columns. You then have data rows below this in corresponding columns.
You’ve looked at the headings in each sheet and added those names that are common to a sheet you’ve called Combine. Not all columns on all sheets are found on the Combine sheet. The Combine sheet is a subset of the total column names in the workbook.
The sheets might contain data from several test runs or whatever. The output might contain common columns as well as some additional data. For example, sheet 1 could contain date, time, location, and result. Sheet 2 could contain date, time, and tester.
You want a combined sheet that shows the common fields, in this case Date, Time, Result, and Tester. You’ve already determined the common headings.
I think your problem might be in Do Until IsEmpty(Sht.Columns(1).Cells(II)). You may be encountering an empty cell.
Also, it is much faster to use Excel's built-in functions to perform moving large blocks of data between sheets.
Given you seem to be learning about VBA and have made a pretty good attempt, I took the liberty to provide you with an example that uses a more advanced way for solving the problem
The code below in effect concatenates the data from each sheet and common column on to the Combine sheet. It leaves blanks where a column does not have a data sheet have data that would be copied into the Combine column. This means that there will be blank cells under the columns Result and Test – based on the source data sheet.
I hope you find this helpful and that it answers your question. I have learned a lot from other's example on this site and am trying to pay it forward.
Option Explicit
Public Sub Tester()
'Not needed
'Dim II%, XX%, ZZ%, I% ' Dim as long
Dim Comb As Worksheet ' Combine Sheet
Set Comb = ThisWorkbook.Worksheets("Combine")
'Declare a range object and assign it to contain column names
'from Combine. This range, converted to a list
'below will compare the combined heading names with
'each column heading on each sheet.
Dim rngCombineHeadings As Range
'set combine headings into the range using the function
'EndOfRangeColumn, which is decribed below
Set rngCombineHeadings = EndOfRangeColumn(Comb.Range("A1"))
'Declare a collection to be used in the for loop to compare
'Combine column headings with each source sheets headings
'Only copy those columns that match
Dim colCombinedHeadings As Collection
'Get a collection (aka list of strings) of the column headings
Set colCombinedHeadings = GetCommonHeadings(rngCombineHeadings)
'Declare two ranges to be used as the index inside
'for loops below.
Dim combineColTargetRng As Range
Dim colRng As Range
'Declare a variant to used use the index for looing
'through the Combine sheet headings
Dim vHeading As Variant
'Declare tblRng. It will be set to contain the entire data table
'on each sheet. Row 1 contains the headings, rows 2 - n contain
'the data that may be moved.
Dim tblRng As Range
'This is the range that will be manipulated and copied
'to the Combine sheet
Dim copyRng As Range
'Looping through the worksheets in the workbook
'Index variable used in for each loop below best practice is
'declare you variables near where they are used.
Dim Sht As Worksheet ' Every Sheet on This Workbook
For Each Sht In ThisWorkbook.Worksheets
' ignore Sheet "Combine" and "Val"
If Sht.Name <> "Combine" And Sht.Name <> "Val" Then
'Set the data table to the tblRng object.
Set tblRng = EndOfRangeRow(Sht.Range("A1"))
Set tblRng = EndOfRangeColumn(tblRng)
'For each sheet, loop through each headings on
'the Combined sheet and compare those to the
'headings on the data table on the current sheet
For Each vHeading In colCombinedHeadings
For Each colRng In tblRng.Columns
'if the heading on Combined = the current
'columns heading then, copy the data
'to the combined sheet.
If vHeading = colRng.Value2(1, 1) Then
'Resize the copy range to exclude the heading row
'and to reduce the size by one row, reflecting removal
'of the header row from the range
Set copyRng = ResizeTheRange(colRng.Offset(1, 0))
'Find the column on the Combine sheet that
'matches the current value in vHeading
Set combineColTargetRng = rngCombineHeadings.Find(colRng.Value2(1, 1))
'Copy the current sheet-current column to the clipboard
copyRng.Copy
'The if statement below determines if this is the first
'column of data being copied to the Combine sheet
'if it is, the row 2 current column is empty
'otherwise it has a value and we need to move the paste point
'to the end of the current Combine sheet column
If combineColTargetRng.Offset(1, 0).Value2 = "" Then
Set combineColTargetRng = combineColTargetRng.Offset(1, 0)
Else
Set combineColTargetRng = EndOfRangeRow(combineColTargetRng)
Set combineColTargetRng = _
combineColTargetRng.Offset( _
combineColTargetRng.Rows.Count, 0)
End If
'Paste the values copied from the current sheet
'that are under the same column heading as on the combined sheet
'There are a number of options for pasteSpecial
'See https://learn.microsoft.com/en-us/office/vba/api/excel.range.pastespecial
combineColTargetRng.PasteSpecial Paste:=xlPasteAll
End If
Next
Next
End If
Next
End Sub
'*****************************************************************************
'**
'** This function demonstrates use of the ParamArray. It enables the
'** calling routine, to provide the range as an Excel Range, a Collection
'** an Array, or a list of strings.
'**
'** Calling the Function:
'** Dim aCol as Collection
'** Set aCol = GetCommonHeadings(aCol)
'** Dim rngExcelRange as Range
'** set rngExcelRange = Range("A1:X1")
'** Set aCol = GetCommonHeadings(rngExcelRange)
'** Dim vArr() as Variant
'** vArr = Array("H1", "H2", "H3", "H4")
'** Set aCol = GetCommonHeadings(vArr)
'** Set aCol = GetCommonHeadings("Title1", "Title2", "Title3", "Title4")
Public Function GetCommonHeadings(ParamArray mRange() As Variant) As Collection
'Instantiate the return collection
Dim retVal As New Collection
Dim nDx As Long
If UBound(mRange) < 0 Then
'Cannot do anything without the heading range
Set retVal = Nothing
ElseIf TypeOf mRange(0) Is Range Then
'Heading Range is an Excel Range
Dim rngMaster As Range
Dim colRng As Range
Set rngMaster = mRange(0)
For Each colRng In rngMaster.Columns
retVal.Add colRng.Value2
Next
ElseIf TypeOf mRange(0) Is Collection Then
'Heading Range is a collection of text strings
Set retVal = mRange(0)
ElseIf VarType(mRange(0)) = vbArray + vbVariant Then
'Heading Range passed is an array of strings
Dim varArr() As Variant
varArr = mRange(0)
For nDx = 0 To UBound(varArr)
retVal.Add varArr(nDx)
Next
ElseIf VarType(mRange(0)) = vbString Then
'mRange contains an array of strings
For nDx = 0 To UBound(mRange)
retVal.Add mRange(nDx)
Next
Else
Set retVal = Nothing
End If
Set GetCommonHeadings = retVal
End Function
'****************************************************************************
'**
'** The Functions EndOfRangeColumn, EndOfRangeRow, StartOfRangeColumn, and
'** StartOfRangeRow take one parameter which is an Excel Range. Based on
'** the funtions name it will return the cell that is at the other end.
'** These are just wrappers to make the code more readable. The real work
'** is done by the Private Function GetRangeAtEnd. The private function
'** takes an Excel Range and the direction you want to move.
Public Function EndOfRangeColumn(ByRef mStartOfRange As Range) As Range
Set EndOfRangeColumn = GetRangeAtEnd(mStartOfRange, xlToRight)
End Function
Public Function EndOfRangeRow(ByRef mStartOfRange As Range) As Range
Set EndOfRangeRow = GetRangeAtEnd(mStartOfRange, xlDown)
End Function
Public Function StartOfRangeColumn(ByRef mEndOfRange As Range) As Range
Set StartOfRangeColumn = GetRangeAtEnd(mStartOfRange, xlToLeft)
End Function
Public Function StartOfRangeRow(ByRef mEndOfRange As Range) As Range
Set StartOfRangeRow = GetRangeAtEnd(mStartOfRange, xlUp)
End Function
Private Function GetRangeAtEnd(ByRef mRange As Range, ByVal mDirection As XlDirection) As Range
Set GetRangeAtEnd = Range(mRange, mRange.End(mDirection))
End Function
'***************************************************************
'**
'** The Private Function ResizeTheRange takes an Excel range
'** provide in the parameter. In effect it removes the first
'** row from the provided range, and reduces the size by one.
Private Function ResizeTheRange(ByRef mRange As Range) As Range
Dim retVal As Range
Set retVal = mRange.Offset(1, 0)
Set retVal = retVal.Resize(retVal.Rows.Count - 1, 1)
Set retVal = EndOfRangeRow(retVal)
Set ResizeTheRange = retVal
End Function

VBA: Unable to reference Range in another sheet

This is my first post, so please provide any feedback about my approach to presenting the problem.
I'm building a sub that (ultimately) is supposed to copy a range from one sheet ("Sandbox") to another ("Master"). The steps are:
Identify the selected rows
Loop through the Sandbox rows, determining whether to find a matching Master row or add as a new end-row in Master
Copy the values only from each selected Sandbox row to the appropriate Master row
The error pops with the setting the range for the PasteSpecial function. That line consistently gives a "1004 (Method 'Range' of object '_Global' failed" message.
Here's the code :
Sub UpdateMaster()
Dim currentSelection As Range
Set currentSelection = Selection
Dim sheetSB As Worksheet
Set sheetSB = ThisWorkbook.Sheets("Sandbox")
Dim sheetMaster As Worksheet
Set sheetMaster = ThisWorkbook.Sheets("Master")
Dim lastTargetRow As Integer
lastTargetRow = sheetMaster.Range("IDRange").End(xlDown).Row + 1
Dim startingTargetColumn As Integer
startingTargetColumn = sheetMaster.Range("IDRange").Column
Dim thisID As String
Dim thisStatus As String
For Each thisrow In currentSelection.Rows
' Capture the current ID value
thisID = Cells(thisrow.Row, Range("IDRange").Column).Value
' Capture the current Status value
thisStatus = Cells(thisrow.Row, Range("NewRange").Column).Value
' If the row has no ID...
If thisID = "" Then
' ...do nothing
' If the row is flagged as new...
ElseIf thisStatus = "New" Then
'...identify the first blank row, and set all data columns to be copied
Range(Cells(thisrow.Row, Range("IDRange").Column), Cells(thisrow.Row, Range("LastSandboxColumn")).Column).Copy _
Destination:=sheetMaster.Range(lastTargetRow, startingTargetColumn)
' Increment the next available last row by 1
lastTargetRow = lastTargetRow + 1
Else
' Otherwise, find the corresponding row and set the non-ID columns to be copied
Dim sourceColumn1 As Integer, sourceColumn2 As Integer
Dim targetRow As Integer, targetColumn As Integer
Dim matchRow As Integer
sourceColumn1 = Range("IDRange").Column + 1
sourceColumn2 = Range("LastSandboxColumn").Column
targetRow = Application.WorksheetFunction.Match(thisID, sheetMaster.Range("IDRange"), 0)
targetColumn = startingTargetColumn + 1
Range(Cells(thisrow.Row, sourceColumn1), Cells(thisrow.Row, sourceColumn2)).Copy
Range(sheetMaster.Cells(targetRow, targetColumn)).PasteSpecial xlPasteValues
End If
Next
End Sub
The error is happening on the last line:
Range(sheetMaster.Cells(targetRow, targetColumn)).PasteSpecial xlPasteValues
Inexplicably, the following seems to work:
Range(Cells(thisrow.Row, sourceColumn1), Cells(thisrow.Row, sourceColumn2)).Copy _
Destination:=Range(sheetMaster.Cells(targetRow, targetColumn))
Unfortunately, I want only the values; bringing over formulas and formatting will screw up other behavior in the sheet.
I have tried many variations, but essentially it will not allow me to create a range, referencing Master, if I use Cells().
Any help much appreciated.
Just do:
sheetMaster.Cells(targetRow, targetColumn).PasteSpecial xlPasteValues
An error could occur with this, if the sheetMaster isn't the ActiveSheet at runtime:
Range(sheetMaster.Cells(targetRow, targetColumn).PasteSpecial) xlPasteValues
Also note, for this problem:
Unfortunately, I want only the values; bringing over formulas and formatting will screw up other behavior in the sheet.
You can get the range's .Value as an array, and write it directly to the other sheet without invoking either Copy or Paste/PasteSpecial methods. The answer below shows several methods of copying/pasting from one workbook to another, but could easily be modified for sheet-to-sheet transfer, instead.
Copy from one workbook and paste into another

Resources