Comparing similar words in two different columns - excel

I have list of different categories in same dataset in two different columns.
Example data how the comparison should be:
There are some similar words in the two columns. So by comparing the two columns the maximum matched wordings should be created in new column as shown in attached image. Is their any formula that we can compare two columns.
I tried to use vlookup the cases but in that only full matched columns are joining. I need matching words to join

This VBA solution kind of works I guess but is definitely not 100% reliable:
Sub matchWords()
Dim arr() As Variant, rng As Range
Set rng = Range("data")
arr = rng
Dim val1 As String, val2 As String
For i = LBound(arr) To UBound(arr)
arr(i, 3) = ""
For j = LBound(arr) To UBound(arr)
val1 = LCase(arr(i, 2))
val2 = LCase(Left(Replace(arr(j, 1), " ", ""), Int(Len(Replace(arr(j, 1), " ", "")) * 0.7)))
If InStr(1, val1, val2) <> 0 Then
arr(i, 3) = arr(j, 1) & "?" & arr(i, 3)
End If
Next j
arr(i, 3) = Left(arr(i, 3), Len(arr(i, 3)) - 1)
Next i
rng = arr
End Sub
Tested on this table called "data". Sometimes, there is more than one match in which case both of them are put into the third column, separated by a question mark:
cat1
cat2
matchedCat1
anesthesiologist
professional. Accountants
accounting
appliances
nightlife.adultentertainment
adult entertainment
aircraft dealer
professional.advertising
advertising
airline
industry.agriculture
agriculture
animal shelter
auto.aircraftdealers
aircraft dealer
apartments
hotelstravel.transport.airlines
airline
airport
hotelstravel.airports
airport
alternative medicine
hotelstravel.airports.airportterminals
airport terminal?airport
amusement park
health.physicians.allergist
allergist
airport terminal
health.alternativemedicine
alternative medicine
allergist
active.amusementparks
amusement park
accounting
health.physicians.anesthesiologists
anesthesiologist
advertising
pets.animalshelters
animal shelter
agriculture
realestate.apartments
apartments
adult entertainment
shopping.homeandgarden.appliances
appliances
*just in case any moderator comes across this: The reason the table looks like this is because SO will not allow me to post it without each of the entries formatted as code. This "feature" seriously needs to either be fixed or done away with completely.

Related

VLOOKUP with multiple parameters?

Novice user here, so please bear with me. I am pretty decent with VLOOKUP, but that is about where my expertise ends.
Sheet1 is my active sheet which I am working on.
Sheet2 is my source data.
This sheet contains thousands of lines of client data over the span of the last 6 months.
Each client will currently have anywhere between 1 to 6 unique lines of data within the list (and growing), with the main difference for each client's line being a "date" (1 date per client each month), a "type" (i.e. Trail, Arrears) and a "$ amount".
There are a lot more column than I've mentioned above, so in my active sheet I have already used VLOOKUP to transfer the 3 main columns of data I am using, which are;
"Loan No", "Client Name", "Lender"
Duplicate rows, based on "Loan No" have also been removed. So, now each client just as 1 row.
What I am now trying to do, within each clients unique row, using the original source data, is populate the "$ amount" into a corresponding column, with a month heading, also based on the "Type" value
So basically
Within "Sheet1", look up Loan Number (cell A1) within "Sheet2"
Within "Sheet2", find the row that has both the matching "Loan Number" and matching "Date" (keeping in mind "Sheet1" only has the Month, whereas "Sheet2" has a full DD/MM/YYY)
If this row has a "Type" of "Trail" or "Arrears" (there are other Type fields I want to omit), then
Return the "Amount" to the cell the formula is entered into.
I know there may be multiple ways to do this, but I don't want to mess around with Pivots or anything like that, I also don't want to change the format of the source data. Basic formula is preferred as I am integrating some VBA functions using written formulas etc...
Any help would be greatly appreciated!
Simon
You'll need to adapt this across your worksheets but a SUMIFS should do it for you ...
This is the formula in cell K2 ...
=SUMIFS($F$2:$F$9,$A$2:$A$9,$H2,$D$2:$D$9,">=" & K$1,$D$2:$D$9,"<=" & EOMONTH(K$1,0))
Essentially, it's summing off your data with multiple criteria. You can add additional criteria as need be. The important thing to note here is the dates ...
K1 = 1/07/2021, formatted as ... mmmm ... it must be a date.
L1 = =EDATE(K1,1), formatted as ... mmmm
Make sure you fill across from K1 to N1.
To filter on the dates (i.e. using >= and <=) all fields need to be valid dates.
The dates are important, if they're not dates, then comparing dates (i.e. 1/01/2021) to the words (i.e. January) will not work.
Please, try the next code. It should be fast, using arrays and most of processing is done in memory. It returns in another sheet (shDest), I tested it to return in the next one:
Sub TransposeDataByLenderMonth()
Dim sh As Worksheet, shDest As Worksheet, lastR As Long, minD As Date, maxD As Date, arrD
Dim dict As Object, El, arr, arrFin, i As Long, k As Long, mtch, strD As String
Set sh = ActiveSheet 'use here the sheet you need
Set shDest = sh.Next 'use here the destination sheet (where the processing result to be returned)
'if next one is empty, the code can be used as it is
lastR = sh.Range("A" & sh.rows.Count).End(xlUp).row
minD = WorksheetFunction.min(sh.Range("D2:D" & lastR)) 'find first Date
maxD = WorksheetFunction.Max(sh.Range("D2:D" & lastR)) 'find last date
'create months arrays (one for months header and second to match the date):
arrD = GetMonthsIntArraysl(minD, maxD)
arr = sh.Range("A2:F" & lastR).Value 'place the whole range in an array, for faster iteration
'Extract unique keys by LoanNo:
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(arr)
dict(arr(i, 1)) = Empty
Next i
ReDim arrFin(1 To dict.Count + 1, 1 To UBound(arrD(1)) + 4): k = 1
'Place the header in the final array:
arrFin(1, 1) = "LoanNo": arrFin(1, 2) = "Client Name": arrFin(1, 3) = "Lender"
For i = 1 To UBound(arrD(0))
arrFin(1, 4 + i) = CStr(arrD(0)(i, 1))
Next i
k = 2 'reinitialize k to load values after the header
For Each El In dict.Keys 'iterate between the unique elements:
For i = 1 To UBound(arr) 'iterate between the main array rows:
If arr(i, 1) = El Then 'when a match is found:
arrFin(k, 1) = arr(i, 1): arrFin(k, 2) = arr(i, 2): arrFin(k, 3) = arr(i, 3)
strD = CStr(Format(DateSerial(Year(arr(i, 4)), month(arr(i, 4)), 1), "dd/mm/yyyy"))
mtch = Application.match(Replace(strD, ".", "/"), arrD(1), True)
arrFin(k, 4 + mtch) = arr(i, 6) + arrFin(k, 4 + mtch) 'add the value of the appropriate month
End If
Next i
k = k + 1
Next El
'Format a little and drop the processed array content:
With sh.Range("J1").Resize(1, UBound(arrFin, 2))
.NumberFormat = "#"
.BorderAround 1, xlMedium
End With
With sh.Range("J1").Resize(UBound(arrFin), UBound(arrFin, 2))
.Value = arrFin
.EntireColumn.AutoFit
.BorderAround 1, xlMedium
.Borders(xlInsideVertical).Weight = xlThin
End With
MsgBox "Job done..."
End Sub
'The following function returns an array of two arrays.
'One for header and the other for matching the date columns (in the final array)
Private Function GetMonthsIntArraysl(startDate As Date, endDate As Date) As Variant
Dim monthsNo As Long, rows As String, monthsInt, dd As Long, arrStr, arrD
monthsNo = DateDiff("m", startDate, endDate, vbMonday)
rows = month(startDate) & ":" & monthsNo + month(startDate)
arrStr = Evaluate("Text(Date(" & Year(startDate) & ",row(" & rows & "),1),""mmmm YYYY"")")
arrD = Evaluate("Text(Date(" & Year(startDate) & ",row(" & rows & "),1),""dd/mm/yyyy"")")
GetMonthsIntArraysl = Array(arrStr, arrD)
End Function
The above code adds all values for dates belonging to the same months/Client, if the case...
I took your question like a challenge, but you must learn that, in order to receive a solution, you must make some research by your own and show us a piece of code. Please, take it as a favor and next time place a better question, complying to the community rules, from the above mentioned point of view.

Excel VBA - N number of Random records per unique group

I am working on developing a system health check tool to validate that 4 different systems are in sync. To do that, I need to create a sample dataset of random N number of records for every unique key/combination from a main data set everyday. All 4 systems will be checked for records from this sample dataset and any differences will be highlighted using conditional formatting.
I am having trouble figuring out how to extract the sample dataset from the main dataset with the criteria mentioned above.
For Example, I have a report that has 700 rows. Each unique combination (concatenation to create a key) of the 6 fields [Client-Contractor-Distribution Center-Service Level-Alert Value-Status] has 100 records. This part will be dynamic. There could be any number of unique combinations and any number of records per combination. Image below for reference. Only the groups are shown here as I cannot paste 700 records in the question. There are 7 unique groups with 100 records each.
There are some questions in the comments for which I am giving the clarifications below:
-Combination/Group = Basically a key created with concatenation of the focus columns to recognize/define a category the records may belong to. As example concating First Name & Last Name to create a unique identity of a person.
All records will be on a single sheet. It is a report downloaded from a system.
Sequence of the records of each grouping: All records of a particular group will not be bunched together. All records are dumped from the system on the report. We are creating the group/key by concating the focus columns.
Let's say I want 5 random records for each of the 7 GroupKeys. Essentially, I need a way to get 35 records that are randomly selected, 5 per unique combination.
A sample of the desired output is shown below.
I have tried using RAND() and RANDBETWEEN() formulas. I do get random records. But the problem is that I cannot ensure that I get 5 records per combination and sometimes duplicate records are returned as well. I am open to any method (VBA/Formulas) to achieve this.
This is a very complex problem for someone like me who is only a novice/beginner at VBA at most.
Please, test the next code. It needs a reference to 'Microsoft Scripting Runtime':
Sub RandomRecPerGroup()
Dim sh As Worksheet, shRet As Worksheet, lastR As Long, dict As New Scripting.Dictionary
Dim arr, arrIt, i As Long, j As Long, f As Long, k As Long, count As Long, arrFin
Set sh = ActiveSheet 'use here the sheet you need
Set shRet = sh.Next 'use here the sheet you need (for testing reason, the next against the active one)
shRet.Range("G1").EntireColumn.NumberFormat = "#" 'format the column to keep 'Reference number' as text
lastR = sh.Range("A" & sh.rows.count).End(xlUp).row 'last row
arr = sh.Range("A2:G" & lastR).Value ' place the range in an array for faster iteration
ReDim arrFin(1 To 5, 1 To 7): k = 1 'reDim the array to keep each group
For i = 1 To UBound(arr) 'iterate between the array elements:
'create a dictionary key if not already existing, with the number of the row as item:
If Not dict.Exists(arr(i, 1) & arr(i, 2) & arr(i, 3) & arr(i, 4) & arr(i, 5) & arr(i, 6)) Then
dict.Add arr(i, 1) & arr(i, 2) & arr(i, 3) & arr(i, 4) & arr(i, 5) & arr(i, 6), i
Else 'adding the number of row, separated by "|"
dict(arr(i, 1) & arr(i, 2) & arr(i, 3) & arr(i, 4) & arr(i, 5) & arr(i, 6)) = _
dict(arr(i, 1) & arr(i, 2) & arr(i, 3) & arr(i, 4) & arr(i, 5) & arr(i, 6)) & "|" & i
End If
Next i
Dim rndNo As Long 'a variable to receive the random number
For i = 0 To dict.count - 1 'iterate between the dictionary elements:
arrIt = Split(dict.items(i), "|"): ' split the item by "|" to obtain the same group existing rows
For k = 1 To 5 'iterate to extract the 5 necessary sample rows of each group
Randomize 'initialize the random numbers generation
If UBound(arrIt) = -1 Then Exit For 'for the case of less than 5 rows per group
rndNo = CLng(UBound(arrIt) * Rnd()) 'give a value to the variable keeping the random numbers
For f = 1 To 7 'iterating to place in the array all 7 columns value
arrFin(k, f) = arr(arrIt(rndNo), f)
Next f
arrIt = Filter(arrIt, arrIt(rndNo), False) 'eliminate the element just placed in an array, to avoid doubling
Next k
lastR = shRet.Range("A" & sh.rows.count).End(xlUp).row + 1 'last empty row of the sheet where the result is returned
shRet.Range("A" & lastR).Resize(5, 7).Value = arrFin 'drop the array content
Next i
MsgBox "Ready..."
End Sub
The code may work without the mentioned reference (using labe binding), but I think it should be good to benefit of intellisense suggestions. If it looks complicated to create it, please (firstly) run the next code which will add it automatically:
Sub addScrRunTimeRef()
'Add a reference to 'Microsoft Scripting Runtime':
'In case of error ('Programmatic access to Visual Basic Project not trusted'):
'Options->Trust Center->Trust Center Settings->Macro Settings->Developer Macro Settings->
' check "Trust access to the VBA project object model"
On Error Resume Next
Application.VBE.ActiveVBProject.References.AddFromFile "C:\Windows\SysWOW64\scrrun.dll"
If err.Number = 32813 Then
err.Clear: On Error GoTo 0
MsgBox "The reference already exists...": Exit Sub
Else
On Error GoTo 0
MsgBox """Microsoft Scripting Runtime"" reference added successfully..."
End If
End Sub
Saving the workbook will keep the reference. So, no need to run the code again...
So basically you have 700 possibilities, and you want to get 5 random values out of them, while you are sure that you don't have duplicates?
There are, basically, two ways to do this:
You make a resulting collection of random values, you use the random generator to generate numbers from 1 to 700, but before adding them to your collection, you verify if they are already present in your collection. Something like (pseudo-code):
Dim col_Result as Collection
Dim finished as Boolean = False;
Dim r as integer;
while (not finished){
r = ConvertToInt(Random(700)) + 1;
if not(col_Result.Contains(r))
then col_Result.Add(r);
finished = (col_Result.Count == 5);
}
You make a collection of all numbers from 1 to 700, and 5 times you retrieve a random value out of it, while subtracting that value from the collection. Something like (pseudo-code again):
Dim col_Values as Collection = (1, 2, ..., 700);
Dim col_Result as Collection;
Dim r as integer;
for (int i = 0; i < 5; i++){
r = ConvertToInt(Random(700));
col_Result.Add(r);
col_Values.Subtract(r);
}
When using this last approach, it is vital that subtracting a value from the collection shifts the other values: (1,2,3,4,5).Subtract(2) yields (1,3,4,5).

Recovering the data of a column of record of an Excel sheet in another sheet

I want to retrieve the data (registration numbers) of a column of record from an Excel sheet on another Excel sheet when the name columns are the same.
That is to say on the "Convocation" sheet there is
Matric Apellido Nombre Avión
12 Burrow Irving F15
42 Nelson Howard A10
18 Krings Jack F18
10 Mitaux-Maurouard Guy Rafale
And in the sheet "RECAP" I have
Apellido Nombre ...
Nelson Howard ...
Burrow Irving ...
Mitaux-Maurouard Guy
Krings Jack ...
Y me gustaría
Apellido Nombre ... Matric
Nelson Howard ... 42
Burrow Irving ... 12
Krings Jack ... 18
I tried :
Sub Test()
Dim i As Long
Dim arr As Variant
Dim Matriculas As New Scripting.Dictionary 'Need the Microsoft Scripting Runtime library in Tools-> References
'We store the sheet with everything in an array
With ThisWorkbook.Sheets("Convocation")
arr = .UsedRange.Value
End With
'We assume that the registration is in column A and surnames B and C
For i = 2 To UBound(arr)
If arr(i, 1) = vbNullString Then Exit For 'if we find empty values we leave the loop
If Not Matriculas.Exists(arr(i, 2) & arr(i, 3)) Then 'we check that the combo of surnames is not duplicated
Matriculas.Add arr(i, 2) & arr(i, 3), arr(i, 1) 'we keep in the dictionary the combo of surnames with their registration
Else 'If the person could have more than 1 license plate then:
Matriculas(arr(i, 2) & arr(i, 3)) = Matriculas(arr(i, 2) & arr(i, 3)) & ", " & arr(i, 1) 'we add the others separated by ","
End If
Next i
'We store the sheet with everything in an array
With ThisWorkbook.Sheets("RECAP")
arr = .UsedRange.Value
'We assume that the surnames are in columns A and B, and the registration in C
For i = 2 To UBound(arr)
If arr(i, 1) = vbNullString Then Exit For 'if we find empty values we leave the loop
arr(i, 3) = Matriculas(arr(i, 1) & arr(i, 2)) 'here we assign the registration stored in the dictionary according to surnames
Next i
.UsedRange.Value = arr 'we return the array to the sheet
End With
End Sub
But when I compile I have this error: Sub or Function undefined. I have put the code in Microsoft Excel Objects that contains all the sheets, in particular in ThisWorkbook.
Edit: I know my problem
My problem wasn't with the first line but with Ubond. When I get rid of it I don't have errors anymore. But they are necessary for the loops.
Data on CONVOCATION sheet is like:
And sheet RECAP is:
To get the number from field MAtric I've used an array formula:
=INDEX(Convocation!$A$2:$A$5;MATCH(A2&B2;Convocation!$B$2:$B$5&Convocation!$C$2:$C$5;0))
Because this is an array formula, it must be inserted with
CTRL+SHIFT+ENTER or it won't work!
NOTE: About your data, this formula will work as long as all Apellido and Nombre are different between rows. If at any moment you have 2 clients (2 rows) with same Apellido and Nombre then the formula won't work properly, because yoo would need a third field to differentiate both clientes between them (maybe a second Apellido).
Hope you can adapt this to your needs.
UPDATE: In case the formula finds nothing, it will throw an error, but you can trap it with an IFERROR, so the ideal formula would be:
=IFERROR(INDEX(Convocation!$A$2:$A$5;MATCH(A2&B2;Convocation!$B$2:$B$5&Convocation!$C$2:$C$5;0));"Not found!")
Because this is an array formula, it must be inserted with
CTRL+SHIFT+ENTER or it won't work!
UPDATE 2: You can download a sample here: https://drive.google.com/open?id=1kQ0boXYl7nvkTef62zVg9Jw7raOqgsuf

Text to columns - Uniform response with different numbers of Spaces

I have a spreadsheet where column A is a list of names. Some of these names have titles (e.g., Mr John Doe, Miss Jane Doe, Mrs Jane Bloggs, Cllr Joe Bloggs etc) some of the names do not (just Joe Doe, John Bloggs, Jane Doe etc). I've been asked to split the names into three columns - Title, First Name, Last Name.
When I try the simple "text to columns", it's fine where there is a title, but where there isn't one, the first name defaults to the title column.
Is there a way to have the data split into the correct cells, or is it going to be a lot of manual work for someone?
You can use VBA to accomplish this.
You will create two different arrays. The first one is your raw data (your single column) preArr(), and your new array that will be written back to the worksheet postArr() that has been dimensioned for three columns ReDim postArr(..., 1 To 3).
First, test if the string from preArr(i, 1) contains known salutations. If it does, then you will add the first split string to postArr(, 1) - otherwise you won't add anything to this column.
Side Note: You can add additional salutations to this line:
.Pattern = "^(?:MRS?|MS|MIS+|CLLR|DR)\.?\s"
This is a regular expression, but just add another | separator for additional checks. I combined MR and MRS into one group, the ? makes the S optional in case you were wondering.
Here is the full program:
Option Explicit
Sub splitOnNames()
Dim preArr(), postArr(), ws As Worksheet, preRng As Range
Set ws = Selection.Parent
Set preRng = Selection
preArr = preRng.Value
If UBound(preArr, 2) > 1 Then
MsgBox "This can only be done on a single column!", vbCritical
Exit Sub
End If
ReDim postArr(LBound(preArr) To UBound(preArr), 1 To 3)
Dim i As Long, x As Long, tmpArr
For i = LBound(preArr) To UBound(preArr)
If preArr(i, 1) <> "" Then
tmpArr = Split(preArr(i, 1))
If testSalutation(preArr(i, 1)) Then
postArr(i, 1) = tmpArr(0)
postArr(i, 2) = tmpArr(1)
For x = 2 To UBound(tmpArr) 'Some last names have two names
postArr(i, 3) = Trim(postArr(i, 3) & " " & tmpArr(x))
Next x
Else
postArr(i, 2) = tmpArr(0)
For x = 1 To UBound(tmpArr) 'Some last names have two names
postArr(i, 3) = Trim(postArr(i, 3) & " " & tmpArr(x))
Next x
End If
Erase tmpArr
End If
Next i
With preRng
Dim postRng As Range
Set postRng = ws.Range(ws.Cells(.Row, .Column), _
ws.Cells(.Rows.Count + .Row - 1, .Column + 2))
postRng.Value = postArr
End With
End Sub
Private Function testSalutation(ByVal testStr As String) As Boolean
With CreateObject("VBScript.RegExp")
.IgnoreCase = True
.Pattern = "^(?:MRS?|MS|MIS+|CLLR|DR)\.?\s"
testSalutation = .Test(testStr)
End With
End Function
See it Live:
If I have to do this, then I use the 'Text to columns'. After that I sort by third column.
Now all rows having only 2 values are one after the other listed. I mark the first column for all this rows, press 'Ctrl + or' or click the right mouse and select 'insert cells'. Then you will be asked if you like to shift down or right. Select shift right and a cells are arranged as you like to have it.

"Flatten" multiple rows containing different data but with a common reference into a single row

I've tried searching Stackoverflow and Google for an answer to this but haven't found it yet. I think part of my problem is I'm not sure what the keyword(s) for what I'm trying to do would be.
My data looks something like this:
ID Var1 Var2 Name
01 0001 0002 Bill
01 0001 0002 Jim
01 0001 0002 Sally
02 0003 0004 Sam
02 0003 0004 Kyle
You'll see that I have multiple rows with the same ID and same Var1 and Var2 but each row has a unique name. I want to "flatten" the rows so there is only a single row for each ID and each row has as many "Name" columns as are necessary to fit all of the data.
Like this:
ID Var1 Var2 Name1 Name2 Name3
01 0001 0002 Bill Jim Sally
02 0003 0004 Sam Kyle
Does anyone know how to do this or what it's called?
Thanks!
Update based on comments:
My data source is .csv file and I'm trying to manipulate it with Excel. Excel macros or VBA solutions would be best. Unfortunately my SQL is very elementary so learning to apply an SQL solution would be time-prohibitive.
Something like this is very quick using variant arrays and a dictionary object
The code dumps the output from A1:Dx to F1
Update: fixed name numerals
Sub ReCut()
Dim X
Dim Y
Dim C
Dim lngRow As Long
Dim lngCol As Collection
Dim lngCnt1 As Long
Dim lngCnt As Long
Dim objDic As Object
Set objDic = CreateObject("scripting.dictionary")
X = Range([a1], Cells(Rows.Count, "C").End(xlUp)).Value2
Y = X
ReDim Y(1 To UBound(Y), 1 To 100)
For lngCnt1 = 1 To (UBound(Y, 2) - 3)
Y(1, lngCnt1) = "Name" & lngCnt1
Next
For lngRow = 1 To UBound(X, 1)
If objDic.exists(X(lngRow, 1) & X(lngRow, 2) & X(lngRow, 3)) Then
'find first blank entry in relevant array row
C = Split(Join(Application.Index(Y, lngCnt), "| "), "|")
Y(lngCnt, Application.Match(" ", C, 0)) = X(lngRow, 4)
Else
lngCnt = lngCnt + 1
Y(lngCnt, 1) = X(lngRow, 1)
Y(lngCnt, 2) = X(lngRow, 2)
Y(lngCnt, 3) = X(lngRow, 3)
Y(lngCnt, 4) = X(lngRow, 4)
objDic.Add X(lngRow, 1) & X(lngRow, 2) & X(lngRow, 3), lngCnt
End If
Next
[f1].Resize(UBound(Y, 1), UBound(Y, 2)) = Y
End Sub
If you are going for a SQL request, you might take a look at triggers.
First, you need to loop through your data.
CREATE TRIGGER tg AFTER INSERT ON `myTable`
FOR EACH ROW
BEGIN
insert into myTable(MyNewName) values (Name);
END
;
Also you need to work with Alter Table in order to add a new column
ALTER TABLE myTable
ADD MyNewName VARCHAR
http://www.w3schools.com/sql/sql_alter.asp
And to make a comparison if Var1 already exists you do an IF-condition
IF previousrecord = nextrecord
BEGIN
ALTER TABLE myTable
ADD MyNewName VARCHAR
END
http://msdn.microsoft.com/fr-fr/library/ms182717.aspx
Now combine all of them with a trigger:
CREATE TRIGGER tg AFTER INSERT ON `myTable`
FOR EACH ROW
BEGIN
IF previousrecord = currentrecord // where at beginning previousrecord=firstrecord
BEGIN
ALTER TABLE myTable
ADD MyNewName VARCHAR // MyNewName you can create a variable that increases
// smth like $added=0 then increase it
insert into myTable(MyNewName) values (Name);
END
END
;
It is a supposition when you read the data from your input that it is sorted by ID. It's maybe not the final solution, but it is supposed to help you out.
Formula-only requires quite a lot of explanation but is merely a sequence of operations that individually are quite familiar to many:
Select your four columns (say A:D).
Data > Outline – Subtotal with At each change in: ID, Use function: Count, Add subtotal to: check all, check Replace current subtotals and Summary below data and OK.
Filter A:E and for ColumnA choose Text Filters, Contains C, OK.
Enter, in B5 =B4 and copy across to D5
In F5:
=IF(COLUMN()<6+$E5,OFFSET($E5,COLUMN()-6-$E5,),"")
Copy F5 across to say Z5 (further to the right if necessary).
Copy B5:D5 and F5:Z5 down to last grouped row.
Unfilter (select all).
Copy whole sheet and paste over the top with Paste Special, Values.
Remove All in Subtotal.
Filter ColumnA to select Grand Count and (Blanks) only.
Delete rows numbered in blue.
Delete ColumnA.
Drag D1 to E1 and append 1.
Drag E1 across to the right as far as required.
Delete ColumnD.

Resources