I have a workbook with one main index sheet and a template sheet.
I have information in my index sheet.
Each line in the main sheet should generate a new sheet.
I want to duplicate the template with all the data in there, but with a name from each line from main sheet.
I can create the sheets with the right names, but with zero data in them.
This is the VBA code to make a new sheet with the right name. I need to copy all the data into all the new sheets. It comes from this blog post by Oscar Cronquist:
'Name macro
Sub CreateSheets()
'Dimension variables and declare data types
Dim rng As Range
Dim cell As Range
'Enable error handling
On Error GoTo Errorhandling
'Show inputbox to user and prompt for a cell range
Set rng = Application.InputBox(Prompt:="Select cell range:", _
Title:="Create sheets", _
Default:=Selection.Address, _
Type:=8)
'Iterate through cells in selected cell range
For Each cell In rng
'Check if cell is not empty
If cell <> "" Then
'Insert worksheet and name the worksheet based on cell value
Sheets.Add.Name = cell
End If
'Continue with next cell in cell range
Next cell
'Go here if an error occurs
Errorhandling:
'Stop macro
End Sub
Create Template Worksheets
Sub CreateTemplateWorksheets()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ash As Object: Set ash = wb.ActiveSheet
Dim lws As Worksheet: Set lws = wb.Worksheets("Main Index")
Dim lrg As Range
Set lrg = lws.Range("A2", lws.Cells(lws.Rows.Count, "A").End(xlUp))
Dim sws As Worksheet: Set sws = wb.Worksheets("Template")
Dim lCell As Range
Dim dws As Worksheet
Dim dwsCount As Long
Dim dName As String
For Each lCell In lrg.Cells
dName = CStr(lCell.Value)
If Len(dName) > 0 Then
On Error Resume Next
Set dws = wb.Worksheets(dName)
On Error GoTo 0
If dws Is Nothing Then
sws.Copy After:=wb.Sheets(wb.Sheets.Count)
Set dws = ActiveSheet
dws.Name = dName
dwsCount = dwsCount + 1
End If
Set dws = Nothing
End If
Next lCell
ash.Select
MsgBox "Worksheets created: " & dwsCount, vbInformation
End Sub
Related
Hello all I did a macro in VBA that should check column D for the first empty cell then paste on that row but on column C, and when adding new info in the table it should take the first empty cell again, but it is replacing data, I don't check column C for first row because I have an filled cell midway, and if data were to replace that cell it should add a new row and avoid that.
`Sub CopyPasteToAnotherSheet()
Dim sourceRange As Range
Dim targetRange As Range
Dim lastRow As Long
Dim firstEmptyRow As Long
Set sourceRange = Selection
Set targetRange = Sheets("PARKING").Range("D18")
lastRow = targetRange.End(xlDown).Row
firstEmptyRow = Sheets("PARKING").Range("D" & lastRow).End(xlUp).Row + 1
If lastRow = targetRange.Row Then
targetRange.EntireRow.Insert
End If
If Sheets("PARKING").Range("C" & firstEmptyRow).Value <> "" Then
firstEmptyRow = firstEmptyRow + 1
End If
Set targetRange = Sheets("PARKING").Range("C" & firstEmptyRow)
sourceRange.Copy
targetRange.PasteSpecial xlPasteValues
End Sub
`
I have tried to work with different search ranges but it keeps overwriting data.
also if it would keep numbering the newly added rows when adding new data it would be great I am clueless on how I should do that
Append Values
Sub AppendValues()
Const PROC_TITLE As String = "Append Values"
Const DST_NAME As String = "PARKING"
Const DST_FIRST_CELL As String = "C18"
If Selection Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf Selection Is Range Then Exit Sub ' not a range
Dim srg As Range: Set srg = Selection
Dim sws As Worksheet: Set sws = srg.Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
If Not sws.Parent Is wb Then Exit Sub ' not in this workbook
Dim dws As Worksheet: Set dws = wb.Sheets(DST_NAME)
If sws Is dws Then Exit Sub ' src. and dst. are the same worksheet
If dws.FilterMode Then dws.ShowAllData ' '.Find' will fail if 'dws' filtered
Dim dfCell As Range: Set dfCell = dws.Range(DST_FIRST_CELL)
Dim dlCell As Range
Set dlCell = dws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If Not dlCell Is Nothing Then
Set dfCell = dfCell.Offset(dlCell.Row - dfCell.Row + 1)
End If
Dim sarg As Range
For Each sarg In srg.Areas
dfCell.Resize(sarg.Rows.Count, sarg.Columns.Count).Value = sarg.Value
Set dfCell = dfCell.Offset(sarg.Rows.Count)
Next sarg
MsgBox "Values appended to worksheet """ & DST_NAME & """.", _
vbInformation, PROC_TITLE
End Sub
Hi I have created macro where it opens the sheet based on user input,
what I need is once the new sheet is opened I have some fields where user need to fill those data(Different subjects marks) and calculate the percentage using formula then I need to fill those data to another sheet named "Data" without overwriting previous data?.
Please suggest how to add data without overwriting in vba.
Sub open_sheet()
Dim sourcesheet As Worksheet
Dim ClassA As Worksheet
Dim ClassB As Worksheet
Dim ClassC As Worksheet
Set sourcesheet = Sheets("Main")
Set ClassA = Sheets("Class A")
Set ClassB = Sheets("Class B")
Set ClassC = Sheets("Class C")
If sourcesheet.Range("Class").Value = "Class A" Then
Worksheets("Class A").Activate
ElseIf sourcesheet.Range("Class").Value = "Class B" Then
Worksheets("Class B").Activate
Else:
Worksheets("Class C").Activate
End If
End Sub
Copy Cell Values to Another Worksheet
Option Explicit
Sub CopyData()
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source worksheet.
Dim sws As Worksheet: Set sws = wb.Sheets("Main")
' Reference the source range (the values from these cells will be copied).
Dim srg As Range: Set srg = sws.Range("A3,B4,C5")
' Retrieve the destination worksheet name.
' Hopefully you have created a drop down to easily select the class.
Dim dName As String: dName = sws.Range("Class").Value
' Late at night (tired), a final check could become a life saver:
Dim Msg As Long
Msg = MsgBox("This will copy to """ & dName & """." & vbLf & vbLf _
& "Are you sure?", vbQuestion + vbYesNo)
If Msg = vbNo Then Exit Sub
' Reference the destination worksheet.
Dim dws As Worksheet: Set dws = wb.Sheets(dName)
If dws.FilterMode Then dws.ShowAllData ' 'Find' will fail if 'dws' filtered
' Reference the first (available) destination cell.
Dim dCell As Range ' First Destination Cell
With dws.UsedRange
Dim dlCell As Range ' Last Cell
Set dlCell = .Find("*", , xlFormulas, , xlByRows, xlPrevious)
If dlCell Is Nothing Then Exit Sub ' empty worksheet
Set dCell = dws.Cells(dlCell.Row + 1, "A") ' below last in column 'A'
End With
' Copy the values from the source to the destination cells.
Dim sCell As Range
For Each sCell In srg.Cells
dCell.Value = sCell.Value
Set dCell = dCell.Offset(, 1) ' next, adjacent to the right
Next sCell
MsgBox "Data copied.", vbInformation
End Sub
In general, here's a way to append info to a table. I would just put your average calculations in the table total row.
Option Explicit
Sub FillNewRow1()
Dim Class_A As Worksheet
Dim ClassName As String
Dim DataRange
Dim lRow As Long
ClassName = Worksheets("Master").Range("B2").Value
Set Class_A = ThisWorkbook.Worksheets(ClassName)
DataRange = Worksheets("Master").Range("B5:B8")
lRow = Class_A.Range("A" & Rows.Count).End(xlUp).Row + 1
Class_A.Range("A" & lRow).Resize(1, UBound(DataRange, 1)).Value = _
Application.Transpose(DataRange)
End Sub
But seeing as we have no idea what your source od destination data look like that's the best help I can give.
Suplimentary :
PivotCharts & Pivot Tables are awesome:
I have a code that retrieves data from those sheets that are not hidden to a summary sheet. Issue is that the other sheets contain both list drop down menus and some of them contain IF statements based on the input. But no "real" data populated into those cells if not specified.
The summary sheet is expected to only retrieve those rows with actual data specified in it. The sheets contain borders, so perhaps that could be an issue?
Sub CreateSummary()
Const dName As String = "Summary"
Const dFirstCellAddress As String = "A1"
Const sColsAddress As String = "B:N"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Application.ScreenUpdating = False
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
dws.Move After:=wb.Sheets(wb.Sheets.Count)
dws.UsedRange.Clear
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim sws As Worksheet
Dim srg As Range
Dim i As Long
Dim n As Long
For i = 1 To Worksheets.Count - 1 ' exclude 'dws' (last worksheet)
Set sws = wb.Worksheets(i)
If sws.Visible = xlSheetVisible Then
n = n + 1
Set srg = Intersect(sws.UsedRange, sws.Columns(sColsAddress))
If n > 1 Then ' all but the first worksheet; exclude headers
Set srg = srg.Resize(srg.Rows.Count - 1).Offset(1)
Else ' first worksheet
srg.Rows(1).Copy
dfCell.PasteSpecial xlPasteColumnWidths
End If
srg.Copy dfCell
Set dfCell = dfCell.Offset(srg.Rows.Count)
'Else ' worksheet is not visible; do nothing
End If
Next i
Application.Goto Reference:=dws.Cells(1), Scroll:=True
Application.ScreenUpdating = True
MsgBox "Summary created.", vbInformation
End Sub
This Excel function within a VBA code can determine if a row is empty or it has atleast 1 cell filled.
If WorksheetFunctions.CountA(sws.Rows(rownumber)) > 0 then
'This row has value in atleast a column
End If
I'm trying to create a macro that copies a certain range (CA1:CZ99) from "Sheet A" to lots of other sheets. The names of the other sheets are based on a value of column F in "Sheet B".
The code for copying the data is easy to find.
Worksheets("Sheet A").Range("CA1:CZ99").Copy Worksheets("Sheet X").Range("CA1")
But how do I loop this part over all the sheets from column F?
Copy a Range to Multiple Worksheets
Option Explicit
Sub CopyRange()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets("Sheet A")
Dim srg As Range: Set srg = sws.Range("CA1:CZ99")
' Lookup
Dim lws As Worksheet: Set lws = wb.Worksheets("Sheet B")
Dim lfRow As Long: lfRow = 2
Dim llRow As Long: llRow = lws.Cells(lws.Rows.Count, "F").End(xlUp).Row
If llRow < lfRow Then Exit Sub ' no data
Dim lrg As Range: Set lrg = lws.Cells(lfRow, "F").Resize(llRow - lfRow + 1)
' Copy to Destination
Dim dws As Worksheet
Dim lCell As Range
Dim lCount As Long
For Each lCell In lrg.Cells
On Error Resume Next ' check if the worksheet exists
Set dws = wb.Worksheets(CStr(lCell.Value))
On Error GoTo 0
If Not dws Is Nothing Then ' the worksheet exists
lCount = lCount + 1
srg.Copy dws.Range("CA1")
Set dws = Nothing
'Else ' the worksheet doesn't exist
End If
Next lCell
' Inform
MsgBox "Range copied to " & lCount & " worksheets.", _
vbInformation, "CopyRange"
End Sub
Specify exactly where to get the data from as a variable, and then loop over it. Example:
Sub loopCopy()
Dim shtRng As Range
Dim c As Variant
Set shtRng = Worksheets("Sheet B").Range("F1:F5")
For Each c In shtRng
Worksheets("Sheet A").Range("CA1:CZ99").Copy Worksheets(c.Value).Range("CA1")
Next c
End Sub
This is a very basic setup. If the value from the column doesn't match a sheet, or if "Sheet A" or "Sheet B" change names, it will crash.
You might want to have the list adjust in size dynamically by finding last row, etc.
my code aims to copy the same range from multiple sheets and paste the data from each sheet into the next empty column in a Combined sheet. My code copies from each sheet correctly, but pastes into the same column and overwrites the preceding paste.
Could someone please point out my error?
Many thanks!
Sub CopyToNextCol()
Dim Sh As Worksheet
Dim NextCol As Long
For Each Sh In ThisWorkbook.Worksheets
If Sh.Name <> "Master" And Sh.Name <> "Lists" And Sh.Name <> "Combined" Then
NextCol = Sheets("Combined").Cells(, Columns.Count).End(xlToLeft).Column + 1
Sh.Range("B2:B44").Copy Sheets("Combined").Cells(, NextCol)
End If
Next Sh
End Sub
Copy Same Ranges From Multiple Worksheets
The following example will copy the worksheet names ("I am planning to use a different column header" in the comments) in the first row and each range below it.
s - Source, d - Destination.
A Quick Fix
Option Explicit
Sub CopyToNextCol()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = wb.Worksheets("Combined")
Dim dCell As Range
Set dCell = dws.Cells(1, dws.Columns.Count).End(xlToLeft).Offset(, 1)
Dim sws As Worksheet
Dim srg As Range
For Each sws In wb.Worksheets
Select Case sws.Name
Case "Master", "Lists", "Combined"
' Skip (do nothing)
Case Else
Set srg = sws.Range("B2:B44")
dCell.Value = sws.Name
srg.Copy dCell.Offset(1)
Set dCell = dCell.Offset(, 1)
End Select
Next sws
'wb.Save
End Sub