Efficiently import multiple spreadsheets into one master sheet using Excel VBA - vba

I am new to VBA and I have some code which I have written and although it works I think it is bulky and not very good should a change ever need to be made to it.
The code opens a spreadsheet, runs a Function (Called "LastRow") to copy the data and another (Called "NxtRow")to paste it into the next empty row of the spreadsheet with the macro then closes the sheet that the data was copied from and moves on to the next one. Basically it is concatenating multiple sheets into one.
I am thinking that there must be a way to write the code to call the functions once and then loop through each sheet in a list. Is this possible?
My code is:
NxtRow() Function
Public Function NxtRow()
Dim BlankRow As Long
Windows("GA_BudgetTool_MASTER.xlsm").Activate
BlankRow = Range("A" & Rows.Count).End(xlUp).Row + 1
Cells(BlankRow, 1).Select
ActiveSheet.Paste
BlankRow = Range("A" & Rows.Count).End(xlUp).Row + 1
Cells(BlankRow, 1).Select
End Function
LstRow() Function
Public Function LastRow()
Dim LstRow As Long, LstCol As Long, Rng As Range, A3 As Range
LstRow = Range("A" & Rows.Count).End(xlUp).Row
LstCol = Range("O" & LstRow).Column
Set Rng = Range(Cells(LstRow, 1), Cells(LstRow, LstCol))
Set A3 = Range("A3")
Range(A3, Rng).Select
Selection.Copy
End Function
VBA Sub()
Sub ImpData()
' Deactivate Screen Updating and Display Alerts
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' Import Worksheet 1
Workbooks.Open Filename:= _
"Worksheet1_Filename.xlsx"
LastRow
NxtRow
Windows("Worksheet1.xlsx").Activate
ActiveWindow.Close
' Import Worksheet 2
Workbooks.Open Filename:= _
"Worksheet2_Filename.xlsx"
LastRow
NxtRow
Windows("Worksheet2.xlsx").Activate
ActiveWindow.Close
' Import Worksheet 3
Workbooks.Open Filename:= _
"Worksheet3_Filename.xlsx"
LastRow
NxtRow
Windows("Worksheet3.xlsx").Activate
ActiveWindow.Close
This goes on in this fashion for about 30 sheets. Is there an easier way to write this and make it easier to amend later if needed?

I would just make a little array of your filenames and then use a for loop to repeat the function calls as many times as necessary
Sub ImpData()
'Deactivate Screen Updating and Display Alerts
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
Dim filenames As Variant
filenames = Array("file1", "file2")
For i = 1 To UBound(filenames) + 1
Workbooks.Open Filename:=filenames(i - 1)
LastRow
NxtRow
Windows("Worksheet" & i & ".xlsx").Activate
ActiveWindow.Close
Next i
'Reactivate Screen Updating and Display Alerts
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub

Related

VBA: copying data into a new sheet while keeping it relative

I have two sheets in my excel file - one consists of Backend Data on clients (date, quantity, rate, etc) and the other is a Summary sheet which only lists this information if the transaction is 'OPEN'. So the Backend Data sheet has a column saying whether the transaction is OPEN and if it is, it is copied to the Summary sheet. So basically the Summary sheet has a changing number of rows. This is the code I have for that (PS. it works). This code basically copy pastes the info if the transaction is OPEN and deletes the info if the transaction is no longer OPEN and then deletes any blank rows.
My main issue is that:
I want this code to be relative such that I can insert rows above and below in the Summary Sheet w/o affecting the data.
If data exists outside the Summary Sheet, I don't want it to be erased. Basically, I want the code to work only within a specific range of cells (will a Named Range help?)
Option Explicit
Sub Main()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim Last_Row2 As Long, i As Integer
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
With ws2
For i = 1 To Last_Row2 Step 1
If .Range("F" & i).Value = "OPEN" Then
' copy pastes the info if the transaction is OPEN
ws2.Range("B" & i, "E" & i).Copy
ws1.Range("A" & i, "D" & i).PasteSpecial
ElseIf .Range("F" & i).Value = "" Then
' deletes the info if the transaction is no longer OPEN
ws1.Range("A" & i, "D" & i).ClearContents
End If
Next i
End With
Application.ScreenUpdating = True
' deletes blank rows in Summary Sheet
Dim iCounter As Long
Worksheets("Sheet1").Range("A3:D50").Select
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
For iCounter = Selection.Rows.Count To 1 Step -1
If WorksheetFunction.CountA(Selection.Rows(iCounter)) = 0 Then
Selection.Rows(iCounter).EntireRow.Delete
End If
Next iCounter
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
ws1.Cells(1, 1).Select
End Sub

Copy and paste rows from one to another worksheet VBA

I know already a few people had that problem but their solutions did not help me. I am pretty new to VBA and I want to copy a row if the respective first cell is not empty to another file and iterate as long as the data is.
So far so good. My code runs the first time and actually works (for one line). But then the macro does not open the file again and spits out an error. If I want to manually open the target file it says: "Removed Feature: Data Validation from /xl/worksheets/sheet2.xml part" (and I think this is the reason why it does not iterate further). Do you have any idea what I can do?
Sub transferData()
Dim LastRow As Long, i As Integer, erow As Long
LastRow = ActiveSheet.Range("BC" & Rows.Count).End(xlUp).Row
For i = 3 To LastRow
If IsEmpty(Cells(i, 63).Value) = False Then
Range(Cells(i, 55), Cells(i, 63)).Select
Selection.Copy
Workbooks.Open Filename:="PATH.xlsx"
Worksheets("NewProjects").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Cells(erow, 1).Select
ActiveSheet.PasteSpecial
ActiveSheet.Sort.SortFields.Clear
ActiveWorkbook.Save
ActiveWorkbook.Close SaveChanges:=False
Application.CutCopyMode = False
End If
Next i
End Sub
Data Validation for the file is corrupt (dropdown lists) - either delete Data Validation, or fix it
Once the file is fixed, the code bellow will copy the data without opening the destination file multiple times. It AutoFilters current sheet for empty values in column BK (63), and copies all visible rows, from columns BC to BK, to the end of the new file (starting at first unused cell in column A)
Option Explicit
Public Sub TransferData()
Const OLD_COL1 = "BC"
Const OLD_COL2 = "BK"
Const NEW_COL1 = "A"
Dim oldWb As Workbook, oldWs As Worksheet, oldLR As Long
Dim newWb As Workbook, newWs As Worksheet, newLR As Long
On Error Resume Next 'Expected errors: new file not found, new sheet name not found
Set oldWb = ThisWorkbook
Set oldWs = ActiveSheet 'Or: Set oldWs = oldWb.Worksheets("Sheet2")
oldLR = oldWs.Cells(oldWs.Rows.Count, OLD_COL1).End(xlUp).Row
Application.ScreenUpdating = False
Set newWb = Workbooks.Open(Filename:="PATH.xlsx")
Set newWs = newWb.Worksheets("NewProjects")
If Not newWs Is Nothing Then
newLR = newWs.Cells(oldWs.Rows.Count, NEW_COL1).End(xlUp).Row
With oldWs.Range(oldWs.Cells(2, OLD_COL2), oldWs.Cells(oldLR, OLD_COL2))
.AutoFilter Field:=1, Criteria1:="<>"
If .SpecialCells(xlCellTypeVisible).Cells.Count > 2 Then
oldWs.Range(oldWs.Cells(3, OLD_COL1), oldWs.Cells(oldLR, OLD_COL2)).Copy
newWs.Cells(newLR + 1, NEW_COL1).PasteSpecial
Application.CutCopyMode = False
newWs.Sort.SortFields.Clear
newWb.Close SaveChanges:=True
Else
newWb.Close SaveChanges:=False
End If
.AutoFilter
End With
End If
Application.ScreenUpdating = True
End Sub

How to save to the next available row instead of replacing it

I had tried to use VBA to help grab values from a Excel form into a another workbook (Which is blank inside for now) here is the VBA code I'm using:
Sub RunMe()
Dim lRow, lCol As Integer
Sheets("Sheet1").Select
lRow = Range("A" & Rows.Count).End(xlUp).Row
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For Each cell In Range(Cells(1, "B"), Cells(1, lCol))
Union(Range("A1:A" & lRow), Range(Cells(1, cell.Column), Cells(lRow, cell.Column))).Copy
Workbooks.Add
Range("A1").PasteSpecial
ActiveWorkbook.SaveAs Filename:= _
"C:\Users\john\Desktop\Testforvba" & cell.Value & ".xls"
ActiveWorkbook.Close
Next cell
Application.CutCopyMode = False
End Sub
But the thing is that when I run this code after inputting a sample value on the form and manually run the macro, it works as it creates a new file and store the sample data I had type on the Form workbook.
But once I tried running the macro again, I realised that it recreates the file AGAIN which means it replace all the previous data. VBA is so dang hard lol. Anyone please give a hand thanks.
P.S The macro I stored in my personal Workbook
Try this one:
Option Explicit
Sub RunMe()
Application.ScreenUpdating = False
Dim lRow As Long, lCol As Long
Dim wb As Workbook, wbNew as Workbook
Dim ws As Worksheet, wsNew as Worksheet
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
lRow = ws.Range("A" & Rows.Count).End(xlUp).Row
lCol = ws.Cells(1, Columns.Count).End(xlToLeft).Column
Dim cell As Variant
For Each cell In ws.Range(ws.Cells(1, "B"), ws.Cells(1, lCol))
Union(ws.Range("A1:A" & lRow), ws.Range(ws.Cells(1, cell.Column), ws.Cells(lRow, cell.Column))).Copy
Set wbNew = Workbooks.Add
Set wsNew = wbNew.Sheets("Sheet1")
Dim yourdesktopaddress As String
yourdesktopaddress = CreateObject("WScript.Shell").specialfolders("Desktop") & "\Testforvba"
wsNew.Range("A1").PasteSpecial
If Not Dir(yourdesktopaddress & "\" & cell.Value & ".xls", vbDirectory) = vbNullString Then
'MsgBox "exists"
Application.DisplayAlerts = False
Else
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:= _
yourdesktopaddress & "\" & cell.Value & ".xls"
End If
wbNew.Close
Application.DisplayAlerts = True
Next cell
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
The main issue was, whenever macro runs, Excel was creating the files from zero and this was causing Excel to recreate each file again. I have added that If Not Dir(yourdesktopaddress & "\Testforvba" & cell.Value & ".xls", vbDirectory) = vbNullString part of my code to check whether did this file already created or not, if not it's creating the file now. If you delete the "'" from the beginning of 'MsgBox "exists" it will always tell you that this file is already exist.
Also In the case of variables are not defined well, excel might start to overwrite itself and it may replace the previous data. (Especially Range("A1).PasteSpecial and Activeworkbook.close kind of critical points are most important ones) So I also edited whole code,defined all variables, defined the user's desktop address to ensure code works on every user.

VBA codes could not run in marco enabled file type

Sorry that I am new to VBA, thanks to all the experts here I am able to copy some of the codes and modify them to suit my needs. Basically, they are just a couple of command buttons which carry out various functions. It work out fine in my excel 2010. However, when I try to save the file in my another computer with Excel 2007 (Confirmed that vba is running), a message popup saying
"The following Features cannot be saved in a macro-free workbooks:
VB Project
To save a file with these features, click no, and then choose a macro-enabled file type..."
Even I clicked no and then save it as xlsm. When I opened the file, all the vba codes are disabled. I just wonder whether it is due to any line of the following codes that could not be run in excel 2007. Many thanks for your help!
Apologies for the codes being a mess.
Private Sub CommandButton1_Click()
' Defines variables
Dim Wb1 As Workbook, Wb2 As Workbook
' Disables screen updating to reduce flicker
Application.ScreenUpdating = False
' Sets Wb1 as the current (destination) workbook
Set Wb1 = ThisWorkbook
' Sets Wb2 as the defined workbook and opens it - Update filepath / filename as required
Set Wb2 = Workbooks.Open("\\new_admin\MASTER_FILE.xlsx")
' Sets LastRow as the first blank row of Wb1 Sheet1 based on column A (requires at least header if document is otherwise blank)
lastrow = Sheets(1).Cells(Rows.count, "A").End(xlUp).Row + 1
' With workbook 2
With Wb2
' Activate it
.Activate
' Activate the desired sheet - Currently set to sheet 1, change the number accordingly
.Sheets(1).Activate
' Copy the used range of the active sheet
.ActiveSheet.UsedRange.Copy
End With
' Then with workbook 1
With Wb1.Sheets(1)
' Activate it
.Activate
' Select the first blank row based on column A
.Range("A1").Select
' Paste the copied data
.Paste
End With
' Close workbook 2
Wb2.Close
' Re-enables screen updating
Application.ScreenUpdating = False
End Sub
Private Sub CommandButton2_Click()
' Defines variables
Dim Wb1 As Workbook, Wb2 As Workbook
' Disables screen updating to reduce flicker
Application.ScreenUpdating = False
' Sets Wb1 as the current (destination) workbook
Set Wb1 = ThisWorkbook
' Sets Wb2 as the defined workbook and opens it - Update filepath / filename as required
Set Wb2 = Workbooks.Open("C:\Users\admin\Desktop\Accom_Master_File.xlsx")
' Sets LastRow as the first blank row of Wb1 Sheet1 based on column A (requires at least header if document is otherwise blank)
lastrow = Sheets(2).Cells(Rows.count, "A").End(xlUp).Row + 1
' With workbook 2
With Wb2
' Activate it
.Activate
' Activate the desired sheet - Currently set to sheet 1, change the number accordingly
.Sheets(1).Activate
' Copy the used range of the active sheet
.ActiveSheet.UsedRange.Copy
End With
' Then with workbook 1
With Wb1.Sheets(2)
' Activate it
.Activate
' Select the first blank row based on column A
.Range("A1").Select
' Paste the copied data
.Paste
End With
' Close workbook 2
Wb2.Close
' Re-enables screen updating
Application.ScreenUpdating = False
Dim wkb As Workbook
Set wkb = ThisWorkbook
wkb.Sheets("Sheet1").Activate
End Sub
Private Sub CommandButton3_Click()
Range("B2").CurrentRegion.Select
Selection.Sort Key1:=Range("B2"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
ThisWorkbook.Sheets("Sheet2").Range("B:C").Delete xlUp
ThisWorkbook.Sheets("Sheet2").Columns(2).Copy
ThisWorkbook.Sheets("Sheet2").Columns(1).Insert
ThisWorkbook.Sheets("Sheet2").Columns(3).Delete
End Sub
Private Sub CommandButton4_Click()
Dim dicKey As String
Dim dicValues As String
Dim dic
Dim data
Dim x(1 To 35000, 1 To 24)
Dim j As Long
Dim count As Long
Dim lastrow As Long
lastrow = Cells(Rows.count, 1).End(xlUp).Row
data = Range("A2:X" & lastrow) ' load data into variable
With CreateObject("scripting.dictionary")
For i = 1 To UBound(data)
If .Exists(data(i, 2)) = True Then 'test to see if the key exists
x(count, 3) = x(count, 3) & ";" & data(i, 3)
x(count, 8) = x(count, 8) & ";" & data(i, 8)
x(count, 9) = x(count, 9) & ";" & data(i, 9)
x(count, 10) = x(count, 10) & ";" & data(i, 10)
x(count, 21) = x(count, 21) & ";" & data(i, 21)
Else
count = count + 1
dicKey = data(i, 2) 'set the key
dicValues = data(i, 2) 'set the value for data to be stored
.Add dicKey, dicValues
For j = 1 To 24
x(count, j) = data(i, j)
Next j
End If
Next i
End With
Rows("2:300").EntireRow.Delete
Sheets("Sheet1").Cells(2, 1).Resize(count - 1, 24).Value = x
End Sub
Private Sub CommandButton5_Click()
If ActiveSheet.AutoFilterMode Then Selection.AutoFilter
ActiveCell.CurrentRegion.Select
With Selection
.AutoFilter
.AutoFilter Field:=1, Criteria1:="ACTIVE"
.AutoFilter Field:=5, Criteria1:="NUMBERS"
.Offset(1, 0).Select
End With
Dim ws As Worksheet
Dim rVis As Range
Application.ScreenUpdating = False
For Each ws In Worksheets
Do Until ws.Columns("A").SpecialCells(xlVisible).count = ws.Rows.count
Set rVis = ws.Columns("A").SpecialCells(xlVisible)
If rVis.Row = 1 Then
ws.Rows(rVis.Areas(1).Rows.count + 1 & ":" & rVis.Areas(2).Row - 1).Delete
Else
ws.Rows("1:" & rVis.Row - 1).Delete
End If
Loop
Next ws
Application.ScreenUpdating = True
Dim LR As Long
LR = Cells(Rows.count, 1).End(xlUp).Row
Rows(LR).Copy
Rows(LR + 2).Insert
End Sub
Private Sub CommandButton6_Click()
Columns("A").Delete
Dim lastrow As Long
lastrow = Range("A2").End(xlDown).Row
Range("X2:X" & lastrow).FormulaR1C1 = "=IF(RC[+1]=""PAYING"", VLOOKUP(RC[-23],'Sheet2'!R1C1:R20000C8,8,0),""PENDING"")"
Range("Y2:Y" & lastrow).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-24],'Sheet2'!R1C1:R20000C8,2,0), ""PENDING"")"
Range("Z2:Z" & lastrow).FormulaR1C1 = "=(LEN(RC[-24])-LEN(SUBSTITUTE(RC[-24], "";"", """"))+1)*1200"
Range("AA2:AA" & lastrow).FormulaR1C1 = "=VLOOKUP(RC[-26],'Sheet3'!R2C2:R220C4,2,0)"
Range("AB2:AB" & lastrow).FormulaR1C1 = "=VLOOKUP(RC[-27],'Sheet3'!R2C2:R220C4,3,0)"
Range("AC2:AC" & lastrow).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-28],'Sheet4'!R1C1:R30C3,2,0),"""")"
Range("AD2:AD" & lastrow).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-29],'Sheet4'!R1C4:R30C6,2,0),"""")"
Columns("X:AD").EntireColumn.AutoFit
Sheets(1).Columns(24).NumberFormat = "#"
Sheets(1).Columns(25).NumberFormat = "#"
Sheets(1).Columns(29).NumberFormat = "#"
Sheets(1).Columns(30).NumberFormat = "#"
End Sub
Private Sub CommandButton7_Click()
Sheet1.Cells.Clear
End Sub
When something like this happens to me I just start up a new workbook and save explicitly in .xls or .xlsm format and then copy and paste my module or class code into new modules and classes in the new workbook. -- cannot post comments yet so if this doesn't help i shall delete this answer.

Need help merging two macros for Excel VBA

Both of these macros are macros I found online and adapted to my use. I am using this code and it works well to separate specific data into new sheets:
Sub Copy_To_Worksheets()
'Note: This macro use the function LastRow
Dim My_Range As Range
Dim FieldNum As Long
Dim CalcMode As Long
Dim ViewMode As Long
Dim ws2 As Worksheet
Dim Lrow As Long
Dim cell As Range
Dim CCount As Long
Dim WSNew As Worksheet
Dim ErrNum As Long
'Set filter range on ActiveSheet: A1 is the top left cell of your filter range
'and the header of the first column, D is the last column in the filter range.
'You can also add the sheet name to the code like this :
'Worksheets("Sheet1").Range("A1:D" & LastRow(Worksheets("Sheet1")))
'No need that the sheet is active then when you run the macro when you use this.
Set My_Range = Range("A1:Z" & Range("A" & Rows.Count).End(xlUp).Row)
My_Range.Parent.Select
If ActiveWorkbook.ProtectStructure = True Or _
My_Range.Parent.ProtectContents = True Then
MsgBox "Sorry, not working when the workbook or worksheet is protected", _
vbOKOnly, "Copy to new worksheet"
Exit Sub
End If
'This example filters on the first column in the range(change the field if needed)
'In this case the range starts in A so Field:=1 is column A, 2 = column B, ......
FieldNum = 5 'I changed this to 3 for column C
'Turn off AutoFilter
My_Range.Parent.AutoFilterMode = False
'Change ScreenUpdating, Calculation, EnableEvents, ....
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
ActiveSheet.DisplayPageBreaks = False
'Add a worksheet to copy the a unique list and add the CriteriaRange
Set ws2 = Worksheets.Add
With ws2
'first we copy the Unique data from the filter field to ws2
My_Range.Columns(FieldNum).AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=.Range("A1"), Unique:=True
'loop through the unique list in ws2 and filter/copy to a new sheet
Lrow = .Cells(Rows.Count, "A").End(xlUp).Row
For Each cell In .Range("A2:A" & Lrow)
'Filter the range
My_Range.AutoFilter Field:=FieldNum, Criteria1:="=" & _
Replace(Replace(Replace(cell.Value, "~", "~~"), "*", "~*"), "?", "~?")
'Check if there are no more then 8192 areas(limit of areas)
CCount = 0
On Error Resume Next
CCount = My_Range.Columns(1).SpecialCells(xlCellTypeVisible) _
.Areas(1).Cells.Count
On Error GoTo 0
If CCount = 0 Then
MsgBox "There are more than 8192 areas for the value : " & cell.Value _
& vbNewLine & "It is not possible to copy the visible data." _
& vbNewLine & "Tip: Sort your data before you use this macro.", _
vbOKOnly, "Split in worksheets"
Else
'Add a new worksheet
Set WSNew = Worksheets.Add(After:=Sheets(Sheets.Count))
On Error Resume Next
WSNew.Name = cell.Value
If Err.Number > 0 Then
ErrNum = ErrNum + 1
WSNew.Name = "Error_" & Format(ErrNum, "0000")
Err.Clear
End If
On Error GoTo 0
'Copy the visible data to the new worksheet
My_Range.SpecialCells(xlCellTypeVisible).Copy
With WSNew.Range("A1")
' Paste:=8 will copy the columnwidth in Excel 2000 and higher
' Remove this line if you use Excel 97
.PasteSpecial Paste:=8
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
.Select
End With
End If
'Show all data in the range
My_Range.AutoFilter Field:=FieldNum
Next cell
'Delete the ws2 sheet
On Error Resume Next
Application.DisplayAlerts = False
.Delete
Application.DisplayAlerts = True
On Error GoTo 0
End With
'Turn off AutoFilter
My_Range.Parent.AutoFilterMode = False
If ErrNum > 0 Then
MsgBox "Rename every WorkSheet name that start with ""Error_"" manually" _
& vbNewLine & "There are characters in the name that are not allowed" _
& vbNewLine & "in a sheet name or the worksheet already exist."
End If
'Restore ScreenUpdating, Calculation, EnableEvents, ....
My_Range.Parent.Select
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
What I need help with is to add a particular set of formulas to the bottom of each sheet that is created from the above macro. The following macro adds the formulas to all the sheets in the workbook. I need it to add the formulas to only the sheets that are created in the above macro. The number of sheets created change every time they are generated, depending on the source data. I was thinking it might be best to merge bottom macro into the top but I have no idea how to go about doing that.
Sub Insert_Formulas()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Activate
'Start
NxtRw = Cells(Rows.Count, "B").End(xlUp).Row + 1
With Cells(NxtRw, "B")
.Value = "Total Open Cases"
End With
With Cells(NxtRw, "C")
.EntireRow.Insert
.Value = "Total Closed Cases"
End With
'Next Row below
NxtRw = Cells(Rows.Count, "B").End(xlUp).Row + 1
With Cells(NxtRw, "B")
.Formula = "=CountIf(B2:B" & NxtRw - 1 & ", ""Open*"")"
End With
With Cells(NxtRw, "C")
.Formula = "=CountIf(B2:B" & NxtRw - 1 & ", ""Closed*"")"
End With
Next
End Sub
Any help would be greatly appreciated.
Thank you, Ck
I wouldn't combine the 2 macros, simply call the Insert_Formulas macro from the Copy_To_Worksheets macro when it is needed.
To call the macro all you need is this line:
Insert_Formulas
Edit to respond to comment:
Given you don't know how many sheets are being added I have one suggestion you may try.
High level, add text to a cell in each sheet to indicate if it is new or not. When new sheet is created cell should say "new". When not new it should say "existing". Then in the
If you want to give this a try, and let me know what doesn't work I can check back and help update the code.
In the Copy_To_Worksheets macro you'll need to add a line to set all existing sheets to "existing"
In then Copy_To_Worksheets macro add a line so that new sheets get set to "new"
In Insert_Formulas macro, still loop through all sheets, but check to see if the sheet is "new", and if so, run the code to add the formulas.
A cleaner (but slightly more difficult) option would be to define a name on each sheet (use the same name for each and limit the scope to each individual sheet) and use that instead of a cell on each sheet.
If you parametrize the function so that it takes the worksheet which needs the formulas as a parameter
Sub Insert_Formulas_Into_WorkSheet(ws As Worksheet)
ws.Activate
'Start
NxtRw = Cells(Rows.Count, "B").End(xlUp).Row + 1
With Cells(NxtRw, "B")
.Value = "Total Open Cases"
End With
With Cells(NxtRw, "C")
.EntireRow.Insert
.Value = "Total Closed Cases"
End With
'Next Row below
NxtRw = Cells(Rows.Count, "B").End(xlUp).Row + 1
With Cells(NxtRw, "B")
.Formula = "=CountIf(B2:B" & NxtRw - 1 & ", ""Open*"")"
End With
With Cells(NxtRw, "C")
.Formula = "=CountIf(B2:B" & NxtRw - 1 & ", ""Closed*"")"
End With
End Sub
Then you can add the formulas after each new worksheet is created by calling
Insert_Formulas_Into_WorkSheet WSNew