Why wont the code below execute when a cell is double clicked on? - vba

The code below ran earlier but will not execute when a cell is double clicked.
Private Sub Worksheet_DoubleClick(ByVal Target As range, Cancel As Boolean)
If Target.Font.Bold = False Then
Target.Font.Bold = True
Target.Font.Color = vbRed
Else
Target.Font.Bold = False
Target.Font.Color = 1
End If
End Sub

Not an answer to why it's not working (#Mat's Mug and #Scott Craner beat me to that again), but a shortened version of the code.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
With Target.Font
.Bold = Not .Bold
.Color = Choose(Abs(CLng(.Bold)) + 1, 1, vbRed)
End With
End Sub
Ok, not as easy to follow as the original but here's what it's doing:
Target.Font.Bold is either TRUE or FALSE, so Not .Bold will return the opposite.
Bold = TRUE so Not Bold = FALSE
Abs(CLng(.Bold)) + 1
Again, .Bold is either TRUE or FALSE. Numerically TRUE = -1, FALSE = 0.
CLNG(.Bold) will return -1 or 0.
ABS(CLNG(.Bold)) will return 1 or 0.
Abs(CLng(.Bold)) + 1 will return 1 or 2 - which is used in the CHOOSE command to return vbRed or 1.

DO NOT type any of these signatures manually!
Use the code pane dropdowns instead:
Select Worksheet from the left dropdown, and pick an event to handle in the right dropdown; the VBE will generate a method stub with the proper signature for you.
Typing them out manually off the top of your head can (and does!) result with handlers that end up never being called, or worse, that are called, but are given parameter values in the wrong arguments, e.g. if UserForm_QueryClose is typed up manually with inverted parameters (the handler has 2 Integer parameters, so you need to remember the exact order.. otherwise you assign Cancel and the form understands that you assigned CloseMode)
If you're not seeing Worksheet in the left dropdown, then you're not in a worksheet's code-behind module. Worksheet events can only be handled in a worksheet module.
In a Workbook module (i.e. ThisWorkbook) you can handle the SheetBeforeDoubleClick event to handle a double-click on any worksheet in the workbook:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
End Sub

Related

Trigger macro with change in different worksheet

Apologies any incorrect terms, this is the first time I am trying to code a macro. I currently have the following code running:
Private Sub Worksheet_Deactivate()
'Alpha Show / Hide
If Sheets("Project_selection").Range("D4") = Range("C2") Then
Sheet3.EnableCalculation = True
ElseIf Sheets("Project_selection").Range("D4") = "All" Then
Sheet3.EnableCalculation = True
Else
Sheet3.EnableCalculation = False
End If
End Sub
which has been cobbled together from other codes and google. It works, but only when I move out of the sheet, which I think is being driven by the first line.
I would actually like it to activate when the Cell D4 in the 'Project_selection' sheet (a separate sheet to the one the code is on) gets changed - does anyone know how I would do that? I have seen references to worksheet_change, but I do not understand how one defines the target/range to get the appropriate reference.
Hope that makes sense and thanks in advance!
If you were to place the following code under the sheet (Project_selection), it would fire that event every time a change has happened in Cell D4:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet: Set ws = Sheets("Project_selection")
If Target.Address = "$D$4" Then
If ws.Range("D4") = ws.Range("C2") Then
Sheet3.EnableCalculation = True
ElseIf ws.Range("D4") = "All" Then
Sheet3.EnableCalculation = True
Else
Sheet3.EnableCalculation = False
End If
End If
End Sub

Locking cell based on value on other cell

Please find the below code. I am not sure where am I going wrong in my code.
My purpose is to check the value in D44 cell(drop down list) and based on the value lock/unlock D45 cell.
Values in D44 are NO,13 fracto,18 fracto,Any Other Fracto"
User should be able to edit the cell D45 only if the D44 cell value is set to "Any Other Fracto".
Sub TheSelectCase()
Select Case Range("D44").Value
Case "Any Other Fracto"
Range("D45").Locked = False
Range("D45").Activate
Case = "NO"
Range("D45").Locked = True
Range("D45").Clear
Case <> "NO" Or "Any Other Fracto"
Range("D45").Locked = True
End Select
End Sub
Unless the dropdown is an ActiveX control, you'll need to do this via Worksheet_Change event handler, and also, you only have two cases: 1) A case where user is allowed to edit ("Any other fracto") and 2) any other value in which the user is not allowed to edit.
Assuming you're using a Validation List, do this in the worksheet's Worksheet_Change event:
Private Sub Worksheet_Change(ByVal Target As Range)
'Exit on any other cell
If Intersect(Target, Range("D44")) Is Nothing Then Exit Sub
Application.EnableEvents = False
Dim inputCell As Range
Set inputCell = Range("D45")
Select Case Trim(LCase(Target.Value))
Case "any other fracto"
inputCell.Locked = False
inputCell.Activate
Case Else
'This handles **ANY** other value in the dropdown
inputCell.Locked = True
InputCell.Clear
End Select
Application.EnableEvents = True
End Sub

Mandatory fields red. Now how to save?

What it does: Requires fields from users. Blocks user from saving if specific fields are missing. Turns those fields red until saved correctly.
What I need: Well, how the hell am I supposed to save this...
What I would like: Since the worksheet is blank. I cannot save. and required fields are red. EVEN if I could save I would LIKE the cells to be on no fill until I roll it out.
View Original Post Here
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim xlSht As Worksheet
Dim cellsNotPopulated As Boolean
cellsNotPopulated = False
Set xlSht = ThisWorkbook.Worksheets("1st Call")
With xlSht
If .Range("F7") = "" Then
.Range("F7").Interior.Color = RGB(255, 0, 0)
cellsNotPopulated = True
Else
.Range("F7").Interior.ColorIndex = xlNone
End If
End With
If cellsNotPopulated = True Then
MsgBox "Please review the highlighted cells and ensure the fields are populated."
Cancel = True
End If
End Sub
If you are in the middle of development and want to "break the rules" and save your current efforts, then in a standard module:
Sub MyPrivateSave()
Application.EnableEvents = False
ThisWorkbook.Save
Application.EnableEvents = True
End Sub
Of course, when you finish development, you would remove this little "save tool" before you send the workbook out to the users.
or add as the first line if environ("Username")=your username then exit sub

Sub or function not defined: Buttons()

I had this sub in another spreadsheet where I could click a button to collapse and expand certain columns. I copied it into a new spreadsheet to use to collapse some rows but now I get the error "Sub or function not defined". It highlights Buttons
Sub HideDetails()
Range("3:8").Select
If Selection.EntireColumn.Hidden Then
Selection.EntireColumn.Hidden = False
Buttons("btnToggleDetails").Caption = "-"
Else
Selection.EntireColumn.Hidden = True
Buttons("btnToggleDetails").Caption = "+"
Range("A1").Select
Application.CutCopyMode = False
End If
Range("A1").Select
Application.CutCopyMode = False
End Sub
There are no other scripts in this workbook. This one was originally in Module1 but I tried moving it to a new module.
Edit: I changed the button name in the code but not the screenshot. Both references are to btnToggleDetails now but it still throws the same error.
It's telling you that the identifier Buttons() can't be found in the current scope. If Buttons() is something that you've declared somewhere else, you either need to make it public or you need to fully qualify the object that contains the Buttons() object, for example:
Sheet1.Buttons("btnToggleDetails").Caption = "+"
Had to add my answer as was sure I could shorten the lines of code:
If you consider that Selection.EntireColumn.Hidden returns TRUE/FALSE or 0/-1.
CHR(45) is a minus sign.
CHR(43) is a plus sign.
ABS turns -1 into 1.
So:
If TRUE (0) then 45-(0*2) = 45
If FALSE (-1) then 45-(1*2) = 43
This will swap the columns from hidden to visible and vice-versa and display the correct button caption in the immediate window:
Sub HideShowColumns()
Selection.EntireColumn.Hidden = Not (Selection.EntireColumn.Hidden)
Debug.Print Chr(45 - (Abs(CLng(Selection.EntireColumn.Hidden)) * 2))
End Sub
This should work in your procedure:
Sub HideDetails()
Dim rng As Range
Set rng = ActiveSheet.Range("3:8")
rng.EntireColumn.Hidden = Not (rng.EntireColumn.Hidden)
Buttons("btnToggleDetails").Caption = Chr(45 - (Abs(CLng(rng.EntireColumn.Hidden)) * 2))
End Sub

Custom function will not update automatically (settings are set to auto calculations!)

I have a custom function that detects if a cell is bold
Function isBold(cellBold)
If cellBold.Font.Bold = True Then
isBold = 1
ElseIf cellBold.Font.Bold = False Then
isBold = 0
Else
isBold = 0
End If
End Function
Puts 1 in a cell if the reference cell is bold and 0 if it is not bold
This works well and all the first time around but if I make the reference cell bold the number stays at 0. Automatic calculations are on, the only way for the function to calculate again is to retype the function
Adding Application.Volatile to the top of your function will make it auto update when the workbook change event is fired.
Function isBold(cellBold)
Application.Volatile
If cellBold.Font.Bold = True Then
isBold = 1
ElseIf cellBold.Font.Bold = False Then
isBold = 0
Else
isBold = 0
End If
End Function
This will not help you if you just bold a result but you can add an event to the sheet you're working on
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Calculate
End Sub
If both of these things are in place, your formula will update every time you select a different cell which may work well enough for you. However, I suggest using this method with caution because if you have a very large number of formulas this could slow things down.
-Edit- This should fix the copy paste issue.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim col As Range
For Each col In ActiveSheet.UsedRange.Columns
col.Calculate
Next
End Sub
OK, So I'll be the first to admit this is not an ideal solution, and is pretty hackish. But i think it will fix your solution.
After adding the volatile line to your code as so:
Function isBold(cellBold)
Application.Volatile True
If cellBold.Font.Bold = True Then
isBold = 1
ElseIf cellBold.Font.Bold = False Then
isBold = 0
Else
isBold = 0
End If
End Function
First Change your Workbook_Open to this:
Private Sub Workbook_Open()
Sheets("Sheet1").rngLastCell = Range("A1").Address
Sheets("Sheet1").fntLastCell = Range("A1").Font.Bold
End Sub
Then on the worksheet you are working with (In my example Sheet1) Add this to the Worksheet function:
Option Explicit
Public fntLastCell As Boolean
Public rngLastCell As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Sheets("Sheet1").Range(rngLastCell).Font.Bold <> fntLastCell Then
Calculate
End If
Sheets("Sheet1").rngLastCell = Target.Address
Sheets("Sheet1").fntLastCell = Target.Font.Bold
End Sub
Now to have it work you must Save then close, Then re open your worksheet.
This works by setting 2 global variables each time you select a new cell.
a Boolean variable that states weather the Last Cell selected WAS PREVIOUSLY Bold or not. And a String Variable that references that same Cell. So, you can now check the Bold state of the cell you exited (when it was entered) against the Current Bold State of the cell you just existed and if there was a change it will calculate the workbook. Otherwise nothing will happen.
Hope this works and helps,
Cheers