VBA Like Function - excel

Basically my code works in such a way that an Incoming email subject from Outlook is compared to a list column in Excel - supposedly those existing email. If the Incoming email is matched with any records then it Shows the value in Excel. However, I noticed that, if the data in Excel contains the hashtag (#) value, even if the incoming email is not the same as the one in Excel- the code marks it as matched.
If emlSubj Like "*" & strSubj & "*" Then
Debug.Print strSubj
Is there something wrong with the code or is it the limitation of the LIKE function?

Use the InStr function instead. It returns an integer specifying the start position of the first occurrence of one string within another.
If InStr(emlSubj , strSubj) > 0 Then
Debug.Print strSubj
End If

Related

Vba to break up text within a cell? Text to columns not working

How can I break up text within a cell with vba? I exported emails to an excel file using a vba and the information exported in one of the cells is formatted as seen below:
Name * xxxxxx
Country of residence * xxxxxx Email * xxxxx#gmail.com mailto:xxxxxxx#gmail.com
Mobile phone number * 0xxxxxx
Do you want to become a member of Assoc? Yes Check all that apply *
Members
Education
Ethical Conduct
Events
Regulation
I tried the solution below and it’s not working.
From article: If you need to build a formula to remove these line breaks all you need to know is that this ‘character’ is character 10 in Excel. You can create this character in an Excel cell with the formula =CHAR(10).
So to remove it we can use the SUBSTITUTE formula and replace CHAR(10) with nothing ( shown as “”).
https://www.auditexcel.co.za/blog/removing-line-breaks-from-cells-the-alt-enters/#:~:text=Building%20a%20formula%20to%20remove%20the%20ALT%20ENTER%20line%20breaks,-If%20you%20need&text=You%20can%20create%20this%20character,cell%20with%20no%20line%20breaks.
My understanding is that you dump an email into 1 excel cell and are hoping to separate a series of strings [Country, Email, Etc.] that are separated by a line break?
I suggest using the split function to separate the strings into an array, then loop through that array to put the information in the desired cells. Mind you this will only work if the items are in the same order everytime, if the order can change then you will need to add a data verification step. i.e. if inStr("#",[Range]) then its an email...
Split([string to split], [delimiter])
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/split-function
Dim strEmail as String 'Email dump
Dim arrEmail() as String 'Array for looping
Dim ItemsInArray as Integer 'Used to hold array count
Dim i as Integer 'Counter
strEmail = ActiveSheet.Cells("[Column,Row]") 'Cell your email dumps to
arrEmail = Split(strEmail, char(10)) 'Populate array
ItemsInArray = UBound(arrEmail) 'Get upper bound of array (total item count)
For i = 0 to ItemsInArray
ActiveSheet.Cells("[Column,Row]") = arrEmail(i)
Column + 1
Next i
when i = 0 its a country code
when i = 1 its an email
when i = 2 its a phone #
etc....

VBA Vlookup errors

I have written vlookups plenty of times but dont have any of my old code examples to hand and I know I am missing something really simple here.
Context - I am creating a code workbook separate from the file to work on. I have created a function that creates an order ID and during that process I have to lookup a value and swop it for the value of the look up. I am absolutely certain I am simply not getting the syntax right for the sheet referencing part of the lookup but despite checking various posts on here and changing it several times I cannot get it right
Function build_order_ID(building_name As String, customer_name As String, order_number As Integer)
Dim building_name_new As String
building_name_new = WorksheetFunction.VLookup(building_name, ThisWorkbook.Sheets("building_ref").Range("A1:B5"), 2, False).Value
build_order_ID = building_name & "-" & order_number & "-" & customer_name
End Function
The sheet is sheet3 but named building_ref
I am using this code to generate the output but it always stops during the lookup normally with object errors but I did get different errors when changing the format of calling the sheet
Public Sub test_order_ID()
Dim order_ID As String
order_ID = build_order_ID("testvalue", "Jack", 1)
MsgBox order_ID
End Sub
Thank you to https://stackoverflow.com/users/9245853/bigben who pointed out my error with the .value at the end of the vlookup. After removal the code executed correctly

Comparing Strings Producing Unexpected Results

I have a list of data and I created a form to enter new data to be added to the list. Upon the click of a button it will take the information (name and email address) from the form and add it to the corresponding sheets in alphabetical order. There are linked cells involved so I can't just add this to the bottom and sort. Instead, I have it searching the last name cell in the correct sheets to insert a row into the correct location.
This was working as expected for the most part until I came along a possibly unique situation that I can't figure out.
Basically, I have an if statement checking to see if the name is a duplicate and afterwards checking to see if the if the new name should be inserted.
For i = 2 To lastrow
''^^IF STATEMENT CHECKING FOR DUPLICATE^^''
'''''''''''''''''''''''''''''''''''''''''''
'''vvIF STATEMENT CHECKING TO ADD DATAvv'''
ElseIf StrComp(lastname, searchl) = 1 And StrComp(lastname, searchl2) = -1 Then
Sheets("Master List").Range("A" & i).Offset(1).EntireRow.Insert (xlDown)
Sheets("Master List").Range("A" & i + 1).Value = firstname
Sheets("Master List").Range("B" & i + 1).Value = lastname
Sheets("Master List").Range("C" & i + 1).Value = fullname
Variables searchl and searchl2 are the last names from search rows i and i + 1, respectively.
My problem is that when I tried to add the last name "Kralik" it tried to insert the data between the last names "Day" and "de Castro"
Originally, I tried comparing the names using the line of code below:
ElseIf lastname > searchl And lastname < searchl2 Then
This executed the exact same way as the code outlined above. I then inserted a break point and decided to use the StrComp method for troubleshooting. Comparing "Kralik" to "Day" produced results expected but the problem occurs when comparing "Kralik" to "de Castro". For some reason, the code thinks "Kralik" is less than "de Castro" and enters the if statement to insert the data at that location. Even more head scratching for me is that I opened a new workbook and quickly typed "Kralik" into A1, "de Castro" into A2 and the formula "=A1>A2" into A3. The formula gave a result TRUE which is what I would have expected from VBA as well.
EDIT: After more tests, I think it must have something to do with the capitalization of "Kralik" vs. "de Castro" my code works as expected as long as the "k" in "Kralik" is uncapitalized. I will use the UCase method on my variables and come back with the results.
EDIT 2: Using UCase works as well. Outlined by GSerg's answer below as to why my original method was not working.
Excel formulas use case insensitive comparisons by default.
VBA uses case sensitive comparisons by default.
If you want case insensitive comparisons, either put
Option Compare Text
at the beginning of the code module to make all text comparisons in that code module case insensitive by default, or request a comparison type in each specific comparison:
ElseIf StrComp(lastname, searchl, vbTextCompare) = 1 And StrComp(lastname, searchl2, vbTextCompare) = -1 Then
On top of that, you should be using binary search in your particular case to find the position to insert. MATCH with match_type = 1 will return you position in a sorted list where the value should go.

Prevent Partial Duplicates in Excel

I have a worksheet with products where the people in my office can add new positions. The problem we're running into is that the products have specifications but not everybody puts them in (or inputs them wrong).
Example:
"cool product 14C"
Is there a way to convert Data Valuation option so that it warns me now in case I put "very cool product 14B" or anything that contains an already existing string of characters (say, longer than 4), like "cool produKt 14C" but also "good product 15" and so on?
I know that I can prevent 100% matches using COUNTIF and spot words that start/end in the same way using LEFT/RIGHT but I need to spot partial matches within the entries as well.
Thanks a lot!
If you want to cover typo's, word wraps, figure permutations etc. maybe a SOUNDEX algorithm would suit to your problem. Here's an implementation for Excel ...
So if you insert this as a user defined function, and create a column =SOUNDEX(A1) for each product row, upon entry of a new product name you can filter for all product rows with same SOUNDEX value. You can further automate this by letting user enter the new name into a dialog form first, do the validation, present them a Combo Box dropdown with possible duplicates, etc. etc. etc.
edit:
small function to find parts of strings terminated by blanks in a range (in answer to your comment)
Function FindSplit(Arg As Range, LookRange As Range) As String
Dim LookFor() As String, LookCell As Range
Dim Idx As Long
LookFor = Split(Arg)
FindSplit = ""
For Idx = 0 To UBound(LookFor)
For Each LookCell In LookRange.Cells
If InStr(1, LookCell, LookFor(Idx)) <> 0 Then
If FindSplit <> "" Then FindSplit = FindSplit & ", "
FindSplit = FindSplit & LookFor(Idx) & ":" & LookCell.Row
End If
Next LookCell
Next Idx
If FindSplit = "" Then FindSplit = "Cool entry!"
End Function
This is a bit crude ... but what it does is the following
split a single cell argument in pieces and put it into an array --> split()
process each piece --> For Idx = ...
search another range for strings that contain the piece --> For Each ...
add piece and row number of cell where it was found into a result string
You can enter/copy this as a formula next to each cell input and know immediately if you've done a cool input or not.
Value of cell D8 is [asd:3, wer:4]
Note the use of absolute addressing in the start of lookup range; this way you can copy the formula well down.
edit 17-Mar-2015
further to comment Joanna 17-Mar-2015, if the search argument is part of the range you're scanning, e.g. =FINDSPLIT(C5; C1:C12) you want to make sure that the If Instr(...) doesn't hit if LookCell and LookFor(Idx) are really the same cell as this would create a false positive. So you would rewrite the statement to
...
...
If InStr(1, LookCell, LookFor(Idx)) <> 0 And _
Not (LookCell.Row = Arg.Row And LookCell.Column = Arg.Column) _
Then
hint
Do not use a complete column (e.g. $C:$C) as the second argument as the function tends to become very slow without further precautions

Excel/VBA: How to Keep the first row containing first occurrence of var and remove the rest and repeat?

Problem:
I have about 50,000 rows in Excel. Each row contains a the word domain=[a-Z0-9]
where [a-Z0-9] is a placeholder for a bunch of numbers and text like a GUID. This domain ID let's call abc123 it is unique. However in the 50,000 rows it is not a unique key for the table so I need to make it unique by removing all the other rows where domain ID = abc123. But I have to do this for all domains so I can't be specific. I need a script to figure this out. The domain ID is always in the same column and there many different domain ID's that repeat themselves.
Sample
column 2
abunchofstuff3123123khafadkfh23k4h23kh*DomainID=abc123*
Pseudo Code
//Whenever there is a value for domain in row i col 2
//does it already exist in ListOfUniqueDomains?
//if so then remove this row
//else add to the ListOfUniqueDomains
How would one do this with Excel/VBA?
UPDATED ANSWER
So I really liked the idea of using Pivot Tables but I still had to extract the domain ID so I thought I'd post the solution to that portion here. I actually stole the function from some other website while googling but I lost the original post to give proper credit. So forgive me if that person is you but give yourself a pat on the back and I'll buy you lunch if you're in my neighborhood (easy everyone).
So in my case I had 2 delimeters (=, &) for the string domain=abc123& which is embedded in a longer string. So to extract the domain ID I did the following.
Public Function extract_value(str As String) As String
Dim openPos As Integer
Dim closePos As Integer
Dim midBit As String
On Error Resume Next
openPos = InStr(str, "=") 'get the position of the equal sign
On Error Resume Next
closePos = InStr(str, "&") ' get the position of the &
On Error Resume Next
midBit = Mid(str, openPos + 1, closePos - 1)
'get the string that is between equal sign and before '&' however this seems
'greedy and so it 'picked up the last '&'.I used split to get the first occurrence
'of '&' because that was how my string was designed.
Dim s As String
s = Split(midBit, "&")(0)
extract_value = s
End Function
Is VBA even a good idea for something like this?
Thanks
I've done this for some fairly large file (50k rows) where I needed to extract only unique elements. What I've done is quite simple: use a pivot table. This way you don't even need VBA, but if you want to process it further it's still very simple to update the table and extract data.
One of the reasons I really love this method is that it is extremely easy and powerful at the same time. You have no looping or algorithm to write, it's all right there in the Excel features.

Resources