So, this should be fairly easy to implement, but I am unable to get the message box to display.
Context - this is for an estimation tool - if the user enters a value for a particular cell that is less than a minimum threshold, I want to bring up a message box to let them know that's not a valid entry.
The cell I am referring to is named (let's just say TEST). Its location is on the UI tab (1 of 4 tabs in the workbook) is row 47, column 17.
Here is the code I have tried so far:
Sub UI Alerts()
If Cells(47, 17) < "1000" Then
MsgBox ("Minimum Value is 1000")
Exit Sub
End If
Similarly, with the named cell
Sub UI Alerts()
If ("TEST").value < "1000" Then
MsgBox ("Minimum Value is 1000")
Exit Sub
End If
I have set this up in the VBA module that corresponds to the UI tab, so I shouldn't have to reference the sheet. Any idea why the message box isn't displaying? Is it possible to automatically display a message box based on a cell value?
Thanks.
Unless there is a specific reason we need this to be a macro, it sounds like standard data validation would work for you here. Try this: select the cell you want the rules applied to, then on the ribbon/toolbar find Data > Data Validation. You can require a whole number greater than 1,000 (or a value in another cell), display a comment box with instructions when the user selects the cell, and an error message if an invalid number is entered.
You need to use the Change event within the worksheet. Below is a sample code that should work with your named range. At any rate, it should show you how to do so.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("TEST").Address Then
If Range("TEST").Value < 1000 Then
MsgBox ("Minimum Value is 1000")
End If
End If
End Sub
You need to add your code to the Worksheet "Change" event.
Right now, you have code but it never gets called.
Related
I have a dropdown in i7. In j7 I have a formula, that adjusts the hyperlink -- based on value in i7. HLinks are to different cells in the same worksheet.
Trying to get XL to automatically jump to j7 upon value change in i7, and to follow/execute the corresponding HLink, meaning for the j7 to act as if it was clicked on (but without the use of sendkeys-left mouse click).
So far either line of below code, executed one at a time - on j7, gives "Run-time error '9': Subscript out of range"
Sub HLink_follow()
ActiveCell.Hyperlinks(1).Follow
ActiveWorkbook.FollowHyperlink ActiveCell.Hyperlinks(1).Address
End Sub
Am aware that this all can be done via VBA, without even having j7, but want to keep it the way that it is.
If you are not clear on something, ask a question.
When you use the Hyperlink-function in a formula, it doesn't add an entry to the hyperlink-collection of a cell. With other words, ActiveCell.Hyperlinks.Count is 0 and ActiveCell.Hyperlinks(1) therefore gives an Subscript out of range.
There is a question here on SO about that, have a look to this answer: https://stackoverflow.com/a/40343924/7599798. It suggests to parse the formula (split it by quote character) to get the URL and use FollowHyperlink with the extracted URL.
Now your case is more complicated as your cell doesn't contain only a simple =Hyperlink(..)-formula and therefore parsing is not an option. I see 2 possible solutions:
a) Instead of using a formula, add the Hyperlink via the Link-menu in Excel or the Worksheet.Hyperlink.Add method. Then add the logic to change the address in the Change-Trigger of your worksheet whenever some relevant data is changed.
b) Use a helper cell to calculate the destination of the hyperlink. The helper cell (let's say H7) would get a formula like IF(COUNTIF(I7,"x1"),"#A591",IF(COUNTIF(I7,"x2"),"#A665")). Your HLink_follow-routine would use the calculated address of that helper cell while the formula in J7 would have the simple formula =Hyperlink(H7, "See pic")
P.S. Yes, I am located in Europe - just look at my profile
Private Sub Worksheet_Change(ByVal Target As Range)
'auto selects cell
Dim MyVariable As String
MyVariable = Range("k8").Value
Application.Goto Reference:=Range(MyVariable)
End Sub
K8 contains a substitute formula to strip "#" from K7.
Works as expected.
I have an userform with a few texbox and i want that when you put the value on the first one scan the data sheet and if it found the same value it fill the rest of textboxes, i think i can manage to do it if i do it in two steps. First take the value of textbox1 as variable and with it scan the data an generate the second userform with the data already paste on it. But is there a way to do it live? at the moment i put data in textbox1 shows the data of the rest of the columns on the others textboxes?
Also i was trying to do more or less the same thing in a sheet with an vlookup formula (VLOOKUP(A27,BDD!A:B,2,FALSE)) and it worked but the problem is that i want the formula to change the value of the cells only in case it found a mach in the data and also i don't want the formula in the cells i want to change so i can put new data without problem.
Lets say i have in the sheet "bdd" numbers in the first columns and names in the second. I want in another sheet to put a number and if that number already exist in the bdd i want to have the name near to it but i dont want the formula near to the numbers because i want to be able to put new numbers and names if necessary.
bdd:
101 Antonio
102 Luis
sheet
101 Antonio (At the moment i finish writing 101)
103 Peter (nothing happens because it isn't in the bdd yet and i have to type peter to complete that line or put 103 peter in the bdd)
Sorry if it wasn't clear i tried :P Thanks in advance
If data is in this range
Private Sub TextBox1_Change()
'Skip if value is not there
On Error Resume Next
'take any random cell to store textbox1's value
Range("C4").Value = TextBox1.Text
'Vlookup to get the value
TextBox2.Text = Application.WorksheetFunction.VLookup(Range("C4").Value,Sheet1.Range("A:B"), 2, 0)
End Sub
I have a Data Validation list with dates in it. When you change the date it effects what data is shown in the rest of the worksheet.
I would like to to create 2 command buttons,
"Next" - when clicked will move to the next date in the list, when it reaches the end of the list it goes back to the beginning of the list
"Previous" - when clicked will move to the previous date in the list, when it reaches the beginning of the list it will go to the end of the list
Is this possible?
I did look at List Box and Combo Box but got highly confused with the coding!!!
Any help would be great!
You have to distinguish 3 cases:
data validation with in-line list elements (e.g. Source = "1;2;3;4;5")
data validation with list elements in a range
List/Combo box
Case 1 is maybe the most difficult, because you can access the list elements only in a string and have to split them up into an array, get the index of the current selection and move the index with two buttones in order to get the wanted result
Case 2 is a bit simpler, but again you need to somehow keep track of the current position within the range defining your dates
Case 3 is maybe the most easiest to implement ... but still requires a certain coding effort, like
load list of dates into the list/combo box before first display (OnLoad or OnActivate
create code for the UP and DOWN buttons to increment/decrement the list box index, with automatic wrap-around
I suggest a 4th case to you ... use an ActiveX Spin Button ... this provides up and down functions in one element:
create your list of dates in a vertical named range DateList
reserve one more cell for the index of the Spin Button and name it DateIndex
using Developer ribbon, insert an ActiveX Spin Button (default name is SpinButton1)
set the LinkedCell property in SpinButton1 (be sure to be in Developer / Design mode; right click the Spin button and select "properties") to DateIndex
create the following code (still in design mode, right click the SpinButton and select "view code")
code
Private Sub SpinButton1_SpinDown()
If SpinButton1 = 0 Then
SpinButton1 = Range("DateList").Rows.Count
End If
End Sub
Private Sub SpinButton1_SpinUp()
If SpinButton1 = Range("DateList").Rows.Count + 1 Then
SpinButton1 = 1
End If
End Sub
At the cell where you want to display the selected date, enter formula =INDEX(DateList,DateIndex)
since you are working with named ranges, DateList and DateIndex may be in a different sheet (even a hidden one) than the user sheet.
if you want to create a copy of the currently chosen date at the cell where the user has currently put the cursor, add the following statement to the end of the SpinDown/Up Sub's (after End If: Selection = Range("DateList").Cells(SpinButton1, 1)
i want to do a simple function in a module in excel vba,
so i can use it as a custom function in excel.
(i use excel 2003, or 2007 , it's doesnt matter)
i create a function(!) in a new workbook and it's looks like this:
Function a()
Sheets(1).Range("A1").Value = 4
end function
but when i try to use it on the sheet1 it's wont work!
i tried many things.
how can i make this work (with no workarounds, i want to use it as a custom function) ?
please help.
thanks,
gadym
A function that uses other cells cannot become a formula function (UDF) in Excel, because it breaks Excel's dependency model (all cell dependencies must be explicit in the formula). However a formula can use cell values as inputs.
Here is a simple function added to a module in VBA:
Public Function testFunction(inputValue As Integer) As Integer
testFunction = inputValue * 2
End Function
This can be used in any cell formula. For example, =testFunction(4) or =testFunction(A5).
EDIT
Okay, reviewing the comment you made against guitarthrower's answer. A formula can only send an answer to the cell it is in - it cannot send an answer to a different cell. Therefore, if a formula is your only choice, you must have a formula in cell A1 that reads input from C1.
Formula in A1:
=a(C1)
Function in module:
Public Function a(string col)
a = iif(col = "ok", "1", "2")
End Function
However, if there is a problem putting a formula into A1, you are left with a manually driven process (a sheet button, a toolbar button etc. to push these values) or a worksheet cell change event. The downside of a worksheet event is that it fires off every single cell change, so you need to keep the code light and not do any heavy duty work - or if you do, make it rare.
You would add a new subroutine to the worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
This is fired whenever cells are changed; the changed cells are indicated by the Target range. Your code would update A column cells if the Target contained C column cells. This is more work than the formula approach, but it does render the process entirely automatic. I have no access to Excel right now so the following is just from memory and Googled fragments, untested:
For Each cCell In Application.Intersect(Target, Me.Range("C1:C5"))
cCell.Offset(, -2).Value = iif(cCell.Value = "ok", "1", "2")
I would prefer not to use explicit ranges, but rather a named range as it makes your code less fragile to change. But that would make finding the corresponding A column cell a little more tricky to determine and I'm not going to attempt that code without Excel to hand =)
It looks like you're trying to programatically change the value of an cell within your spreadsheet. This can be done, but as Joel Goodwin pointed out, this can't be done with a "User-Defined Function." However, you can do this with a macro or by adding a button to the sheet and putting code in the button.
For example, add a button to your sheet by going to View > Toolbars > Control Toolbox (this will be different for newer versions of Excel) and selecting the button control and adding it to your sheet. Once the button is added, double click on it. This should bring up the Visual Basic editor. Put your code in the body of the Sub that it provides, like this:
Private Sub CommandButton1_Click()
Sheets(1).Range("A1").Value = 4
End Sub
Go back to your worksheet and disable design mode in the control toolbox (it's the icon with the light blue triangle in it). With design mode disabled, click the button and the value of cell A1 will change to 4.
If cell A1 contains the formula =a(), and you want A1 to show 4 (or any other cell with the formula =a() in it) then you need to change your code to this:
Function a()
a = 4
End Function
I am writing a quick application myself - first project, however I am trying to find the VBA code for writing the result of an input string to a named cell in Excel.
For example, a input box asks the question "Which job number would you like to add to the list?"... the user would then enter a reference number such as "FX1234356". The macro then needs to write that information into a cell, which I can then use to finish the macro (basically a search in some data).
You can use the Range object in VBA to set the value of a named cell, just like any other cell.
Range("C1").Value = Inputbox("Which job number would you like to add to the list?)
Where "C1" is the name of the cell you want to update.
My Excel VBA is a little bit old and crusty, so there may be a better way to do this in newer versions of Excel.
I recommend always using a named range (as you have suggested you are doing) because if any columns or rows are added or deleted, the name reference will update, whereas if you hard code the cell reference (eg "H1" as suggested in one of the responses) in VBA, then it will not update and will point to the wrong cell.
So
Range("RefNo") = InputBox("....")
is safer than
Range("H1") = InputBox("....")
You can set the value of several cells, too.
Range("Results").Resize(10,3) = arrResults()
where arrResults is an array of at least 10 rows & 3 columns (and can be any type). If you use this, put this
Option Base 1
at the top of the VBA module, otherwise VBA will assume the array starts at 0 and put a blank first row and column in the sheet. This line makes all arrays start at 1 as a default (which may be abnormal in most languages but works well with spreadsheets).
When asking a user for a response to put into a cell using the InputBox method, there are usually three things that can happen¹.
The user types something in and clicks OK. This is what you expect to happen and you will receive input back that can be returned directly to a cell or a declared variable.
The user clicks Cancel, presses Esc or clicks × (Close). The return value is a boolean False. This should be accounted for.
The user does not type anything in but clicks OK regardless. The return value is a zero-length string.
If you are putting the return value into a cell, your own logic stream will dictate what you want to do about the latter two scenarios. You may want to clear the cell or you may want to leave the cell contents alone. Here is how to handle the various outcomes with a variant type variable and a Select Case statement.
Dim returnVal As Variant
returnVal = InputBox(Prompt:="Type a value:", Title:="Test Data")
'if the user clicked Cancel, Close or Esc the False
'is translated to the variant as a vbNullString
Select Case True
Case Len(returnVal) = 0
'no value but user clicked OK - clear the target cell
Range("A2").ClearContents
Case Else
'returned a value with OK, save it
Range("A2") = returnVal
End Select
¹ There is a fourth scenario when a specific type of InputBox method is used. An InputBox can return a formula, cell range error or array. Those are special cases and requires using very specific syntax options. See the supplied link for more.
I've done this kind of thing with a form that contains a TextBox.
So if you wanted to put this in say cell H1, then use:
ActiveSheet.Range("H1").Value = txtBoxName.Text