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
Related
Currently I am working on a data set that has multiple filter bars that can be selected and help search the data and provide how many meet its requirements among other things. E.g. by choosing a manager and partner name it looks through those lines in the data table.
I have made it so it posts out a string of the text formula into boxes which are then concatenated and using a UDF Eval, enforced (it's needed to be broken down a lot due to lots of If and Else statements.
The thing is, as jobs are completed they are not deleted instead they are hidden.
How do I allow this data table to do a Count Ifs search with only looking at visible? Presumably its a UDF?
The ranges are from 6:1000
Below is the breakdown of the code I have. I need find a function to make this code work only on visible.
I have made it so it posts out a string of the text formula into boxes which are then concatenated and using a UDF Eval, enforced (it's needed to be broken down a lot due to lots of If and Else statements.
The thing is, as jobs are completed they are not deleted instead they are hidden.
How do I allow this data table to do a Count Ifs search with only looking at visible? Presumably its a UDF?
The ranges are from 6:1000
Below is the breakdown of the code I have. I need find a function to make this code work only on visible.
Sub SetCriteria()
If Sheet8.Range("E6").Value = 1 Then
'The 1 is displayed if there is a value placed in the filter part of the dashboard. If not this value remains 0.
Sheet8.Range("F6") = "Tank!G6:G1000,Dashboard!C6,"
'If there is a value in the filter, then the writing for the CountIf formaul is displayed, linking to the criteria.
Else: Sheet8.Range("F6") = "Tank!G6:G1000,""*"","
'If there isn't anything placed in the critieria then a wild card is selected to ensure all option for that catergory are chosen.
End If
If Sheet8.Range("E7").Value = 1 Then
'Same as above, though this time for Task Manager.
Sheet8.Range("F7") = "Tank!I6:I1000,Dashboard!C7,"
Else: Sheet8.Range("F7") = "Tank!I6:I1000,""*"","
'The two different printed formulas, depending on criteria inclusion
End If
If Sheet8.Range("E8").Value = 1 Then
'Procedure for TAS Consultant
Sheet8.Range("F8") = "Tank!J6:J1000,Dashboard!C8,"
Else: Sheet8.Range("F8") = "Tank!J6:J1000,""*"","
End If
If Sheet8.Range("E9").Value = 1 Then
'Procedure for Pillar
Sheet8.Range("F9") = "Tank!H6:H1000,Dashboard!C9)"
Else: Sheet8.Range("F9") = "Tank!H6:H1000,""*"")"
End If
End Sub
EDIT: Here is my Evaluate Function
Function Eval(Ref As String)
Application.Volatile
Eval = Evaluate(Ref)
End Function
Below array-formula to put in a cell, (Codename Sheet8 is Sheetname Sheet8 I assume)
close it with Ctrl+Shift+Enter
=SUM(SUBTOTAL(3,OFFSET(Tank!G6:G1000,ROW(Tank!G6:G1000)-MIN(ROW(Tank!G6:G1000)),,1))*(IF(Sheet8!E6=1,Tank!G6:G1000=Dashboard!C6,1))*(IF(Sheet8!E9=1,Tank!H6:H1000=Dashboard!C9,1))*(IF(Sheet8!E7=1,Tank!I6:I1000=Dashboard!C7,1))*(IF(Sheet8!E8=1,Tank!J6:J1000=Dashboard!C8)))
This formula is instead of your Sub setcriteria and your Eval function,
You could also break it down as you did before and put it in your eval function.
(Not visible rows must be filtered)
But when you go the VBA-route, have a look at looping your range, only visible rows, check for the criteria and count if met.
I want to select a value from one sheet and put it in a cell on a different sheet.
My script determines the proper value but I cannot get the value into the sheet.
This function returns the !Value error on the 6th line of the following excerpt:
Function PrintTest(Cell)
Dim iRow As Integer
Dim bs As Worksheet
Set bs = ThisWorkbook.Sheets("By System")
iRow = Cell.Row
bs.Cells(iRow, 6).Value = "Hello World"
End Function
I also tried using .Text.
Note: In the actual Script the text will be seeded from the other sheet and I have it stored in a variable. I am not looking for a way to get the same text into many different cells.
Update: Cell is passed from an Excel spreadsheet as an empty cell G4. Row is defined as 4. To call the functions I have been typing "=PrintTest(G4)" in my Excel worksheet named "By System" .
Update 2: Scott Holtzman answered the question in a comment. You cannot write to cells from a UDF called from within a cell. The fix was to call it from a button.
Set a cell value with Cells(Row, Col).Value="Some text"
If your sheet is active you do not need to fully qualify the address. If you activate the sheet you can just use Cells all of the time. If you have to retrieve data from a different sheet then you will have to qualify the address with the sheet name, i.e. Sheets("My Sheet").Cells(Row, Col).Value.
Also your code has Row=Cell.Row, but you are not saying what cell is active. In that case you are getting some arbitrary value. So that is where your error is, probably. Cell.Row=????? Also Row is an excel word. Use something like intRow for your variable. For example intRow=25. Cells(intRow, 6).Value="My Cell". If the cursor is on a cell you can say intRow=ActiveCell.Row.
When you have a problem such as this set a break point in your code (in your example, the Set statement). Thenm run your code. When it stops at the set statement you can hit F8 to step through one line at a time and examine your variables. Then you will see if Row is really a number or just garbage.
Hope that helps
I have a sheet with a lots of columns ordered in a hierarchical way with the cells merged:
I'd like to name those columns (in example: row 5) like this:MainGroupA-SubGroupA-SubSubGroupA.
Simply referencing the columns above in the classic way won't work as the field above isn't available anymore. (In the example: the fields B1 to F1) (i.e. I can't enter A1&A2&A3 / R[-4]C&R[-3]C&R[-2]C as this formula tries to read from the "hidden" cells).
Is there a way to do this without manual work or the need to un-merge the parent-cells? I might be able to do this with some external text editor or even VBA but would prefer an "Excel formula solution" as it would stay updated for new groups and columns.
To Clarify: I'd like all columns in Line 5 to have the text like in A5
If you want:
MainGroupA-SubGroupA-SubSubGroupA
in A5 then this should work:
=A1&"-"&A2&"-"&A3
Edit Then try:
=OFFSET(A1,0,1-MOD(COLUMN(),6))&"-"&OFFSET(A2,0,MOD(COLUMN(),2)-1)&"-"&A3
though this won't give the same text as in A5 across the complete row.
The answer from pnuts is great and helped me solve some test cases. It was however a little difficult to adapt and produced empty strings for the last column, so I also wrote a VBA-Function to do exactly what I need.
Open the VBA Editor (ALT + F11) and enter the following code in a new module:
Public Function checkLeftIfEmpty(start As range) As String
If start.Cells.Count > 1 Then
checkLeftIfEmpty = "Only a single cell allowed as parameter"
Exit Function
End If
Dim currentRange As range
Set currentRange = start
Do While currentRange.Column >= 1
If currentRange.Value <> "" Then
checkLeftIfEmpty = currentRange.Value
Exit Function
Else
Set currentRange = currentRange.Offset(0, -1)
End If
Loop
End Function
You can now use the function checkLeftIfEmpty to find the first cell left-side from your parameter which contains text: (This will be the text of the merged cell itself, if applied to a "hidden by merge" cell)
And also in combination to concatenate a string:
I'm working on an excel spreadsheet and want an if statement in a cell that allows user input if a certain condition is met, and calculates a value otherwise. Something like
=if(condition true, whatever user wants, 5*$A$1,)
Is there a way to do this?
You won't be able to have the user-input in the same cell as your formula. (without using VBA)
To do it without VBA you will need to use at least 2 cells, one with your formula, and one for the user value
There are a couple of ways you can do it with VBA
Heres a simple one, but would not really recomment it, if lots of cells use this it you'll get lots of inputboxes!
usage: =IF(condition, UserInput(), false result)
Public Function UserInput() As Integer ' used integer as an example
Dim Result As Variant
Result = Application.InputBox("Enter an Integer", "Input Required", , , , , , 1) ' inputbox, the final 1 makes it only accept numbers
If VarType(Result) = vbBoolean Then
UserInput = 0 ' the default value
Else
UserInput = CInt(Result) ' make sure its an integer
End If
End Function
Another one, would involve using the selection change and cell change events to read the initial value of the cell being changed, and allow the change (adding the value into the initial formula's "true" block or deny the changes by reverting the cells formula to the initial one.
You either need to use a Macro to update only null columns or you need to allow user to enter values in another column and then merge the values in this column, third option is to fill it with formulas and allow people to edit it to any value if they want only values
=IF(C11="Economic",120,IF(C11="DBServer",480,IF(C11="Gamer",120,IF(C11="Custom",M15,"null"))))
My example was to build an optimal computer given certain constraints. There was a drop down with Economic, DBServer, Gamer, and Custom as options. If you chose economic, then 120 would show up in the cell, DbServer meant 480, etc. If you selected custom, then it would refer to cell M15 which was a user input that didn't affect the code of the cell you wanted the final number in.
I'm writing a tool that syncs a simple database with Excel sheets. Each item in a table in the database corresponds to one row in the worksheet. I read the Excel sheet into the tool using C# and the Excel interop com interface, then compared the items' values (i.e. one of the columns in the excel sheet) after the sync just to make sure that they are equal.
Yesterday I found a case where the comparison wasn't true:
"'<MedalTitle>' Medal - <MedalDescription>"
"<MedalTitle>' Medal - <MedalDescription>"
The second is the one I've read in from Excel, and as you can see it's skipped the first apostrophe. Is there a way to tell Excel to treat the cell as just text (no, just setting the cell's formatting doesn't help)?
I even tried to copy the value ( 'hello' ) of a cell in VBA like this:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Target.Offset(1, 0).Value = Target.Worksheet.Range("b2").Value
Target.Offset(2, 0).Value = Target.Worksheet.Range("b2").Formula
Target.Offset(3, 0).Formula = Target.Worksheet.Range("b2").Formula
Target.Offset(4, 0).Formula = Target.Worksheet.Range("b2").Value
End Sub
The result was that the value of target cell is always hello'
If there is no way, I'll have to do something ugly like
if (dbitem.value[0] == ''' )
{
// stuff
}
else
{
// regular comparison
}
I'm afraid the apostrophe ' is a special character for Excel when it appears as the first character in a cell as you've found. It tells Excel to treat the rest of the string as text, so that you can enter something like '34.2 in the cell, and it'll treat it as the string instead of the number (for formatting and so on).
I suggest doing something similar to what you've suggested, except that where you're putting it into Excel, check the first character, and add an extra ' if there's one there already.
Alternatively, you could prepend an apostrophe to all values - if you want them all as text that is. That way you don't need the extra first character check.
Look at the PrefixCharacter property of the Range object which corresponds to that cell
From the help:
If the TransitionNavigKeys property is
False, this prefix character will be '
for a text label, or blank. If the
TransitionNavigKeys property is True,
this character will be ' for a
left-justified label, " for a
right-justified label, ^ for a
centered label, \ for a repeated
label, or blank.
The TransitionNavigKeys part relates to Lotus 1-2-3 compatibility so it's more than likely going to be False
Answer based on article at:
http://excel.tips.net/Pages/T003332_Searching_for_Leading_Apostrophes.html
(warning: slightly annoying pop-up may appear)
edit: actually this probably isn't going to be any use because PrefixCharacter is read-only :(
edit2: I was right the first time. PrefixCharacter only gets populated if the value added to the cell started with ' so just read back PrefixCharacter plus Value and concatenate. As long as TransitionNavigKeys is False, that is
try targetcell.Value instead. .Formula is the formula seen in the formula bar while .Value is the evaluated value of the cell.
So, I am guessing that you would have used .Formula in your original code as well. Changing that should work.
EDIT: Ok, it did not work (embarrassed).
Excel treats the starting single quote specially.. so specially that even obscure cell / range properties do not have access. The only workaround I could find is essentially the same as what you thought initially. Here goes:
If VarType(cell) = 8 And Not cell.HasFormula Then
GetFormulaI = "'" & cell.Formula
Else
GetFormulaI = cell.Formula
End If
You might try pre-pending a single quote to your text fields ( '''' + dbField ) in your query so that for fields with embedded single quotes your query would return:
"''stuff in single quotes'"
which when placed in an Excel cell would convert to:
"'stuff in single quotes'"
for characters that weren't in quotes you would get:
"'stuff that wasn't in quotes"
which when placed in an Excel cell would convert to:
"stuff that wasn't in quotes"
Worth a shot. :-)