I have a spreadsheet that is going to be used in a survey.
How can I make the cells only to return "x" regardless of what the survey taker type in.
For instance, if I write a "w" in the cell, it should turn into an "x".
I have come to a point where I think there is an option when I protect the workbook or sheet. Because I can tell from another spreadsheet (which has this function) that it only works if the workbook is protected.
I tried to google it, but it seems as if I don't know the right keywords to find the answer.
Also, I have found a set of Vba code that I fiddle with, but I'm not sure this is correct. I don't want to attach the code as I don't want to confuse any response here.
Thank you for any help provided.
Put this code in the worksheet module and test it out, when you change a cell in column A (1) it will activate,
Where is the worksheet Module?
Copy and paste the code ,
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Intersect(Target, Range("A1,B1,C1,A4,B4,C4")) Is Nothing Then Exit Sub
Application.EnableEvents = 0
If Target <> "" Then Target = "X"
Application.EnableEvents = 1
End Sub
This should work for you (just change the range to the one you need) :
Option Explicit
Sub worksheet_Change(ByVal Target As Range)
On Error GoTo errorbutler 'error handler - important to have this in case your macro does a booboo
Application.Calculation = xlCalculationManual 'turn off automatic calculation to speed up the macro
Application.EnableEvents = False 'turn off events in order to prevent an endless loop
Dim LR, cell As Range 'Declare your variables
Set LR = Range("A1:b3") ' Select range of cells this macro would apply to
For Each cell In Target 'Loops through the cells that user have changed
If Union(cell, LR).Address = LR.Address Then 'Checks if the changed cell is part of your range
cell.Value="x" 'changes the value of that cell to x
End if
Next cell
Errorexit: 'part of error handling procedure
Application.EnableEvents = True 'Turn autocalc back on
Application.Calculation = xlCalculationAutomatic 'turn events back on
Exit Sub
Errorbutler: 'error handling procedure
Debug.Print Err.Number & vbNewLine & Err.Description
Resume Errorexit
End Sub
Oh yes, and this code should be put into the worksheet module - the same way as Dave has shown you
Related
I would like to hide rows in column B9-B40 when Index/Match formula returns "N/A" , now I managed to get it done in VBA when the table is static but I have a dynamic table based on drop-down selection which means the number of N/As returned can be different for each time drop-down selection changes.
Here is what I have right now which hides the rows with N/A based on current drop-down selection, my dropdowns are in C2,C3 and C4. But it doesn't takes any further change in the dropdown into consideration afterwards. I am not very competent with the VBA so any help would be great.
Thanks.
Option Explicit
Sub hide_if_error()
Dim MyCell As Range, Rng As Range
Set Rng = Range("B9:B40")
For Each MyCell In Rng
If IsError(MyCell) Then
MyCell.EntireRow.Hidden = True
End If
Next MyCell
End Sub
You can do
Range("B9:B40").SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Hidden = True
You will need a test in advance that errors are present though.
That might look like:
Option Explicit
Public Sub hide_if_error()
With ThisWorkbook.Worksheets("Sheet4")
.Range("B9:B40").EntireRow.Hidden = False
If Evaluate("=SUM(IF(ISERROR(" & .Range("B9:B40").Address & "),1))") > 0 Then '<==check if any errors present
.Range("B9:B40").SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Hidden = True
End If
End With
End Sub
If necessary, you could link the above to a worksheet change or dropdown change event so it is fired each time there is an update using the dropdown(s)
For example:
If you data validation was in C2:C4 you would put in the code pane for the sheet the following event code:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ErrHand
If Not Intersect(Target, Range("C2:C4")) Is Nothing Then
Application.EnableEvents = False
hide_if_error
End If
ErrHand:
Application.EnableEvents = True
End Sub
Note:
The worksheet event code goes in the code pane associate with sheet 4:
The other code goes in a standard module (module 1 here):
Example run:
first of all I'm not a VBA programmer but typically an end-user who uses snippets of code that I gather in forums like this in his spreadsheets, trying to understand what the code does. Code for which I thank you all!
My objective:
I have a spreadsheet that is basically an input-form for users.
Based on their input and selections via dropdown my intention is to guide them through the form by hiding & unhiding rows with input fields, presenting the users with the relevant questions.
On each row I have created an IF-formula that creates a 1 or 0 based on previous provided input
1 -> unhide the row , 0 -> hide the row.
So I'm looking for a macro that runs with every sheet calculation and hides or unhides the next rows as needed.
These formulas are in range I3:I70 on top of that I created a summary field in I2 =sum(I3:I70) so i thought I can either check changes in the range I3:I70 or changes on cell I2 to trigger the macro. [Neither solution fixed my problem]
I've tried several code examples discribed on the forums and I've tested the macros that checks for change in the range or the cell individually.
As long as I call a test macro with a MsgBox it works fine.
Also the macro that hides or unhides runs fine when I call it manually.
My problem:
When I let the 'auto'-macro call the 'hide'-macro, Excel simply crashes; no warnings, nothing --> just crash.
My code:
Private Sub Worksheet_Calculate()
Dim Xrg As Range
Set Xrg = Range("H3:H70")
If Not Intersect(Xrg, Range("H3:H70")) Is Nothing Then
Macro1
End If
End Sub
Sub Sample()
MsgBox "Yes"
End Sub
Sub Macro1()
Dim cell As Range
For Each cell In Range("H3:H70")
If Not IsEmpty(cell) Then
If cell.Value = 0 Then
cell.EntireRow.Hidden = True
End If
If cell.Value = 1 Then
cell.EntireRow.Hidden = False
End If
End If
Next
End Sub
Thanks for any suggestions and tips in advance.
JeWe
Never give up searching :-) I gave it a last search and found some code on the microsfof dot com site that seems to work.
Don't ask me the details but this seems to do what i'm looking for
Private Sub Worksheet_Calculate()
Dim LastRow As Long, c As Range
Application.EnableEvents = False
On Error Resume Next
For Each c In Range("H3:H70")
If c.Value = 0 Then
c.EntireRow.Hidden = True
ElseIf c.Value = 1 Then
c.EntireRow.Hidden = False
End If
Next
On Error GoTo 0
Application.EnableEvents = True
End Sub
It's late on my end of the world, going to sleep. Will update tomorrow.
Txs JeWe
I'm currently using VBA to check when cells in a certain column are changed, so I can call a different macro to sort them. This works wonderfully, except that it also triggers whenever I insert a new row. So using IsEmpty I added a check to see if the cell in question isn't empty. But I'm obviously doing it wrong, since my macro is still called whenever I insert a row. What am I doing wrong?
The VBA that triggers on cell changes:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("A:A")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
If Not IsEmpty(KeyCells) Then
Call SortByDate
End If
End If
End Sub
You might filter out row insertions by checking the number of cells that received a change. In the case of a row insertion, this is greater than or equal to the worksheet's columns.count. If you are changing anything on that worksheet use application.enableevents = false before starting to change anything and application.enableevents = true before leaving the sub.
Private Sub Worksheet_Change(ByVal Target As Range)
' exit immediately on row insertion
If Target.CountLarge >= Columns.Count Then Exit Sub
If Not Intersect(Target, Columns(1)) Is Nothing Then
'escape route
On Error GoTo bm_Safe_Exit
'don't declare or Set anything until you know you will need it
'(this isn't really terribly necessary)
Dim KeyCells As Range
Set KeyCells = Range("A:A")
If Application.CountA(KeyCells) Then 'is there ANYTHING in A:A?
Application.EnableEvents = False
Call SortByDate
End If
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
Failing to disable event handling and subsequently changing anything on the worksheet will trigger another change event and the Worksheet_Change event macro will try to run on top of itself.
I have an Excel like shown below which is a sharedExcel.
Now i should not allow paste option for the rows which have backcolour as GRAY(These are not fixed at runtime any row may get GRAY colour). As it sharedExcel and i can't use the Lock property. Any help wouls be appreciated greatly.
Using a color as a property that is used to check true / false is bad behaviour.
You can get around this by for example adding a column (hidden if needed) with 0 / 1 or TRUE / FALSE which you make accessible by for example a combobox (then you can still adapt the color into gray by clicking this cbb box).
The you can check on a dynamically composed range via a Sheet event on_Change.
The basic syntax for the sheet event:
Private Sub Worksheet_Change(ByVal Target As Range)
'Set range dynamically instead of this hard coded example
If Not Intersect(Target, Thisworkbook.Sheets(1).Range("A1:A10")) Is Nothing Then
'Do something
End If
End Sub
After spending some time on this problem i have coded following lines. It work's fine. Here i have taken another spreadsheet called PasteSheet for coding purpose but i am not showing it to user at any moment.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Application.CutCopyMode Then
SelectedRow = ActiveCell.Row
With Sheets("PasteSheet")
.Activate
.Range("A1").PasteSpecial xlPasteValues
CR = Selection.Rows.Count
End With
Worksheets("ActualSheet").Activate
For k = SelectedRow To (SelectedRow + CR)
If Worksheets("ActualSheet").Cells(k, 30).Interior.Color = RGB(215, 215, 215) Then
Application.EnableEvents = False
MsgBox "Pasting is not allowed here!"
'Clearing data in PasteSheet
Worksheets("PasteSheet").Cells.ClearContents
Worksheets("ActualSheet").Activate
Application.EnableEvents = True
Exit Sub
End If
Next
End If
End Sub
I have made a spreadsheet which a user can enter a postcode and a quantity into 2 cells and I have other cells doing calculations and displaying the results.
I have added some VBA to prevent anyone from deleting rows and columns but I would like to prevent deletion of any cell within a range but also allow a user to make changes to certain cells but also prevent editing of cells with formula in there.
In cell E4, the user can enter a postcode. In E6, the user can enter a quantity. These can be edited but not deleted. E8:E9 and E11:E14 are all drop down lists (validation) which hold data from lists. These can be changed using the drop down but not deleted.
L10:L14, L16, L23:L27, L29, L30:L33 can all have their data edited but not deleted.
What would the VBA for this look like? I guess it would use the Worksheet_Change() event.
Is this what you are trying? Users can edit cell E4 and E6 but they cannot leave it empty. I am also assuming that the cell are not empty before hand.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
If Not Intersect(Target, Range("E4")) Is Nothing Then
If Len(Trim(Range("E4").Value)) = 0 Then Application.Undo
ElseIf Not Intersect(Target, Range("E6")) Is Nothing Then
If Len(Trim(Range("E6").Value)) = 0 Then Application.Undo
End If
LetsContinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
FOLLOWUP
Thanks that is what i want to do. What about the other ranges? Is it just a case of loads of IF THEN or can we use a CASE and loop through? – AdRock 2 mins ago
Add/Delete cell addresses from below as applicable.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
If Not Intersect(Target, Range("E4,E6,E8:E9,E11:E14,L10:L14,L16,L23:L27,L29,L30:L33")) Is Nothing Then
If Len(Trim(Target.Value)) = 0 Then Application.Undo
End If
LetsContinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
You are partly right but Worksheet_Change() is triggered after the change, so after the deletion.
What I'd do is to have a hidden sheet to store the values entered by the user and then you can check in Worksheet_Change() whether the new value is empty (deleted) or not.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$E$4" Then
' check the previous value on the hidden sheet here, if changed, then save it, if empty, then restore it
End If
End Sub