I have a UserForm with text boxes that are already bound to certain worksheet cells through the ControlSource property. I need to run a calculation between two of these bound values and have the result end up in a third worksheet cell. I know there are numerous ways this can be done, but I'm wondering whether there's some way to do this as a formula in the worksheet cell that references the UserForm control values. For example, I would like to be able to put a formula in cell C3 that goes something like
= UserForm1.TextBox1.Value * UserForm1.TextBox2.Value
but I haven't found any reference that addresses using worksheet cell formulas to fetch values directly from UserForm controls. (And no, in this case I can't just reference the bound cells by plugging something like "= A1 * B2" into cell C3. This question is specifically about whether it's feasible to reference a UserForm control from within a worksheet cell formula.)
Thanks in advance for any helpful suggestions.
The only way to refer to the property of an ActiveX control on a worksheet, is via a user-defined-function, such as:
Public Function GetTextBoxValue(TextBoxName As String) As String
On Error GoTo 0
Dim o As OLEObject
Set o = Sheet1.OLEObjects(TextBoxName)
On Error Resume Next
If Not o Is Nothing Then
GetTextBoxValue = o.Object.Text
End If
End Function
Then call the function from a cell, like: =GetTextBoxValue("TextBox1")
Related
I am trying to code my spreadsheet to react to changes to a specific cell in my spreadsheet. This cell contains a formula so the programing is not recognizing any change to the cell although the number is updating the formula is not. I am looking for a way to return the results of the cell containing the formula into another cell as a value so the change can be recognized by the code.
The change event isn't firing because the contents of the cell aren't changing, just what it displays (the formula result) is. You could use the Worksheet_Calculate event and check the value against another static value. If it's changed, then update it and trigger your other code.
It sounds like there's a better way to design your sheet though.
Private Sub Worksheet_Calculate()
Dim watchCell As Range ' set to something
Dim checkCell As Range ' set to something
If checkCell.Value = watchCell.Value Then Exit Sub
' Value has changed. Update the check and trigger action.
checkCell.Value = watchCell.Value
Call SomeOtherResponse
End Sub
I have a number of cells which have validation lists that are based on the use of the INDIRECT function. In this case there are two variables - one is the currently selected State (as reference through the named range dtState) and another based on a separate selection already made by the user in a different cell. The function in the Validation List for the cell is:
=INDIRECT("dtHdrPlates"&dtSize&dtState)
dtsize : could equal "70" or "90"
dtState : couldequal "VIC" or "QLD"
Naturally there is a named range for all combination of "dtHdrPlates" and the possible options of dtSize and dtState. The INDIRECT function in the Cell Validation list gives me a list that changes based on the selections in other cells.
dtHdrPlates70VIC
dtHdrPlates90VIC
dtHrdPlates70QLD
dthrdPlates90QLD
This works well thanks to advice previously obtained in this forum - thanks!
I am now trying to implement the use of a Combo Box over top of this cell, positioned, populated, made visible, activated and if relevant, dropped down by VBA Code; and removed once the use leaves the control.
Where I'm currently stuck is populating the ListFillRange of the ComboBox in the sheet - based on the INDIRECT function in the Validation.Formula1 of the cell the combo box is intended to supplant.
Sub BuildComboBox(rngCell as Range)
' This procedure checks to see if the Cell concerned is a list, and if so creates a combobox over top of the cell with the appropriate contents.
Dim rngCell as Range ' the cell concerned
Dim ws as Worksheet
Dim Dim cbo As OLEObject
If rngCell.Validation.Type = xlValidateList Then
Set ws = Excel.ActiveSheet
Set cbo = ActiveSheet.OLEObjects("ComboBox")
cbo.Left = rngCell.Left
cbo.Top = rngCell.Top
cbo.Width = rngCell.Width
cbo.Height = rngCell.Height
CBO.LISTFILLRANGE = RNGCELL.VALIDATION.FORMULA1
cbo.LinkedCell = rngCell.Address
If rngCell.Validation.ShowError = True Then
CBO.MATCHREQUIRED = TRUE
Else
CBO.MATCHREQUIRED = FALSE
End If
cbo.Visible = True
cbo.Activate
If rngCell.Value2 = "" Then
CBO.DROPDOWN
End If
End If
End Sub
I am stuck in three places in the above code (where the code is in CAPITALS).
What I would like to solve at the moment is how to get the indirect function taken from the cell validation list (rngCell.Validation.Formula1) and have it converted to the named range acceptable to cbo.ListFillRange - at the moment it comes across as =INDIRECT("dtHdrPlates"&sglLBWWallThickness&dtState) which does not work.
I've been playing with the EVALUATE function but just can't get it to parse the text coming from the Validation.formula1
If while you're looking at this you could also steer me towards how to change the status of an ActiveX ComboBox's MatchRequire property - and how to force it to DropDown, that would be lovely too.
Thanks, Regards, Ken
I am having a list of names in a Range A2:A77, in the worksheet name called Manual. whenever i choose a name, that is when a cell gets selected from the range, that active cell value should get reflected in the cell C1. Also, the macro should not work incase if i selected else where, other than the given worksheet or range.
I have googled alot but nothing seem to be matching my criteria, so i'm here, hoping for a better solution. You may ask me to achieve this by using data validation, but for that i will have to do multiple clicks and scrolling work to be done everytime. so to avoid that i'm looking for vba code to minimize the work and time.
Thank You.
I am only just learning VBA at the moment so this could be some very horible code but here goes.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim cells As Range
Set cells = ActiveSheet.Range("A1:A27")
If Not (Intersect(Target, cells) Is Nothing) Then
ActiveSheet.Range("C1").Value = Target.Value
End If
End Sub
Worksheet_SelectionChange is called if the selected cell in the sheet changes then using the test from InRange that I found here: VBA test if cell is in a range test if the cell is within the defined range then set the values.
Edited as sugested by #Vitaliy Prushak in comments.
How do you force an excel workbook to use itself as a source for worksheet links?
I'm writing a VBA macro to automate the process of adding an excel worksheet into a workbook. The worksheet (sheet1) takes only certain (but very many) responses from within the several sheets (response1, response2, response3) of the questionnaire. As a result of this, sheet1 contains lots of cell references that don't lead anywhere until after the macro is run.
For instance a1 in sheet1 "='response1'!b6". This returns a #REF! error before the macro is run (which is fine).
After the macro is run sheet1 is now inside the correct workbook, and "='response1'!b6" is now a valid cell reference.
Except excel doesn't realise this until after I manually click the cell in Sheet1, press f2, then press enter. When I do this the cell is correctly populated. The trouble is there are large numbers of cells.
Is it possible to construct a VBA macro that will simulate this process of selecting formula boxes and pressing "Enter". Looking up people with similar problems, most have had the problem remedied by some combination of f9, turning automatic calculation back on, or ActiveSheet.Calculate or a variant. None of these have worked, it appears to be an issue with references, even though the references point to valid locations.
Otherwise, is it possible to use VBA to perform the same process as:
Data > Edit Links > Update Values
But in this case we'd need to specify the currently opened workbook as it's own source. Is there any way to do this?
When I manually selected the current workbook as the source under "Edit Links > Update Values" excel strangely repeats the worksheet name in the cell references, like this: "='[response1]response1!B31", which then fails to update when cell b31 changes, so this is not a solution.
Here's the code that runs on button press:
Private Sub CommandButton1_Click()
'copy worksheet into responses
Dim CopyFromWbk As Workbook
Dim CopyToWbk As Workbook
Dim CopyToWbk As Workbook
Set CopyFromWbk = Workbooks("Addition.xlsm")
Set ShToCopy = CopyFromWbk.Worksheets("Sheet1")
Set CopyToWbk = Workbooks("QuestionnaireResponses.xlsm")
ShToCopy.Copy After:=CopyToWbk.Sheets(CopyToWbk.Sheets.Count)
Workbooks("QuestionnaireResponses.xlsm").Activate
'Put code to update links in here
ThisWorkbook.UpdateLink Name:="myfilepathgoeshere.QuestionnaireResponses.xlsm", Type:=xlExcelLinks
'End update links
Thanks for any help, this one's a head scratcher.
Great idea from #Kyle. For those who having trouble forcing cell references to update, TextToColumns works.
However TextToColumns draws an error if the source range is empty, so if there's any chance of that being the case use an if statement with no action attached to skip over those instances.
My successful code looks like this:
Dim i As Integer
For i = 1 To 1004
'Scans through row 2 from col A onwards
'If cell is empty, does nothing.
'If cell is not empty, performs TextToColumns where source range = target range.
If IsEmpty(Workbooks("QuestionnaireResponses.xlsm").Worksheets_
("response1").Cells(2, i)) Then 'Does nothing if the cell is empty.
Else
Workbooks("QuestionnaireResponses.xlsm").Worksheets("response1").Cells(2, i).Select
Selection.TextToColumns Cells(2, i) 'Performs TextToColumns
End If
Next
All of my data is on the same long row. To apply the above to an entire spreadsheet, just nest everything between, and including, For i = 1 and Next within another For loop with different letter replacing i.
I use a vba function to get cell name (taken from Retrieving Cell name in Excel)
Public Function CellName(oCell As Range) As Variant
Dim oName As Name
For Each oName In ThisWorkbook.Names
If oName.RefersToRange.Parent Is oCell.Parent Then
If Not Intersect(oCell, oName.RefersToRange) Is Nothing Then
CellName = oName.Name
Exit Function
End If
End If
Next
CellName = CVErr(xlErrNA)
End Function
When the name of the cell does not exist, it shows error -- and that is of course intended behaviour. However, when I then name the other cell (the one which name I want to get), the error in my cell is still active. Recalculating does not help. I need then to change the value of the other cell (I can change its value or change value of yet another cell that is in its formula), or its formula, so the value in that cell would be recalculated, so my cell with CellName function gets properly refreshed.
I don't see the point why, and what can I do to simple make the cell refresh when I name the cell I point to?
This is Excel 2007, file type xlsm.
I think you need to set the function as Volatile
at the beginning of your UDF, add this code:
application.volatile
see MSDN Library: Volatile Method [Excel 2003 VBA Language Reference]