How to insert a character in Excel cell by simply clicking on it? Clicking again on the cell would remove the character from the cell.
Example:
I have a cell range, A1:A10. If I click on a cell on this range a "X" is inserted on that specific cell, clicking again on it would remove the "X".
Can this be made through a button assigned to a macro? (the button would be assign to a specific cell)
I have a cell range, A1:A10. If I click on a cell on this range a "X" is inserted on that specific cell, clicking again on it would remove the "X".
You have to be very careful when you are using Worksheet_BeforeDoubleClick. If you do not take care of that in the code then the code will fire whenever there is a double click. Also use Cancel = True appropriately else you may get undesired results.
Is this what you are trying?
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, _
Cancel As Boolean)
'~~> Check if the double click happened in Range A1:A10
'~~> Also notice the placement of `Cancel = True`
If Not Intersect(Target, Range("A1:A10")) Is Nothing Then
'~~> Check if the cell is empty
If Len(Trim(Target)) = 0 Then
Target.Value = "X"
Cancel = True
'~~> Check if the cell already has X. This is to ensure that
'~~> the cell is not cleared if the user has typed something
'~~> else in the cell.
ElseIf UCase(Trim(Target)) = "X" Then
Target.ClearContents
Cancel = True
End If
End If
End Sub
I would suggest to use double click to enter/remove value. If you're ok with using double click..then here's the code for that:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
If IsEmpty(Target.Cells) Then
Target.Cells.Value = "x"
Else: Target.Cells.Clear
End If
Cancel = True
End Sub
The code needs to be placed in ThisWorkbook object
This does not seem like a good approach. Why not use dropdowns?
Go to Data->Validation select a list. You can either select your list of options from an Excel range or simply specify the list like this "Item1;Item2" etc.
Using any VBA will prevent the usage Undo function in Excel meaning - any time a macro executes in Excel all you undo history is cleared. This is very inconvenient when making changes.
Related
I have the below code. I want to have my cursor active in a cell, run the macro, and have the vba put the string of periods onto the clipboard then paste them into the cell where my cursor is active. Can this be done?
Dim obj As New DataObject
Dim txt As String
'Put some text inside a string variable
txt = ".............................."
'Make object's text equal above string variable
obj.SetText txt
'Place DataObject's text into the Clipboard
obj.PutInClipboard
Looking at your last question you may be able to use a Worksheet_Change event to simply add your periods at the end of the string after every edit.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge = 1 Then
If Len(Target) > 0 Then
Application.EnableEvents = False
Target = Target & "......"
Application.EnableEvents = True
End If
End If
End Sub
You can customize this to a degree if this route is feasible. For instance, right now the macro ignores any changes that result in the cell being blank (i.e. you can still clear a cell with normal functionality). As per #BigBen's suggestion, the macro also ignores changes that apply to multiple cells at once (i.e. pasting a range to your sheet) You can also amend this to only fire if the cell changed is in a certain row/column. etc.
I want my macro to stop if there's no value entered in any of the four cells I need. But i want it to run if there's at leats one value in those four cells.
This is what i have so far:
If Range("e12,h12,k12,d12").Value = "" Then
MsgBox ("Por favor introducir dimensiones")
Range("e12").Select
Exit Sub
End If
If you introduce a value in cell e12, it will run. But if you introduce a value in any other cell, the msgbox will pop out and the macro will stop.
Could you help me find the problem?
Thank you!
Please install the event procedure below in the code sheet of the worksheet on which you want the action.
Private Sub Worksheet_Change(ByVal Target As Range)
Const Triggers As String = "E12,H12,K12,D12"
Dim Rng As Range
Dim Cell As Range
' skip if more than one cell was changed (like paste)
If Target.Cells.CountLarge = 1 Then
Set Rng = Range(Triggers)
For Each Cell In Rng
If Cell.Value = "" Then
Cell.Select
Exit For
End If
Next Cell
End If
End Sub
Now, if the user enters something in E12 the macro will select H12. If the user enters something in D12 next the macro will take him back to K12. That's all very nice.
But if the user changes something in A3 (anywhere, in fact) he will be taken to the first empty cell of the trigger range. Therefore the system must be tweaked to accommodate your workflow. Perhaps the code should be made to run only when D12 is entered, or when the user clicks on the cell he shouldn't click on before completing the trigger range.
In short, the scope of the procedure may have to be trimmed to suit your workflow. This can be done by either including specific cells in the trigger range, or by excluding other cells.
you coudl use WorksheetFunction.CountA() function to count the number of not empty cells:
If WorksheetFunction.CountA(Range("e12,h12,k12,d12")) <> 4 Then
MsgBox ("Por favor introducir dimensiones")
Range("e12").Select
Exit Sub
End If
I'm working on a table where I've inserted some Checkboxes (Form Control) which are linked to cells that return True or False when either Checkbox is ticked.
I wrote a code that should change the cell's color according to the returned value.
The code works fine but only when I double click the cell and validate by pressing Enter, or when I run the Sub by hitting F5 or a clicking a button.
(I used a similar code that updates everything automatically in another project but it doesn't seem to work here)
How can I make the Sub run automatically (or the sheet update) once a checkbox is ticked?
Here is the code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Range("A2:Q21"), Range(Target.Address)) Is Nothing Then
Dim cell As Range
For Each cell In ActiveWorkbook.Sheets("Sheet1").Range("A2:Q21")
If cell.Value = "True" Then
cell.Interior.Color = vbGreen
ElseIf cell.Value = "False" Then
cell.Interior.Color = vbRed
End If
Next
End Sub
I know I could use conditional formatting but this sheet will expand rapidly and I don't see myself copy-pasting hundreds of checkboxes
As the sheet will expand I think it'll be better to include a "lastRow" statement since I will be adding new rows at the bottom using a UserForm
Thanks!
You should extract the part doing the coloring to a new function and call that from both the original and from the checkbox's event handler.
' In Sheet1 Module
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Range("A2:Q21"), Range(Target.Address)) Is Nothing Then
ColorCells
End If
End Sub
' In Module1 Module
Sub CheckBox1_Click()
ColorCells
End Sub
Public Sub ColorCells()
Dim cell As Range
For Each cell In ActiveWorkbook.Sheets("Sheet1").Range("A2:Q21")
If cell.Value = "True" Then
cell.Interior.Color = vbGreen
ElseIf cell.Value = "False" Then
cell.Interior.Color = vbRed
End If
Next
End Sub
Update
If there are too many checkboxes than you may use the Worksheet's Calculation event handler assuming that the checkboxes have Linked Cells and some other Cell refers to their value.
' In Sheet1 Module
Private Sub Worksheet_Calculate()
ColorCells
End Sub
Note, if the checkbox does not have a Linked Cell, it won't work. If the checkbox has a Linked Cell but it is not referred to by any other cell, it won't work. This is because in these cases no recalculation will be initiated.
You can test this: Assign A1 to a Checkbox (on a new sheet), and try if the macro runs (should not), then write in A2 =2*--A1, and check again, now it should work.
If you want to minimize the footprint of this requirement, find an unused cell on the sheet and enter the following formula: =INDEX(1:1048576,1,1). This refers to all cells but it does not require a lengthy calculation. Of course, if you want to place it into A1, you should change the ,1,1 part to something else to avoid circular references.
Instead of firing your colouring sub at Worksheet_Change, put it under Worksheet_Calculate. Then insert the formula =A1:Q21(or whatever you need to cover your range) somewhere in your sheet. It will resolve to #value but that isn't important. This formula will force your sheet to automatically recalculate when anything within its range is changed, including the cells linked to your checkboxes. And then upon recalculate it will fire the sub that colours your cells correctly.
In the code below that i got working, when i select a cell in a range, an input box pops up and my input is sent to the same cell i clicked but in sheet 2. I want to take this one step further. i want to bypass the input box completely and just send the value F, and i only want to do this after i click cell b2. so cell b2 would have to work as some kind of toggle (maybe put an invisible shape over it to act as a button?)
Example 1: sheet 1, select cell B2 turns on macro, select cell in range example: D10 inputs the letter F into cell D10 on sheet 2, select cell B2 turns off macro so if i select cell D10 or any cell in that range nothing will happen anymore. it would also need to remove the value F from D10 if the cell is clicked again while the macro is on.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xRtn As Variant
If Selection.Count = 1 Then
If Not Intersect(Target, Range("D9:AS20")) Is Nothing Then
xRtn = Application.InputBox("Insert your value please")
Sheets("2020").Range(Target.Address).Value = xRtn
End If
End If
End Sub
Untested. I'm not sure if I understood all of your objectives.
I think if you add a checkbox to your worksheet (resize and store it wherever you want; maybe in cell B2) called "Check Box 1" then the below code should work.
One way of adding a check box might be: Excel > Developer > Insert > Check Box (Form Control) (depending on your Excel version). If the Developer tab is not visible, you may need to get it to show first.
Option Explicit
Private Function GetCheckBox() As Shape
Set GetCheckBox = Me.Shapes("Check Box 1")
End Function
Private Function IsCheckBoxTicked() As Boolean
IsCheckBoxTicked = (GetCheckBox.OLEFormat.Object.Value = 1)
End Function
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.CountLarge <> 1 Then Exit Sub
If Intersect(Target, Me.Range("D9:AS20")) Is Nothing Then Exit Sub
If IsCheckBoxTicked() Then
With ThisWorkbook.Worksheets("2020").Range(Target.Address)
.Value = IIf(.Value = "F", Empty, "F")
End With
End If
End Sub
I have a question regarding creating macros whereas the scenarios as follows:
Sheet1
Upon clicking any cell in Sheet1, it will automatically filter based on cell A and B.
Sheet2
Automatically display filtered criteria based on double click from Sheet1
For example: when I double click on C1, on Sheet2 will automatically diplay filtered data based on A1 and B1 and same thing goes to if I double clik on C2 on Sheet2 will automatically diplay filtered data based on A1 and B2.
Really need help from the experts here.
This would be the code you need to catch your single-click event:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Debug.Print Target.Address
End Sub
This would be the code you need to catch your double-click event:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Debug.Print Target.Address
'cancel the double click, prohibiting editng of cell per double-click
Cancel = true
End Sub
I would have helped you with your filtering too, but since you did not paste any code to that, and I don't get how excactly you want what data to be filtered, I'll leave that up to you ;)
Edit:
This code can be used for Worksheet_SelectionChange and will set a filter based on a valid selection inside the used range. If a filter is already in place, it will be deactivated.
On Error Resume Next
If Sheet1.AutoFilterMode Then
'clear existing autofilter
Sheet1.UsedRange.AutoFilter
Else
'setup filter based on selection
Sheet1.UsedRange.AutoFilter field:=Target.Column, _
Operator:=xlFilterValues, _
Criteria1:=Target.Value, _
VisibleDropDown:=True
End If