Hi all i will give an Excel Document for the user with some basic information as follows
Now if the user leaves a cell which is required i would like to prompt him a message saying that it is a required value with in the excel.
I have referred to some articles
But i am unable to achieve what I required so can any one help. Also I would like to know is it possible to apply Regular expression validators with in the Excel. Something like Date format should be mm/dd/yyyy and SSN should be 9 digited like that..
I tried some thing like but this didn't prompt me any error or Dialog
Private Sub Worksheet_BeforeSave(Cancel As Boolean)
If Sheet1.Range("A3:B3").Value = "" Then
Application.EnableEvents = True
MsgBox "Cannot print until required cells have been completed!"
Cancel = True
End If
End Sub
Part 1
That code has a few issues
You need a Workbook event - there is no WorkSheet_BeforeSave event
You cant test for two blank cells with Sheet1.Range("A3:B3").Value = ""
If the code is running then events are already enabled, so this line Application.EnableEvents = True is redundant
Something like this test for both A3 and B3 being non blank on the leftmost sheet
{code goes in the ThisWorkbook module}
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Application.WorksheetFunction.CountA(Sheets(1).Range("a3:b3")) <> 2 Then
MsgBox "Cannot print until required cells have been completed!"
Cancel = True
End If
End Sub
While you can use a Regex for part 2, plain data validation should work fine,ie
a) You can use an "allow" Date in Data Validation
b) You could use a Whole Number between 100,000,000 and 999,999,999 for a 9 digit number
Answer to Part 2 (Regular Expression thing)
You can write a user-defined function in VBA and use it in Excel. Here's an example that extracts parts of a string using RegEx, but with a bit of tweaking you can use it to do validation.
Related
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.
Google should provide me with ample examples but none of them seem to work
What I want: Everytime the user presses, and then releases, the ENTER key, for my program to do do something (ie. create a MsgBox, or call function Foo). I would prefer this in the form of a MWE
What I have done: I have tried googling it but none of the examples are functional. They compile, but don't do anything. I have also made sure to save in a macro compatible Excel format.
What I am using: I am using Excel 2016, 64 bit with Office 365
EDIT: The user is entering this information into the worksheet. I want to intercept the user input and everytime they press ENTER, take the cursor/active cell down two rows, so there is an empty cell below every cell. If the user presses tab, I want to take the cursor/active cell right two columns, so there si an empty cell to the right of every cell.
EDIT 2: here is a MWE of what I have right now which should work, but which does nothing. I am adding this to the worksheet, and not as a module
Sub SomeActions()
MsgBox ("Hello")
End Sub
Private Sub Workbook_Open()
Application.OnKey "~", "SomeActions"
End Sub
First, make an callback Sub that performs the logic you need. Put it into a new code module (NOT into worksheet code):
Sub SomeActions()
...
End Sub
Then, subscribe to OnKey event, for example, when the user opens the workbook (this code goes into ThisWorkbook) module in VBA editor:
Private Sub Workbook_Open()
Application.OnKey "~", "SomeActions"
End Sub
"~" means Enter key. For numeric keypad key use "{ENTER}".
What I want: Everytime the user presses, and then releases, the ENTER key, for my program to do do something (ie. create a MsgBox, or call function Foo). I would prefer this in the form of a MWE
If I read this correctly, you want a blank row between every user inputted value doing down and a blank column between every user inputted value going right.
On the worksheet code sheet:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
Dim r As Long, c As Long
If Target.Row / 2 <> Int(Target.Row / 2) Then r = 1
If Target.Column / 2 <> Int(Target.Column / 2) Then c = 1
Target.Offset(r, c).Activate
Application.EnableEvents = True
End Sub
This occurs for all navigation. If you only want this to occur on input, modify to suit a Worksheet_Change event macro instead of a Worksheet_SelectionChange event macro.
Google should provide me with ample examples but none of them seem to work
What I want: Everytime the user presses, and then releases, the ENTER key, for my program to do do something (ie. create a MsgBox, or call function Foo). I would prefer this in the form of a MWE
What I have done: I have tried googling it but none of the examples are functional. They compile, but don't do anything. I have also made sure to save in a macro compatible Excel format.
What I am using: I am using Excel 2016, 64 bit with Office 365
EDIT: The user is entering this information into the worksheet. I want to intercept the user input and everytime they press ENTER, take the cursor/active cell down two rows, so there is an empty cell below every cell. If the user presses tab, I want to take the cursor/active cell right two columns, so there si an empty cell to the right of every cell.
EDIT 2: here is a MWE of what I have right now which should work, but which does nothing. I am adding this to the worksheet, and not as a module
Sub SomeActions()
MsgBox ("Hello")
End Sub
Private Sub Workbook_Open()
Application.OnKey "~", "SomeActions"
End Sub
First, make an callback Sub that performs the logic you need. Put it into a new code module (NOT into worksheet code):
Sub SomeActions()
...
End Sub
Then, subscribe to OnKey event, for example, when the user opens the workbook (this code goes into ThisWorkbook) module in VBA editor:
Private Sub Workbook_Open()
Application.OnKey "~", "SomeActions"
End Sub
"~" means Enter key. For numeric keypad key use "{ENTER}".
What I want: Everytime the user presses, and then releases, the ENTER key, for my program to do do something (ie. create a MsgBox, or call function Foo). I would prefer this in the form of a MWE
If I read this correctly, you want a blank row between every user inputted value doing down and a blank column between every user inputted value going right.
On the worksheet code sheet:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
Dim r As Long, c As Long
If Target.Row / 2 <> Int(Target.Row / 2) Then r = 1
If Target.Column / 2 <> Int(Target.Column / 2) Then c = 1
Target.Offset(r, c).Activate
Application.EnableEvents = True
End Sub
This occurs for all navigation. If you only want this to occur on input, modify to suit a Worksheet_Change event macro instead of a Worksheet_SelectionChange event macro.
I've got a list of ships in a spreadsheet, and one of the columns will contain the email address for each ship. However, entering an email address turns it into a hyperlink, while I'd like it all stored as plain text. Is there any way to either prevent that from happening or strip the hyperlink out afterwards?
My current attempt is this little sub:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("VesselEmails")) Is Nothing Then Exit Sub
Application.EnableEvents = False
If Target.Hyperlinks.Count > 0 Then Target.Hyperlinks.Delete
Application.EnableEvents = True
End Sub
It doesn't do the job, unfortunately. Is there any way I can do to make it work, or a format mask I can apply or something?
EDIT: To clarify, I don't want to switch off email address autoformatting altogether, just in that column.
You can remove hyperlinks in a column with Columns(1).Hyperlinks.Delete. Run this line in your on change sub and change the 1 in Columns(1) to the column number that has the email data - you can change it to a column letter as well, for example Columns("E").
Hope that will help.
You can try this as an alternative - it is working for me in Excel 2010:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 5 Then
Application.AutoFormatAsYouTypeReplaceHyperlinks = False
Else
Application.AutoFormatAsYouTypeReplaceHyperlinks = True
End If
End Sub
This makes the behaviour column-specific per your edit to the question. Obviously you can extend the If Target.Column = 5 code to include more columns depending on your form.
I realize you want to apply this to only one column and this answer does not achieve that. But for the record, here is how to prevent typed text turning into links or email addresses in all workbooks you open with Excel:
File > Options > Proofing > AutoCorrect options > Autoformat as you type > untick Internet and network paths with hyperlinks
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.