VBA code to Paste the borders If Range A:A <> "" - excel

I have wrote a code which paste the borders on Sheet1 used range whenever i make an entry and same for Sheet2. The data is cover by borders automatically.
I have been facing an error (select method of range class failed) if i apply the both codes in sheet1 and Sheet2.
If i use the code for single sheet it works.
Is there an way to merge these both codes OR any way to make it work OR to do this thing in an efficient way.
Any help will be appreciated.
Sheet1
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Dim lngLstCol As Long, lngLstRow As Long
lngLstRow = Sheet1.UsedRange.Rows.Count
lngLstCol = Sheet1.UsedRange.Columns.Count
For Each rngCell In Range("A2:A" & lngLstRow)
If rngCell.Value > "" Then
r = rngCell.Row
c = rngCell.Column
Range(Cells(r, c), Cells(r, lngLstCol)).Select
With Selection.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Font
.Name = "Calibri"
.Size = 10
End With
End If
Next
Application.ScreenUpdating = True
End Sub
Sheet2
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
lngLstRow = Worksheets("Current Stock").UsedRange.Rows.Count
lngLstCol = Worksheets("Current Stock").UsedRange.Columns.Count
For Each rngCell In Range("A2:A" & lngLstRow)
If rngCell.Value > "" Then
r = rngCell.Row
c = rngCell.Column
Range(Cells(r, c), Cells(r, lngLstCol)).Select
With Selection.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Font
.Name = "Calibri"
.Size = 10
End With
End If
Next
Application.ScreenUpdating = True
End Sub

If i use the code for single sheet it works.
This might be because you are not fully qualifying ranges: If you don not qualify Cells and Range it works on the activesheet so you need to pre-qualify wuith the sheet that contains the ranges so target.parent.Cells and target.parent.range might solve your problem
Is there an way to merge these both code
Define a sub which takes a worksheet as a parameter
sub do_the_work(byref ws as worksheet)
Application.ScreenUpdating = False
lngLstRow = Worksheets("Current Stock").UsedRange.Rows.Count
lngLstCol = Worksheets("Current Stock").UsedRange.Columns.Count
For Each rngCell In ws.Range("A2:A" & lngLstRow)
If rngCell.Value > "" Then
r = rngCell.Row
c = rngCell.Column
ws.Range(ws.Cells(r, c), ws.Cells(r, lngLstCol)).Select
With Selection.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Font
.Name = "Calibri"
.Size = 10
End With
End If
Next
Application.ScreenUpdating = True
end sub
then inside the worksheet.change call
Private Sub Worksheet_Change(ByVal Target As Range)
do_the_work target.parent
End Sub
Improvement removing select
With ws.Range(ws.Cells(r, c), ws.Cells(r, lngLstCol))
With .Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With .Font
.Name = "Calibri"
.Size = 10
End With
End With

Related

Why does VBA Crashes with simple Copy-Paste code

My code opens workbook, copies, and paste into this main workbook (essentially it consolidates several worksheets from different workbooks) but it crashes and excel closes and re-opens (recover). However when I add breakpoints it runs without issues. The source workbooks have similar layout / headers. It has formatting inside as well hence the copying of formats below. I have tried commenting out the formatting portion, commenting out the ContinueDo portion, and it still crashes. What did i do wrong? This is my code:
Private Sub CommandButton1_Click()
Dim File_Path As String, wsSrce As String
Dim File_Name As String
Dim firstrow, LastRow As Long
Dim wbDst As Workbook, wbSrce As Workbook, New_Workbook As Workbook
Dim wsDst As Worksheet
Dim rng As Range, r1 As Range, r2 As Range
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.DisplayAlerts = False
.EnableEvents = False
End With
wsSrce = "Part A"
Set wbDst = ThisWorkbook
Set wsDst = wbDst.Worksheets("Consolidated Data") 'destination sheet
wsDst.Range("A5:AI1048576").Clear
wsDst.Range("AM5:AQ1048576").Clear
wsDst.Range("AS5:BJ1048576").Clear
wsDst.Range("Aj5:al1048576").ClearFormats
wsDst.Range("Ar5:ar1048576").ClearFormats
File_Path = wbDst.Worksheets("Folder Reference").Cells(1, 2) & "\"
File_Name = Dir(File_Path & "*.xls*")
ActiveRow = 5
Do While File_Name <> ""
Set wbSrce = Workbooks.Open(Filename:=File_Path & File_Name, UpdateLinks:=False, Password:="MBIShariah")
For i = 1 To 5
If Left(Worksheets(i).Name, 6) = "Part A" Then
Worksheets(i).Activate
wsSrce_rename = Worksheets(i).Name
End If
Next i
firstrow = 1 + Application.WorksheetFunction.Match("No", Worksheets(wsSrce_rename).Columns("A:A"), 0)
LastRow = wbSrce.Worksheets(wsSrce_rename).Cells(Rows.Count, 8).End(xlUp).Row
If LastRow = 4 Then
GoTo ContinueDo
End If
wbSrce.Worksheets(wsSrce_rename).Range("A" & firstrow & ":AI" & LastRow).Copy
wsDst.Cells(ActiveRow, 1).PasteSpecial xlValues
wsDst.Cells(ActiveRow, 1).PasteSpecial xlFormats
wbSrce.Worksheets(wsSrce_rename).Range("AJ" & firstrow & ":AN" & LastRow).Copy
wsDst.Cells(ActiveRow, 39).PasteSpecial xlValues
wsDst.Cells(ActiveRow, 39).PasteSpecial xlFormats
wbSrce.Worksheets(wsSrce_rename).Range("AO" & firstrow & ":BJ" & LastRow).Copy
wsDst.Cells(ActiveRow, 45).PasteSpecial xlValues
wsDst.Cells(ActiveRow, 45).PasteSpecial xlFormats
LastRowDst = wsDst.Cells(Rows.Count, 8).End(xlUp).Row
Set r1 = wsDst.Range("AJ" & ActiveRow & ":AL" & LastRowDst)
Set r2 = wsDst.Range("AR" & ActiveRow & ":AR" & LastRowDst)
Set rng = Union(r1, r2)
With rng.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With rng.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With rng.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With rng.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With rng.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With rng.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
Application.CutCopyMode = False
ContinueDo:
ActiveRow = 1 + wsDst.Cells(1048576, 8).End(xlUp).Row
wbSrce.Close savechanges:=False
' Kill File_Path & File_Name
File_Name = Dir()
Loop
wsDst.Activate
wsDst.Cells(1, 1).Select
'ActiveWorkbook.RefreshAll
MsgBox "Data copied."
With Application
.ScreenUpdating = True
.Calculation = xlAutomatic
.DisplayAlerts = True
.EnableEvents = True
End With
End Sub

Doing a loop from 1 to LastRow

I've written the code below to do a loop witch I have used in the past, I now however want to do switch the loop.
If a cell in column Q contains a 1 then it adds a row with a certain layout. The code now goes from Q3276 to Q8, how do I reverse the process Preferably I want the loop to go rom Q8 to Q LastRow. Also if anyone has a more lean way of writing the code please let me know.
Dim rngc As Range, rc As Long
Set rngc = Range("Q8:Q3276")
For rc = rngc.Count To 1 Step -1
If rngc(rc).Value = 1 Then
rngc(rc + 1).EntireRow.Insert
rngc(rc + 1).EntireRow.Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
Selection.Borders(xlInsideVertical).LineStyle = xlNone
Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
Range("A35").Select
End If
Next rc
Preferably I want the loop to go rom Q8 to Q LastRow.
To reverse a loop, you can use For rc = 1 to rngc.Count. Note that this will complicate what you are trying to do.
Also if anyone has a more lean way of writing the code please let me know.
Avoid using Select/Selection etc
Use Autofilter. This way no loops will be required and you can work with filtered rows in ONE GO
The border constants range form 5 to 12. What I mean is that the value of xlDiagonalDown is 5 and so on till xlInsideHorizontal which has a value of 12. In such a case we can use a Loop/Select Case to format the borders/cells as shown below
I have commented the code so you should not have a problem understanding it.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
Dim rng As Range
Dim filteredRange As Range
Dim i As Long
'~~> Change this to the relevant sheet
Set ws = Sheet1
With ws
'~~> Remove any filters
.AutoFilterMode = False
'~~> Find last row in Col Q
lRow = .Range("Q" & .Rows.Count).End(xlUp).Row
'~~> Set your range
Set rng = .Range("Q8:Q" & lRow)
'~~> Filter the range and set your filtered range
With rng
.AutoFilter Field:=1, Criteria1:="=1"
Set filteredRange = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
'~~> Check if we have any filtered rows
If Not filteredRange Is Nothing Then
With filteredRange
'~~> Change interior color
With .Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With
'~~> Format the borders
For i = 5 To 12
Select Case i
'~~> Left, Top, Bottom, Right
Case 7 To 10
With .Borders(i)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
'~~> DiagUp,DiagDown,InsideVert,InsideHorz
Case 5, 6, 11, 12
.Borders(i).LineStyle = xlNone
End Select
Next i
End With
End If
'~~> Remove filters
.AutoFilterMode = False
End With
End Sub

VBA Execute Loop from different worksheet

I have a macro with a loop that references the activecell. This works perfectly when I was building the code. However now I'm tidying up this excel template and am trying to execute this from another worksheet, which is like a menu/control sheet.
Everything works using the With Sheets apart from the part where I call on the activecell. Is there something I need to change?
With Sheets("EU Analysis")
With .Range("C7:I5000")
.Cells.ClearContents
.Borders.LineStyle = xlNone
.Interior.Color = 16777215
End With
With .Range("M7:Q21")
.Cells.ClearContents
End With
With .Range("M23:N27")
.Cells.ClearContents
End With
Dim r3 As Range
Set r3 = .Range("C7:I7")
r3.CopyFromRecordset rst4a
Set r3 = .Range(r3, r3.End(xlDown).End(xlToRight))
With r3
.Borders(xlDiagonalDown).LineStyle = xlNone
.Borders(xlDiagonalUp).LineStyle = xlNone
.Borders(xlEdgeLeft).LineStyle = xlContinuous
.Borders(xlEdgeRight).LineStyle = xlContinuous
.Borders(xlEdgeTop).LineStyle = xlContinuous
.Borders(xlEdgeBottom).LineStyle = xlContinuous
.Borders(xlInsideVertical).LineStyle = xlContinuous
.Borders(xlInsideHorizontal).LineStyle = xlContinuous
End With
RowCount = .Range("C" & Rows.Count).End(xlUp).Row - 6
For i = 7 To RowCount + 6
.Cells(i, 8).Select
If ActiveCell.Value = "" Then
ActiveCell.Value = "New"
ActiveCell.HorizontalAlignment = xlCenter
ActiveCell.Interior.Color = RGB(255, 192, 0)
End If
Next i
For i = 7 To RowCount + 6
.Cells(i, 7).Select
If ActiveCell.Value = "" Then
ActiveCell.Value = "Expired"
ActiveCell.HorizontalAlignment = xlCenter
ActiveCell.Interior.Color = RGB(141, 180, 226)
End If
Next i
End With
Thanks in advance

Format a cell in each worksheet

I changed the color and other things of cell M1 in a worksheet. I need to do the same thing in all worksheets of my workbook (the same cell in all the sheets).
There are about 40 sheets so I need to program this task with VBA.
I recorded the procedure but don't know how to write the code to do this in all the worksheets.
The code I recorded:
Sub Macro_1() '' Macro_1 Macro ' Change the look of a cell in all worksheets '
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Selection.Font.Bold = True
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlMedium
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlMedium
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlMedium
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlMedium
End With
Selection.Borders(xlInsideVertical).LineStyle = xlNone
Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
End Sub
Try this for starters:
Option Explicit 'always use this, this helps avoiding typing mistakes in code
Sub MyRoutine()
'declaration of variables
Dim colIndex As Long, rowIndex As Long, ws As Worksheet
colIndex = 13 'M column
rowIndex = 1 'first row
'loop through all worksheets
For Each ws In Sheets
ws.Cells(rowIndex, colIndex).Interior.ColorIndex = 1 'put your color here
'do other stuff with the cell, like
'ws.Cells(rowIndex, colIndex).Value = "some value"
Next
End Sub
Loop each sheet of your workbook and apply the color formatting. below is the example code - sets bold property to first cell of every sheet.
For Each sh In ThisWorkbook.Sheets
'Do your format here.
sh.Range("$A$1").Font.Bold = True
Next
You can modify this for you needs:
Option Explicit
Sub allsheets()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
For Each ws In wb.Sheets
ws.Cells(1, 1).Value = "TEST"
Next
End Sub

Excel Macro Help - Stacking Macros

I am using the following subroutine to combine multiple Excel files from a single folder into a single workbook with multiple worksheets.
Sub Merge2MultiSheets()
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim MyPath As String
Dim strFilename As String
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
MyPath = "C:\MyPath" ' <-- Insert Absolute Folder Location
Set wbDst = Workbooks.Add(xlWBATWorksheet)
strFilename = Dir(MyPath & "\*.xls", vbNormal)
If Len(strFilename) = 0 Then Exit Sub
Do Until strFilename = ""
Set wbSrc = Workbooks.Open(Filename:=MyPath & "\" & strFilename)
Set wsSrc = wbSrc.Worksheets(1)
wsSrc.Copy After:=wbDst.Worksheets(wbDst.Worksheets.Count)
wbSrc.Close False
strFilename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
The end product is an excel file with multiple worksheets (as well as one blank Sheet 1). I was wondering how I can then apply another macro to this newly created Workbook. As an example, I wish for all the worksheets within this new workbook to have their Headers bold and coloured a certain way, and to have the empty Worksheet deleted.
eg:
Sub Headers()
Rows("1:1").Select
Selection.Font.Bold = True
With Selection.Interior
.ColorIndex = 37
.Pattern = xlSolid
End With
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
End Sub
Sheets.Select 'selects all sheets'
Rows("1:1").Select
Selection.Interior.ColorIndex = 37
Add a parameter to Headers that specifies a sheet, then call the sub somewhere in the Do Loop after the copy, like:
Call Headers(wbDst.Worksheets(wbDst.Worksheets.Count))
with your second sub looking like this:
Sub Headers(workingSheet As Worksheet)
workingSheet.Rows("1:1").Select
Selection.Font.Bold = True
With Selection.Interior
.
.
.
This code will do the following:
1) First, delete Sheet1 as you asked for in your post
2) Format the top row in the remaining sheets
Sub Headers()
Dim wkSheet As Worksheet
//Delete Sheet1. Note that alerts are turned off otherwise you are prompted with a dialog box to check you want to delete sheet1
Application.DisplayAlerts = False
Worksheets("Sheet1").Delete
Application.DisplayAlerts = False
//Loop through each worksheet in workbook sheet collection
For Each wkSheet In ActiveWorkbook.Worksheets
With wkSheet.Rows("1:1")
.Interior.ColorIndex = 37
//Add additional formatting requirements here
End With
Next
End Sub

Resources