I have an excel list of school courses that needs to be transposed/merged, the data looks like this
I want it to look like this
Is this possible without VBA?
With Office 365 we can use UNIQUE to get a list of unique Row Labels:
=UNIQUE(A2:A9)
With 2019 one would have to get the Unique list with:
=IFERROR(INDEX(A:A,AGGREGATE(15,7,ROW($A$2:$A$9)/(COUNTIF($E$1:E1,$A$2:$A$9)=0),1)),"")
Then use TEXTJOIN to do the concatenation:
=E2&" " &TEXTJOIN(", ",TRUE,FILTER(B:B,A:A=E2,""))
With 2016 use the formula for the unique list from 2019 and then use the method here: Outputting multiple VLookup values in Excel
To use a helper column then use:
=E2&" "&VLOOKUP(E2,A:C,3,FALSE)
to return the desired value:
With Excel 365. D2:
=INDEX(UNIQUE(A$2:A$8),ROW(A1))&" "&TEXTJOIN(", ",,FILTER(B:B,A:A=INDEX(UNIQUE(A$2:A$8),ROW(A1))))
or older version: Format Column A using this format text. E2:
=D2&SUBSTITUTE(PHONETIC(OFFSET(A$1,MATCH(D2,A:A,)-1,,COUNTIF(A:A,D2),2)),D2," ")
English is not my native language; please excuse typing errors.This is for your reference only.
Related
I have a set of data with this format:
Each cell has one or some names, each of them are followed by a date. I want to compare the dates which are presented in each cell and check whether they are the same or not.
Example of a cell content: university XXX (2016-10-21) company YYY (2016-10-22)
I used the formula: =MID(A1,SEARCH("(",A1,1)+1,10) to find the first date. how could I find 2nd, 3rd, ... dates?
Thank you in advance,
Easiest if done step by step:
So break down your MID(A1,SEARCH("(",A1,1)+1,10) (and make it more specific to dates - you don't want to match "(KACST)") as:
B1: =SEARCH("(2",A1,1) and H1: =mid(A1,B1+1,10)
Then add
C1: =SEARCH("(2",A1,B1+1) This tells the search to start from the character after the one it has already found
I1: =mid(A1,C1+1,10)
etc
If you have Office 365 (Windows), here's one way that should work, depending on the variability in your real data:
=LET(arr,--MID(FILTERXML("<t><s>" & SUBSTITUTE(A1," ","</s><s>") & "</s></t>","//s[contains(.,'(')]"),2,10),
numDates,COUNT(arr),
AGGREGATE(14,6,arr,SEQUENCE(numDates)))
create an XML
Use FILTERXML to return only nodes containing the (
Convert those nodes to a date serial number
Will => error if the 10 characters subsequent to the ( are not numeric
Return those values.
Then you can compare those values however you want
For example, if you wanted to see if all the dates were the same:
=COUNT(UNIQUE(
LET(arr,--MID(FILTERXML("<t><s>" & SUBSTITUTE(A1," ","</s><s>") & "</s></t>","//s[contains(.,'(')]"),2,10),
numDates,COUNT(arr),
AGGREGATE(14,6,arr,SEQUENCE(numDates)))))=1
If you don't have Office 365, or if your data is more varied than what you show, such that the method I used for determining if the parenthesized values are dates is not reliable, I suggest you develop a VBA solution, possibly using Regular Expressions.
I'm currently using excel 365 but need to make a spreadsheet compatible with 2019. I have a list of unique departments each with a specific volume of production. I need to create a dynamic filter for the bottom 5 producers, along with a vlookup alternative to get the values so I can graph them.
In excel 365 it's as simple as
Departments: =FILTER(Metrics!$B$2:$B$41,Metrics!$AL$2:$AL$41<E22)
Values: =IFERROR(VLOOKUP(D25#,Metrics!$B$2:$AM$41,37,FALSE),"")
The table goes from A1:A41 with row 1 being the headers.
I've tried using MIN and SMALL but can't figure out how to get more than one value. I'm open to but would prefer not to use VBA if I can help it.
For a function using SMALL, you'll have to use it in an array.
To do that, type out your formula, then instead of hitting enter like usual, press 'ctrl + shift + enter' to tell Excel to use an array. This will put {} around your formula to indicate it worked properly. From there just drag your formula down your desired amount of columns and should be good to go.
For example:
I want it to become:
This clearly has to be done dynamically.
In Office 365 you could create the required result in a different column/sheet with this formula: =A1:A11&IF(COUNTIF(OFFSET(A1,,,SEQUENCE(COUNTA(A1:A11),),),A1:A11)-1=0,"","_"&COUNTIF(OFFSET(A1,,,SEQUENCE(COUNTA(A1:A11),),),A1:A11)-1)
Or using LET:
=LET(data,A1:A11,
countif,COUNTIF(OFFSET(data,,,SEQUENCE(COUNTA(data))),data)-1,
data&IF(countif=0,"","_"&countif))
If you want the data replaced with the amended data you need a VBA solution
I am attempting to make Excel generate a 6-character password string, exactly like TeamViewer (3 letters, 3 numbers). Is there a function I might be unaware of?
I have tried =CHOOSE(RANDBETWEEN(1,2),CHAR(RANDBETWEEN(0,9)),CHAR(RANDBETWEEN(97,122)))&CHOOSE(RANDBETWEEN(1,2),CHAR(RANDBETWEEN(0,9)),CHAR(RANDBETWEEN(97,122)))&CHOOSE(RANDBETWEEN(1,2),CHAR(RANDBETWEEN(0,9)),CHAR(RANDBETWEEN(97,122)))&CHOOSE(RANDBETWEEN(1,2),CHAR(RANDBETWEEN(0,9)),CHAR(RANDBETWEEN(97,122)))&CHOOSE(RANDBETWEEN(1,2),CHAR(RANDBETWEEN(0,9)),CHAR(RANDBETWEEN(97,122)))&CHOOSE(RANDBETWEEN(1,2),CHAR(RANDBETWEEN(0,9)),CHAR(RANDBETWEEN(97,122))), and here's an example of one of the results: ckjfs.
Please see above for the Formula.
The expected result is something like: aaa111, or 1aaa11. I don't want the Formula to allow something like 11aaaa, aaaaaa, or 1234aa.
Here is an option for you to consider:
Formula in A2:
=RANDBETWEEN(1,6)
Formula in B2:
=CHAR(RANDBETWEEN(IF(OR(RANK.EQ(A2,$A$2:$A$7)+COUNTIF($A$2:A2,A2)-1={1,2,3}),48,97),IF(OR(RANK.EQ(A2,$A$2:$A$7)+COUNTIF($A$2:A2,A2)-1={1,2,3}),57,122)))
Drag down.....
Formula in D2:
Excel 2016 with CONCAT:
=CONCAT(C2:C7)
Lower versions without CONCAT:
=C2&C3&C4&C5&C6&C7
I can offer this rather long array formula:
=ArrayFormula(TEXTJOIN("",TRUE,IF(MID(TEXT(DEC2BIN(INDEX({7,11,13,14,19,21,22,25,26,28,35,37,38,41,42,44,49,50,52,56},RANDBETWEEN(1,20))),"000000"),{1,2,3,4,5,6},1)="0",
CHAR(CHOOSE({1,2,3,4,5,6},RANDBETWEEN(48,57),RANDBETWEEN(48,57),RANDBETWEEN(48,57),RANDBETWEEN(48,57),RANDBETWEEN(48,57),RANDBETWEEN(48,57))),
CHAR(CHOOSE({1,2,3,4,5,6},RANDBETWEEN(97,122),RANDBETWEEN(97,122),RANDBETWEEN(97,122),RANDBETWEEN(97,122),RANDBETWEEN(97,122),RANDBETWEEN(97,122))))))
I had to test it in Google Sheets because I only have an old version of Excel without the array concatenation features - it should work in later versions of Excel if you remove the ArrayFormula wrapper and enter it with Ctrl-Shift-Enter.
The idea is that there are only 20 ways of selecting 3 items (letters) out of 6 (letters and numbers) so choose one of them in binary (e.g. 010101) and generate letters where there are 1's and numbers where there are 0's.
EDIT
Confirmed working through Excel 2019, confirmed through CtrlShiftEnter:
I've created an Excel Userform to facilitate the data entry of new lines into a contract register. I have a field that auto-generates a new unique contract number by looking for the largest number in the list of contract numbers (Column A) and then adds 1. This formula works perfectly:
Me.tbContractNumber = Application.WorksheetFunction.Max(Sheet1.UsedRange.Columns(1)) + 1
I now have to add an IF criteria to filter out any contract numbers LESS Than "2018000". I have worked out how to do this in a normal Excel workbook using MAXIFS but apparently MAXIFS is not an available function in VBA?
Can someone suggest an equivalent VBA code to the below Excel formula? Thanking you in advance!
=MAXIFS(A2:A500,A2:A500,"<2018000")+1
EDIT Our work computers run 2010 and won't allow me to add the MS Office 16.0 Object Library so MAXIFS function will not work. I can get the following array formula to work but I have never used an array formula in VBA. Could someone please suggest an equivalent VBA code to the below Excel formula? Thanking you in advance!
{=MAX(IF(A:A<2018000,A:A)) +1}
If you're looking for the largest number anyway, do you need to filter out anything lower than 2018000? If you have at least one entry equal to/higher than 2018000, your end result will be higher regardless of the other entries.
I'm sure there are more efficient ways of doing it, but if you are happy with:
Me.tbContractNumber = Application.WorksheetFunction.Max(Sheet1.UsedRange.Columns(1)) + 1
then try:
me.tbContractNumber = Application.WorksheetFunction.MaxIfs(Sheet1.UsedRange.Columns(1), Sheet1.UsedRange.Columns(1), ">" & 2018000) + 1
...but apparently MAXIFS is not an available function in VBA. In VBA it is not present, but if you add the Excel 16.0 Object Library (second on the screenshot) to your project, you would be able to access it as follows:
Application.WorksheetFunction.MaxIfs 'Only in Excel
Excel.WorksheetFunction.MaxIfs 'Any host of VBA - Excel, Access, Word
The library is added by default, if you work in Excel. Concerning "translation" the working formula from Excel to VBA, check this:
https://stackoverflow.com/a/49363501/5448626
I just learned the Evaluate function! So equivalent of the array formula I want to use converts in VBA to:
Me.tbContractNumber = Evaluate("=MAX(IF(" & "A:A" & "<2018000," & "A:A" & "))+1")