I have 5 worksheets: (1) Summary (2) 2020 (3) 2019 (4) 2018 (5) 2017
In my "Summary" worksheet, I have Column A with cells each containing the name of each worksheet (A1: 2020, A2: 2019, A3: 2018, A4: 2017) and Column B with the number "1" in each corresponding row.
Let's say I delete the "2019" worksheet so that it is no longer between worksheets "2020" and "2017" - is there any formula that I could use to flag that in row 2? Perhaps through some sort of "if(..,1,0)" formula for Column B? I do not want to use VBA.
There are various error-checking functions available in Excel, and most of them would be appropriate for your situation. The simplest would be to use IFERROR and just refer to a cell on one of the sheets, like this:
=IFERROR('2020'!A1,"Missing")
If the formula receives an error value because it can't find the cell, it will display the text "Missing"; otherwise, it will show the value of the cell.
The disadvantage of doing it this way, hard-coding the sheet name into the function, is that if the sheet is deleted the sheet name will be replaced in the formula with #Ref!, so even if the sheet is restored the formula will need to be changed.
We can enhance the functionality by using an INDIRECT along with the IFERROR. This will take a text string and turn it into a cell reference. So assuming we have worksheet names in column A, we could do this:
=IFERROR(Indirect(A1 & "!A1"),"Missing")
The INDIRECT function takes the value in A1 and combines it with the text string, and reads the whole thing as a cell reference. This has the same result, but is more robust since deleting the sheet and then replacing it will clear the error.
For a slightly more elaborate result, we could next IF and ISERROR instead of using IFERROR. It gives us more control over the result.
=IF(ISERROR(INDIRECT(A1 & "!A1")),"Missing","Found")
ISERROR returns TRUE if the first argument throws an error, an FALSE if it does not. This will return "Found" if the sheet is present, or "Missing" if it isn't.
Related
I have a drop down list (with name of sheets) and based on that value, let's say that I select the Sheet4 as in the image, I want to bring to another sheet the value of that selection, let's say on the cell B8.
I know that this works:
=IF(B1="Sheet1", Sheet1!B8, IF(B1="Sheet2", Sheet2!B8, Sheet3!B8))
That's for just 3 sheets but is there a nicer or more efficient way to do this?
This is in general how all the sheets look like:
Use INDIRECT to construct a valid worksheet and cell reference from text-that-looks-like-a-worksheet-and-cell-reference 1
The indirect takes a string and turns it into a valid reference.
=INDIRECT("'" & B1 & "'!B8")
So in the case above it would create a string "'Sheet4!B8". Then the Indirect will turn it into a valid cell reference.
As Jeeped also pointed out in the comments The B8 reference since it is literal text it will not change if the formula is copied or dragged to another cell.
The B1 which is a cell reference and is relative will change as it is copied or dragged to different cells.
1 as per #Jeeped comment
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.
I have 2 worksheets in my excel, the first sheet allows me to select a calculation method from a drop down list and input the variable for the calculation (shown in green cell, the column in blue shows some constant number). The result entry will search for the corresponding calculation formula from my second worksheet (database), then paste the formula to the sheet 1, I need the formula to calculate using the cells in sheet 1 instead of cells in my database.
currently I created an user defined function called Eval as below:
Function Eval(ref As String)
Eval = Application.Evaluate(ref)
End Function
by combining the Eval with vlookup :=Eval(VLOOKUP(A3,Database!A2:E10,5,FALSE)) I will get the result that the calculation equation uses the cells from my database, how can I achieve the result which the formula takes cells in sheet 1 during calculation?
One simple way would be to use all formulas within one CHOOSE like this:
=IFERROR(CHOOSE(SUMPRODUCT(MATCH(A2,"Calculation "&ROW($1:$9),0)),B2*C2*D2,B2*C2-D2,B2+C2-D2,B2^2-C2+D2,B2*D2-C2^2,B2+C2*D2,B2*C2-C2*D2,B2-D2-C2*D2,C2-D2*B2),"")
Another would be to use the Application.Caller like:
Public Function eval(ref As String)
eval = Application.Caller.Parent.Evaluate(ref)
End Function
This ensures the use of of the parent of the caller (the sheet with the eval() formula) to be used as main-ref.
EDIT
Keep in mind that your "rows" are static in the formulas. Going for "Calculation 4" will use row 5 (and not the row of your formula from the first sheet). For this you could use something like:
=Eval(SUBSTITUTE(VLOOKUP(A3,Database!A2:E10,5,FALSE),"##",ROW()))
While all row-numbers should be changed to ## (or whatever unique identifier you like). Then "Calculation 1" would look like: =B##*C##*D##
If you still have any questions, just ask :)
I have two sheets.
This is the first sheet. Named 3
And this is the second sheet. Named centralizare
I have to write in Sheet2 C5 the number of 'Id garantie' from Sheet1 if the 'Categorie' from Sheet1 is 'Done' (Sheet2 B5) and 'Status 1'from Sheet1 is 'In lucru' (Sheet 2 B4)
I tried this
=COUNT(INDEX('3'!$C$2:$C$99,MATCH(B5,'3'!A2:A99,0)))
but it returns only one number if only the 'Categorie' is Done.
And other method with errors
=MATCH('3'!C2:C99,(centralizare!C5='3'!B2:B96)*(D4='3'!F2:F96),0)
=INDEX('3'!$C$2:$C$99,MATCH(D5,'3'!C2:C99,0))
=COUNT(INDEX('3'!A2:A96, MATCH("In lucru",'3'!E2:E96)))
You could try an array formula with sumproduct:
=SUMPRODUCT(--IFERROR((('3'!A2:A5=centralizare!B5)),0))
Must be entered using ctrl + alt + enter. Is should appear like so in your formula bar if done right:
{=SUMPRODUCT(--IFERROR((('3'!A2:A5=centralizare!B5)),0))}
Sample workbook: https://filetea.me/t1sjZdwkvxrRxGePZmKZyB7BQ
EDIT: It also seems that you should never had "finalizat" & "wip" in the same row, if I understand your rules right. WIth the array formula, you can check for both rules & only count those that meet both rules, not just one, and somewhat check data quality this way.:
{=SUMPRODUCT(--IFERROR((('3'!A2:A5=centralizare!B5))*('3'!C2:C5=***choose a cell/range where you put a reference to finalizat/in luru instead of wip/donw***),0))}
In other words, the general format for multiple criterial is:
{=SUMPRODUCT(--IFERROR(((CRITERIA ONE)*(CRITERIA TWO)),0))}
Lets say
sheet3.name = "d"
Is there a way I could put in a cell on sheet2 the formula =sum(sheet3!b:b) where sheet3 is being substituted with the actual sheet3 name?
I can only get =sum('d'!b:b) to work so far.
I could use VBA for this probably but I'm curious how to do this in a cell so I don't have to run a macro each time.
If you can use a UDF User Defined Function that will return the sheet name
Function SHEETNAME(number As Long) As String
SHEETNAME = Sheets(number).Name
End Function
then a formula like
=SUM(INDIRECT(SHEETNAME(3) &"!B:B"))
will return the sum from column B on sheet 3.
SHEETNAME(number) returns the sheet name of the number which is index.
So Sheet(1) returns Sheet1, etc
Use below formula anywhere in the sheet to get the sheet name - the sheet must have a filename for this to work:
=REPLACE(CELL("filename"),1,FIND("]",CELL("filename")),"")
You can either reference that cell using Indirect:
=SUM(Indirect("'"&A1&"'!B:B"))
or, if you don't want to have a second cell, you can combine the two formulas into one:
=SUM(INDIRECT("'"&REPLACE(CELL("filename"),1,FIND("]",CELL("filename")),"")&"'!B:B"))
For anyone not concerned with the order of the sheets, the post by Biff here on mrexcel.com works well.
In Excel 2013, go to the Formulas tab in the ribbon and make a defined name:
Name: SheetNames
Refers to: =GET.WORKBOOK(1)&T(NOW())
Then use a formula like this example:
=INDIRECT("'"&INDEX(MID(SheetNames,FIND("]",SheetNames)+1,255),A3)&"'!A1")
where A3 refers to the index number in a cell in the current sheet, and A1 refers to the location of the value to be retrieved from the other sheet. I.e., in the current sheet, if A3 = 2, then the formula will point to cell A1 in the second sheet of the workbook. I just use a column of index numbers in my current sheet, then drag this formula down and it fills in values from all of my other sheets.
You will need to save as a macro-enabled file (.xlsm).
I'm not sure if this is a good idea but it's the first one I could think of.
I would add additional function to your VBA project which will return actual name of your Sheet3:
Function Sheet3Name()
Sheet3Name = Sheet3.Name
End Function
Next, when you create sum formula of column B:B in Excel cell you need to do it in this way:
=SUM(INDIRECT(Sheet3Name()&"!A:A"))