How to reverse search in Excel? - excel

I have a text in a worksheet like:
The girl is very beautiful
I want a formula to perform a search from right to left for the word "very", and if found then extract it to some other region of the sheet.
Note: Purpose of doing reverse search is because I want to implement it in my workbook which requires reverse search.
At least, say me how to revert the text like this :
beautiful very is girl The
Then I can do a normal search. I don't know VBA so please give some formula.

VBA Function to reverse the words in text:
Public Function StrReverse(strIn As String, Optional Delimiter As String = " ") As String
'Reverse the words in 'StrIn', split on a "Space" unless 'Delimiter' is specified
Do While InStrRev(strIn, Delimiter) <> 0
StrReverse = StrReverse & Delimiter & Right(strIn, Len(strIn) - InStrRev(strIn, Delimiter))
strIn = Trim(Left(strIn, InStrRev(strIn, Delimiter) - 1))
Loop
StrReverse = Trim(StrReverse & Delimiter & strIn)
If Left(StrReverse, 1) = Delimiter Then StrReverse = Right(StrReverse, Len(StrReverse) - 1)
End Function
For example, if cell A1 contains:
The girl is very beautiful
...then you could enter in another cell:
=StrReverse(A1)
...which would return:
beautiful very is girl The
To add a custom VBA function to a workbook:
Copy the code for the function you want to add to Excel (from above).
In an Excel, workbook, press Alt + F11 to open the VBA Editor (VBE).
Press Alt + I M to insert a new module.
Press Ctrl + V to paste in the code.
Press Alt + F C to return to Excel.
Edit #1:
Added optional delimiter to function above (defaults to a " " space).
Also, FindReverse (below), which allows VBA's (little-known) InStrRev function to be used on worksheets.
Public Function FindReverse(StringCheck As String, StringMatch As String, _
Optional Start As Long = -1) As Long
'Returns the position number of the last occurrence of 'Stringmatch"
'within StringCheck', Optionally specify the position number from the
'end to begin the search. (-1 = Begin at the end)
FindReverse = InStrRev(StringCheck, StringMatch, Start)
End Function
Edit #2:
LOL # Myself ... I'm always telling people not to try to recreate functionality that's already built into MS Office, and it seems that I unwittingly did the same thing -- even giving it the same as the existing VBA Function.
Built-in VBA function:
I realize that it's not identical functionality as the StrReverse function I wrote (above) but I suspect it also could have solved OP's original inquiry...
Nonetheless, I am really surprised that VBA even allows a custom function to have the same name as a built-in function!
How to confuse VBA:

Related

Filter phone numbers from open text field - Power BI, excel, VBA

I have a text field in a table where I need to substitute phone numbers where applicable.
For example the text field could have:
Call me on 08588812885 immediately
Call me on 07525812845
I need assistance please contact me
Good service
Sometimes a phone number will be in the text but not always and the phone number entered will always be different.
Is there a measure to use to replace the phone numbers with no text.
Ideally the solution would be Power BI, but can also be done in the raw data using excel or VBA
Regular expression in VBA (excel) or Python (Power BI) is a straightforward solution.
I have never used PowerBI with Python before but manage to make following python script.
In PowerBI transformation steps I created a new column that would copy [message] columns and named it [noPhoneNumber], then next step ran this python script
import re
def removePhone(x):
return re.sub('\d{10,11}', "**number removed**", x)
length = len(dataset["noPhoneNumber"])
for iRow in range(length):
dataset["noPhoneNumber"][iRow] = removePhone(dataset["noPhoneNumber"][iRow])
so column "noPhoneNumber"
Call me on 08588812885 immediately
Call me on 07525812845
I need assistance please contact me
Good service
becomes
Call me on **number removed** immediately
Call me on **number removed**
I need assistance please contact me
Good service
In VBA Preferable create UDF (user defined function) and don't create a subroutine, that would be too error prone for this kind of problem.
[Added]
If you need to make a Excel based solution, you can create a UDF function like so:
(remember early binding to import of VBScript_RegExp_55.RegExp in excel)
Function removePhoneNumber(text As String, Optional replacement As String = "**number removed**") As String
Dim regex As New RegExp
regex.Pattern = "\d{10,11}"
removePhoneNumber = regex.Replace(text, replacement)
End Function
...and then use excel function like so:
=removePhoneNumber(A2),
=removePhoneNumber(A3)
and so on...
A simple VBA function alternative
Function removePhone(s As String) As String
Const DELIM As String = " "
Dim i As Long, tokens As Variant
tokens = Split(s, DELIM)
For i = LBound(tokens) To UBound(tokens)
If IsNumeric(tokens(i)) Then
tokens(i) = "*Removed*" ' << change to your needs
Exit For ' assuming a single phone number per string
End If
Next
removePhone = Join(tokens, DELIM)
End Function
You can do this in Power Query. Create a custom column with this below code. I have considered the column name is Comments but please adjust this with your column name.
if Text.Length(Text.Select([comments], {"0".."9"})) = 11
then
Text.Replace(
[comments],
Text.Select([comments], {"0".."9"}),
""
)
else [comments]
Here is the output below. You can also replace phone numbers with other text like #### to make is anonymous.
NOTE
This will only work if there are only 1 number in the string with length 11 (You can adjust the length in code as per requirement).
This will Not work if there are more than one Numbers in the string.
If there are 1 number in the string but length not equal 11, this will keep the whole string as original.

Excel find and replace function correct formula

I wish to use the find and replace function in excel to remove example sentences from cells similar to this:
text <br>〔「text」text,「text」text〕<br>(1)text「sentence―sentence/sentence」<br>(2)text「sentence―sentence」
Sentences are in between 「」brackets and will include a ― and / character somewhere inside the brackets.
I have tried 「*―*/*」 however this will delete everything from the right of the〔
Is there any way to target and delete these specific sentence brackets, with the find and replace tool?
Desired outcome:
text <br>〔「text」text,「text」text〕<br>(1)text<br>(2)text「sentence―sentence」
Quite a long formula but in Excel O365 you could use:
=SUBSTITUTE(CONCAT(FILTERXML("<t><s>"&SUBSTITUTE(CONCAT(IF(MID(A1,SEQUENCE(LEN(A1)),1)="「","</s><s>「",IF(MID(A1,SEQUENCE(LEN(A1)),1)="」","」</s><s>",MID(A1,SEQUENCE(LEN(A1)),1)))),"<br>","|$|")&"</s></t>","//s[not(contains(., '「') and contains(., '―') and contains(., '/') and contains(., '」'))][node()]")),"|$|","<br>")
As long as you have access to CONCAT you could also do this in Excel 2019 but you'll have to swap SEQUENCE(LEN(A1)) for ROW(A$1:INDEX(A:A,LEN(A1)))
This formula won't work in many cases, but if the string has matching rules as in your example, then try this:
=SUBSTITUTE(C5,"「" & INDEX(TRIM(MID(SUBSTITUTE(","&SUBSTITUTE(C5,"」","「"),"「",REPT(" ",99)),(ROW(A1:INDEX(A1:A100,LEN(C5)-LEN(SUBSTITUTE(C5,"」",""))))*2-1)*99,99)),MATCH("*―*/*",TRIM(MID(SUBSTITUTE(","&SUBSTITUTE(C5,"」","「"),"「",REPT(" ",99)),(ROW(A1:INDEX(A1:A100,LEN(C5)-LEN(SUBSTITUTE(C5,"」",""))))*2-1)*99,99)),0)) & "」","")
explain how it works:
split the string between the characters "「 "and "」" into an array
use match("*―*/*",,0) to find the string position (note that it will only return one value if it exists, if you have multiple strings, you can replace match("*―*/*",) with search ("*―*/*",..) and use it as an extra column to get matches string)
Use the index(array,match("*―*/*",..)) to get the string needs replacing (result)
Replace the original string with the results found =substitute(txt,result,"")
Or,
In B1 enter formula :
=SUBSTITUTE(A1,"「"&TRIM(RIGHT(SUBSTITUTE(LEFT(A1,FIND("」",A1,FIND("/",A1))),"「",REPT(" ",99)),99)),"")
You did not tag [VBA], but if you are not averse, you could write a User Defined Function that would do what you want using Regular Expressions.
To enter this User Defined Function (UDF), alt-F11 opens the Visual Basic Editor.
Ensure your project is highlighted in the Project Explorer window.
Then, from the top menu, select Insert/Module and
paste the code below into the window that opens.
To use this User Defined Function (UDF), enter a formula like =replStr(A1) in some cell.
Option Explicit
Function replStr(str As String) As String
Dim RE As Object
Const sPat As String = "\u300C(?:(?=[^\u300D]*\u002F)(?=[^\u300D]*\u2015)[^\u300D]*)\u300D"
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = sPat
replStr = .Replace(str, "")
End With
End Function

How do I extract a series of numbers along with a single letter followed by another series of numbers?

The problem that I'm facing is that I have an entire column that has text separated by _ that contains pixel size that I want to be able to extract but currently can't. For example:
A
Example_Number_320x50_fifty_five
Example_Number_One_300x250_hundred
Example_Number_two_fifty_728x49
I have tried using Substitute function to grab the numbers which works but only grabs the numbers when I need something like: 320x50 instead I'm getting 0, as I'm not sure how to exactly extract something like this. If it was consistent I could easily do LEFT or RIGHT formula's to grab it but as you can see the data varies.
The result that I'm looking for is something along the lines of:
A | B
Example_Number_320x50_fifty_five | 320x50
Example_Number_One_300x250_hundred | 300x200
Example_Number_two_fifty_728x49 | 728x49
Any help would be much appreciated! If any further clarification is needed please let me know and I'll try to explain as best as I can!
-Maykid
I would probably use a Regular Expressions UDF to accomplish this.
First, open up the VBE by pressing Alt + F11.
Right-Click on VBAProject > Insert > Module
Then you can paste the following code in your module:
Option Explicit
Public Function getPixelDim(RawTextValue As String) As String
With CreateObject("VBScript.RegExp")
.Pattern = "\d+x\d+"
If .Test(RawTextValue) Then
getPixelDim = .Execute(RawTextValue)(0)
End If
End With
End Function
Back to your worksheet, you would use the following formula:
=getPixelDim(A1)
Looking at the pattern \d+x\d+, an escaped d (\d) refers to any digit, a + means one or more of \d, and the x is just a literal letter x. This is the pattern you want to capture as your function's return value.
Gosh, K Davis was just so fast! Here's an alternate method with similar concept.
Create a module and create a user defined function like so.
Public Function GetPixels(mycell As Range) As String
Dim Splitter As Variant
Dim ReturnValue As String
Splitter = Split(mycell.Text, "_")
For i = 0 To UBound(Splitter)
If IsNumeric(Mid(Splitter(i), 1, 1)) Then
ReturnValue = Splitter(i)
Exit For
End If
Next
GetPixels = ReturnValue
End Function
In your excel sheet, type in B1 the formula =GetPixels(A1) and you will get 320x50.
How do you create a user defined function?
Developer tab
Use this URL to add Developer tab if you don't have it: https://www.addintools.com/documents/excel/how-to-add-developer-tab.html
Click on the highlighted areas to get to Visual Basic for Applications (VBA) window.
Create module
Click Insert > Module and then type in the code.
Use the user defined function
Note how the user defined function is called.

Remove text appearing between two characters - multiple instances - Excel

In Microsoft Excel file, I have a text in rows that appears like this:
1. Rc8 {[%emt 0:00:05]} Rxc8 {[%emt 0:00:01]} 2. Rxc8 {[%emt 0:00:01]} Qxc8 {} 3. Qe7# 1-0
I need to remove any text appearing within the flower brackets { and }, including the brackets themselves.
In the above example, there are three instances of such flower brackets. But some rows might have more than that.
I tried =MID(LEFT(A2,FIND("}",A2)-1),FIND("{",A2)+1,LEN(A2))
This outputs to: {[%emt 0:00:05]}. As you see this is the very first instance of text between those flower brackets.
And if we use this to within SUBSTITUTE like this: =SUBSTITUTE(A2,MID(LEFT(A2,FIND("}",A2)),FIND("{",A2),LEN(A2)),"")
I get an output like this:
1. Rc8 Rxc8 {[%emt 0:00:01]} 2. Rxc8 {[%emt 0:00:01]} Qxc8 {} 3. Qe7# 1-0
If you have noticed, only one instance is removed. How do I make it work for all instances? thanks.
Highlight everything
Go to replace
enter {*} in text to replace
leave replace with blank
This should replace all flower brackets and anything in between them
It is not that easy without VBA, but there is still a way.
Either (as suggested by yu_ominae) just use a formula like this and auto-fill it:
=IFERROR(SUBSTITUTE(A2,MID(LEFT(A2,FIND("}",A2)),FIND("{",A2),LEN(A2)),""),A2)
Another way would be iterative calculations (go to options -> formulas -> check the "enable iterative calculations" button)
To do it now in one cell, you need 1 helper-cell (for my example we will use C1) and the use a formula like this in B2 and auto-fill down:
=IF($C$1,A2,IFERROR(SUBSTITUTE(B2,MID(LEFT(B2,FIND("}",B2)),FIND("{",B2),LEN(B2)),""),B2))
Put "1" in C1 and all formulas in B:B will show the values of A:A. Now go to C1 and hit the del-key several times (you will see the "{}"-parts disappearing) till all looks like you want it.
EDIT: To do it via VBA but without regex you can simply put this into a module:
Public Function DELBRC(ByVal str As String) As String
While InStr(str, "{") > 0 And InStr(str, "}") > InStr(str, "{")
str = Left(str, InStr(str, "{") - 1) & Mid(str, InStr(str, "}") + 1)
Wend
DELBRC = Trim(str)
End Function
and then in the worksheet directly use:
=DELBRC(A2)
If you still have any questions, just ask ;)
Try a user defined function. In VBA create a reference to "Microsoft VBScript Regular Expressions 5.5. Then add this code in a module.
Function RemoveTags(ByVal Value As String) As String
Dim rx As New RegExp
rx.Global = True
rx.Pattern = " ?{.*?}"
RemoveTags = Trim(rx.Replace(Value, ""))
End Function
On the worksheet in the cell enter: =RemoveTags(A1) or whatever the address is where you want to remove text.
If you want to test it in VBA:
Sub test()
Dim a As String
a = "Rc8 {[%emt 0:00:05]} Rxc8 {[%emt 0:00:01]}"
Debug.Print RemoveTags(a)
End Sub
Outputs "Rc8 Rxc8"

Please assist with writing a Macro to clean up data entries

Quick question that should be easy enough for a lot of you but I'm not well versed in VBA or code in general for that matter but I have a problem that only a Macro or piece of VBA code can resolve for me. I have to edit a large number of data entries in a spreadsheet, cell by cell.
So on to the question. Could you please show me an example or provide a complete macro for me to use to edit these cells?
The editing that I require is as follows:
I need to read each cell in the following range: B2 to Q383. A typical entry that needs to be examined and edited looks like this: 629.64\3.00\01:30
What needs to happen now is for everything to the left of the first "\" and everything to the right of the second "\" needs to be removed, including the "\", from each cell.
I've tried fiddling around with the LEFT and RIGHT commands and I can output the data that needs to be removed from the cells with something like this
=left(B11, Find("\", B11) - 1)
So what would be the delete command in a macro to target that data selection in that cell? Or how do I use a delete command with those parameters?
Thanks in advance for any advice or answers!
Not 100% sure what you're after - you say you want to remove the bits from the left and right, but the formula returns the bit on the left.
Anyway, here's 3 formula to do it:
Left: =TRIM(LEFT(B11,FIND("\",B11)-1))
Middle: =LEFT(MID(B11,FIND("\",B11)+1,LEN(B11)),FIND("\",MID(B11,FIND("\",B11)+1,LEN(B11)))-1)
Right: =MID(B11,FIND("\",SUBSTITUTE(B11,"\","~",1))+1,LEN(B11))
And three VBA functions to do it
(use these as you would formula - =leftbit(B11), or if you're looking for something other than backslashes - =leftbit(B11,"|") will find the I-bar as a divider. )
Public Function LeftBit(target As Range, Optional Divider As String = "\") As String
LeftBit = Trim(Left(target, InStr(target, Divider) - 1))
End Function
Public Function MiddleBit(target As Range, Optional Divider As String = "\") As String
Dim First As Long, Second As Long
First = InStr(target, Divider)
Second = InStr(First + 1, target, Divider)
MiddleBit = Mid(target, First + 1, Second - First - 1)
End Function
Public Function RightBit(target As Range, Optional Divider As String = "\") As String
RightBit = Right(target, Len(target) - InStrRev(target, Divider))
End Function

Resources