Use formula as a string - vba

I one cell I have to use several different formula depending on certains case.
I another sheet named Static, I wrote a Matrix of formulas in TEXT for all the cases.
My matrix have Criteria1 in rows Criteria2 in columns
So with INDEX/MATCH i will get the text formula for every scenario Criteria1/Criteria2.
Now I want to Evaluate this formula in text.
I did a custom function in VBA
Function Evalue(ByVal str As String)
Application.Volatile
Evalue = Evaluate(str)
End Function
It works when the function is in one block like SUM CONCATENATE etc... but not when there operation of function + -

Your UDF works for me........in A1 enter the text string:
sum(B2:B5)+sum(C4:C9)
in another cell:
=Evalue(A1) displays the correct value.

Related

Populating Excel multiple cells with data from Add-in user defined function (UDF)

I am working on an Add-in for Excel that needs to populate one or more cells in the worksheet with the data from server. I did following:
Created an Add-in (xlam) and created the user defined function:
GetMyData()
I am calling this function from a simple Excel Worksheet. In A1 cell, I entered the formula =GetMyData()
My server returns JSON Array. I am able to parse the JSON and now trying to populate the A1 and the below rows with values I got from the server. (in this case, I have 20 values, so I want to populate A1:A20 cells).
The issue is that according to Microsoft KB, a user defined function is able to change the value of the active cell only.
https://support.microsoft.com/en-us/help/170787/description-of-limitations-of-custom-functions-in-excel
I also tried to run the code below that changes only one cell to a hardcoded value:
ActiveWorkbook.Sheets("DataSheet").Cells(1, 1).Value = '12312'
Still - getting exception.
Could any one assist with this issue?
Have the function return a vertical array.
For Example:
Function GetMyData() As Variant()
Dim test() As Variant
test = Array(1, 2, 3, 4)
GetMyData = Application.Transpose(test)
End Function
Then highlight all the cells you would ever need with the top as the active cell.
Then put this formula in the formula bar:
=GetMyData()
And hit Ctrl-Shift-Enter instead of Enter to array enter the formula.
If you choose more than the array returns you will get errors.
Or you can, using the Array return, use this to deal with error and enter normally, but it runs the function for each time it is put in a cell.
Put this in the first cell:
=IFERROR(INDEX(GetMyData(),ROW(1:1)),"")
Then copy/drag down till you get blanks
Here is a simple example:
Public Function cerial(d As Date)
Dim bry(1 To 20, 1 To 1) As String
For i = 1 To 20
bry(i, 1) = CStr(d) & "_" & i
Next i
cerial = bry
End Function
It creates an array of 20 items.
There is a tiny trick to using it in the worksheet.
Select, say, E1 through E20. Then click in the formula bar and enter the array formula:
=cerial(TODAY())
Array formulas must be entered with Ctrl + Shift + Enter rather than just the Enter key. If this is done properly, the formula will appear enclosed in brackets in the Formula Bar.
NOTE:
In this example, the internal array bry() is two dimensional.

INDEX & MATCH instead VLOOKUP

I have 2 validation lists, both have numbers & texts amongst them (but none of the lists have alpha-numeric symbols). They are on another sheet called "Source".
I'm using the statement of:
=INDEX(Sources!$A$3:$A$32,MATCH(LEFT(Sources!$A$3:$A$32,3)&"*",Sources!$B$3:$B$42,0)).
But I keep getting #N/A. Can anyone help?
You will not be able to lookup a range within another range using MATCH formula. In your formula you are using match to lookup A3:A32 within B3:B42. Ideally the match formula can lookup only 1 value in B3:B42 and not the complete range of values.
Your formula should be,
=INDEX(Sources!$A$3:$A$32,MATCH(LEFT(Sources!$A$3,3)&"*",Sources!$B$3:$B$42,0))
If you want to drag formula varying the A3 to A32 , use the below,
=INDEX(Sources!$A$3:$A$32,MATCH(LEFT(Sources!A3,3)&"*",Sources!$B$3:$B$42,0))
This type of lookup with range within a range works only on array formulas. Your formula seems much of array formula. After pasting the formula in formula bar, press ctrl + shift + enter . This will make your formula as an array formula. If you do not want to use that as an array formula, try my formulas with just enter

UDF to return formatted number

Sometimes I like to display numbers along with text in the same cell. To do this, I custom format the cell to something like 0.00" test", e.g. a cell A1 with formula =PI(), but formatted with custom format 0.00" test" would return a displayed result of 3.14 test.
Crucially, the value of the cell is unchanged by the formatting - you can still do =A1 * 3 in another cell and get the result - since the value of A1 is still Pi, only it's display has changed.
For a UDF that returns a numerical value (in my case, Long, but it could be any number), is there a way of returning a cell such that it is displayed 1 way, but it's actual value (.Value2 in VBA I believe) is a number, not text.
I've tried Format( in VBA, but it returns a text string. I would just format my cell how I want it manually, but as you can see from the below code, the formatting is dependent on intermediate results (I'm trying to return the value formatted with the time the calculation took).
UDF_RESULT = Format(valueResult.Length, IIf(tElapsed < timeout, "0" & " """ & Round(tElapsed, 2) & "s""", "0"))
This would be easy to do with a Macro, but within a UDF it's harder. I could declare all of the intermediate values at a module level, then a Worksheet_Calculate() macro can access those values and apply the custom formatting, but a UDF-wrapped approach would be much better.
No.
You're confusing a cell's value with its number format. A UDF can compute a value, and the cell is free to format that value as needed.
So if a UDF returns a number, the cell's value is the result of that function - a number.
Just format the cell as needed. A function doesn't format anything.

Output of formula as cells for Excel's Indirect()

I'm using the INDIRECT() function to dynamically refer to worksheets. It seems to me that the function requires a known cell address as input of the formula in quotation marks. However, since I don't know the cell address in advance, I would like to input a cell address that is an output of another formula (e.g., VLOOKUP() or INDEX(MATCH()) ). Is there a way to do this?
Yes, you can compose the string required by INDIRECT() by concatenating formulas that return values that look like a cell address or parts of a cell address.
For example, if your Vlookup or your Index/Match formula returns "A1", then you can use that like
=Indirect(Vlookup(this,there,2,false))
Or, if one formula returns "A" and the other formula returns "1", then combine the output of the two formulas with the & sign.
=Indirect(Vlookup(columnLookup,Table,2,false)&Vlookup(RowLookup,Table,2,false))

VBA script in excel to find and highlight text

I am looking for a VBA script that will help me find certain keywords in a cell and if found highlight the entire row. Below are my requirements:
I have a database of words eg hell, get out, shut up, don't you dare etc. I need a macro to search the data in column "E" of excel and in case any of the cell in column "E" contains any word listed in the database (irrespective of the case of the word upper or lower)the entire row is highlighted. The word can be in the beginning, middle or end of the cell and the macro should be able to find that word and highlight the column.
Seeking help from all VBA masters for this.
You can do this with conditional formatting, instead of VBA.
Conditional formatting works by applying a 'second formula' to a given cell. If the 'second formula' results in TRUE, then special formatting conditions can be applied.
EXAMPLE CONDITIONAL FORMATTING
For example, if you have a single column of Data, A:A, and you want to check if that column has the exact string "hello world", you could add a conditional format [Home ribbon, Styles section, Conditional Formatting] that turns a cell yellow with this formula:
=$A1="hello world"
This will only result in TRUE if the cell in column A at that row equals exactly "hello world" [note that Column A has an absolute-reference $, and row 1 does not, so row 1 is relative to the position of the cell in the condiitonal format rule].
To check to see if any row in column A includes hellow world, we need to add a SEARCH function, which checks to see if a small search string is inside of a larger string:
=SEARCH("hello world",$A1)>0
Because SEARCH by default returns the first character in a larger string that matches the search term (and if it finds nothing, it returns #N/A), we check to see if our search for "hello world" in column A returns a number.
SEARCHING MULTIPLE COLUMNS
Now, to see if ANY column, say from A-D, includes "hello world", we concatenate each value of each column so that it gives us a single string, which we can search through for "hello world", like so:
=SEARCH("hello world",$A1&$B1&$C1&$D1)>0
This will first create a single string, equal to A1 & B1 & C1 & D1 all in a row. Then it will search that newly created string to see if "hello world" is inside it, and return a number value if it is.
ARRAY FORMULA BASICS
Finally, we need to do the tricky part - searching for multiple terms instead of just "hello world". This is called an Array Formula. An array formula works by performing a single operation on multiple cells, and then returning multiple results in an Array. In an Excel sheet, an array formula must be confirmed with CTRL + SHIFT + ENTER (instead of just ENTER), but in conditional formatting, you actually don't need to do anything special - it will recognize an array formula without a special command.
As an example of conditional formatting, see this example, which checks whether any value from A1:A5 = 10, and if it does, it gives us the value in B1:B5:
=IF(A1:A5=10,B1:B5,"")
Remember in Excel on a worksheet, this would be confirmed by pressing CTRL + SHIFT + ENTER. If you do test this, it will give you the following result, assuming A2 = 10 and A5 = 10:
={"";B2;"";"";B5}
This result would actually be hidden, because Excel can't "collapse" an array function on its own. So assume column B had values, and we actually want to sum them together. We would then wrap the Array formula in a SUM function:
=SUM(IF(A1:A5=10,B1:B5,""))
As you can see if you test this, we have actually created our own SUMIF function, using Array formulas instead of the built-in SUMIF.
SEARCHING FOR MULTIPLE TERMS WITH ARRAY FORMULAS
So now we apply these principles to the conditional formatting, to create an array formula which will check our concatenated 'NEW STRING' for any number of provided terms, as follow [Assumes the search terms are typed into cells E1:E10]:
=SUM(SEARCH($E$1:$E$10,$A1&$B1&$C1&$D1)>0)
This formula can be placed as a conditional formatting rule which reaches all of A:D. Set the rule to highlight / change format in whatever way you like.