Context: I'm working on creating a dynamic tool in Excel to append existing ID's from our donor database onto incoming recurring gifts that will be imported.
I'm using an Array formula with multiple criteria to try and match IDs from our database based on incoming data of dubious quality (due to custom user input).
Sample Content:
By request, here are headings with a sample row below. First from one sheet, and then from the next.
WISE_TRANSACTIONS_2
Date Type Transaction Amount Description Payment Type Payment Name Account Code Email First Name Name.1.2 Last Name Address 1 Address 2 City State Zip Country
7/31/2018 23:27 Sponsorship $48.00 Sponsorship for Beneficiary XX11 Debit / MasterCard Peter K Tular IND-0019793 petetee#icloud.com Peter K Tular 123 Fake St Los Angeles Ca. 90043 US
GIFT_ID_1
First Name Name.1.2 Last Name Gift Type Nickname Constituent ID Gift ID Gift Amount Preferred Address Line 1 Preferred City Preferred State Preferred ZIP E-Mail Number Fund ID
Peter Tular Recurring Gift 81435 9777445 $48.00 123 Fake St Los Angeles California 90043 petertee#me.com Sponsorship
Problem: My formula seems to not prioritize the first IF statement in a series of nested IF statements. This first IF is based on their email since that's likely the most unique identifier available from the import.
Sorry the copied formula text is grotesque because of my weird excel formatting. Let me know if you'd like this redone in some way from my end.
Full formula - doesn't give e-mail priority, but I think it should
{=INDEX(GIFT_ID_1[#All],
MATCH(1,
(GIFT_ID_1[[#All],[Gift Amount]]=WISE_TRANSACTIONS_2[#[Transaction Amount]])*
IF((LEFT(GIFT_ID_1[[#All],[E-Mail Number]],6)=LEFT(WISE_TRANSACTIONS_2[#Email],6)),
(LEFT(GIFT_ID_1[[#All],[E-Mail Number]],6)=LEFT(WISE_TRANSACTIONS_2[#Email],6)),
(IF((GIFT_ID_1[[#All],[Last Name]]=WISE_TRANSACTIONS_2[#[Last Name]]),
(GIFT_ID_1[[#All],[Last Name]]=WISE_TRANSACTIONS_2[#[Last Name]]),
IF((LEFT(GIFT_ID_1[[#All],[First Name]],6)=LEFT(WISE_TRANSACTIONS_2[#[Last Name]],6)),
(LEFT(GIFT_ID_1[[#All],[First Name]],6)=LEFT(WISE_TRANSACTIONS_2[#[Last Name]],6)),
IF((LEFT(GIFT_ID_1[[#All],[First Name]],6)=LEFT(WISE_TRANSACTIONS_2[#[First Name]],6)),
(LEFT(GIFT_ID_1[[#All],[First Name]],6)=LEFT(WISE_TRANSACTIONS_2[#[First Name]],6)),
(GIFT_ID_1[[#All],[Nickname]]=WISE_TRANSACTIONS_2[#[First Name]]))))*
(IF((LEFT(GIFT_ID_1[[#All],[Preferred Address Line 1]],6)=LEFT(WISE_TRANSACTIONS_2[#[Address 1]],6)),
(LEFT(GIFT_ID_1[[#All],[Preferred Address Line 1]],6)=LEFT(WISE_TRANSACTIONS_2[#[Address 1]],6)),
IF((GIFT_ID_1[[#All],[Preferred ZIP]]=WISE_TRANSACTIONS_2[#Zip]),
(GIFT_ID_1[[#All],[Preferred ZIP]]=WISE_TRANSACTIONS_2[#Zip]),
(GIFT_ID_1[[#All],[Preferred City]]=WISE_TRANSACTIONS_2[#City])))))),
0),6)}
Instead it's using something less ideal, and several steps further down the line, like first name.
If I strip out the entire IF section of the formula, the email match works perfectly.
Reduced formula:
{=INDEX(GIFT_ID_1[#All],
MATCH(1,
(GIFT_ID_1[[#All],[Gift Amount]]=WISE_TRANSACTIONS_2[#[Transaction Amount]])*
(LEFT(GIFT_ID_1[[#All],[E-Mail Number]],5)=LEFT(WISE_TRANSACTIONS_2[#Email],5)),
0),6)}
What am I missing here? This is about as deep as I've dived into Excel up to now, and my first post on here ever. Any help is appreciated!
It's not perfect yet, but I've got it working for the problem cases I was looking at.
I realized the Index Match was making it's way down the Array, simply seeing who the first entry was it came across that matched anything it needed to find.
Therefore even though I was searching using
Michael Hernando, $48.00, 477 Bowter Plant Dr, Apex, NC, 35779,
hernandos#gmail.com
This (with a different last name and unrelated email)
Michael Johnson, $48.00, 555 Nebraska Ave, Apex, NC, 35779, tomatoboy#aol.com
Was found before this
Michael Hernando, $48.00, 911 Maui Ct, Maggie Valley, NC, 35688,
hernandos#gmail.com
Because I allowed a worst case scenario where only the Transaction Amount, First Name and Zip or City all matched.
Basically, I needed to tighten up my requirements. A few changes I made:
E-mail now searches everything up to the # symbol. Because there are a few e-mail row's in my array's e-mail column that are empty, I had to throw in IFERROR to deal with #N/A results.
I figured a matching street address for 8 characters is a good indicator, so I put that on par with e-mail.
Alternatively, some semblance of matching First, Last and location is the backup method.
I also made simplified use of IF conditions after realizing we're just trying to get 1's and 0's.
The formula I went with was this
{=INDEX(GIFT_ID_1[#All],
MATCH(1,
(GIFT_ID_1[[#All],[Gift Amount]]=WISE_TRANSACTIONS_2[#[Transaction Amount]]) *
IF(IFERROR((LEFT(GIFT_ID_1[[#All],[E-Mail Number]],FIND("#",GIFT_ID_1[[#All],[E-Mail Number]])-1)=LEFT(WISE_TRANSACTIONS_2[#Email],FIND("#",WISE_TRANSACTIONS_2[#Email])-1)),0) +
(LEFT(GIFT_ID_1[[#All],[Preferred Address Line 1]],8)=LEFT(WISE_TRANSACTIONS_2[#[Address 1]],8)) +
(IF(IF((GIFT_ID_1[[#All],[Last Name]]=WISE_TRANSACTIONS_2[#[Last Name]]) +
(LEFT(GIFT_ID_1[[#All],[First Name]],6)=LEFT(WISE_TRANSACTIONS_2[#[Last Name]],6))
>0,1,0) *
IF(((LEFT(GIFT_ID_1[[#All],[First Name]],6)=LEFT(WISE_TRANSACTIONS_2[#[First Name]],6)) +
(GIFT_ID_1[[#All],[Nickname]]=WISE_TRANSACTIONS_2[#[First Name]]))
>0,1,0) *
IF(((LEFT(GIFT_ID_1[[#All],[Preferred Address Line 1]],6)=LEFT(WISE_TRANSACTIONS_2[#[Address 1]],6)) +
(GIFT_ID_1[[#All],[Preferred ZIP]]=WISE_TRANSACTIONS_2[#Zip]) +
(GIFT_ID_1[[#All],[Preferred City]]=WISE_TRANSACTIONS_2[#City]))
>0,1,0)
>0,1,0))
>0,1,0),
0),6)}
Related
Hi Stackoverflow Community,
This is my first post, apologies ahead if I haven't structured my question better, I'll try to improve on it later on.
I have a 2 excel columns with street address numbers and street address, none of which are unique hence using vlookup/index match is tricky.
I am trying to populate another column with the minimum and maximum value of the street address numbers using TEXTJOIN and it works, however I need the min/max for each specific street address group, there are close to 1 million lines of data.
For example, min=1, max=13, on florence st, min=3, max=53, on gibson st
Is such a formula helpful for you:
=MINIFS(B$2:B$10,A$2:A$10,"Ramsay street")
As you see, I take the minimum value of the "B" column, based on a criterion on the "A" column.
Hereby a screenshot of an example:
If you are on Excel 365 - current channel you can use this formula:
=LET(streetnamesUnique,UNIQUE(data[StreetName]),
minNumber,BYROW(streetnamesUnique,LAMBDA(s, MINIFS(data[Number],data[StreetName],s))),
maxNumber,BYROW(streetnamesUnique,LAMBDA(s, MAXIFS(data[Number],data[StreetName],s))),
HSTACK(streetnamesUnique,minNumber,maxNumber))
If on Excel 365 semi annual channel:
=LET(streetnamesUnique,UNIQUE(data[StreetName]),
minNumber,BYROW(streetnamesUnique,LAMBDA(s, MINIFS(data[Number],data[StreetName],s))),
maxNumber,BYROW(streetnamesUnique,LAMBDA(s, MAXIFS(data[Number],data[StreetName],s))),
MAKEARRAY(ROWS(streetnamesUnique),3,LAMBDA(r,c,
IF(c=1,INDEX(streetnamesUnique,r),
IF(c=2,INDEX(minNumber,r),
INDEX(maxNumber,r))))))
Both formulas first retrieve the unique streetnames - then retrieves, per each streetname min and max number.
In the end the new range is built from these values - either by HSTACK or MAKEARRAY.
I am trying to separate information copied from a PDF table - id usually use text to columns but the only delamination is spaces and this then splits the data into multiple unusable columns
The data comes like this:
Raw Data
A1 Company 0
Company2 40000
name a 1
name b 15
name c 184
Big 17 Company 1887
I need the output to be:
Company
Units
A1 Company
0
Company2
40000
name a
1
name b
15
name c
184
Big 17 Company
1887
So the company name (that might contain numbers) is separated for the unit number (that could be 1-5 digits long).
I haven't been able to figure out a way that uses =len() as the string length isn't a constant mixed with the last numbers not being a consistent number of digits.
I'm currently using:
=SUMPRODUCT(MID(0&A2, LARGE(INDEX(ISNUMBER(--MID(A2, ROW(INDIRECT("1:"&LEN(A2))), 1)) * ROW(INDIRECT("1:"&LEN(A2))), 0), ROW(INDIRECT("1:"&LEN(A2))))+1, 1) * 10^ROW(INDIRECT("1:"&LEN(A2)))/10)
This gives me all the numbers in the cell - which works for 90% of the data as most of the company's don't have numbers in their name. But for something like 'A1 Company 0' it gives 10 as the output not just the 0. I then go and manually edit the small number of companies that this happens too.
I then use a mixture of =LEN() =LEFT and =RIGHT to split the information up as required for the further automated analysis.
I'd prefer a formula over VBA/macro
I cant provide the actual data but I hope I've given enough examples in the table above to show the main problems (different company name lengths, companies with numbers in their name, different amount of digits representing the units)
Using Libre Office, but this formula checks for the last space in the cell
=RIGHT(A1,LEN(A1)-FIND("#",SUBSTITUTE(A1," ","#",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))),1))
Taken from: https://trumpexcel.com/find-characters-last-position/
FILTERXML() would best choice for this case. Try-
=FILTERXML("<t><s>"&SUBSTITUTE(A1:A6," ","</s><s>")&"</s></t>","//s[last()]")
Details about FILTERXML() from JvdV here.
See if the following works for you:
Formula in B2:
=LEFT(A2,LEN(A2)-1-LEN(C2))
In C2:
=-LOOKUP(1,-RIGHT(A2,ROW($1:$5)))
For those users using ms365's newest functions:
=HSTACK(TEXTBEFORE(A2," ",-1),TEXTAFTER(A2," ",-1))
I have exported updates from my help desk ticket tracking software into Excel. Each cell contains all updates made on a single ticket over the life of the ticket. Here is an example of a typical cell:
IM1234567;"4/20/16 15:31:01 US/Eastern (Smith John ABC DEF GHI): Some text about the status of the ticket. 04/13/16 23:53:06 (Doe Jane ABC DEF GHI): Some more text about the status."
The goal is to count each technician's name in the ticket if they have made an update to the ticket in the last month. I have all the technicians broken out into individual columns with each ticket in its own row. Here is an example:
Ticket Jane Doe John Smith James Adam Etc
IM1234567 1 0 0 0
IM1234568 0 1 0 0
IM1234569 0 0 1 0
Given how varied each ticket is I am not sure how to go about doing this. Some of the tickets are extremely long, and as they are free text fields punctuation and spelling are sometimes lacking.
Thanks for the support.
EDIT: Updated to handle 1- or 2-digit month and day.
EDIT2: Updated to automatically calculate how far ahead in the ticket to look for the name.
If you're ok with the name in the table being in last first format, this will work. Enter as an array formula (ctrl+shift+enter):
SUM(IF(ISNUMBER(VALUE(MID($A2,ROW(INDIRECT("1:"&LEN($A2))),1))),IF(ISNUMBER(VALUE(MID($A2,ROW(INDIRECT("1:"&LEN($A2)))-1,1))),0,IF(LEN(SUBSTITUTE(MID($A2,ROW(INDIRECT("1:"&LEN($A2))),8),"/",""))=6,IF(IFERROR(DATEVALUE(MID($A2,ROW(INDIRECT("1:"&LEN($A2))),8)),IFERROR(DATEVALUE(MID($A2,ROW(INDIRECT("1:"&LEN($A2))),7)),IFERROR(DATEVALUE(MID($A2,ROW(INDIRECT("1:"&LEN($A2))),6)),0)))>EDATE(TODAY(),-3),IF(IFERROR(FIND(" ("&C$1,MID($A2,ROW(INDIRECT("1:"&LEN($A2))),SEARCH(")",MID($A2,ROW(INDIRECT("1:"&LEN($A2)))+8,LEN($A2))))),0)>0,1,0),0),0)),0))
The formula =(LEN(<Insert Complete string ticket address here>)-LEN(SUBSTITUTE(<Insert Complete string ticket address here>,<Insert name or address here>,"")))/LEN(<Insert name or address here>) should do the trick.
Edit: To solve the lastname, firstname order issue, flip the names when you refer to them in your formula with: =MID(B1&" "&B1,FIND(" ",B1)+1,LEN(B1)).
So, in resume, place on B2:
=(LEN($A2)-LEN(SUBSTITUTE($A2,MID(B$1&" "&B$1,FIND(" ",B$1)+1,LEN(B$1)),"")))/LEN(MID(B$1&" "&B$1,FIND(" ",B$1)+1,LEN(B$1))) and drag it to the other cells.
Finally, for find the value you want (sorry for the late edit, I didn't read your question with much attention), try the following (on B2 cell):
{=SUM(IF(IFERROR(FIND(TEXT(NOW()-31;"m/yy");(FILTERXML("<t><s>" & SUBSTITUTE($A2; "."; "</s><s>") & "</s></t>"; "//s")));0)<>0;LEN((FILTERXML("<t><s>" & SUBSTITUTE($A2; "."; "</s><s>") & "</s></t>"; "//s")))-LEN(SUBSTITUTE((FILTERXML("<t><s>" & SUBSTITUTE($A2; "."; "</s><s>") & "</s></t>"; "//s"));MID(B$1&" "&B$1;FIND(" ";B$1)+1;LEN(B$1));"")))/LEN(MID(B$1&" "&B$1;FIND(" ";B$1)+1;LEN(B$1))))}
Please make sure:
First: you place the formula as an array (Ctrl+Shift+Enter) to enter the brackets;
Second: check the format display "m/yy" used in your country or in your Excel version.
I tested the formula on a similar file of my own and it worked.
I have an issue at the moment which I'm not able to resolve even with multiple combinations of If and Vlookups. I'm not doing this right.
I have a sheet which has the names of the products and an empty column for the Sl Number. The Sl number needs to be retrieved from Sheet 2 if it matches the value in the adjacent cell of the formula (This I know can be possible with Vlookup). However, I am trying to display the value even if the match is not exact. By that I mean if the product name has all the values as on the sheet 1 but also has additional information in brackets, then the value should still be displayed.
Sheet 1
Formula in A2 - A7 = "=VLOOKUP(B2, Sheet2!B:E, 2, 0)"
Sheet 2
The complete data
Is this possible?
Thanks in advance.
Apologies, I'm new here and not sure how this works. So trying to do the right thing but may take some time.
Thanks Frank and Tim. I have another extended question to this.
Is there a way to retrieve the value by ignoring text in brackets on the lookup cell itself?
For example:
Sheet 1
Sl Number Name
123454 Cream SPF 30+ 50g
**NA** Bar Chocolate 70g X 6 (Sample)
234256 Hand Wash 150ml
26786 Toothpaste - Whitening 110g
Sheet 2
ID Name Sl number Manufacturer Quantity
8 Collagen Essence 10ml 456788 AL 87
9 Hand Wash 150ml 234256 AD 23
10 Bar Chocolate 70g X 6 835424 AU 234
Row 2 on Sheet 1 has the name that includes (Sample) and the same product on sheet 2 does not contain the (Sample) for that product. Is there a way I can use lookup in the above scenario?
Thank you
Tim's comment
=VLOOKUP(B2 & "*", Sheet2!B:E, 2, 0) as long as the "Extra" info is tagged onto the end of the name, and none of your product names is a
substring of another product name. – Tim Williams 53 mins ago
Will get what you are looking for, as for getting rid of text between "(...)" use
=IFERROR(IF(FIND("(",A2),LEFT(A2,FIND("(",A2)-1),A2),A2)
To create a new column that will cut out anything that has parentheses "(...)" this presumes that all of your entries has the "(...)" at the end, i.e. far right side.
As you are new, I presume you might be interested in an explanation. I'll explain what Tim and I did. If I am incorrect, anyone is free to edit.
Based on your question, it would appear that you are familiar with Excel but not the site. This said, my understanding of the key difference between your attempt and Tim's was =VLOOKUP(B2 & "*", Sheet2!B:E, 2, 0) or specifically & "*". This introduces a Wildcard to the search parameter. So if you typed "Bob" but the actual reference was "Bob's Burger" That "*" would allow ['s Burger] to be included as part of the possible search given that you set vLookup to search for Approximate rather than exact matches. =VLOOKUP(B2 & "*", Sheet2!B:E, 2, 0) specifically , 0).
As for my part, IFERROR is effectively an catch-all for errors in IF functions. If there is a error, then X. In this case, if it does not find "(" in the cell, then it will throw an error. Since it is an error, display the original cell.
As for IF(FIND("(",A2),LEFT(A2,FIND("(",A2)-1),A2) It asks Excel to look for "(" in the cell A2, if it finds it, then it it counts from the LEFT until it finds the "(" and deletes the text one space to the left of the first "(". Thus removing the "(...)".
I have a free text column full of contact details. I want to extract realtion ship out of the contact details. I tried different formulas, but didnt work. Even I have added a column with relationship status and tried
=INDEX(D$2:D$5,MATCH(1,IF(ISERROR(SEARCH(D$2:D$5,A2)),0,1),0),1)
but it didnt work.
For ex:
Contact Details Column:
Matthew Brown: Wife: 937268475663 (home) or 939848399384 (mobile)
Bill Benoit: Father: 7494785736784
Spouse - Matha Nocon - 948479 289374
Mrs Elaine Batty: Wife: 29474567334
Iain Beveridge020 8877 3537
Janice Waddy01482 581000 Work 07986501322 Mobile
Tony Salter (Father)Tel: 0207 583 5000
Mrs Amanda Bluff - 01507 466198
Paula Washburn[Sister] - 87362 741895 [Home]
Cliff Potter (Husband) - 0263 88472363(Work)
I want an excle formula that searches relationship from ralationship status column inside the contact details column and extract relationship (wife, husband, etc.).
Hi Kaliakanhu Panigrahi,
You use array in your formula and you forgot put it on {}.
You can do it by pressing Ctrl + Shift + Enter when you are in the formula cell.
When I did this it works fine for me.