Combining formulas - excel

I have this formula in a table which basically collects data from two columns and combines them. Now, I'm looking to combine this formula with a REPLACE formula that basically takes these characters æ,ø,å and replaces them with a,o,a.
Here's the formula:
=LOWER(LEFT(tableFaste[[#This Row];[Fornavn:]])&tableFaste[[#This Row];[Etternavn:]])

Sorry, don't know of a Formula way to remove any of a list of characters from a string. You might have to revert to vba for this. Here's a user defined function to do it. Your formula will become
=DeleteChars([#UserName],{"æ","ø","å";"a","o","a"})
To replace the characters use {"æ","ø","å";"a","o","a"} where the list up to the ; is the old characters, after the ; the new. You can make the list as long as you need, just make sure the lists are the same length.
To Delete the characters replace use {"æ","ø","å"} an array list of characters you want to remove
UDF code:
Function DeleteChars(r1 As Range, ParamArray c() As Variant) As Variant
Dim i As Long
Dim s As String
s = r1
If UBound(c(0), 1) = 1 Then
For i = LBound(c(0), 2) To UBound(c(0), 2)
s = Replace(s, c(0)(1, i), "")
Next
Else
For i = LBound(c(0), 2) To UBound(c(0), 2)
s = Replace(s, c(0)(1, i), c(0)(2, i))
Next
End If
DeleteChars = s
End Function

You can use SUBSTITUTE
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(LOWER(LEFT(tableFaste[[#This Row];[Fornavn:]])&tableFaste[[#This Row];[Etternavn:]]),"æ","a"),"ø","o"),"å","a")

Related

Seperating a character string

I want to separate a character string using the special characters in that string as cutting lines. After each division the next group of strings should be copied in the next column. The picture below shows how it should work.
My first approach doesn't work and maybe it's too complicated. Is there a simple solution to this task?
Sub SeparateString()
Dim i, j, k, counterA, counterB As Integer
Dim str1, str2 As String
Const Sonderz As String = "^!§$%&/()=?`*'_:;°,.-#+´ß}][{³²"
For i = 1 To Worksheets("Tabelle1").Range("A1").End(xlDown).Row
counterA = 0
For j = 1 To Len(Worksheets("Tabelle1").Range("A" & i))
counterB = 0
For k = 1 To Len(Sonderz)
If Mid(Worksheets("Tabelle1").Range("A" & i), j, 1) = Mid(Sonderz, k, 1) Then
counterA = counterA + 1
End If
If Mid(Worksheets("Tabelle1").Range("A" & i), j, 1) <> Mid(Sonderz, k, 1) And counterA = 0 And counterB = 0 Then
Worksheets("Tabelle1").Range("B" & i) = Worksheets("Tabelle1").Range("B" & i) & Mid(Worksheets("Tabelle1").Range("A" & i), j, 1)
counterB = counterB + 1
End If
Next k
Next j
Next i
End Sub
If you are interested and you do have access to Microsoft 365's dynamic arrays:
Formula in B1:
=LET(X,MID(A1,SEQUENCE(LEN(A1)),1),TRANSPOSE(FILTERXML(CONCAT("<t><s>",IF(ISNUMBER(FIND(X,"^!§$%&/()=?`*'_:;°,.-#+´ß}][{³²")),"</s><s>",X),"</s></t>"),"//s")))
Or nest a SUBSTITUTE() if you need to return string variables:
=LET(X,MID(A1,SEQUENCE(LEN(A1)),1),TRANSPOSE(SUBSTITUTE(FILTERXML(CONCAT("<t><s>'",IF(ISNUMBER(FIND(X,"^!§$%&/()=?`*'_:;°,.-#+´ß}][{³²")),"</s><s>'",X),"</s></t>"),"//s"),"'","")))
If VBA is a must, you could think about a regular expression to replace all the characters from a certain class with a uniform delimiter to use Split() on:
Sub Test()
Dim s As String: s = "CD!02?WX12EF"
Dim arr() As String
With CreateObject("vbscript.regexp")
.Global = True
.Pattern = "[!§$%&\/()=?`*'_:;°,.#+´ß}\][{³²^-]"
arr = Split(.Replace(s, "!"), "!")
End With
For Each el In arr
Debug.Print el
Next
End Sub
The caret has been moved from being the 1st character to any but the first to prevent a negated-character class; also the hyphen has been moved to the back to prevent an array-construct of characters. Funny enough, if you actually want to be less verbose you could throw these character in a more condense class [!#-/:;?[]-`{}§=°´ß³²].
Assuming the first data is in cell A2,
I would go with the simple use of find() with left() mid() and right()
=left(A2,find("!",A2,1)-1)
then:
=mid(A2,find("!",A2,1)+1,find("?",A2,1)-find("!",A2,1)-1)
and:
=right(A2,len(A2)-find("?",A2,1))
Tested and working with one correction done.
You can also do this in Power Query which has a command to split by ANY delimiter.
In the code below, I generate a list of all possible special characters defined as characters NOT in the set of A..Za..z0..9 and you can easily add to that list by editing the code if you want to include other characters in the permitted list.
Edit: If you only have a few special characters, you can just hard-code the list, eg {"!","?"} instead of using List.Generate, but in your question you did not necessarily restrict the list of special characters, even though those are the only two showing in your examples
To use Power Query:
Select some cell in your Data Table
Data => Get&Transform => from Table/Range
When the PQ Editor opens: Home => Advanced Editor
Make note of the Table Name in Line 2
Paste the M Code below in place of what you see
Change the Table name in line 2 back to what was generated originally.
Read the comments and explore the Applied Steps to understand the algorithm
let
//change Table name in next line to reflect actual table name
Source = Excel.CurrentWorkbook(){[Name="Table15"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Source", type text}}),
//Generate list of "special characters" for splitting
//the List.Contains function contains the non-special characters
splitterList = List.RemoveNulls(
List.Generate(()=>0,
each _ <= 255,
each _ +1,
each if List.Contains({"A".."Z","a".."z","0".."9"}, Character.FromNumber(_)) then null else Character.FromNumber(_))),
splitIt = Table.SplitColumn(#"Changed Type", "Source",
Splitter.SplitTextByAnyDelimiter(splitterList))
in
splitIt

How to split a string with multiple delimiters and join parts in vba excel?

Good day All,
I would like some input on the following.
I have a function that split parts of a string and converts single digits to double digits.
The function uses '.' as a delimiter then joins the parts again by a different delimiter.
When I call the function I simply add "=Outliner(C3)" to the cell I want the formatting to happen.
Everything works beautiful. If I put 14.1.1.1 the function returns 14-01-01-01 which is exactly what I need it to do.
Now a new scenario have come up where I am getting the number as 14.1.1-1 and now the function returns 14-01-01-43831 which is not what I want. I still want to have 14-01-01-01.
Is there an easy fix to the function. I have added the code below.
Function Outliner(S As String) As String
Dim x As Long, Parts() As String
Parts = Split(S, ".")
For x = 0 To UBound(Parts)
Parts(x) = Format(Parts(x), "00")
Next
Outliner = Join(Parts, "-")
End Function
Replace
Parts = Split(S, ".")
with
Parts = Split(Replace(S, "-", "."), ".")

How do i get part of string after a special character?

I have a column where i pickup increasing numbering values, and their format is xx_yy
so the first is 1_0, second 1_1 and so forth, no we are at 23_31
I want to get the right side of the string, and i am already getting the left side correctly.
using
newActionId = Left(lastActionID, (Application.WorksheetFunction.Find("_", lastActionID, 1) - 1))
i wish to do the following, human writing below
nextSubid = entire stringvalue AFTER special character "_"
I tried just switching left to right, didnt go so well, do you have a suggestion?
You can use Split function to get the relevant text.
Syntax: Split(expression, [ delimiter, [ limit, [ compare ]]])
Option Explicit
Sub Sample()
Dim id As String
Dim beforeSplChr As String
Dim afterSplChr As String
id = "23_31"
beforeSplChr = Split(id, "_")(0)
afterSplChr = Split(id, "_")(1)
Debug.Print beforeSplChr
Debug.Print afterSplChr
End Sub
Another way
Debug.Print Left(id, (InStrRev(id, "_", -1) - 1)) '<~~ Left Part
Debug.Print Right(id, (InStrRev(id, "_", -1) - 1)) '<~~ Right Part
Even though Siddharth Rout has given what can probably be considered a better answer here, I felt that this was worth adding:
To get the second part of the string using your original method, you would want to use the Mid function in place of Left, rather than trying to use Right.
Mid(string, start, [ length ])
Returns length characters from string, starting at the start position
If length is omitted, then will return characters from the start position until the end of the string
newActionId = Mid(lastActionID, Application.WorksheetFunction.Find("_", lastActionID, 1) + 1)
Just for fun (Split is the way to go here), an alternative way using regular expressions:
Sub Test()
Dim str As String: str = "23_31"
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "\d+"
Debug.Print .Execute(str)(0) 'Left Part
Debug.Print .Execute(str)(1) 'Right Part
End With
End Sub
Btw, as per my comment, your first value could also be achieved through:
Debug.Print Val(str)
Split function of string is very usefull for this type of query.
Like:
String s = "23_34";
String left = s.split("_")[0];
String right = s.split("_")[1];
Or you can also use combination of indexOf and substring method together.
String left = s.substring(0,s.indexOf('_')+1)
String right = s.substring(s.indexOf('_'));

Extract last alpha+numeric pair in a string in Excel

I'm trying to figure out a way to extract the last alpha+numeric sequence in a string made up of similar patterns. The sequence is an alpha+numeric pair: an alpha string (one or more letters) plus a numeric string (one or more numbers). For instance:
G98Y8RT9 -- I need to isolate "RT9"
H8L77 -- I need to isolate "L77"
D64RL19HT7899 -- I need to isolate "HT7899"
As shown above, there are a variable number of characters in each part of the pair and also in the number of pairs preceding the last one. I've tried Excel formulas using FIND, ISNUMBER, etc., but I couldn't figure out the logic to make it work for these variables.
Is there a formula that would help? Or is some kind of regex VBA function the way to go?
I think this should work, as a user-defined function you can place it in a standard module, and call it like:
=GetLastPair($A$1), etc.
Here is the function:
Function GetLastPair(str As String)
Dim numPart As Integer
Dim strPart As Integer
Do Until Not IsNumeric(Mid(str, Len(str) - numPart, 1))
numPart = numPart + 1
Loop
Do Until IsNumeric(Mid(str, Len(str) - numPart - strPart, 1))
strPart = strPart + 1
Loop
GetLastPair = Right(str, numPart + strPart)
End Function
Results:
A bit long formula, but seems to work:
=RIGHT(A1,MATCH(TRUE,ISNUMBER(1*MID(A1,LEN(A1)-MATCH(FALSE,ISNUMBER(1*MID(A1,LEN(A1)-{0,1,2,3,4,5,6,7,8},1)),0)-{0,1,2,3,4,5,6,7,8},1)),0)+MATCH(FALSE,ISNUMBER(1*MID(A1,LEN(A1)-{0,1,2,3,4,5,6,7,8},1)),0)-1)

How to use Excel's array-formulas for a UDF to read each cell correctly?

G'Day,
I have a question more towards helping myself understand how Excel's array-formulas (Control+Shift+Enter) can read each cell dynamically into the formula.
I made an simplified example to show you what I mean.
I created a small fictional farm that has some animals, listed by names and will provide the sound of what the animal makes. In the next column I made a User Defined Function called MakesSound which takes an input of what animal it is and respond the sound that animal it makes. As shown in the snapshot picture below.
Unfortunately, I thought an arrayformula could pick up that I have different cells listing the animals and it ends like this snapshot instead.
so how can I ask the arrayformula to recognise I have different cells in Column B as I know Quacks isn't the answer for other animals. :-)
Here is another snapshot showing the formulas next to arrayformulas for comparsion and code I used as well.
Public Function MakesSound(AnimalName As String) As Variant
Select Case AnimalName
Case Is = "Duck"
MakesSound = "Quack!"
Case Is = "Cow"
MakesSound = "Moo!"
Case Is = "Bird"
MakesSound = "Tweet!"
Case Is = "Sheep"
MakesSound = "Ba-Ba-Ba!"
Case Is = "Dog"
MakesSound = "Woof!"
Case Else
MakesSound = "Eh?"
End Select
End Function
I'm open to suggestions.
Thanks,
Peter.
you need to make you array function read the data into an array, process it and create an output array. Then the array function nneeds to be entered in a multi-cell array formula (D3:D7) using ctrl-shift-enter.
Public Function MakesSound(AnimalName As Range) As Variant
Dim Ansa() As Variant
Dim vData As Variant
Dim j As Long
vData = AnimalName.Value2
ReDim Ansa(1 To UBound(vData), 1 To 1)
For j = 1 To UBound(vData)
Select Case vData(j, 1)
Case Is = "Duck"
Ansa(j, 1) = "Quack!"
Case Is = "Cow"
Ansa(j, 1) = "Moo!"
Case Is = "Bird"
Ansa(j, 1) = "Tweet!"
Case Is = "Sheep"
Ansa(j, 1) = "Ba-Ba-Ba!"
Case Is = "Dog"
Ansa(j, 1) = "Woof!"
Case Else
Ansa(j, 1) = "Eh?"
End Select
Next j
MakesSound = Ansa
End Function
The purpose of using Array formulas for the given sample is really obscure for me, but anyway, if you insist - try the following:
Select region C3:C7 (as on your topmost screen).
Press F2 to edit on the spot and type the following formula: =MakesSound(B2:B7)
Press CTRL+SHIFT+ENTER instead of usual ENTER - this will define an ARRAY formula and will result in {} brackets around it (but do NOT type them manually!).
I'm not sure whether your UDF may handle array notation properly, but for usual Excel formulas this works as expected, e.g. try =LEFT(B2:B7,2) as an array one for step 2 - and this will return 2 starting letters from each animal name.
Hope that was somehow helpful. Good luck!

Resources