Extract numbers from cells of varying lengths/formats - excel

I am looking for a formula to extract digits from column A. The problem I am running into is the varying lengths and formats. I am seeking a solution based on the desired result column below.
Formula in Column B:
=IFERROR(INT(LEFT(REPLACE(SUBSTITUTE(A4,"-"," "),1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},A4&1/17))-1,""),5)),INT(LEFT(REPLACE(SUBSTITUTE(A4,"-"," "),1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},A4&1/17))-1,""),4)))
Workbook:
Thank you!

Try the following User Defined Function:
Public Function LastNumber(s As String) As Variant
Dim L As Long, i As Long, temp As String, arr
Dim CH As String
L = Len(s)
temp = ""
For i = 1 To L
CH = Mid(s, i, 1)
If CH Like "[0-9]" Then
temp = temp & CH
Else
temp = temp & " "
End If
Next i
arr = Split(Application.WorksheetFunction.Trim(temp), " ")
For i = UBound(arr) To LBound(arr) Step -1
If IsNumeric(arr(i)) Then
LastNumber = CLng(arr(i))
Exit Function
End If
Next i
LastNumber = ""
End Function
It will return the last number (set of numerals) in a string.
User Defined Functions (UDFs) are very easy to install and use:
ALT-F11 brings up the VBE window
ALT-I
ALT-M opens a fresh module
paste the stuff in and close the VBE window
If you save the workbook, the UDF will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the UDF:
bring up the VBE window as above
clear the code out
close the VBE window
To use the UDF from Excel:
=myfunction(A1)
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
and for specifics on UDFs, see:
http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx
Macros must be enabled for this to work!

Try this user defined function in a standard public module code sheet.
function lastNumber(str as string)
dim i as long, tmp as string
tmp = str
for i=len(tmp) to 1 step-1
if asc(right(tmp, 1))<48 or asc(right(tmp, 1))>57 then
tmp = left(tmp, len(tmp)-1)
else
exit for
end if
next i
for i=len(tmp) to 1 step-1
if asc(mid(tmp, i))<48 or asc(mid(tmp, i))>57 then
exit for
end if
next i
lastNumber = mid(tmp, i+1)
end function

You could use Regex, which needs a reference to Microsoft VBScript Regular Expressions:
Public Function GetLastNum(str As String) As String
Dim numRegEx As RegExp
Set numRegEx = New RegExp
Dim matchColl As MatchCollection
Dim retStr As String
With numRegEx
.Global = True
.Pattern = "[0-9]+"
Set matchColl = .Execute(str)
If matchColl.Count > 0 Then
GetLastNum = matchColl.Item(matchColl.Count - 1)
Exit Function
End If
End With
End Function

Related

Excel - Using IF and OR

Here is my code as text:
Function NurZahl(ByVal Text As String) As Long
Dim i%, tmp
Dim Val As String
For i = 1 To Len(Text)
Val = Mid(Text, i, 1)
If(OR(IsNumeric(Val),Val=","),TRUE, FALSE) Then tmp = tmp & Mid(Text, i, 1)
Next i
NurZahl = tmp
End Function
Complete Beginner here:
What is my problem with the if?
Is there a possibility to show me the exact problem in excel?
The text is only highlighted with red color - if
i hover with the mouse-arrow above, there is no error message given.
This is my source of my knowledge for the structure of my if: Support Microsoft - Is this the wrong type of documentation for me?
Got the solution now with your help (thanks to everyone who replied) - I wanted to extract a number with decimal from a string:
Function CleanString(strIn As String) As String
Dim objRegex
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Global = True
.Pattern = "[^\d,]+"
CleanString = .Replace(strIn, vbNullString)
End With
End Function
The "If" line is written like an Excel formula. This is what is should look like in basic.
If IsNumeric(Val) Or Val = "," Then tmp = tmp & Mid(Text, i, 1)
The red text is a syntax error. If you go to the Debug menu and click Compile VBA Project, you'll get the error message.
The link that you included is for functions that are typed into a cell. You need a VBA reference. Here's a link to MS's reference, but a decent book would make your life a lot easier. Just search for "Excel VBA".
https://learn.microsoft.com/en-us/office/vba/api/overview/
You can try something like this:
Function NurZahl (ByVal MyText As String) As Long
' Set up the variables
Dim i as Integer
Dim tmp as String
Dim MyVal As String
' Start tmp with an empty string
tmp = ""
' Loop through each character of the input MyText
For i = 1 To Len(MyText)
' Read the character
MyVal = Mid(MyText, i, 1)
' Check whether the character is a number or a comma
' and take reasonable action
If IsNumeric(MyVal) or MyVal = "," then
tmp = tmp & Mid(MyText, i, 1)
End if
Next i
NurZahl = tmp
End Function
You'll have to change the code above to do what you want to do. The illustration above is to show how VBA code can be written.
In your VBA editor, when you see a red color on a line that means the editor has detected some issue with it.
If you were writing this function in Excel, you would typically use that function in a cell like this: =NurZahl(A1)

After Setting a value in cell function/sub then program exits - Macro VBA

After searching more for this solution I asked in SO. I just trying to automate the work and new bie in VBA code. Here I m facing problem that when I update cell value in excel using macro. Then the program stops it not procceds to next step.
My sample code:
Private Function trim_Func(i As Integer, j As Integer) As String
Dim fStr As String
Set Workx = ActiveWorkbook.Sheets("Sales").Cells(i, j)
fStr = ActiveWorkbook.Sheets("Sales").Cells(i, j)
fStr = trim(fStr)
ActiveWorkbook.Sheets("Sales").Cells(i, j) = fStr
MsgBox Workx
trim_Func = "Yes"
End Function
Here After this line "ActiveWorkbook.Sheets("Sales").Cells(i, j) = fStr the function stopped not calling MsgBox or anyother. But the value is changed. I have another function after this to be called.
Edit: The Trim function is called like this after a button click in excel sheet.
Private Sub CommandButton1_Click()
Dim data_value As String
data_value = trim_Func(2, 6)
// Some other conditions and functions
Edit :
I have provided sample tested screenshot. It does not return function or not going next to that value changed in cell.
Excel:
Code:
Thanks all. I have found solution after much thinking. Made some mistake by asigning value in Set. Thats problem.
Function trim_Func(i As Integer, j As Integer) As String
Dim fStr As String
fStr = ActiveWorkbook.Sheets("Sales").Cells(i, j)
fStr = trim(fStr)
ActiveWorkbook.Sheets("Sales").Cells(i, j) = fStr
trim_Func = "Yes"
End Function

How to copy from excel multine cells without quote duplication?

When I paste it into any editor, quotes appear at the end and at beginning, and the quotes inside gets duplicated.
Create a macro and try the following code:
Sub copy()
'If needed Attach Microsoft Forms 2.0 Library: tools\references\Browse\FM20.DLL
'Then set a keyboard shortcut to the CopyCells Macro (eg Crtl T)
Dim objData As New DataObject
Dim cell As Object
Dim concat As String
Dim cellValue As String
CR = ""
For Each cell In Selection
If IsNumeric(cell.Value) Then
cellValue = LTrim(str(cell.Value))
Else
cellValue = cell.Value
End If
concat = concat + CR + cellValue
CR = Chr(13)
Next
objData.SetText (concat)
objData.PutInClipboard 
End Sub

Excel VBA - how to find the largest substring value in a column

I have a column in a spreadsheet.
The format of the data in each cell is aa-0001-xx.
I need to examine the whole column to find the highest value of the sequence number. this would be the substring from column4 thru column7.
I can find the sequence number using Mid(ActiveWorkbook.Sheets("Sheet1").Range("B2:B2"), 4, 4)
But I need to find the max sequence in the whole column.
I am doing this in VBA.
Any help would be appreciated.
Here is my code so far:
Private Sub CommandButton1_Click()
Dim sQuoteNumber As String
Dim sFileName As String
Dim sPathName As String
Dim checkit As String
'Log the Quote
'First, open the log file and determine the next sequential log number.
sPathName = "C:\Users\Rich\Documents\Bryan\BigProject\"
sFileName = "QuoteLog2016.xlsx"
ControlFile = ActiveWorkbook.Name
Workbooks.Open Filename:=sPathName & sFileName
'Create the new Quote Number
checkit = Mid(ActiveWorkbook.Sheets("Sheet1").Range("B2:B2"), 4, 4) ' This is a temp test line
If Mid(ActiveWorkbook.Sheets("Sheet1").Range("B2:B2"), 4, 4) = "" Then
sQuoteNumber = "16-0001"
Else
'find the biggest number
'Here I was looking to like pass the mid function to a Max function of some sort.
sQuoteNumber = "16-0002"
End If
MsgBox ("The new Quote Number is: " + sQuoteNumber)
'Save the log entry
Workbooks(sFileName).Close
All of the comments made to your answer would work well for you. It's also true that there's no evidence in your code at having attempted something, however rudimentary, and this is why answers to a rather trivial task are not forthcoming for you. Perhaps, in future, have a go at some kind of solution ( even if it feels more guesswork than anything) and people on this site will be much more supportive of you.
To set you on your way, you could make use of the Split() function which converts a String into a String array, separated by a nominated value - in the case of your quotations, you could use "-" as your separator. This might be easier than your Mid function and will deal with the case of different sized quotations.
The code below will get you started but you'd want some error handling in there to test, for example, that each cell splits appropriately or that any cells aren't blank. I'll leave all of that to you.
Option Explicit
Private mLastQuote As Long
Public Sub Test()
Initialise 'call this routine just once at the start of your project
MsgBox GetNextQuote(16) 'use the GetNextQuote() function to get next number
MsgBox GetNextQuote(16)
MsgBox GetNextQuote(16)
End Sub
Private Function GetNextQuote(prefix As Integer) As String
mLastQuote = mLastQuote + 1
GetNextQuote = CStr(prefix) & "-" & _
Format(mLastQuote, "000#")
End Function
Private Sub Initialise()
Const PATH_NAME As String = "C:\Users\Rich\Documents\Bryan\BigProject\"
Const FILE_NAME As String = "QuoteLog2016.xlsx"
Const QUOTE_COL As String = "B"
Dim wb As Workbook
Dim ws As Worksheet
Dim v As Variant
Dim r As Long
Dim parts() As String
Dim num As Long
Application.ScreenUpdating = False
Set wb = Workbooks.Open(PATH_NAME & FILE_NAME, True, True)
Set ws = wb.Worksheets("Sheet1")
'Read quote values into variant array
With ws
v = .Range(.Cells(2, QUOTE_COL), _
.Cells(.Rows.Count, QUOTE_COL).End(xlUp)) _
.Value2
End With
'Find max quote
For r = 1 To UBound(v, 1)
parts = Split(v(r, 1), "-") 'splits quote into 3 parts
num = CLng(parts(1)) 'index (1) is the middle part
If num > mLastQuote Then mLastQuote = num
Next
wb.Close False
Application.ScreenUpdating = True
End Sub

Get a list of the macros of a module in excel, and then call all those macros

Please help with the following:
1) A code that sets a list of all macros of "Module3", and place this list in "Sheet5", starting in cell "E14" below.
2) Then, the code should run all the listed macros
I tried with a code that referred VBComponent, but I got an error.
Based on my google search, I found the answer That I commented you , but They forgot and important thing, that is check and option to allow you run the macro.
First the Function to list all macros in excel and return and string separated by white space:
Function ListAllMacroNames() As String
Dim pj As VBProject
Dim vbcomp As VBComponent
Dim curMacro As String, newMacro As String
Dim x As String
Dim y As String
Dim macros As String
On Error Resume Next
curMacro = ""
Documents.Add
For Each pj In Application.VBE.VBProjects
For Each vbcomp In pj.VBComponents
If Not vbcomp Is Nothing Then
If vbcomp.CodeModule = "Module_name" Then
For i = 1 To vbcomp.CodeModule.CountOfLines
newMacro = vbcomp.CodeModule.ProcOfLine(Line:=i, _
prockind:=vbext_pk_Proc)
If curMacro <> newMacro Then
curMacro = newMacro
If curMacro <> "" And curMacro <> "app_NewDocument" Then
macros = curMacro + " " + macros
End If
End If
Next
End If
End If
Next
Next
ListAllMacroNames = macros
End Function
The next step, of well could be the first one, you need to change some configuration of the office (Excel) trustcenter, check the follow images:
Step 1:
Step 2:
Step 3 (Final) Check the option "rely on access to the data model project vba":
Then you need to add this reference to your Excel:
Don't worry if you have another version of Microsoft Visual Basic for Applications Extensibility, in this case is 5.3. Check and then accept.Don't forget that you need to find that reference, there is no on the top of the list.
Finally you can invoke the ListAllMacroNames ( ) function With This other macro named execute () , Look That I 'm Validated That doesn't call the same macros (execute , ListAllMacroNames ) or could make an infinite loop.
Public Sub execute()
Dim AppArray() As String
AppArray() = Split(ListAllMacroNames, " ")
For i = 0 To UBound(AppArray)
temp = AppArray(i)
If temp <> "" Then
If temp <> "execute" And temp <> "ListAllMacroNames" Then
Application.Run (AppArray(i))
Sheet5.Range("E" & i + 14).Value = temp
End If
End If
Next i
End Sub
EDIT 2 Change "Module_name" in first method, to your desire module, and set the corret sheet name (in this case Sheet 5) in execute method.

Resources