How to ensure correct character length is being input - excel

I need to ensure that the user types in an integer with length (blank) in any cell of a certain column. If the user inputs a number that is not length (blank), the Excel freezes the user at that cell and prompts to re-enter until integer length (blank) has been inputted or cancel is hit.
I currently have most of the things I request working. However, my issue is that Excel doesn't recognize length errors until I move away from the cell and come back to it.
For example (using 3 as desired length):
If i am currently on Cell B12 and type in 15646, which is not length 3, I can still click enter and it will move to Cell B13, which I want to prevent. But if I move up to B12 again from B13, the length error is seen and Excel prompts me to input integer with correct length until its fixed.
For now, the length error is only being recognized when I come back to cell. I need it to recognize as soon as I hit enter and prevent from moving on to next cell.
Sub InputNum()
row = ActiveCell.row
col = ActiveCell.Column
If col = 2 And ActiveCell.Value <> "" Then
Dim lotTextLen As Integer
lotTextLen = Len(ActiveCell.Value)
'checks to ensure the number put in is 3 characters long
'requests an input number to be put in
If lotTextLen <> 3 Then
lotData = InputBox("Invalid Entry Length. Scan in Lot #")
If Len(lotData) <> 3 Then
'error message
Result = MsgBox("Invalid Lot # Inputed. Must be 3 Characters. Try Again?", vbOKCancel)
'if cancel is clicked, input number is made blank and sub is exited
If Result <> vbOK Then
ActiveCell.Value = ""
'if ok is clicked to try again, recurses to beginning of code again
Else
InputNum
End If
Else
ActiveCell.Value = lotData
End If
End If
End If
End Sub
InputNum is being called in the Sheet1
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Application.Intersect(Target, Range("B:C")) Is Nothing Then
InputNum
End If
End Sub

In the sheet object place the following
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Columns(2)) Is Nothing Then
Application.EnableEvents = False
InputNum Target
Application.EnableEvents = True
End If
End Sub
Then use this in a standard module
Public Sub InputNum(Target As Range)
Dim IoTData As String
Dim Result As String
Dim isCancel As Boolean
Do While Len(Target.Value2) <> 3
IoTData = InputBox("Invalid Entry Length. Scan in Lot #")
If Len(IoTData) = 3 Then
Target.Value2 = IoTData
Else
If IoTData <> vbNullString Then
' error message
Result = MsgBox("Invalid Lot # Inputed. Must be 3 Characters. Try Again?", vbOKCancel)
If Result <> vbOK Then isCancel = True
Else
isCancel = True
End If
End If
If isCancel Then
Target.Value2 = vbNullString
Exit Do
End If
Loop
End Sub
By placing your code in a loop it will keep pestering the user for the right length until either they enter the right format or they press cancel in which instance the cell will be cleared of it's input.
You can also add And IsNumeric(IoTData) to your If statement to test that a number has been entered.
Replace
If Len(IoTData) = 3 Then
With
If Len(IoTData) = 3 And IsNumeric(IoTData) Then

Option Explicit
Dim add As String
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B:C")) Is Nothing And Target.Count = 1 Then
If Len(Target.Value) <> 3 Then
MsgBox "Invalid entry in cell with address " & add
Application.EnableEvents = False
Target.Activate
'Enter more code
Application.EnableEvents = True
End If
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("B:C")) Is Nothing And Target.Count = 1 Then
add = Target.Address
End If
End Sub

Related

Excel VBA: multiple Individual Exclusive Checkboxes with data validation (create a Macro with selecting cells to format them) (code is here)

I'm trying to introduce Checkboxes into my personal project Planning, unfortunately normal Checkboxes tend to bug out, so I found this side here and am trying to convert it into a macro to select the rows I want checks at. Specifically the last one that is NOT "Mutually Exclusive" but with data validation.
http://www.vbaexpress.com/kb/getarticle.php?kb_id=879
Unfortunately it does not let me make it into a macro like I wanted to and I spent a lot of time trying already. :(
Please Help
I tried to write a SelectionRng. Or searched for a way to write it into a Macro to select it in the Worksheet.
Option Explicit
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'Limit Target count to 1
If Target.Count > 1 Then Exit Sub
'Isolate Target to a specific range
If Intersect(Target, Range("Ckboxes")) Is Nothing Then Exit Sub
'Set Target font to "marlett"
Target.Font.Name = "marlett"
'Check value of target
If Target.Value <> "a" Then
Target.Value = "a" 'Sets target Value = "a"
Target.Interior.ColorIndex = 44
Cancel = True
Exit Sub
End If
If Target.Value = "a" Then
Target.ClearContents 'Sets target Value = ""
Target.Interior.ColorIndex = 0
Cancel = True
Exit Sub
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
'Limit Target count to 1
If Target.Count > 1 Then Exit Sub
'Isolate Target to a specific range
If Intersect(Target, Range("Ckboxes")) Is Nothing Then Exit Sub
'Select a specific subset of the range "Ckboxes"
Select Case Target.Address
Case Else
'Populate the cell to the right of Target with its status
If Target.Value = "a" Then
Target.Offset(0, 6) = "Checked"
Else:
Target.Offset(0, 6).Value = "Not Checked"
End If
End Select
End Sub

Insert other values from drop-down list with macro, but several times

I make an Excel file that I use to import on a website. However, the values displayed mean nothing to the website, it needs IDs, but it's just not user-friendly. To help my users I said to myself I'll make a drop-down list that will change the value. For example, if you click on Switzerland, it will show 1 in the cell.
I have created one Macro based on the instruction on https://www.extendoffice.com/documents/excel/4130-excel-drop-down-list-show-different-value.html
'Updateby Extendoffice
Dim xRg As Range
selectedNa = Target.Value
If Target.Column = 3 Then
Set xRg = ActiveWorkbook.Names("Dropdown_cantons").RefersToRange
selectedNum = Application.VLookup(selectedNa, xRg, 2, False)
If Not IsError(selectedNum) Then
Target.Value = selectedNum
End If
End If
End Sub
For the first column it's ok
For my second collone with the cities this time, I thought I would change the collone numbers and follow the instructions in the link above. Maybe I can't put two macros in one Excel?
I tried to do it as a module, but it doesn't work for the second collone either. Do you have an idea?
Could look something like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub 'only handle single-cell changes
Select Case Target.Column
'depending on the column number, call `SetId` with specific arguments
Case 3: SetId Target, ActiveWorkbook.Names("Dropdown_cantons").RefersToRange, 2
Case 4: SetId Target, ActiveWorkbook.Names("Dropdown_countries").RefersToRange, 2
End Select
End Sub
'translate a data validation drop-down "text" selection into a matching "id" value
Sub SetId(c As Range, rngTable As Range, returnCol As Long)
Dim v, res
v = c.Value
If Len(v) > 0 Then
res = Application.VLookup(v, rngTable, returnCol, False) 'find the id
If Not IsError(res) Then 'got a match
On Error GoTo haveError 'ensure we exit with events back on
Application.EnableEvents = False 'disable events
c.Value = res 'switch the value
Application.EnableEvents = True 're-enable events
End If
End If
Exit Sub 'normal exit
haveError:
Application.EnableEvents = True 'just in case....
End Sub

Updating value of a non-Target cell in Excel VBA

I found the attached when looking for how to due an event change to correct user data based on the values in two columns. I'm not a programmer, so I may have butchered the code as I combined two different solutions together.
Right now, it's working exactly as I want it to. Changing the offset cell value forces Excel to replace the target value with what I've specified. What I'm looking to achieve (and am not sure is possible), is to reverse the code. Basically, I want to change the offset cell, if the values are entered in the opposite order. The code will change the cell value to "Beta" if a user enters "Bravo" in column A, and then "Gamma" in column C.
What I'm trying to achieve is that if the user enters "Bravo" in column A second, that Excel still sees the combination of these cells and still replaces the value with "Beta". I know this is additional code, but I couldn't find anything to support replacing cell when the target cell isn't the value being updated.
Thanks in advance!
Dim oldCellAddress As String
Dim oldCellValue As String
Private Sub Worksheet_Change(ByVal Target As Range)
oldCellValue = "Bravo"
If Target = "Bravo" And Target.Offset(0, -2) = "Gamma" Then
Target.Value = "Beta"
Application.EnableEvents = True
End If
End Sub
This may meet your needs:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim colnum As Long, v As Variant
colnum = Target.Column
v = Target.Value
If colnum = 1 Then
If v = "Bravo" And Target.Offset(0, 2) = "Gamma" Then
Application.EnableEvents = False
Target.Value = "Beta"
Application.EnableEvents = True
End If
Exit Sub
End If
If colnum = 3 And v = "Gamma" And Target.Offset(0, -2) = "Bravo" Then
Application.EnableEvents = False
Target.Offset(0, -2).Value = "Beta"
Application.EnableEvents = True
End If
End Sub
For example if the user puts Bravo in cell A1 and C1 already contained Gamma, the code puts Beta in A1 (the code corrects the A1 entry).If the user puts Gamma in cell C1 and cell A1 already contained Bravo, the code corrects A1.
There are two possible scenarios like below...
Scenario 1:
If ANY CELL on the sheet is changed, the following code will check the content of column A and C in the corresponding row and change the content of the Target Cell.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
Dim r As Long
r = Target.Row
On Error GoTo Skip:
Application.EnableEvents = False
If Cells(r, "A") = "Bravo" And Cells(r, "C") = "Gamma" Then
Target.Value = "Beta"
End If
Skip:
Application.EnableEvents = True
End Sub
Scenario 1:
If a cell in column D is changed, the change event will be triggered and check the content in column A and C in the corresponding row and change the Target Cell in Column D.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
Dim r As Long
On Error GoTo Skip:
'The below line ensures that the sheet change event will be triggered when a cell in colunm D is changed
'Change it as per your requirement.
If Not Intersect(Target, Range("D:D")) Is Nothing Then
Application.EnableEvents = False
r = Target.Row
If Cells(r, "A") = "Bravo" And Cells(r, "C") = "Gamma" Then
Target.Value = "Beta"
End If
End If
Skip:
Application.EnableEvents = True
End Sub

prevent entering characters more than given number of times in a column range-excel VBA

here is my excel sheet example:
Private Sub test2()
Dim count As Long
Dim a As String
Dim Act As Integer
Worksheets("test").Activate
a = ActiveCell.Offset(0, -1).Value
' "count" counts the occorance of "b"
count = Application.WorksheetFunction.CountIf(Range("A2:A16"), a)
Act = ActiveCell
If count > Act Then
MsgBox "exceeded"
Else
MsgBox count
End If
End Sub
`
Steps Required
1. You need the Worksheet_Change Event
2. Once you have understood that you need to do something like the following
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ItemMultipleData As Range
For Each ItemMultipleData In Target 'handles multiple cells, paste, del, etc
If Not Intersect(ItemMultipleData, Columns(1)) Is Nothing Then
If Application.WorksheetFunction.CountIf(Columns(1), ItemMultipleData.Value) > 3 Then MsgBox ("Not allowed"): ItemMultipleData.Value = ""
End If
Next ItemMultipleData
End sub

Trouble getting user form button code working

Got a workbook with two sheets in it. The first is where the data is, and the second has been set up as a "corrections" page. This workbook is sent out to users who are to review it and note inconsistencies/discrepencies. Right now it's set up to highlight the cell via double-click then forward the active cell to a cell at the end of the same row. As it turns out people want more room for comments so I've decided to go with a second sheet that works as a comments sheet. I've got the userform and everything with it done except the "submit" button. When the user double-clicks now the cell is still highlighted, but instead of forwarding to the end of row it opens the user form for comments. I'm trying to get the submit button to do two things:
First, I want it to place the row# of the cell that was highlighted into the first column; and second, I want what the user puts in the textbook to be placed into the second column.
I can get it to enter a value in the first row for the textbox, but I don't know where to start for the row#'s (maybe ActiveCell.Row ?); also, I don't know how to go about getting it set to move down to the next row if the first row already has comments in it (need something with a Row +1 I guess? It's just this one last button that's slowing me up; got the rest done, but I could use some advice on this part of the userform coding. Thanks!
Here's how I'd do it (rough draft):
Private Sub Worksheet_Beforedoubleclick(ByVal Target As Range, Cancel As Boolean)
Const CLR_INDX As Integer = 6
If Target.Interior.ColorIndex = xlNone Then 'If cell is clear
With frmCorrections
Set .CellRange = Target
.HiliteColorIndex = CLR_INDX
.Show
End With
'Or Else if cell is already yellow
ElseIf Target.Interior.ColorIndex = CLR_INDX Then
Target.Interior.ColorIndex = xlNone 'Then clear the background
End If
Cancel = True
End Sub
and the user form code:
Dim m_rng As Range
Dim m_index As Integer
Public Property Set CellRange(rng As Range)
Set m_rng = rng
End Property
Public Property Let HiliteColorIndex(indx As Integer)
m_index = indx
End Property
Private Sub cmdCancel_Click()
Me.Hide
End Sub
Private Sub cmdOK_Click()
Dim cmt As String, NextCell As Range
cmt = Me.txtComment.Text
If Len(cmt) > 0 Then
Set NextCell = ThisWorkbook.Sheets("Corrections").Cells( _
Rows.Count, 1).End(xlUp).Offset(1, 0)
With NextCell
.Parent.Hyperlinks.Add Anchor:=NextCell, Address:="", _
SubAddress:=m_rng.Address(False, False, , True), _
TextToDisplay:=m_rng.Address(False, False)
.Offset(0, 1).Value = cmt
End With
m_rng.Interior.ColorIndex = m_index
End If
Me.Hide
End Sub
Private Sub UserForm_Activate()
Me.txtComment.Text = ""
Me.lblHeader.Caption = "Enter comment for cell: " & _
m_rng.Address(False, False)
End Sub
EDIT:
This is what I finally came up with to get it working the way I wanted. On the first worksheet the user can double click on the cell, which then highlights the cell and prompts with the user form. If the user cancels then the highlight is removed and the user can keep working; if they enter anything in the box and submit it then the cell addressis placed in one row on the "Comments" page and the text is enteredone column over in the row corresponding to the original cell's address so I can see where the correction is and what their justification was. Anyways the codes are below.
I use the following for highlighting and calling the form:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Application.EnableEvents = False
Dim TargRow As Variant
Dim TargCol As Variant
TargRow = Target.Row
TargCol = Target.Column
Header = 8
FirstCol = 0
LastCol = 13
CommentCol = 13
If TargRow > Header And TargCol > FirstCol And TargCol < LastCol Then
'If the cell is clear
If Target.Interior.ColorIndex = xlNone Then
Cancel = True
'Then change the background to yellow
Target.Interior.ColorIndex = 6
Corrections.Show
'Else if the cell background color is already yellow
ElseIf Target.Interior.ColorIndex = 6 Then
'Then clear the background
Target.Interior.ColorIndex = xlNone
End If
End If
'This is to prevent the cell from being edited when double-clicked
Cancel = True
Application.EnableEvents = True
End Sub
And I use this for the user form itself:
Private Sub UserForm_Initialize()
TextBox.Value = ""
End Sub
Private Sub CommandButton2_Click()
Unload Corrections
ActiveCell.Interior.ColorIndex = xlNone
End Sub
Private Sub CommandButton1_Click()
Dim PrevCell As Range
Set PrevCell = ActiveCell
ActiveWorkbook.Sheets("Comments").Activate
Range("A6").Select
Do
If IsEmpty(ActiveCell) = False Then
ActiveCell.Offset(1, 0).Select
End If
Loop Until IsEmpty(ActiveCell) = True
ActiveCell.Value = PrevCell.Address
ActiveCell.Offset(0, 1) = TextBox.Value
Unload Corrections
ActiveWorkbook.Sheets("DataPage").Activate
End Sub

Resources