How to count differences between Cells - excel

I have VBA which comparing 2 cells. Each cell can contain between 1 and 3 different parameters ant parameters are trimmed by the "," comparison is made by simple double for loop(check code). Thing what i can't figure it out is that: How to modify code and get number of unique entries, example
cell 1 [music, art, science]; cell 2 [art, music]; When i run my for loops i get 2 matches(which is fine) but how to count number of unique words in this case should be 3.
I have tried to enter this part of code but its not working well num_possible = num_possible + 1
game_tags_parts = Split(Cells(11, 2), ",")
game_tags_parts_j = Split(Cells(11, j), ",")
num_matches = 0
num_possible = 0
For m = LBound(game_tags_parts) To UBound(game_tags_parts)
num_possible = num_possible + 1
For n = LBound(game_tags_parts_j) To UBound(game_tags_parts_j)
If Trim(game_tags_parts(m)) = Trim(game_tags_parts_j(n)) Then
num_matches = num_matches + 1
End If
Next n
Next m
Actual result should be number of unique words used in those cells, in some cases i get 3 matches, example cell 1 [scifi, space, star] cell 2 [star, space, scifi] and its in total 3 matches. Modification should provide me an number 3 as number of unique words used in both cells. Or in this case where i have cell 1 [art, music, science] and cell 2 [scifi, space, star] where program gives me 0 same words and modification should give me a number 6 as unique used words.

One easy way to get a unique count is to use a Dictionary object:
game_tags_parts = Split(Cells(11, 2), ",")
game_tags_parts_j = Split(Cells(11, j), ",")
Dim myDict As Object
Set myDict = CreateObject("Scripting.Dictionary")
For Each v In game_tags_parts
If Not myDict.Exists(v) Then myDict.Add v, v
Next v
For Each v In game_tags_parts_j
If Not myDict.Exists(v) Then myDict.Add v, v
Next v
MsgBox "unique count: " & myDict.Count

Related

Excel SUMPRODUCT Substring Match

I am using SUMPRODUCT to match a cell equaling one of many things.
Using the below formula, I am attempting to match the value 2147 (A single value from a column of many values) to the below variations of the number 2147:
=SUMPRODUCT( -- ("2147"=Table6[data])) > 0
Table6[data] Return Value
1 2147 TRUE
2 2147, 500 FALSE
3 2146-2148 FALSE
4 21475 FALSE
The first TRUE and last FALSE values are as expected (success), but I need the middle two to match TRUE (Identify the 2147 next to the , 500 and between the range 2146-2148.
This uses a custom function. If you use it, I suggest you give it a more meaningful name.
So you'd put this formula in B1 and copy down
=Match2(2147,A1)
In outline, the function checks if a hyphen exists (using Split) and if so, checks the desired value against the lower and upper limits.
If not, using Split again, we split by commas, and if any element of the resultant array equals our desired value we return TRUE.
Function Match2(d As Double, r As Range) As Boolean
Dim v As Variant, i As Long
v = Split(r, "-")
If UBound(v) = 1 Then
If Val(v(0)) <= d And Val(v(1)) >= d Then
Match2 = True
Else
Match2 = False
End If
'we could shorten the five lines above to
'Match2 = (Val(v(0)) <= d And Val(v(1)) >= d)
Else
v = Split(r, ",")
For i = LBound(v) To UBound(v)
If Val(v(i)) = d Then
Match2 = True
Exit Function
End If
Next i
Match2 = False
End If
End Function
Just for an an FYI, this is the formula:
=SUM(IF(ISNUMBER(SEARCH("-",TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(INDEX(XFD:XFD,1):INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+1,99)))),(2147 >= --LEFT(TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(INDEX(XFD:XFD,1):INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+1,99)),FIND("-",TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(INDEX(XFD:XFD,1):INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+1,99)))-1))*(2147<=--MID(TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(INDEX(XFD:XFD,1):INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+1,99)),FIND("-",TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(INDEX(XFD:XFD,1):INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+1,99)))+1,99)),--(2147 = --TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(INDEX(XFD:XFD,1):INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+1,99)))))>0
It is an array formula that needs to be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode.

Multiply two 100-Digit Numbers inside Excel Using Matrix

I want to multiply two 100-Digit Numbers In Excel using matrix. The issue in Excel is that after 15-digit, it shows only 0. So, the output also need to be in a Matrix.
1st Number: "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
2nd Number: "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
Output: "22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222217777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777778"
This may be what OP was after. I thought I would try a naive multiplication method to see how long it would take to run. The answer is less than a second for two 100-digit numbers. You have to select the output range (i.e. A3:GR3 for a 200-digit result) and enter the formula containing the input ranges as an array formula using CtrlShiftEnter e.g.
=Multiply(A1:CV1,A2:CV2)
for two 100-digit numbers.
The method is basically just a simulation of school maths long multiplication, except that the intermediate rows are not stored but immediately added to the answer thus saving a lot of space.
The utility of it is obviously not that it is a replacement for the Karatsuba method, but it is a simple verifiable method which could be used for one-off calculations.
Currently limited to multiplication of rows containing more than one cell (so if you wanted to multiply by a single digit number, would have to enter it as e.g. 09).
Start of numbers
Middle of numbers
End of numbers
Function Multiply(rng1 As Variant, rng2 As Variant)
Dim arr() As Integer
Dim arrLength, r1Length, r2Length, carry, product, digit As Integer
Dim tot, totDigit, totCarry As Integer
Dim v1, v2 As Variant
v1 = rng1
v2 = rng2
r1Length = UBound(v1, 2)
r2Length = UBound(v2, 2)
arrLength = r1Length + r2Length
' Declare 1D array with enough space
ReDim arr(1 To arrLength)
' Loop over digits in first number starting from right
For i = r1Length To 1 Step -1
carry = 0
totCarry = 0
' Loop over digits in second number starting from right
For j = r2Length To 1 Step -1
' Calculate next digit in intermediate values (i.e. one row of long multiplication)
product = v1(1, i) * v2(1, j) + carry
digit = product Mod 10
carry = Int(product / 10)
' Calculate next digit in final values (i.e. totals line of long multiplication)
tot = arr(i + j) + digit + totCarry
arr(i + j) = tot Mod 10
totCarry = Int(tot / 10)
Next j
' Process final carry
arr(i) = carry + totCarry
Next i
' Return as an array
Multiply = arr
End Function
OK it might work like this:-
(1) You need to concatenate your numbers into a string because that's what you need as the input to your function. Native Excel won't do concatenation on arrays so you need a UDF like this one. So B2 contains
=concat(D1:G1)
(2) The output from the function is a string so you need to split it back into separate cells. You could use another UDF or a formula like this one copied across:-
=IF(COLUMNS($C3:C3)>LEN($B$3),"",VALUE(MID($B3,COLUMNS($C3:C3),1)))
So for the simple example it would look like this:-
But I might have got the wrong end of the stick completely.
Place your arrays into A1:A100 and B1:B100, then use three formulas:
1) In C2:C200 enter this as an array formula:
=MMULT(IFERROR(INDEX(A1:A100*TRANSPOSE(B1:B100),(ROW(INDIRECT("1:"&ROWS(A1:A100)*2-1))>0)+TRANSPOSE(ROW(INDIRECT("1:"&ROWS(A1:A100))))-1,MOD(ROW(INDIRECT("1:"&ROWS(A1:A100)*2-1))-TRANSPOSE(ROW(INDIRECT("1:"&ROWS(A1:A100)))),ROWS(A1:A100)*2-1)+1),0),SIGN(A1:A100+1))
2) In D1 enter =C1+INT(D2/10) and fill down to D200.
3) In E1 enter =MOD(D1,10) and fill down to D200.
E1:E200 will contain the answer.

Names having same ID should come in one cell

I have different ids for for different names in excel. Many names having the the same ids. How to get all the names having same id in one cell correspondingly. I need formula. Please help me out
Is this what you're looking for? It'd have been nicer if you had shown your progress so far, but hope to be of help like this.
Option Explicit
Sub Concatenate_Names()
Dim a As Integer
Dim i As Integer
Dim x As Integer
i = 1
x = *[number of items in your list]*
For a = 1 To *[number of unique values in a separate list]*
i = 1
Do While i <= x
'The cell references should be dependent on where your unique value list is,
'as well as where the full list is.
'"a" for the unique values, "i" for the full list - matching IDs
If Cells(a, 8).Value = Cells(i, 1).Value Then
'"a" for the unique values, "i" for the full list - appending names
Cells(a, 9).Value = Cells(a, 9).Value & Cells(i, 2).Value
End If
i = i + 1
Loop
Next
End Sub
If you want to avoid the VBA aproach, you still can use recursive functions :
Add column to store a semantic representation with key / values, in my example, the representation schema is : #Key1:Value11[;Value12...][#Key2:Value21[;Value22...]...]
The formula bellow recursively builds such a representation, the last row will contain the complete representation of pairs key / values :
=IF(IFERROR(FIND("#"&A2&":";C1);-1)=-1;C1&"#"&A2&":"&B2;IF(IFERROR(FIND("#";C1;FIND("#"&A2&":";C1)+1);-2) = -2;LEFT(C1;FIND("#";C1;FIND("#"&A2&":";C1)+1)-1)&";"&B2;LEFT(C1;FIND("#";C1;FIND("#"&A2&":";C1)+1)-1)&";"&B2&RIGHT(C1;LEN(C1)-FIND("#";C1;FIND("#";C1;FIND("#"&A2&":";C1)+1)) + 1)))
Add a second new column to retrieve values associeted to current row / key, the formula uses the last computed representation :
=IFERROR(LEFT(RIGHT(INDEX(C:C;MATCH(REPT("z";255);C:C));LEN(INDEX(C:C;MATCH(REPT("z";255);C:C)))-FIND("#"&A2;INDEX(C:C;MATCH(REPT("z";255);C:C)))-1-LEN(A2));FIND("#";RIGHT(INDEX(C:C;MATCH(REPT("z";255);C:C));LEN(INDEX(C:C;MATCH(REPT("z";255);C:C)))-FIND("#"&A2;INDEX(C:C;MATCH(REPT("z";255);C:C)))-1-LEN(A2));2)-1);RIGHT(INDEX(C:C;MATCH(REPT("z";255);C:C));LEN(INDEX(C:C;MATCH(REPT("z";255);C:C)))-FIND("#"&A2;INDEX(C:C;MATCH(REPT("z";255);C:C)))-1-LEN(A2)))
The result should look like this :
Key Value Representation Values
1 a #1:a a;e;i
2 b #1:a#2:b b;h
3 c #1:a#2:b#3:c c;j
1 e #1:a;e#2:b#3:c a;e;i
5 f #1:a;e#2:b#3:c#5:f f
6 g #1:a;e#2:b#3:c#5:f#6:g g
2 h #1:a;e#2:b;h#3:c#5:f#6:g b;h
1 i #1:a;e;i#2:b;h#3:c#5:f#6:g a;e;i
3 j #1:a;e;i#2:b;h#3:c;j#5:f#6:g c;j

Generate all possible combinations of a set of numbers in excel

How can I generate all possible combinations, in Excel, by using only 3, 6 and 9 in a 5 digit number? Naturally digits can repeat.
I am trying to learn more about EXCEL and this is something I cannot figure out - how to generate all possible combinations and see them instead of just having a number of possibilities.
I've looked through many forums, there's nothing I can use...
http://planetcalc.com/3756/?license=1 - This link is to an online generator, however there must be a mistake in its code since it doesn't show 5 digit numbers.
Just loop over the selections:
Sub Maja()
Dim K As Long
K = 1
vals = Array("3", "6", "9")
For Each a In vals
For Each b In vals
For Each c In vals
For Each d In vals
For Each e In vals
Cells(K, 1) = a & b & c & d & e
K = K + 1
Next e
Next d
Next c
Next b
Next a
MsgBox K
End Sub
A snap of the top of the list:
NOTE:
Technically, you would call these permutations rather than combinations because values like 33363 and 33336 both appear in the list as they represent different numerical values.

Combination Generator yet keep in order

Wondering if anyone could help me. I'm stumped. It's been ages since I used excel....
I have 9 columns with different values in each cell, different numbers of cells per column.
I need a formula/macro to spit out all combinations of the cells and yet still remain in the exact same order of the columns.
For example
Columns:
D / 003 / 23 / 3 / 3R / C / VFX
... / 005 / 48 / 3 / 12 / .. / VDF
... / 007 / ... / 1 / ... /... / HSF
And it spits out like this:
D0032333RCVFX
D0032333RCVDF
D0032333RCHSF
D0034833RCVFX
D0034833RCVDF
and so on....
and so on.....
Presumably you will want to call this function with a "serial number" - so that you can call "the Nth combination". The problem then breaks into two parts:
Part 1: figure out, for a given "serial number", which element of each column you need. If you had the same number of elements E in each column it would be simple: it's like writing N in base E. When the number of elements in each column is different, it's a little bit trickier - something like this:
Option Base 1
Option Explicit
Function combinationNo(r As Range, serialNumber As Integer)
' find the number of entries in each column in range r
' and pick the Nth combination - where serialNumber = 0
' gives the top row
' assumes not all columns are same length
' but are filled starting with the first row
Dim ePerRow()
Dim columnIndex As Integer
Dim totalElements As Integer
Dim i, col
Dim tempString As String
ReDim ePerRow(r.Columns.Count)
totalElements = 1
i = 0
For Each col In r.Columns
i = i + 1
ePerRow(i) = Application.WorksheetFunction.CountA(col)
totalElements = totalElements * ePerRow(i)
Next
If serialNumber >= totalElements Then
combinationNo = "Serial number too large"
Exit Function
End If
tempString = ""
For i = 1 To UBound(ePerRow)
totalElements = totalElements / ePerRow(i)
columnIndex = Int(serialNumber / totalElements)
tempString = tempString & r.Cells(columnIndex + 1, i).Value
serialNumber = serialNumber - columnIndex * totalElements
Next i
combinationNo = tempString
End Function
You call this function with the range where your columns are, and a serial number (starting at 0 for "top row only"). It assumes that any blank space is at the bottom of each column. Otherwise, it will return a string that is the concatenation of combinations of values in each column, just as you described.
EDIT perhaps the following picture, which shows how this is used and what it actually does, helps. Note that the first reference (to the table of columns of different length) is an absolute reference (using the $ sign, so when you copy it from one cell to another, it keeps referring to the same range) while the second parameter is relative (so it points to 0, 1, 2, 3 etc in turn).

Resources