Center aligning largest number in selection by indenting - excel

I have a longstanding formatting frustration. I often do this manually but doing it manually takes forever, and there has to be a way to do this with either a VBA macro, conditional formatting or a clever number format.
Below is my desired result. It has the following properties:
The largest number in the column (in this case the last number in the column, $103,420) is centered within the cell.
The largest number in the cell is not, however, center aligned, it is right indented until the value is centered.
All other numbers in the column are also right indented an equal amount. This is desirable because it lines up the ones place, tens place etc. in each number.
Negative numbers are denoted surrounded by parentheses.
The dollar sign is adjacent to the leftmost number.
Commas are included properly for numbers greater than 999.
This result was achieved by:
Applying the following number format:$#,##0_);($#,##0)_);$0_);#_)
Manually adjusting the right indent of the cell on the largest number to determine when it is roughly centered. If more space must be on one side or the other, the larger space is left on the left side of the number.
I attempted to apply a number format similar to the one used in response to this question.
Specifically my attempt at using this was to center align all cells using the following number format: $?,??0;($?,??0);
That produces the following close but not quite result below.
Thoughts on how I can address this? I'm imagining a macro that identifies the largest number in the selection, gets the number of digits in that number, the font size, the width of the column, does some computation yielding the desired right indent and then applies the right indent. I'm just not sure how to do that kind of computation.

'Select your data range, and run formatCells_Accounting(). The number formatting in the selected cells will widen to the cell with the longest value. Note, the macro does not work on values greater than 10^14 (not sure why.)
Sub formatCells_Accounting()
Dim rg As Range
Set rg = Selection
maxVal = Application.WorksheetFunction.Max(rg)
minVal = Application.WorksheetFunction.Min(rg)
If Abs(minVal) > maxVal Then
longest_ = minVal
Else
longest_ = maxVal
End If
lenLongest = Len(CStr(Round(longest_, 0)))
rg.NumberFormat = "_($" & addCommasToFormat(lenLongest) & "_);" & _
"_(($" & addCommasToFormat(lenLongest) & ");" & _
"_($" & addCommasToFormat(lenLongest - 1) & "0_);" & _
"_(#_)"
End Sub
Function addCommasToFormat(ByVal lenLongest) As String
str_ = String(lenLongest, "?")
new_str_ = ""
For i = 1 To Len(str_)
If i Mod 3 = 1 And i <> 1 Then
new_str_ = new_str_ & ",?"
Else
new_str_ = new_str_ & "?"
End If
Next
addCommasToFormat = StrReverse(new_str_)
End Function

Chris - your answer doesn't do what I was hoping for (your answer leaves space between the dollar sign and the "last" digit for numbers shorter than the longest number in the set)
However, your code was a helpful starting point for this solution I've come up with. The result is shown in the image below along with the inherent downside to this solution - running a formula on the numbers in the column after they've been formatted in this way results in a weird number format.
The only solution I can come up with that doesn't have the problem this solution does is, one that relies on estimating an indent, and applying it. That solution only works so long as the column width is not adjusted going forwards. If it is adjusted the macro would have to be re-run. Additionally, because the indent can only be increased by an increment of 1 (and nothing less), a macro that applied an indent would typically result in the largest number in the column not being exactly centered. Not a huge deal but my current solution doesn't have either of these problems and in my use case, these formats are being applied as the last step in the process of formatting a spreadsheet so additional calculations aren't likely to happen and if they do, the macro can simply be re-run as needed.
'Select your data range, and run formatCells_Accounting(). The number formatting in the selected cells will widen to the cell with the longest value. Note, the macro does not work on values greater than 10^14 (not sure why.)
Sub formatCells_Accounting()
Dim rg, thisColRange, rCell As Range
Dim maxVal, minVal, valueLen, longest_, lenLongest As Long
Set rg = Selection
'Center aligns all selected cells
rg.HorizontalAlignment = xlCenter
'Loops through each column in the selected range so that each column can have it's own max value
For Each thisColRange In rg.Columns
maxVal = Application.WorksheetFunction.Max(thisColRange)
minVal = Application.WorksheetFunction.Min(thisColRange)
'The longest number in the range may be the most negative
'This if section accounts for this scenario
If Abs(minVal) > maxVal Then
longest_ = minVal
Else
longest_ = maxVal
End If
'Gets the length of the longest value rounded to the ones place (aka length not including decimals)
lenLongest = Len(CStr(Round(Abs(longest_), 0)))
'Creates a number format for every cell
For Each rCell In thisColRange.Cells
'Gets the length of the value in the current cell
valueLen = Len(CStr(Round(Abs(rCell.Value), 0)))
rCell.NumberFormat = "_(" & addCommasDollarsToFormat(lenLongest, valueLen, rCell.Value) & "_);" & _
"_(" & addCommasDollarsToFormat(lenLongest, valueLen, rCell.Value) & ")_);" & _
"_(" & Left(addCommasDollarsToFormat(lenLongest, 1, rCell.Value), Len(addCommasDollarsToFormat(lenLongest, 1, rCell.Value)) - 1) & "0_);" & _
"_(#_)"
Next
Next
End Sub
Function addCommasDollarsToFormat(ByVal lenLongest, ByVal valueLen, ByVal cellVal) As String
Dim new_str_ As String
Dim i, j As Long
'Initializes empty strings
new_str_ = ""
nearlyFinishedString = ""
'Adds ? and , through the length of the value currently being formatted
For i = 1 To valueLen
If i Mod 3 = 1 And i <> 1 Then
new_str_ = new_str_ & ",?"
Else
new_str_ = new_str_ & "?"
End If
Next
If cellVal < 0 Then
new_str_ = new_str_ & "$("
Else
new_str_ = new_str_ & "$"
End If
For j = i To lenLongest
If j Mod 3 = 1 Then
new_str_ = new_str_ & ",?"
Else
new_str_ = new_str_ & "?"
End If
Next
addCommasDollarsToFormat = StrReverse(new_str_)
End Function
Solution visualized with the downside of the solution shown below it.

Related

Give results in next column of predefined (but changing) words from text-cell

I have a chart with a text-column with numerous entries per cell.
Entries are separated with “;”.
Entries have the format “xy 00/00” (e.g. “AB 03/18”).
I need Excel to find and give in the next column a specific entry I predefine per row (above the column, example below).
Only the first two and last two characters are defined, the characters in the middle can be whatever (e.g. “AB ??/18”).
A cell can have more than one entry with the definition of “AB ??/18” (e.g. “AB 03/18” & “AB 08/18” etc.).
I need to know, if there are more than 1 of this predefined entries.
If I change the search box to “ZZ ??/12”, it should overwrite the previous defined search and give me back only the ZZ… ones.
For example:
Screenshot Chart
I tried a formula, but it gives me the first AB…, not the rest.
If it is only possible to give back the amount of the searched text in the cell above, that would also be ok.
Your screenshot doesn't seem entirely consistent with your objective, i.e.
the pattern AB ##/18 can be found 3 times in the string
blabla WF 12/23; AB 08/18; AB 09/18; AB 08/18
but your count column registers only 1 result (for AB 08/18)- there is also a match in the 1st row (for AB 12/18), but there you have a count of 0...
The code below assumes that the 4 data cells from your screenshot are in the range A3:A6 and that they are not part of a table
Sub txtMatching()
Dim results As String, cell As Range, incidence As Integer, pattern As String, pos As Integer, temp As String
pattern = "AB ##/18"
For Each cell In Range("A3:A6")
pos = 1
If cell.Value Like "*" & pattern & "*" Then
Do
pos = InStr(pos, cell.Value2, Mid(pattern, 1, InStr(1, pattern, "#") - 1))
If pos = 0 Then Exit Do
temp = Mid(cell.Value2, pos, Len(pattern))
If temp Like pattern Then
results = results & temp & "; "
incidence = incidence + 1
End If
pos = pos + Len(pattern)
Loop While pos < Len(cell.Value2)
cell.Offset(0, 1).Resize(1, 2).Value2 = Array(Mid(results, 1, Len(results) - 2), incidence)
results = vbNullString
incidence = 0
Else
cell.Offset(0, 2).Value2 = 0
End If
Next cell
End Sub

Can Excel Sort Differently Than Its Default U.S. Character Set?

My question is basically the opposite of THIS ONE (which had a database-based solution I can't use here).
I use SAP, which sorts characters this way:
0-9, A-Z, _
but I'm downloading data into Excel and manipulating ranges dependent on correct SAP character set sort order.
How can I force Excel to sort the same way as SAP, with underscore coming last.
After attempting a Custom Sort List of single characters in Excel's Sort feature, Excel still/always sorts like this:
_, 0-9, A-Z
Is there any way to get Excel to sort like SAP? I'm capable of doing Excel macros, if needed.
Alternatively, if anyone knows how to get native SAP tables to sort like Excel in the SAP interface, that would take care of this problem, as well.
The principle of the following solution is to insert a new column in which the cells have a formula which calculates a "sortable code" of each cell of the column that you want to sort.
If you sort this new column, the rows will be sorted in the ASCII order (0-9, A-Z, _).
It should be able to handle any number of rows. On my laptop, the calculation of cells takes 1 minute for 130.000 rows. There are two VBA functions, one for ASCII and one for EBCDIC. It's very easy to define other character sets.
Steps:
Create a module in your Excel workbook and place the code below.
Close the VB editor otherwise it will run slowly.
In the worksheet that you want to sort, insert one column for each column you want to sort, for instance let's say the sort is to be done for column A, create a new column B, in the cell B1 insert the formula =SortableCodeASCII(A1) and do the same for all the cells of column B (up to the last row of column A).
Make sure that the calculation of formulas is over (it takes 1 minute for 130.000 rows on my laptop), otherwise if you sort, the order will be incorrect because formulas are not yet calculated. You see the progress indicator (percentage) on the status bar at the bottom of the Excel window. If you don't see it, press Ctrl+Alt+F9.
Sort on column B. The values in column A should be sorted according to the ASCII order (0-9, A-Z, _)
Good luck!
Option Compare Text 'to make true "a" = "A", "_" < "0", etc.
Option Base 0 'to start arrays at index 0 (LBound(array) = 0)
Dim SortableCharactersASCII() As String
Dim SortableCharactersEBCDIC() As String
Dim SortableCharactersTEST() As String
Sub ResetSortableCode()
'Run this subroutine if you change anything in the code of this module
'to regenerate the arrays SortableCharacters*
Erase SortableCharactersASCII
Erase SortableCharactersEBCDIC
Erase SortableCharactersTEST
Call SortableCodeASCII("")
Call SortableCodeEBCDIC("")
Call SortableCodeTEST("")
End Sub
Function SortableCodeASCII(text As String)
If (Not Not SortableCharactersASCII) = 0 Then
SortableCharactersASCII = getSortableCharacters( _
orderedCharacters:=" !""#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}" & ChrW(126) & ChrW(127))
End If
SortableCodeASCII = getSortableCode(text, SortableCharactersASCII)
End Function
Function SortableCodeEBCDIC(text As String)
If (Not Not SortableCharactersEBCDIC) = 0 Then
SortableCharactersEBCDIC = getSortableCharacters( _
orderedCharacters:=" ¢.<(+|&!$*);-/¦,%_>?`:##'=""abcdefghi±jklmnopqr~stuvwxyz^[]{ABCDEFGHI}JKLMNOPQR\STUVWXYZ0123456789")
End If
SortableCodeEBCDIC = getSortableCode(text, SortableCharactersEBCDIC)
End Function
Function SortableCodeTEST(text As String)
If (Not Not SortableCharactersTEST) = 0 Then
SortableCharactersTEST = getSortableCharacters( _
orderedCharacters:="ABCDEF 0123456789_")
End If
SortableCodeTEST = getSortableCode(text, SortableCharactersTEST)
End Function
Function getSortableCharacters(orderedCharacters As String) As String()
'Each character X is assigned another character Y so that sort by character Y will
'sort character X in the desired order.
maxAscW = 0
For i = 1 To Len(orderedCharacters)
If AscW(Mid(orderedCharacters, i, 1)) > maxAscW Then
maxAscW = AscW(Mid(orderedCharacters, i, 1))
End If
Next
Dim aTemp() As String
ReDim aTemp(maxAscW)
j = 0
For i = 1 To Len(orderedCharacters)
'Was a character with same "sort weight" previously processed ("a" = "A")
For i2 = 1 To i - 1
If AscW(Mid(orderedCharacters, i, 1)) <> AscW(Mid(orderedCharacters, i2, 1)) _
And Mid(orderedCharacters, i, 1) = Mid(orderedCharacters, i2, 1) Then
'If two distinct characters are equal when case is ignored (e.g. "a" and "A")
'(this is possible only because directive "Option Compare Text" is defined at top of module)
'then only one should be used (either "a" or "A" but not both), so that the Excel sorting
'does not vary depending on sorting option "Ignore case".
Exit For
End If
Next
If i2 = i Then
'NO
aTemp(AscW(Mid(orderedCharacters, i, 1))) = Format(j, "000")
j = j + 1
Else
'YES "a" has same weight as "A"
aTemp(AscW(Mid(orderedCharacters, i, 1))) = aTemp(AscW(Mid(orderedCharacters, i2, 1)))
End If
Next
'Last character is for any character of input text which is not in orderedCharacters
aTemp(maxAscW) = Format(j, "000")
getSortableCharacters = aTemp
End Function
Function getOrderedCharactersCurrentLocale(numOfChars As Integer) As String
'Build a string of characters, ordered according to the LOCALE order.
' (NB: to order by LOCALE, the directive "Option Compare Text" must be at the beginning of the module)
'Before sorting, the placed characters are: ChrW(0), ChrW(1), ..., ChrW(numOfChars-1), ChrW(numOfChars).
'Note that some characters are not used: for those characters which have the same sort weight
' like "a" and "A", only the first one is kept.
'For debug, you may define constdebug=48 so that to use "printable" characters in sOrder:
' ChrW(48) ("0"), ChrW(49) ("1"), ..., ChrW(numOfChars+47), ChrW(numOfChars+48).
sOrder = ""
constdebug = 0 'Use 48 to help debugging (ChrW(48) = "0")
i = 34
Do Until Len(sOrder) = numOfChars
Select Case constdebug + i
Case 0, 7, 14, 15: i = i + 1
End Select
sCharacter = ChrW(constdebug + i)
'Search order of character in current locale
iOrder = 0
For j = 1 To Len(sOrder)
If AscW(sCharacter) <> AscW(Mid(sOrder, j, 1)) And sCharacter = Mid(sOrder, j, 1) Then
'If two distinct characters are equal when case is ignored (e.g. "a" and "A")
'("a" = "A" can be true only because directive "Option Compare Text" is defined at top of module)
'then only one should be used (either "a" or "A" but not both), so that the Excel sorting
'does not vary depending on sorting option "Ignore case".
iOrder = -1
Exit For
ElseIf Mid(sOrder, j, 1) <= sCharacter Then
'Compare characters based on the LOCALE order, that's possible because
'the directive "Option Compare Text" has been defined.
iOrder = j
End If
Next
If iOrder = 0 Then
sOrder = ChrW(constdebug + i) & sOrder
ElseIf iOrder = Len(sOrder) Then
sOrder = sOrder & ChrW(constdebug + i)
ElseIf iOrder >= 1 Then
sOrder = Left(sOrder, iOrder) & ChrW(constdebug + i) & Mid(sOrder, iOrder + 1)
End If
i = i + 1
Loop
'Last character is for any character of input text which is not in orderedCharacters
sOrder = sOrder & ChrW(constdebug + numOfChars)
getOrderedCharactersCurrentLocale = sOrder
End Function
Function getSortableCode(text As String, SortableCharacters() As String) As String
'Used to calculate a sortable text such a way it fits a given order of characters.
'Example: instead of order _, 0-9, Aa-Zz you may want 0-9, Aa-Zz, _
'Will work only if Option Compare Text is defined at the beginning of the module.
getSortableCode = ""
For i = 1 To Len(text)
If AscW(Mid(text, i, 1)) < UBound(SortableCharacters) Then
If SortableCharacters(AscW(Mid(text, i, 1))) <> "" Then
getSortableCode = getSortableCode & SortableCharacters(AscW(Mid(text, i, 1)))
Else
'Character has not an order sequence defined -> last in order
getSortableCode = getSortableCode & SortableCharacters(UBound(SortableCharacters))
End If
Else
'Character has not an order sequence defined -> last in order
getSortableCode = getSortableCode & SortableCharacters(UBound(SortableCharacters))
End If
Next
'For two texts "a1" and "A1" having the same sortable code, appending the original text allows using the sort option "Ignore Case"/"Respecter la casse"
getSortableCode = getSortableCode & " " & text
End Function
EDIT: this solution is based on the automatic calculation of a custom order list, but it doesn't work if there are too many distinct values. In my case it worked with a custom order list of maybe a total of 35.000 characters, but it failed for the big list of the original poster.
The following code sorts the requested column(s) by ASCII value, which has this kind of order:
0-9, A-Z, _, a-z
I guess the lower case being separated from the upper case is not an issue as SAP defines values mostly in upper case. If needed, the code can be easily adapted to obtain the custom order 0-9, Aa-Zz, _ (by using UCase and worksheet.Sort.MatchCase = False).
This order is different from the built-in Excel sort order which is based on the locale. For instance, in English, it would be:
_, 0-9, Aa-Zz
The principle is to use a "custom order list" whose values are taken from the Excel column, made unique, and sorted with a QuickSort3 algorithm (subroutine MedianThreeQuickSort1 provided by Ellis Dee at http://www.vbforums.com/showthread.php?473677-VB6-Sorting-algorithms-(sort-array-sorting-arrays)).
Performance notes about the Excel sorting via custom list (I'm not talking about QuickSort3):
The more the distinct values in the custom order list, the lower the performance. 4,000 rows having 20 distinct values are sorted immediately, but 4,000 rows having 4,000 distinct values takes 8 seconds to sort!
For the same number of distinct values, the performance does not change a lot if there are many rows to sort. 300,000 rows having 6 distinct values takes 3 seconds to sort.
Sub SortByAsciiValue()
With ActiveSheet.Sort
.SortFields.Clear
.SetRange Range("A:A").CurrentRegion
.SortFields.Add Key:=Columns("A"), Order:=xlAscending, _
CustomOrder:=DistinctValuesInAsciiOrder(iRange:=Columns("A"), Header:=True)
.Header = xlYes
.Apply
End With
End Sub
Function DistinctValuesInAsciiOrder(iRange As Range, Header As Boolean) As String
Dim oCell As Range
Dim oColl As New Collection
On Error Resume Next
For Each oCell In iRange.Cells
Err.Clear
If Header = True And oCell.Row = iRange.Row Then
ElseIf oCell.Row > iRange.Worksheet.UsedRange.Rows.Count Then
Exit For
Else
dummy = oColl.Item(oCell.Text)
If Err.Number <> 0 Then
oColl.Add oCell.Text, oCell.Text
totalLength = totalLength + Len(oCell.Text) + 1
End If
End If
Next
On Error GoTo 0
If oColl.Count = 0 Then
Exit Function
End If
Dim values() As String
ReDim values(1)
ReDim values(oColl.Count - 1 + LBound(values))
For i = 1 To oColl.Count
values(i - 1 + LBound(values)) = oColl(i)
Next
Call MedianThreeQuickSort1(values)
' String concatenation is complex just for better performance (allocate space once)
DistinctValuesInAsciiOrder = Space(totalLength - 1)
Mid(DistinctValuesInAsciiOrder, 1, Len(values(LBound(values)))) = values(LBound(values))
off = 1 + Len(values(LBound(values)))
For i = LBound(values) + 1 To UBound(values)
Mid(DistinctValuesInAsciiOrder, off, 1 + Len(values(i))) = "," & values(i)
off = off + 1 + Len(values(i))
Next
End Function

VBA number formatting (with commas as decimal separator)

The main problem started when I wanted to "convert to number" by the green triangle (I know I can do it by hand, but there are a lot of cells like that and in the future I only want to use code).
So I wanted to do it by code, and I came across with this code that helps, but I have a problem with the number format which removes the decimal numbers.
Sub Valor3()
Dim LastRow As Long, i As Long
LastRow = Sheets("Hoja3").Range("A" & Rows.Count).End(xlUp).Row
'Sheets("Hoja3").Range("A1:A" & LastRow).NumberFormat = "# ##0,00"
For i = 1 To LastRow
If Val(Sheets("Hoja3").Range("A" & i).Value) <> 0 Then _
Sheets("Hoja3").Range("A" & i).Formula = _
Val(Sheets("Hoja3").Range("A" & i).Value)
Next i
End Sub
I've been trying many formats but none of them seems to help.
It might be because here we use the comma as a decimal separator and there is no miles separator.
What number format would help me?
The issue is that you use Val function in combination with a non-us-english decimal separator, which is not a proper solution to your issue.
The Val function recognizes only the period ( .) as a valid decimal separator. When different decimal separators are used, as in international applications, use CDbl instead to convert a string to a number.
Source: Microsoft documentation Val function.
Since the Val function does not convert a text into a value but extracts
The Val function only works with a dot . as decimal separator.
Example:
Val("2.55") 'will return 2.55 as number
Val("2,55") 'will return 2 as number (because it cuts off all text and the comma is not considered as decimal separator)
To get rid of the green triangle and convert a number that is saved as text into a real number properly, use the following:
Option Explicit
Public Sub ConvertNumberAsTextIntoRealNumber()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Hoja3")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
With ws.Range("A1", "A" & LastRow)
.NumberFormat = "# ##0.00" 'set your desired number format
.Value = .Value 'this will in most cases already convert to real numbers.
End With
'But if your numbers are hard coded to text and begin with a `'` you need the following additionally:
Dim iRow As Long
For iRow = 1 To LastRow
With ws.Cells(iRow, "A")
If IsNumeric(.Value) Then 'can the value be interpreted as a number
If .Value <> 0 Then 'is the value not zero
.Value = CDbl(.Value) 'then convert it into a real number
End If
End If
End With
Next iRow
End Sub
I know you are looking for VBA solution, but here's a small Excel trick that you might find useful:
Enter 1 (numeric value) somewhere in the file and copy it:
Select your range (A1:A6) and go to Paste > Paste Special > select Multiply:
The final result is all your text values being converted to numbers:
The same trick will work with other combinations, e.g. Operation: Add while having 0 copied, etc.

Any ideas why VBA isn't being case-sensitive in a VLookup?

I've created a VBA Macro to look at a string of input text in the cell E3, split it into individual characters and then VLookup those characters against a table of individual character pixel widths, which is added to the code using a named range, "pw_Table".
The pixel-widths for each letter are then summed and displayed in a cell below the text input box - "Cells(4,5)". Hitting return is meant to show the combined pixel-width total for the complete string.
The problem is that it is not being case sensitive and is using the same VLookup value for both upper and lower case characters.
All the manuals I've seen say VBA is case sensitive on VLookup, and all I can find are ways to get around this.
For my issue, however, the VLookup must be case sensitive to make sure I get the correct pixel width for each letter, for example, "c" is 9 pixels wide, "C" is 13.
I have tried reordering the upper and lower case characters in the table to see if that made a difference, but it only uses the first values it encounters for each letter of the alphabet, whether they be upper- or lower-case.
I thought that I might use INDEX, MATCH, and EXACT, but couldn't see how to implement that in VBA.
This is the Macro code ...
Private Sub ReadCharacter()
cell_value = ThisWorkbook.Sheets("Pixel-widths").Range("E3")
Character_Value = 0
For rep = 1 To Len(cell_value)
Character = Mid(cell_value, rep, 1)
On Error GoTo MyErrorHandler
Character_Value = Application.WorksheetFunction.VLookup(Character, [pw_Table], 2, 0)
Pixel_Width = Pixel_Width + Character_Value
MyErrorHandler:
Character_Value = 10
Resume Next
Next rep
Cells(4, 5) = Pixel_Width
End Sub
I had some issues with numbers, with VBA reporting Run-time Error 1004, but I bodged this by adding an error trap because all the numerals from 0-9 are 10 pixels wide.
I simply can't see why VBA is breaking its own rules.
Vlookup isnt case sensitive.
ive found this function that "simulates" a vlookup case sensitive.
Function CaseVLook(FindValue, TableArray As Range, Optional ColumnID As Integer = 1) As Variant
Dim xCell As Range
Application.Volatile
CaseVLook = "Not Found"
For Each xCell In TableArray.Columns(1).Cells
If xCell = FindValue Then
CaseVLook = xCell.Offset(0, ColumnID - 1)
Exit For
End If
Next
End Function
to use it just call it CaseVLook(F1,A1:C7,3)
more information in here
https://www.extendoffice.com/documents/excel/3449-excel-vlookup-case-sensitive-insensitive.html
good luck
Here's another way...
Character_Value = Evaluate("INDEX(" & Range("pw_Table").Address(, , , True) & _
",MATCH(TRUE,EXACT(INDEX(" & Range("pw_Table").Address(, , , True) & ",0,1),""" & Character & """),0),2)")
Hope this helps!

Excel Parse out a list of numbers from text (several numbers from one cell)

I need to parse out a list of tracking numbers from text in excel. The position in terms of characters will not always be the same. An example:
Location ID 987
Your package is arriving 01/01/2015
Fruit Snacks 706970554628
<http://www.fedex. com/Tracking?tracknumbers=706970554628>
Olive Oil 709970554631
<http://www.fedex. com/Tracking?tracknumbers=709970554631>
Sign 706970594642
<http://www.fedex .com/Tracking?tracknumbers=706970594642>
Thank you for shopping with us!
The chunk of text is located in one cell. I would like the results to either be 3 separate columns or rows looking like this:
706970554628 , 709970554631 , 706970594642
There will not always be the same number of tracking numbers. One cell might have six while another has one.
Thank you for any help!!
I think you'll need some VBA to do this. And it's not going to be super simple stuff. #Gary'sStudent has a great example of grabbing numbers from a big string. If you need something that is more specific to your scenario you'll have to parse the string word by word and have it figure out when it encounters a tracking number in the URL.
Something like the following will do the trick:
Function getTrackingNumber(bigMessage As String, numberPosition As Integer) As String
Dim intStrPos As Integer
Dim arrTrackNumbers() As Variant
'create a variable to hold characters we'll use to identify words
Dim strWorkSeparators As String
strWordSeparators = "()=/<>?. " & vbCrLf
'iterate through each character in the big message
For intStrPos = 1 To Len(bigMessage)
'Identify distinct words
If InStr(1, strWordSeparators, Mid(bigMessage, intStrPos, 1)) > 1 Then 'we found the start of a new word
'if foundTrackNumber is true, then this must be a tracking number. Add it to the array of tracking numbers
If foundTrackNumber Then
'keep track of how many we've found
trackNumbersFound = trackNumbersFound + 1
'redim the array in which we are holding the track numbers
ReDim Preserve arrTrackNumbers(0 To trackNumbersFound - 1)
'add the track
arrTrackNumbers(trackNumbersFound - 1) = strword
End If
'Check to see if the word that we just grabbed is "tracknumber"
If strword = "tracknumbers" Then
foundTrackNumber = True
Else
foundTrackNumber = False
End If
'set this back to nothing
strword = ""
Else
strword = strword + Mid(bigMessage, intStrPos, 1)
End If
Next intStrPos
'return the requested tracking number if it exists.
If numberPosition > UBound(arrTrackNumbers) + 1 Then
getTrackingNumber = ""
Else
getTrackingNumber = arrTrackNumbers(numberPosition - 1)
End If
End Function
This is a UDF, so you can use it in your worksheet as a formula with:
=getTrackingNumber(A1, 1)
Which will return the first tracking number it encounters in cell A1. Consequently the formula
=getTrackingNumber(A1, 2)
will return the second tracking number, and so on.
This is not going to be a speedy function though since it's parsing the big string character by character and making decisions as it goes. If you can wrangle Gary's Student's answer into something workable it'll be much faster and less CPU intensive on larger data. However, if you are getting too many results and need to go at this like a surgeon, then this should get you in the ballpark.
If tracking is always a 12 digit number, then select the cell run run this short macro:
Sub parser117()
Dim s As String, ary, i As Long
With ActiveCell
ary = Split(Replace(Replace(.Text, Chr(10), " "), Chr(13), " "), " ")
i = 1
For Each a In ary
If Len(a) = 12 And IsNumeric(a) Then
.Offset(0, i).Value = a
i = i + 1
End If
Next a
End With
End Sub

Resources