Allow append of data to a summary sheet in another workbook - vba

I have this code which appends data from three worksheets to a summary sheet, however on execution it is taking 12 of the 13 rows from sheet 1 and 2 and thirteen from sheet 3 to the summary I also would like this to work by sending to a summary sheet in a different workbook
Sub SummurizeSheets()
Dim ws As Worksheet
Application.ScreenUpdating = False
Sheets("Summary").Activate
For Each ws In Worksheets
If ws.Name <> "Summary" Then
ws.Range("D2:D6, D8:D15").Copy
Worksheets("Summary").Cells(Rows.Count, 4).End(xlUp).Offset(0, 0).PasteSpecial (xlPasteValues)
End If
Next ws
End Sub

Change Offset(0,0) to Offset(1,0). What's happening is not that it's copying 12 rows, but rather that the subsequent blocks are being pasted starting at the end of the previous block. That is, the first block is pasted into D1:D13, and the second block is pasted into D13:D26. By using Offset(1,0), the second block will be pasted starting with the first empty cell (that is, D14).
You can place the results in a new workbook simply by creating it in the code and referring to it in the paste, for example:
Option Explicit
Sub SummurizeSheets()
Dim ws As Worksheet
Dim currentWB As Workbook: Set currentWB = ActiveWorkbook
Dim newWB As Workbook: Set newWB = Application.Workbooks.Add
newWB.Worksheets(1).Name = "Summary"
For Each ws In currentWB.Worksheets
ws.Range("D2:D6, D8:D15").Copy
With newWB.Worksheets("Summary").Cells(Rows.Count, 4).End(xlUp)
If IsEmpty(.Value) Then
.PasteSpecial (xlPasteValues)
Else
.Offset(1, 0).PasteSpecial (xlPasteValues)
End If
End With
Next ws
End Sub
EDIT updated to paste into the first empty cell in column, even if that is row 1.

Related

Excel copy range and paste in a specific range available and print

I would like to copy a range in one sheet and paste it as a value in another sheet, but just in a specific range in the next available cell in column B. Starting from B4 to B23 only.
I changed some code I found online but it's not working for me in finding the next available row. After I run the macro the first time, when I run it again and again it does nothing, and it's not working in pasting only the values either.
I tried saving the file before running the Macro again, but still it's not working.
At the end, when the range in the Print sheet is full, I would like a message box asking me to select one of the printers (not the default) on one of my servers (specifying the server path in the code like \a_server_name) and print this Print Sheet only, or clear the records in the range in the Print Sheet, or save only the Sheet Print in a new file (SaveAs) to a location I can choose on one of my servers (specifying the server path in the code \a_server_name) or simply do nothing and end the sub.
Thank you.
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets(“Data”)
Set pasteSheet = Worksheets("Print”)
copySheet.Range("J11:Q11").Copy
pasteSheet.Range("B4:I23").End(xlUp).Offset(1,0)
.PasteSpecial.xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
This will set the values equal to each other without copying/pasting.
Option Explicit
Sub Testing()
Dim wsC As Worksheet: Set wsC = ThisWorkbook.Sheets("Data")
Dim wsP As Worksheet: Set wsP = ThisWorkbook.Sheets("Print")
Dim LRow As Long
LRow = wsP.Range("B" & wsP.Rows.Count).End(xlUp).Offset(1).Row
wsP.Range("B" & LRow).Resize(wsC.Range("J11:Q11").Rows.Count, wsC.Range("J11:Q11").Columns.Count).Value = wsC.Range("J11:Q11").Value
End Sub
Modifying your code - and reducing to minimal example
Sub test()
Dim copySheet As Worksheet: Set copySheet = Worksheets("Data")
Dim pasteSheet As Worksheet: Set pasteSheet = Worksheets("Print")
copySheet.Range("J11:Q11").Copy
pasteSheet.Range("B" & pasteSheet.Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValues
End Sub
From what i can gather, you want to copy 8 cells and paste all 8 cells to 20 rows, starting at B4. You are not clear on how you want to rerun the macro, it will just write over the data you just pasted.
The first code will copy the 8 cells into the 20 rows
With ThisWorkbook
Sheets("Data").Range("J11:Q11").Copy
Sheets("Print").Range("B4:I23").PasteSpecial Paste:=xlPasteValues
End With
This second code uses a for loop to accoplish the same task, but it also will write over the previously pasted data.
Dim i As Long
With ThisWorkbook
For i = 4 To 23
Sheets("Data").Range("J11:Q11").Copy
Sheets("Print").Cells(i, 2).PasteSpecial Paste:=xlPasteValues
Next i
End With
If you want to be able to reuse the macro, you will have to modify the range to be copied that allows you to select the range you want to copy. Maybe a variable that allows a user input with a InputBox.
Edit:
Dim lRow As Long
lRow = Sheets("Print").Cells(Rows.Count, 2).End(xlUp).Row
With ThisWorkbook
Sheets("Data").Range("J11:Q11").Copy
Sheets("Print").Cells(lRow, 2).Offset(1).PasteSpecial Paste:=xlPasteValues
End With
Edit #3
With ThisWorkbook
Dim lRow As Long
lRow = .Sheets("Print").Range("B" & Rows.Count).End(xlUp).Row
Sheets("Data").Range("J11:Q11").Copy
Sheets("Print").Cells(lRow, 2).Offset(1).PasteSpecial Paste:=xlPasteValues
End With

Copying specific ranges/cells on a standard template

I fairly new to VBA, using it to work on simple macros to automatize my time.
I am looking for an Excel macro which copies specific cells, on different regions of a series of worksheets from the same template(see the image, I want to copy the, yellow, gray and green cells). All sheets work on the same workbook. The main quest is: Put it all together, as values, sequentially on one sheet, with just the same headers and put a total sum in the end of this columns. If it's simpler to keep/use the template and sum the values in there, ok for me too. If I've created 20 new sheets, the macro will read the already existed and the new sheets and consolidate it in the sheet "consolidated".
I've found a code that do almost everything I need, but I'm struggling to change de range on to copy regions I want.
Like I said, using the template (create a copy from the master template and summing the values in there?) or simply combining the value side by side, so every row represent a sheet, for me ok too.
Please, any help is welcomed, thanks in advance.
The code I used follows below [source].
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
'Delete the sheet "Consolidado" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("Consolidado").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "Consolidado"
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "Consolidado"
'loop through all worksheets and copy the data to the DestSh
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name And sh.Name <> "Menu" And sh.Name <> "Infos" And sh.Name <> "Log Update" And sh.Name <> "Master" Then
'Find the last row with data on the DestSh
Last = LastRow(DestSh)
'Fill in the range that you want to copy
Set CopyRng = sh.Range("A1").CurrentRegion
'Test if there enough rows in the DestSh to copy all the data
If Last + CopyRng.Rows.Count > DestSh.Rows.Count Then
MsgBox "There are not enough rows in the Destsh"
GoTo ExitTheSub
End If
'This example copies values/formats, if you only want to copy the
'values or want to copy everything look at the example below this macro
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
'AutoFit the column width in the DestSh sheet
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
The Excel Template
EDIT:
The results can be one of the 2 below, which is easier to do.
Result sheet option 1
Result sheet option 2
EDIT 2
Clean workbook
After the clarification in the comments I would do as follows:
For simplicity lets take the following Template:
So you want Cell A2 in Sheet Consolidado to be the sum of Cell A2 of all the other sheets, and for the other cells respectivelly.
I propose the following: You create a sheet Consolidado from the template. You then fill the valueCells array with the list of cells you want to be summed up in the Consolidadosheet.
The code below then will go through the targeted sheets, and add the value from each cell in the array to an outputArray. After the targeted sheets are summed up, it is pasted to the Consolidado sheet
Sub CopyRangeFromMultiWorksheets()
Dim wb As Workbook
Dim sh As Worksheet
Dim DestSh As Worksheet
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb = ThisWorkbook
Set DestSh = wb.Sheets("Consolidado")
valueCells = Array("A2", "C2", "A4", "B4", "C4")
Dim outputArray As Double
ReDim outputArray(UBound(valueCells))
For Each sh In wb.Worksheets
If sh.Name <> DestSh.Name And sh.Name <> "Menu" And sh.Name <> "Infos" And sh.Name <> "Log Update" And sh.Name <> "Master" Then
For i = LBound(valueCells) To UBound(valueCells)
outputArray(i) = outputArray(i) + sh.Range(valueCells(i))
Next i
End If
Next sh
For i = LBound(valueCells) To UBound(valueCells)
DestSh.Range(valueCells(i)) = outputArray(i)
Next i
End Sub

Macro to copy first two columns from all sheets to a master sheet is skipping sheets

I'm using this macro to copy columns A and B from all of my sheets into a new sheet named Master. What I notice is that entire sheets worth of information are missing in the master sheet and I can't figure out why. The format for my sheets is column A has a string of characters that follow this structure: M2,004,005,004,007,17,096,01:07:45,45 and column B is just a date such as 4/19/2017.
I have hundreds of these sheets in my workbook and each has 224 rows that I need to copy into a single master sheet. Could anyone help me figure out how to get this code to stop skipping sheets?
Thanks.
Sub CreateMaster()
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Master"
Sheets(2).Activate
Range("A1:B1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1:B1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1:B1").Select
Selection.CurrentRegion.Select
Selection.Copy Destination:=Sheets(1).Range("A65536:B65536").End(xlUp)(2)
Next
End Sub
while searching for solutions online, I came across this macro that seems to do the same thing, but also seems to skip the exact same sheets as my macro does.
Sub CopyFromWorksheets()
Dim wrk As Workbook 'Workbook object - Always good to work with object
variables
Dim sht As Worksheet 'Object for handling worksheets in loop
Dim trg As Worksheet 'Master Worksheet
Dim rng As Range 'Range object
Dim colCount As Integer 'Column count in tables in the worksheets
Set wrk = ActiveWorkbook 'Working in active workbook
For Each sht In wrk.Worksheets
If sht.Name = "Master" Then
MsgBox "There is a worksheet called as 'Master'." & vbCrLf & _
"Please remove or rename this worksheet since 'Master' would be" & _
"the name of the result worksheet of this process.", vbOKOnly + vbExclamation, "Error"
Exit Sub
End If
Next sht
'We don't want screen updating
Application.ScreenUpdating = False
'Add new worksheet as the last worksheet
Set trg = wrk.Worksheets.Add(After:=wrk.Worksheets(wrk.Worksheets.Count))
'Rename the new worksheet
trg.Name = "Master"
'Get column headers from the first worksheet
'Column count first
Set sht = wrk.Worksheets(1)
colCount = sht.Cells(1, 255).End(xlToLeft).Column
'Now retrieve headers, no copy&paste needed
With trg.Cells(1, 1).Resize(1, colCount)
.Value = sht.Cells(1, 1).Resize(1, colCount).Value
'Set font as bold
.Font.Bold = True
End With
'We can start loop
For Each sht In wrk.Worksheets
'If worksheet in loop is the last one, stop execution (it is Master worksheet)
If sht.Index = wrk.Worksheets.Count Then
Exit For
End If
'Data range in worksheet - starts from second row as first rows are the header rows in all worksheets
Set rng = sht.Range(sht.Cells(2, 1), sht.Cells(65536, 1).End(xlUp).Resize(, colCount))
'Put data into the Master worksheet
trg.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
Next sht
'Fit the columns in Master worksheet
trg.Columns.AutoFit
'Screen updating should be activated
Application.ScreenUpdating = True
End Sub
as a workaround, since only the most recent data is immediately pertinent, I worked around it, but deleting the first 150 sheets. that still left around 100 sheets for my macro to work on, but now the missing pieces of data seem to be there. I wonder if there's something about the quantity of sheets that is causing this to malfunction?
Comments may not get it across correctly. Restructure your loop (and add the variables mentioned).
Dim x as Long
Dim thisSht as Worksheet
For x = 1 to wrk.Worksheets.Count
set thisSht = wrk.Worksheets(x)
'Data range in worksheet - starts from second row as first rows are the header rows in all worksheets
Set rng = thisSht.Range(sht.Cells(2, 1), sht.Cells(65536, 1).End(xlUp).Resize(, colCount))
'Put data into the Master worksheet
trg.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
Next x

copy cells but not replace them

im stuck at a vba problem.
i want to copy some cells from worksheet to another
first i go through all worksheets begin with "IT*"
For Each ws In wb.Worksheets
If ws.Name Like "IT*" Then
ws.Select
Call transfer
End If
Next ws
then call transfer
Sub transferAP()
'
' transferAP Makro
'
Dim strSheetName As String
strSheetName = ActiveSheet.Name
Sheets(strSheetName).Select
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A3")
Worksheets(strSheetName).Range("E9").Copy Worksheets("Berechnung_Personal").Range("B3")
Worksheets(strSheetName).Range("G9").Copy Worksheets("Berechnung_Personal").Range("C3")
Worksheets(strSheetName).Range("G11").Copy Worksheets("Berechnung_Personal").Range("D3")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A4")
Worksheets(strSheetName).Range("E24").Copy Worksheets("Berechnung_Personal").Range("B4")
Worksheets(strSheetName).Range("G24").Copy Worksheets("Berechnung_Personal").Range("C4")
Worksheets(strSheetName).Range("G26").Copy Worksheets("Berechnung_Personal").Range("D4")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A5")
Worksheets(strSheetName).Range("E39").Copy Worksheets("Berechnung_Personal").Range("B5")
Worksheets(strSheetName).Range("G39").Copy Worksheets("Berechnung_Personal").Range("C5")
Worksheets(strSheetName).Range("G41").Copy Worksheets("Berechnung_Personal").Range("D5")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A6")
Worksheets(strSheetName).Range("M3").Copy Worksheets("Berechnung_Personal").Range("B6")
Worksheets(strSheetName).Range("O3").Copy Worksheets("Berechnung_Personal").Range("C6")
Worksheets(strSheetName).Range("O5").Copy Worksheets("Berechnung_Personal").Range("D6")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A7")
Worksheets(strSheetName).Range("M18").Copy Worksheets("Berechnung_Personal").Range("B7")
Worksheets(strSheetName).Range("O18").Copy Worksheets("Berechnung_Personal").Range("C7")
Worksheets(strSheetName).Range("O20").Copy Worksheets("Berechnung_Personal").Range("D7")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A8")
Worksheets(strSheetName).Range("M33").Copy Worksheets("Berechnung_Personal").Range("B8")
Worksheets(strSheetName).Range("O33").Copy Worksheets("Berechnung_Personal").Range("C8")
Worksheets(strSheetName).Range("O35").Copy Worksheets("Berechnung_Personal").Range("D8")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A9")
Worksheets(strSheetName).Range("U3").Copy Worksheets("Berechnung_Personal").Range("B9")
Worksheets(strSheetName).Range("W3").Copy Worksheets("Berechnung_Personal").Range("C9")
Worksheets(strSheetName).Range("W5").Copy Worksheets("Berechnung_Personal").Range("D9")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A10")
Worksheets(strSheetName).Range("U18").Copy Worksheets("Berechnung_Personal").Range("B10")
Worksheets(strSheetName).Range("W18").Copy Worksheets("Berechnung_Personal").Range("C10")
Worksheets(strSheetName).Range("W20").Copy Worksheets("Berechnung_Personal").Range("D10")
Worksheets(strSheetName).Range("C3").Copy Worksheets("Berechnung_Personal").Range("A11")
Worksheets(strSheetName).Range("U33").Copy Worksheets("Berechnung_Personal").Range("B11")
Worksheets(strSheetName).Range("W33").Copy Worksheets("Berechnung_Personal").Range("C11")
Worksheets(strSheetName).Range("W35").Copy Worksheets("Berechnung_Personal").Range("D11")
It runs at all, but if there is another worksheet ( and there is another) named "IT*" it will replace the copied files cause of the non relative output cell destination.
I want to continue with the new worksheet data at the end of the last copied data.
Hope you get what im trying to explain.
I propose you the following refactoring of your code
Sub transferAP(sourceSht As Worksheet)
With Worksheets("Berechnung_Personal") '<--| reference target sheet
With .Cells(.Rows.Count, 1).End(xlUp).Offset(1) '<--| reference its column A first empty cell after last not empty one)
sourceSht.Range("C3").Copy .Cells(1,1)
sourceSht.Range("E9").Copy .Cells(2,1)
sourceSht.Range("G9").Copy .Cells(3,1)
.... and so on: keep in mind that .Cells(1,1) syntax assumes the referenced range as the starting cell
End With
End With
End Sub
And your main sub will call it as follows:
transferAP ws
This is your new Main sub. It is basically unchanged from your earlier code, but I have specified Wb to be ThisWorkbook. You may like to specify another.
Sub Main()
Dim Wb As Workbook
Dim Ws As Worksheet
Dim R As Long
Set Wb = ThisWorkbook
For Each Ws In Wb.Worksheets
If Ws.Name Like "IT*" Then
TransferAP Ws, R ' pass the Ws to the sub
End If
Next Ws
End Sub
In your TransferAP I have also specified ThisWorkbook as the workbook where the target worksheet "Berechnung_Personal" is found. Excel presumes the ActiveWorkbook if no specification is made. Note that ThisWorkbook needs not be the ActiveWorkbook. ThisWorkbook is the Workbook that contains the code. The ActiveWorkbook is the last workbook you looked at before switching to the VBE window or the workbook you activated using code thereafter.
Sub TransferAP(Ws As Worksheet, R As Long)
' 21 Mar 2017
Dim WsTarget As Worksheet
Dim Sources() As String ' List of source cells
Dim i As Integer ' index for Sources
Set WsTarget = ThisWorkbook.Worksheets("Berechnung_Personal")
If R = 0 Then R = 3 ' row 3 is the first row to use
Sources = Split("E9,E24,E39,M3,M18,M33,U3,U18,U33", ",")
For i = 0 To UBound(Sources)
With WsTarget
.Cells(R, 1).Value = Ws.Range("C3").Value
.Cells(R, 2).Value = Ws.Range(Sources(i)).Value
.Cells(R, 3).Value = Ws.Range(Sources(i)).Offset(0, 2).Value
.Cells(R, 4).Value = Ws.Range(Sources(i)).Offset(2, 2).Value
End With
R = R + 1
Next i
End Sub
The TransferAP returns the final value of R to the Main. So, when the next source worksheet is found R will continue counting from where it left off - I hope. I didn't test the loop.

Search for next blank cell in another sheets and paste

I am new using macro of Excel, and this is the first time I ask a question here.
I did some research here about this problem, but still can't solve it.
I have several sheets named :page 1, page 2, etc, and I want to copy the data in specific range and paste them to the sheets named "ULD".
When I run the macro in page 1, everything works perfect. But when I run it in page 2 or other sheet, the new data will paste and replace the data pasted from page 1.
The following is my vba code:
Sub test()
Dim ws As Worksheet
Set ws = Sheets("ULD")
'Only Copy Visible Cells'
Range("L3:L100").Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("ULD").Activate
For Each cell In ws.Range("I4:I10").Cells
If IsEmpty(cell) = True Then cell.Select.Paste: Exit For
Next cell
End Sub
Besides, I want the data being paste only value, how should I write the code?
There is some confusion, this is how I interpret what you are trying to do.
Sub test2()
Dim ws As Worksheet, LstRw As Long
Set ws = Sheets("ULD")
With ws
LstRw = .Cells(.Rows.Count, "I").End(xlUp).Row
End With
'Only Copy Visible Cells'
Range("L3:L100").SpecialCells(xlCellTypeVisible).Copy
ws.Range("I" & LstRw + 1).PasteSpecial xlPasteValues
Application.CutCopyMode = 0
End Sub