i have a data set in Excel where in the 1st column there is and ID with 12 characters in which i must change from 1 to -1 if the first 6 characters from left to right has several conditions.
I have tried the following, but i cant get it work with out using VBA
=IFT((LEF([#Cuenta],6)=AND("503-01","503-02","503-50","503-60")),-1,A847)
I would like to make it as short as possible cause the person that works with the sheet gets confused with long formulas
Related
This question already has answers here:
Find last used cell in Excel VBA
(14 answers)
Closed 1 year ago.
I need some expert advice on VBA code. I have created a procedure to compare two short reports (the same format, generated from the system). I used the for loop starting from the first row until the last one using UsedRange.Rows.Count. The problem I have is that UsedRange.Rows.Count always return 30 even though the reports are generally shorter than that - usually around 20-25 rows. It returns 30 even if I clear the content inside these rows. It only returns the correct number when I permanently delete the blank rows up to row 30.
Why is that happening? It bothers me because also for some reason the macro highlights the blank rows (from the last actually used to row 30) showing them as a difference between the reports, while they exist and are the same (blank) in both.
Thank you
UsedRange will expand to include all cells that Excel registers as containing any data. Values, formulae, formatting — even (and I suspect that this may be what is happening here) a cell that has had a value deleted from it. Anything outside of UsedRange is treated as not yet officially existing yet.
As an analogy, this is the difference between an empty box, and no box (with the worksheet cells being boxes). UsedRange tells you where the last box is, even if you've emptied it (with Value = "" or ClearContent); only deleting the Rows/Columns/Cells will get rid of the box itself.
There are many much better ways to get the size of your data than by using UsedRange (although, it at least provides an Upper Bound)
For example, if your data is contiguous, then you can select a single cells (e.g. Range("A1") / Cells(1,1)), and get the CurrentRegion (Cells(1,1).CurrentRegion.Rows.Count). Or, if you know a column that always contains data, you can use End(..) to find the bottommost cell (Cells(Rows.Count,1).End(xlUp).Row)
I have written a simple iteration loop that goes through each row of a workbook and reads the value in the first cell. Using the instring function of vba I determine whether or not the cell contains certain characters and if the criteria is met it either deletes or preserves the row. When I run this code, however, there are two cells that are spelled and formatted identically to each other, but one is deleted and one is saved. The cells in question contain the text (CJ 20210526) - Merlin FLIR Calibration. I have included the code for reference, because it is not very long and after scouring it multiple times I cannot find the issue. I don't understand how two cells that are exactly the same can be treated so disparately.
Filter Code in VBA
You need to run the code backwards.
Replace:
For x=1 to last_row
by:
For x=last_row to 1 Step -1
Also dim x as Long
(there may be other errors)
In addition to the question I posted previously, (Change text length based on drop down option selected), I have another scenario where a Bank's account numbers (BANK C) are either 10 or 15 digits long. The answer to my previous question facilitated changing the text length to a range (between 10 and 15 digits) and changing the text length to exactly 12 digits, by creating a lookup table and defining the min and max values.
I was told that a different approach would be needed to change the text length to either one of two values (meaning either 10 or 15 digits), but nothing I've tried so far has worked.
As shown in the last question:
I am using the following table:
I am using the following formula in my Data Validation:
=AND(LEN(B2)<=VLOOKUP(A2,F:H,3,FALSE),LEN(B2)>=VLOOKUP(A2,F:G,2,FALSE))
VLOOKUP will only return the first line and I need it find multiple so I can test against those.
How can I go about getting this to work, while still allowing the other two ways to work?
Maybe slightly different approach as shown below. Validation rule formula seems working to me:
=NOT(ISERROR(MATCH(LEN(C3),OFFSET($G$4:$G$9,,MATCH(B3,$G$3:$I$3,0)-1),0)))
We are just checking if we can find length in specific column in the table. Possible values means all possible lengths. You can also build your table horizontally, but this will require some formula adjustments. If you want, you can either expand Range G4:G9 and G3:I3 or change it to named range, or try referencing to column and header of table - these solutions will make our validation formula flexible (when you add item to list, formula will change automatically).
I am pretty sure that it is also possible to simplify that formula.
I'm sorry for cutting row numbers in the screenshot.
The following formula worked for me:
=IF(AND(ISNUMBER(SEARCH(1, A4)), AND(LEN(B4)>MIN(9), LEN(B4)<MAX(16))), TRUE, IF(AND(ISNUMBER(SEARCH(2, A4)), LEN(B4)=12), TRUE, IF(AND(ISNUMBER(SEARCH(3, A4)), OR(LEN(B4)=10, LEN(B4)=15)), TRUE,FALSE)))
So basically if "1" is found in cell A4, where the drop-down list of all the bank names is, it will only allow between 10 and 15 characters to be entered into cell B4 (where i'm inputting the bank account number). If "2" is found in cell A4, it will only allow 12 characters to be entered and if "3" is found in cell A4, only 10 OR 15 characters can be entered. Thanks for the replies though everyone.
I'm new to excel but have enjoyed trying new things with the program. I'm trying to figure out if I can have one cell read something based on the standing of other cells. For example:
If g10 = 6 then h14 will read either unacceptable, acceptable, recognized or exemplary based on a the scale shown below.
0-1 unacceptable
2-4 acceptable
5-7 recognized
8-9 exemplary
Is this possible?
There are a dozen ways to do any one thing in Excel and this is no different. I'll show you two.
First you can do this with a bunch of IF statements
=IF(G10<=2,"Unacceptable",IF(G10<=4,"Acceptable",IF(G10<=7,"Recognized",IF(G10<=9,"Exemplary","Too Good"))))
You can see this is pretty good but it means you need to rewrite your formula if anything changes in your scale.
The other way is to use VLookups.
I put these values in the range A1:B10
0 Unaceptable
1 Unaceptable
2 Acceptable
3 Acceptable
4 Acceptable
5 Recognized
6 Recognized
7 Recognized
8 Exemplary
9 Exemplary
Then used this formula for the lookup
=VLOOKUP(G10,A1:B10,2,FALSE)
Where
=VLOOKUP(D16 <~~ The value to use to look up
,A1:B10 <~~ The range in which you're doing the lookup. The lookup is always performed on the left most column. Any other columns included in the range are available to be return values.
,2 <~~ Column from range A1:B10 to return from the Vlookup function
,FALSE <~~ Whether or not to do approximate matching. You more than likely always want exact matching so this will usually be false
)
If you will be using this in more than one cell and/or are copy/pasting it around you can lock in the lookup range using $. i.e. =VLOOKUP(G10,$A$1:$B$10,2,FALSE) These will not be relative references if you use the $ sign. You can put this in by hitting F4
One step better than this is to use named ranges though. This means while you have our grading scale highlighted in A1:B10 you go to that text box to the left of the formula bar and type MyGradingScale and they now you can refer to that range by name.
=VLOOKUP(G10,MyGradingScale,2,FALSE)
You can then use this formula in lots of places and upgate it in one place. Go to Formulas>Name Manager on the ribbon to change the reference.
This is fairly simple, depending on what version of Excel you're using.
A simple, IF(AND()) formula should work here
Try:
=IF(AND(A1>=0,A1<=1), "Unacceptable", NEXT TEST HERE)
That should get you started, just use nested IF(AND()) statements.
(Alternate title: Why on earth doesn't Excel support user-defined formulas with parameters without resorting to VB and the problems that entails?).
[ Updated to clarify my question ]
In excel when you define a table it will tend to automatically replicate a formula in a column. This is very much like "fill down".
But ... what if you need exceptions to the rule?
In the tables I'm building to do some calculations the first row tends to be "special" in some way. So, I want the auto-fill down, but just not on the first row, or not on cells marked as custom. The Excel docs mention exceptions in computed columns but only in reference to finding them and eliminating them.
For example, first row is computing the initial value
The all the remaining rows compute some incremental change.
A trivial example - a table of 1 column and 4 rows:
A
1 Number
2 =42
3 =A2+1
4 =A3+1
The first formula must be different than the rest.
This creates a simple numbered list with A2=42, A3=43, A4=44.
But now, say I'd like to change it to be incremented by 2 instead of 1.
If I edit A3 to be "A2+2", Excel changes the table to be:
A
1 Number
2 =A1+2
3 =A2+2
4 =A3+2
Which of course is busted -- it should allow A2 to continue to be a special case.
Isn't this (exceptions - particularly in the first row of a table) an incredibly common requirement?
If you have the data formatted as a table you can use table formulas (eg [#ABC]) instead of A1 format (eg A1, $C2 etc). But there are 2 tricks to account for.
Firstly there is no table formula syntax for the previous row, instead excel will default back to A1 format, but you can use the offset formula to move you current cell to the previous row as shown below. However in this case it will return an # value error since I cant +1 to "ABC".
ABC
1 =OFFSET([#ABC],-1,0)+1
2 =OFFSET([#ABC],-1,0)+1
3 =OFFSET([#ABC],-1,0)+1
4 ....
So the second trick is to use a if statement to intialise the value, buy checking if the previous row value = heading value. If the same use the initial value else add the increment. Note assumes table is named Table1
ABC
1 =IF(OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]],42,OFFSET([#ABC],-1,0)+1)
2 =IF(OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]],42,OFFSET([#ABC],-1,0)+1)
3 =IF(OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]],42,OFFSET([#ABC],-1,0)+1)
4 ....
Note you can set the initial value to be a cell outside the table to define the initial value (in say $A$1) and increment (in say $A$2) as below
ABC
1 =IF(OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]],$A$1,OFFSET([#ABC],-1,0)+$A$2)
2 =IF(OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]],$A$1,OFFSET([#ABC],-1,0)+$A$2)
3 =IF(OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]],$A$1,OFFSET([#ABC],-1,0)+$A$2)
4 ....
I use this IF OFFSET combination all the time for iterating and looping in tables.
If you have alot of columns that need to determine if they are the first row you can have one column test if first row and the rest can work with a simpler if. eg ABC will give true for first row false for others, then DEF with increment the initial value
ABC DEF
1 =OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]] =IF([#ABC],$A$1,OFFSET([#DEF],-1,0)+$A$2)
2 =OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]] =IF([#ABC],$A$1,OFFSET([#DEF],-1,0)+$A$2)
3 =OFFSET([#ABC],-1,0)=Table1[[#Headers],[ABC]] =IF([#ABC],$A$1,OFFSET([#DEF],-1,0)+$A$2)
4 ....
Hope that helps
I don't know if you are looking for something as simple as locking down a formula. You can do that by highlighting the part of the formula you do not want to change and then hitting F4. This will absolute this section of the formila, using a $ to indicate it, and will not change as you copy/paste it down the table.
Alternately, you may be able to use Defined Names. These you can set up in the Data tab and basically assigns something to a name or variable you can then put into your formulas. These can be as simple as an easy reference for a cell on another sheet to incredibly complex multi-sheet formals.
Normally, to handle "exceptional" formula in the first row of a table consiting of several columns, you simply enter it there manually, and fill only the lines below. But if you have more "exceptional" cases scattered around, you will need another column with 0/1 values indicating where the exceptins are. And then you use if(condition, formula_if_true, formula_if_false) everywhere.
A B
Number Exceptional?
1 if(C1,42,A1+1) 0
2 if(C2,42,A2+1) 1
3 if(C3,42,A3+1) 0
As much as I love Excel, and as much as it is the best product of whole MS, it is still a weak tool. FYI, you can quiclky learn modern and poweful scripting languages, such as Ruby, here, and never be bothered by spreadsheet idiosyncrasies again.