Count the number of instances of a digit in a range of cells - vba

If I have a column and the cells are
579
39
357
3467
34579
I want to be able to count the number of times any of the digits occurs. For example, 3 occurs 4 times in this range.
I tried using the countif function, but this seems to only work if the only thing in the cell is a 3.
Is this possible using a function, or will I have to do a workaround?

Try using using Application Evaluate on a native SUMPRODUCT function.
application.evaluate("SUMPRODUCT(LEN(A2:A99)-LEN(SUBSTITUTE(A2:A99, 3, """")))")
This will count multiple occurrences within a single value; e.g. 233453 hold 3 occurrences of 3.
If I was doing this, I would qualify the parent worksheet in those cell range addresses to avoid any confusion. The external parameter of the Range.Address property can help you construct a string to be evaluated as a formula.

Related

AVG of Cells Next to Cells used in Another Formula

I am new to asking questions here so I hope I get this correct. I am helping my dad with a spreadsheet and I'm having issues with figuring out how to do one formula. Dont know if it can be done with a formula or if it has to be done with macros.
This is a scoring sheet with multiple matches. For each match there is a total score and the cell next to the score is an X count (number of bulleyes). In the same row (column K) I calculate the top 6 total scores and average them:
=AVERAGE(LARGE((N15,Q15,T15,W15,Z15,AC15,AF15,AI15,AL15,AO15,AR15,AU15,AX15,BA15,BD15,BG15,BJ15),{1,2,3,4,5,6}))
Now I need to take the AVG of the X counts that are next to the total scores that are used in the formula above and put solution in column L.
For example, if the cells that are used for AVG score in that row are:
N15,Q15,T15,W15,Z15,AC15
then the cells that would need to be used for the X count AVG would be:
O15,R15,U15,X15,AA15,AD15
This result would be put into L15
Please help. If any clarification is needed just let me know.
Screen Shot:
Please try the following formula:
=SUMPRODUCT(O15:BM15,
--(MOD(COLUMN(N15:BL15)-COLUMN($N15),3)=0),
--(N15:BL15+O15:BM15/10^3+COLUMN(N15:BL15)/10^6>=
LARGE(N15:BL15+O15:BM15/10^3+COLUMN(N15:BL15)/10^6,6))
)/6
How does it work?
SUMPRODUCT has 3 parameters - first is the array to sum, next 2 parameters return an array of 0 and 1 to choose only interesting elements of the first array.
MOD(COLUMN(N15:BL15)-COLUMN($N15),3)=0)
This part is included to avoid listing every single cell. If the score is in every third column of the input range, we can calculate column number relative to first column, and function MOD(column,3) returns: {1,0,0,1,0,0...}. So only every third column of input array will be included in sum.
(N15:BL15+O15:BM15/10^3+COLUMN(N15:BL15)/10^6>=
LARGE(N15:BL15+O15:BM15/10^3+COLUMN(N15:BL15)/10^6,6)
This part is to decide which 6 of the scores should be included in the final sum. The trickiest part is to decide what to do with ties. My approach is to take:
if two scores are the same, take the one with higher number of bulleyes
if it is still tied, take the one from first columns
This means that instead of N15 value we calculate:
N15+O15/10^3+COLUMN(N15)/10^6
With your sample data it evaluates to: 566.017014. First three decimal places is the number of bulleyes, next 3 is column number.
You can use the same formula to calculate average of top 6 scores by changing the first parameter:
=SUMPRODUCT(N15:BL15,
--(MOD(COLUMN(N15:BL15)-COLUMN($N15),3)=0),
--(N15:BL15+O15:BM15/10^3+COLUMN(N15:BL15)/10^6>=
LARGE(N15:BL15+O15:BM15/10^3+COLUMN(N15:BL15)/10^6,6))
)/6
You can try this not so elegant solution:
=SUMPRODUCT(INDEX(N15:BK15,MATCH(LARGE((N15,Q15,T15,W15,Z15,AC15,AF15,AI15,AL15,AO15,AR15,AU15,AX15,BA15,BD15,BG15,BJ15),{1,2,3,4,5,6}),N15:BK15,0)+1))/6
Entered as array formula by Ctr+Shift+Enter in Cell L15:M15 (2 cells) which should look like this:
{=SUMPRODUCT(INDEX(N15:BK15,MATCH(LARGE((N15,Q15,T15,W15,Z15,AC15,AF15,AI15,AL15,AO15,AR15,AU15,AX15,BA15,BD15,BG15,BJ15),{1,2,3,4,5,6}),N15:BK15,0)+1))/6}
with added braces.
The number 6 is the equates to the number of top scores you want returned.
Now, why 2 cells (L15:M15). I cannot make SUMPRODUCT evaluate the resulting array from the INDEX so we have to enter it at 2 cells. I don't think that would be a problem since in your screen shot, Column M is not used.
Note: If the range evaluated have less than 6 items, it will error out. Also good point by user3964075. It may or may not be able to deal with ties.

VBA conditional cell selection

I was having a play around with excel 2007 VBA and was hoping to create a Macro that generates a random number, then outputs a string based on the number generated. For example,
Number String
1 Athena
2 Belerephone
3 Castor
4 Dionysos
If the random number is 4, the output would be Dionysos, 1 would be Athena and so on.
Basically, I want the Macro to search through the "Number" column, find the cell that matches the randomly generated number, then output the string in the cell to its right.
I have a table of a similar nature in my Excel worksheet.
So far I have not had much success at doing this, any thoughts?
With your data in A1 thru B4, use:
=VLOOKUP(RANDBETWEEN(1,4),A1:B4,2,FALSE) or its VBA equivalent
EDIT#1 :
With the upper bound of the table stored in cell D3 :
=VLOOKUP(RANDBETWEEN(1,D3),INDIRECT("A1:B" & D3),2,FALSE)
You can use application.worksheetfunction.vlookup to perform a vlookup within your macro, and use the 1+Int(10 * Rnd()) function to return random numbers from 1 to 10 (and possibly 11, but statistically unlikely).

VBA to check for blank cells in columns based on value in another column

Given
O 1 2 3 A
A 4 5 6 B
B 7 8 9 D
O 3
C 15
T 18
I'm looking for VBA code to validate that when column A contains a value that the remaining columns also contain values and when it doesn't contain a value, that columns 2 & 5 also contain values but 3 & 4 don't.
I've simplified the example, in a real sheet there will be many more columns and rows to check.
I've considered COUNTIF and INDEX/MATCH and array forumlas but from my understanding these all work on single columns at a time.
I want to do something like WHEN A1:An<>"" THEN COUNTBLANK(B:E) ELSE COUNTA (C:D)
Is the best way to use autofilter using blanks in A and then countblank and then a second autofilter for values in A.
Thanks
You can do it with a couple of nested IF formulae as follows:
=IF(A1<>"",
"A not empty, "&IF(COUNTBLANK(B1:E1)=0,
"B:E not blank",
"B:E have blanks"),
"A blank, "&IF(AND(COUNTBLANK(B1)+COUNTBLANK(E1)=0,
COUNTBLANK(C1)+COUNTBLANK(D1)=2),
"Columns 2&5 have values and Columns 3&4 don't",
"but condition not met"))
The reason for going down the VBA route is that I want a generic reusable function as opposed to a formula I copy between cells and sheets changing the columns etc along the way ending up with a lot of duplicate code.
So something that takes a column to test and a value to test it with. Third parameter would be a range of columns to validate, and the fourth parameter the validation.
I don't want any solution to have the columns hard coded and I don't want intermediate totals at the end of rows. This is fairly easily achieved in Excel itself...
The reason for trying to use countblank is that I can apply it to a range.
After a lot of searching I discovered this (the columns don't match the original example)
=SUMPRODUCT((A2:A19<>"")*(B2:D19=""))
=SUMPRODUCT((A2:A19="")*(D2:D19=""))
=SUMPRODUCT((A2:A19="")*(B2:C19<>""))
Nice huh? I just need to convert it into VBA now.
Thanks

Returning entry from an array that fits a range condition

Is there a way to have a cell in Excel 2007 view through an array of six numbers and return the highest of any of the numbers that fit into a specified range?
My particular numbers in the array are 22 18 14 10 7 4 and my range is 6 to 12. I was thinking of creating a separate column with the AND function to simplify some steps but I can't make it work.
I am not sure what you are referring to when you say array, but if the array refers to cells:
{=MAX(IF(B18:G18<12,IF(B18:G18>6,B18:G18,0),0))}
Will give you the value between (6,12) which is highest in the range A1:A6.
Be sure to make the function an array wise function by using control + shift + enter.

copy only those rows whose string len is > 6 in b column cell values

is it possible to copy only those rows which has string length more than 6 characters and paste them to a new sheet? The task is I have to remove all the unwanted characters in the rows. the range is 2 to 4000 something like that
I was using looping and mid function to do that which i found on google because I found only looping solution to that on google, because I only need numbers in each cell of B column and remove all other character except &,/, ,,. Then after cleaning up all ce
lls in B column I need to check the number of digits in each row of B column and if it contains more than 6 it should be copied to new sheet and it may contain blank cells too in between
a b c
6451 1234567 somevalue
4563 12345 somevalue
3245 123456789 somevalue
2345 1234 somevalue
Now I have to copy the 1 and 3 rd row but not the other rows as length of string is less than 7. I have to check only the B column and copy the entire row if it has more than 6 digits
I think what your boss is trying to say (not very well, btw) about using variant arrays, etc. instead of worksheets is to keep it in VBA. Read in the data once and manipulate it within VBA instead of pasting and manipulating data on a worksheet to get the desired result. This of course extends to anything outside of making calls to Excel, not just variant arrays. Perhaps you are often looping through cells one by one and he is trying to say he'd prefer if you dumped a range into a variant array and worked on it inside of VBA instead.
Of course, the best method depends on the task on hand, in my opinion.
As for your row question, it's a little unclear what you're trying to do (try to be careful how you use the words 'row' 'cell' and 'column'). A row cannot have a 'string length' so I am assuming you mean cell. Please confirm.