VBA PDF # 24-352 Since 2020 2021 - V1.
4
Your Free Workbook The Training Video Got Questions?
Download Here Watch Here Join Our 66K Community
August 6, 2024 by Rob Haman (ROB’s EXCEL SUPPORT)
Excel For Freelancers – Randy Austin
06-08-2024
Facebook – Excel For Freelancers Group
This VBA Code book is intended to be used as an Aid for
Excel VBA Users & Developers to give a better readability
and insight on the used VBA code.
VBACodePrint
PERSONAL WEALTH ULTIMATE NEWS CUSTOMER MANAGER INCOME & EXPENCE PHARMACY POS (24-347)
MANAGER (24-351) AGGREGATOR (24-350) DASHBOARD (24-349) BUDGET (24-348)
SORT LISTBOX DATA IN QUANTITY DISCOUNTS ACCOUNTING SHARE & SYNC ADD-IN CHATGPT PICTURES TO
USERFORM (24-346) POS (24-345) FORMULAS + ERP (24-343) PROGRAM (24-342)
SOFTWARE (24-344)
VBA PDF # 24-352 Since 2020 2021 - V1.4
Table of Contents
Projects .....................................................................................................................................................................................................................4
Personal_Notes_Manager ....................................................................................................................................................................................4
Documents ........................................................................................................................................................................................................4
Admin ............................................................................................................................................................................................................4
(Declarations) ............................................................................................................................................................................................4
Worksheet_SelectionChange [Sub ] .........................................................................................................................................................4
NotesDB ........................................................................................................................................................................................................5
(Declarations) ............................................................................................................................................................................................5
PNM ..............................................................................................................................................................................................................6
(Declarations) ............................................................................................................................................................................................6
Worksheet_Change [Sub ] ........................................................................................................................................................................6
Worksheet_SelectionChange [Sub ] .........................................................................................................................................................6
ThisWorkbook ...............................................................................................................................................................................................7
(Declarations) ............................................................................................................................................................................................7
Forms ................................................................................................................................................................................................................8
NotesFrm ......................................................................................................................................................................................................8
(Declarations) ............................................................................................................................................................................................8
CancelBtn_Click [Sub ] .............................................................................................................................................................................8
Field5_Exit [Sub ] ......................................................................................................................................................................................8
Field6_Exit [Sub ] ......................................................................................................................................................................................8
Field7_Exit [Sub ] ......................................................................................................................................................................................8
Field8_Exit [Sub ] ......................................................................................................................................................................................8
Field9_Exit [Sub ] ......................................................................................................................................................................................8
SaveBtn_Click [Sub ] ................................................................................................................................................................................9
UserForm_Initialize [Sub ] .........................................................................................................................................................................9
Modules ..........................................................................................................................................................................................................10
Admin_Macros ............................................................................................................................................................................................10
(Declarations) ..........................................................................................................................................................................................10
Admin_SetTypeColor [Sub ]....................................................................................................................................................................10
Notes_Macros .............................................................................................................................................................................................11
(Declarations) ..........................................................................................................................................................................................11
Note_AddNew [Sub ] ...............................................................................................................................................................................11
Note_Edit [Sub ] ......................................................................................................................................................................................11
Note_SaveUpdate [Sub ].........................................................................................................................................................................11
PNM_Macros ..............................................................................................................................................................................................12
(Declarations) ..........................................................................................................................................................................................12
Note_CheckForMove [Sub ] ....................................................................................................................................................................12
Note_Select [Sub ] ..................................................................................................................................................................................12
Notes_Refresh [Sub ] ..............................................................................................................................................................................13
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 3 of 16
Admin Personal_Notes_Manager
1 Option Explicit
2
3 Private Sub Worksheet_SelectionChange(ByVal Target As Range)
4 If Target.CountLarge > 1 Then Exit Sub
5 If Shapes("ColorPalette" ).Visible = True Then Shapes("ColorPalette" ).Visible = msoFalse
6
7 'Show color palette
8 If Not Intersect(Target, Range("C7:C17,E21" )) Is Nothing Then
9 With Shapes("ColorPalette" )
10 .Left = Range("C" & Target.Row).Left
11 .Top = Range("C" & Target.Row + 1).Top
12 .Visible = msoCTrue
13 End With
14 End If
15
16 End Sub
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 4 of 16
NotesDB Personal_Notes_Manager
1 Option Explicit
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 5 of 16
PNM Personal_Notes_Manager
1 Option Explicit
2
3 Private Sub Worksheet_Change(ByVal Target As Range)
4 If Not Intersect(Target, Range("E3" )) Is Nothing Then Notes_Refresh
5 End Sub
6
7 Private Sub Worksheet_SelectionChange(ByVal Target As Range)
8 Range("B9" ).Value = True
9 End Sub
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 6 of 16
ThisWorkbook Personal_Notes_Manager
1 Option Explicit
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 7 of 16
NotesFrm Personal_Notes_Manager
1 Option Explicit
2
3 Private Sub CancelBtn_Click()
4 Unload Me
5 End Sub
6
7 Private Sub Field5_Exit(ByVal Cancel As MSForms.ReturnBoolean)
8 If Me.Field5.Value <> Empty Then Me.Field5.Value = Format(Me.Field5.Value, "dd/mm/yyyy" ) 'Format
as date
9 End Sub
10
11 Private Sub Field6_Exit(ByVal Cancel As MSForms.ReturnBoolean)
12 'On Error Resume Next
13 If Me.Field6.Value <> Empty Then Me.Field6.Value = Format(Me.Field6.Value, Admin.Range("J7"
).Value)
14 On Error GoTo 0
15 End Sub
16
17 Private Sub Field7_Exit(ByVal Cancel As MSForms.ReturnBoolean)
18 'On Error Resume Next
19 If Me.Field7.Value <> Empty Then Me.Field7.Value = Format(Me.Field7.Value, Admin.Range("J8"
).Value)
20 On Error GoTo 0
21 End Sub
22
23 Private Sub Field8_Exit(ByVal Cancel As MSForms.ReturnBoolean)
24 'On Error Resume Next
25 If Me.Field8.Value <> Empty Then Me.Field8.Value = Format(Me.Field8.Value, Admin.Range("J9"
).Value)
26 On Error GoTo 0
27 End Sub
28
29 Private Sub Field9_Exit(ByVal Cancel As MSForms.ReturnBoolean)
30 'On Error Resume Next
31 If Me.Field9.Value <> Empty Then Me.Field9.Value = Format(Me.Field9.Value, Admin.Range("J10"
).Value)
32 On Error GoTo 0
1
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 8 of 16
NotesFrm Personal_Notes_Manager
1
33 End Sub
34
35 Private Sub SaveBtn_Click()
36 Note_SaveUpdate
37 End Sub
38
39 Private Sub UserForm_Initialize()
40 Dim FieldRow As Long
41 Dim Label As Control
42 For FieldRow = 7 To 10
43 Set Label = Me.Controls("CustLbl" & FieldRow)
44 Label.Caption = Admin.Range("H" & FieldRow).Value 'Set Custom Field Name
45 Next FieldRow
46 End Sub
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 9 of 16
Admin_Macros Personal_Notes_Manager
1 Option Explicit
2
3 Sub Admin_SetTypeColor()
4 ActiveCell.Interior.Color = Admin.Shapes(Application.Caller).Fill.ForeColor.RGB
5 Admin.Shapes("ColorPalette" ).Visible = msoFalse
6 End Sub
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 10 of 16
Notes_Macros Personal_Notes_Manager
1 Option Explicit
2 Dim NoteRow As Long, NoteCol As Long
3 Dim Field As Control
4
5 Sub Note_AddNew()
6 PNM.Range("B2" ).ClearContents 'Clear out any Note id
7 NotesFrm.Show
8 End Sub
9
10 Sub Note_Edit()
11 If PNM.Range("B3" ).Value = Empty Then
12 MsgBox "Please select a note to edit"
13 Exit Sub
14 End If
15 NoteRow = PNM.Range("B3" ).Value 'SEt Note row
16 With NotesFrm
17 For NoteCol = 2 To 10
18 Set Field = .Controls("Field" & NoteCol - 1)
19 Field.Value = NotesDB.Cells(NoteRow, NoteCol).Value 'Load Notes
20 If NoteCol > 6 Then
21 Field.Value = Format(Field.Value, Admin.Range("J" & NoteCol).Value)
22 End If
23 Next NoteCol
24 .Show
25 End With
26 End Sub
27
28 Sub Note_SaveUpdate()
29 With NotesFrm
30 PNM.Range("B9" ).Value = True 'Stop Any Loops
31 If .Field1.Value = Empty Or .Field2.Value = Empty Or .Field4.Value = Empty Then
32 MsgBox "Please make sure to add in a name, priority and category for this note before saving"
33 Exit Sub
34 End If
35 If PNM.Range("B3" ).Value = Empty Then
36 NoteRow = NotesDB.Range("A9999" ).End(xlUp).Row + 1 ' First Avail Row
37 PNM.Range("B2" ).Value = PNM.Range("B4" ).Value 'Set New Note ID
38 NotesDB.Range("A" & NoteRow).Value = PNM.Range("B2" ).Value 'Save Note
39 NotesDB.Range("J" & NoteRow).Value = "=Row()" 'Set DB Row
40 Else 'Existing Note
41 NoteRow = PNM.Range("B3" ).Value 'Existing Note Row
42 End If
43 For NoteCol = 2 To 10
44 Set Field = .Controls("Field" & NoteCol - 1)
45 NotesDB.Cells(NoteRow, NoteCol).Value = Field.Value 'Save Notes
46 Next NoteCol
47 Unload NotesFrm
48 Notes_Refresh
49 End With
50 End Sub
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 11 of 16
PNM_Macros Personal_Notes_Manager
1 Option Explicit
2 Dim ViewType As String, NoteID As String, NoteName As String, Priority As String
3 Dim CatColor As String, Category As String
4 Dim NoteShp As Shape
5 Dim NoteCol As Long, NoteRow As Long, LastRow As Long, LastResultRow As Long, PriorNumb As Long,
ResultRow As Long
6 Dim CatRow As Long, CategoryRow As Long, PriorityRow As Long, LastArchiveCol As Long, ColCount As
Long, CatCol As Long
7 Dim TopPos As Double, LeftPos As Double
8
9 Sub Note_CheckForMove()
10 Dim Count As Long
11 With PNM
12 If .Range("B3" ).Value = Empty Then GoTo EndLoop
13 NoteRow = .Range("B3" ).Value 'note DB Row
14 Set NoteShp = .Shapes("NoteItem" & NoteID)
15 If NoteShp Is Nothing Then Exit Sub
16 For Count = 1 To 100000
17 DoEvents
18 If .Range("B9" ).Value = True Then Exit For
19 With NoteShp
20 On Error GoTo EndLoop
21 If .Left <> PNM.Range("B7" ).Value Or .Top <> PNM.Range("B8" ).Value Then 'Shape has been
moved
22 PNM.Range("B9" ).Value = True 'Set Move to true
23 'Check For out of bounds move
24 If .Left < PNM.Range("D1" ).Left Or .Top < PNM.Range("3:3" ).Top Or .Left > PNM.Range("Z1"
).Left Or .Top > PNM.Range("100:100" ).Top Then
25 MsgBox "Please make sure to move the note within the correct area"
26 GoTo EndLoop
27 End If
28 'Check for Archive
29 If .Left > PNM.Range("D1" ).Left And .Left < PNM.Range("F1" ).Left Then 'Moved to column D
or E
30 If .Top < PNM.Range("17:17" ).Top Then 'Moved to archive
31 NotesDB.Range("C" & NoteRow).Value = "Archived"
32 GoTo EndLoop
33 Else 'Delete Note
34 If MsgBox("Are you sure you want to delete this Note?" , vbYesNo, "Delete Note" ) =
vbNo Then GoTo EndLoop
35 NotesDB.Range(NoteRow & ":" & NoteRow).EntireRow.Delete
36 GoTo EndLoop
37 End If
38 End If
39 'Check for Priority or Category change
40 If PNM.Cells(3, .TopLeftCell.Column).Value = Empty Then 'Empty Category or Priority
41 MsgBox "Please make sure to drag the note to an actual " & PNM.Range("E3" ).Value
42 GoTo EndLoop
43 End If
44 If PNM.Range("E3" ).Value = "Category" Then
45 NotesDB.Range("E" & NoteRow).Value = PNM.Cells(3, .TopLeftCell.Column).Value
46 Else 'Priority
47 NotesDB.Range("C" & NoteRow).Value = PNM.Cells(3, .TopLeftCell.Column).Value
48 End If
49 GoTo EndLoop
50 End If 'Shape Moved
51 End With
52
53 Next Count
54 EndLoop:
55 .Range("B9" ).Value = True 'Exit out of Loop
56 Notes_Refresh 'Refresh Notes
57 End With
58 End Sub
59
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 12 of 16
PNM_Macros Personal_Notes_Manager
60 Sub Note_Select()
61 With PNM
62 NoteID = Replace(Application.Caller, Left(Application.Caller, 8), "" ) 'Set Note ID
63 .Range("B2" ).Value = NoteID 'Set Note ID
64 If .Range("B3" ).Value = Empty Then Exit Sub
65 NoteRow = .Range("B3" ).Value 'Note DB Row
66 .Range("F2" ).Value = NotesDB.Range("B" & NoteRow).Value 'Place Note Name
67 .Range("B7" ).Value = .Shapes(Application.Caller).Left 'Set Left Pos
68 .Range("B8" ).Value = .Shapes(Application.Caller).Top 'Set Top Pos
69 .Range("B9" ).Value = False 'Set Move to false
70 .Shapes("NoteGrp" & NoteID).Select
71 '.Shapes("NoteGrp" & NoteID).ZOrder msoBringToFront
72 Note_CheckForMove 'Run macro to check for move
73 End With
74 End Sub
75
76 Sub Notes_Refresh()
77 With PNM
78 .Range("F3:Z3,F100:Z100" ).ClearContents 'Clear Column headers and Col. Note Counts
79 For Each NoteShp In .Shapes
80 On Error Resume Next
81 If InStr(NoteShp.Name, "NoteGrp" ) > 0 Then NoteShp.Delete
82 If InStr(NoteShp.Name, "NoteItem" ) > 0 Then NoteShp.Delete
83 On Error GoTo 0
84 Next NoteShp
85 If .Range("E3" ).Value = Empty Then Exit Sub 'Exit on no view selection
86 ViewType = .Range("E3" ).Value 'Set View Type (Category, Priority or Archived)
87 End With
88 With NotesDB
89 LastRow = .Range("A99999" ).End(xlUp).Row 'Last Data Row
90 If LastRow < 4 Then Exit Sub
91 .Range("A3:ZK" & LastRow).AdvancedFilter xlFilterCopy, CriteriaRange:=.Range("P2:P3" ),
CopyToRange:=.Range("S2:AC2" ), Unique:=True
92 LastResultRow = .Range("S99999" ).End(xlUp).Row
93 If LastResultRow < 3 Then Exit Sub
94 TopPos = PNM.Range("4:4" ).Top 'Set Initial top Position
95 Select Case ViewType
96 Case Is = "Priority"
97 For PriorityRow = 7 To 10
98 PNM.Cells(3, PriorityRow - 1).Value = Admin.Range("E" & PriorityRow).Value 'Add IN 4
Priorities
99 Next PriorityRow
100 Case Is = "Category"
101 For CategoryRow = 7 To Admin.Range("B26" ).End(xlUp).Row
102 PNM.Cells(3, CategoryRow - 1).Value = Admin.Range("B" & CategoryRow).Value 'Add in
Categories
103 Next CategoryRow
104 Case Is = "Archived"
105 LastArchiveCol = Abs((LastResultRow - 1) / 10) + 6
106 Range(PNM.Cells(3, 6), PNM.Cells(3, LastArchiveCol)).Value = "Achrived" 'Add Archived to each
column as needed
107 NoteCol = 6 'Set initial column to 6 only for archived
108 End Select
109 If LastResultRow < 4 Then GoTo NoSort
110 'Sort Notes Descending based on Due Date
111 With .Sort
112 .SortFields.Clear
113 .SortFields.Add Key:=NotesDB.Range("X3" ), SortOn:=xlSortOnValues, Order:=xlDescending,
DataOption:=xlSortNormal 'Sort
114 .SetRange NotesDB.Range("S3:AC" & LastResultRow) 'Set Range
115 .Apply 'Apply Sort
116 End With
117 NoSort:
118 For ResultRow = 3 To LastResultRow
119 NoteID = .Range("S" & ResultRow).Value 'Note ID
120 NoteName = .Range("T" & ResultRow).Value 'Note Name
121 Category = .Range("V" & ResultRow).Value 'Note Category
1 2 3
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 13 of 16
PNM_Macros Personal_Notes_Manager
1 2 3
122 Priority = .Range("W" & ResultRow).Value 'Note Priority
123 If Priority = "Archived" Then
124 CatColor = Admin.Range("ArchiveColor" ).Interior.Color 'Set Archived Color
125 Else 'Not Archived
126 On Error Resume Next
127 CatRow = Admin.Range("Categories" ).Find(Category, , xlValues, xlWhole).Row
128 On Error GoTo 0
129 If CatRow <> 0 Then
130 CatColor = Admin.Range("C" & CatRow).Interior.Color 'Set Category Color
131 Else
132 CatColor = Admin.Range("ArchiveColor" ).Interior.Color 'Set Archived Color 'Set to
Archived if not found
133 End If
134 End If
135 Select Case ViewType
136 Case Is = "Priority"
137 On Error Resume Next
138 NoteCol = PNM.Range("F3:Z3" ).Find(Priority, , xlValues, xlWhole).Column 'Column in which
Priority was found
139 On Error GoTo 0
140 If NoteCol = 0 Then GoTo NextNote
141 Case Is = "Category"
142 On Error Resume Next
143 NoteCol = PNM.Range("F3:Z3" ).Find(Category, , xlValues, xlWhole).Column 'Column in which
cat. was found
144 On Error GoTo 0
145 If NoteCol = 0 Then GoTo NextNote
146 Case Is = "Archived"
147 If PNM.Cells(100, NoteCol).Value = 10 Then
148 NoteCol = NoteCol + 1
149 End If
150 End Select
151 LeftPos = PNM.Cells(1, NoteCol).Left 'Set left Position
152 ColCount = PNM.Cells(100, NoteCol).Value 'Extract Column Note Count
153 TopPos = (ColCount * (PNM.Shapes("SampleNote" ).Height) / 2) + PNM.Range("4:4" ).Top + 1 'Set
Top Position based on the # of notes in the given column
154 PNM.Cells(100, NoteCol).Value = PNM.Cells(100, NoteCol).Value + 1 'Increment Column Count
155 PNM.Shapes("SampleNote" ).Duplicate.Name = "NoteItem" & NoteID 'Create Unique Note
156 With PNM.Shapes("NoteItem" & NoteID)
157 .Left = LeftPos 'Set Left Position
158 .Top = TopPos 'Set Top Position
159 .Width = PNM.Cells(1, NoteCol).Width - 2 'Set Note shape width slightly less than column
width
160 .Fill.ForeColor.RGB = CatColor 'Set Note Color
161 .TextFrame2.TextRange.Text = NoteName 'Set Note Name
162 End With
163 'Add in priority Flag
164 On Error Resume Next
165 PriorNumb = Admin.Range("Priorities" ).Find(Priority, , xlValues, xlWhole).Row - 6 'Get
Priority #
166 On Error GoTo 0
167 If Priority = "Archived" Then PriorNumb = 4 'Set Archived Priority
168 If PriorNumb <= 0 Then GoTo NoPrior
169 PNM.Shapes("Priority" & PriorNumb).Duplicate.Name = "NotePrior" & NoteID
170 With PNM.Shapes("NotePrior" & NoteID)
171 .Left = LeftPos + PNM.Shapes("NoteItem" & NoteID).Width - 15 'Set Left Pos of Prior flag
172 .Top = PNM.Shapes("NoteItem" & NoteID).Top + 1 'Set Top Pos of Prior Flag
173 End With
174 PNM.Shapes.Range(Array("NoteItem" & NoteID, "NotePrior" & NoteID)).Group.Name = "NoteGrp" &
NoteID 'Group & Name Note shapes
175 NoPrior:
176 NextNote:
177 PriorNumb = 0 'Reset Priority #
178 If ViewType <> "Archived" Then NoteCol = 0 'Clear Out Note Column unless archived
179 Next ResultRow
1 2
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 14 of 16
PNM_Macros Personal_Notes_Manager
1 2
180 End With
181 End Sub
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 15 of 16
Index
Top, 4, 12-14
A I TopLeftCell, 12
Abs, 13 InStr, 13 TopPos, 12-14
ActiveCell, 10 Interior, 10, 14
Add, 13 Intersect, 4, 6 U
Admin, 8-11, 13, 14 Unique, 13
Admin_SetTypeColor, 10 K Unload, 8, 11
AdvancedFilter, 13 Key, 13 UserForm_Initialize, 9
Application, 10, 13
Apply, 13 L V
Array, 14 Label, 9 Value, 6, 8, 9, 11-14
LastArchiveCol, 12, 13 vbNo, 12
C LastResultRow, 12, 13 vbYesNo, 12
Caller, 10, 13 LastRow, 12, 13 ViewType, 12-14
Cancel, 8 Left, 4, 12-14 Visible, 4, 10
CancelBtn_Click, 8 LeftPos, 12, 14
Caption, 9 W
CatCol, 12 M Width, 14
CatColor, 12, 14 MSForms, 8 Worksheet_Change, 6
Category, 12-14 MsgBox, 11, 12 Worksheet_SelectionChange, 4, 6
CategoryRow, 12, 13 msoCTrue, 4
CatRow, 12, 14 msoFalse, 4, 10 X
Cells, 11-14 xlDescending, 13
Clear, 13 N xlFilterCopy, 13
ClearContents, 11, 13 Name, 13, 14 xlSortNormal, 13
ColCount, 12, 14 NextNote, 14 xlSortOnValues, 13
Color, 10, 14 NoPrior, 14 xlUp, 11, 13
Column, 12, 14 NoSort, 13 xlValues, 14
Control, 9, 11 Note_AddNew, 11 xlWhole, 14
Controls, 9, 11 Note_CheckForMove, 12, 13
CopyToRange, 13 Note_Edit, 11
Count, 12 Note_SaveUpdate, 9, 11
CountLarge, 4 Note_Select, 13
CriteriaRange, 13 NoteCol, 11-14
NoteID, 12-14
D NoteName, 12-14
DataOption, 13 NoteRow, 11-13
Delete, 12, 13 Notes_Refresh, 6, 11-13
DoEvents, 12 NotesDB, 11-13
Duplicate, 14 NotesFrm, 11
NoteShp, 12, 13
E
Empty, 8, 11-13 O
EndLoop, 12 Order, 13
EntireRow, 12
Explicit, 4-8, 10-12 P
PNM, 11-14
F Priority, 12, 14
Field, 11 PriorityRow, 12, 13
Field1, 11 PriorNumb, 12, 14
Field2, 11
Field4, 11 R
Field5, 8 Range, 4, 6, 8, 9, 11-14
Field5_Exit, 8 Replace, 13
Field6, 8 ResultRow, 12-14
Field6_Exit, 8 ReturnBoolean, 8
Field7, 8 RGB, 10, 14
Field7_Exit, 8 Row, 4, 11, 13, 14
Field8, 8
Field8_Exit, 8 S
Field9, 8 SaveBtn_Click, 9
Field9_Exit, 8 SetRange, 13
FieldRow, 9 Shape, 12
Fill, 10, 14 Shapes, 4, 10, 12-14
Find, 14 Show, 11
ForeColor, 10, 14 Sort, 13
Format, 8, 11 SortFields, 13
SortOn, 13
G
Group, 14 T
Target, 4, 6
H Text, 14
Height, 14 TextFrame2, 14
TextRange, 14
Personal_Notes_Manager.xlsm By Rob's Excel Support - Since 2020 16 of 16