Hiding multiple columns in Excel based on the value of a cell - vba

I am trying to get columns to hide in a worksheet based on the value in a certain cell. This value could range from 1 to 30, and different columns are hidden for each possible option. I have the following code, but it doesn't seem to work all the time, and then sometimes it only hides some of the columns in the range, but not all (like if 5 was in cell AA1, then sometimes AN:AR will hide and AS:FC will not be hidden). If anyone has any ideas, I would appreciate the help. Thanks!
I have a sample workbook at: https://drive.google.com/file/d/0B8qPItN2DU0BZ3B0LW1XUS1BMFk/view?usp=sharing
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("AA1").Value = 1 Then
Columns("O:FC").EntireColumn.Hidden = True
Else
Columns("O:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 2 Then
Columns("T:FC").EntireColumn.Hidden = True
Else
Columns("T:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 3 Then
Columns("Y:FC").EntireColumn.Hidden = True
Else
Columns("Y:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 4 Then
Columns("AD:FC").EntireColumn.Hidden = True
Else
Columns("AD:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 5 Then
Columns("AI:FC").EntireColumn.Hidden = True
Else
Columns("AI:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 6 Then
Columns("AN:FC").EntireColumn.Hidden = True
Else
Columns("AN:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 7 Then
Columns("AS:FC").EntireColumn.Hidden = True
Else
Columns("AS:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 8 Then
Columns("AX:FC").EntireColumn.Hidden = True
Else
Columns("AX:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 9 Then
Columns("BC:FC").EntireColumn.Hidden = True
Else
Columns("BC:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 10 Then
Columns("BH:FC").EntireColumn.Hidden = True
Else
Columns("BH:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 11 Then
Columns("BM:FC").EntireColumn.Hidden = True
Else
Columns("BM:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 12 Then
Columns("BR:FC").EntireColumn.Hidden = True
Else
Columns("BR:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 13 Then
Columns("BW:FC").EntireColumn.Hidden = True
Else
Columns("BW:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 14 Then
Columns("CB:FC").EntireColumn.Hidden = True
Else
Columns("CB:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 15 Then
Columns("CG:FC").EntireColumn.Hidden = True
Else
Columns("CG:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 16 Then
Columns("CL:FC").EntireColumn.Hidden = True
Else
Columns("CL:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 17 Then
Columns("CQ:FC").EntireColumn.Hidden = True
Else
Columns("CQ:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 18 Then
Columns("CV:FC").EntireColumn.Hidden = True
Else
Columns("CV:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 19 Then
Columns("DA:FC").EntireColumn.Hidden = True
Else
Columns("DA:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 20 Then
Columns("DF:FC").EntireColumn.Hidden = True
Else
Columns("DF:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 21 Then
Columns("DK:FC").EntireColumn.Hidden = True
Else
Columns("DK:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 22 Then
Columns("DP:FC").EntireColumn.Hidden = True
Else
Columns("DP:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 23 Then
Columns("DU:FC").EntireColumn.Hidden = True
Else
Columns("DU:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 24 Then
Columns("DZ:FC").EntireColumn.Hidden = True
Else
Columns("DZ:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 25 Then
Columns("EE:FC").EntireColumn.Hidden = True
Else
Columns("EE:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 26 Then
Columns("EJ:FC").EntireColumn.Hidden = True
Else
Columns("EJ:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 27 Then
Columns("EO:FC").EntireColumn.Hidden = True
Else
Columns("EO:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 28 Then
Columns("ET:FC").EntireColumn.Hidden = True
Else
Columns("ET:FC").EntireColumn.Hidden = False
End If
If Range("AA1").Value = 29 Then
Columns("EY:FC").EntireColumn.Hidden = True
Else
Columns("EY:FC").EntireColumn.Hidden = False
End If
End Sub

Seems like there's a pattern of 5 columns per integer increase in the value in AA1, so:
Dim v, sht
Set sht = ActiveSheet
v = sht.Range("AA1").Value
sht.Columns("O:FC").EntireColumn.Hidden = False
If v >= 1 And v <= 30 Then
sht.Range(sht.Cells(1, 10+(5*v)), _
sht.Range("FC1")).EntireColumn.Hidden = True
End If
Although it's not particularly clear from the question exactly what the logic for hiding/showing is.

You are hiding a range of columns, and as your code is executed you are hiding, then re-displaying a lot of the columns.
You would be better to firstly display all columns in the largest range (O:FC) in your example, and then only hide the ones that match your value. So you could change the if else constructs to be a select case like this:
Columns("O:FC").EntireColumn.Hidden = False
select case Range("AA1").Value
case 1:
Columns("O:FC").EntireColumn.Hidden = True
case 2:
Columns("T:FC").EntireColumn.Hidden = True
' Add extra cases for each possible value
end select

Related

VBA Procedure too large; having trouble running a sub procedure

I've divided an excel worksheet into different sections, each section being 20 rows in size (example: Section 1 = rows 132 to 152, Section 2 = rows 153 to 173, etc.). There are 100 sections. I'm running a procedure in VBA that, for each section, will hide a certain number of rows based on a desired number of rows for each section. After about running the routine on 23 sections, I get a "Procedure too Large" error. I was told that I should run a sub procedure to solve the problem. I'm not sure how to do that. I'm using Sub proc1(), but it's not working. Here is the first part of the code, followed by the Sub proc1(). It's not working. I'm now getting the following error immediately after the Sup proc1() line:
Ambiguous name detected: Worksheet_Change
If anyone can help me with the proper code after the Sub proc1() that would help immensely!
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveSheet.Unprotect
ActiveSheet.Activate
If Not Application.Intersect(Range("G20"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "0": Rows("132:152").EntireRow.Hidden = True
Case Is = "1": Rows("134:152").EntireRow.Hidden = True
Rows("123:133").EntireRow.Hidden = False
Case Is = "2": Rows("135:152").EntireRow.Hidden = True
Rows("123:134").EntireRow.Hidden = False
Case Is = "3": Rows("136:152").EntireRow.Hidden = True
Rows("123:135").EntireRow.Hidden = False
Case Is = "4": Rows("137:152").EntireRow.Hidden = True
Rows("123:136").EntireRow.Hidden = False
Case Is = "5": Rows("138:152").EntireRow.Hidden = True
Rows("123:137").EntireRow.Hidden = False
Case Is = "6": Rows("139:152").EntireRow.Hidden = True
Rows("123:138").EntireRow.Hidden = False
Case Is = "7": Rows("140:152").EntireRow.Hidden = True
Rows("123:139").EntireRow.Hidden = False
Case Is = "8": Rows("141:152").EntireRow.Hidden = True
Rows("123:140").EntireRow.Hidden = False
Case Is = "9": Rows("142:152").EntireRow.Hidden = True
Rows("123:141").EntireRow.Hidden = False
Case Is = "10": Rows("143:152").EntireRow.Hidden = True
Rows("123:142").EntireRow.Hidden = False
Case Is = "11": Rows("144:152").EntireRow.Hidden = True
Rows("123:143").EntireRow.Hidden = False
Case Is = "12": Rows("145:152").EntireRow.Hidden = True
Rows("123:144").EntireRow.Hidden = False
Case Is = "13": Rows("146:152").EntireRow.Hidden = True
Rows("123:145").EntireRow.Hidden = False
Case Is = "14": Rows("147:152").EntireRow.Hidden = True
Rows("123:146").EntireRow.Hidden = False
Case Is = "15": Rows("148:152").EntireRow.Hidden = True
Rows("123:147").EntireRow.Hidden = False
Case Is = "16": Rows("149:152").EntireRow.Hidden = True
Rows("123:148").EntireRow.Hidden = False
Case Is = "17": Rows("150:152").EntireRow.Hidden = True
Rows("123:149").EntireRow.Hidden = False
Case Is = "18": Rows("151:152").EntireRow.Hidden = True
Rows("123:150").EntireRow.Hidden = False
Case Is = "19": Rows("152:152").EntireRow.Hidden = True
Rows("123:151").EntireRow.Hidden = False
Case Is = "20": Rows("123:152").EntireRow.Hidden = False
End Select
End If
and so on...then:
If Not Application.Intersect(Range("G43"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "0": Rows("615:635").EntireRow.Hidden = True
Case Is = "1": Rows("617:635").EntireRow.Hidden = True
Rows("615:616").EntireRow.Hidden = False
Case Is = "2": Rows("618:635").EntireRow.Hidden = True
Rows("615:617").EntireRow.Hidden = False
Case Is = "3": Rows("619:635").EntireRow.Hidden = True
Rows("615:618").EntireRow.Hidden = False
Case Is = "4": Rows("620:635").EntireRow.Hidden = True
Rows("615:619").EntireRow.Hidden = False
Case Is = "5": Rows("621:635").EntireRow.Hidden = True
Rows("615:620").EntireRow.Hidden = False
Case Is = "6": Rows("622:635").EntireRow.Hidden = True
Rows("615:621").EntireRow.Hidden = False
Case Is = "7": Rows("623:635").EntireRow.Hidden = True
Rows("615:622").EntireRow.Hidden = False
Case Is = "8": Rows("624:635").EntireRow.Hidden = True
Rows("615:623").EntireRow.Hidden = False
Case Is = "9": Rows("625:635").EntireRow.Hidden = True
Rows("615:624").EntireRow.Hidden = False
Case Is = "10": Rows("626:635").EntireRow.Hidden = True
Rows("615:625").EntireRow.Hidden = False
Case Is = "11": Rows("627:635").EntireRow.Hidden = True
Rows("615:626").EntireRow.Hidden = False
Case Is = "12": Rows("628:635").EntireRow.Hidden = True
Rows("615:627").EntireRow.Hidden = False
Case Is = "13": Rows("629:635").EntireRow.Hidden = True
Rows("615:628").EntireRow.Hidden = False
Case Is = "14": Rows("630:635").EntireRow.Hidden = True
Rows("615:629").EntireRow.Hidden = False
Case Is = "15": Rows("631:635").EntireRow.Hidden = True
Rows("615:630").EntireRow.Hidden = False
Case Is = "16": Rows("632:635").EntireRow.Hidden = True
Rows("615:631").EntireRow.Hidden = False
Case Is = "17": Rows("633:635").EntireRow.Hidden = True
Rows("615:632").EntireRow.Hidden = False
Case Is = "18": Rows("634:635").EntireRow.Hidden = True
Rows("615:633").EntireRow.Hidden = False
Case Is = "19": Rows("635:635").EntireRow.Hidden = True
Rows("615:634").EntireRow.Hidden = False
Case Is = "20": Rows("615:635").EntireRow.Hidden = False
End Select
End If
Call proc1
Call proc2
End Sub
Sub proc1()
If Not Application.Intersect(Range("G44"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "0": Rows("636:656").EntireRow.Hidden = True
Case Is = "1": Rows("638:656").EntireRow.Hidden = True
Rows("636:637").EntireRow.Hidden = False
Case Is = "2": Rows("639:656").EntireRow.Hidden = True
Rows("636:638").EntireRow.Hidden = False
Case Is = "3": Rows("640:656").EntireRow.Hidden = True
Rows("636:639").EntireRow.Hidden = False
Case Is = "4": Rows("641:656").EntireRow.Hidden = True
Rows("636:640").EntireRow.Hidden = False
Case Is = "5": Rows("642:656").EntireRow.Hidden = True
Rows("636:641").EntireRow.Hidden = False
Case Is = "6": Rows("643:656").EntireRow.Hidden = True
Rows("636:642").EntireRow.Hidden = False
Case Is = "7": Rows("644:656").EntireRow.Hidden = True
Rows("636:643").EntireRow.Hidden = False
Case Is = "8": Rows("645:656").EntireRow.Hidden = True
Rows("636:644").EntireRow.Hidden = False
Case Is = "9": Rows("646:656").EntireRow.Hidden = True
Rows("636:645").EntireRow.Hidden = False
Case Is = "10": Rows("647:656").EntireRow.Hidden = True
Rows("636:646").EntireRow.Hidden = False
Case Is = "11": Rows("648:656").EntireRow.Hidden = True
Rows("636:647").EntireRow.Hidden = False
Case Is = "12": Rows("649:656").EntireRow.Hidden = True
Rows("636:648").EntireRow.Hidden = False
....and so on
You can use a loop and a some math to reduce your code a lot:
Private Sub Worksheet_Change(ByVal Target As Range)
Const BLOCK_SIZE As Long = 20 '(+1 header)
Dim n As Long, i As Long, rngCheck As Range, c As Range, rStart As Long
Me.Unprotect 'use Me to refer to the sheet itself
Set rngCheck = Me.Range("G20") 'first cell to check
rStart = 132 'start row (header) for section 1
For i = 1 To 100
Set c = Application.Intersect(rngCheck, Target) 'Target intersects with cell being checked?
If Not c Is Nothing Then
n = c.Value
If n > BLOCK_SIZE Then n = BLOCK_SIZE 'limit number of rows to show
Me.Cells(rStart, 1).Resize(BLOCK_SIZE + 1).EntireRow.Hidden = True 'hide all
If n > 0 Then Me.Cells(rStart, 1).Resize(n + 1).EntireRow.Hidden = False 'unhide the ones we want
End If
Set rngCheck = rngCheck.Offset(1, 0) 'next cell to check
rStart = rStart + (BLOCK_SIZE + 1) 'next block starting row
Next i
End Sub

hide/unhide many textboxes on a form based on combo value in ms-access (userform)

I currently have too many if statements; what is the best solution to coding hiding and unhiding about textboxes, I think I have 8 or more combinations here is the current code I have when trying this it only works with the last if statement combinations are as follows A-D, and all combinations between.:
If Combo308.Value = "A" Then
Combo305.Visible = True
Option103.Visible = True
Else
Combo305.Visible = False
Option103.Visible = False
End If
If Combo308.Value = "B" Then
Combo306.Visible = True
Option105.Visible = True
Else
Combo306.Visible = False
Option105.Visible = False
End If
If Combo308.Value = "D" Then
Combo309.Visible = True
Option111.Visible = True
Text310.Visible = True
Option113.Visible = True
Combo311.Visible = True
Option115.Visible = True
Text312.Visible = True
Option117.Visible = True
Text313.Visible = True
Option119.Visible = True
Combo314.Visible = True
Option121.Visible = True
Text315.Visible = True
Option123.Visible = True
Text316.Visible = True
Option125.Visible = True
Text317.Visible = True
Option127.Visible = True
Text318.Visible = True
Option129.Visible = True
Text319.Visible = True
Option131.Visible = True
Else
Combo309.Visible = False
Option111.Visible = False
Text310.Visible = False
Option113.Visible = False
Combo311.Visible = False
Option115.Visible = False
Text312.Visible = False
Option117.Visible = False
Text313.Visible = False
Option119.Visible = False
Combo314.Visible = False
Option121.Visible = False
Text315.Visible = False
Option123.Visible = False
Text316.Visible = False
Option125.Visible = False
Text317.Visible = False
Option127.Visible = False
Text318.Visible = False
Option129.Visible = False
Text319.Visible = False
Option131.Visible = False
End If
If Combo308.Value = "A,B" Then
Combo305.Visible = True
Option103.Visible = True
Combo306.Visible = True
Option105.Visible = True
Else
Combo305.Visible = False
Option103.Visible = False
Combo306.Visible = False
Option105.Visible = False
End If
If Combo308.Value = "A,B,C" Then
Combo305.Visible = True
Option103.Visible = True
Combo306.Visible = True
Option105.Visible = True
Combo307.Visible = True
Option109.Visible = True
Else
Combo305.Visible = False
Option103.Visible = False
Combo306.Visible = False
Option105.Visible = False
Combo307.Visible = False
Option109.Visible = False
End If
I guess you need first hide all controls, then unhide a selection:
Combo305.Visible = False
Option103.Visible = False
' etc. - all controls in question.
Select Case Combo308.Value
Case "A"
Combo305.Visible = True
Option103.Visible = True
Case "B"
Combo306.Visible = True
Option105.Visible = True
Case "D"
' etc.
'
Case "A,B,C"
Combo305.Visible = True
Option103.Visible = True
Combo306.Visible = True
Option105.Visible = True
Combo307.Visible = True
Option109.Visible = True
End Select
And do rename all your controls to have meaningful names.

Code for pivot table in VBA only works one time

I have a sheet with 1532 rows and 7 columns called "Delayed Students". I want to make a pivot table in the sheet but every time I use my code, I get a
run-time error'438 "Object doesn't support this property or method"
And this area is yellow (.Position =1):
With .PivotFields("FACULTY_ID")
.Orientation = xlDataField
.Postion = 1
But it creates the pivot table anyways. The problem is when i delete the table and try to use the code again it doesn't create the pivot table again. So something must be wrong with my code:
Sub Pivot1()
Dim PvtTbl As PivotTable
Dim PvtCache As PivotCache
Dim PvtTblName As String
Dim pivotTableWs As Worksheet
PvtTblName = "pivotTableName"
Set pivotTableWs = Sheets("Delayed Students")
Set PvtCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:="Delayed Students!R1C1:R1532C7")
Set PvtTbl = pivotTableWs.PivotTables.Add(PivotCache:=PvtCache, TableDestination:=pivotTableWs.Range("J1"), TableName:=PvtTblName)
With PvtTbl
.ColumnGrand = True
.HasAutoFormat = True
.DisplayErrorString = False
.DisplayNullString = True
.EnableDrilldown = True
.ErrorString = ""
.MergeLabels = False
.NullString = ""
.PageFieldOrder = 2
.PageFieldWrapCount = 0
.PreserveFormatting = True
.RowGrand = True
.SaveData = True
.PrintTitles = False
.RepeatItemsOnEachPrintedPage = True
.TotalsAnnotation = False
.CompactRowIndent = 1
.InGridDropZones = False
.DisplayFieldCaptions = True
.DisplayMemberPropertyTooltips = False
.DisplayContextTooltips = True
.ShowDrillIndicators = True
.PrintDrillIndicators = False
.AllowMultipleFilters = False
.SortUsingCustomLists = True
.FieldListSortAscending = False
.ShowValuesRow = False
.CalculatedMembersInFilters = False
.RowAxisLayout xlCompactRow
With .PivotCache
.RefreshOnFileOpen = False
.MissingItemsLimit = xlMissingItemsDefault
End With
.RepeatAllLabels xlRepeatLabels
With .PivotFields("STUDYBOARD_ID")
.Orientation = xlRowField
.Position = 1
End With
With .PivotFields("FACULTY_ID")
.Orientation = xlDataField
.Postion = 1
End With
End With
End Sub
Hope someone can help me with what i am doing wrong :)

Looking for ways to simplify my code

I'm having trouble adding another function in that macro I used to activate or deactivate columns in a Excel Workbook we are using at work. I'm getting the Out of stack space error when running it just adding one of the following function.
Mostly, I've used an If( ;1;0) to manage the activation part and an If(;TRUE;FALSE) for the locked/unlocked part. The function I want to had is based on the same idea using a verification code to Clearcontents of a cell and locked it. If the verification code is false, then, I want the cell to be unlocked so the user can write the value. Here is the code line I want to had times 15 as already done for the locked, unlocked function.
If Range("AS16") = "Vrai" Then
Range("AA16").ClearContents
Range("AA16").Locked = True
Else:
Range("AA16").Locked = False
End If
Here is the code I'm using right now.
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveSheet.Unprotect ("Francis")
Dim Cell As Range
Set Cell = ActiveCell
Application.ScreenUpdating = False
For Each cellule In Range("S50:X50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("S50:X50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
If Range("AR16") = "Vrai" Then
Range("K16").Locked = False
Range("O16").Locked = False
Else:
Range("K16").Locked = True
Range("O16").Locked = True
End If
If Range("AR18") = "Vrai" Then
Range("K18").Locked = False
Range("O18").Locked = False
Else:
Range("K18").Locked = True
Range("O18").Locked = True
End If
If Range("AR20") = "Vrai" Then
Range("K20").Locked = False
Range("O20").Locked = False
Else:
Range("K20").Locked = True
Range("O20").Locked = True
End If
If Range("AR22") = "Vrai" Then
Range("K22").Locked = False
Range("O22").Locked = False
Else:
Range("K22").Locked = True
Range("O22").Locked = True
End If
If Range("AR24") = "Vrai" Then
Range("K24").Locked = False
Range("O24").Locked = False
Else:
Range("K24").Locked = True
Range("O24").Locked = True
End If
If Range("AR26") = "Vrai" Then
Range("K26").Locked = False
Range("O26").Locked = False
Else:
Range("K26").Locked = True
Range("O26").Locked = True
End If
If Range("AR28") = "Vrai" Then
Range("K28").Locked = False
Range("O28").Locked = False
Else:
Range("K28").Locked = True
Range("O28").Locked = True
End If
If Range("AR30") = "Vrai" Then
Range("K30").Locked = False
Range("O30").Locked = False
Else:
Range("K30").Locked = True
Range("O30").Locked = True
End If
If Range("AR32") = "Vrai" Then
Range("K32").Locked = False
Range("O32").Locked = False
Else:
Range("K32").Locked = True
Range("O32").Locked = True
End If
If Range("AR34") = "Vrai" Then
Range("K34").Locked = False
Range("O34").Locked = False
Else:
Range("K34").Locked = True
Range("O34").Locked = True
End If
If Range("AR36") = "Vrai" Then
Range("K36").Locked = False
Range("O36").Locked = False
Else:
Range("K36").Locked = True
Range("O36").Locked = True
End If
If Range("AR38") = "Vrai" Then
Range("K38").Locked = False
Range("O38").Locked = False
Else:
Range("K38").Locked = True
Range("O38").Locked = True
End If
If Range("AR40") = "Vrai" Then
Range("K40").Locked = False
Range("O40").Locked = False
Else:
Range("K40").Locked = True
Range("O40").Locked = True
End If
If Range("AR42") = "Vrai" Then
Range("K42").Locked = False
Range("O42").Locked = False
Else:
Range("K42").Locked = True
Range("O42").Locked = True
End If
If Range("AR44") = "Vrai" Then
Range("K44").Locked = False
Range("O44").Locked = False
Else:
Range("K44").Locked = True
Range("O44").Locked = True
End If
Application.ScreenUpdating = True
Application.Goto Cell
'ActiveSheet.Protect Password:="Francis"
End Sub
Thanks a lot for your help.
Have a nice day!
You typically don't want to have performance-expensive code running in that specific handler. Worksheet_Change gets invoked every time a cell changes... and that includes changing a cell's Locked property value.
So that's how you run out of stack space: your handler is modifying cells' Locked state, which triggers the Worksheet_Change event, which modifies cells' Locked state, which triggers the Worksheet_Change event, which modifies cells' Locked state, which triggers the Worksheet_Change event, which... which eventually blows the call stack.
So prevent this accidental recursion, you need to prevent Excel from firing worksheet events when you're handling one:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo CleanFail
Application.EnableEvents = False
'do stuff
CleanExit:
Application.EnableEvents = True
Exit Sub
CleanFail:
'handle errors here...
Resume CleanExit
End Sub
As for simplifying the code, that's more of a mandate for Code Review Stack Exchange, once your code works as intended.
If any C# dev is reading this, this particular situation now has an up-for-grabs issue on Rubberduck's GitHub repository: #3109 Prevent accidental recursion in Worksheet_Change and Workbook_SheetChange handlers; once that inspection is implemented, Rubberduck will be able to warn you when you handle Worksheet_Change without disabling application events.
The Out of stack error is caused by the Change event, as noted by #Mat
Try this version which also turns the events off and on
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cellule As Range, r As Long, isVrai As Boolean
ActiveSheet.Unprotect "Francis"
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
For Each cellule In Union(Range("I50:J50"), Range("S50:X50"))
With cellule
Select Case .Value2
Case "1": .EntireColumn.Hidden = False
Case "0": .EntireColumn.Hidden = True
End Select
End With
Next
For r = 16 To 44 Step 2
isVrai = (Range("AR" & r).Value2 = "Vrai")
Range("K" & r).Locked = Not isVrai
Range("O" & r).Locked = Not isVrai
If isVrai Then Range("AR" & r).ClearContents
Next
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
'ActiveSheet.Protect Password:="Francis"
End Sub
This section can be simplified:
For Each cellule In Range("S50:X50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("S50:X50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "1" Then cellule.EntireColumn.Hidden = False
Next cellule
For Each cellule In Range("I50:J50")
If cellule.Value = "0" Then cellule.EntireColumn.Hidden = True
Next cellule
To the following (however, note that this will unhide any non-zero values).
For Each cellule in Range("S50:X50")
cellule.EntireColumn.Hidden = (cellule.Value = "0")
Next
For Each cellule in Range("I50:J50")
cellule.EntireColumn.Hidden = (cellule.Value = "0")
Next
And this section:
If Range("AR16") = "Vrai" Then
Range("K16").Locked = False
Range("O16").Locked = False
Else:
Range("K16").Locked = True
Range("O16").Locked = True
End If
If Range("AR18") = "Vrai" Then
Range("K18").Locked = False
Range("O18").Locked = False
Else:
Range("K18").Locked = True
Range("O18").Locked = True
End If
....
Can be simplified using a loop over Range("AR16:AR44")
For Each cellule in Range("AR16:AR44") Step 2
cellule.Offset(,-33).Locked = (cellule.Value = "Vrai")
cellule.Offset(,-29).Locked = (cellule.Value = "Vrai")
Next

more than one Select All Checkboxes for each frame

Following Userform has 4 (Four) Select All Check-boxes.
SelectAllE for Eastern Europe
SelectAllA for Middle East & Africa
SelectAllL for Latin America & Caribbean
SA for Select All Regions (Working)
only the fourth one is working correctly
Following are codes for each Checkboxes
Private Sub SA_Click() ' this one is working Correctly
Dim ctl As Control
Dim j As Long
For Each ctl In Me.Controls
If TypeOf ctl Is MSForms.CheckBox Then
If Me.Controls(ctl.Name).Value = True Then
Me.Bulgaria.Value = True
Me.Croatia.Value = True
Me.Croatia.Value = True
Me.czechrepublic.Value = True
Me.Estonia.Value = True
Me.Hungary.Value = True
Me.Latvia.Value = True
Me.Lithuania.Value = True
Me.Macedonia.Value = True
Me.Poland.Value = True
Me.Romania.Value = True
Me.Russia.Value = True
Me.Ukraine.Value = True
Me.Bahrain.Value = True
Me.CoteD.Value = True
Me.Egypt.Value = True
Me.Ghana.Value = True
Me.Iraq.Value = True
Me.Kenya.Value = True
Me.Kuwait.Value = True
Me.Morocco.Value = True
Me.Namibia.Value = True
Me.Nigeria.Value = True
Me.Oman.Value = True
Me.Palestine.Value = True
Me.Qatar.Value = True
Me.Rwanda.Value = True
Me.SaudiArabia.Value = True
Me.Turkey.Value = True
Me.Uganda.Value = True
Me.UAE.Value = True
Me.Zimbabwe.Value = True
Me.Chile.Value = True
Me.Mexico.Value = True
Me.Colombia.Value = True
Else
Me.Bulgaria.Value = False
Me.Croatia.Value = False
Me.Croatia.Value = False
Me.czechrepublic.Value = False
Me.Estonia.Value = False
Me.Hungary.Value = False
Me.Latvia.Value = False
Me.Lithuania.Value = False
Me.Macedonia.Value = False
Me.Poland.Value = False
Me.Romania.Value = False
Me.Russia.Value = False
Me.Ukraine.Value = False
Me.Bahrain.Value = False
Me.CoteD.Value = False
Me.Egypt.Value = False
Me.Ghana.Value = False
Me.Iraq.Value = False
Me.Kenya.Value = False
Me.Kuwait.Value = False
Me.Morocco.Value = False
Me.Namibia.Value = False
Me.Nigeria.Value = False
Me.Oman.Value = False
Me.Palestine.Value = False
Me.Qatar.Value = False
Me.Rwanda.Value = False
Me.SaudiArabia.Value = False
Me.Turkey.Value = False
Me.Uganda.Value = False
Me.UAE.Value = False
Me.Zimbabwe.Value = False
End If
End If
Next
End Sub
Private Sub SelectallE_Click() ' this one is not working Correctly
Dim ctl As Control
Dim j As Long
For Each ctl In Me.Controls
If TypeOf ctl Is MSForms.CheckBox Then
If Me.Controls(ctl.Name).Value = True Then
Me.Bulgaria.Value = True
Me.Croatia.Value = True
Me.Croatia.Value = True
Me.czechrepublic.Value = True
Me.Estonia.Value = True
Me.Hungary.Value = True
Me.Latvia.Value = True
Me.Lithuania.Value = True
Me.Macedonia.Value = True
Me.Poland.Value = True
Me.Romania.Value = True
Me.Russia.Value = True
Me.Ukraine.Value = True
Else
Me.Bulgaria.Value = False
Me.Croatia.Value = False
Me.Croatia.Value = False
Me.czechrepublic.Value = False
Me.Estonia.Value = False
Me.Hungary.Value = False
Me.Latvia.Value = False
Me.Lithuania.Value = False
Me.Macedonia.Value = False
Me.Poland.Value = False
Me.Romania.Value = False
Me.Russia.Value = False
Me.Ukraine.Value = False
Me.Chile.Value = False
Me.Mexico.Value = False
Me.Colombia.Value = False
End If
End If
Next
End Sub
Private Sub SelectAllA_Click() ' this one is not working Correctly
Dim ctl As Control
Dim j As Long
For Each ctl In Me.Controls
If TypeOf ctl Is MSForms.CheckBox Then
If Me.Controls(ctl.Name).Value = True Then
Me.Bahrain.Value = True
Me.CoteD.Value = True
Me.Egypt.Value = True
Me.Ghana.Value = True
Me.Iraq.Value = True
Me.Kenya.Value = True
Me.Kuwait.Value = True
Me.Morocco.Value = True
Me.Namibia.Value = True
Me.Nigeria.Value = True
Me.Oman.Value = True
Me.Palestine.Value = True
Me.Qatar.Value = True
Me.Rwanda.Value = True
Me.SaudiArabia.Value = True
Me.Turkey.Value = True
Me.Uganda.Value = True
Me.UAE.Value = True
Me.Zimbabwe.Value = True
Else
Me.Bahrain.Value = False
Me.CoteD.Value = False
Me.Egypt.Value = False
Me.Ghana.Value = False
Me.Iraq.Value = False
Me.Kenya.Value = False
Me.Kuwait.Value = False
Me.Morocco.Value = False
Me.Namibia.Value = False
Me.Nigeria.Value = False
Me.Oman.Value = False
Me.Palestine.Value = False
Me.Qatar.Value = False
Me.Rwanda.Value = False
Me.SaudiArabia.Value = False
Me.Turkey.Value = False
Me.Uganda.Value = False
Me.UAE.Value = False
Me.Zimbabwe.Value = False
End If
End If
Next
End Sub
Private Sub SelectAllL_Click() ' this one is not working Correctly
Dim ctl As Control
Dim j As Long
For Each ctl In Me.Controls
If TypeOf ctl Is MSForms.CheckBox Then
If Me.Controls(ctl.Name).Value = True Then
Me.Chile.Value = True
Me.Mexico.Value = True
Me.Colombia.Value = True
Else
Me.Chile.Value = False
Me.Mexico.Value = False
Me.Colombia.Value = False
End If
End If
Next
End Sub
Your code is too complicated, why not keeping it more simple? Since you are inside the Click event you know the control and don't need to loop each control of the userform!
Private Sub SA_Click()
SelectAllA.Value = SA.Value
SelectAllL.Value = SA.Value
SelectallE.Value = SA.Value
End Sub
Private Sub SelectallE_Click()
Bulgaria.Value = SelectallE.Value
Croatia.Value = SelectallE.Value
Croatia.Value = SelectallE.Value
czechrepublic.Value = SelectallE.Value
Estonia.Value = SelectallE.Value
Hungary.Value = SelectallE.Value
Latvia.Value = SelectallE.Value
Lithuania.Value = SelectallE.Value
Macedonia.Value = SelectallE.Value
Poland.Value = SelectallE.Value
Romania.Value = SelectallE.Value
Russia.Value = SelectallE.Value
Ukraine.Value = SelectallE.Value
End Sub
Private Sub SelectAllA_Click()
Bahrain.Value = SelectAllA.Value
CoteD.Value = SelectAllA.Value
Egypt.Value = SelectAllA.Value
Ghana.Value = SelectAllA.Value
Iraq.Value = SelectAllA.Value
Kenya.Value = SelectAllA.Value
Kuwait.Value = SelectAllA.Value
Morocco.Value = SelectAllA.Value
Namibia.Value = SelectAllA.Value
Nigeria.Value = SelectAllA.Value
Oman.Value = SelectAllA.Value
Palestine.Value = SelectAllA.Value
Qatar.Value = SelectAllA.Value
Rwanda.Value = SelectAllA.Value
SaudiArabia.Value = SelectAllA.Value
Turkey.Value = SelectAllA.Value
Uganda.Value = SelectAllA.Value
UAE.Value = SelectAllA.Value
Zimbabwe.Value = SelectAllA.Value
End Sub
Private Sub SelectAllL_Click()
Chile.Value = SelectAllL.Value
Mexico.Value = SelectAllL.Value
Colombia.Value = SelectAllL.Value
End Sub