Trying to paste underneath all the data on a different workbook but am getting application defined error
Edit:
Sub Matt_Liam()
Dim Rng As Range
Set Rng = Workbooks("orders (3).xlsx").Worksheets("Sheet3").Range("A1:AY300")
Rng.Copy
Dim i As Long
Dim s11 As Workbook
Set s11 = Workbooks("11 Production")
Set s11 = ActiveWorkbook
With Sheets("Sheet1")
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastRow = 1
End If
End With
Rng.PasteSpecial
End Sub
The errors are here
Range(Selection, Selection.End(xlDown)).Select
And Here
Workbooks("11 Production.xlsx").Worksheets("Sheet1").Range("A" & i).Select
Related
I want to loop or find multiple value in another sheets. My code doesn't work even after I do..loop the code.
For i = 1 To lastrowBAU
Worksheets(fname).Range("A1:A" & lastrowsheet).Select
Do Until Cell Is Nothing
Set Cell = Selection.find(What:=ThisWorkbook.Worksheets("BAU").Range("A" & i).Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
MatchCase:=False)
If Not Cell Is Nothing Then
Cell.Activate
ActiveCell.Copy
ActiveCell.Insert Shift:=xlShiftDown
ActiveCell.Offset(1, 0).Select
Selection.Replace What:=ThisWorkbook.Worksheets("BAU").Range("A" & i).Value, _
replacement:=ThisWorkbook.Worksheets("BAU").Range("B" & i).Value, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False
Set Cell = Worksheets(fname).Range("A1:A" & lastrowsheet).FindNext(Cell)
End If
Loop
Next i
You need to set the cell before entering the loop
Set cell = rngSrc.Find(sA, LookIn:=xlFormulas, LookAt:=xlPart, _
After:=rngSrc.Cells(rngSrc.Cells.Count), SearchOrder:=xlByRows, MatchCase:=False)
If Not cell Is Nothing Then
however you also need to avoid an endless loop by checking if the search has returned to the first one found.
Option Explicit
Sub macro1()
Dim ws As Worksheet, wsBAU As Worksheet
Dim cell As Range, rngSrc As Range
Dim fname As String, lastrow As Long, lastrowBAU As Long
Dim i As Long, n As Long, first As String
Dim sA As String, sB As String
fname = "Sheet1"
With ThisWorkbook
Set ws = .Sheets(fname)
Set wsBAU = .Sheets("BAU")
End With
With ws
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rngSrc = .Range("A1:A" & lastrow)
End With
With wsBAU
lastrowBAU = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
With ws
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rngSrc = .Range("A1:A" & lastrow)
End With
' search and replace
Application.ScreenUpdating = False
For i = 1 To lastrowBAU
sA = wsBAU.Cells(i, "A")
sB = wsBAU.Cells(i, "B")
Set cell = rngSrc.Find(sA, LookIn:=xlFormulas, LookAt:=xlPart, _
After:=rngSrc.Cells(rngSrc.Cells.Count), SearchOrder:=xlByRows, MatchCase:=False)
If Not cell Is Nothing Then
first = cell.Address
Do
' insert cell above
cell.Insert xlDown
cell.Offset(-1).Value2 = cell.Value2
cell.Value2 = Replace(cell.Value2, sA, sB)
' expand search range
n = n + 1
Set rngSrc = ws.Range("A1:A" & lastrow + n)
' find next
Set cell = rngSrc.FindNext(cell)
Loop While cell.Address <> first
End If
Next
Application.ScreenUpdating = True
MsgBox n & " replacements", vbInformation
End Sub
The code below is supposed to take the value for net in each month, copies it, search for net name in range1(another worksheet) and pastes value in the cell corresponding to that row and column "AA".
This part of code is having issue:
Set Netrng = Range("AA" & Range1.Find(What:=Net, After:=ActiveCell, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Rows.row)
The error is -
object variable or with block variable not set.
what am I doing wrong?
Sub test()
Dim Range2 As Range
Dim lRow As Long
Dim Count As Long
Dim Net As String
Dim Line As Range
Dim Netrng As Range
Dim First As Range
Dim Range1 As Range
Dim wb As Worksheet
Set First = ActiveCell
Set wb = ActiveSheet
Set Range1 = wb.Range(First, First.End(xlDown))
ActiveWindow.ActivatePrevious
ActiveSheet.PivotTables("PivotTable1").PivotFields("Client Code").CurrentPage _
= "BUN"
ActiveSheet.Range("B5").Activate
lRow = Cells(Rows.Count, 1).End(xlUp).row - 6
Set Range2 = Range(ActiveCell.Offset(2, -1), ActiveCell.Offset(lRow, -1))
Set Months = Range(ActiveCell.Offset(0, 0), ActiveCell.Offset(0, 2))
Count = 1
While Count <= Range2.Count
Set Line = Range2.Rows(Count)
Net = Line.Value
Line.Offset(0, 1).Copy
ActiveWindow.ActivatePrevious
Set Netrng = Range("AA" & Range1.Find(What:=Net, After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).row)
Netrng.Offset(0, 4).PasteSpecial Paste:=xlPasteValues
Netrng.Value = 0
ActiveWindow.ActivatePrevious
Line.Offset(0, 2).Copy
ActiveWindow.ActivatePrevious
Netrng.Offset(0, 8).PasteSpecial Paste:=xlPasteValues
ActiveWindow.ActivatePrevious
Count = Count + 1
Wend
End Sub
As is, the code is assuming that the Find is successful, which may not always be the case.
To test:
Dim foundRng as Range
Set foundRng = Range1.Find(What:=Net, After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not FoundRng is Nothing Then
Set Netrng = Range("AA" & foundRng.Row)
...
End If
Other recommendations:
Avoid using Select and Activate. (and ActiveCell, ActiveWindow, anything Active).
Fully qualify which Workbook and Worksheet each Range is on (helpful reading in the answer on avoiding Select).
While...Wend is old-fashioned. Use a For Each loop.
The code I have, works, but it is slow and I want to avoid using select.
I have tried something in the line of the following:
Sub PopulateBlastEvents()
Dim wsfr As Worksheet
Dim wsl As Worksheet
Dim BlNumber As String
Dim BSStep As Long
Dim SI As String
Dim Srng As Range
Dim Nrng As Range
Dim Arng As Range
Dim NotF As String
Dim Found As Range
Application.ScreenUpdating = False
NotF = "NO INFO"
BSStep = 1
Set Rrng = Sheets("Blast List").Range("A2:A45")
Set Srng = Sheets("Blast List").Range("E1:R1")
For Each cell In Rrng
If cell <> "" Then
For Each cell2 In Srng
If cell2 <> "" Then
On Error Resume Next
SI = cell.Value
BlNumber = CStr("Blasted " & BSStep)
Set wsfr = Sheets(CStr(BlNumber))
Set wsl = Sheets("Blast List")
With wsfr.Range("A:A")
Set Found = Cells.Find(What:=SI, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Found Is Nothing Then
With wsl.Range("A:A")
Set Found1 = Cells.Find(What:=BlNumber, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).End(xlToRight).Offset(0, 1)
Found1.Value = NotF
End With
Else
With wsl.Range("A:A")
Set Found1 = Cells.Find(What:=BlNumber, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).End(xlToRight).Offset(0, 1)
Found1.Value = Found.Value
End With
End If
End With
End If
Next cell2
BSStep = BSStep + 1
End If
Next cell
Set Arng = ThisWorkbook.Worksheets("Blast List").Range("E3:X3").End(xlDown).Select
Application.ScreenUpdating = True
Columns("A:S").EntireColumn.AutoFit
End Sub
The code does run, but returns no value as the range value "rng" remains at NOTHING even though it is in the sheet where it is looking for the value.
Below is the current code I am using that needs to change:
Sub PopulateBlastEvents()
Dim wsfr As Worksheet
Dim wsl As Worksheet
Dim BlNumber As String
Dim BSStep As Long
Dim SI As String
Dim Srng As Range
Dim Nrng As Range
Dim Rrng As Range
Dim Brng As Range
Dim Arng As Range
Dim NotF As String
Application.ScreenUpdating = False
NotF = "NO INFO"
BSStep = 1
Set Rrng = Sheets("Blast List").Range("A2:A45")
Set Srng = ThisWorkbook.Worksheets("Blast List").Range("E1:R1")
For Each Brng In Rrng.Cells
If Brng <> "" Then
For Each Nrng In Srng.Cells
If Nrng <> "" Then
On Error Resume Next
SI = Nrng.Value
BlNumber = CStr("Blasted " & BSStep)
Set wsfr = ThisWorkbook.Worksheets(CStr(BlNumber))
Set wsl = ThisWorkbook.Worksheets("Blast List")
wsfr.Select
Range("A1").Select
Cells.Find(What:=SI, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
Selection.Copy
If Err.Description <> "" Then
Sheets("Blast List").Select
Range("A1").Select
Cells.Find(What:=BlNumber, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).End(xlToRight).Offset(0, 1).Select
Selection.Value = NotF
Else
Sheets("Blast List").Select
Range("A1").Select
Cells.Find(What:=BlNumber, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).End(xlToRight).Offset(0, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
End If
Next Nrng
BSStep = BSStep + 1
End If
Next Brng
Set Arng = ThisWorkbook.Worksheets("Blast List").Range("E3:X3").End(xlDown).Select
Application.ScreenUpdating = True
Columns("A:X").EntireColumn.AutoFit
End Sub
I really want to speed up the code and all previous questions I have posted, I was informed not to or avoid using Select.
Please could someone help.
I found and modified a code that works pretty well but I am struggling with Set CopyRng = sh.Range("A11:AI15") . What I want to do is to create a dynamic range that will copy values from first table from each worksheet between header called Language and last row in table called Total. Some cells are merged in the table (default template) and there are empty columns in the table (so .CurrentRegion doesn't work).
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
Sub CopyRangeFromMultiWorksheets()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set DestSh = ActiveWorkbook.Worksheets("test")
' Loop through all worksheets and copy the data to the
' summary worksheet.
For Each sh In ActiveWorkbook.Worksheets
If sh.Name Like "test*" Then
Last = LastRow(DestSh)
' Specify the range to place the data.
Set CopyRng = sh.Range("A11:AI15")
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial
Application.CutCopyMode = False
End With
DestSh.Cells(Last + 1, "A").Resize(CopyRng.Rows.Count).Value = sh.Range("F8")
DestSh.Cells(Last + 1, "AK").Resize(CopyRng.Rows.Count).Formula = "=AG10*3%"
DestSh.Cells(Last + 1, "AL").Resize(CopyRng.Rows.Count).Formula = "=AG10+AK10"
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Regards,
Here is a function that will return you the range. Parameters explained:
oW = The worksheet you want to get the range from
sStartColHeader = Holds the name of the header column you want to start the range from (i.e. in your example this would be "Language")
Function GetRange(ByVal oW As Worksheet, ByVal sStartColHeader As String) As Range
Dim oTotRng As Range: Set oTotRng = oW.Cells.Find("total", oW.Cells(1, 1), xlValues, xlPart, xlByRows, xlNext, False, , False)
Dim oLan As Range
Set oLan = oW.Cells.Find(sStartColHeader, oW.Cells(1, 1), xlValues, xlPart, xlByRows, xlNext, False, , False)
If oLan Is Nothing Then
Set GetRange = Nothing
Else
Set GetRange = Range(oLan.Offset(1, 0), oTotRng.Offset(0, 1))
End If
End Function
How to use this function:
In CopyRangeFromMultiWorksheets function, change Set CopyRng = sh.Range("A11:AI15") to Set CopyRng = GetRange(sh, "Language"). Then have an If condition to check if a range was returned. For example:
Set CopyRng = GetRange(sh, "Language")
If CopyRng Is Nothing Then
' your exception code here as range was not returned
Else
' rest of your code here as a range was returned
End If
NOTE: Presumption is that the actual total amount in the sheet is in the cell to the right of the cell that contains the text Total. So if "H10" has text Total, actual total is held in cell "I10"
I have found a solution that works great. See the code below:
Sub CopyRangeFromMultiWorksheets()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
Dim findrow As Long, findrow2 As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set DestSh = ThisWorkbook.Worksheets("Summary")
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
Last = LastRow(DestSh)
'this method doesn't work with merged cells thhat is why I have to unmerge them first.
sh.Range("B10:B200").UnMerge
findrow = sh.Range("B:B").Find("Language Pair", sh.Range("B1")).Row
findrow2 = sh.Range("B:B").Find("Total", sh.Range("B" & findrow)).Row
Set CopyRng = sh.Range("A" & findrow + 1 & ":AJ" & findrow2 - 1)
CopyRng.Copy
With DestSh.Cells(Last + 1, "B")
.PasteSpecial
Application.CutCopyMode = False
End With
DestSh.Cells(Last + 1, "A").Resize(CopyRng.Rows.Count).Value = sh.Range("F8")
DestSh.Cells(Last + 1, "AK").Resize(CopyRng.Rows.Count).Formula = "=AG10*3%"
DestSh.Cells(Last + 1, "AL").Resize(CopyRng.Rows.Count).Formula = "=AG10+AK10"
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
I need to find out the column that is the last column in a range that is defined with:
Set RngSource = ActiveWorkbook.ActiveSheet.UsedRange
First things first
Never use UsedRange to set your range. I have explained it HERE as to why you shouldn't use UsedRange
Set RngSource = ActiveWorkbook.ActiveSheet.UsedRange
Find the Last Column that has data and the Last Row which has data and then set your range. So your question of finding the last column from the range will not arise. Here is an example
Sub Sample()
Dim ws As Worksheet
Dim rng As Range
Dim lRow As Long, lCol As Long
'~~> Set your worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
'~~> Find Last Row
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
'~~> Find Last Column
lCol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Else
lRow = 1: lCol = 1
End If
'~~> Set your range
Set rng = .Range(.Cells(1, 1), .Cells(lRow, lCol))
Debug.Print rng.Address
End With
End Sub
Use End(xlToRight) with an activecell.