VBA insert a Row with formula - Unable to Track - excel

Al,
There is a sheet which Macro is written to add a new team along with formula. I would like to change the formula, but i am unable to find it.
The formula is =IFNA(INDEX($F$24:$F$9223,MATCH($A4,$A$24:$A$9223,0)),0)
VBA Code is:
frmAllTeams.Show
'Adding a team to the dtl overview page
Sheets("HLE").Activate
Call unprotect_sheet
Worksheets("HLE").Range("A1").Activate
'Identifying String name
strname = frmAllTeams.cbox1.Value
typenote = frmAllTeams.cbox2.Value
Dim i As Integer, intValueToFind As String
intValueToFind = frmAllTeams.cbox1.Value
For i = 1 To 30 ' Revise the 500 to include all of your values
If Cells(i, 1).Value = intValueToFind Then
MsgBox ("You cannot add a team twice " & i)
Exit Sub
End If
Next i
'Un-Hiding the third row on dtl overview
ActiveSheet.Rows("3:3").Hidden = False
'loop until you find the row "Project Management" and insert line above
Do
ActiveCell.Offset(1, 0).Select
Loop Until ActiveCell = "Project Management"
Rows(Selection.Row - 1).Copy
Rows(Selection.Row).Insert Shift:=xlDown
'name the cell in col A the name of the page
Cells(ActiveCell.Row, 1).Select
ActiveCell.Value = strname
'formatting
Range(ActiveCell, Cells(ActiveCell.Row, ActiveCell.Column + 8)).Select
With Selection.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
ActiveCell.Offset(0, 8).Select
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.Weight = xlThick
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlMedium
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.Weight = xlMedium
.ColorIndex = xlAutomatic
End With
'go to the team sheet and select col 3-5 on last row and copy
Sheets("HLETeams").Activate
Range("F1:P16").Select
Selection.Copy
'select the col 2 on team line and paste
Sheets("HLE").Select
Range("A1").Select
Dim lastRow As Long
lastRow = ActiveSheet.UsedRange.Rows.Count
'lastRow = lastRow
'MsgBox ("Last Row" & lastRow)
ActiveCell.Offset(lastRow, 0).Select
ActiveCell.PasteSpecial xlPasteAll
Cells.Replace What:="TMxxxx", Replacement:=strname, LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="TEAM: TMxxxx", Replacement:="TEAM: " + strname, LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Dim c As Range
For Each c In Range("A23:I1000").Cells
If c.Value = strname Then
c.EntireRow.Hidden = True
End If
Next c
Worksheets("HLE").Range("A1").Activate
Do
ActiveCell.Offset(1, 0).Select
Loop Until ActiveCell = "TEAM: " & strname
ActiveCell.AddComment typenote
ActiveCell.Offset(2, 2).Select
If typenote = "Mainframe" Then
With Selection.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=mfmod"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
ElseIf typenote = "Distributed" Then
With Selection.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=distmod"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
ElseIf typenote = "Other" Then
ActiveCell.Value = "Other Item"
End If
'Hiding the third row on dtl overview
ActiveSheet.Rows("3:3").Hidden = True
Call protect_sheet
teamcount = teamcount + 1
End Sub
I verified the formula and checked the dependents, but no clue, i just clicked on the dotted line, i didn't see the above said formula.
Where that formula is constructed in VBA code?
EDIT: Please refer below the default row added in the sheet.

As I mentioned in the comments, the formula already exists in row 3, but the row is hidden by default. The code unhides this row and then hides it again. You can accomplish the same thing manually by highlighting rows 2 through 4, right clicking, and clicking Unhide. You should then be able to manually update this formula and hide the row again.
Alternatively, as Siddharth Rout mentioned in the comments, you can press CTRL + F, type =IFNA(INDEX in the Find Box, set the "Within" to "Workbook" and "Look In" to "Formulas", and simply find it. It will directly take you to the cell which has that formula. Then you can edit the formula without unhiding the row.
If you are able to edit the code, I would suggest making some changes to avoid using Select, as discussed here.

Related

Intermittent Run-time Error 1004 or 13 in Excel 365

I am at a loss, I have been working to create this macro to help automate an obnoxious process we have at work and the best way to sum up where it is right now is, 60% of the time it works every time!
The macro takes a workbook with the raw data, reorders the columns, filters out data based on certain criteria, creates separate files for each unique value in one of the columns and then attaches that newly created workbook to an email. The email has text and a logo that is placed into the body of the email. Altogether, when the macro finishes running, it will create anywhere from 7 to 11 separate files and emails.
The problem I am having is when I run the macro, 1 of the following 3 things happens:
No issue, it runs perfectly as expected
I get Run-time error '1004':
Method 'SaveAs' of object '_Workbook' failed
This error happens on this line in the code:
ActiveWorkbook.SaveAs FName
I get Run-time error '13':
Type mismatch
This error happens on this line in the code:
OutMailDocument.Range(0, 1).InsertBefore EmailText
I have tried searching several sites and although I can find information about the errors, I can't seem to find anything that has provided any help in fixing the problem.
I do not know where in my macro I went wrong, but I don't understand why sometimes it works just fine and other times I get one of the 2 errors?
Anyway, I am hoping someone may be able to help provide some guidance as to where I am going wrong. I have posted the full code below for reference:
Sub FeeManagement()
Dim CurrentColumn As Integer
Dim Columnheading As String
Dim lastrow As Long
Dim columnorder As Variant, ndx As Integer
Dim found As Range, counter As Integer
Dim wb As Workbook, ws As Worksheet
Dim lr As Long
Dim i As Integer
Dim ar As Variant
Dim j As Long
Dim rng As Range
Dim OutApp As Object
Dim Outmail As Object
Dim OutMailDocumet As Object
Dim OutShape As Excel.Shape
Dim OutWorksheet As Excel.Worksheet
Dim FName As String
Dim FPath As String
Application.ScreenUpdating = False
ActiveSheet.Cells.Interior.Color = xlNone
Range("A1").End(xlDown).Offset(1).Resize(ActiveSheet.UsedRange.Rows.Count).EntireRow.Delete
ActiveSheet.Cells.Font.Name = "Arial"
ActiveSheet.Cells.Font.Size = "10"
Sheets("Sheet1").Copy before:=Sheets(Sheets.Count)
ActiveSheet.Name = "Original"
Worksheets("Sheet1").Activate
'Remove Unwanted Columns
For CurrentColumn = ActiveSheet.UsedRange.Columns.Count To 1 Step -1
Columnheading = ActiveSheet.UsedRange.Cells(1, CurrentColumn).Value
Select Case Columnheading
Case "Auditor", "Auditor ID", "SAI. Nbr", "Pol. Form", "Pol. Nbr", "Aud. Type", "Days todue date", "Pol. Eff Date", "End Date", "Due Date", "Ins. Name", _
"State", "Market Group", "Scheduled Dt.", "Assigned Date", "CI Date", "Aud. System Key"
Case Else
ActiveSheet.Columns(CurrentColumn).Delete
End Select
Next
'Rearrange Columns
columnorder = Array("Auditor", "Assigned Date", "SAI. Nbr", "Ins Name", "State", "Pol. Eff Date", "End Date", "Due Date", "Pol. Form", "Pol. Nbr", "Days to ue date", _
"MarketGroup", "Aud. Type", "Aud. System Key", "Scheduled DT.", "CI Date", "Auditor ID")
counter = 1
For ndx = LBound(columnorder) To UBound(columnorder)
Set found = Rows("1:1").Find(columnorder(ndx), LookIn:=xlValues, Lookat:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
If Not found Is Nothing Then
If found.Column <> counter Then
found.EntireColumn.Cut
Columns(counter).Insert Shift:=xlToRight
Application.CutCopyMode = False
End If
counter = counter + 1
End If
Next ndx
'Add Due Date Columns and Amend Auditor Column
Range("K1").Value = "Days To Due Date"
Columns("L:L").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
Range("L1").Value = "Days Assigned"
Range("S1").Value = "Sched DT Helper"
Range("T1").Value = "CI Helper"
With Sheets("Sheet1")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
With .Range("K2:K" & lastrow)
.NumberFormat = "0"
End With
With .Range("L2:L" & lastrow)
.Formula = "=-(B2-Today())"
.NumberFormat = "0"
End With
With .Range("S2:S" & lastrow)
.Formula = "=(Q2-Today())"
.NumberFormat = "0"
End With
With .Range("T2:T" & lastrow)
.Formula = "=ABS(Q2-Today())"
.NumberFormat = "0"
End With
End With
Columns("A:B").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
Range("B1").Value = "Auditor"
With Sheets("Sheet1")
lastrow = .Cells(.Rows.Count, "C").End(xlUp).Row
With .Range("B2:B" & lastrow)
.Formula = "=left(C,25)"
End With
End With
Sheets("Sheet1").Columns("B").Copy
Sheets("Sheet1").Columns("A").PasteSpecial Paste:=xlPasteValues
Columns("B:C").EntireColumn.Delete
Worksheets("Sheet1").Columns("A:Z").AutoFit
Worksheets("Sheet1").Range("A1").AutoFilter
'Filter and Delete records based on assigned/due dates & scheduled DT/CI Dates
Set ws = ActiveSheet
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
ws.Range("A1:A20000").AutoFilter Field:=12, Criteria:="<=6"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
ws.Range("A1:A20000").AutoFilter Field:=11, Criteria:=">=30"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
ws.Range("A1:A20000").AutoFilter Field:=19, Criteria:=">=-3"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
ws.Range("A1:A20000").AutoFilter Field:=20, Criteria:="<=6"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
Columns("S:T").EntireColumn.Delete
Columns("P:Q").EntireColumn.Delete
ws.AutoFilter.Sort.SortFields.Clear
ws.AutoFilter.Sort.SortFields.Add2 Key:=Range( _
"K1:K10000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ws.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Columns("P:T").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
Range("P1").Value = "New Status"
Range("Q1").Value = "New Status Text"
Range("R1").Value = "Date"
Range("S1").Value = "New Status Date"
Range("T1").Value = "Host Status"
'Create separate worksheets
Set wb = ActiveWorkbook
Set ws = ActiveSheet
lr = ws.Range("A" & Rows.Count).End(xlUp).Row
Set rng = ws.Range("A1:A" & lr)
j = ws.[A1].CurrentRegion.Columns.Count + 1
rng.AdvancedFilter 2, , ws.Cells(1, j), True
ar = ws.Range(ws.Cells(2, j), ws.Cells(Rows.Count, j).End(xlUp))
ws.Columns(j).Clear
For i = 1 To unbound(ar)
rng.AutoFilter 1, ar(i, 1)
If Not Evaluate("=ISREF('" & ar(i, 1) & "'!A10") Then
Sheets.Add(after:=Sheets(Sheets.Count)).Name = ar(i, 1)
Else
Sheets(ar(i, 1)).Move after:=Sheets(Sheets.Count)
End If
ws.Range("A1:A" & lr).Resize(, j - 1).Copy [A1]
Next
ws.AutoFilterMode = False
Sheet("Sheet1").Name = "Modified"
'Create separate files and email
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "original" And ws.Name <> "Modified" Then
ws.Copy
Workbooks("Fee Management Macro.xlsm").Sheets("List").Copy before:=Sheets(Sheets.Count)
Range("A2:A13").Select
ActiveWorkbook.Names.Add Name:="StatusList", RefersToR1C1:="=List!R2C1:R12C1"
ActiveWorkbook.Names("StatusList").Comment = ""
Worksheets("Lis").Visible = False
Rows("2:2").Select
ActiveWindow.FreezePanes = True
With ActiveSheet
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
With .Range("S2:S" & lastrow)
.Formula = "=Now()"
End With
With .Range("T2:T") & lastrow
.Formula = "=IFERROR(VLOOKUP(RC[-4],List!C[-19]:[C-18],2,FALSE,"""")"
End With
With .Range("P2:P" & lastrow).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=Statuslist"
.IgnoreBlank = False
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = "Select Status"
.ErrorMessage = "Please select status from the list"
.ShowInput = True
.ShowError = True
End With
With .Range("Q2:Q" & lastrow).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=0", Formula2:="460"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = "Max 460 Characters"
.InputMessage = "If black, do not complete"
.ErrorMessage = "Max 460 Characters"
.ShowInput = True
.ShowError = True
End With
With .Range("R2:R" & lastrow).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlGreater, Formula1:="11/1/2012"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = "Invalid Date"
.InputMessage = "If black, do not complete"
.ErrorMessage = "Please enter a valid date."
.ShowInput = True
.ShowError = True
End With
With .Range("P2:P" & lastrow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TintAndShade = 0.599993896298105
.Patterntintshade = 0
End With
With .Range("Q2:Q" & lastrow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
.Patterntintshade = 0
End With
With .Range("R2:R" & lastrow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
.Patterntintshade = 0
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Contacted Insured"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Appointment Date Set"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Close Out Submitted"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Contacted Agent"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Other"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
End With
Rows("1:1").Select
With Selection
.Font.Bold = True
.Font.Underline = xlUnderlineStyleSingle
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
ActiveSheet.Columns("A:Z").AutoFit
ActiveSheet.Columns("A:Z").HorizontalAlignment = xlCenter
ActiveSheet.Columns("A:Z").VerticalAlignment = xlCenter
ActiveSheet.Range("A1").AutoFilter
With ActiveSheet.Sort
.SortFields.Add Key:=Range("K1"), Order:=xlAscending
.Header = xlYes
.Apply
End With
lcol = Cells(1, Columns.Count).End(xlToLeft).Column
lrow = Cells(Rows.Count, "A").End(xlUp).Row
Range(Cells(1, lcol + 1), Cells(Rows.Count, Columns.Count)).EntireColumn.Hidden = True
Range(Cells(lrow + 1, 1), Cells(Rows.Count, Columns.Count)).EntireRow.Hidden = True
Columns("C").Hidden = True
Columns("O").Hidden = True
Columns("S").Hidden = True
Columns("T").Hidden = True
Columns("U").Hidden = True
Range("A1").Select
Selection.AutoFilter
Range("R:R").Select
Selection.NumberFormat = "yyy-mm-dd;#"
Range("H;H,G:G,F;F,B:B").Select
Selection.NumberFormat = "m/d/yyy"
Range("D:D,A:A").Select
Range("A1").Activate
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Rows("1:1").Select
With Selection
.HorizontalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Columns("A:A").ColumnWidth = 25
Columns("D:D").ColumnWidth = 30
Columns("P:P").ColumnWidth = 30
Columns("Q:Q").ColumnWidth = 35
Columns("R:R").ColumnWidth = 10
Range("P:P,Q:Q,R:R").Locked = False
ActiveSheet.Protect Password:="ChrisBrianGreg2020", Userinterfaceonly:=True
FName = ws.Name & ".xlsx"
ActiveWorkbook.SaveAs FName
Set EmailText = Workbooks("Fee Management Macro.xlsm").Sheets("List").Range("M14")
Set OutWorksheet = Workbooks("Fee Management Macro.xlsm").Sheets("List")
Set OutApp = CreateObject("Outlook.Application")
Set Outmail = OutApp.CreateItem(OutAppOutMailItem)
Set OutMailDocument = Outmail.GetInspector.WordEditor
On Error Resume Next
With Outmail
.To = ""
.CC = ""
.BCC = ""
.Subject = "Weekly Inventory Status Update -" & " " & Date & " " & "-" & " " & ws.Name
.Body = ""
.Attachments.Add ActiveWorkbook.FullName
.Display
End With
On Error GoTo 0
'Copy Images to the email
For Each OutShape In OutWorksheet.Shapes
OutShape.Copy
OutMailDocument.Range(0, 1).Paste
Next
OutMailDocument.Range(0, 1).InsertBefore EmailText
Application.CutCopyMode = False
FName = Application.ActiveWorkbook.FullName
ActiveWorkbook.Saved = True
Application.ActiveWorkbook.ChangeFileAccess xlReadOnly
Kill FName
Application.ActiveWorkbook.Close False
End If
Next ws
Set Outmail = Nothing
Set OutApp = Nothing
Application.ScreenUpdating = True
End Subenter code here

How to check if the content of the Target cell is deleted in a Worksheet_Change Event

I want to either delete the validation of a cell or set an empty validation if the Target of Worksheet_Change is deleted.
The Target cell is a merged cell which also has a xlValidateList. If I choose one of the values, my code runs ok, but when I delete the content of this cell, it doesn't change the validation of the other cell.
I think it comes from the merging of the cells or because it has a xlValidateList
I tried to check IsEmpty(Target) but its always FALSE, even if I delete the content of the Target cell
My code so far:
Private Sub Worksheet_Change(ByVal Target As range)
Dim lengthFromCell As range
Dim lengthToCell As range
' only execute when on column F and
If Target.Column <> 6 Or Target.Cells.Count > 1 Then Exit Sub
Set lengthFromCell = Target.Offset(0, 1)
Set lengthToCell = lengthFromCell.Offset(1, 0)
' Delete contents of "length" cells
lengthFromCell.value = ""
lengthToCell.value = ""
If Target.value = "A" Then
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="1, 2, 3"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = ""
.ErrorMessage = ""
.ShowError = True
End With
ElseIf Target.value = "B" Then
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="4, 5, 6"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = ""
.ErrorMessage = ""
.ShowError = True
End With
Else
'here either delete the validation or at least set it to 0 or ""
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="0, 0, 0"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = ""
.ErrorMessage = ""
.ShowError = True
End With
End If
End Sub
EDIT:
"Target" is the target from Worksheet_Change which is of type Range. So it is the merged cell in which my dropdown list with values "A and B" are in.
The main problem is that my code doesn't recognice the deletion of the value "A" in merged cells, but in single cells it does.
Please, try the next function:
Function isMergeEmpty(rng As Range) As Boolean
Dim x As String
On Error Resume Next
x = rng.value
If err.Number <> 0 Then
isMergeEmpty = True
End If
On Error GoTo 0
End Function
It can be called from the event in this way:
Private Sub Worksheet_Change(ByVal Target As Range)
If isMergeEmpty(Target) Then
'do here what you need...
MsgBox "Empty merge cell..."
End if
End Sub
Edited:
Please, test the next full solution:
Private Sub Worksheet_Change(ByVal Target As range)
Dim myList As Object
Set myList = CreateObject("Scripting.Dictionary")
myList.Add "Einseitig", 1
myList.Add "Doppelseitig", 2
myList.Add "Halbzylinder", 3
Dim lengthFromCell As range
Dim lengthToCell As range
' only execute when on column F and no more of one cell (IF Target is NOT merged):
If Target.Column <> 6 Or (Target.Cells.Count > 1 And Target.MergeCells = False) Then Exit Sub
Set lengthFromCell = Target.Offset(0, 1)
Set lengthToCell = lengthFromCell.Offset(1, 0)
Application.EnableEvents = False 'to avoid the event running three times
'it will also be triggered for each of the following lines:
' Delete contents of "length" cells
lengthFromCell.value = ""
lengthToCell.value = ""
If isMergeEmpty(Target) Then 'it should be first, in order to avoid `Target.value` which returns an error for an empty merged range
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="0, 0, 0"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = "Werte ausserhalb Bereich"
.ErrorMessage = "Einseitig bla blub"
.ShowError = True
End With
ElseIf Target.value = "Einseitig" Then
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="1, 2, 3"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = "Werte ausserhalb Bereich"
.ErrorMessage = "Einseitig bla blub"
.ShowError = True
End With
ElseIf Target.value = "Doppelseitig" Then
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="4, 5, 6"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = "Werte ausserhalb Bereich"
.ErrorMessage = "Einseitig bla blub"
.ShowError = True
End With
ElseIf Target.value = "Halbzylinder" Then
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:="7, 8, 9"
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = "Werte ausserhalb Bereich"
.ErrorMessage = "Einseitig bla blub"
.ShowError = True
End With
End If
Application.EnableEvents = True
End Sub
Function isMergeEmpty(rng As range) As Boolean
Dim x As String
On Error Resume Next
x = rng.value
If Err.Number <> 0 Then
isMergeEmpty = True
End If
On Error GoTo 0
End Function
Now, the main problem of our code as it was consisted in the way it was exited, in case of more then one cell. VBA has a peculiar behavior when treats a merged range having a value and *an empty such merged range, in terms of Cells.Count property. You must know that TargetCells.Count returns 1 if it refers a merged range having a value and **the number of cells in the mergeArea if it is empty. That's why the need to add Or (Target.Cells.Count > 1 And Target.MergeCells = False). To exclude from exiting cases of empty merged Target. Your code, as it was, exited on this line and the supplied function was never called.
Then, in order to avoid Target.Value = ..., which returns an error in case of an empty merged Target the checking for an empty Target must be first.
I also optimized the code in order to avoid the event to be triggered three times, instead of one.
If something still unclear, please do not hesitate to ask for clarifications. I alo commented the specific lines inside the code...
Second Edit:
I thought that you created an unmerged example only to show the different behavior against the merged one. But if you need the code to also work in such a case, another condition must be add at the end. Then, the code cam become more compact as the next one:
Private Sub Worksheet_Change(ByVal Target As range)
Dim myList As Object: Set myList = CreateObject("Scripting.Dictionary")
myList.Add "Einseitig", 1: myList.Add "Doppelseitig", 2: myList.Add "Halbzylinder", 3
Dim lengthFromCell As range, lengthToCell As range, strFormula As String
' only execute when on column F and Target.CellsCount =1 (excluding the merged Target):
If Target.Column <> 6 Or (Target.Cells.Count > 1 And Target.MergeCells = False) Then Exit Sub
Set lengthFromCell = Target.Offset(0, 1): Set lengthToCell = lengthFromCell.Offset(1, 0)
Application.EnableEvents = False
' Delete contents of "length" cells
lengthFromCell.value = "": lengthToCell.value = ""
If isMergeEmpty(Target) Then
strFormula = "0, 0, 0"
ElseIf Target.value = "Einseitig" Then
strFormula = "1, 2, 3"
ElseIf Target.value = "Doppelseitig" Then
strFormula = "4, 5, 6"
ElseIf Target.value = "Halbzylinder" Then
strFormula = "7, 8, 9"
ElseIf Target.value = "" Then 'for the case of not merged Target:
strFormula = "0, 0, 0"
End If
If strFormula <> "" Then
With Target.Offset(0, 1).Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:=strFormula
.IgnoreBlank = True
.InCellDropdown = True
.ErrorTitle = "Werte ausserhalb Bereich"
.ErrorMessage = "Einseitig bla blub"
.ShowError = True
End With
End If
Application.EnableEvents = True
End Sub

MS Excel - VBA - Issues with searching a #, then returning relevant cells to different worksheet

I've got a workbook in Excel that I can add orders at my work and it stores into a database. I have another sheet that you can type in an order number (ECO number in the code) and I want it to display the # plus any relevant part numbers. I am having issue getting it to select only the range that I need.
Here is what I have in VBA so far:
Sub PlayMacro()
Dim Prompt As String
Dim RetValue As String
Dim Rng As Range
Dim RowCrnt As Long
Prompt = ""
With Sheets("ECO Database")
Do While True
RetValue = InputBox(Prompt & "Type in ECO#")
If RetValue = "" Then
Exit Do
End If
Set Rng = .Columns("A:A").Find(What:=RetValue, After:=.Range("A1"), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Rng Is Nothing Then
Prompt = "ECO""" & RetValue & """Not Found"
Else
Sheets("ECO Updates").Select
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveWindow.SmallScroll Down:=3
ActiveCell.Range("A1:T49").Select
Selection.Delete Shift:=xlToLeft
Sheets("ECO Database").Select
ActiveCell.Offset(-2, 0).Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
ActiveCell.Range("A:U").Select
Selection.Copy
Sheets("ECO Updates").Select
ActiveCell.Select
ActiveSheet.Paste
End If
Prompt = Prompt & vbLf
Loop
End With
End Sub
I have gotten it to pop up with a dialog box and ask for the number I want. I type it in, and I get errors due to my programming mistakes, or it selects everything in the sheet (All cells) and memory issues arise. I used the macro recorder so you can see that I'm very much a novice.
I have in column A the ECO number that I'm searching for. In Columns B through U I have the data I want. When I add the ECO orders into the database, I've left one blank row between all of them. I thought it would be easier to find where they end, but obviously I'm having difficulty. The reason I want to copy/eventually cut the data is so that any ECO can be adjusted and then "Saved" (Copy/Cut back to the database). Any suggestions would be hugely appreciated!
PS I'm not allowed to add images yet it says, otherwise I would show you what the format is.
Here is what I got as a solution after more time working on this! I have updated my entire sheet with some extras also. This achieves the result I want! Now I'm just struggling getting it to display a msg box with an error rather than a compiling error when I search for something that isn't found. You'll have to ignore the comments behind the ' as that is me trying to get this damn thing to say Not Found. It is coming up with that message when I search for something that DOES exist. A different problem for a different day.
Sub ECO_SEARCH()
Dim val As String
'Dim Rng As Range
'Is B1 empty?
If IsEmpty(Range("B1").value) = True Then
MsgBox "Please enter an ECO#"
Range("A3:T150").Select
Selection.ClearContents
GoTo LastLine
End If
Sheets("ECO Updates").Select
Range("A3:T150").Select
Selection.Delete Shift:=xlToLeft
ActiveWindow.SmallScroll Down:=-21
Range("B1").Select
val = Range("B1").value
'ActiveCell.FormulaR1C1 = "B1"""
Sheets("ECO Database").Select
Range("A3").Select
Cells.Find(What:=val, After:=ActiveCell, LookIn:=xlFormulas2, LookAt _
:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase _
:=False, SearchFormat:=False).Activate
'If Not Rng Is Nothing Then
' MsgBox "ECO# Not Found!"
' GoTo LastLine
'End If
ActiveCell.Offset(0, 1).Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight).Offset(0, 18)).Select
Selection.Copy
Sheets("ECO Updates").Select
Range("A3").Select
ActiveSheet.Paste
Range("A3:T150").HorizontalAlignment = xlCenter
Range("A3:T150").Font.Size = 10
Range("A3:T150").Font.Bold = False
Range("A3:T150").Borders(xlEdgeBottom).Weight = xlThin
Range("A3:T150").Borders(xlEdgeTop).Weight = xlThin
Range("A3:T150").Borders(xlEdgeLeft).Weight = xlThin
Range("A3:T150").Borders(xlEdgeRight).Weight = xlThin
Range("A3:T150").Borders(xlInsideHorizontal).Weight = xlThin
Range("A3:T150").Borders(xlInsideVertical).Weight = xlThin
Range("A3:T150").Borders(xlEdgeBottom).LineStyle = xlContinuous
Range("A3:T150").Borders(xlEdgeTop).LineStyle = xlContinuous
Range("A3:T150").Borders(xlEdgeLeft).LineStyle = xlContinuous
Range("A3:T150").Borders(xlEdgeRight).LineStyle = xlContinuous
Range("A3:T150").Borders(xlInsideHorizontal).LineStyle = xlContinous
Range("A3:T150").Borders(xlInsideVertical).LineStyle = xlContinous
Range("A3:T150").Borders(xlEdgeBottom).Color = vbBlack
Range("A3:T150").Borders(xlEdgeTop).Color = vbBlack
Range("A3:T150").Borders(xlEdgeLeft).Color = vbBlack
Range("A3:T150").Borders(xlEdgeRight).Color = vbBlack
Range("A3:T150").Borders(xlInsideHorizontal).Color = vbBlack
Range("A3:T150").Borders(xlInsideVertical).Color = vbBlack
Range("A3:T150").HorizontalAlignment = xlCenter
Range("A3:T150").VerticalAlignment = xlCenter
LastLine:
End Sub

Receiving "Compile Error: Next without For" when attempting to insert new formatting instructions to existing code

I have made an amendment to existing code (my insertion double asterisk below). The existing code works fine without my addition, and I'm not sure why once including the additional cell border formatting I receive the above prompt, "Compile Error: Next without For". The line of code where I am receiving this error message is also double asterisk. I have looked through existing threads and none of the advice seems applicable. Please can someone assist? Thanks!
`For Each WS In Worksheets
'This code will delete the debt financing in the Property Summary tab
With Worksheets("Property Summary").Activate
'Range might need to be updated if it has moved around due to AE
version updates.
Range("E27:H36").Delete
Range("E27:H36").Select
Selection.ClearContents
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
Selection.Borders(xlEdgeLeft).LineStyle = xlNone
Selection.Borders(xlEdgeTop).LineStyle = xlNone
Selection.Borders(xlEdgeBottom).LineStyle = xlNone
Selection.Borders(xlEdgeRight).LineStyle = xlNone
Selection.Borders(xlInsideVertical).LineStyle = xlNone
Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
With Selection.Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
**Range("E26:H26").Select
Selection.Border(xlEdgeLeft).LineStyle = xlNone
Selection.Border(xlEdgeRight).LineStyle = xlNone
With Selection.Border(xlEdgeTop)
.Pattern = xlContinuous
.TintAndShade = 5
.Weight = xlThin
End With**
'This code will clean up the Cash Flow Report tab
With Worksheets("Cash Flow").Activate
'Range might need to be updated if it has moved around due to AE version updates
Range("A2").Select
Cells.Replace What:=" (Amounts in EUR)", Replacement:="", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:=" (Amounts in PLN)", Replacement:="", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:=" (Amounts in USD)", Replacement:="", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
NomProperty = Range("A2").Value
'Blue
Range("B8:L8").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With
'Clean Up
'This will unmerge the first 4 rows (A1:M4) and delete columns M:Z
Range("A1:M4").Select
Selection.UnMerge
Columns("L:Z").Select
Selection.Delete Shift:=xlToLeft
'This will delete unwanted rows and minimize rows
For i = 9 To 100
If Cells(i, 1).Value = "" Or Cells(i, 1).Value = " " Or Cells(i, 1).Value = " " Or
Cells(i, 1).Value = " " Or Cells(i, 1).Value = " " Then
Rows(i).RowHeight = 3
GoTo Following
End If
If Cells(i, 1).Value = " Scheduled Base Rent" Then GoTo Following
If Cells(i, 1).Value = " CPI Increases" Then GoTo Following
If Cells(i, 1).Value = " Free CPI Increases" Then GoTo Following
If Cells(i, 1).Value = "Total Rental Revenue" Then GoTo Following
If Cells(i, 1).Value = "Total Other Revenue" Then GoTo Following
If Cells(i, 1).Value = "Potential Gross Revenue" Then GoTo Following
If Cells(i, 1).Value = "Total Vacancy & Credit Loss" Then GoTo Following
If Cells(i, 1).Value = "Effective Gross Revenue" Then GoTo Following
If Cells(i, 1).Value = "Net Operating Income" Then GoTo Following
If Cells(i, 1).Value = " Total Capital Expenditures" Then GoTo Following
If Cells(i, 1).Value = "Total Leasing & Capital Costs" Then GoTo Following
If Cells(i, 1).Value = "Cash Flow Before Debt Service" Then GoTo Following
If Cells(i, 1).Value = "Cash Flow Available for Distribution" Then GoTo Following
If Cells(i, 1).Value = "Total Other Tenant Revenue" Then GoTo Following
If Cells(i, 1).Value = "Total Tenant Revenue" Then GoTo Following
If Cells(i, 1).Value = "Total Operating Expenses" Then GoTo Following
If Cells(i, 1).Value = "Property Resale" Then GoTo Following
If Cells(i, 1).Value = "Total Cash Flow" Then GoTo Following
Rows(i).Delete Shift:=xlUp
i = i - 1
Rows(9).RowHeight = 12.75
Following:
Next
DATABASE_LOC = "C:\Users\32948\Desktop\Cockpit\Cockpit"
If IsFileOpen(DATABASE_LOC & "\Cashflow Appendix.xlsx") Then
Windows("Cashflow Appendix.xlsx").Activate
Else
Set WbDatabase = Workbooks.Open(DATABASE_LOC & "\Cashflow Appendix.xlsx")
End If
WB_Appendix_Name = "Cashflow Appendix.xlsx"
Windows(WB_Appendix_Name).Activate
Columns("A:Z").Select
Selection.Delete Shift:=xlUp
Cells.Select
Selection.Copy
Windows(WB_Appendix_Name).Activate
Cells.Select
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close
Set WbDatabase = Nothing
End With
**Next WS**
ActiveWorkbook.Save
ActiveWorkbook.Close True
Application.StatusBar = MyFile & " closed."
'read next filename
MyFile = Dir()
Loop`
With Worksheets("Property Summary").Activate
the Activate method doesn't return anything you can use in your With block
? typename(activesheet.activate) '>>Boolean
And you're not using the WS from your outer loop.
Were did you get the code you inserted from? I wasn't able to run just the insertion in sa sample macro, but this ran
Sub topborder()
Range("E26:H26").Select
Selection.Borders(xlEdgeLeft).LineStyle = xlNone
Selection.Borders(xlEdgeRight).LineStyle = xlNone
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.TintAndShade = 0
.Weight = xlThin
End With
End Sub

VBA code in excel runs slow on Activate event in worksheet. Need to improve performance please

I am trying to protect rows, set dropdown list dynamically on Worksheet_Activate event but my code for 1000 rows takes 15 mins to open the worksheet as it keeps spinning. When I switch between tabs I want to be able to set the dropdowns, disable rows and set color on the rows.Can you tell how I can improve the performance of the worksheet while being able to achieve the mentioned objective.?
Sub DisableOsIs()
On Error Resume Next
Dim NoOfDataRows As Integer
Dim RngOP, RngIL, RngL, RngM, RngN, RngO, RngP, RngQ, RngR, RngLockAll As Range
Dim cell As Range
'ActiveSheet.Unprotect Password:="1234"
'Set NoOfDataRows = ActiveSheet.UsedRange.Rows.Count
Set RngOP = Range("P5:P" & ActiveSheet.UsedRange.Rows.Count)
Set RngIL = Range("I5:I" & ActiveSheet.UsedRange.Rows.Count)
Set RngL = Range("L5:L" & ActiveSheet.UsedRange.Rows.Count)
Set RngM = Range("M5:M" & ActiveSheet.UsedRange.Rows.Count)
Set RngN = Range("N5:N" & ActiveSheet.UsedRange.Rows.Count)
Set RngO = Range("O5:O" & ActiveSheet.UsedRange.Rows.Count)
Set RngP = Range("P5:P" & ActiveSheet.UsedRange.Rows.Count)
Set RngQ = Range("Q5:Q" & ActiveSheet.UsedRange.Rows.Count)
Set RngR = Range("R5:R" & ActiveSheet.UsedRange.Rows.Count)
Set RngLockAll = Range("A" & ActiveSheet.UsedRange.Rows.Count + 1 & ":R" & ActiveSheet.UsedRange.Rows.Count + 1000)
Call SetLEDWattageList(RngL)
Call SetColorTemperatureList(RngM)
Call SetLShield(RngN)
Call SetRemoveSLModifyAList(RngO)
Call SetRemoveSLModifyAList(RngP)
Call SetALengthList(RngQ)
Call SetArmDModList(RngR)
Call DisableLED(RngIL)
Call LockAll(RngLockAll)
End Sub
Sub LockAll(ByVal Target As Range)
On Error Resume Next
ActiveSheet.Unprotect Password:="1234"
With Cells(Target.Row, Target.Column)
.Locked = True
End With
ActiveSheet.Protect Password:="1234"
End Sub
Sub SetLEDWattageList(ByVal Target As Range)
With Cells(Target.Row, Target.Column)
.Locked = False
With .Validation
.Delete
'replace "=A1:A6" with the range the data is in.
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!D2:D5"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
End Sub
Sub SetColorTemperatureList(ByVal Target As Range)
With Cells(Target.Row, Target.Column)
.Locked = False
With .Validation
.Delete
'replace "=A1:A6" with the range the data is in.
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!E2:E3"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
End Sub
Sub SetLShield(ByVal Target As Range)
With Cells(Target.Row, Target.Column)
.Locked = False
With .Validation
.Delete
'replace "=A1:A6" with the range the data is in.
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!A2:A4"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
End Sub
Sub SetRemoveSLModifyAList(ByVal Target As Range)
With Cells(Target.Row, Target.Column)
.Locked = False
With .Validation
.Delete
'replace "=A1:A6" with the range the data is in.
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!I2:I3"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
End Sub
Sub SetALengthList(ByVal Target As Range)
With Cells(Target.Row, Target.Column)
.Locked = False
With .Validation
.Delete
'replace "=A1:A6" with the range the data is in.
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!F2:F4"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
End Sub
Sub SetArmDModList(ByVal Target As Range)
With Cells(Target.Row, Target.Column)
.Locked = False
With .Validation
.Delete
'replace "=A1:A6" with the range the data is in.
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!G2:G9"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
End Sub
'I am passing in a range and checking if the value is LED and color the 'successive columns and protect them.
Sub DisableLED(ByVal Target As Range)
On Error Resume Next
'Check if Target cell in the "Make a selection" range is changed
If Not Intersect(Target, Range("I5:O" & ActiveSheet.UsedRange.Rows.Count)) Is Nothing Then
' ActiveSheet.Cells.Locked = False
If Target.Value = "LED" Then
ActiveSheet.Unprotect Password:="1234"
'Dropdown and error message on cells 2 and 3 columns left of "Make a selection" will be enabled
With Cells(Target.Row, Target.Column + 1)
.Interior.Color = RGB(255, 255, 204)
'.Value = vbNullString
End With
With Cells(Target.Row, Target.Column + 2)
.Interior.Color = RGB(255, 255, 204)
'.Value = vbNullString
End With
With Cells(Target.Row, Target.Column + 3)
.Interior.Color = RGB(217, 217, 217)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
With Cells(Target.Row, Target.Column + 4)
.Interior.Color = RGB(217, 217, 217)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
With Cells(Target.Row, Target.Column + 5)
.Interior.Color = RGB(217, 217, 217)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
With Cells(Target.Row, Target.Column + 6)
.Interior.Color = RGB(217, 217, 217)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
With Cells(Target.Row, Target.Column + 7)
.Interior.Color = RGB(217, 217, 217)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
With Cells(Target.Row, Target.Column + 8)
.Interior.Color = RGB(221, 217, 196)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
With Cells(Target.Row, Target.Column + 9)
.Interior.Color = RGB(221, 217, 196)
.Value = vbNullString
With .Validation
.InCellDropdown = False
.ShowError = False
End With
End With
Target.Locked = False
'Range(Target.Row & ":" & Target.Column).Cells.Locked = False
Cells(Target.Row, Target.Column + 1).Locked = True
Cells(Target.Row, Target.Column + 2).Locked = True
Cells(Target.Row, Target.Column + 3).Locked = True
Cells(Target.Row, Target.Column + 4).Locked = True
Cells(Target.Row, Target.Column + 5).Locked = True
Cells(Target.Row, Target.Column + 6).Locked = True
Cells(Target.Row, Target.Column + 7).Locked = True
Cells(Target.Row, Target.Column + 8).Locked = True
Cells(Target.Row, Target.Column + 9).Locked = True
ActiveSheet.Protect Password:="1234" 'Contents:=True, DrawingObjects:=False
End If
End If
End Sub
At the first glance, your code does not need the functions you call loosing time calling them cell by cell. For instance, the first three calls can be replaced, making the code more efficient, by simple doing that:
Dim RngIL As Range, RngM As Range, RngN As Range, lastRow As Long
Dim sh As Worksheet
Set sh = ActiveSheet 'You have to define sh according to your sheet name
sh.Unprotect "1234"
lastRow = sh.Cells(sh.Rows.count, "M").End(xlUp).Row
Set RngIL = sh.Range("I5:I" & lastRow): RngIL.Locked = False
With RngIL.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!D$2:D$5"
.IgnoreBlank = True
.InCellDropdown = True
.ShowInput = True
.ShowError = True
End With
Set RngM = sh.Range("M5:M" & lastRow): RngM.Locked = False
With RngM.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!E$2:E$3"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ShowInput = True
.ShowError = True
End With
Set RngN = sh.Range("N5:N" & lastRow): RngN.Locked = False
With RngM.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="=listone!A$2:A$4"
.IgnoreBlank = True
.InCellDropdown = True
.ShowInput = True
.ShowError = True
End With
'do here the locking procedure if you consider it makes sense...
sh.Protect "1234"
'and so on for all ranges where you must change their cells in the same way...
And a simpler/shorter piece of code doing the same, but un-protecting the sheet:
Sub testSimplified()
Dim RngIL As Range, RngM As Range, RngN As Range, lastRow As Long, cel As Range
Dim sh As Worksheet
Set sh = ActiveSheet 'You have to define sh according to your sheet name
sh.Unprotect "1234"
lastRow = sh.Cells(sh.Rows.count, "M").End(xlUp).Row
Set RngIL = sh.Range("I5:I" & lastRow): RngIL.Locked = False
ChangeValidation RngIL, "=listone!D$2:D$5"
Set RngM = sh.Range("M5:M" & lastRow): RngM.Locked = False
ChangeValidation RngM, "=listone!E$2:E$3"
Set RngN = sh.Range("N5:N" & lastRow): RngN.Locked = False
ChangeValidation RngN, "=listone!A$2:A$4"
'do here the locking procedure...
For Each cel In RngIL
If cel.value = "LED" Then
DisableLED cel, sh
End If
Next
sh.Protect "1234"
End Sub
Sub ChangeValidation(rng As Range, strCondition As String)
With rng.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=strCondition
.IgnoreBlank = True
.InCellDropdown = True
.ShowInput = True
.ShowError = True
End With
End Sub
Sub DisableLED(ByVal Target As Range, sh As Worksheet)
With sh.Range(Target.Offset(0, 1).Address & ":" & Target.Offset(0, 2).Address)
.Interior.Color = RGB(255, 255, 204)
End With
With sh.Range(Target.Offset(0, 3).Address & ":" & Target.Offset(0, 7).Address)
.Interior.Color = RGB(217, 217, 217)
.Validation.Delete
End With
With sh.Range(Target.Offset(0, 8).Address & ":" & Target.Offset(0, 9).Address)
.Interior.Color = RGB(221, 217, 196)
.Validation.Delete
End With
sh.Range(Target.Offset(0, 1).Address & ":" & Target.Offset(0, 9).Address).Locked = True
End Sub
You must take care of making the validation range absolute (using '$' in front of the validation range row)...
A even better way would be to use named ranges.
No need of un-protect in the called sub due to the fact that the sheet has been un-protected at the beginning of the code.

Resources