I have information in a whole lot of worksheets in workbook Wb1 and this information is always in range F11:F500 I want to transfer this information into one sheet in workbook wb in column A. See code below. I receive the error
at this line rng2.Paste
Option Explicit
Sub NameRisk()
' Copy and paste
Dim wb1 As Workbook
Dim wb As Workbook
Dim ws As Worksheet
Dim ws1 As Worksheet
Dim rng As Range
Dim c As Range
Dim lastrow As Long
Dim rng2 As Range
Set wb1 = Application.Workbooks("COMBINED ADD.xls")
Set wb = Application.Workbooks("NameRiskXtract.xlsm")
Set ws = wb.Worksheets("Sheet1")
For Each ws1 In wb1.Sheets
Set rng = Range("F11:F500")
For Each c In rng
If c.Value <> "" Then
c.Copy
With ws
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
Set rng2 = ws.Range("A" & lastrow)
rng2.Paste
End With
End If
Next c
Next ws1
End Sub
Range("F11:F500") should have a parent worksheet; I'm guessing it is ws1. You may be cancelling the Copy operation. Better to Copy with a destination.
...
For Each ws1 In wb1.Sheets
Set rng = ws1.Range("F11:F500")
For Each c In rng
If c.Value <> "" Then
c.Copy destination:=ws.Cells(ws.Rows.Count, "A").End(xlUp).offset(1, 0)
End If
Next c
Next ws
...
You are still in your with statement. try:
For Each ws1 In wb1.Sheets
Set rng = Range("F11:F500")
For Each c In rng
If c.Value <> "" Then
c.Copy
With ws
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
Set rng2 = .Range("A" & lastrow) " <--- removed ws
rng2.Paste
End With
End If
Next c
Next ws1
You may also want to avoid copy/paste entirely and use this snippet instead:
For Each ws1 In wb1.Sheets
For Each c In ws1.Range("F11:F500")
If c.Value <> "" Then ws.Range("A" & ws.Cells(.Rows.Count, "A").End(xlUp).Row + 1).value = c.value
Next c
Next ws1
Related
I am trying to create a formula that compares two workbooks.
I get:
Run-time error 9.
Here is the code:
Sub Compare()
Dim wb1 As Workbook
Dim wb2 As Workbook
Set wb1 = Workbooks("Testing1.xlsx")
Set wb2 = Workbooks("Testing2.xlsx")
'Setting variable to represent last row and last column
lRow = Cells(Rows.Count, 1).End(xlUp).Row
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 2 To lRow
For j = 2 To lCol
'Created the IF then Statement to Highlight Cells that show a difference
If wb2.Sheets("Sheet1").Cells(i, j) <> wb1.Sheets("Sheet1").Cells(i, j) Then
wb2.Sheets("Sheet1").Cells(i, j).Interior.ColorIndex = 5
End If
Next j
Next i
End Sub
Compare the Same Cells in Two Different Workbooks
This is just a basic example that may serve you well at this stage.
Option Explicit
Sub CompareBasic()
' Source: compare; just read
Dim swb As Workbook: Set swb = Workbooks("Testing1.xlsx")
Dim sws As Worksheet: Set sws = swb.Worksheets("Sheet1")
' Destination: compare and highlight
Dim dwb As Workbook: Set dwb = Workbooks("Testing2.xlsx")
Dim dws As Worksheet: Set dws = dwb.Worksheets("Sheet1")
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, "A").End(xlUp).Row
Dim dlCol As Long
dlCol = dws.Cells(1, dws.Columns.Count).End(xlToLeft).Column
Application.ScreenUpdating = False
Dim r As Long
Dim c As Long
For r = 2 To dlRow
For c = 2 To dlCol
If dws.Cells(r, c).Value <> sws.Cells(r, c).Value Then
' Using 'Color' is preferred for it to work the same,
' not depending on which color palette is used.
dws.Cells(r, c).Interior.Color = vbYellow
Else
' It may have previously been different (highlighted)
' but now it's the same (not highlighted):
dws.Cells(r, c).Interior.Color = xlNone
End If
Next c
Next r
Application.ScreenUpdating = True
MsgBox "Differences highlighted.", vbInformation
End Sub
I have numbers in the Range G2:G10, I have to check if these numbers are in one of the Cells in the Row B of the second file. Now I just have a true if argument when the same number is in G2(File 1) and B2(File 2). But how can I do this, so that when G2(File 1) and B4(File 2) are the same the if also works?
Dim cell As Range
Dim wb1 As Workbook, ws1 As Worksheet
Dim wb2 As Workbook, ws2 As Worksheet
Set wb1 = Application.Workbooks.Open("T:\folder\Map2.xlsm")
Set ws1 = wb1.Sheets("Tabelle1")
Set wb2 = Application.Workbooks.Open("T:\folder\file.xlsx")
Set ws2 = wb2.Sheets("sheet1")
For Each cell In wb1.Sheets(1).Range("G2:G10")
If cell.Value = ws2.Cells(cell.Row, "B").Value Then
ws2.Cells(cell.Row, "D").Resize(1, 3).Select
End If
Next cell
End Sub
Try this
Sub test()
Dim c As Range, cx As Range, str$
Dim wb1 As Workbook, ws1 As Worksheet
Dim wb2 As Workbook, ws2 As Worksheet
Set wb1 = Application.Workbooks.Open("T:\folder\Map2.xlsm")
Set ws1 = wb1.Sheets("Tabelle1")
Set wb2 = Application.Workbooks.Open("T:\folder\file.xlsx")
Set ws2 = wb2.Sheets("sheet1")
For Each c In ws1.Range(ws1.Cells(1, 7), ws1.Cells(ws1.Rows.Count, 7).End(xlUp))
For Each cx In ws2.Range(ws2.Cells(1, 2), ws2.Cells(ws2.Rows.Count, 2).End(xlUp))
If c = cx Then
cx.Offset(, 2).Resize(1, 3).Select
str = str & ", " & cx.Address
'Msgbox cx.Address
End If
Next cx
Next c
Msgbox "The following cells meet the conditions: " & Replace(str, ",", "", 1, 1)
End Sub
This uses a dictionary and does what I think you are looking for. Though I might have your sheets backwards. I tested using a single workbook and just added in your workbook and sheet values. I am also unsure what you want to do when a value is found so I left that blank.
Sub compare()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim cell As Range
Dim lastrow As Long
Dim dict As Object
Set wb1 = Application.Workbooks.Open("T:\folder\Map2.xlsm")
Set ws1 = wb1.Sheets("Tabelle1")
Set wb2 = Application.Workbooks.Open("T:\folder\file.xlsx")
Set ws2 = wb2.Sheets("sheet1")
Set dict = CreateObject("Scripting.Dictionary") 'This is late bound you can change to early binding if you want
With ws2
lastrow = .Cells(.Rows.Count, 2).End(xlUp).Row
For Each cell In .Range("B1:B" & lastrow)
If Not dict.exists(cell.Value) Then 'Avoid errors
dict.Add cell.Value,cell 'Add key value, item will be the range
End If
Next cell
End With
With ws1
For Each cell In Range("G2:G10")
If dict.exists(cell.Value) Then 'Duplicate found when true
'Here we take the matched range offset and place it in the new offset range
Range(cell.Offset(0, 2), cell.Offset(0, 4)).Value = Range(dict(cell.Value).Offset(0, 2), dict(cell.Value).Offset(0, 4)).Value
End If
Next cell
End With
End Sub
I have data in a table, where I compare two columns J and T. The values which J and T can take include A2B, APL, BGF, CMA, among others (see code).
If these values are equal, copy row i into the sheet which has the name of the cells just checked.
If these values are not equal, copy row i into the sheets which have the name of the cells just checked.
Example: Compare J2 and T2,
Suppose J2=T2=BGF then copy row 2 and paste into sheet("BGF")
Next, compare J3 and T3
Suppose J3=BGF and T3=CMA, copy row 3 and paste into sheet(BGF) and sheet(CMA)
Next, compare J4 and T4
Suppose J4=Nothing and T4=CMA, copy row 4 and paste into sheet CMA
the only other combination is where Ji has a value and Ti is empty.
Problem: When running this code, If J3=BGF and T3= nothing (its empty), then the line is not copied to any sheet.
Here's the code
Sub Sortdata()
'step 1 clear all data
Sheets("A2B").Cells.ClearContents
Sheets("APL").Cells.ClearContents
Sheets("BGF").Cells.ClearContents
Sheets("CMA").Cells.ClearContents
Sheets("K Line").Cells.ClearContents
Sheets("MacAndrews").Cells.ClearContents
Sheets("Maersk").Cells.ClearContents
Sheets("OOCL").Cells.ClearContents
Sheets("OPDR").Cells.ClearContents
Sheets("Samskip").Cells.ClearContents
Sheets("Unifeeder").Cells.ClearContents
Dim i As Long
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim LastRow As Long
With Worksheets("All Data")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 2 To LastRow
If IsEmpty(.Range("J" & i)) Then
Set ws1 = Nothing
Else
Set ws1 = Worksheets(.Range("J" & i).Value)
End If
If IsEmpty(.Range("T" & i)) Then
Set ws2 = Nothing
Else
Set ws2 = Worksheets(.Range("T" & i).Value)
End If
If ws1 Is Nothing Then
If Not ws2 Is Nothing Then
CopyToWs ws2, .Rows(i)
End If
ElseIf ws2 Is Nothing Then
If Not ws1 Is Nothing Then
CopyToWs ws1, .Rows(i)
End If
Else
CopyToWs ws1, Rows(i)
If ws1.Name <> ws2.Name Then
CopyToWs ws2, .Rows(i)
End If
End If
Next
End With
End Sub
Sub CopyToWs(ws As Worksheet, rng As Range)
rng.Copy
ws.Cells(ws.Rows.Count, 1).End(xlUp).Offset(1, 0).EntireRow.PasteSpecial xlPasteValuesAndNumberFormats
End Sub
Please try this code. It takes a slightly different approach to what you tried but it gets the job done, I think.
Option Explicit
Sub Sortdata()
' Variatus #STO 20 Jan 2020
Const WsNames As String = "A2B,APL,BGF,CMA,K Line,MacAndrews," & _
"Maersk,OOCL,OPDR,Samskip,Unifeeder"
Dim WsS As Worksheet ' Source
Dim Ws As Worksheet
Dim Rng As Range
Dim Rt As Long ' target row
Dim LastRow As Long
Dim J As Long, T As Long
Dim Tmp As Variant, PrevTmp As Variant
Dim R As Long, C As Long
'step 1 clear all data
Tmp = Split(WsNames, ",")
For R = LBound(Tmp) To UBound(Tmp)
On Error Resume Next
Worksheets(Tmp(R)).Cells.ClearContents
Next R
Application.ScreenUpdating = False
Set WsS = Worksheets("All Data")
With WsS
J = .Columns("J").Column
T = .Columns("T").Column
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
For R = 2 To LastRow
PrevTmp = ""
For C = J To T Step T - J
Tmp = .Cells(R, C).Value
If Len(Tmp) And Tmp <> PrevTmp Then
On Error Resume Next
Set Ws = Worksheets(Tmp)
If Err = 0 Then
Set Rng = .Range(.Cells(R, 1), .Cells(R, .Columns.Count).End(xlToLeft))
With Ws
Rt = Application.Max(.Cells(.Rows.Count, "A").End(xlUp).Row + 1, 2)
Rng.Copy Destination:=Ws.Cells(Rt, 1)
End With
End If
End If
PrevTmp = Tmp
Next C
If R Mod 25 = 0 Then Application.StatusBar = "Currently processing row " & R
Next R
End With
With Application
.ScreenUpdating = True
.StatusBar = "Done"
End With
End Sub
I think you will be able to find your way through it and make any required modifications. Let me know if you require any assistance.
So I pull data then I have to copy and paste the rows to their respective sheets basing on the value of Column D. I have a code that does the thing but it takes too slow when there are thousands of rows.
Sub COPY_DATA()
Dim bottomD As Long
bottomD = Range("D" & Rows.Count).End(xlUp).Row
Dim c As Range
Dim ws As Worksheet
For Each c In Sheets("Data").Range("D2:D" & bottomD)
For Each ws In Sheets
ws.Activate
If ws.Name = c And ws.Name <> "Userform" Then
c.EntireRow.copy Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
End If
Next ws
Next c
Worksheets("Data").Activate
End Sub
I want to make the process of copy and pasting faster
This should be faster:
Sub COPY_DATA()
Dim dict As Object
Dim bottomD As Long
Dim c As Range
Dim ws As Worksheet,wb as workbook, wsData as Worksheet
Set wb = ActiveWorkbook
Set wsData = wb.worksheets("Data")
'collect the sheet names
Set dict = CreateObject("scripting.dictionary")
For Each ws In wb.Worksheets
If ws.Name <> "Userform" Then dict.Add ws.Name, True
Next ws
Application.ScreenUpdating = False
bottomD = wsData.Range("D" & Rows.Count).End(xlUp).Row
For Each c In wsData.Range("D2:D" & bottomD)
If dict.exists(c.Value) Then
c.EntireRow.Copy wb.Worksheets(c.Value).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
End If
Next c
Application.ScreenUpdating = True
wsData.Activate
End Sub
Stop .Activating! Totally unnecessary and updating the UI is taking time. Make sure all calls to ranges are qualified.
Option Explicit '<--- Always at the top of modules!
Sub COPY_DATA()
Dim bottomD As Long
bottomD = Range("D" & Rows.Count).End(xlUp).Row
Dim c As Range
Dim ws As Worksheet
For Each c In Sheets("Data").Range("D2:D" & bottomD)
For Each ws In Sheets
With ws
If .Name = c.Value And .Name <> "Userform" Then
c.EntireRow.copy Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0)
End If
End With
Next ws
Next c
End Sub
Note also that I explicitly stated c.Value instead of using the implicit/default property (which just happens to be Value).
I have two separate Excel files. In one of these in Sheet1 is stored infomration about orders and order numbers. Now every time I make a new order I want this information be collected from my order and inserted in to so called "database" workbook. It should identify the last empty row in column A:A in C:\Users\user\Desktop\Order_number.xlsx and insert new values from range ("C6,C17,C10,H18,B32,G32,H6,H9") to the next empty row. Here is the code I came up to but there is some mistake and it is not working. How it can be fixed?
Sub TransferValues465()
Dim wsMain As Worksheet: Set wsMain = ThisWorkbook.ActiveSheet
Dim wsData As Worksheet: Set wsData = Workbooks.Open("C:\Users\user\Desktop\Order_number.xlsx").Sheets("Sheet1")
Dim rngToCopy As Range: Set rngToCopy = wsMain.Range("C6,C17,C10,H18,B32,G32,H6,H9")
Dim c As Long
Dim ar As Range
Dim cl As Range
Dim LastRow As Long
Dim rngDestination As Range
With Application
.DisplayAlerts = False
.ScreenUpdating = False
.EnableEvents = False
End With
'Get the last row in Database sheet:
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
Set rngDestination = wsData.Cells(LastRow + 1, 1).Resize(1, 25).Offset(0, 0)
For Each ar In rngToCopy.Areas
For Each cl In ar
c = c + 1
'I used this next line for testing:
' rngDestination.Cells(c).Value = cl.Address
rngDestination.Cells(c).Value = cl.Value
Next
Next
End Sub
A few corrections:
1) Set wsData = Workbooks("C:\Users\user\Desktop\Order_number.xlsx").Sheets("Sheet1") will not work. Either use Set wsData = Workbooks("Order_number.xlsx").Sheets("Sheet1") if the workbook is open. Or you need to open the workbook first.
2) I am not famliar on using Application.WorksheetFunction.CountA(wsData.Range("A:A")) to get the last row. To get the last row in Column A (with the possibility of skipping balnk cells in the middle) use wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row.
3) My preference is to use Copy >> PasteSpecial xlPasteValues with cl.Copy and the following line wsData.Range("A" & C).PasteSpecial xlPasteValues.
Code
Option Explicit
Sub TransferValues465()
Dim wsMain As Worksheet
Dim wbData As Workbook
Dim wsData As Worksheet
Dim rngToCopy As Range
Dim C As Long
Dim ar As Range
Dim cl As Range
Dim LastRow As Long
Dim rngDestination As Range
Set wsMain = ThisWorkbook.ActiveSheet
Application.DisplayAlerts = False
' you need to open the workbook
Set wbData = Workbooks.Open("C:\Users\user\Desktop\Order_number.xlsx")
Set wsData = wbData.Sheets("Sheet1")
Set rngToCopy = wsMain.Range("C6,C17,C10,H18,B32,G32,H6,H9")
'Get the last row in Database sheet:
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
C = 1
For Each cl In rngToCopy
cl.Copy
wsData.Cells(LastRow + 1, C).PasteSpecial xlPasteValues
C = C + 1
Next cl
wbData.Close True '<-- close and save the changes made
Application.DisplayAlerts = True '<-- restore settings
End Sub