I set up a excel sheet with drop-down menus for some of the cells. The
user can only select values from that list and an error message pops up
when something is typed it that is not in the list (via Data Validation
Error Alert).
So this works all fine ... But when the user copy paste into the cells then validation doesnt work. How to make validation effective in case of copy paste.
I have searched and found one solution but its not working.
Here is the code that I have found. but its not working any more..It always return true enven I copy paste worng
Private Sub Worksheet_Change(ByVal Target As Range)
If HasValidation(Range(ActiveCell.Address)) Then
Exit Sub
Else
Application.Undo
MsgBox "Your last operation was canceled." & _
"It would have deleted data validation rules.", vbCritical
End If
End Sub
Private Function HasValidation(r) As Boolean
On Error Resume Next
x = r.Validation.Type
If Err.Number = 0 Then HasValidation = True Else HasValidation = False
End Function
It looks like you took the code from this page:
http://www.j-walk.com/ss/excel/tips/tip98.htm
When Worksheet_Change fires, your code always refers to the active cell, not the target where the copy/paste operation is being performed.
Change
ActiveCell.Address
to
Target.Address
and see if that works.
The "Target.Address" worked for me as mentioned by #JimmyPena.
But the solution still brings a bug, that if one tries to add another validation after adding the above mentioned VB code, the user is fired with the amount of message boxes produced by the vb code which is applied to the number of cells (viz. You will have to click on "OK" of the message box provided by the VB code for the number of cells the VB code has been applied to.. If code applied to 40 cells then you have to click "OK" 40 times... phew..)
Can you please try to help to add another condition to help this?
Or the last way that remains to only add the VB code after adding all the validations.
Related
I am using VBA to add data validation to my cells. However instead of using the AlertStyle argument provided in the Add method, I want to create a custom error handler. Reason being, the AlertStyles provided by VBA do not force the user to abort cell editing if an incorrect value is added. The user can select "Retry" or "Cancel", and sometimes, when they hit "Cancel", all cell contents are lost (if there was only one value previously in the cell. If there was more than one value previously in the cell, no values are lost). So I'd rather create an error handler that exits the Sub when the user enters invalid data.
Here's my attempt:
Sub customised_validation_dates_2()
With ActiveSheet.Range("Date_Entry").Validation
On Error GoTo err
.Delete
.Add Type:=xlValidateDate, _
Operator:=xlBetween, Formula1:="01/01/2000", Formula2:="=TODAY()"
.IgnoreBlank = True
err: Exit Sub
End With
End Sub
but when an invalid date is entered, a message box still pops up, prompting the user to either retry data entry or cancel data entry, but like I said, if there is exactly one value previously in the cell and the user hits "Cancel", the cell value is lost.
extra context:
I have another macro running that allows the user to enter multiple values in one cell. So what I am trying to do is, if in the cell there is already another value, and the user tries adding another value that is invalid, I want to exit cell editing without giving the user the option to retry or cancel data entry, which is the root of my issue (because when they hit "cancel" and there is already a value in the cell, that other value gets erased).
I think you've gotten confused about your errors. Your code relating to errors (on error and err) is related to VBA errors and has nothing to do with cell validation.
To illustrate a error walkthrough example...
Sub exampleOfErrorHandling()
Dim aResponse As String
aResponse = InputBox("Enter something. Text will trigger an error while a nubmer will be accepted.")
If aResponse = "" Then Exit Sub
'programs procedure to jump to section problem with an error
On Error GoTo ProblemZone
Dim anyNumber As Integer 'variable will only accept number
anyNumber = aResponse
On Error GoTo 0 'sets errors to be handled in default method
MsgBox anyNumber & " is a valid number"
'section where other code would typically be inserted
Exit Sub 'where normal code would end
ProblemZone:
'section to handle errors
Dim tryAgain As Long
tryAgain = MsgBox(aResponse & " is not a number. Try again?", vbYesNo + vbCritical)
If tryAgain = vbYes Then Call exampleOfErrorHandling
End Sub
What it appears you want is something with cell validation. You might consider trying the record macro while setting validation to capture exactly what you want. Then engineer that to set the validation as you prefer.
Alternatively, you could use the change event to remove prior values if they don't meet requirement. Here's example of requiring cell A2 to be numeric. Note this must be in the sheet module, not the typical Modules section.
Private Sub Worksheet_Change(ByVal Target As Range)
'cell A2 must be a number
If Not Intersect(Target, Me.Range("A2")) Is Nothing Then
If Not IsNumeric(Me.Range("A2")) Then
MsgBox "A2 is not numeric"
Application.Undo
End If
End If
End Sub
The below code is written into the code of a Sheet (called "Start page") rather than connected to a button.
For reference, cell C17 asks the user of the sheet if they're ready to start, and they have a data validation in D17 linking to M2 (Yes) and M3 (No).
The idea is that when the user selects Yes, the code kicks in and auto-advances to the next sheet ("Selection page"). If they select No, a pop-up box will display advising the workbook will close (I've not written this code yet).
The problem is, whilst I can't see what's wrong with this code, whenever the user selects anything from the data validation, nothing happens.
I'd be really grateful if someone could review the code to see what I'm missing. I've tried Range("D17") and Range("D17").Value but still nothing.
Thanks
EDIT - latest code listed below
Private Sub Worksheet_Change()
Dim output As Integer
Application.ScreenUpdating = False
Dim output As Integer
If Sheets("Start page").Range("D17") Is Nothing Then GoTo ExitHandler
If Sheets("Start page").Range("D17") = Sheets("Start page").Range("M2") Then
Sheets("Selection page").Activate
Else
output = MsgBox("This sheet will now close.", vbCritical, "Closing")
Activebook.Close
ExitHandler:
Application.ScreenUpdating = True
End Sub
Currently, you have nothing triggering the code. You probably want to tie this into a Worksheet event, such as Worksheet_Change or Worksheet_SeletionChange
The quick way to check what Events are available is to go to the top of the Code Pane, select the "Worksheet" object from the Left drop-down, and select the Even from the Right drop-down. This will also automatically add the correct Parameter list:
The "Change" event will occur when any cell on the Worksheet is Changed - while the "SelectionChange" event will happen when you select something new, even if you haven't altered the old thing
For the "Change" event of the Worksheet there is 1 Parameter, ByVal Target As Range - this is the Range of Cells that have been changed. So, for example, you can use MsgBox "Row " & Target.Row & " was changed" to display a message telling you which row the changed cell is on.
Since the Event will automatically pass the Argument to the Sub, you need to have the Parameter there to 'catch' it.
I have looked at some examples for my question but couldn't find an answer that works.
Background:
I have a list of items (let's say apple, orange, banana) in Sheet1 (A2:A77, which is already a defined range with the name "Liste").
I then have on another sheet (Let's say Sheet2) with several cells where a userform (created with vba code) pops up where the user can choose an item and click OK.
However, due to the nature of the userform (and the list), you can have spelling errors etc and it will still be accepted. So I would like to create a check where it matches the input to the given list (to prevent users from putting anything else in). The userform/code is on purpose to keep it searchable (rather than just a simple data validation list).
Issue:
I tried to create this with vba code that checks the input, matches it to the Sheet1 list and if there is no match, shows a msgbox with a statement. This partially worked (for some letters but not others, very strange).
Here is the code I had:
Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Dim rSearchRng As Range
Dim vFindvar As Variant
If Not Intersect([B7:B26], Target) Is Nothing Then
Set rSearchRng = Sheet4.Range("Liste")
Set vFindvar = rSearchRng.Find(Target.Value)
If Not vFindvar Is Nothing Then
MsgBox "The Audit Project Name you have entered is not valid. Please try again!", vbExclamation, "Error!"
Selection.ClearContents
End If
End If
Application.EnableEvents = True
End Sub
So I was thinking of creating this error message instead with a simple data validation.
Data validation
I have tried the "list" option (and put it equal to the named range) but that did nothing (no error box showed up)
I have tried "Custom" with the following formula 'SUMPRODUCT(--(B12=Liste)>0)=TRUE (I found this on a post which worked for others when I tried it in the cell it gave me the expected "TRUE/FALSE" results) but still nothing shows up
UPDATE
Tigeravatars data validation recommendations work if you don't have a userform (see comments below).
For it to work with a UserForm, I changed the 'MatchEntry' to TRUE and also deleted any unwanted "change events" from my ComboBox code. The final code I use now is below:
Dim a()
Private Sub CommandButton2_Click()
End Sub
Private Sub UserForm_Initialize()
a = [Liste].Value
Me.ComboBox1.List = a
End Sub
Private Sub ComboBox1_Change()
Set d1 = CreateObject("Scripting.Dictionary")
tmp = UCase(Me.ComboBox1) & "*"
For Each c In a
If UCase(c) Like tmp Then d1(c) = ""
Next c
Me.ComboBox1.List = d1.keys
Me.ComboBox1.DropDown
End Sub
Private Sub CommandButton1_Click()
ActiveCell = Me.ComboBox1
Unload Me
End Sub
Private Sub cmdClose_Click()
Unload Me
End Sub
I thought I show it here in case anyone stumbles across my question.
Thank you!
Select your cells where you want to put the data validation
With the cells selected, go to Data Tab -> Validation
Set "Allow" to "List" and set the Source to =Liste as shown here:
Next go to the "Error Alert" tab and set "Style" to "Warning" and enter the desired text in "Title" and "Error Message" as shown here:
Test it out. You should now have a drop-down list of valid choices, and if you attempt to manually enter an invalid choice you'll get the error message you specified.
As a note, if you want the data validation to completely disallow/prevent any entry not in the list, you'll need to set the Error Allert -> Style to be "Stop" instead of "Warning".
EDIT:
Per comments, it can't be a drop-down list. I highly recommend using a drop-down list for this because it will be the most effective way to cut down on time entering data as well as reduce errors from typos. However, if it absolutely cannot be a drop-down list, then you can use a Custom Data Validation and set the formula to =ISNUMBER(MATCH(B7,Liste,0)) (we are using B7 here because it is the first cell in the range of cells that contains this data validation).
Try the following formula:
=NOT(ISERROR(FIND("-"&A1&"-",(TEXTJOIN(,"-",TRUE,Sheet1!A1:A77)))))
That combines all the texts and then see if what's in the cell occurs in the list. I put it between dashes to prevent it from accepting partials.
I have a macro which is basically working as I want (alerting the user when two conflicting checkboxes are selected) - code below. The 1 in G2 is the value generated to indicate this case.
The error message fires on SelectionChange, but this appears to be only when another cell is selected by mouse. The worksheet contains a series of checkboxes for the user to select from, and the intention is for the user to only use the checkboxes, never needing to select or input directly into cells. In which case, the error message would never fire even when the scenario described has occurred.
Is there a way of having a msgbox macro trigger by the update of any checkbox on the sheet?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("G2") = 1 Then
MsgBox "ERROR - Select AND Reject checked"
End If
End Sub
Also, I would like to extend the range to apply to all the cells in column G, I just can't seem to get this to work for me. I have seen a few examples citing "G:G" but I have so far only got this to work for one cell.
Apologies in advance for any glaring errors, I've used Excel for a while now - but I'm brand new to using VBA.
Mutually exclusive options are usually indicated with option buttons (also known as radio buttons) instead of checkboxes. Is there any reason you're not using option buttons for this task?
As far as calling the same code for all checkboxes, the checkboxes would have to be Form Controls (not ActiveX Controls), and you could assign them to this macro:
Sub CheckBox_Clicked()
Dim chk As CheckBox
Set chk = ActiveSheet.CheckBoxes(Application.Caller)
MsgBox chk.Name
End Sub
And lastly, for your SelectionChange event to monitor an entire column, it would look similar to this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim ClickedCell As Range
Dim rngClicked As Range
Application.EnableEvents = False
Set rngClicked = Intersect(Columns("G"), Target)
If Not rngClicked Is Nothing Then
For Each ClickedCell In rngClicked.Cells
If ClickedCell.Value = 1 Then MsgBox "ERROR - Select AND Reject checked"
Next ClickedCell
End If
Application.EnableEvents = True
End Sub
I have two macros in a worksheet. The first one check whether certain cells are addressed and have certain values then runs another macro. The following code is used for this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("K10:K1000")) Is Nothing And Target.Value = "Trapezoidal roof 0.6mm and above" Or Target.Value = "LightBox ballasted" Then
Application.ScreenUpdating = False
Call PPAPricePerkWp
End If
End Sub
This works fine on it's own.
The second macro is run when a button is clicked. This macro copies and pastes cells/rows to other parts of the spreadsheet.
When the macro is run I get the error Runtime error 7 - out of memory and it breaks on the above bit of code.
Is there another way I can check whether cells in a certain column are addressed and have certain values and won't lead to the above error?
you might want to disable events before you call your subroutine, so that the Worksheet_Change is not being triggered every time you change a cell
Application.EnableEvents = False
Don't forget to turn it back on when you are finished