I am looking for some help on this issue. I am using VBA in Excel 2007 to consolidate tables from five separate worksheets onto one worksheet. This works great in a stand alone workbook, but I need to move this into a workbook with other tabs that I will not consolidate data from. I tried creating an array as a varaible which included the five workbooks I need to consolidate, but I could not get it to work.
Here is the code I am using as a separate process that works:
Sub SummariseData()
Dim x As Long, llastrow As Long, lfirstrow As Long
Range("Data").CurrentRegion.Offset(1, 0).ClearContents
Application.ScreenUpdating = False
For x = 1 To Sheets.Count
If Sheets(x).CodeName <> "Sheet1" Then
If Sheets(x).Range("A2") <> "" Then
lfirstrow = Sheet1.Range("A" & Rows.Count).End(xlUp).Row + 1
llastrow = Sheets(x).Range("A1").End(xlDown).Row
Sheets(x).Range("A2:N" & llastrow).Copy Destination:=Sheet1.Range("B" & Rows.Count).End(xlUp).Offset(1, 0)
Sheet1.Range("A" & lfirstrow & ":A" & lfirstrow + llastrow - 2) = Sheets(x).Name
End If
End If
Next x
End Sub
Can anoyone help with how to write the code to specifically call the the five tabs I need to consolidate, instead of loop through all tabs in the workbook? The tab names are T1, T2, T3, T4, T5 all consolidaing to a tab call Summary.
You can try this:
Dim sh As Worksheet, ws As Worksheet
Set ws = Thisworkbook.Sheets("Summary")
For Each sh in Thisworkbook.Sheets(Array("T1","T2","T3","T4","T5"))
If sh.Range("A2").Value <> "" Then
sh.Range("A1",sh.Range("A" & Rows.Count).End(xlUp).Offset(0,14).Address).Copy _
ws.Range("B" & Rows.Count).End(xlUp).Offset(1,0)
ws.Range(Range("A" & Rows.Count).End(xlUp).Offset(1,0).Address, _
Range("B" & Rows.Count).End(xlUp).Offset(0,-1).Address).Value = sh.Name
End If
Next
Not tested though so i leave it to you.
Try to replace with this :
Sub SummariseData()
Dim x As Long, llastrow As Long, lfirstrow As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Worksheets("Summary")
Range("Data").CurrentRegion.Offset(1, 0).ClearContents
Application.ScreenUpdating = False
For x = 1 To 5
sheetName = "T" & x
Set ws2 = Worksheets(sheetName)
If ws2.Range("A2") <> "" Then
lfirstrow = ws1.Range("A" & Rows.Count).End(xlUp).Row + 1
llastrow = ws2.Range("A1").End(xlDown).Row
ws2.Range("A2:N" & llastrow).Copy Destination:=ws1.Range("B" & Rows.Count).End(xlUp).Offset(1, 0)
ws1.Range("A" & lfirstrow & ":A" & lfirstrow + llastrow - 2) = sheetName
End If
Next x
End Sub
Details on what I changed :
I used worksheet objects instead of calling the worksheet by its name each time (ws1 for the worksheet TO which you're copying, and ws2 for the worksheet FROM which you're copying.
I used a loop that goes from 1 to 5, to concatenate that value to a T, in order to get the tab name.
Related
I wan't to transfer data within a range from each worksheet of a workbook excluding specific worksheet names based on a value being greater than zero within a range. Based on the value being greater than zero I wan't to transfer corresponding column values in the same row and update the database sheet by putting the values under specific columns from all worksheets apart from specific sheet and populate the list in the database sheet. My code does not seem to be working.
Sub Button4_Click()
Dim sourceRng As Range
Dim cell As Range
Dim i As Long
Dim ws As Worksheet
Dim wsC As Worksheet
Set wsC = Sheets("Database")
For Each wkSht In ThisWorkbook.Worksheets
If ws.Name <> "Database" And ws.Name <> "Combine" And ws.Name <> "CETIN" Then
Set sourceRng = ActiveSheet.Range("AY17:AY30")
i = 1
For Each cell In sourceRng
If cell.Value > 0 Then
cell.Resize(1, 1).Copy Destination:=wsD.Range("A" & i)
i = i + 1
End If
Next cell
End If
Next
End Sub
I believe this should work for you. Your image is hard to read, so you may need to adjust the columns if I read them wrong.
Option Explicit
Sub Button4_Click()
Dim i As Long
Dim wkSht As Worksheet
Dim wsC As Worksheet
Dim rowCount As Integer
Dim nextEmptyRow As Integer
Set wsC = ThisWorkbook.Worksheets("Database")
For Each wkSht In ThisWorkbook.Worksheets
nextEmptyRow = wsC.Cells(Rows.Count, "A").End(xlUp).Row + 1
If wkSht.Name <> "Database" And wkSht.Name <> "Combine" And wkSht.Name <> "CETIN" Then
For i = 17 To 30
If wkSht.Range("AY" & i).Value > 0 Then
wkSht.Range("AY" & i).Copy Destination:=wsC.Range("A" & nextEmptyRow)
wkSht.Range("K" & i).Copy Destination:=wsC.Range("B" & nextEmptyRow)
wkSht.Range("R" & i).Copy Destination:=wsC.Range("C" & nextEmptyRow)
wkSht.Range("T" & i).Copy Destination:=wsC.Range("D" & nextEmptyRow)
End If
Next i
End If
Next wkSht
End Sub
You can also replace wkSht.Range("AY" & i).Copy Destination:=wsC.Range("A" & nextEmptyRow) with wsC.Range("A" & nextEmptyRow).value = wkSht.Range("AY" & i).value for those 4 lines if you only want to preserve the value and not formatting.
I am trying to create code (Loop) so that when a task is allocated to a team member (in a cell in column H) the code searches the cell value with the existing sheet names and if there is a match, the sheet then makes the task member sheet active sheet, finds the last available line and adds the allocated tasks to the sheet. The code should run for all filled cells in the column.
However, the code i have currently written bugs out. I am finding it hard to define the worksheetname (Cell value) etc.
Sub TaskAllocation()
Dim cell As Range, Lastrow1 As Double, i As Integer
Dim SubTaskWs As Worksheet, Ws As Worksheet, Lastrow2 As Double
Set SubTaskWs = ActiveWorkbook.Worksheets("Sub tasks")
Set Ws = ActiveWorkbook.Sheets(WsName)
i = o
Lastrow1 = SubTaskWs.Range("H" & Rows.Count).End(xlUp).Row
Lastrow2 = Ws.Range("A" & Rows.Count).End(xlUp).Row
For Each cell In SubTaskWs.Range("H4:H" & Lastrow1)
For Each Ws In Sheets
If cell.value = Ws.Name Then
Ws.Range("A" + (Lastrow2 + (i))).EntireRow.Insert
Call copyFormattingAbove(Ws, "A" & Lastrow2)
Ws.Range(("A" & Lastrow2) + (i)).value = cell.Offset(, -6)
Ws.Range(("B" & Lastrow2) + (i)).value = cell.Offset(, -5)
i = i + 1
End If
Next Ws
Next cell
End Sub
I did change a bit your code to make it more readable.
Some tips for the future:
Use the Option Explicit on the top of your moduel to fource the declaration of all your variables.
Always try to declare your variables close to where they are used.
Never declare a integervariable, use Long instead. Don't use Double for rows either, Double and Single are for floating numbers.
Here is the code:
Option Explicit
Sub TaskAllocation()
Dim cell As Range
Dim SubTaskWs As Worksheet
Set SubTaskWs = ActiveWorkbook.Worksheets("Sub tasks")
Dim Lastrow1 As Long
Lastrow1 = SubTaskWs.Range("H" & Rows.Count).End(xlUp).Row
Dim ws As Worksheet
Dim cell As Range
Dim Lastrow2 As Long, i As Long
i = 0
Dim Tasks As Object
FillTasks Tasks
For Each cell In SubTaskWs.Range("H4:H" & Lastrow1) 'change this range and loop through the column with the tasks
If Tasks.Exists(cell) Then GoTo AlreadyDone
For Each ws In Sheets
If SubTaskWs.Cells(cell.Row, "H") = ws.Name Then
Lastrow2 = ws.Range("A" & Rows.Count).End(xlUp).Row + 1
copyFormattingAbove ws, "A" & Lastrow2
ws.Range("A" & Lastrow2).Value = SubTaskWs.Cells(cell.Row, 2)
ws.Range("B" & Lastrow2).Value = SubTaskWs.Cells(cell.Row, 3)
End If
Next ws
AlreadyDone:
Next cell
End Sub
Function FillTasks(Tasks As Object)
Set Tasks = CreateObject("Scripting.Dictionary")
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets 'loop through sheets
If Not ws.Name = "Sub tasks" Then
'code to find the right columnd and loop through the existing tasks
'there is no need for an item on this case, you only need to know if it exists
If Not Tasks.Exists(cell) Then Tasks.Add cell, 1
End If
Next ws
End Function
Need some assistance. I have a template that gets data exported into it from a different program. The rows of data varies from export to export and a new workbook is needed for each export.
I, currently, have a 'Master' macro written that cleans up the worksheet (formats, text to numbers, etc.) and also adds checkboxes to the end of each row that contains data. These checkboxes are linked to a cell. Once the operator completes the worksheet, they will then need to check a checkbox for each row of data that is 'out of spec'. These rows will then be copied onto the next sheet in the workbook. This is triggered by a button. My current macro works other than copying the entire row of data when I only want to copy over cells in columns 'A' through 'I'. Cells in columns 'J' and out contain data that does NOT need to be copied.
Here is my current macro that, like I said, copies the entire row:
Sub CopyRows()
Dim LRow As Long, ChkBx As CheckBox, WS2 As Worksheet
Set WS2 = Worksheets("T2 FAIR (Single Cavity)")
LRow = WS2.Range("A" & Rows.Count).End(xlUp).Row
For Each ChkBx In ActiveSheet.CheckBoxes
If ChkBx.Value = 1 Then
LRow = LRow + 1
WS2.Cells(LRow, "A").Resize(, 14) = Range("A" & _
ChkBx.TopLeftCell.Row).Resize(, 14).Value
End If
Next
End Sub
In the right-side of your equation, your Range() object is not properly qualified (with a worksheet). So, I used the fake wsX in this example.
Also, I used the ending column of "D" - but you can change to whatever you need it to be.
LRow = LRow + 1
r = ChkBx.TopLeftCell.Row
ws2.Range(ws2.Cells(LRow, "A"), ws2.Cells(LRow, "D")) = wsX.Range( _
wsX.Cells(r, "A"), wsX.Cells(r, "D"))
or
ws2.Range("A" & LRow & ":D" & LRow) = wsX.Range("A" & r & ":D" & r)
From Comment:
The templates ALWAYS start, with the imported data, in "A19". When I run this macro, to copy the checked data to the next worksheet, it starts in with cell "A18". I have no idea as to why. How do I specify that the checked data is to be copied starting with "A19" on the next worksheet?
If it's always off by one, you can just add 1. I am not sure how your layout is, so this will be something you will have to either add to LRow or r. So either
ws2.Range("A" & LRow + 1 & ":D" & LRow + 1) = ...
or
... = wsX.Range("A" & r + 1 & ":D" & r + 1)
Answer is as follows:
Sub CopyRows()
Dim ws1 As Worksheet
Set ws1 = Worksheets("T1 FAIR (Single Cavity)")
Dim ws2 As Worksheet
Set ws2 = Worksheets("T2 FAIR (Single Cavity)")
Dim LRow As Long
LRow = ws2.Range("A" & rows.count).End(xlUp).row
Dim r As Long
Dim ChkBx As CheckBox
For Each ChkBx In ws1.CheckBoxes
If ChkBx.value = 1 Then
LRow = LRow + 1
r = ChkBx.TopLeftCell.row
ws2.Range("A" & LRow + 1 & ":I" & LRow + 1).value = _
ws1.Range("A" & r & ":I" & r + 1).value
End If
Next
End Sub
I am trying to paste values from a bunch of tables into one long list. I have the tables spread across different sheets and the number of rows changes, but the columns do not. Then I am also trying to paste a string value that tells what sheet it came from, but having trouble with the active cell part of the code.
When I first tried it, it did not compile, hence why I came here, to figure out why it did not compile. Going back and forth with urdearboy, below, I was able to get the correct code working here.
I have the following:
sub copypaste()
Dim ws1 as worksheet
dim ws2 as worksheet
dim mas as worksheet
Set ws1 =ThisWorkbook.Sheets("Sheet1")
Set ws2=ThisWorkbook.Sheets("Sheet2")
Set mas=ThisWorkbook.Sheets("Master") 'where I create my list
For Each ws In Worksheets
If ws.Name <> mas.Name Then
LRow = mas.Range("A" & mas.Rows.Count).End(xlUp).Offset(1, 0).Row
wsLRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range("A2:A" & wsLRow - 1).Copy
mas.Range("A" & LRow).PasteSpecial Paste:=xlPasteValues
ws.Range("B2:B" & wsLRow - 1).Copy
mas.Range("B" & LRow).PasteSpecial Paste:=xlPasteValues
mas.Range(mas.Cells(LRow, 4), mas.Cells(wsLRow + LRow - 2, 4)) = ws.Name 'I need my sheet value in the fourth column, not the third, but simply change the col coordinate in the Cells equation above
End If
Next ws
'In order to figure out the sheet name, I used the following:
Dim rng As Range
Set rng = mas.Range("D2", Range("D2").End(xlDown))
For Each Cell In rng
If Cell.Value = "Sheet 1" Then
Cell.Value = "S1"
ElseIf Cell.Value = "Sheet 2" Then
Cell.Value = "S2"
End If
Next Cell
end sub
This will loop through all sheets, with the exception of Master, and import the values on Column A to Master accompanied by the origin of the data (sheet name).
Option Explicit for good measure.
Option Explicit
Sub copypaste()
Dim mas As Worksheet: Set mas = ThisWorkbook.Sheets("Master")
Dim ws As Worksheet, LRow As Long, wsLRow As Long
Application.ScreenUpdating = False
For Each ws In Worksheets
If ws.Name <> mas.Name Then
LRow = mas.Range("A" & mas.Rows.Count).End(xlUp).Offset(1).Row
wsLRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range("A2:A" & wsLRow).Copy mas.Range("A" & LRow)
mas.Range(mas.Cells(LRow, 2), mas.Cells(wsLRow + LRow - 2, 2)) = ws.Name
End If
Next ws
Application.ScreenUpdating = True
End Sub
To paste values change
ws.Range("A2:A" & wsLRow).Copy mas.Range("A" & LRow)
to this
ws.Range("A2:A" & wsLRow).Copy
mas.Range("A" & LRow).PasteSpecial xlPasteValues
Is there a shorter way to do this?
Like in one click and the data goes to where I want it to be?
Or maybe a shorter code for this?
Because the worksheet may vary but the details are all the same.. Please see the difference in transfersheet2 and 3...
Some cells may be blank in column C (referring to where I am copying from) but I want to copy it so that the details of each row won't be messed up. Can this be done? To copy even if it there is an empty cell?
Also, something's wrong with my second and third loop... The second one, when I click it once, it's ok but if by accident you click it again the data will duplicate.. Is there a way to stop this duplication from happening?
I tried using a message box but it's not working the way I want it to be.. I wanted the message box to appear only if I click it the second time... I think it's because of the offset I used... but I don't really know.
Sub TransferSheet1()
Dim i As Long
Dim LastRow As Long
Dim wb As Workbook
Dim sec As Worksheet
Dim sht1 As Worksheet
Set wb = ThisWorkbook
Set sec = wb.Sheets("SECOND")
Set sht1 = wb.Sheets("Sheet1")
'Find the last row (in column c) with data.
LastRow = sht1.Range("C:C").Find("*", searchdirection:=xlPrevious).row
ii = 2
'This is the beginning of the loop
For i = 6 To LastRow
'First activity
sec.Range("A" & ii) = sht1.Range("C" & i).Value
sec.Range("B" & ii) = sht1.Range("D" & i).Value
sec.Range("C" & ii) = sht1.Range("F" & i).Value
sec.Range("D" & ii) = sht1.Range("G" & i).Value
ii = ii + 1
Next i
End Sub
Private Sub GetValuesFromSheet2()
Dim i As Long
Dim ii As Long
Dim LastRow As Long
Dim wb As Workbook
Dim sec As Worksheet
Dim sht2 As Worksheet
Set wb = ThisWorkbook
Set sec = wb.Sheets("SECOND")
Set sht2 = wb.Sheets("Sheet2")
'Find the last row (in column c) with data.
LastRow = sht2.Range("C:C").Find("*", searchdirection:=xlPrevious).row
ii = 1
'This is the beginning of the loop
For i = 6 To LastRow
'First activity
sec.Range("A" & Rows.count).End(xlUp).Offset(1) = sht2.Range("C" & i).Value
sec.Range("B" & Rows.count).End(xlUp).Offset(1) = sht2.Range("D" & i).Value
sec.Range("C" & Rows.count).End(xlUp).Offset(1) = sht2.Range("F" & i).Value
sec.Range("D" & Rows.count).End(xlUp).Offset(ii, 1) = sht2.Range("G" & i).Value
ii = ii + 1
Next i
With Application
.EnableEvents = True
.DisplayAlerts = True
End With
MsgBox "Content Already copied"
End Sub
Private Sub CmdTransferSheet3_Click()
Dim i As Long
Dim ii As Long
Dim LastRow As Long
Dim wb As Workbook
Dim sec As Worksheet
Dim sht2 As Worksheet
Set wb = ThisWorkbook
Set sec = wb.Sheets("SECOND")
Set sht2 = wb.Sheets("Sheet3")
'Find the last row (in column c) with data.
LastRow = sht2.Range("C:C").Find("*", searchdirection:=xlPrevious).row
ii = 1
'This is the beginning of the loop
For i = 6 To LastRow
'First activity
sec.Range("A" & Rows.count).End(xlUp).Offset(1) = sht2.Range("C" & i).Value
sec.Range("B" & Rows.count).End(xlUp).Offset(1) = sht2.Range("D" & i).Value
sec.Range("C" & Rows.count).End(xlUp).Offset(1) = sht2.Range("F" & i).Value
sec.Range("E" & Rows.count).End(xlUp).Offset(ii,1) = sht2.Range("G" & i).Value
ii = ii + 1
Next i
End Sub