0% found this document useful (0 votes)
1 views

Sheet1 VBA Code

The document contains VBA code for optimizing operations on an Excel sheet, specifically 'Sheet1'. It includes functions for protecting and unprotecting the sheet, handling row operations (inserting and deleting rows), and validating table data before saving. Additionally, it manages formatting, error handling, and user prompts for better user interaction and data integrity.

Uploaded by

samadhan.kadam
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views

Sheet1 VBA Code

The document contains VBA code for optimizing operations on an Excel sheet, specifically 'Sheet1'. It includes functions for protecting and unprotecting the sheet, handling row operations (inserting and deleting rows), and validating table data before saving. Additionally, it manages formatting, error handling, and user prompts for better user interaction and data integrity.

Uploaded by

samadhan.kadam
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8

' Sheet1 VBA Code - Optimized Version

Const SheetPassword As String = "ADG"


Dim SkipColumnBCheck As Boolean
Dim mblnPerformingRowOperation As Boolean
Dim mblnSkipNextChangeEvent As Boolean

Public Sub ProtectSheet()


On Error GoTo ErrorHandler

With Me
.Protect Password:=SheetPassword, UserInterfaceOnly:=True, _
AllowFormattingCells:=True, AllowFormattingColumns:=True, _
AllowFormattingRows:=True, AllowInsertingColumns:=True, _
AllowInsertingRows:=True, AllowInsertingHyperlinks:=True, _
AllowDeletingColumns:=True, AllowDeletingRows:=True, _
AllowSorting:=True, AllowFiltering:=True,
AllowUsingPivotTables:=True
End With
Exit Sub

ErrorHandler:
Debug.Print "ProtectSheet error: " & Err.Description
' Fallback to basic protection
Me.Protect Password:=SheetPassword
End Sub

Public Sub UnprotectSheet()


On Error Resume Next
Me.Unprotect SheetPassword
On Error GoTo 0
End Sub

Public Sub HandleSheetSetup()


Dim ws As Worksheet
Dim cell As Range, tbl As ListObject
Dim lastRow As Long, lastCol As Long

On Error GoTo ErrorHandler


Application.ScreenUpdating = False
UnprotectSheet

Set ws = ThisWorkbook.Sheets("Sheet1")

' Hide Column A and lock Column B


With ws
.Columns("A:A").Hidden = True
.Columns("B:B").Locked = True

' Disable table auto-expansion


Application.AutoCorrect.DisplayAutoCorrectOptions = False
Application.AutoCorrect.AutoExpandListRange = False

' Color header row (A1:E1)


.Range("A1:E1").Interior.Color = RGB(217, 225, 243)
.Range("A1:E1").Locked = True

' Color Column B cells with content


lastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
For Each cell In .Range("B1:B" & lastRow)
cell.Interior.Color = IIf(Trim(cell.Value) <> "", RGB(230, 230, 230),
xlNone)
Next cell

' Highlight non-empty cells from Column C onwards


.Range("C:XFD").Interior.ColorIndex = xlNone
On Error Resume Next
With .Range("C:XFD").SpecialCells(xlCellTypeConstants)
.Interior.Color = RGB(255, 243, 204)
End With
With .Range("C:XFD").SpecialCells(xlCellTypeFormulas)
.Interior.Color = RGB(255, 243, 204)
End With
On Error GoTo 0

' Format tables


For Each tbl In .ListObjects
With tbl
.Range.Interior.Color = RGB(227, 253, 232)
.HeaderRowRange.Interior.Color = RGB(202, 230, 207)
With .Range.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0)
End With
End With
Next tbl
End With

CleanUp:
ProtectSheet
Application.ScreenUpdating = True
Exit Sub

ErrorHandler:
MsgBox "Error in HandleSheetSetup: " & Err.Description, vbCritical
Resume CleanUp
End Sub

' ---- Row Operations ----


Public Sub InsertRowsBelow()
Dim ws As Worksheet, tbl As ListObject
Dim selectedRow As Long, numRows As Long, insertAtRow As Long
Dim response As Variant, addInTable As VbMsgBoxResult

On Error GoTo CleanUp


mblnPerformingRowOperation = True
mblnSkipNextChangeEvent = True
Application.ScreenUpdating = False
UnprotectSheet

Set ws = ActiveSheet

' Validate selection


If Selection.Cells.CountLarge > 1 Then
MsgBox "Select a single cell to insert rows below.", vbExclamation
GoTo CleanUp
End If
selectedRow = Selection.Row
If selectedRow < 2 Then
MsgBox "You can't insert rows here!", vbExclamation
GoTo CleanUp
End If

' Check if in table


On Error Resume Next
Set tbl = Selection.ListObject
On Error GoTo CleanUp
If tbl Is Nothing Then
MsgBox "You can only insert rows within table ranges.", vbExclamation
GoTo CleanUp
End If

' Get number of rows to insert


response = InputBox("How many rows to insert below the selected row?", "Insert
Rows", 1)
If Not IsNumeric(response) Or response <= 0 Then
MsgBox "Please enter a valid positive number.", vbExclamation
GoTo CleanUp
End If

numRows = CLng(response)
addInTable = MsgBox("Add the rows within the table?", vbYesNo + vbQuestion,
"Add to Table")

' Insert empty rows below table


insertAtRow = tbl.Range.Row + tbl.Range.Rows.Count
ws.Rows(insertAtRow & ":" & insertAtRow + numRows - 1).Insert Shift:=xlDown

' Resize table if requested


If addInTable = vbYes Then
tbl.Resize tbl.Range.Resize(tbl.Range.Rows.Count + numRows)
With ws.Range(tbl.Range.Cells(tbl.Range.Rows.Count + 1, 1), _
ws.Cells(insertAtRow + numRows - 1,
tbl.Range.Columns.Count)).Borders
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0)
End With
End If

CleanUp:
mblnPerformingRowOperation = False
mblnSkipNextChangeEvent = False
ProtectSheet
Application.ScreenUpdating = True
End Sub

Public Sub DeleteSelectedRows()


Dim ws As Worksheet
Dim selectedRow As Long, numRows As Long, i As Long
Dim response As Variant, canDelete As Boolean

On Error GoTo CleanUp


mblnPerformingRowOperation = True
mblnSkipNextChangeEvent = True
Application.ScreenUpdating = False
UnprotectSheet

Set ws = ThisWorkbook.Sheets("Sheet1")

' Validate selection


If Selection.Cells.CountLarge > 1 Then
MsgBox "Select a single cell to delete rows.", vbExclamation
GoTo CleanUp
End If

selectedRow = Selection.Row

' Check for template content


If ws.Cells(selectedRow, "A").Value <> "" Then
MsgBox "Template content cannot be deleted.", vbExclamation
GoTo CleanUp
End If

If selectedRow < 2 Then


MsgBox "You can't delete this row", vbCritical
GoTo CleanUp
End If

' Get number of rows to delete


response = InputBox("How many rows to delete?", "Delete Rows", 1)
If Not IsNumeric(response) Or response <= 0 Then
MsgBox "Please enter a valid positive number.", vbExclamation
GoTo CleanUp
End If

numRows = CLng(response)

' Validate row range


If selectedRow + numRows - 1 > ws.Rows.Count Then
MsgBox "You cannot delete beyond the last row!", vbExclamation
GoTo CleanUp
End If

' Check for protected rows


canDelete = True
For i = 0 To numRows - 1
If ws.Cells(selectedRow + i, "A").Value <> "" Then
MsgBox "Template content cannot be deleted from row " & (selectedRow +
i), vbExclamation
canDelete = False
Exit For
End If
Next i

If Not canDelete Then GoTo CleanUp

' Confirm deletion


If MsgBox("Delete " & numRows & " rows starting from row " & selectedRow & "?",
vbYesNo + vbQuestion) = vbNo Then
GoTo CleanUp
End If

' Delete rows


For i = numRows - 1 To 0 Step -1
ws.Rows(selectedRow + i).Delete Shift:=xlUp
Next i

CleanUp:
mblnPerformingRowOperation = False
mblnSkipNextChangeEvent = False
ProtectSheet
Application.ScreenUpdating = True
End Sub

' ---- Worksheet Events ----


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim tbl As ListObject

If mblnPerformingRowOperation Then Exit Sub

' Check if in table data range


On Error Resume Next
Set tbl = Target.ListObject
On Error GoTo 0

If Not tbl Is Nothing And Target.Cells.Count = 1 Then


If IsEmpty(Target.Value) Or Target.Value = "" Then
If Me.ProtectContents Then Me.Unprotect SheetPassword
Exit Sub
End If
End If

' Protect columns A and B


If Not Intersect(Target, Me.Columns("A:B")) Is Nothing Then
MsgBox "Cell " & Target.Address(False, False) & " is not editable (Columns
A and B are protected)", vbInformation
Exit Sub
End If

' Handle protection for single cell selection


If Target.Cells.Count = 1 Then
If Not Me.ProtectContents And (IsEmpty(Target.Value)) Then
Me.Protect SheetPassword
ElseIf Not IsEmpty(Target.Value) Then
If Me.ProtectContents Then Me.Unprotect SheetPassword
End If
End If
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)


Dim cell As Range, showMessage As Boolean, shouldProtect As Boolean

If mblnPerformingRowOperation Or mblnSkipNextChangeEvent Then


mblnSkipNextChangeEvent = False
Exit Sub
End If

If Target.Rows.Count > 1 Or Target.Cells.Count = Me.Rows.Count Then Exit Sub


If SkipColumnBCheck Then Exit Sub

' Prevent changes to columns A and B


If Not Intersect(Target, Me.Columns("A:B")) Is Nothing Then
Application.EnableEvents = False
On Error Resume Next
Application.Undo
On Error GoTo 0
Application.EnableEvents = True
MsgBox "Cannot modify " & Target.Address(False, False) & " - Columns A and
B are protected", vbExclamation
Exit Sub
End If

If Target.Cells.CountLarge > 1 Then Exit Sub

' Validate changes


showMessage = False
shouldProtect = True

For Each cell In Target


' Check protected areas
If Not Intersect(cell, Me.Range("A1:E1")) Is Nothing Then
showMessage = True
MsgBox "Header row cannot be edited!", vbCritical
Exit For
End If

' Determine if protection needed


If Not cell.ListObject Is Nothing Then shouldProtect = False
If cell.Interior.Color = RGB(255, 243, 204) Then shouldProtect = False
Next cell

' Handle protection


If Me.ProtectContents Then Me.Unprotect SheetPassword

If showMessage Then
Application.EnableEvents = False
On Error Resume Next
Application.Undo
On Error GoTo 0
Application.EnableEvents = True
End If

If shouldProtect And Not Me.ProtectContents Then


Me.Protect SheetPassword, UserInterfaceOnly:=True
End If
End Sub

' ---- Utility Functions ----


Public Sub AddBordersToRowsAndColumns()
Dim ws As Worksheet, rng As Range, cell As Range
Dim lastRow As Long, lastCol As Long

On Error GoTo ErrorHandler


Application.ScreenUpdating = False
UnprotectSheet

Set ws = ThisWorkbook.Sheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
lastCol = 11 ' Column K
Set rng = ws.Range("A1").Resize(lastRow, lastCol)
rng.Borders.LineStyle = xlNone

Application.ScreenUpdating = False
For Each cell In rng
If Trim(cell.Value) <> "" Then
With cell.Borders
.LineStyle = xlContinuous
.Weight = xlThin
End With
End If
Next cell

CleanUp:
ProtectSheet
Application.ScreenUpdating = True
Exit Sub

ErrorHandler:
MsgBox "Error in AddBorders: " & Err.Description, vbCritical
Resume CleanUp
End Sub

Public Sub HandleUpdateCurrentDate()


On Error GoTo ErrorHandler
Application.ScreenUpdating = False
UnprotectSheet

ThisWorkbook.Sheets("Sheet1").Range("E4").Value = Date

CleanUp:
ProtectSheet
Application.ScreenUpdating = True
Exit Sub

ErrorHandler:
MsgBox "Error updating date: " & Err.Description, vbCritical
Resume CleanUp
End Sub

Public Sub ValidateTableBeforeSave(ByRef CancelSave As Boolean)


Dim ws As Worksheet, tbl As ListObject
Dim rng As Range, cell As Range
Dim emptyRows As Collection
Dim tblName As String, msg As String
Dim hasErrors As Boolean
Dim i As Long

On Error GoTo ErrorHandler


Application.ScreenUpdating = False
UnprotectSheet

Set ws = ThisWorkbook.Sheets("Sheet1")
Set emptyRows = New Collection
CancelSave = False
hasErrors = False

' Check all tables in the worksheet


For Each tbl In ws.ListObjects
tblName = tbl.Name
Set rng = tbl.DataBodyRange

' Check for completely empty rows in the table


For i = 1 To rng.Rows.Count
If Application.CountA(rng.Rows(i)) = 0 Then
emptyRows.Add tbl.Range.Row + i - 1
hasErrors = True
End If
Next i

' Check for partially filled rows (all cells empty except one)
For Each cell In rng
If Application.CountA(rng.Rows(cell.Row - rng.Row + 1)) = 1 And _
cell.Value = "" Then
emptyRows.Add cell.Row
hasErrors = True
End If
Next cell
Next tbl

' If errors found, show message and cancel save


If hasErrors Then
msg = "Cannot save because the following issues were found:" & vbCrLf &
vbCrLf
msg = msg & "1. Empty rows detected in tables (rows: "

' Build list of empty rows


If emptyRows.Count > 0 Then
For i = 1 To emptyRows.Count
If i > 1 Then msg = msg & ", "
If i > 10 Then
msg = msg & "..."
Exit For
End If
msg = msg & emptyRows(i)
Next i
End If

msg = msg & ")" & vbCrLf & vbCrLf


msg = msg & "Please either:" & vbCrLf
msg = msg & "- Fill in all required data in these rows" & vbCrLf
msg = msg & "- Delete the empty rows completely" & vbCrLf
msg = msg & "- Move the rows outside the table range"

MsgBox msg, vbCritical, "Validation Error"


CancelSave = True
End If

CleanUp:
ProtectSheet
Application.ScreenUpdating = True
Exit Sub

ErrorHandler:
MsgBox "Validation error: " & Err.Description, vbCritical
CancelSave = True
Resume CleanUp
End Sub

You might also like