I have multiple sheets and I want to copy their data to another workbook on the last empty row of it. The data has a random number of rows but a defined number of columns, and I am having trouble copying it (not all the sheet, only the rows that have data) and then pasting it to the last row of the final workbook. How should I do it? I have no clue at all...
Disclaimer: I don't want to use select of activesheet as I will have multiple workbooks open and this has brought me problems. Also, the data is continues, and in this I mean that there are no empty rows in the middle of it. Also, I don't think this will change anything but this code is running inside a loop so it copies all sheets from multiple files.
Thanks!
col is the column number you're trying to copy
For Each ws in Activeworkbook.worksheets
lastrow = ws.cells(ws.rows.count, col).end(xlup).row
'code to copy and paste
Next ws
I asume you have a handle to the worksheets, so you can use this code to copy the data:
Public Sub CopyAcross(oSheetFrom As Worksheet, oSheetTo As Worksheet)
Const DATA_START_ADDRESS As String = "$A$1"
oSheetFrom.Range(DATA_START_ADDRESS).CurrentRegion.Copy
oSheetTo.Range("A" & oSheetTo.Rows.Count).End(xlUp).PasteSpecial xlPasteAll
Application.CutCopyMode = False
End Sub
Assuming that the data to be copied has the same start address on each sheet, which is specified as DATA_START_ADDRESS
Related
I have a simple problem(at least seems to be) that I just cannot seem to be able to find a good solution to:
I have 4 workbooks, that all contain two of the exact worksheets(rest of the worksheets are unique for each workbook). I am storing these two worksheets in a seperate workbook(so 5th workbook). Out of these 2 worksheets, 1 of them is a Data sheet made up of many tables, which I do updates on and the other one is a sheet called V, which just uses some vlookup functions to bring up the related data from this Data sheet.
I am trying to find a way to be able to pass along this data sheet to each individual workbook, instead of editing the data sheet individually for each workbook(All 4 of them).
I was able to come up with the following macro, which checks if the sheet already exists and if it does it deletes it. Then it opens up location of the excel file, copies this worksheet to the workbook and therefore I have the most "updated" version of this data worksheet.
Sub UpdateT()
Sheets("data").Visible = True
Dim wb As Workbook
Dim aw As Workbook
''Open 2nd Workbook
Set aw = Application.ActiveWorkbook
'Check if data worksheet exists, and if it does delete it
If Not GetWorksheet("data") Is Nothing Then
Application.DisplayAlerts = False
Worksheets("data").Delete
Application.DisplayAlerts = True
End If
'Check if T worksheet exists, and if it does, delete it
If Not GetWorksheet("T") Is Nothing Then
Application.DisplayAlerts = False
Worksheets("T").Delete
Application.DisplayAlerts = True
End If
Set wb = Workbooks.Open(Filename:="C:\Users\yilmadu001\Desktop\Update.xlsx")
'Copy To Different Workbook
wb.Sheets("data").Copy _
After:=aw.Sheets("Data1")
wb.Sheets("5120 TI").Copy _
After:=aw.Sheets("MENU5120")
'Close 2nd Workbook
aw.Save
wb.Close
'Hide the data worksheet
aw.Sheets("data").Visible = False
End Sub
'Function to check if worksheets exist
Function GetWorksheet(shtName As String) As Worksheet
On Error Resume Next
Set GetWorksheet = Worksheets(shtName)
End Function
The problem is the following:
When the new Data worksheet is transferred, the V worksheet is no longer working with the Vlookup function to be able to point to the relative information. So then I thought, okay what if I transfer BOTH Data and V worksheets, however that also did not work.
Is there a way to be able to use Vlookup, while copying the Data sheet? (The name is exactly the same I do not understand why it does not seem to be able to point to the cells of the table). It just looks blank, can't point to anything.
NOTE: I am not changing the format of the Data tables, basically just the values, so the format is the exactly the same.
It is probably important to note that the main excel workbooks(the 4) are in use 24/7, therefore I cannot go the other way(Update from Data workbook to the main workbook). I must "pull" the updated worksheet rather than "push".
If anyone has any suggestions I'd really appreciate. Thank you.
Sub Save7()
Dim NextRow As Range
Set NextRow = Range("AC" & Sheets("Sheet1").UsedRange.Rows.Count)
Sheet3.Range("AC14:AG14").Copy
Sheet1.Activate
NextRow.PasteSpecial Paste:=xlValues, Transpose:=False
Application.CutCopyMode = False
Set NextRow = Nothing
End Sub
My purpose of this code is to copy data ( Five columns of 'NO' in AC14 to AG14) from sheet 3 and paste to sheet 1 where the last active cell is at.
The code above is working well, however I made some modification to the sheet tab name for sheet 1. Sheet 1 is now called "Equipment stuffs", while sheet 3 name is remaining unchanged.
After those changes, the macro stopped working. The cause is probably because I don't know how to declare "Equipment stuffs" in the code .
There's no need to do copy/paste to move data from one place on the spreadsheet to another. You should simply assign the Value of the respective Range objects, for example:
Sheet1.Range("NamedRange2").Value = Sheet1.Range("NamedRange2").Value
Also, use code names for the sheets, instead of Sheets("SheetName"), and defined named for the ranges, instead of Range("AC14:AG14", otherwise your code will stop working if the user renames the sheet or inserts or deletes any rows above your reference.
If you want to automate this a little you could collect the active workbook and loop through each sheet using wb.Worksheets. Then collect the name with targetSheet.Name.
Option Explicit
Public Sub getSheet()
Dim wb As Workbook
Dim targetSheet As Worksheet
Set wb = ActiveWorkbook
For Each targetSheet In wb.Worksheets
Debug.Print targetSheet.Name
Next targetSheet
End Sub
I’m brazilian hehe, I understood your question , I’ve a code for alter the data in same worksheet (I’ll attach it here), for you to change the data in another worksheet, you need put on:
Worksheets("NameWorkSheet) Activate
for the VBA that’s refers to this tab.
An Excel VBA newbie here. I am working on this code for a one-click-for-all worksheets macro. So the idea is to have a macro that once clicked, can trigger the IF-ISERROR-Vlookup formula in multiple worksheets (around 12 now, but will keep increasing in the future). Both the formula and the result are displayed in the same columns in multiple worksheets, but of different number of rows (Sheet 1 col B[data] and C[formula], sheet 2 Col B and C, etc.)
Now the code I did below works only when I go to a worksheet and trigger the macro in that specific worksheet; which means I have to do it one by one per sheet.
I tried removing the select, the selection and the activesheet as recommended in previous posts, but it showed an error message to me.
So my questions are:
a) How can I modify the code so that I can create a macro that triggers all worksheets in one click?
b) As you can see below, I put Range("C4:C54") even though the number of rows are different in every sheet, because I have no idea how to make the range cover different rows only until it hits the last cell with values.
Dim ws As Worksheet
For Each ws In Worksheets
Range("C4").Select
ActiveCell.FormulaR1C1 = _
"=IF(ISERROR(VLOOKUP(RC[-1],TestScore,1,FALSE)),""Pass"",""Fail"")"
Range("C4").Select
Selection.AutoFill Destination:=Range("C4:C54")
Range("C4:C54").Select
Next ws
End Sub
Anybody can help with this problem? Any help would be appreciated. Thanks so much beforehand!
Edit:
Added the sample snapshot of the problem as requested
Put this code in the Module (Insert >> Module):
Dim ws As Worksheet, LastRow As Long
For Each ws In Worksheets
With ws
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'Change the number (1) with appropriate column
.Range("C4:C" & LastRow).FormulaR1C1 = "=IF(ISERROR(VLOOKUP(RC[-1],TestScore,1,FALSE)),""Pass"",""Fail"")"
'The formula will be filled down til the last row
End With
Next ws
Avoid using Select statements - it can cause issues and instead refer to the cells explicitly. This will insert your formula in cells C4 to the last cell in that column
Dim ws As Worksheet
For Each ws In Worksheets
With ws
.Range("C4:C" & .Cells(.Rows.Count, "B").End(xlUp).Row).FormulaR1C1 = _
"=IF(ISERROR(VLOOKUP(RC[-1],TestScore,1,FALSE)),""Pass"",""Fail"")"
End With
Next ws
I have data on multiple sheets in a workbook that I want copied all to one sheet in that same workbook. When I run the macro, I would like it to start by deleting the current data in the "iPage Data Export" sheet and then replacing it with data from the other sheets.
I want the process to occur one column at a time since I may not bring over everything. Right now I am trying to learn how to do just one column.
I was able to get it to copy all of the contents of a column from one sheet, but when it moves to the next sheet, it overwrites the existing data. In the end, I only get one sheets worth of data copied.
Here are my 4 problems:
How do I make it clear the data on this sheet before running the routine?
How can I make it start each copy function at the bottom of that row (i.e. after the last cell with a value)? I have tried many of the suggestions on this and other boards without success. I will admit I am not very experienced in this.
How can I make it copy to a particular column (currently it just seems to default to A.
How can I concatenate multiple columns during the paste function? I.e. what if I want it to insert: A2&", "B2 instead of just A2
Sub CombineData()
Dim Sht As Worksheet
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "iPage Data Export" Then
Sht.Select
Range("C:C").Copy
Sheets("iPage Data Export").Select
ActiveSheet.Paste
Else
End If
Next Sht
End Sub
How do I make it clear the data on this sheet before running the routine?
Sht.Cells.ClearContents
How can I make it start each copy function at the bottom of that row (i.e. after the last cell with a value)? I have tried many of the suggestions on this and other boards without success. I will admit I am not very experienced in this.
Range("C" & Rows.Count).End(xlUp).Offset(1, 0)
In detail:
Rows.Count will return the number of rows in the sheet, so in the legacy style *.xls workbooks this would return the number 65,536. Therefore "C" & Rows.Count is the same as C65536
Range("C" & Rows.Count).End(xlUp) is the same as going to C65536 and pressing Ctrl + ↑ - The command End(xlDirection) tells the program to go the last cell in that range. In this case, we would end up at the last cell containing data in column C.
.Offset(1, 0) means that we want to return the range offset by an amount of rows and/or columns. VBA uses RC (Rows Columns) references, so whenever you see something like the Offset() function with two numbers being passed as the arguments, it usually relates to the row, and the column, in that order. In this case, we want the cell that is one row below the last cell we referenced.
All-in-all the phrase Range("C" & Rows.Count).End(xlUp).Offset(1, 0) means go to the last cell in column C, go up until we hit the last cell with data, and then return the cell below that - which will be the next empty cell.
How can I make it copy to a particular column (currently it just seems to default to A.
Range("C:C").Copy Destination:=Sheets("iPage Data Export").Range("A:A")
You can pass the Destination argument in the same line and actually bypass the clipboard (faster and cleaner)
How can I concatenate multiple columns during the paste function? I.e. what if I want it to insert: A2&", "B2 instead of just A2
Lets say you wanted to reference column A, B, and F - just use:
Range("A1, B1, F1").EntireColumn
To summarise, you could streamline your existing code to something like (untested):
Sub CombineData()
Dim Sht As Worksheet
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "iPage Data Export" Then
Sht.Range("C1:C" & Cells(Sht.Rows.Count, 3).End(xlUp).Row).Copy Destination:=Sheets("iPage Data Export").Range("A:A")
End If
Next
End Sub
This should do for the copying:
Sub CombineData()
Dim sheet As Worksheet
For Each sheet In Worksheets
If (sheet.Name <> "iPage Data Export") Then
sheet.Select
Range("A1", ActiveCell.SpecialCells(xlLastCell)).Select
Selection.Copy
Worksheets("iPage Data Export").Activate
Cells(1, ActiveCell.SpecialCells(xlCellTypeLastCell).Column + 1).Select
ActiveSheet.Paste
End If
Next
End Sub
For the concatenation you need to be more specific - but I guess you should open a new question with a clearer focus if you need specific help on that.
I’d need to write a short VBA script for the following situation. The workbook contains multiple sheets. The first sheet is the summary sheet. After the summary sheet there is an irregular number of sheets that contain the information I would like to display on the summary sheet. The information is always in “Column B”. The script should copy “Column B” of each sheet and paste it to the next empty column in the summary sheet. In other words, it should copy “Column B” in “Sheet 2” and paste it to the next empty column in “Sheet 1”, then copy “Column B” in “Sheet 3” and paste again to the next empty column in “Sheet 1”, etc. etc.
All the help is appreciated, thank you!
You will need to declare a Worksheet type variable (e.g. Dim ws As Worksheet), to loop by a For Each ws In Activeworkbook.Worksheets ... Next ws. Then you need to define which sheet is the master sheet. I recommend once again a Worksheet, e.g. Set wsMain = ActiveWorkbook.Worksheets("Summary").
To complete it use a
wsMain.Cells.Find("*",SearchOrder:=xlByColumns,SearchDirection:=xlPrevious).Column
to tell you the index of the last used column in your summary sheet. You can either store it in a variable then increase it by one in your loop or run it in your loop (not resource-efficient but who cares about that two milliseconds).
You can reference columns by index which in your case will be ws.Cells.Columns(2) and wsMain.Cells.Columns(LastColumn + 1).
Have fun writing your code, I hope I could help!
This worked:
Sub NextWsToNextEmptyColumn()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Cells.Columns(2).Copy Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Offset(, 1)
Next ws
End Sub