Reference combined cell above - excel

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:

Related

combine all cells, numbers and symbols to a sum

Good day,
I'm at a loss on this problem.
I have a group of cells that contain words, like apple, this word would be the value. It is separated by a symbol for completing the math. They can be changed by the user to make custom calculations.
Cell A1 is "apple", B1 is "+", cell C1 is "apple", cell D1 is "*", cell E1 is "apple", call F1 is "=" and cell G1 is the suggested total, in this case would be "6".
It would be posted as | apple | + | apple | * | apple | = | 6 |
The legend holds the value for the word, so if you enter 2 in the legend, apple would be 2.
The logic would determine that the formula would be 2+2*2= if written in excel, I would like to combine all the cells and calculate this.
I tried using =sum, sumproduct, concate and the like to no avail.
Any head way I did make, I ended up getting BEDMAS wrong as it calculated it as 2+2=4*2=8, instead of the correct 2*2=4+2=6.
Anyone know of a way to combine these cells and properly sum the values to the correct total?
Thank you for your time!
Go to the Name manager and create named range Eval, into Refers to field add formula:
=EVALUATE(CONCATENATE(VLOOKUP(Sheet1!A1,Sheet1!$A$3:$B$5,2,0),Sheet1!B1,VLOOKUP(Sheet1!C1,Sheet1!$A$3:$B$5,2,0),Sheet1!D1,VLOOKUP(Sheet1!E1,Sheet1!$A$3:$B$5,2,0)))
In range A3:B5 I have legend.
Change references as you need. Then in cell G1 write formula =Eval.
Sample:
This is a UDF based solution. Its advantage is that it's more versatile and by far easier to maintain if you learn its elements of code. The disadvantage is in that you do have to learn the elements of code and you have an xlsm macro-enabled workbook which isn't welcome everywhere.
The setup is simple. I created a table with columns Item and Value. I placed it on another sheet than the task. In fact, you could make the sheet with the table VeryHidden so that the user can't look at it without access to the VBA project, which you can password protect. I called the table Legend. The item columns has names like apple, pear, orange. The Value column has the numeric values associated with each name.
Note that, since this is a VBA project, the entire list can be transferred to VBA leaving no trace on the sheet. You could have a function to display the value of each item as the user clicks on it and have it disappear as he clicks elsewhere.
Next I created a data validation drop-down in A1 with the List defined as =INDIRECT("Legend[Item]"). Copy this cell to C1 and E1.
Then I created another Data Validation drop-down in B1 with the list as +,-,*,/. This drop-down must be copied to D1.
Now the code below goes into a standard code module. Find the way to create it because it isn't any of those Excel sets up automatically. It's default name would be Module1. Paste the code there.
Function Evalue(Definition As Range) As Double
Dim Task As String
Dim Fact(2) As Double
Dim C As Long
Dim i As Long
With Definition
For C = 1 To 5 Step 2
On Error Resume Next
Fact(i) = Application.VLookup(.Cells(C).Value, Range("Legend"), 2, False)
i = i + 1
Next C
Task = "(" & Fact(0) & .Cells(2).Value _
& Fact(1) & ")" & .Cells(4).Value _
& Fact(2)
End With
Evalue = Evaluate(Task)
End Function
Now you are ready for testing. Call the function from the worksheet with a call like
=Evalue(A1:E1). You can use it in comparisons like =IF(G6 = Evalue(A1:E1), "Baravo!", "Try again"). As you change any of the components the cell with the function will change.
Remember to use absolute addressing if you copy formulas containing the range. If you need to get a result in VBA while testing, use this sub to call the function.
Private Sub TestEvalue()
Debug.Print Evalue(Range("A1:E1"))
End Sub
My Sheet
Here is what I have.
In cells M - U, i count all the instances of the word from cells E, G and I from the legend.
=SUMPRODUCT((LEN(E3)-LEN(SUBSTITUTE(E3,$B$3,"")))/LEN($B$3))
In cells W - AE, I multiply the instances with the value to give me a total each time the word appears.
=SUM(M3*$C$3)
In cell E8 - I8, i add the three possible values together.
=SUM(W3:Y3) so each worded cell is now a number.
I'd like to take the cells E8 - I8 to make a calculation in k8 and so on.
So, each cell is put together to make an
=SUM(E8:I8)
statement, which all works except E11 - I11 which equates to 26 instead of 43.

Excel Formula - Check if cell has formula

What formula do you use to check if another cell has formula? For example, I have 2 columns, A has cells which contains either a formula or a value.
(Column A usually contains Formulas but other users try to change their values by directly typing and replacing the formula that was previously there)
In Column B I want to add a formula that will say "HasFormula" if the cell on Column A has formula and say "PlainValue" if it contains a value.
I'm thinking maybe using =ISNUMBER() but that may not be accurate.
I am using Excel 2010.
Excel actually has a builtin ISFORMULA() function.
Say A1 has a formula and you want to check that. In say B1, you can use:
=If(ISFORMULA(A1),"HasFormula","PlainValue")
Edit: Per your comment, you don't have ISFORMULA(). An alternative is to create a quick UDF, and use the custom function in the worksheet.
In a workbook module, put this code:
Function isFormula(ByVal target As Range) As Boolean
isFormula = target.hasFormula
End Function
Then you can call it like this: =isFormula(A1) and it will return TRUE if A1 has a formula.
If you can't use VBA, then you can use this formula:
=IF(ISERROR(FORMULATEXT(A1)),"PlainText","HasFormula")
The MrExcel website (link below) has this method which uses old code from Excel 4 (which is still present for backward compatibility)...
Define a NAME such as "CellToLeftHasFormula" and in the "refers to" box put
=GET.CELL(48,OFFSET(INDIRECT("RC",FALSE),0,-1))
Then in column B use the formula =CellToLeftHasFormula which will return TRUE if it has.
Be aware that this will mean your Excel will now contain a macro and so will need to be saved as such (xlsm). I use this in Excel 2010.
For full explanation (and other .CELL options, besides 48) see MrExcel link: https://www.mrexcel.com/forum/excel-questions/20611-info-only-get-cell-arguments.html
You can use the Range.HasFormula property.
https://learn.microsoft.com/en-us/office/vba/api/excel.range.hasformula
EDIT:
Text and code from the above link:
"True if all cells in the range contain formulas; False if none of the cells in the range contains a formula; null otherwise. Read-only Variant. ..."
Worksheets("Sheet1").Activate
Set rr = Application.InputBox( _
prompt:="Select a range on this worksheet", _
Type:=8)
If rr.HasFormula = True Then
MsgBox "Every cell in the selection contains a formula"
End If
You can restrict the user by protecting the column A.
You can directly check if a cell contains a formula by using a shortcut Ctrl + `.
You can use vba and write a user defined function :
1. Press alt + F11
2. Insert module in workbook
3. Paste this code
Function IsFormula(cell_ref As Range)
IsFormula = cell_ref.HasFormula
End Function
4. Now, use Isformula in the cell wherever you want.

Excel 2013, searching for partial text in one cell and overwriting adjacent cell if condition is met

I need to write a macro.
I've got a workbook with ~ 30000 rows (changes daily).
I need to search for expression "TRADE" within the strings in cells from column (A)
If string inside the cell contain expression TRADE I need to change string in relevant cell in column (B) (the same row) to expression "TRADEIN"
If condition is not met relevant cells from column (B) need to stay unchanged
What have I learned so far:
Formula =IF(ISNUMBER(FIND("TRADE", A1 )), 1, 2) changes adjacent cell value accordingly ONLY if placed directly inside cell and copied down in Excel.
Problems starts when I try to have string as an outcome
Formula: =IF(ISNUMBER(FIND("TRADE", A1 )), "TRADEIN", "") won't work ->error
Formula: =IF(ISNUMBER(FIND("TRADE", A1 )), ""TRADEIN"", "") won't work ->error
Then any attempts to make my macro insert more complex formulas into cells from VBA failed i.e.:
Below works fine:
For i=1 to i=NumberOfRows
ActiveSheet.Cells(i, 2).Formula = "= 2+2"
next i
Below won't work (again, formula works if placed in the cell directly):
For i=1 to i=NumberOfRows
ActiveSheet.Cells(i, 2).Formula = "=IF(ISNUMBER(FIND("TRADE", (i, 1)), 1, 2)"
next i
I think there's no point in listing all my failed attempts to make it work so far (loads of useless lines to read I presume) but by all means - correct me if I'm wrong.
I can't find solution as specific as my task and have got problems altering some found online whilst other won't work for me at all. Perhaps don't exactly know how to ask for what I need in the most effective way. Be very basic and try not to miss out any declarations from proposed modules/subs if you can - I'm not yet confident when it comes to using and creating objects and methods outside of a few examples I followed, or choosing/using the right type of variables with compatible methods/functions etc.
Using VBA this is how would accomplish the goal. This will find the last row used in column A to set the range to work through.
Sub test()
Dim w As Range
lrow = Range("A1", Range("A" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible).Count
For Each w In Range("A1:A" & lrow).Cells
If w.Value = "trade" Then
w.Offset(0, 1).Value = "tradein"
End If
Next w
End Sub
Practice using the auto filter, once you have that worked out use the macro recorder to get a code to work on.
Select column A and the goto Data=>Filter=>text Filter=>Contains....type the word in the box to filter for.

How to pull keywords from an excel cell

I work in sourcing and I'm trying to look through a list of cells that contain part numbers and their description, but only pull the part number from the cell and place it in another column.
The part numbers have one of 10 possible prefixes (i.e. ABC, DDA, GHF, AH, etc.). The cells may look something like this:
Tire Pressure ABC123873 Monitor
Oil Life ABC849999999021 gauge
Air conditioner GHF211 maintenance
And I want to be able to search that entire list and only pull the following information into another column:
ABC123873
ABC849999999021
GHF211
As you can see from above, the challenge is that the part numbers are all different lengths and have no particular convention to them. The only thing you know about them is that they can have one of ten possible prefixes as I mentioned above (ABC, GHF, etc.).
The current solution I have looks something like this:
C2=FIND("ABC", A2)
D2=FIND(" ", A2, C2)
E2=MID(A2, C2, D2)
Where cell A2 contains the complete part number and description, C2 finds the beginning location of the part number by searching for its prefix, D2 finds the ending location of the part number by searching for a space, and then E2 pulls the substring between those two locations.
As you can see, this isn't a very robust solution and it only allows me to search for parts that start with ABC. I want to be able to search for all 10 possible prefixes (ABC, DDA, GHF, AH, etc.) but that does not work. I tried the approach below:
C2=FIND({"ABC", "DDA", "GHF", "AH"}, A2)
But that only searches for the ABC parts and disregards the other prefixes. Any help you all can offer will be greatly appreciated!!
This is how I would do it. I created a list of prefixes to search in column G. You could even put them on a separate page to keep it cleaner.
=MID(A1,FIND(G1:G2,A1,1),FIND(" ", A1, FIND(G1:G2, A1, 1))-FIND(G1:G2,A1,1))
I only tested two prefixes but just change G1:G2 to G1:G10 and put all you prefixes in them. The formula looks in A1. The first FIND finds the beginning character number. The rest of the equation is calculating the end of the product number minus the beginning which returns the amount of characters to return. Its important to know that MID isn't wanting the beginning and end character. It wants the beginning character and the number of characters after that to return. So FIND(" ", FIND(G1:G2, A1, 1)) does not work as it returns too many characters. Give it a try.
Oh and don't forget to do Ctrl+Shift+Enter to enter the array formula
The VBA answer would be
Sub findProductCode()
' Variable Declarations
Dim productName As String
Dim productArray() As String
Dim wordCount As Integer
' Sets the active sheet to use
' Change Sheet1 to the name of your sheet
With Sheets("Sheet1")
' Selects the first cell to check
' Change A1 to the first cell with data
Range("A1").Select
' Loops through all rows until an empty row
' It will end if you have any empty rows in the midle of data
Do Until IsEmpty(ActiveCell)
' Reads text out of the cell
'Change A to the proper column
productName = Range("A" & ActiveCell.Row).Text
' Splits the string into individual words
productArray = Split(productName, " ")
' Loops through array to find the product number
For wordCount = LBound(productArray) To UBound(productArray)
' Check if the word has the desired 10 prefixes
' Add more Or Left(productArray(wordCount), 3) = "xxx" until you have 10 of your prefixes you need
If Left(productArray(wordCount), 3) = "ABC" Or Left(productArray(wordCount), 3) = "GHF" Then
' Sends the product number to its cell
' Change B to the correct destination Cell
Range("B" & ActiveCell.Row).Value = productArray(wordCount)
End If
Next
' Increments the active cell to the next cell down
ActiveCell.Offset(1, 0).Select
Loop
End With
End Sub
If you don't know how, you need to enable the developer tab in excel. File->Options->Customize Ribbon Add the Developer to the Ribbon. The save your worksheet as .xlsm It is the macro enabled workbook. Then go to the developer tab, Choose "Visual Basic" and double click "ThisWorkBook". Paste the code in. You can run the code from there for a one time deal or you can create a button on the sheet that you can run this macro whenever you want.
To add a button, go back to the sheet you want the button on. On the developer tab select Insert and choose the first form control Button. Draw the button on your sheet and a dialog box will appear. select the findProductCode macro and select OK. Now every time you click the button it will run the macro.
This isn't the prettiest formula, but it should get you on your way. There's definitely a VBA solution, if you're interested in a macro instead of a formula.
Assuming your Tire Pressure ABC123873 Monitor is in A1, enter this into B1:
=MID(SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1),SEARCH("ABC",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1)),SEARCH(" ",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1))-SEARCH("ABC",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1)))
How it works, is it takes your A1, and first uses Substitute. I substitute the first and second [space] for ; and -. (Note, if there are more spaces than two, this will run into issues). Then, I just use Mid to extract the part of the cell starting with ABC and going until it hits the space. If you don't have "ABC" starting the values you want, you need to adjust the Search("ABC"... part (or use an array there). I am still working on it, but hopefully this helps give an idea.

Excel conditional formatting for the entire row with more than one formula

After 3 hours of searching I still didn't find an answer, here is what I am trying to do:
I am trying to fill with green any row that has WBS in it and with Red any row that has ACT in it and Blue any row that has EPR in it. It works for the first formula then when I try to add the second one every thing get messed up.
what i have understood is that you need to search a keyword in a row and if its found in any cell of that row then color it.
May be we can do it with conditional formatting but i have another idea. We can create a simple search function in Excel VBA. Something like this:
=search_row(A1:F1,"EPR")
The function will return 1 if EPR is found in any cell of specified row. Now if you create two different columns at the end of data columns, name first with WPS and second with EPR and write this function in it. Like
G1 =search_row(A1:F1,"WPS")
H1 =search_row(A1:F1,"EPR")
Drag it to end. Now sort the columns. First for WPS from higher to lower. Then color all rows having 1 in a single select. Similarly do the same with EPR (H1) column.
To use this function you can download the macro file from the following URL:
http://asimishaq.com/myfiles/SearchHighlight.xlsm
Now to run it first of all enable macros, and then re-open your data file and then open this macro file. As long as this macro file is opened you can use this function. Following is the VBA code if you want to create the macro yourself:
Function search_row(sRow As Range, Keyword As String)
Dim i As Integer
Dim Found As Integer
For i = 1 To sRow.Columns.Count
If InStr(1, LCase(sRow.Cells(1, i)), LCase(Keyword)) > 0 Then
search_row = 1
End If
Next
End Function
I had a go at making a function similar to asim-ishaq to determine if your search term exists in the row for fun :) then tried to apply it to highlighting rows, turns out I dont know how to use conditional formatting very well! Figured it out in the end, hopefully I've explained it well enough.
With this you will have to have (one) extra column at the end of your data to contain the result.
It might be possible to not require the extra column by putting the function inside the conditional formatting, however I couldn't get it to work (didn't try very hard). This isn't a great loss as it's much simpler to edit the formula if its on the workbook, instead of having to go through each conditional rule to edit it, should you need to edit it in the future.
To get the formatting to work you will need to create a number of rules (one per keyword)
You want to create a rule of the type shown below, in the formula box you need something along the lines of: =INDIRECT("D" & ROW())=0 where D is the column containing the result of the function below and 0 is the index of the keyword you're highlighting.
In my example, the formula in the D Column is: =SearchRow(An:Cn,"ABS","KBS","JBS") (where n is the row the formula is on)
Set the formatting as desired then press OK, when you return to the rule manager you will need to update the Applies to value, which should be a range that covers all the data you want to highlight. In my example it was $A$1:$C$3
My function below takes 2+ Arguments, The first is the range to search. The second (and any subsequent ones) are search terms.
The function will return a number. -1 for no matches and 0+ for the found search term. The number depends on the position in the arguments.
A1 = "ABS"
B1 = "SBA"
A2 = "SBA"
B2 = "ABS"
A3 = ""
B3 = ""
C1 = "=SearchRow(A1:B1, "ABS", "SBA")"
C2 = "=SearchRow(A2:B2, "ABS", "SBA")"
C3 = "=SearchRow(A3:B3, "ABS", "SBA")"
C1 > 0
C2 > 1
C3 > -1
The function will always return the first result, searching left to right comparing each cell to the Keywords in order. Using my example, if a cell contained "SBA ABS" the result would be 0 (for ABS). I guess your cells will probably only contain one keyword though so this shouldn't be a problem?
Public Function SearchRow(ByVal Row As Range, ParamArray Keyword() As Variant) As Integer
Dim Column As Integer
Dim Value As String
Dim Index As Integer
Dim Result As Integer
For Column = 1 To Row.Columns.Count
Value = LCase(Row.Cells(1, Column))
Result = -1
For Index = LBound(Keyword) To UBound(Keyword)
If InStr(1, Value, LCase(Keyword(Index))) > 0 Then
Result = Index
Exit For
End If
Next Index
If Result > -1 Then
Exit For
End If
Next Column
SearchRow = Result
End Function

Resources