I need to calculate how many time any given numbers appeared in an excel cell.
Conditions below:
Each cell can have different combination of repetitive numbers, separated by commas.
The excel formula will be robust enough to search for any numbers desired by user.
Max range up to 20.
Example, I would input any number and the formula should return me a sum of occurrence.
1, 2, 3, 1, 5, 11, 1, 11
=> 5 (input "1" and "11")
=> 3 (input "1" only)
=> 2 (input "11" only)
*****************************************************
Things i have tried:
=LEN(A2)-LEN(SUBSTITUTE(UPPER(A2),"1,","")) => Answer is 7 (wrong)
=LEN(A2)-LEN(SUBSTITUTE(UPPER(A2),"1","")) => Answer is 8 (wrong)
Main difficulty:
The formula seems to search for "1" and therefore "11" would often mistooken as "1" too, and thus added to the sum.
Same goes for "5", "15" etc, any numbers in the tenths.
My approach was to do a text search instead of numbers, that failed.
Appreciate if there are alternate solutions too (Text -> Column ??).
You need to include the delimiters front and back. This means that you also have to add them as a prefix and suffix to the original string.
=(LEN(", "&A2&", ")-LEN(SUBSTITUTE(UPPER(", "&A2&", "),", 1,", "")))/LEN(", 1,")
If VBA is feasible, add this to VBA code and use the following function (assuming your long string is in cell A2)
= getOccurence(A2,5)
VBA Code:
Function getOccurence(inputString As String, numberToSearch As Integer) As Integer
Dim strArray() As String
strArray = Split(inputString, ",")
For i = 0 To UBound(strArray)
If (strArray(i) = numberToSearch) Then
getOccurence = getOccurence + 1
End If
Next
End Function
I would use text to columns to get each number in its own cell. NOTE: you may want to insert blank columns to hold the numbers first so that you do not overwrite any data!
After this, I would use the function COUNTIF to count the number of occurrences of a certain number there is within a range. For example:
=COUNTIF(F5:I5,2)+COUNTIF(F5:I5,3)
This counts the number of 2's and 3's within the range F5:I5
For more on this, see:
https://exceljet.net/excel-functions/excel-countif-function
Related
I have a column of numbers in excel that I would like to replace with their two letter ending "th" "nd" as in 13th, or 62nd. How do I do this in excel? I do have a big key that has the number and its ending on a separate sheet.
Cardinal numbers are normal numeric numbers and look like: 1, 2, 3, 4, etc.
Ordinal numbers have a suffix and look like: 1st, 2nd, 3rd, 4th, etc.
Please note that in ordinal form, numbers are actually text and should only be used for display; Excel will no longer consider them numbers.
If a cardinal number is in A1 this formula will result in its ordinal representation...
=IF(OR(--RIGHT(A1,2)={11,12,13}),"th",IFERROR(CHOOSE(RIGHT(A1),"st","nd","rd"),"th"))
The above formula does NOT need to be array entered. Just a normal confirmation will suffice.
For completeness here is a way to use the above surprisingly concise formula as a UDF. Place the following function in a VBA standard code module...
Function Ordinal(n)
Ordinal = n & Evaluate("IF(OR(--RIGHT(" & n & ",2)={11,12,13}),""th"",IFERROR(CHOOSE(RIGHT(" & n & "),""st"",""nd"",""rd""),""th""))")
End Function
Now you can call it from a formula on a worksheet. For example, in cell A1 you could have the following formula:
=Ordinal(123)
Or from a VBA routine...
Msgbox Ordinal(21)
And to get and hold an array of the first 255 ordinal numbers in VBA you can use the following variation as a function...
Function Ordinals()
Ordinals = [ROW(1:255)&IF((--RIGHT(ROW(1:255),2)>10)*(--RIGHT(ROW(1:255),2)<14),"th",IFERROR(CHOOSE(RIGHT(ROW(1:255)),"st","nd","rd"),"th"))]
End Function
Now get the array like so...
Sub Test()
Dim v
v = Ordinals '<-- v is now a 2d array and holds the first 255 ordinals
MsgBox v(211, 1)
End Sub
I have a spreadsheet where users enter their three character name code corresponding to everyday with number of hours that they plan to spend in a specific task (A, B, C) within brackets. What I want is these needs to be summed up for every user and get populated in rows corresponding to their names everyday.
Currently I am using an custom vba function to perform this sum, however I wanted to know if this can be done directly with any custom formula or VLOOKUP. Any help is appreciated!
Edit: I have been using the function, one specific to each user (the three character code) to calculate this sum.
Function SumJON(Target As Range) As Double
Dim xCell As Range
Dim xSum As Double
xSum = 0
For Each xCell In Target
If xCell.Value <> "" And InStr(xCell.Value, "JON") > 0 Then
Test = Split(xCell.Value, "JON")
Test1 = Test(1)
Test2 = Split(Test1, ")")
Test3 = Test2(0)
xSum = xSum + Test3
End If
Next
SumJON = xSum
End Function
You can try the following, with the below setup of data:
Formula in B2:
=SUM(IF(ISNUMBER(SEARCH(MID($A2,LEN($A2)-3,3),B$6:B$8)),MID(B$6:B$8,SEARCH(MID($A2,LEN($A2)-3,3),B$6:B$8)+4,SEARCH(")",B$6:B$8,SEARCH(MID($A2,LEN($A2)-3,3),B$6:B$8))-SEARCH(MID($A2,LEN($A2)-3,3),B$6:B$8)-4),0)*1)
NOTE: This is an array formula and should be confirmed through CtrlShiftEnter
Drag formula down and right.
It will also work on expending the amount of names in the list AND with decimals:
Note that my system decimal point is a comma.
Breakdown:
To extract the searchvalue, JON, DOE and PRK we can make use of MID since you have a certain pattern to take into account. It would always have to be:
=MID($A2,LEN($A2)-3,3)
This value needs to be used in a SEARCH function which will return a position of our searchvalue in the A,B,C rows. Since it's an array formula it will return all these numeric positions or an error.
Therefor we need to use ISNUMBER to check if the searchvalue is actually found through SEARCH. If so it will return a TRUE and if not it will return FALSE.
Because this is part of our IFstatement, the formula will do another MID function for the TRUE values. Again we will have to make use of our searchvalue formula, but this time we know it will be in these strings and therefor we can use the numerical position as our starting position (+4, because these strings are 3 positions long + the opening paranthesis) in this second MID.
Now we have a starting position to get the lookupvalues from, we just need to know the first position of the next closing paranthesis, and we can do that through SEARCH from this exact position.
Multiplying it by 1 in the end would turn these values in true numerical lookupvalues, which finally can be summed through SUM
Et voila, we got the total of values between the paranthesis where the searchcriteria meets the current user.
In Sheet1 I have several input values x, y and z in columns A, B and C. To simplify let's say I only have two rows with values (as in the picture).
In Sheet2 I have the thresholds; min and max-values for x, y and z, in addition to the corresponding codes.
I want to retrieve, in Sheet1, all codes where the input values fall within the thresholds (matching the values) in Sheet2. The codes do not need to be listed in the same cell if this complicates things; they can be listed in separate columns. I am also open for both formulas and VBA.
I know how to list several results using JOINTEXT if the criteria are exact matches. I also know how to list one result based on several inaccurate matches using INDEX + MATCH + <= >=. I don't know how to combine them.
I looked at these:
EXCEL index match by multiple criteria AND multiple match types?
https://exceljet.net/formula/multiple-matches-in-comma-separated-list
https://exceljet.net/formula/index-and-match-with-multiple-criteria
...and tried this:
=INDEX(F5:L8;SMALL(IF(COUNTIF(F5:F8;"<="&A5)*COUNTIF(G5:G8;">"&A5)*COUNTIF(H5:H8;"<="&B5)*COUNTIF(I5:I8;">"&B5)*COUNTIF(J5:J8;"<="&C5)*COUNTIF(K5:K8;">"&C5);ROW(F5:L8)-MIN(ROW(F5:L8))+1);COLUMN(F4));ROW(F4)+6)
...without any result.
I managed to solve it by using Jeeped's impressive code (see comments). However, since I'm using comma (,) as decimals-seperator I needed to include a small adjustmen. I changed "iOptions", "iIgnoreHeaderRows", "i" and "j" from Variant to Double, and "a" from Variant to Long. I also included the following code:
Dim counter As Integer, sizeOfPairs As Integer
Dim test As String
counter = 0
sizeOfPairs = UBound(pairs, 1)
For counter = 0 To sizeOfPairs
If TypeName(pairs(counter)) = "String" Then
pairs(counter) = Replace(pairs(counter), ",", ".")
End If
Next counter
I have a range of cells which I want to do some math on. But I also want those cells to contain some text.
For instance I want the sum of A1 and B1 where A1 contains the number 10 and "z001" and B1 contains the number 20 and "Z004".
Then I want the formula to ignore the text, and just come up with 30.
Is this possible?
For a quick solution, type "=Left(A1, 2) + Left(B1, 2)" into C1. Drag this equation down the rest of your range and you should get the results you want, provided the numbers you are adding are all 2 digits.
You can also use VBA if you need to run the same equation on multiple cells.
If you can get the same results by just removing the letters, try:
For i = 58 To 127
'Change out str with the variable name you have assigned to your cell value.
str = Replace(str, Chr(i), "")
Next i
58 and 127 represent the first and last positions in a range of characters on the Ascii table that are not numerals http://www.asciitable.com/
If you just want to include the first two numbers of each cell in your equation and ignore the "Z00#", you can try:
strLeft = Left(str, 2)
This will reduce your string down to the first two characters of each cell.
You can look here for other ways to remove characters you don't want.
http://www.globaliconnect.com/excel/index.php?option=com_content&view=article&id=269:excel-vba-string-functions-left-right-mid-len-replace-instr-instrrev&catid=79&Itemid=475
Here is in example of how you would implement something like this with simple addition.
Dim a as range
Dim b as range
Dim aLeft as integer
Dim bLeft as integer
Dim cleft as integer
a = Worksheets("WorksheetName").Cells(A1).Value
b = Worksheets("WorksheetName").Cells(B1).Value
aLeft = Left(a, 2)
bLeft = Left(b, 2)
cLeft = aLeft + bLeft
Worksheets("WorksheetName").Cells(C1).Value = cLeft
This would add the first two digits of cells A1 and B1 then display the result in C1.
As I see it, you have 2 options:
Search for the number within each cell and sum it up (see below).
Split the columns to have 1 column of numbers and one of codes (e.g.
"z001"). See on the "Data" tab on the ribbon and click "Text to
Columns" on the Data Tools group.
The first option would be the quickest and more straightforward. You need to make a third column where the sum will be and then use, for example, the function LEFT. This function allows you to retrieve characters from a cell. See example below:
To get "30" I have used the following formula on C2:
=LEFT(A2,2)+LEFT(B2,2)
Note this is not ideal since this formula is looking for 2 characters every time. If you have a scenario with the following code "5z005" it won't work because it will try to sum "5z" as if it was a number. In that case you're better off finding a pattern (code = "number" "z" "number") and splitting the columns as I said on option 2.
I'm writing a vbs script to extract some data from an excel spreadsheet. Currently using the function:
objSheet.Cells(rowNum, colNum).Value
To get cell values, this allows me to do maths on the column number, e.g. add three to move across three columns. But in some instances I want to specify which Columns to get by letter:
objSheet.Cells(4, E).Value
I therefore need to write a vbs function to convert column letter to numbers E => 5. Needs to be able to handle a spreadsheet more than 26 cols wide.
I've seen lots of functions on the internet and SO for doing the opposite but not found much for doing the conversion this way.
Thanks
This code will run without Excel:
Function ColNum(strCol As String) As Integer
Dim i As Integer, col As Integer
For i = Len(strCol) To 1 Step -1
col = col + (Asc(Mid(strCol, i, 1)) - 64) * (26 ^ (i - 1))
Next
ColNum = col
End Function
Alternatively, in Excel, you can simply use this:
Function ColNum(strCol As String) As Integer
ColNum = Range(strCol & "1").Column
End Function
without vba:
To convert a column number to a letter you enter this formula:
=LEFT(ADDRESS(1,3,4)) (returns the column letter for the cell C1=C)
But this is still not satisfactory because if you insert a column before the column C the number 3 won't change to 4, so here is a fix:
=LEFT(ADDRESS(1,COLUMN(C1),4))
Hope this helps.
This is especially helpful when you need to create strings that specify a cell range for example.