Excel: Get Last characters from parent folder to sub folder - excel

Need your help very badly. I need to get last characters from Folder Name and Sub Folder(if any). To make my point clearly I am giving an example below.
Eg 1:
E:\User\Images\Main_Folder_**1**\SubFolder**1**\Sub_Folder**2**\SubFolder**3**\SubFolder**4**\file.txt
Need to get string "11234".
Eg2:
E:\User\Images\Main_Folder_**1**\SubFolder**2**\Sub_Folder**5**\SubFolder**6**\SubFolder**9**\file.txt
Need to get string "12569".
I Have tried below code to get last character.
=FIND("#",SUBSTITUTE(A1,"\","#",(LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))/LEN("\")))
But I need to search in sub folders(if any) too.
Really appreciate if you guys can provide any help. Thanks.

If your source data is as you show it; always starting with E:\User\Images, and IF that last character will always be a single digit, and IF there will always be 5 folders/subfolders, you could try:
=SUMPRODUCT(--RIGHT(TRIM(MID(SUBSTITUTE(SUBSTITUTE(A1,"E:\User\Images\",""),"\",REPT(" ",99)),(ROW(INDIRECT("1:5"))-1)*99+1,99)),1)*10^{4;3;2;1;0})
Otherwise I would suggest this User Defined Function:
Option Explicit
Function GetLastFolderChar(S As String) As String
Dim T() As String, U As String
Dim I As Long
S = Replace(S, "E:\User\Images\", "")
T = Split(S, "\")
For I = LBound(T) To UBound(T) - 1
U = U & Right(T(I), 1)
Next I
GetLastFolderChar = U
End Function

Possible solution to you problem is to create UDF VBA as shown below:
1). Add Module to you Excel Workbook (Module1 by default) and place a User Defined Function (UDF) in that module:
Option Explicit
Public Function GetLastChars(InputText As Range) As String
Dim tmp As String, ret As String
'skip E:\User\Images\ as per your example
tmp = Replace(InputText.Value, "E:\User\Images\", "")
'loop through the rest of subfolders
Do While (InStr(tmp, "\")) > 0
'adding the last letters to return var
ret = ret & Mid(tmp, InStr(tmp, "\") - 1, 1)
'progressing to the next subfolder
tmp = Mid(tmp, InStr(tmp, "\") + 1)
Loop
'concatenated last letters of subfolders
GetLastChars = ret
End Function
2) Assuming that as per you example the original data (path) is inserted in Cell "A1", enter in Cell "B1" the formula =GetLastChars(A1); correspondingly, in Cell "B2" enter the Formula: =GetLastChars(B1)
Corresponding to your sample: E:\User\Images\Main_Folder_1\SubFolder1\Sub_Folder2\SubFolder3\SubFolder4\file.txt the return value is 11234.
This UDF will work on any number of sub-folders (skipping the root part E:\User\Images as per your sample).
For example: having the path entered as E:\User\Images\Main_Folder_1\SubFolder1\Sub_Folder2\SubFolder3\SubFolder4\SubFolder5\SubFolder6\SubFolder7\file.txt the formula returns 11234567.
For path string like: E:\User\Images\Main_Folder_1\SubFolder1\Sub_Folder2\SubFolder3\SubFolder4\SubFolder5\SubFolder6\SubFolder7\SubFolder8\SubFolder9\SubFolder0\file.txt it returns 11234567890, and so on.
Hope this will help. Best regards,

Related

Is there built-in excel functions that can check for: "10" (or any number) in "1,3,5-9,13,16-20,23"?

As mentioned in the title, I wonder if there is any way to use built-in functions in excel to see whether a cell contains a specific number and count the total numbers in the cell. The cell can contain a list of numbers seperated by comas, for instance, "1,4,7" or ranges "10-25" or a combination of both. See the print screen.
No, there is not, but you could write a VBA function to do that, something like:
Function NumberInValues(number As String, values As String) As Boolean
Dim n As Integer
n = CInt(number)
Dim parts() As String
parts = Split(values, ",")
For i = LBound(parts) To UBound(parts)
parts(i) = Replace(parts(i), " ", "")
Next
Dim p() As String
Dim first As Integer
Dim last As Integer
Dim tmp As Integer
For i = LBound(parts) To UBound(parts)
p = Split(parts(i), "-")
' If there is only one entry, check for equality:
If UBound(p) - LBound(p) = 0 Then
If n = CInt(p(LBound(p))) Then
NumberInValues = True
Exit Function
End If
Else
' Check against the range of values: assumes the entry is first-last, does not
' check for last > first.
first = CInt(p(LBound(p)))
last = CInt(p(UBound(p)))
If n >= first And n <= last Then
NumberInValues = True
Exit Function
End If
End If
Next
NumberInValues = False
End Function
and then your cell C2 would be
=NumberInValues(B2,A2)
Calculating how many numbers there are in the ranges would be more complicated as numbers and ranges could overlap.
The key part of implementing this is to create a List or Array of individual numbers that includes all the Numbers represented in the first column.
Once that is done, it is trivial to check for an included, or do a count.
This VBA routine returns a list of the numbers
Option Explicit
Function createNumberList(s)
Dim AL As Object
Dim v, w, x, y, I As Long
Set AL = CreateObject("System.Collections.ArrayList")
v = Split(s, ",")
For Each w In v
'If you need to avoid duplicate entries in the array
'uncomment the If Not lines below and remove the terminal double-quote
If IsNumeric(w) Then
'If Not AL.contains(w) Then _"
AL.Add CLng(w)
Else
x = Split(w, "-")
For I = x(0) To x(1)
'If Not AL.contains(I) Then _"
AL.Add I
Next I
End If
Next w
createNumberList = AL.toarray
End Function
IF your numeric ranges might be overlapping, you will need to create a Unique array. You can do that by changing the AL.Add function to first check if the number is contained in the list. In the code above, you can see instructions for that modification.
You can then use this UDF in your table:
C2: =OR($B2=createNumberList($A2))
D2: =COUNT(createNumberList($A2))
Here is a possible formula solution using filterxml as suggested in the comment:
=LET(split,FILTERXML("<s><t>+"&SUBSTITUTE(A2,",","</t><t>+")&"</t></s>","//s/t"),
leftn,LEFT(split,FIND("-",split&"-")-1),
rightn,IFERROR(RIGHT(split,LEN(split)-FIND("-",split)),leftn),
SUM(rightn-leftn+1))
The columns from F onwards show the steps for the string in A2. I had to put plus signs in because Excel converted a substring like "10-15" etc. into a date as usual.
Then to find if a number (in C2 say) is present:
=LET(split,FILTERXML("<s><t>+"&SUBSTITUTE(A2,",","</t><t>+")&"</t></s>","//s/t"),
leftn,LEFT(split,FIND("-",split&"-")-1),
rightn,IFERROR(RIGHT(split,LEN(split)-FIND("-",split)),leftn),
SUM((--leftn<=C2)*(--rightn>=C2))>0)
As noted by #Ron Rosenfeld, it's possible that there may be duplication within the list: the Count formula would be susceptible to double counting in this case, but the Check (to see if a number was in the list) would give the correct result. So the assumptions are:
(1) No duplication (I think it would be fairly straightforward to check for duplication, but less easy to correct it)
(2) No range in wrong order like 15-10 (although this could easily be fixed by putting ABS around the subtraction in the first formula).
Here is a little cheeky piece of code for a VBA solution:
Function pageCount(s As String)
s = Replace(s, ",", ",A")
s = Replace(s, "-", ":A")
s = "A" & s
' s now looks like a list of ranges e.g. "1,2-3" would give "A1,A2:A3"
pageCount = Union(Range(s), Range(s)).Count
End Function
because after all the ranges in the question behave exactly like Excel ranges don't they?
and for inclusion (of a single page)
Function includes(s As String, m As String) As Boolean
Dim isect As Range
s = Replace(s, ",", ",A")
s = Replace(s, "-", ":A")
s = "A" & s
Set isect = Application.Intersect(Range(s), Range("A" & m))
includes = Not (isect Is Nothing)
End Function

How to find the text between two values in a string?

I currently have a cell("Filename"). This returns H:\F0791\Purchase Requisitions\[PCS.xlsm].
I would like to single out the 'F0791' Value. I have previously used MID functions however, this does not work if 'F0791' is a different length.
Would it be possible to call up the values between the first two '\'s or is there a better alternative?
I am seeking this in both formula state and VBA. This is different to other questions because they do not offer a formula alternative.
You could use this UDF, that uses the Split Function
Function EXTRACTELEMENT(Txt As String, n, Separator As String) As String
On Error GoTo ErrHandler:
EXTRACTELEMENT = Split(Application.Trim(Mid(Txt, 2)), Separator)(n - 1)
Exit Function
ErrHandler:
' error handling code
MsgBox "ERROR: Verify if the data exists, example if the separator is correct."
On Error GoTo 0
End Function
And this is a test in VBA
Sub test()
Text = "H:\F0791\Purchase Requisitions[PCS.xlsm]"
Debug.Print EXTRACTELEMENT(CStr(Text), 2, "\")
End Sub
And you could also add it to a Cell, If E1= "H:\F0791\Purchase Requisitions[PCS.xlsm]" Then you add this to the desired result cell.
On cell F1, this formula:=EXTRACTELEMENT(E1;2;"\") gives the result on the image below:
Or open the insert function window
Optional, Description for UDF
This code adds a description for the UDF. You must run it once.
Sub DescribeFunction()
Dim FuncName As String
Dim FuncDesc As String
Dim Category As String
Dim ArgDesc(1 To 3) As String
FuncName = "EXTRACTELEMENT"
FuncDesc = "Returns the nth element of a string that uses a separator character"
Category = 7 'Text category
ArgDesc(1) = "String that contains the elements"
ArgDesc(2) = "Element number to return"
ArgDesc(3) = "Single-character element separator (spc default)"
Application.MacroOptions _
Macro:=FuncName, _
Description:=FuncDesc, _
Category:=Category, _
ArgumentDescriptions:=ArgDesc
End Sub
Another formula approach is to use this formula =MID(A1,4,FIND("----",SUBSTITUTE(A1,"\","----",2),1)-4) in cell B2 in case your strings are in column A
For a formula approach, the following worked for me, given that the "filename" cell is in A1:
=MID(A1,FIND("\",A1)+1,((FIND("\",A1,FIND("\",A1)+1))-(FIND("\",A1))-1))
This basically finds the position of the first "\" and the second "\" and uses the mid() function to pull the string between the two "\"s.
=MID(A2, FIND("\", A2)+1, FIND("\", A2, 4) - 4)
This worked for me assuming that the structure is more or less the same except with regard to the length of the code.

Get value between multiple parenthesis with excel/airtable formula

I'm trying to get all the content between multiple parenthesis and comma delimiting them. So for example
A1 contains
thisfile.jpg (/path/to/file.jpg), thisfile2.jpg (/path/to/file2.jpg)
and B1 should look like
/path/to/file.jpg, /path/to/file2.jpg
If it's just one entry I can get what I need with this:
MID(A1,FIND("(",A1)+1,FIND(")",A1)-FIND("(",A1)-1)
But that only returns the first one, I need to be for each parenthesis. The amount of parenthesis in each row will vary.
I am sure there are better solutions out there with formulas only. Yet, I cannot help you there. But the following UDF is surely also a feasible solution. Just copy this code into an empty module:
Option Explicit
Public Function GetPaths(strTMP As String)
Dim i As Long
Dim varArray As Variant
varArray = Split(strTMP, "(")
For i = LBound(varArray) To UBound(varArray)
If InStr(1, varArray(i), ")") > 0 Then
GetPaths = GetPaths & ", " & Mid(varArray(i), 1, InStr(1, varArray(i), ")") - 1)
End If
Next i
GetPaths = Mid(GetPaths, 3)
End Function
Afterwards, you can use this formula in column B as follows: =GetPaths(A1).

Not able to split for multiple special characters

I am trying to split cell value up to last "\" in string
'C:\Users\punateng\Desktop\Pending Spec Updates.xlsx' in cell A1 so that result in cell B1 should be 'C:\Users\punateng\Desktop\'
I have written below code:
Sub mu()
Cells(1, 2).Value = Split(Cells(1, 1).Value, "\")
End Sub
But i am getting result as C: in cell B1.
Please help.
This is a case where a function is better than a sub.
Excel has Find and Search functions but doesn't have a FindLast function.
In a User Defined Function (UDF) you can use some functions that aren't available in the Application.WorksheetFunction collection. One of them is InstrRev which finds the position of the first instance of a string like "\" reading backwards from the end of the string. Using This little gem of knowledge and text editing functions you can build this UDF:
Function FileNameFromPath(Path1 As String)
'Test if you have been parsed an network file path
If InStr(1, Path1, "\") > 0 Then
'Get whatever is after the last "\"
FileNameFromPath = Right(Path1, Len(Path1) - InStrRev(Path1, "\"))
Else
'Could be a SharePoint file with http// address
If InStr(1, Path1, "\") > 0 Then
'Get whatever is after the last "/"
FileNameFromPath = Right(Path1, Len(Path1) - InStrRev(Path1, "/"))
Else
'There isn't a path separator there
FileNameFromPath = "That ain't a path"
End If
End If
End Function
So you can call this UDF in any cell in your workbook by typing "=fi", hitting Tab to paste it into your cell, then selecting the cell you want to test and enter a end bracket ")".
Split returns a string array, which in this case will consist of each part of the input text that was previously separated by a \ - so, you are actually returning the array {"C:";"Users";"punateng";"Desktop";"Pending Spec Updates.xlsx"}. When you try to paste this into Cells(1,2), VBA just interprets this as being the first element of the string array.
Instead, you might want to try
Cells(1,2).Value=Left(Cells(1,1).Value,InstrRev(Cells(1,1).Value,"\")-1)
which should find the last instance of \ and return the text before it.

How to trim letter/characters off the end of a cell entry

I have entries in cells like this:
75864543&m
2211842
1523674&mr
3452435tr
The cells have varying numbers of numeric values, and some have characters/letters at the end. I want to trim everything off except numeric values, but am stuck due to the varying length of number values.
Does anyone have a workaround?
Assuming between 1 & 9 digits at the start of the data (adjust as required) you can use this formula
=LOOKUP(10^10,LEFT(A1,{1,2,3,4,5,6,7,8,9})+0)
Try the following User Defined Function:
Public Function ReturnNumerals(rng As Range) As String
Dim sStr As String, i As Long, sStr1 As String
Dim sChar As String
sStr = rng.Value
For i = 1 To Len(sStr)
sChar = Mid(sStr, i, 1)
If sChar Like "[0-9]" Then
sStr1 = sStr1 & sChar
End If
Next
ReturnNumerals = sStr1
End Function
EDIT #1:
If you are "macrophobic" or VBA is ruled out for other reasons, Then try this array formula:
=MID(SUMPRODUCT(--MID("01"&A1,SMALL((ROW($1:$300)-1)*ISNUMBER(-MID("01"&A1,ROW($1:$300),1)),ROW($1:$300))+1,1),10^(300-ROW($1:$300))),2,300)
Array formulas must be entered with CNTRL-SHFT-ENTER rather than just the ENTER key!
For example, if A1 contains:
a123wer98bg5
the ugly array formula will return:
123985

Resources