Copy the range and check for duplicates - vba

Dears,
I would like to add to the below code, the lines, which do the following:
Copy the range from Results tab and pastes it to every newly created sheet. It should be copied to the same column which is populated by the below macro.
I think we would need to add this code somewhere:
Worksheets("Results").Range("A1:A65").Copy Destination:=ActiveSheet.Range("a50:a150") ???
It should also check this column for duplicates.
Will you ba able to help?
the initial code is the following:
Sub YouShouldHavePostedAnAttemptFirst()
Dim c As Range
Dim CtRows, SheetCtr As Integer
'Try to put your data on sheet 1 then create a new sheet so that it is the
'second sheet in the workbook.
SheetCtr = 4
CtRows = Application.CountA(Sheets("2nd step").Range("r:r"))
For Each c In Range(Cells(1, 18), Cells(CtRows, 18))
c.Offset(, -10).Copy Sheets(SheetCtr).Cells(Rows.Count, "a:a").End(xlUp).Offset(1, 0)
If c.Offset(1, 0) <> c Then
Sheets.Add after:=Sheets(ActiveWorkbook.Sheets.Count)
SheetCtr = SheetCtr + 1
End If
Next c
End Sub
Thank you,

This code will copy the data from Results into your existing sheets and then create four new sheets and paste the data in there as well:
Sub PopulateSheets()
Dim wrkSht As Worksheet
Dim SheetCtr As Long, x As Long
'First go through each sheet in the workbook.
'If you want other sheets apart from 'Results' to be ignored just add them to the Case.
'e.g. Case "Results", "Sheet1" will ignore Results & Sheet1.
For Each wrkSht In ThisWorkbook.Worksheets
Select Case wrkSht.Name
Case "Results"
'Do nothing - we're copying from this sheet.
Case Else
'Copy from Results to the other worksheet.
With ThisWorkbook.Worksheets("Results")
.Range("A1:A65").Copy Destination:=wrkSht.Range("A50")
End With
End Select
Next wrkSht
'Creates 4 sheets, copies the data over and moves the sheet to the end.
SheetCtr = 4
With ThisWorkbook
For x = 1 To SheetCtr
Set wrkSht = ThisWorkbook.Worksheets.Add
.Worksheets("Results").Range("A1:A65").Copy Destination:=wrkSht.Range("A50")
wrkSht.Move After:=Sheets(.Sheets.Count)
Next x
End With
End Sub
If you just want to copy the data when a new sheet is added -
In a normal module add the below code. The procedure takes a reference to a worksheet and copies the data from the Results sheet to it and removes any duplicates.
Public Sub CopyToNewSheet(sht As Worksheet)
With sht
ThisWorkbook.Worksheets("Results").Range("A1:A65").Copy Destination:=.Range("A50")
.Range("A50:A114").RemoveDuplicates Columns:=1, Header:=xlNo
End With
End Sub
In the ThisWorkbook module add the below code. This checks that you're adding a worksheet rather than a chart sheet or any other type and passes the sheet reference to the CopyToNewSheet procedure:
Private Sub Workbook_NewSheet(ByVal Sh As Object)
If Sh.Type = xlWorksheet Then
CopyToNewSheet Sh
End If
End Sub

Related

Loop through worksheets and paste code

Hi I have code which is meant to
Loop through all worksheets which begin with "673"
Copy all the rows which have data from row 5 onwards
Paste the entries on the next empty row in the "Colours" worksheet
I'm having the following issues:
Code only runs in the worksheet that is active
Doesn't loop through all worksheets
When it pastes in the "Colours" worksheet, it pastes directly over the headings in row 2. The first blank row is row 3 onwards and I would like the logic to paste at the next available blank row as it loops through the sheets.
Sub Consolidate()
Dim lastrow As Long
Dim report As Worksheet
Set report = Excel.ActiveSheet
For Each Sheet In ActiveWorkbook.Worksheets
If InStr(Sheet.Name, "673") > 0 Then
With report
.Range(.Cells(5, "K"), .Cells(.Rows.Count, "K").End
(xlUp)).EntireRow.Copy
End With
Worksheets("Colours").Select
lastrow = Worksheets("Colours").Cells(Worksheets("Colours").Rows.Count, 1).End(xlUp).Row
Worksheets("Colours").Cells(lastrow + 1, 1).Select
ActiveSheet.Paste
End If
Next
End Sub
Your help would be greatly appreciated.
KS is right, to get your code functioning you just need to reference the sheet. I'd started modifying it further so I'll post what I've done in totality:
Firstly I removed the 'Set report = ' line, that's not needed (alternatively you could have 'Set report' at the beginning of the loop, but it's easier to work directly 'With Sheet' as KS says).
CHANGED1 = You said it should loop through worksheets that 'begin' with 673, so this new line checks for the first three characters matching 673, rather than just looking to see if 673 appears anywhere in the sheet name.
NEW = Activates the sheet, this makes the next copy command work.
CHANGED2 = With Sheet as explained above.
CHANGED3 = You said it should copy the rows that have data from row 5 onwards (previously your code would copy rows 1-5).
Sub Consolidate()
Dim lastrow As Long
Dim report As Worksheet
For Each Sheet In ActiveWorkbook.Worksheets
If Left(Sheet.Name, 3) = "673" Then 'CHANGED1
Worksheets(Sheet.Name).Select 'NEW
With Sheet 'CHANGED2
.Range("A5", Range("A" & 65536).End(xlUp)).EntireRow.Copy 'CHANGED3
End With
Worksheets("Colours").Select
lastrow = Worksheets("Colours").Cells(Worksheets("Colours").Rows.Count, 1).End(xlUp).Row
Worksheets("Colours").Cells(lastrow + 1, 1).Select
ActiveSheet.Paste
End If
Next
End Sub
Hope this helps!
try the following code
Sub Consolidate()
Dim sheet As Worksheet, coloursSheet As Worksheet
Set coloursSheet = ActiveWorkbook.Worksheets("Colours")
For Each sheet In ActiveWorkbook.Worksheets
If Left(sheet.Name, 3) = "673" Then
sheet.Range("K5:K" & sheet.Cells(sheet.Rows.Count, "K").End(xlUp).Row).SpecialCells(xlCellTypeConstants).EntireRow.Copy _
Destination:=coloursSheet.Cells(coloursSheet.Rows.Count, "A").End(xlUp).Offset(1)
End If
Next
End Sub
it:
avoids useless selections and variables
copies non blank cells only (assuming data are "constants", i.e. not formulas)

Add Worksheet name to first six rows

I have a large numbers of worksheets in a Workbook.
I want to insert a new row at the top of each worksheet (A:A) and insert the name of each worksheet into cells (B1:G1) for all worksheets.
I have the first portion, but am a little stuck on the second part (i.e., adding the worksheet name). I would appreciate some help.
Corrected CODE:
Sub NameSheets()
Dim sheetnm() As String
ReDim sheetnm(1 To Sheets.Count)
Dim i As Long
Dim ws As Worksheet
For i = 1 To Sheets.Count
Sheets(i).Rows("1:1").Insert Shift:=xlDown
sheetnm(i) = Sheets(i).Name
Sheets(i).Range("B1:G1") = Sheets(i).Name
Next i
End Sub
Range ("B1:G1") = ActiveSheet.name . This will add the current worksheet name to all 6 columns
I modified your code. Try this:
Dim sheet As Worksheet
For Each sheet In Worksheets
sheet.Rows("1:1").Insert Shift:=xlDown
sheet.Range("B1:G1").Value = sheet.Name
Next sheet
This will cycle through the sheets twice. The first to add the first row and create an array of the sheet names. The second to input that list in the first row starting in B1:
Sub NameSheets()
Dim sheetnm() As String
ReDim sheetnm(1 To Sheets.Count)
Dim i As Long
For i = 1 To Sheets.Count
Sheets(i).Rows("1:1").Insert Shift:=xlDown
sheetnm(i) = Sheets(i).Name
Next i
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ws.Range("B1").Resize(, UBound(sheetnm)).Value = sheetnm
Next ws
End Sub

Paste worksheet names in multiple worksheets

I have a workbook with over 50 worksheets. I would like to copy the name of each worksheet into a cell of that particular workbook. I can do it for one sheet at a time using a macro with the following VBA code:
Range("B1") = ActiveSheet.Name
But when I try to apply the macro to several worksheets at a time, it fails. I would like it to get the names of the first 30 worksheets only.
Avoid relying on the ActiveSheet property to identify the worksheet you want to process. The With ... End With statement can readily provide the worksheet and help retrieve the Worksheet .Name property.
Sub name_Worksheets()
Dim w As Long
For w = 1 To 30
With Worksheets(w)
.Cells(1, 2) = .Name
End With
Next w
End Sub
See How to avoid using Select in Excel VBA macros for more methods on getting away from relying on select and activate to accomplish your goals.
My Understanding is you want to 1) Go through first 30 sheets of your workbook and 2) Paste the sheet name into cell B1.
Sub PasteSheetNameInB1()
For i = 1 To 30 '(1 to 30 because you said " I would like it to get the names of the first 30 worksheets only.")
ActiveWorkbook.Sheets(i).Select 'Iterates through first 30 sheets
Range("B1") = ActiveSheet.Name 'Pastes Sheet name into B1
Next i
End Sub
You can use this code:
For i = 1 To 30
Sheets(i).Range("B1").Formula = "=MID(CELL(""filename"",A1),FIND(""]"",CELL(""filename"",A1))+1,255)"
Next
Now if you change the name of any worksheet, You don't need to run the macro again, the formula in Rnage("B1") will display the new name.
So with this code, that you'll paste in the destination workbook,
you'll just need to change :
workbook_to_scan's Name and
Sheet's name in which to paste the names
to fit your needs!
Sub test_johnB()
Dim wB1 As Workbook, _
wB2 As Workbook, _
wSDest As Worksheet, _
wS As Worksheet, _
i As Integer
Set wB1 = ThisWorkbook
Set wB2 = Workbooks("workbook_to_scan's Name")
Set wSDest = wB1.Sheets("Sheet's name in which to paste the names")
i = 0
For Each wS In wB2.Sheets
wSDest.Range("B1").Offset(i, 0) = wS.Name
Next wS
End Sub

Allow append of data to a summary sheet in another workbook

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.

Selecting non-blank cells in Excel with VBA

I'm just beginning to dive into VBA and I've hit a bit of a roadblock.
I have a sheet with 50+ columns, 900+ rows of data. I need to reformat about 10 of those columns and stick them in a new workbook.
How do I programmatically select every non-blank cell in a column of book1, run it through some functions, and drop the results in book2?
I know I'm am very late on this, but here some usefull samples:
'select the used cells in column 3 of worksheet wks
wks.columns(3).SpecialCells(xlCellTypeConstants).Select
or
'change all formulas in col 3 to values
with sheet1.columns(3).SpecialCells(xlCellTypeFormulas)
.value = .value
end with
To find the last used row in column, never rely on LastCell, which is unreliable (it is not reset after deleting data). Instead, I use someting like
lngLast = cells(rows.count,3).end(xlUp).row
The following VBA code should get you started. It will copy all of the data in the original workbook to a new workbook, but it will have added 1 to each value, and all blank cells will have been ignored.
Option Explicit
Public Sub exportDataToNewBook()
Dim rowIndex As Integer
Dim colIndex As Integer
Dim dataRange As Range
Dim thisBook As Workbook
Dim newBook As Workbook
Dim newRow As Integer
Dim temp
'// set your data range here
Set dataRange = Sheet1.Range("A1:B100")
'// create a new workbook
Set newBook = Excel.Workbooks.Add
'// loop through the data in book1, one column at a time
For colIndex = 1 To dataRange.Columns.Count
newRow = 0
For rowIndex = 1 To dataRange.Rows.Count
With dataRange.Cells(rowIndex, colIndex)
'// ignore empty cells
If .value <> "" Then
newRow = newRow + 1
temp = doSomethingWith(.value)
newBook.ActiveSheet.Cells(newRow, colIndex).value = temp
End If
End With
Next rowIndex
Next colIndex
End Sub
Private Function doSomethingWith(aValue)
'// This is where you would compute a different value
'// for use in the new workbook
'// In this example, I simply add one to it.
aValue = aValue + 1
doSomethingWith = aValue
End Function
If you are looking for the last row of a column, use:
Sub SelectFirstColumn()
SelectEntireColumn (1)
End Sub
Sub SelectSecondColumn()
SelectEntireColumn (2)
End Sub
Sub SelectEntireColumn(columnNumber)
Dim LastRow
Sheets("sheet1").Select
LastRow = ActiveSheet.Columns(columnNumber).SpecialCells(xlLastCell).Row
ActiveSheet.Range(Cells(1, columnNumber), Cells(LastRow, columnNumber)).Select
End Sub
Other commands you will need to get familiar with are copy and paste commands:
Sub CopyOneToTwo()
SelectEntireColumn (1)
Selection.Copy
Sheets("sheet1").Select
ActiveSheet.Range("B1").PasteSpecial Paste:=xlPasteValues
End Sub
Finally, you can reference worksheets in other workbooks by using the following syntax:
Dim book2
Set book2 = Workbooks.Open("C:\book2.xls")
book2.Worksheets("sheet1")
For me the best way to proceed was to:
Create a new Excel Table
AutoFilter it by the parameter Criterial:="<>"
An example of the code would be:
Sub ExampleFilterCol()
' Create a Table
Dim ws As Worksheet
Dim rg As Range
Set ws = ActiveSheet
Set rg = ws.Range("A1").CurrentRegion
ws.ListObjects.Add(xlSrcRange, rg, , xlYes).Name = "myNonRepeatedTableName"
' Filter the created table
Dim Io As ListObject
Dim iCol As Long
' Set reference to the first Table on the sheet
' That should be the recently created one
Set lo = Sheets("Totalinfo").ListObjects(1)
' Set filter field
iCol = lo.ListColumns("yourColumnNameToFilter").Index
' Non-blank cells – use NOT operator <>
lo.Range.AutoFilter Field:=iCol, Criteria1:="<>"
End Sub
This might be completely off base, but can't you just copy the whole column into a new spreadsheet and then sort the column? I'm assuming that you don't need to maintain the order integrity.