Group on excel rows to a single cell by column id - excel

I have a question regarding excel.
I have two columns, column A has a number and B has country codes. I'm looking for a way to automatically go through 100's thousands of rows to group them so they look like the following...
Is this doable? I'm at a complete loss :(
THE END RESULT
6512 AG,AI,AW,BB,BL,BM,
6513 BQ,BS,BZ,CA,CR
STARTING POINT - column A & B
6512 AG
6512 AI
6512 AW
6512 BB
6512 BL
6512 BM
6513 BQ
6513 BS
6513 BZ
6513 CA
6513 CR

These solutions use a working column named Concatenated Results.
Assuming your data has a header (adjust formulas as required) and is located at B6:C34 (change as required) as in fig below.
Data sorted by ID:
Concatenated Results: Enter this formula in D7.
= CONCATENATE( C7, IF( EXACT( B7, B8 ), "," & D8, "" ) )
ID.Unique: Enter this Array Formula in E7 (FormulaArrays are entered pressing CTRL+SHIFT+ENTER simultaneously, you shall see { and } around the formula if entered correctly)
=IFERROR( INDEX( $B$7:$B$34,
MATCH( 0, COUNTIF( $E6:$E$6, $B$7:$B$34 ), 0 ) * 1 ), "" )
Countries: Enter this formula in F7
=IFERROR(VLOOKUP(E7,$B$6:$J$34,3,0),"")
Copy range D7:F7 till last row of data (i.e. row 34).
Data not sorted: If the data is not sorted enter this formula for the Concatenated Results in D7. All other formulas remain unchanged.
=CONCATENATE( C7,
IF( ISERROR( MATCH( B7, B8:B$35, 0 ) ), "",
"," & VLOOKUP( B7, B8:D$35, 3, 0 ) ) )
Suggest to read the following pages to gain a deeper understanding of the resources used:
Excel functions (alphabetical), Create an array formula, Guidelines and examples of array formulas

Try this out and let me know in case of any queries or if you require detailed explanation.
Step1: Filter the data by column A.
Step2: Make a new column C where use this formula IF(A2=A1,CONCATENATE(B2,",",C1),B2) .
Step3: Make a new column D where use this formula IF(A2=A3," ","REQUIRED_ANS") .
Step4: Filter on column D using ALT + D + F + F and you get you desired output.
My Output:

This is a VBA solution
Assuming your data, excluding header, is located at B7:C34 (change as required).
ID.Unique: Enter this Array Formula in E7 (FormulaArrays are entered pressing CTRL+SHIFT+ENTER simultaneously, you shall see { and } around the formula if entered correctly)
=IFERROR( INDEX( $B$7:$B$34,
MATCH( 0, COUNTIF( $E6:$E$6, $B$7:$B$34 ), 0 ) * 1 ), "" )
Countries: Enter this User Defined Function (UDF) in F7
=Match_Concatenated(E7,$B$7:$C$34)
Copy this UDF code in a VBA Module
Option Explicit
Public Function Match_Concatenated(vValue As Variant, rTrg As Range) As String
Dim sOutput As String
Dim vTrg As Variant, vItm As Variant, lRow As Long
vTrg = rTrg.Value2
For lRow = 1 To UBound(vTrg)
vItm = WorksheetFunction.Index(vTrg, lRow, 0)
If vItm(1) = vValue Then sOutput = sOutput & Chr(44) & vItm(2)
Next
sOutput = Replace(sOutput, Chr(44), vbNullString, 1, 1)
Match_Concatenated = sOutput
End Function
Suggest to read the following pages to gain a deeper understanding of the resources used:
Excel functions (alphabetical),
Create an array formula,
Guidelines and examples of array formulas,
Option Explicit Statement,
Range.Value2 Property (Excel), For...Next Statement,
WorksheetFunction Object (Excel), INDEX function,
If...Then...Else Statement, Replace Function

Related

Excel extract distinct values from multiple columns

I want to extract distinct values from multiple columns.
Example described below :
I have to columns A and B and the desired result is the distinct values between A and B
Use UNIQUE(FILTER()):
=UNIQUE(FILTER(A:B,(A:A<>"")*(B:B<>"")))
Assuming your data is located at [B4:C16] enter this FormulaArray in [E4] then copy to [F4] and [E5:F16]:
= IFERROR( INDEX( B$4:B$16,
MATCH( 1, 1 +
COUNTIFS( $E$3:$E3, $B$4:$B$16, $F$3:$F3, $C$4:$C$16 )
+ ( $B$4:$B$16 = "" ) + ( $C$4:$C$16 = "" ), 0 ) ), "" )
FormulaArray is entered holding down ctrl+shift+enter simultaneously, the formula would be wrapped within { and } if entered correctly.
In Excel 2007, you can use the Advanced Filter
Provide header columns for your data.
I used Country and Year
Set up your criteria range:
A21: Country
A22: <>
B21: Year
B22: <>
Select a cell in your Data range and choose Advanced Filter on the Data tab
In the Advanced Filter dialog
Select Copy to and enter a destination cell in the appropriate area.
Select Unique

Vlookup to fetch adjacent value based on earliest date

I need help to write a code to return values for DF using the ID in the lookup table to fetch value that correspond to the latest date where there are duplications
Try a array formula, copy below formula and paste in cell B14 (i'm considering that "DATABASE" are in A1), and press Ctrl + Shift + Enter.
=INDEX(
$D$3:$D$8,
MATCH(
$A14 &
":" &
MAX(
IF(
$A14 = $A$3:$A$8,
$E$3:$E$8,
0
)
),
$A$3:$A$8 &
":" &
$E$3:$E$8,
0
)
)

Use a Text Based Formula from one cell as the actual formula in another [duplicate]

I have 0,4*A1 in a cell (as a string). How can convert this "string formula" into a real formula and calculate its value, in another cell?
Evaluate might suit:
http://www.mrexcel.com/forum/showthread.php?t=62067
Function Eval(Ref As String)
Application.Volatile
Eval = Evaluate(Ref)
End Function
I concatenated my formula as normal, but at the start I had '= instead of =.
Then I copy and paste as text to where I need it. Then I highlight the section saved as text and press ctrl + H to find and replace.
I replace '= with = and all of my functions are active.
It's a few steps, but it avoids VBA.
UPDATE This used to work (in 2007, I believe), but does not in Excel 2013.
EXCEL 2013:
This isn't quite the same, but if it's possible to put 0.4 in one cell (B1, say), and the text value A1 in another cell (C1, say), in cell D1, you can use =B1*INDIRECT(C1), which results in the calculation of 0.4 * A1's value.
So, if A1 = 10, you'd get 0.4*10 = 4 in cell D1. I'll update again if I can find a better 2013 solution, and sorry the Microsoft destroyed the original functionality of INDIRECT!
EXCEL 2007 version:
For a non-VBA solution, use the INDIRECT formula. It takes a string as an argument and converts it to a cell reference.
For example, =0.4*INDIRECT("A1") will return the value of 0.4 * the value that's in cell A1 of that worksheet.
If cell A1 was, say, 10, then =0.4*INDIRECT("A1") would return 4.
Just for fun, I found an interesting article here, to use a somehow hidden evaluate function that does exist in Excel. The trick is to assign it to a name, and use the name in your cells, because EVALUATE() would give you an error msg if used directly in a cell. I tried and it works! You can use it with a relative name, if you want to copy accross rows if a sheet.
I prefer the VBA-solution for professional solutions.
With the replace-procedure part in the question
search and replace WHOLE WORDS ONLY, I use the following VBA-procedure:
''
' Evaluate Formula-Text in Excel
'
Function wm_Eval(myFormula As String, ParamArray variablesAndValues() As Variant) As Variant
Dim i As Long
'
' replace strings by values
'
For i = LBound(variablesAndValues) To UBound(variablesAndValues) Step 2
myFormula = RegExpReplaceWord(myFormula, variablesAndValues(i), variablesAndValues(i + 1))
Next
'
' internationalisation
'
myFormula = Replace(myFormula, Application.ThousandsSeparator, "")
myFormula = Replace(myFormula, Application.DecimalSeparator, ".")
myFormula = Replace(myFormula, Application.International(xlListSeparator), ",")
'
' return value
'
wm_Eval = Application.Evaluate(myFormula)
End Function
''
' Replace Whole Word
'
' Purpose : replace [strFind] with [strReplace] in [strSource]
' Comment : [strFind] can be plain text or a regexp pattern;
' all occurences of [strFind] are replaced
Public Function RegExpReplaceWord(ByVal strSource As String, _
ByVal strFind As String, _
ByVal strReplace As String) As String
' early binding requires reference to Microsoft VBScript
' Regular Expressions:
' with late binding, no reference needed:
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Global = True
're.IgnoreCase = True ' <-- case insensitve
re.Pattern = "\b" & strFind & "\b"
RegExpReplaceWord = re.Replace(strSource, strReplace)
Set re = Nothing
End Function
Usage of the procedure in an excel sheet looks like:
In my opinion the best solutions is in this link:
http://www.myonlinetraininghub.com/excel-factor-12-secret-evaluate-function
Here is a summary:
In cell A1 enter 1,
In cell A2 enter 2,
In cell A3 enter +,
Create a named range, with =Evaluate(A1 & A3 & A2) in the refers to field while creating the named range. Let's call this named range "testEval",
In cell A4 enter =testEval,
Cell A4 should have the value 3 in it.
Notes:
a) Requires no programming/VBA.
b) I did this in Excel 2013 and it works.
Say, let we have column E filled by formulas that returns string, like:
= " = " & D7
where D7 cell consist more complicated formula, that composes final desired result, say:
= 3.02 * 1024 * 1024 * 1024
And so in all huge qty of rows that are.
When rows are a little - it just enough to copy desired cells as values (by RMB)
to nearest column, say G, and press F2 with following Enter in each of rows.
However, in case of huge qty of rows it's impossible ...
So, No VBA. No extra formulas. No F&R
No mistakes, no typo, but stupid mechanical actions instead only,
Like on a Ford conveyor. And in just a few seconds only:
[Assume, all of involved columns are in "General" format.]
Open Notepad++
Select entire column D
Ctrl+C
Ctrl+V in NPP
Ctrl+A in NPP
Select cell in the first row of desired column G1
Ctrl+V
Enjoy :)
.
Excel 2019 here. EVALUATE isn't valid.
It would work if we created a Named Range out of it:
But in this case we provide an absolute reference, which is not nice:
We would have to modify the formula every time we want to reuse it.
When the value in A1 changes, the evaluated result would not change.
Solution:
=EVALUATE(GET.CELL(5,OFFSET(INDIRECT("RC",FALSE),0,-1)))
The best, non-VBA, way to do this is using the TEXT formula. It takes a string as an argument and converts it to a value.
For example, =TEXT ("0.4*A1",'##') will return the value of 0.4 * the value that's in cell A1 of that worksheet.

How to automatically fill down by multiple?

I have a column of data that need to be filled. The formula should go like:
SUM(A10 + B10)
SUM A20 + B20
SUM A30 + B30
. .
. .
I have no idea on how to do the setup. Appreciate for any help :)
You're looking for the INDIRECT worksheet function. You need to nest it within the SUM function and you'll get what you're after. E.g. assuming you're in a cell in the very first row on a worksheet, you type:
=SUM(INDIRECT("A" & ROW()*10), INDIRECT("B" & ROW()*10))
One option is to use INDEX function here, it's not volatile like INDIRECT and will still work if you insert rows or columns, e.g. in cell C2 use this formula copied down
=SUM(INDEX(A$1:B$1000,ROWS(C$2:C2)*10,0))
.....or alternatively, this method will actually give you the formula =SUM(A10,B10) in the first cell and =SUM(A20,B20) in the next cell etc.
Put this formula in C2 and copy down as far as required
="=SUM(A"&ROWS(C$2:C2)*10&",B"&ROWS(C$2:C2)*10&")"
Select whole range > Right Click > Copy > Right Click > Paste Special > Values > OK > ENTER
That creates text versions of the required formulas - to convert to actual formulas do an "Edit/Replace" and replace = with =
Use =SUM(A10,B10) in the first cell and the drag the cell content to all the below cells if you want to fix a attribute like column number than put a $ symbol in front of it eg =SUM($A10,$B10). Similarly, for rows use =SUM(A$10,B$10).
I would probably do something like this, only because I prefer VBA.
Sub FillSheet()
Dim j, k
j = 10
k = 1
For j = 10 to 500 Step 10 '<<--Starts at 10, then 20, 30, etc up to 500
Worksheets("YourWorkSheetName").Range("A" & k).Formula = "=SUM(A" & j & ":B" & j & ")"
k = k +1
Next j
End Sub
Modify according to your requirements. Change "A" if want the formula in another column. Change "500" to however many lines you need.

How can I pull hashtags out of a text column?

I have an Excel sheet in which there is a "description" column. The values in this column often contain anywhere from 0-3 tags, all starting with the # symbol. Is there a way to pull all of these tags out in to columns?
Perhaps just have 3 blank columns called hashtag 1, 2, 3 and pull them in to each column.
It isn't even important that it remove them from the description column while pulling them out.
Example of descriptions:
"#0034 #lost client lost file" - pull out 0034 and lost
"worker has bad quality #SusanB #quality" - pull out SusanB and quality
"#0840 client complaint" - pull out 0840
"lots of ipsum" - pull out nothing
Lets say Column A is Description column, and in A2 you have the first cell with hashtags
In B2 enter:
=MID(A2;(FIND("#";A2))+1;(FIND(" ";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))-(FIND("#";A2))-1)
In C2 enter:
=MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;(FIND(" ";MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))+(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2))))-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))-1)
In D2 enter:
=MID(A2;(FIND("#";MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))+(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2))))+1;(FIND(" ";MID(A2;(FIND("#";MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))+(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2))))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))+(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2))))))+(FIND("#";MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))+(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))-(FIND("#";MID(A2;(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))+1;LEN(A2)-(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2)))))+(FIND("#";MID(A2;(FIND("#";A2))+1;LEN(A2)-(FIND("#";A2))))+(FIND("#";A2))))-1)
I'm fond of an extension that can let you use REGEX in Excel ...
Without this :
1) find the position of the separator character (# ?) in your string with FIND()
2) then use LEFT(), MID() and RIGHT() to explode your string into 3 columns
3) you can delete the # using MID() instead of LEFT() and RIGHT()
--
It would be something like this for the first tag with the # :
=LEFT(A1,FIND("#",A1)-1)
--
Hope this will help !
This can always be done using regular expression.
In VBE, write following function in a module:
Function getHashTags(rng As Range) As Variant
Dim regEx As RegExp
Set regEx = New RegExp
regEx.Pattern = "#\w*\b"
regEx.IgnoreCase = True
regEx.Global = True
Set myMatches = regEx.Execute(rng.Value)
Dim arr(1 To 1, 1 To 3) As Variant
For i = 1 To 3
If i > myMatches.Count Then
arr(1, i) = ""
Else
arr(1, i) = Replace(myMatches(i - 1), "#", "")
End If
Next i
getHashTags = arr
End Function
Now, let's suppose Column A is the Description column, and in cell A2 you have the first cell with hash tags.
In cell B2 enter this:
=getHashTags(B$2)
Now select the cells B2, C2, D2, Press F2 and then ctrl+shift+enter. This will populate the variant return from the function getHashTags to the selected cells.
I hope this helps.
PS: And, yes for this to work you also need to give reference to Microsoft VBScript Regular Expressions 5.5 library.

Resources