find and copy (multiple) values in column - excel

I have a simple table where I want to search column A for a value via A1:A10.
When it finds a value it should copy/paste it to the correspond ending cell in column B.
-Moreover it would be nice to search for multiple values like
"value1 value2 value3 and to copy all found values in A to B.
The output should be:
And for multiple values:
EDIT:
I had to replace the functions with german, but it won't work for me.
For B2 I added: =GLÄTTEN(VERKETTEN(D2;" ";E2;" ";F2;" ";G2))
For C2 I added: =GLÄTTEN(VERKETTEN(B2;" ";D2;" ";E2;" ";F2;" ";G2))
For C10 I added: =GLÄTTEN(LINKS(B10;FINDEN(" ";B10)))
For D10 I added: =GLÄTTEN(LINKS(B11;FINDEN(" ";B11)))
For E10 I added: =GLÄTTEN(LINKS(B12;FINDEN(" ";B12)))
For F10 I added: =GLÄTTEN(B13)
For B11 I added: =TEIL(B10;LÄNGE(C10)+2;99)
For B12 I added: =TEIL(B11;LÄNGE(D10)+2;99)
For B13 I added: =TEIL(B12;LÄNGE(E10)+2;99)
The translation I got from here.

You can do it efficiently in VBA as below
Hit Alt and F11 to open the Visual Basic Editor (VBE).
From the menu, choose Insert-Module.
copy and paste the code into the code window at right.
Hit Alt and F11 to return to Excel
run the macro from the Developer tab for Excel 2007 and higher, for Excel 2003 use ...Tools-Macro-Macros
enter code here
Sub QuickFInd()
Dim X As Variant
Dim Y As Variant
Dim vWords As Variant
Dim Vword As Variant
Dim lngCnt As Long
X = Range("A2:A8").Value2
ReDim Y(1 To UBound(X), 1 To 1)
vWords = Split([b10].Value)
For lngCnt = 1 To UBound(X)
For Each Vword In vWords
If InStr(X(lngCnt, 1), Vword) > 0 Then Y(lngCnt, 1) = Y(lngCnt, 1) & Vword & Chr(32)
Next Vword
Next
[b2].Resize(UBound(Y), 1).Value2 = Y
End Sub

I've solved your problem with VBA code. To use it, create a VBA module in the excel workbook and paste the following code in. Then go back to the worksheet you want it to run on, and click "Macros" and select "Search".
Let me know how it works ~
Example:
Code:
Public Sub search()
'Enter the location of your "Key Word" cell here (where you want the search values to come from)
Dim KeyCell As String: KeyCell = "B11"
'Enter the range you would like to search here
Dim searchRange As Range: Set searchRange = ActiveSheet.Range("A2", "A11")
'Enter the column you want to print to
Dim printColumn As String: printColumn = "B"
'##### the real program starts here ####
'create an array of values that we will search for
Dim values() As String
'each item in the values array is separated by a space in the "Key Word" cell
values = Split(CStr(ActiveSheet.Range(KeyCell).Value), " ")
Dim dataCell As Object
'now we loop through each cell in the search range
For Each dataCell In searchRange
'loop through each value in our array of values
For Each v In values
'check to see if our value is in the cell we are searching
If InStr(1, CStr(dataCell.Value), CStr(v), vbBinaryCompare) > 0 Then
'print
With ActiveSheet.Range(printColumn & dataCell.Row)
.Value = .Value & " " & CStr(v)
End With
End If
Next v
Next dataCell
End Sub

If you want only a search without PASTE or VBA, you can follow the scheme:
and add formula:
B2 -> =TRIM(CONCATENATE(D2;" ";E2;" ";F2;" ";G2))
C2 -> =IF(IFERROR(FIND(C$10;$A2)>0;"")=TRUE;C$10;"") and autocomplete
C10 -> =TRIM(LEFT(B10;IFERROR(FIND(" ";B10);99))) CORRECT !
D10 -> =TRIM(LEFT(B11;IFERROR(FIND(" ";B11);99))) CORRECT !
E10 -> =TRIM(LEFT(B12;IFERROR(FIND(" ";B12);99))) CORRECT !
F10 -> =TRIM(B13)
B11 -> =MID(B10;LEN(C10)+2;99)
B12 -> =MID(B11;LEN(D10)+2;99)
B13 -> =MID(B12;LEN(E10)+2;99)
Hiding the Support Formula Columns. You can add how many words you want... obviusly adding other formulas.
If you need to add phisically the values, you can add a column between A & B and copy and paste with value the moved column "C" (Ex B). Modify the C2 formula in:
=TRIM(CONCATENATE(B2;" ";D2;" ";E2;" ";F2;" ";G2)) and autocomplete...
This formulas add the keys already saved... (No duplicate check).
I have correct the formula... Previously work only with 4 key...

You could do something like this:
=IF(IFERROR(FIND($B$10,A2,1),0)>0,$B$10&" ","")&IF(IFERROR(FIND($B$11,A2,1),0)>0,$B$11&" ","")&IF(IFERROR(FIND($B$12,A2,1),0)>0,$B$12&" ","")
And just auto-fill that down for all your text items.

Related

Output the text of a cell that is NOT within a text list - IS IT POSSIBLE?

In excel I would like to output the text string in a cell that is not present in a text list.
For example:
I have cell A1 which contains AA,BB,CC
Now I have a list in Array B1:B5 containing
AA
BB
DD
EE
FF
What would the formula be so that CC is the output - a formula finding the text that is NOT in the list.
I have the formula to output those texts that are in the list which is:
TEXTJOIN(", ", TRUE, IF(COUNTIF(A!, ""&B1:B5&""), B1:B5, ""))
Thank you for your help!!!
If you have Excel 365, in C1 enter:
=LET(fx,FILTERXML("<a><b>"&SUBSTITUTE(A1,",","</b><b>")&"</b></a>","//b"),z,IF(ISERROR(MATCH(fx,B1:B5,0)),fx,""),FILTER(z,z<>""))
If you have Excel 2019, you can try:
=TEXTJOIN(",",,FILTERXML("<x><t>"&SUBSTITUTE(A1&",",",","<s>,"&TEXTJOIN(",",,B1:B5)&",</s></t><t>")&"</t></x>","//t[.//*[not(contains(.,concat(',',../text(),',')))]]"))
This would need CSE entering. However, a nice Excel365 alternative is allready provided by #GarysStudent.
You can use a UDF to do this if you are open to VBA solution...
Public Function ABSENT(Target As Range) As String
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim i As Long, Found As Range, Temp
Temp = Split(Target, ",")
For i = LBound(Temp) To UBound(Temp)
Set Found = ws.Range("B2:B6").Find(Trim(Temp(i)))
If Found Is Nothing Then
ABSENT = ABSENT & Trim(Temp(i)) & ", "
End If
Set Found = Nothing
Next i
If Len(ABSENT) Then
ABSENT = Left(ABSENT, Len(ABSENT) - 2)
Else
ABSENT = ""
End If
End Function

Using nested formula in VBA

I'm working on problem that necessitates the use of nested formulas in excel. For eg:
I have a column for errors and one for its analysis
Error Analysis
Enter a valid material number Invalid Material
Eg errors:
Enter a valid material number; The material number 1234 does not
exist.
PO number XYZ does not exist.
VIN number 123 does not exist.
Country of origin AB does not exist.
I have a compendium of such errors and their analyis in the next sheet, and I'm using VLOOKUP in conjuction with FIND to lookup the analysis for the known errors.
=VLOOKUP(LEFT(F2, FIND(" ", F2, FIND(" ", F2) + 1) - 1)&"*", 'Sheet2'!A:B, 2, 0)
What i'm trying to do here is extract the first two words from the error and append a * to it and use it in VLOOKUP.
It would be something like Vlookup "PO number *" in the other sheet and get the analysis for it. Asterisk is because I don 't get the same number daily. And I also know that the extracted first two words of the error will be unique. (I know that error with "Enter a" as the first two words will not appear again).
Now I get errors in the same column so I thought of making a button and writing a code which uses the above formula.
I tried to modify some code off the net, but I'm not getting anywhere with it. I'm totally new to VBA. It'd be great if you can provide a snippet for this. I'll try to replicate the procedure for other needs.
This code seems to be working for now
Sub PopulateAnalysis()
Dim an_row As Long
Dim an_clm As Long
Dim lft As String
Dim st_num As Integer
Dim fin As String
Dim searchStr As String
Dim soughtStr As String
Table1 = Sheet1.Range("F2:F6") 'ErrorColumn from Error table (How do I make the range dynamic??)
Table2 = Sheet5.Range("A1:B6")
an_row = Sheet1.Range("G2").Row ' Populate this column from the analysis table on sheet2
an_clm = Sheet1.Range("G2").Column
For Each cl In Table1
'How do I translate the above formula into VBA statements??
st_num = InStr(InStr(cl, " ") + 1, cl, " ")
lft = left(cl, st_num - 1)
fin = lft & "*"
Sheet1.Cells(an_row, an_clm) = Application.WorksheetFunction.VLookup(fin, Table2, 2, True)
an_row = an_row + 1
Next cl
MsgBox "Done"
End Sub
This should work. You don't need the debug lines of course ;)
Sub PopulateAnalysis()
Dim rngTableWithErrors As Range
Dim rngTableWithAnalysis As Range
Application.ScreenUpdating = False
'set the range for Table with error, Table1 on sheet 1
With Sheets(1) 'change to name of the sheet, more reliable than index num.
Set rngTableWithErrors = .Range("F2:F" & .Cells(.Rows.Count, 6).End(xlUp).Row)
Debug.Print rngTableWithErrors.Address
End With
'set the range for Table with Analysis, Table 2 on sheet 2
With Sheets(2) 'change to name of the sheet, more reliable than index num.
Set rngTableWithAnalysis = .Range("A1:B" & .Cells(.Rows.Count, 2).End(xlUp).Row)
Debug.Print rngTableWithAnalysis.Address
End With
'formula for cell G2
'=VLOOKUP(LEFT(F2;FIND(" ";F2;FIND(" ";F2)+1)- 1)&"*";Sheet2!A1:B23;2; 0)
rngTableWithErrors.Offset(0, 1).FormulaR1C1 = _
"=VLOOKUP(LEFT(R[0]C[-1],FIND("" "",R[0]C[-1],FIND("" "",R[0]C[-1])+1)-1)& ""*"",Sheet2!R1C1:R" & rngTableWithAnalysis.Rows.Count & "C2,2, 0)"
Application.ScreenUpdating = True
MsgBox "Done"
End Sub
Notes
You can notice, that we are setting the upper left cells of ranges manually. It's better practice to somehow find the upper left cells (using Find method is my favorite) and work from there. You never know, how the user will change the worksheet - i.e. add new rows, columns etc.

inserting array formula into excel using vba and referencing cell value exported from outlook email?

I am using a vba code in outlook to export some text from an email body into the next available row in excel. I am also exporting an array formula in the cell next door, so In this instance intRow4 as an integer represents the next available row on my worksheet.
And In this example my next available row is row 34. So we are exporting the description text from our email into cell (D34) in excel and are also inserting an array formula from outlook into excel, cell (E34). The formula is an index lookup formula that references D34 and should lookup the first 5 letters of a word and match it with a 3 letter code from another worksheet.
So on my other worksheet (worksheet 2) I have a list of data in columns
Description Other Other Other Other Code
Hotels NFP
Catering PLQ
Travel LMC
so where my email contains a description text like Catering then this will be exported into my excel cell (D34) and the formula which gets inserted into (E34) should find the corresponding description by referencing cell (D34) and matching it to the description in my column on sheet 2. This should then produce the 3 letter code in column 6. In this case it would be PLQ
My Description text in my email looks like:
Description of Provisional Supplier:
Catering
My export code seems to work fine and cell D34 gets populated with the description text from my email. And the formula gets inserted as an array in cell E34.
The problem is my formula is not producing the 3 letter code, it is showing #NUM! error.
However if I go into my cell D34 and place my cursor to the left of the text and hit the backspace key and hit enter again then the formula produces the 3 letter code.
I am removing spaces and line breaks from my description string at the point when it gets exported into excel and I can not explain why this is happening.
can someone please show me where I am going wrong and show me how I can get this working without me having to manually go in and edit the contents of my cell. thanks
Const SHEET_NAME4 = "Statistics"
intRow4 As Integer, _
Set excWks4 = excWkb.Worksheets(SHEET_NAME4)
intRow4 = excWks4.UsedRange.Rows.Count + 1
Dim l As String
l = excWks4.Cells(intRow4, 4).Address
excWks4.Cells(intRow4, 5).FormulaArray = "=IF(ISERROR(INDEX('Up'!$A$1:$G$10004,SMALL(IF(LEFT('Up'!$B$1:$B$10004,5)=LEFT(" & l & ",5),ROW($B$1:$B$10004)),ROW(1:1)),6)),"""",INDEX('Up'!$A$1:$G$10004,SMALL(IF(LEFT('Up'!$B$1:$B$10004,5)=LEFT(" & l & ",5),ROW($B$1:$B$10004)),ROW(1:1)),6))"
Dim b7 As String
If TypeName(olkMsg) = "MailItem" Then
b7 = olkMsg.Body
Dim indexOfNameb4 As Integer
indexOfNameb4 = InStr(UCase(b7), UCase("Description of the provisional Supplier:"))
Dim indexOfNamec4 As Integer
indexOfNamec4 = InStr(UCase(b7), UCase("Current Status: "))
Dim finalStringb4 As String
Dim LResult3364 As String
Dim LResult33644 As String
finalStringb4 = Mid(b7, indexOfNameb4, indexOfNamec4 - indexOfNameb4)
LResult3364 = Replace(finalStringb4, "Description of the provisional Supplier:", "")
LResult33644 = Replace(LResult3364, Chr(10), "")
Dim TrimString As String
Dim TrimString2 As String
Dim TrimString3 As String
TrimString = Trim(LResult33644)
TrimString3 = Replace(TrimString, " ", "")
excWks4.Cells(intRow4, 4) = TrimString3
End If
My Excel cells are formatted as general format if this helps
Have you tried adding the line
excWks4.Cells(intRow4, 4) = Trim(excWks4.Cells(intRow4, 4))
after the line
l = excWks4.Cells(intRow4, 4).Address
Alternatively you could may be able to add the TRIM function to your long formula around all references to those cells.

How to group excel items based on custom rules?

I have a set of data (webmaster tools search queries) which is in excel with the following header:
Query | Impressions | Clicks | Date
Sample google spreadsheet here.
I want to add in an extra column called Category and categorize all the queries according to custom rules that will search for a string on column A.
Ex:
if A2 contains the string 'laptop' then write 'laptop' on the category next to it
So far I have tried a formula to do this but I'm not sure this is the easiest way. Also, if there are lots of categorization rules the formula gets really long and unmanageable.
=IF(ISNUMBER(SEARCH("laptop",A2)),"laptop",
IF(ISNUMBER(SEARCH("notebook",A2)),"laptop",
IF(ISNUMBER(SEARCH("iphone",A2)),"phone",
IF(ISNUMBER(SEARCH("galaxy s",A2)),"phone",
"other")))
Can you suggest a better way of doing this where I can have the rules in one sheet in this format:
Query_contains | Category_is
where Query_contains would be the string that needs to be matched in column A from the initial sheet the and Category would be the value that needs to be filled into column D.
Ok, I changed your sheet a bit....
Supposing all your data was in cells A1:C9, then you had the following table in cells F1:G5
Search_For: Category:
laptop Laptop
iphone Phone
galaxy Phone
notebook Laptop
Now, in cell D2, put in the following formula:
=IFERROR(INDEX(G$2:G$5,MATCH(TRUE,ISNUMBER(SEARCH(F$2:F$5,A2)),0)),"other")
And enter it as an array formula Meaning, once you enter it, hit CTRL+SHIFT+ENTER.
You can then drag the formula from cell D2 down and it should give you the desired results (and you can, of course, increase the list in columns F & G as necessary).
Hope this does the trick!!
This small macro assumes your data is in Sheet1 and your rules are in worksheet rules in columns A & B:
Sub catagorize()
Dim s1 As Worksheet, s2 As Worksheet
Dim N1 As Long, N2 As Long
Set s1 = Sheets("Sheet1")
Set s2 = Sheets("rules")
N1 = s1.Cells(Rows.Count, "A").End(xlUp).Row
N2 = s2.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To N1
v = s1.Cells(i, 1).Value
For j = 1 To N2
If InStr(1, v, s2.Cells(j, 1).Value) > 0 Then
s1.Cells(i, "D").Value = s2.Cells(j, "B").Value
End If
Next j
Next i
End Sub
And for a 3rd option, you could use a custom formula.
I created a table just for categories on a separate sheet, then inserted the following code in a standard module.
Option Explicit
Function CategoryLookup(s_Query As String, Keyword_tbl As Range)
Dim rngKeywords As Range
Dim s_foundCategory As String
Dim b_CategoryExists As Boolean
b_CategoryExists = False
For Each rngKeywords In Keyword_tbl
If InStr(s_Query, rngKeywords.Value) <> 0 Then
s_foundCategory = rngKeywords.Offset(0, 1).Value
b_CategoryExists = True
Exit For
End If
Next rngKeywords
If b_CategoryExists = True Then
CategoryLookup = s_foundCategory
Else
CategoryLookup = "Other"
End If
End Function
Then in D2 (your category column) insert the following formula (which can then be dragged down)
=CategoryLookup(A2,categories!$A$2:$A$5)

Append string between each cell value in a series

Let's say I have a series of cells like so:
A
1 Foo
2 Bar
3 Hello
4 World
5 Random Text
What I'd like to do is have the result of my formula populate another cell with:
Foo, Bar, Hello, World, Random Text
Now, I know how to concatenate two cells with:
=A1&", "&A2
but how can I do the same thing with the entire series?
Here's a function you might be able to use. Simply put this in your workbook code module, then you can enter it in cells like:
=JoinRange(A1:A6) or =JoinRange(A2:D15), etc.
Public Function JoinRange(ByVal rng As Range) As String
Dim dlmt As String: dlmt = ","
Dim multiRow As Boolean: multiRow = rng.Rows.Count > 1
Dim r As Long, c As Long
Select Case rng.Columns.Count
Case 1
If multiRow Then
JoinRange = Join(Application.WorksheetFunction.Transpose(rng), dlmt)
Else:
'a single cell
JoinRange = rng
End If
Case Is > 1
If multiRow Then
'a 2d range of cells:
For r = 1 To rng.Rows.Count
For c = 1 To rng.Columns.Count
JoinRange = JoinRange & rng(r, c) & dlmt
Next
Next
JoinRange = Left(JoinRange, Len(JoinRange) - 1)
Else:
JoinRange = Join(Application.WorksheetFunction.Transpose( _
Application.WorksheetFunction.Transpose(rng)), dlmt)
End If
Case Else
End Select
End Function
Put a comma and a space in cell B1, then use this formula:
=CONCATENATE(A1,B1,A2,B1,A3,B1,A4, B1, A5)
There are several answers to the following question that you can try as well, including VBA options and a formula:
Need to concatenate varying number of cells...
With =A1 in B1 then =B1&", "&A2 in B2 and copied down would seem to work.

Resources