Copy all conditional formatting rules from one sheet to another - excel

When I set up a new project I have a template sheet that I copy a specific range from. This pulls in the headers for a number of tables and their functions. However, the tables are scalable both across rows and down columns so I have a number of conditional formatting rules to ensure the data is presented in the right way as it scales.
The code I use to copy the sheet is as follows and I have it adjusting the widths of the columns automatically to ensure all the data is visible -
Sub CreateNewSheet(strNameOfSheetToCreate As String, strNameOfSheetToCreateAfter As String, strDefaultSheetToCreateAfter As String)
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim strCreateAfterSheetName As String
If Not IsTextEmpty(strNameOfSheetToCreateAfter) Then
strCreateAfterSheetName = strNameOfSheetToCreateAfter
Else
If Not IsTextEmpty(strDefaultSheetToCreateAfter) Then
strCreateAfterSheetName = strDefaultSheetToCreateAfter
End If
End If
' Only create sheet if sheet doesn't exist
If Not IsTextEmpty(strCreateAfterSheetName) Then
' Only create sheet if sheet doesn't exist
If Not WorkSheetExists(strNameOfSheetToCreate, wb) Then
If WorkSheetExists(strCreateAfterSheetName, wb) Then
wb.Sheets.Add(After:=wb.Sheets(strCreateAfterSheetName)).Name = strNameOfSheetToCreate
Else
wb.Sheets.Add.Name = strNameOfSheetToCreate
End If
' Update the list of sheets
ListSheets
End If
' Copy all cells including functions for specified range
wb.Worksheets("Project 1").Range("A1:I15").Copy wb.Worksheets(strNameOfSheetToCreate).Range("A1:I15")
' Fix Sheet Column widths to match the data
Dim SheetToModify As Worksheet
Set SheetToModify = wb.Worksheets(strNameOfSheetToCreate)
AutofitAllUsedColumns SheetToModify
End If
End Sub
Function WorkSheetExists(shtName As String, Optional wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
WorkSheetExists = Not sht Is Nothing
End Function
Sub AutofitAllUsedColumns(ByVal mySheet As Worksheet)
mySheet.UsedRange.EntireColumn.AutoFit
End Sub
' Check if string is empty
Public Function IsTextEmpty(t As String)
If Trim(t & vbNullString) = "" Then
End If
End Function
The following are all the rules I'd like to copy to the new sheet. Any help to automate this on creating the new project sheet will be appreciated.

Related

Rename sheet with if sheet name already exists while looping workbooks

I am running my code trying to loop through old and new formatted workbooks.
And the sheet names in my old workbooks are different from the new workbooks.
The code is set to run when the new workbook's names are found.
The old workbooks have sheets named "01", "02" and "03".
The new workbooks have sheets named "newname01", "newname02" and "03".
The code is set to run to "newname01" and "newname02".
What I need to do is if the code runs through an old workbook, change the old sheet names to the new workbook's sheet names and run the code. And when running through a new workbook, run through it without changing the sheet names.
I tried changing the old workbook's sheet names to the new ones at the beginning of the code. But when the code is running through an old workbook, its sheets don't contain the new names the code shows an error.
I tried using -
If Not______Is Nothing then.
But I couldn't figure out how that code works.
my code--->
Sub CD3()
Dim wb As Workbook
For Each wb In Application.Workbooks
If Not Application.ActiveProtectedViewWindow Is Nothing Then
Application.ActiveProtectedViewWindow.Edit
End If
Sheets("newname01").Select
Range("A8:B10").Orientation = 90
Range("C10:D10").Orientation = 90
Range("E8:F10").Orientation = 90
Range("G10:H10").Orientation = 90
Range("I8:J10").Orientation = 90
Range("K10:N10").Orientation = 90
Range("O8:Q10").Orientation = 90
Range("Q8:Q10").FormulaR1C1 = "Observation/ Proposals"
'List Sheet Adding
Sheets.Add After:=Sheets("newname02")
Sheets("Sheet1").Select
Sheets("Sheet1").Name = "03"
'more code
ActiveWindow.Zoom = 75
ActiveWindow.ScrollRow = 1
ActiveWindow.ScrollColumn = 1
Range("A11").Select
ActiveWorkbook.Save
ActiveWorkbook.Close
Next ws
End Sub
When the code is running through an old workbook, it has sheets named "01" and "02". I need to change their name to "newname01" and "newname02" and then run the code.
this is a code I found it changed the code regardles of the name
Sub RenameSheet()
Dim Sht As Worksheet
Dim NewSht As Worksheet
Dim newShtName As String
Set NewSht = ActiveSheet
newShtName = "newname01"
For Each Sht In ThisWorkbook.Sheets
If Sht.Name = "newname02" Then
newShtName = "newname01" & "_" &
ThisWorkbook.Sheets.Count
End If
Next Sht
NewSht.Name = newShtName
End Sub
I only need to Change sheet name "01" to "newname01" and "02" to "newname02". And when it already named "newname01" run the rest of the code.
?I tride using -
If Not______Is Nothing then.
I have a feeling that you are not using proper error handling and hence that line or the one before that where you are setting the worksheet is erroring out. Try something like this (UNTESTED)
Option Explicit
Sub Sample()
Dim wbOld As Workbook
Dim wbNew As Workbook
Dim wsOld As Worksheet
Dim wsNew As Worksheet
Dim wsName As String
'~~> Change these two as applicable
Set wbOld = Workbooks("OldWorkBook")
Set wbNew = Workbooks("NewWorkBook")
'~~> Loop through the worksheets in the old workbook
For Each wsOld In wbOld.Worksheets
'~~> Create the name as per new worksheet
'newname01
wsName = "newname" & wsOld.Name
'~~> Attempt to set it. If the worksheet doesn't
'~~> exists, you will not get an error
On Error Resume Next
Set wsNew = wbNew.Sheets(wsName)
On Error GoTo 0
'~~> Check if the object is not nothing
If Not wsNew Is Nothing Then
'~~> Worksheet exists
'
'~~> Do what you want
'
'~~> This is important to prevent false positives
Set wsNew = Nothing
End If
Next wsOld
End Sub
I Wrote two Codes for the two sheet names. The run the code Below
Sub If_Run()
If Not Application.ActiveProtectedViewWindow Is Nothing Then
Application.ActiveProtectedViewWindow.Edit
End If
'Run_for_newname01() = for workbooks containing a Sheet with "newname01"
'Run_for_01() = for workbooks containing a Sheet with "01"
ws = ActiveWorkbook.Worksheets.Count
For i = 1 To ws
With ActiveWorkbook.Worksheets(i)
If .Name Like "*newname01*" Then
Run_for_newname01
ElseIf .Name Like "*01*" Then
Run_for_01
End If
End With
Next i
End Sub

Selecting a worksheet based on a cell value in Excel VBA

I am trying to select a particular page based on cell value U2. I am using the backend Excel names not the display names for the sheets. "Sheet11" is the sheet I am currently trying to connect to. I have tried the following codes, but getting run-time error 9, out of range.
What could I try next?
Thanks
'#1
Dim ws As Worksheet
ws = Range("U2")
Set ws = ActiveSheet
'#2
(Range("U2").Activate
'#3
Sheet11.Activate
Works but no variable
'#4
Sheets(Range("U2").Text).Activate
'#5
Sheets(Range("U2").Value).Activate
'#6
Dim GetString As String
GetString = Range("U2")
GetString.Activate
Is this what you are looking for?
Sheets(ActiveSheet.Range("U2").Value).Select
Reference a Worksheet By Its Code Name
Option Explicit
Sub RefByCodeName()
' Write the code name to a string variable ('wscName').
' Adjust the worksheet!
Dim wscName As String: wscName = CStr(Sheet1.Range("U2").Value)
' Using the 'RefWorksheetByCodeName' function, attempt to reference
' the worksheet ('ws') by its code name.
Dim ws As Worksheet: Set ws = RefWorksheetByCodeName(wscName, ThisWorkbook)
' Validate the worksheet.
If ws Is Nothing Then
MsgBox "No worksheet with the code name '" & wscName & "' found.", _
vbCritical
Exit Sub
End If
' Continue, e.g.:
'MsgBox "Name: " & ws.Name & vbLf & "Code Name: " & ws.CodeName, _
vbInformation
' Make sure the workbook is active.
If Not ThisWorkbook Is ActiveWorkbook Then ThisWorkbook.Activate
' Select the worksheet.
ws.Select
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: In a workbook ('wb'), references a worksheet
' by its code name ('WorksheetCodeName').
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefWorksheetByCodeName( _
ByVal WorksheetCodeName As String, _
ByVal wb As Workbook) _
As Worksheet
Dim ws As Worksheet
For Each ws In wb.Worksheets
If StrComp(ws.CodeName, WorksheetCodeName, vbTextCompare) = 0 Then
Set RefWorksheetByCodeName = ws
Exit Function
End If
Next ws
End Function
Sheets have 3 ways of referring to them:
Name (What you see on the tab at the bottom)
Index (A number representing the sheet's position in the workbook, i.e. this will change if you change the position of a sheet)
CodeName (This is what you refer to as the back end excel name)
You can select a sheet using any of these. If I had a workbook with tabs named after months in Jan to Dec order and I haven't changed the code names the code to select November using each would be as follows:
1.Name Worksheets("November").Select
2.Index Worksheets(11).Select
3.CodeName Sheet11.Select
Unlike name and index you can refer to the codename directly as it is an object.
the following code uses the index to loop through the sheet codenames comparing them to the value in U2 when it is the same as U2 it will select the sheet.
Dim lCodeName As String
Dim lWSCount, lCount As Integer
lCodeName = ActiveSheet.Range("U2").Value
lWSCount = ActiveWorkbook.Worksheets.Count
For lCount = 1 To lWSCount
If Worksheets(lCount).CodeName = lCodeName Then
Worksheets(lCount).Select
Else
End If
Next

copy and paste error causing workbook to crash

I'm having an issue with copy and pasting from one spreadsheet to another.
I am using the following code:
Sub LoadnH()
Dim NF As Workbook
Dim shtMain As Worksheet
Set shtMain = Worksheets("Main")
Dim filePath As String
Dim strFileName As Variant
strFileName = Application.GetOpenFilename("All Files (*.*), *.*", , "Select File to Import", , False)
shtMain.Range("filePath").Value = strFileName
If strFileName <> False Then
Set NF = Application.Workbooks.Open(strFileName)
Application.CutCopyMode = False
NF.Sheets("Summary").Copy
Application.DisplayAlerts = False
NF.Close False
Dim nH As Worksheet
Set nH = Worksheets("Hedge Data")
nH.Activate
With nH
.Cells.Clear
.Pictures.Delete
.Range("A1").Select
.PasteSpecial xlPasteValues
End With
End If
End Sub
The code errors out at the following point
.PasteSpecial xlPasteValues
The code show a runtime error '1004':
Method 'PasteSpecial' of object'_Worksheet' failed
how can I fix this so this error? Many times when it hits this error excel will crash and shutdown as well.
To Avoid Select and other similar methods you can assign your value of the destination range with the value from your source range.
You are using the Worksheet.Copy method which copies an entire Worksheet not the data in a Range of the worksheet. This will be creating a new copy of your source worksheet each time you run the code but not copying the data of the worksheet to the clipboard. (NB: below demonstrates using the Before parameter which dictates where the Worksheet will be copied to).
The Range.Copy method will copy the defined range's data to the clipboard (unless you specify the destination parameter).
Rather than using Copy/Paste etc. you can assign the value of the destination range with the value from your source range.
These examples below are all for demonstration of the above points and are tested using 2 new workbooks with default names for the workbooks and worksheets.
E.g 1
Sub WorksheetCopyMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
SourceWorksheet.Copy DestinationWorksheet
End Sub
The result of this test creates a copy of Sheet1 from Book1 before Sheet1 on Book2.
E.g 2
Sub RangeCopyMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
SourceWorksheet.Range("A1").Copy
DestinationWorksheet.Range("A1").PasteSpecial xlPasteValues
End Sub
This example copies cell A1 from Book1 - Sheet1 and pastes it to cell A1 in Book2 - Sheet1.
E.g 3
Sub AvoidSelectMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
DestinationWorksheet.Range("A1").Value = SourceWorksheet.Range("A1").Value
End Sub
This example assigns the Value property of A1 from Book1 - Sheet1 to cell A1 in Book2 - Sheet1. It's the same outcome as E.g 2 but avoids using Select, Copy & Paste etc. This method is much faster and generally less error prone than the 2nd example.
Depending on your environment, the first example may be the easiest and quickest method.

Copy Data from Sheet to another based on drop-down value

I have several sheets in one workbook. I want to copy-paste the data (entire content) from different sheets to sheet 1 (let's say from B6) based on the drop-down value in 'A2' in Sheet 1. Drop-down consists of names of all the other sheets. So, if I select Sheet 2 in drop-down, it should copy entire content from Sheet 2 to Sheet 1, starting from B6.
Here is the macro, I created for it. But it's not working. Can you help me figure out what's wrong with my code?
Sub Button21_Click()
Dim wb As Workbook
Dim criteria As String
Application.ScreenUpdating = False
'Set values for your variables.
Set wb = ThisWorkbook
criteria = wb.Sheets("Sheet1").Range("A2")
Dim TT As ListObject
For i = 1 To Sheets.Count
With Sheets(i)
For Each TT In Sheets(i).ListObjects
If TT.Name = criteria Then TT.Range.Copy Sheets("Sheet1").Range("B6:Q22").PasteSpecial: Exit Sub
Next
End With
Next
Application.ScreenUpdating = True
End Sub
Here's code that does work.
Sub Button21_Click()
Dim Wb As Workbook
Dim Criteria As String
Dim i As Integer ' loop counter: Sheets
Dim Tbl As ListObject ' loop object
'Set values for your variables.
Set Wb = ThisWorkbook
Criteria = Wb.Sheets("Sheet1").Range("A2")
Application.ScreenUpdating = False
For i = 1 To Wb.Sheets.Count ' { "Shees(1)" is in the ActiveWorkbook
' { which may be different from Wb
For Each Tbl In Wb.Sheets(i).ListObjects
If Tbl.Name = Criteria Then
Tbl.Range.Copy
Wb.Worksheets("Sheet1").Range("B6").PasteSpecial
Exit Sub
End If
Next Tbl
Next i
Application.ScreenUpdating = True
End Sub
You should declare all variables, not only objects. And it's better to prepare your tools before starting on the job, i.e. declare variables before writing code that uses them.
What's the point of declaring Set Wb = ThisWorkbook if you use the default workbook (= ActiveWorkbook) thereafter?
PasteSpecial needs its own line. The construct you used would deliver the argument for the Copy object's Destination property. The latter is an address and can't include the PasteSpecial method.
It's enough to specify the first cell to paste to.
Note that the ListObject's Range comprises of the entire table. Use the DataBodyRange to specify only data (without headers and totals).

Making sheet name the same as cell value

I am currently working on macro in a workbook with multiple worksheets, that aims to show and hide certain worksheets based on the values in a master worksheet. The worksheet names are also contained in the master worksheet and the main procedure looks at these values when referencing to a worksheet it needs to show or hide. The problem with this method is that, the macro will produce errors if the user changes the worksheet tab names. I was hoping to insert an additional procedure that makes the tab names of each worksheet equal to the values in the respective cell of the master worksheet. I came up with the following:
Sub SheetName()
If Not ActiveWorkbook Is ThisWorkbook Then Exit Sub
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
DataImport.Range("A13").Value = Sheet1.Name
End Sub
This code works fine but there are about 100+ worksheets in this workbook. I was wondering if there is a more efficient way to do this, as opposed to typing the same procedure 100 times. I've tried storing the worksheet code names in an array and looping the same procedure through the array, for example:
Sub test()
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
Dim index As Long
Dim ws(0 To 2) As Worksheet
Set ws = Array(Sheet1, Sheet2, Sheet3)
For i = 13 To 14
index = i - 13
DataImport.Cells(i, "A").Value = ws(index).Name
Next i
End Sub
but the error message "Can't Assign to Array" shows up. Sorry in advance if my code looks garbage, I am still new to VBA and I still have quite a lot to learn.
If you list the sheet codenames in ColA of your master sheet, then this code will update columns B and C with the current sheet tab names and indexes respectively:
Sub UpdateIndex()
Dim ws As Worksheet, cn As String, m
For Each ws In ThisWorkbook.Worksheets
cn = ws.CodeName
If cn <> DataImport.CodeName Then
'look for the codename in the Import sheet
m = Application.Match(cn, DataImport.Columns(1), 0)
If Not IsError(m) Then
'got a match - update this row
DataImport.Cells(m, "B").Value = ws.Name 'tab name
DataImport.Cells(m, "C").Value = ws.Index 'sheet index
End If
End If
Next ws
End Sub
Assumes you set the code name for your "Data Import" worksheet to DataImport.
If your code is driven by the sheet codename, it doesn't matter whether the user renames the tabs or changes the sheet order.
For your second attempt, you can use Excel built-in Sheets object and Workbook.Sheets collection:
Sub test()
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
Dim index As Long
Dim ws As Excel.Sheets
Set ws = ThisWorkbook.Sheets
For i = 13 To 14
index = i - 13
DataImport.Cells(i, "A").Value = ws(index).Name
Next i
End Sub

Resources