Macro to Run a Procedure Across Several Excel Worksheets - excel

I'm stuck with this problem. I need to run a macro that will do the following:
Find the last line in a table on the worksheet called "Baseline".
Add a row to that table
Copy the formats and formulas (but not values) from the row above to the new row.
Repeat the process for the other worksheets (called Quarter 1, Quarter 2 etc), that have the same structure as the worksheet called Baseline.
My problem is that the process only seems to work on the first worksheet, Baseline, but not on any of the other worksheets. I wonder if the problem is the way I have tried to get the code to copy formulas and formats only.
Here is the code, just for the Baseline and Quarter 1 worksheets:
Public Sub AddRow()
On Error GoTo errhandler
Worksheets("Baseline").Activate
'Find Last Row in Service User Details
Dim rgeLastRowBaseline As Range
Set rgeLastRowBaseline = ActiveWorkbook.Worksheets("Baseline").Cells.Find("Cost")
' Select and Copy Last Row
rgeLastRowBaseline.End(xlDown).EntireRow.Select
Selection.Offset(1).EntireRow.Insert
rgeLastRowBaseline.End(xlDown).EntireRow.Select
Selection.Copy
rgeLastRowBaseline.End(xlDown).Offset(1).EntireRow.Select
rgeLastRowBaseline.End(xlDown).Offset(1).EntireRow.PasteSpecial
Application.CutCopyMode = False
Selection.SpecialCells(xlCellTypeConstants, 23).Select
Selection.ClearContents
'Quarter 1
Worksheets("Quarter 1").Activate
Dim rgeLastRowQ1 As Range
Set rgeLastRowQ1 = ActiveWorkbook.Worksheets("Quarter 1").Cells.Find("Cost")
' Select and Copy Last Row
rgeLastRowQ1.End(xlDown).EntireRow.Select
Selection.Offset(1).EntireRow.Insert
rgeLastRowQ1.End(xlDown).EntireRow.Select
Selection.Copy
rgeLastRowQ1.End(xlDown).Offset(1).EntireRow.Select
rgeLastRowQ1.End(xlDown).Offset(1).EntireRow.PasteSpecial
Application.CutCopyMode = False
Selection.SpecialCells(xlCellTypeConstants, 23).Select
Selection.ClearContents
Exit Sub
errhandler:
Application.CutCopyMode = False
End Sub
Does anyone have any suggestions please?
Thanks

You'll need to use Worksheet type variables. I did not correct your technical solutions even though I don't completely agree with selecting everything.
Sub onesheet(ws As Worksheet)
On Error GoTo errhandler
ws.Activate
Dim rgeLastRowQ1 As Range
Set rgeLastRowQ1 = ws.Cells.Find("Cost")
' Select and Copy Last Row
rgeLastRowQ1.End(xlDown).EntireRow.Select
Selection.Offset(1).EntireRow.Insert
rgeLastRowQ1.End(xlDown).EntireRow.Select
Selection.Copy
rgeLastRowQ1.End(xlDown).Offset(1).EntireRow.Select
rgeLastRowQ1.End(xlDown).Offset(1).EntireRow.PasteSpecial
Application.CutCopyMode = False
Selection.SpecialCells(xlCellTypeConstants, 23).Select
Selection.ClearContents
Exit Sub
errhandler:
Application.CutCopyMode = False
End Sub
Sub sheetloop()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = "Baseline" Or ws.Name Like "Quarter*" Then Call onesheet(ws)
Next ws
End Sub

Related

Creating a new column and pasting data into that new column with VBA

I am attempting to create a new column on a different sheet and then copy data into that column.
Below is the code I have written. The first sub is a new column to the left and the second sub is the column to the right.
The insert column part is working. I hid a column and have a cell in there as a named range which I used to select in my macro. The data I want to copy is on the Input sheet and is named InputData.
Dim sourceSheet As Worksheet
Set sourceSheet = ActiveSheet
Sheets("Data").Activate
Sheets("Data").Range("DividerColumn").Select
Selection.EntireColumn.Offset(0, 0).Insert Shift:=xlToLeft
'Sheets("Input").Activate
'Range("InputData").Copy
'Sheets("Data").Activate
'ActiveCell offset maybe?
'Range().PasteSpecial xlPasteValues
Call sourceSheet.Activate
End Sub
Dim sourceSheet As Worksheet
Set sourceSheet = ActiveSheet
Sheets("Data").Activate
Sheets("Data").Range("DividerColumn").Select
Selection.EntireColumn.Offset(0, 1).Insert Shift:=xlToRight
Call sourceSheet.Activate
End Sub
Oh I didn't see your copy range. In that case this could probably work. I see you just got the answer, but this would be a good way to avoid select.
Sub copyToLeft()
Call doTheCopy(False)
End Sub
Sub CopyToRight()
Call doTheCopy(True)
End Sub
Private Sub doTheCopy(goRightIsTrue As Boolean)
With Sheets("Data").Range("DividerColumn").EntireColumn.Offset(0, IIf(goRightIsTrue, 1, 0))
.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
.Offset(0, -1).Value = Sheets("Input").Range("InputData").EntireColumn.Value
End With
End Sub
I found the solution by using an offset function. Below is my code. Hope this helps someone with a similar situation.
Dim sourceSheet As Worksheet
Set sourceSheet = ActiveSheet
Sheets("Data").Activate
Sheets("Data").Range("DividerColumn").Select
Selection.EntireColumn.Offset(0, 0).Insert
Shift:=xlToLeft
Sheets("Input").Activate
Range("InputData").Copy
Sheets("Data").Activate
Range("DividerColumn").Select
ActiveCell.Offset(0, -1).PasteSpecial
xlPasteValues
Call sourceSheet.Activate
End Sub
-1 in the offset function moves your active cell to the left one cell and then 1 moves it to the right. So once the column is created, either right or left, my macro goes and copies the information and then goes back to the sheet I want it to and selects my named range again and then it gets moved to the left and pastes my data.

Add Row in Table without affecting conditional formatting

I am using this code which works fine, however it messes up conditional formatting in my table. Is there a way to insert a new row in table via VBA without affecting conditional formatting?
Public Sub insertRowBelow()
ActiveCell.Offset(1).EntireRow.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromRightOrBelow
ActiveCell.EntireRow.Copy
ActiveCell.Offset(1).EntireRow.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End Sub
This Will Work:
Public Sub insertRowBelow()
ActiveCell.Offset(1).EntireRow.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ActiveCell.EntireRow.Copy
ActiveCell.Offset(1).EntireRow.PasteSpecial xlPasteAllMergingConditionalFormats
ActiveCell.Offset(1).EntireRow.Clear
Application.CutCopyMode = False
End Sub
Try:
Option Explicit
Sub test()
'Change Sheet name if needed
With ThisWorkbook.Worksheets("Sheet1").ListObjects("Table1")
If Not Intersect(ActiveCell, .DataBodyRange) Is Nothing Then
'Change table name if needed - Insert one row above active cell
.ListRows.Add ((ActiveCell.Row - ActiveCell.ListObject.Range.Row))
'Change table name if needed - Insert one row below active cell
.ListRows.Add ((ActiveCell.Row - ActiveCell.ListObject.Range.Row + 1))
End If
End With
End Sub
Add the row only within the ListObject not within the whole sheet (see The VBA Guide To ListObject Excel Tables)
Option Explicit
Public Sub AddRowInListObject()
Dim ActTable As ListObject
On Error Resume Next 'next line throws error if ActiveCell is not in a table
Set ActTable = ActiveCell.ListObject
On Error GoTo 0 're-activate error reporting!
If Not ActTable Is Nothing Then 'only add row if ActiveCell is within a table
ActTable.ListRows.Add ActiveCell.Row - ActTable.Range.Row
End If
End Sub
Note that there are 2 differnt row counting systems:
ActiveCell.Row which returns the absolute row number of the worksheet
ListRows.Add which awaits the row number relatively to the beginning of the ListObject
So for example if the ListObject starts in row 5 of the worksheet then row number 1 of the ListObject is row number 5 of the worksheet.

I want to copy a range of cells and paste them to another sheet dependent on a drop down selection and activated using a button

I have an Export to sheet button but I can't get it working correctly.
I selects the correct cells to copy but can't then transpose them on to selected sheet that appears in the drop down box in cell A1, I then also need it to paste on the next available row in that specific sheet. The problem is that I can't just list the sheets in VBA as the list in the drop down box changes. I have tried several ways to with no success. If someone could help it would be great
Sub Button2_Click()
Worksheets("Sheet1").Range("a2:x2").Copy
ActiveSheet.Paste Destination:=Worksheets("Sheet1!A1").Range("a:x")
End Sub
Here is some more code I have tried for the issue but still does not seem to work.
Sub ExportButton1()
'
' ExportButton1 Macro
' Exports Data to staff sheet from drop down box
'
' Keyboard Shortcut: Ctrl+e
'
ActiveWorkbook.Save
End Sub
Private Sub CommandButton1_Click(ByVal Target As Range)
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Data")
'On Error Resume Next
'If Not (Application.Intersect(Range("H2"), Target) Is Nothing) Then _
Set pasteSheet = Worksheets(ActiveSheet.Range("H2"))
copySheet.Range("G5:AA5").Copy
pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
you need to change the sheet name in your worksheet function.
This might work.
Sub Button2_Click()
'Copying the Data
Worksheets("Sheet1").Range("a2:x2").Copy
'Pasting the data
' What we were missing was to pass the name of the tab dynamically. Now this code will pick up the name that appears in the Cell A1.
ActiveSheet.Paste Destination:=Worksheets(Worksheets("Sheet1").Range("A1").value).Range("A1")
End Sub
Also in the paste range you only need to put the first cell range to paste values.
To paste the Transposed Values check the function PasteSpecial with Transpose property set to True.
'I have found another way around the problem to copy paste cells to certain sheet then on 'staff sheet a formula in a table to tests column A value on data sheet for name and only 'transpose those rows
Sub Macro1()
Range("A2:J2").Select
Selection.Copy
Sheets("Sheet3").Select
Range("A60000").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
End Sub
'Formula on staff sheet is -=IF(Sheet3!A:A="Column1",Sheet3!$B:$B,"")

How to iteratively copy each columns in one sheet to different sheets

I am trying to use VBA to realize the following goal:
I have two sheets: "revenue" and "sales tax", and they record the revenue and sales tax of 100 stores from May 1st to May 28th. Now I am trying to create a sheet for each store recording its revenue and sales tax from May 1st to May 28th.
Sub test1()
Sheets("Sheet1").Select
Sheets("Sheet1").Copy Before:=Sheets(17)
Sheets("revenue").Select
Range("D154:D168").Select
Selection.Copy
Sheets("Sheet1 (2)").Select
Range("C5").Select
ActiveSheet.Paste
Sheets("sales tax").Select
Range("D138:D152").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1 (2)").Select
Range("F5").Select
ActiveSheet.Paste
Sheets("Sheet1 (2)").Select
Sheets("Sheet1 (2)").Name = " reportF "
End Sub
Using this code I am only able to establish a file for 1 store each time. What loop syntax should I use to loop through all stores?
It looks like your data has the store name in column D? This code runs down all cells in column D and copies them into separate sheets depending on the contents
Sub ExampleCode
Dim r as range 'declare a pointer variable
Dim ws as worksheet 'declare a worksheet variable
set r = Range("d1") 'point to fist cell
Do 'Start a loop
If SheetNotExist(r.text) then 'if no sheet of that name
set ws = worksheets.add(after:=worksheets.count) 'add one
ws.name = r.text 'and name it as text in r
End if
r.copy worksheets(r.text).cells(rows.count,4).end(xlup).offset(1,0) 'copy to next blank cell
set r = r.offset(1,0) 'shift pointer down one cell
Loop until r.text = "" 'keep going until r is empty
End Sub
Function SheetNotExist(s as string) as boolean 'check if sheet exists
On error goto nope 'jump on error
Dim ws as worksheet
set ws = worksheets(s) 'this will error if sheet doesn't exist
'so if we get here the sheet does exist
SheetNotExist = False 'so return false
Exit Function 'and go back
nope: 'we only get here if sheet doesn't exist
SheetNotExist = True 'so return that
End Function
Written on my phone - don't have excel so there may be typos - code may not compile therefore,

VBA check sheet for filtered data

Is there any way to check if sheets have any filtered data (If there is filtered data, then clear filter, else do nothing)? I have this code here, but I don't know how to write second part:
Sub ProtectAll()
Dim wSheet As Worksheet
For Each wSheet In Worksheets
With wSheet
If .AutoFilterMode Then
.ShowAllData
.Cells.Locked = True
.Cells.FormulaHidden = False
'.Range(wSheet.Cells(12, 1), wSheet.Cells(12, 18)).AutoFilter
'.Protect Password:=Pwd, AllowFiltering:=True
ElseIf ??? Then
End If
End With
Next wSheet
End Sub
This code removes all autofilters from ActiveSheet
ActiveSheet.Autofilter.Range.Autofilter
Afterwards you can reset the filter (no criteria selected) by defining an appropriate range
ActiveSheet.Range("A1:B1").Autofilter
I think the best way is using .FilterMode
If Sheets("NameSheet").FilterMode Then Sheets("NameSheet").ShowAllData
This code removes filtered data the sheet have and show all data keeping autofilters.

Resources